From 066aaa52d587658a1343ea87c6bc7ad95df0e928 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 31 May 2013 11:22:36 -0400 Subject: [PATCH 01/53] ENH: Added visualization script sliced probability maps --- scripts/sliced_probmap_viz | 74 ++++++++++++++++++++++++++++++++++++++ setup.py | 3 +- 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100755 scripts/sliced_probmap_viz diff --git a/scripts/sliced_probmap_viz b/scripts/sliced_probmap_viz new file mode 100755 index 0000000..c4f981d --- /dev/null +++ b/scripts/sliced_probmap_viz @@ -0,0 +1,74 @@ +#!/usr/bin/env python +from pylab import * +import nibabel +import sys + +import argparse + + +def main(): + parser = argparse.ArgumentParser(description='Superimposed slices viz') + parser.add_argument('-s', dest='slices', type=int, nargs='+', + help='Slices to show', required=True) + parser.add_argument('-i', dest='base_image', type=str, + help='base image to show', required=True) + parser.add_argument('-j', dest='tract_image', type=str, + help='tract image to show', required=True) + parser.add_argument('-o', dest='output', type=str, + help='output image', required=True) + parser.add_argument('--invert', dest='inverse_order', + action='store_true', help='invert the slice order') + parser.add_argument('--step', dest='step', + action='store_true', help='Take the slices as `start end step`') + parser.add_argument('-t', dest='threshold', type=float, default=0, + help='lower threshold of the tract image') + parser.add_argument('--axis', dest='axis', type=int, default=2, + help='axis of the slices') + + parser.add_argument( + '--displacement', dest='displacement', type=float, default=.1, + help='displacement between axes between 0. and 1.') + parser.add_argument( + '--displacement_direction', dest='displacement_direction', type=str, + choices=('row', 'col'), default='row', + help='displacement direction: "row" or "col"') + + args = parser.parse_args() + fig = figure(frameon=False) + fa = nibabel.load(args.base_image).get_data() + tract = nibabel.load(args.tract_image).get_data() + t_colormap = cm.YlOrRd_r + t_colormap.set_under(alpha=0) + fa_cm = cm.gray + fa_cm.set_under(alpha=0) + thr = min(tract.max() - 1e-10, args.threshold) + if args.step: + args.slices = xrange(args.slices[0], args.slices[1], args.slices[2]) + for i, y in enumerate(args.slices): + if args.inverse_order: + pos = len(args.slices) - 1 - i + else: + pos = i + + if args.displacement_direction == 'row': + fig.add_axes([pos * args.displacement, 0, .5, .5], frameon=False) + else: + fig.add_axes([0, pos * args.displacement, .5, .5], frameon=False) + ax = gca() + ax.hold(True) + + slices = [slice(None)] * 3 + slices[args.axis] = y + slices = tuple(slices) + + imshow(fa[slices].T, cmap=fa_cm, vmin=1e-10, origin=True, interpolation='spline36') + imshow(tract[slices].T, cmap=t_colormap, + vmin=thr, vmax=tract.max(), origin=True, interpolation='gaussian') + xticks([]) + yticks([]) + ax.hold(False) + savefig(args.output, bbox_inches='tight', transparent=True, pad_inches=0) + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/setup.py b/setup.py index 32f0804..444aac0 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,8 @@ def configuration(parent_package='', top_path=None): ], scripts=[ 'scripts/tract_querier', - 'scripts/tract_math' + 'scripts/tract_math', + 'scripts/sliced_probmap_viz', ], **(configuration().todict()) ) From ccb1c4a35adebe1ac40ec502198c568c5418ca5d Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Mon, 17 Jun 2013 15:44:03 -0400 Subject: [PATCH 02/53] ENH: Added functionalities to the viz tool --- scripts/sliced_probmap_viz | 73 +++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 12 deletions(-) diff --git a/scripts/sliced_probmap_viz b/scripts/sliced_probmap_viz index c4f981d..e85fac6 100755 --- a/scripts/sliced_probmap_viz +++ b/scripts/sliced_probmap_viz @@ -2,6 +2,7 @@ from pylab import * import nibabel import sys +from itertools import izip import argparse @@ -9,13 +10,13 @@ import argparse def main(): parser = argparse.ArgumentParser(description='Superimposed slices viz') parser.add_argument('-s', dest='slices', type=int, nargs='+', - help='Slices to show', required=True) + help='Slices to show')#, required=True) parser.add_argument('-i', dest='base_image', type=str, - help='base image to show', required=True) - parser.add_argument('-j', dest='tract_image', type=str, - help='tract image to show', required=True) + help='base image to show')#, required=True) + parser.add_argument('-j', dest='tract_image', type=str, nargs='+', + help='tract image to show')#, required=True) parser.add_argument('-o', dest='output', type=str, - help='output image', required=True) + help='output image')#, required=True) parser.add_argument('--invert', dest='inverse_order', action='store_true', help='invert the slice order') parser.add_argument('--step', dest='step', @@ -24,6 +25,8 @@ def main(): help='lower threshold of the tract image') parser.add_argument('--axis', dest='axis', type=int, default=2, help='axis of the slices') + parser.add_argument('--mip', dest='mip', action='store_true', + help='show maximum intensity projections') parser.add_argument( '--displacement', dest='displacement', type=float, default=.1, @@ -32,16 +35,54 @@ def main(): '--displacement_direction', dest='displacement_direction', type=str, choices=('row', 'col'), default='row', help='displacement direction: "row" or "col"') + parser.add_argument('--color', dest='color', type=str, nargs='+', + default='YlOrRd_r', help='Coloring for the tract (default %(default)s)') + parser.add_argument('--alpha', dest='alpha', type=float, nargs='+', default=1., + help='Alpha for the probability maps') + + parser.add_argument('--print-colors', dest='print_colors', action='store_true', + help='Print the list of colormaps') args = parser.parse_args() + + if args.print_colors: + from matplotlib import colors + maps = [ + cm_ for cm_ in dir(cm) + if isinstance(getattr(cm, cm_), colors.Colormap) + ] + max_length = max(len(cm_) for cm_ in maps) + 3 + str_ = "{:<" + str(max_length) + "}" + for i in xrange(0, len(maps), 4): + maps_ = maps[i: i + 4] + str_line = str_ * len(maps_) + print str_line.format(*maps_) + parser.exit(0) + fig = figure(frameon=False) fa = nibabel.load(args.base_image).get_data() - tract = nibabel.load(args.tract_image).get_data() - t_colormap = cm.YlOrRd_r - t_colormap.set_under(alpha=0) + + if isinstance(args.tract_image, str): + args.tract_image = [args.tract_image] + tracts = [nibabel.load(tract_image).get_data() for tract_image in args.tract_image] + + if isinstance(args.alpha, float): + args.alpha = [args.alpha] + if len(args.alpha) == 1: + args.alpha *= len(tracts) + + if isinstance(args.color, str): + args.color = [args.color] + if len(args.color) == 1: + args.color *= len(tracts) + + t_colormap = [] + for colormap in args.color: + t_colormap.append(getattr(cm, colormap)) + t_colormap[-1].set_under(alpha=0) + fa_cm = cm.gray fa_cm.set_under(alpha=0) - thr = min(tract.max() - 1e-10, args.threshold) if args.step: args.slices = xrange(args.slices[0], args.slices[1], args.slices[2]) for i, y in enumerate(args.slices): @@ -61,9 +102,17 @@ def main(): slices[args.axis] = y slices = tuple(slices) - imshow(fa[slices].T, cmap=fa_cm, vmin=1e-10, origin=True, interpolation='spline36') - imshow(tract[slices].T, cmap=t_colormap, - vmin=thr, vmax=tract.max(), origin=True, interpolation='gaussian') + imshow(fa[slices].T, cmap=fa_cm, vmin=min(1e-10, fa[slices].min), origin=True, interpolation='spline36') + for tract, colormap in izip(tracts, t_colormap): + thr = min(tract.max() - 1e-10, args.threshold) + if args.mip: + tract_slice = tract.max(args.axis).T + else: + tract_slice = tract[slices].T + imshow( + tract_slice, cmap=colormap, + vmin=thr, vmax=tract.max(), origin=True, interpolation='gaussian' + ) xticks([]) yticks([]) ax.hold(False) From 51d80cdb361c6470c41c7dd1929446cab70e3ec4 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Thu, 20 Jun 2013 10:13:32 -0400 Subject: [PATCH 03/53] ENH: Added client side for web app, hardcoded --- scripts/tract_querier | 59 +++++++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/scripts/tract_querier b/scripts/tract_querier index a7cec69..87805c7 100644 --- a/scripts/tract_querier +++ b/scripts/tract_querier @@ -41,6 +41,11 @@ def main(): "to put both in AC-PC coordinate space" ) + parser.add_option( + '--interactive-webdisplay', dest='interactive_url', + help='Enables interactive display of the results' + ) + (options, args) = parser.parse_args() if ( @@ -116,13 +121,23 @@ def main(): options.tractography_file_name ) - tractography_extension = os.path.splitext(options.tractography_file_name)[-1] - if tractography_extension == '.trk': - tractography_extra_kwargs = { - 'affine': tr.affine, - 'image_dimensions': tr.image_dims - } + input_split = os.path.splitext(options.tractography_file_name) + output_split = os.path.splitext(options.output_file_name) + if len(output_split) > 1: + options.output_file_name = output_split[0] + tractography_extension = output_split[1] + if tractography_extension == '.trk': + if input_split[-1] == '.trk': + tractography_extra_kwargs = { + 'affine': tr.affine, + 'image_dimensions': tr.image_dims + } + else: + tractography_extra_kwargs = { + 'affine': labels_nii.get_affine(), + 'image_dimensions': img.shape + } else: tractography_extra_kwargs = {} @@ -154,13 +169,27 @@ def main(): extension=tractography_extension, extra_kwargs=tractography_extra_kwargs ) else: - query_save = ( - lambda query_name, query_result: - save_query( - query_name, tr, options, {query_name: query_result}, - extension=tractography_extension, extra_kwargs=tractography_extra_kwargs - ) - ) + if options.interactive_url is None: + def query_save(query_name, query_result): + return save_query( + query_name, tr, options, {query_name: query_result}, + extension=tractography_extension, extra_kwargs=tractography_extra_kwargs + ) + else: + def query_save(query_name, query_result): + import urllib + filename = save_query( + query_name, tr, options, {query_name: query_result}, + extension=tractography_extension, extra_kwargs=tractography_extra_kwargs + ) + if filename is not None: + try: + params = urllib.urlencode({'file': filename}) + f = urllib.urlopen(options.interactive_url, params) + f.close() + except Exception, e: + print "Interactive URL error:", e + return filename interactive_shell = tract_querier.TractQuerierCmd( tractography_spatial_indexing, @@ -176,12 +205,14 @@ def save_query(query_name, tractography, options, evaluated_queries, extension=' tract_numbers = evaluated_queries[query_name] print "\tQuery %s: %.6d" % (query_name, len(tract_numbers)) if tract_numbers: + filename = options.output_file_name + "_" + query_name + extension save_tractography_file( - options.output_file_name + "_" + query_name + extension, + filename, tractography, tract_numbers, extra_kwargs=extra_kwargs ) + return filename def save_tractography_file( From 920fc9c53467eaff3f00a52d0e858328c51fbc5c Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Sat, 22 Jun 2013 01:08:34 -0400 Subject: [PATCH 04/53] ENH: First addition of the web application viz --- scripts/tract_querier | 58 +- tract_querier/setup.py | 1 + tract_querier/shell.py | 20 +- .../tornado_server/FreeSurferColorLUT.txt | 728 ++++++++++++++++++ tract_querier/tornado_server/__init__.py | 130 ++++ tract_querier/tornado_server/css/default.css | 7 + tract_querier/tornado_server/css/viewer.css | 61 ++ tract_querier/tornado_server/index.html | 56 ++ .../tornado_server/js/FreeSurferColorLUT.js | 725 +++++++++++++++++ .../tornado_server/js/jquery-1.8.3.min.js | 2 + .../js/jquery-ui-1.9.2.custom.min.js | 6 + .../tornado_server/js/jquery.ui.slider.js | 114 +++ tract_querier/tornado_server/js/wmqlviz.js | 198 +++++ tract_querier/tornado_server/js/wmqlviz.js.in | 214 +++++ .../tornado_server/js/wmqlviz_scratch.js | 302 ++++++++ .../tornado_server/js/x.controller.js | 360 +++++++++ tract_querier/tornado_server/js/x.viewer2d.js | 139 ++++ tract_querier/tornado_server/js/xtk.js | 348 +++++++++ tract_querier/tornado_server/js/xtk_edge.js | 360 +++++++++ tract_querier/tornado_server/setup.py | 13 + 20 files changed, 3837 insertions(+), 5 deletions(-) create mode 100644 tract_querier/tornado_server/FreeSurferColorLUT.txt create mode 100644 tract_querier/tornado_server/__init__.py create mode 100644 tract_querier/tornado_server/css/default.css create mode 100644 tract_querier/tornado_server/css/viewer.css create mode 100644 tract_querier/tornado_server/index.html create mode 100644 tract_querier/tornado_server/js/FreeSurferColorLUT.js create mode 100644 tract_querier/tornado_server/js/jquery-1.8.3.min.js create mode 100644 tract_querier/tornado_server/js/jquery-ui-1.9.2.custom.min.js create mode 100644 tract_querier/tornado_server/js/jquery.ui.slider.js create mode 100644 tract_querier/tornado_server/js/wmqlviz.js create mode 100644 tract_querier/tornado_server/js/wmqlviz.js.in create mode 100644 tract_querier/tornado_server/js/wmqlviz_scratch.js create mode 100644 tract_querier/tornado_server/js/x.controller.js create mode 100644 tract_querier/tornado_server/js/x.viewer2d.js create mode 100644 tract_querier/tornado_server/js/xtk.js create mode 100644 tract_querier/tornado_server/js/xtk_edge.js create mode 100644 tract_querier/tornado_server/setup.py diff --git a/scripts/tract_querier b/scripts/tract_querier index 87805c7..5b2b320 100644 --- a/scripts/tract_querier +++ b/scripts/tract_querier @@ -40,9 +40,16 @@ def main(): help="Bounding box to apply to the image affine transform and tracts " "to put both in AC-PC coordinate space" ) - parser.add_option( - '--interactive-webdisplay', dest='interactive_url', + '--interactive-webdisplay', dest='interactive_web', action='store_true', + help='Enables interactive display of the results' + ) + parser.add_option( + '--interactive-colortable', dest='interactive_colortable', type=str, + help='Atlas colortable for the webgl viz' + ) + parser.add_option( + '--interactive-webdisplay-url', dest='interactive_url', help='Enables interactive display of the results' ) @@ -66,6 +73,12 @@ def main(): import tract_querier + if options.interactive_web: + kill_server_callback = activate_webserver(options) + options.interactive = True + else: + kill_server_callback = None + if options.bounding_box_affine_transform: bounding_box_affine_transform = np.fromstring( options.bounding_box_affine_transform, sep=',' @@ -127,6 +140,13 @@ def main(): options.output_file_name = output_split[0] tractography_extension = output_split[1] + if options.interactive_web is not None and tractography_extension != '.trk': + print ( + "The web application only works with Trackvis output files" + " setting the output to Trackvis mode" + ) + tractography_extension = '.trk' + if tractography_extension == '.trk': if input_split[-1] == '.trk': tractography_extra_kwargs = { @@ -169,7 +189,7 @@ def main(): extension=tractography_extension, extra_kwargs=tractography_extra_kwargs ) else: - if options.interactive_url is None: + if options.interactive_url is None and options.interactive_web is None: def query_save(query_name, query_result): return save_query( query_name, tr, options, {query_name: query_result}, @@ -195,6 +215,7 @@ def main(): tractography_spatial_indexing, initial_body=query_script, save_query_callback=query_save, + eof_callback=kill_server_callback, include_folders=folders ) @@ -252,6 +273,37 @@ def save_tractography_file( ) +def activate_webserver(options): + import os + from multiprocessing import Process + from tract_querier import tornado_server + + options.interactive = True + + if options.interactive_url is None: + options.interactive_url = 'http://localhost:9999/tracts' + + print "Starting web server, please direct your browser to http://localhost:%04d" % 9999 + + p = Process( + target=tornado_server.xtk_server, + args=(os.path.abspath(options.atlas_file_name),), + kwargs={ + 'colortable': options.interactive_colortable, + 'port': 9999, + 'files_path': os.getcwd(), + + } + ) + + p.start() + + def kill_server(): + p.terminate() + + return kill_server + + if __name__ == "__main__": main() sys.exit() diff --git a/tract_querier/setup.py b/tract_querier/setup.py index a799360..e44d88d 100644 --- a/tract_querier/setup.py +++ b/tract_querier/setup.py @@ -8,6 +8,7 @@ def configuration(parent_package='', top_path=None): config.add_subpackage('tract_math') config.add_subpackage('code_util') config.add_subpackage('nipype') + config.add_subpackage('tornado_server') config.add_data_files(('queries', [ 'data/FreeSurfer.qry', 'data/JHU_MNI_SS_WMPM_Type_II.qry', diff --git a/tract_querier/shell.py b/tract_querier/shell.py index 38a4256..cd58a14 100644 --- a/tract_querier/shell.py +++ b/tract_querier/shell.py @@ -95,6 +95,8 @@ def __init__( tractography_spatial_indexing, initial_body=None, tractography=None, save_query_callback=None, + del_query_callback=None, + eof_callback=None, include_folders=['.'] ): cmd.Cmd.__init__(self, 'Tab') @@ -108,6 +110,9 @@ def __init__( self.save_query_callback, self.querier ) + self.del_query_callback = del_query_callback + self.eof_callback = eof_callback + if initial_body is not None: if isinstance(initial_body, str): initial_body = queries_preprocess( @@ -137,6 +142,16 @@ def do_dir(self, patterns): for k in keys: print k + @safe_method + def do_del(self, name): + if self.del_query_callback is None: + print "Can not delete a query in this mode" + return + if name not in self.names(): + print "Error, query does not exist" + else: + self.del_query_callback(name) + def emptyline(self): return @@ -186,8 +201,7 @@ def completenames(self, text, *ignored): self.names() ) - if '=' in text: - candidates += keywords + candidates += keywords options = [ candidate @@ -203,6 +217,8 @@ def completedefault(self, text, *ignored): def do_EOF(self, line): s = raw_input("\nSure you want to leave (y/n)? ") if s.lower() == 'y': + if self.eof_callback is not None: + self.eof_callback() return True else: return False diff --git a/tract_querier/tornado_server/FreeSurferColorLUT.txt b/tract_querier/tornado_server/FreeSurferColorLUT.txt new file mode 100644 index 0000000..d42b3af --- /dev/null +++ b/tract_querier/tornado_server/FreeSurferColorLUT.txt @@ -0,0 +1,728 @@ +#$Id: FreeSurferColorLUT.txt,v 1.15.2.4 2006/05/22 17:32:14 greve Exp $ +0 Unknown 0 0 0 0 +1 Left-Cerebral-Exterior 205 62 78 255 +2 Left-Cerebral-White-Matter 245 245 245 255 +3 Left-Cerebral-Cortex 205 62 78 255 +4 Left-Lateral-Ventricle 120 18 134 255 +5 Left-Inf-Lat-Vent 196 58 250 255 +6 Left-Cerebellum-Exterior 0 148 0 255 +7 Left-Cerebellum-White-Matter 220 248 164 255 +8 Left-Cerebellum-Cortex 230 148 34 255 +9 Left-Thalamus 0 118 14 255 +10 Left-Thalamus-Proper 0 118 14 255 +11 Left-Caudate 122 186 220 255 +12 Left-Putamen 236 13 176 255 +13 Left-Pallidum 12 48 255 255 +14 3rd-Ventricle 204 182 142 255 +15 4th-Ventricle 42 204 164 255 +16 Brain-Stem 119 159 176 255 +17 Left-Hippocampus 220 216 20 255 +18 Left-Amygdala 103 255 255 255 +19 Left-Insula 80 196 98 255 +20 Left-Operculum 60 58 210 255 +21 Line-1 60 58 210 255 +22 Line-2 60 58 210 255 +23 Line-3 60 58 210 255 +24 CSF 60 60 60 255 +25 Left-Lesion 255 165 0 255 +26 Left-Accumbens-area 255 165 0 255 +27 Left-Substancia-Nigra 0 255 127 255 +28 Left-VentralDC 165 42 42 255 +29 Left-undetermined 135 206 235 255 +30 Left-vessel 160 32 240 255 +31 Left-choroid-plexus 0 200 200 255 +32 Left-F3orb 100 50 100 255 +33 Left-lOg 135 50 74 255 +34 Left-aOg 122 135 50 255 +35 Left-mOg 51 50 135 255 +36 Left-pOg 74 155 60 255 +37 Left-Stellate 120 62 43 255 +38 Left-Porg 74 155 60 255 +39 Left-Aorg 122 135 50 255 +40 Right-Cerebral-Exterior 205 62 78 255 +41 Right-Cerebral-White-Matter 0 225 0 255 +42 Right-Cerebral-Cortex 205 62 78 255 +43 Right-Lateral-Ventricle 120 18 134 255 +44 Right-Inf-Lat-Vent 196 58 250 255 +45 Right-Cerebellum-Exterior 0 148 0 255 +46 Right-Cerebellum-White-Matter 220 248 164 255 +47 Right-Cerebellum-Cortex 230 148 34 255 +48 Right-Thalamus 0 118 14 255 +49 Right-Thalamus-Proper 0 118 14 255 +50 Right-Caudate 122 186 220 255 +51 Right-Putamen 236 13 176 255 +52 Right-Pallidum 13 48 255 255 +53 Right-Hippocampus 220 216 20 255 +54 Right-Amygdala 103 255 255 255 +55 Right-Insula 80 196 98 255 +56 Right-Operculum 60 58 210 255 +57 Right-Lesion 255 165 0 255 +58 Right-Accumbens-area 255 165 0 255 +59 Right-Substancia-Nigra 0 255 127 255 +60 Right-VentralDC 165 42 42 255 +61 Right-undetermined 135 206 235 255 +62 Right-vessel 160 32 240 255 +63 Right-choroid-plexus 0 200 221 255 +64 Right-F3orb 100 50 100 255 +65 Right-lOg 135 50 74 255 +66 Right-aOg 122 135 50 255 +67 Right-mOg 51 50 135 255 +68 Right-pOg 74 155 60 255 +69 Right-Stellate 120 62 43 255 +70 Right-Porg 74 155 60 255 +71 Right-Aorg 122 135 50 255 +72 5th-Ventricle 120 190 150 255 +73 Left-Interior 122 135 50 255 +74 Right-Interior 122 135 50 255 +75 Left-Lateral-Ventricles 120 18 134 255 +76 Right-Lateral-Ventricles 120 18 134 255 +77 WM-hypointensities 200 70 255 255 +78 Left-WM-hypointensities 255 148 10 255 +79 Right-WM-hypointensities 255 148 10 255 +80 non-WM-hypointensities 164 108 226 255 +81 Left-non-WM-hypointensities 164 108 226 255 +82 Right-non-WM-hypointensities 164 108 226 255 +83 Left-F1 255 218 185 255 +84 Right-F1 255 218 185 255 +85 Optic-Chiasm 234 169 30 255 +86 Corpus_Callosum 250 255 50 255 +96 Left-Amygdala-Anterior 205 10 125 255 +97 Right-Amygdala-Anterior 205 10 125 255 +98 Dura 160 32 240 255 +100 Left-wm-intensity-abnormality 124 140 178 255 +101 Left-caudate-intensity-abnormality 125 140 178 255 +102 Left-putamen-intensity-abnormality 126 140 178 255 +103 Left-accumbens-intensity-abnormality 127 140 178 255 +104 Left-pallidum-intensity-abnormality 124 141 178 255 +105 Left-amygdala-intensity-abnormality 124 142 178 255 +106 Left-hippocampus-intensity-abnormality 124 143 178 255 +107 Left-thalamus-intensity-abnormality 124 144 178 255 +108 Left-VDC-intensity-abnormality 124 140 179 255 +109 Right-wm-intensity-abnormality 124 140 178 255 +110 Right-caudate-intensity-abnormality 125 140 178 255 +111 Right-putamen-intensity-abnormality 126 140 178 255 +112 Right-accumbens-intensity-abnormality 127 140 178 255 +113 Right-pallidum-intensity-abnormality 124 141 178 255 +114 Right-amygdala-intensity-abnormality 124 142 178 255 +115 Right-hippocampus-intensity-abnormality 124 143 178 255 +116 Right-thalamus-intensity-abnormality 124 144 178 255 +117 Right-VDC-intensity-abnormality 124 140 179 255 +118 Epidermis 255 20 147 255 +119 Conn-Tissue 205 179 139 255 +120 SC-Fat/Muscle 238 238 209 255 +121 Cranium 200 200 200 255 +122 CSF-SA 74 255 74 255 +123 Muscle 238 0 0 255 +124 Ear 0 0 139 255 +125 Adipose 173 255 47 255 +126 Spinal-Cord 133 203 229 255 +127 Soft-Tissue 26 237 57 255 +128 Nerve 34 139 34 255 +129 Bone 30 144 255 255 +130 Air 147 19 173 255 +131 Orbital-Fat 238 59 59 255 +132 Tongue 221 39 200 255 +133 Nasal-Structures 238 174 238 255 +134 Globe 255 0 0 255 +135 Teeth 72 61 139 255 +136 Left-Caudate/Putamen 21 39 132 255 +137 Right-Caudate/Putamen 21 39 132 255 +138 Left-Claustrum 65 135 20 255 +139 Right-Claustrum 65 135 20 255 +140 Cornea 134 4 160 255 +142 Diploe 221 226 68 255 +143 Vitreous-Humor 255 255 254 255 +144 Lens 52 209 226 255 +145 Aqueous-Humor 239 160 223 255 +146 Outer-Table 70 130 180 255 +147 Inner-Table 70 130 181 255 +148 Periosteum 139 121 94 255 +149 Endosteum 224 224 224 255 +150 R/C/S 255 0 0 255 +151 Iris 205 205 0 255 +152 SC-Adipose/Muscle 238 238 209 255 +153 SC-Tissue 139 121 94 255 +154 Orbital-Adipose 238 59 59 255 + + +193 Left-hippocampal_fissure 0 196 255 255 +194 Left-CADG-head 255 164 164 255 +195 Left-subiculum 196 196 0 255 +196 Left-fimbria 0 100 255 255 +197 Right-hippocampal_fissure 128 196 164 255 +198 Right-CADG-head 0 126 75 255 +199 Right-subiculum 128 96 64 255 +200 Right-fimbria 0 50 128 255 +201 alveus 255 204 153 255 +202 perforant_pathway 255 128 128 255 +203 parasubiculum 255 255 0 255 +204 presubiculum 64 0 64 255 +205 subiculum 0 0 255 255 +206 CA1 255 0 0 255 +207 CA2 128 128 255 255 +208 CA3 0 128 0 255 +209 CA4 196 160 128 255 +210 GC-DG 32 200 255 255 +211 HATA 128 255 128 255 +212 fimbria 204 153 204 255 +213 lateral_ventricle 121 17 136 255 +214 molecular_layer_HP 128 0 0 255 +215 hippocampal_fissure 128 32 255 255 +216 entorhinal_cortex 255 204 102 255 +217 molecular_layer_subiculum 128 128 128 255 +218 Amygdala 104 255 255 255 +219 Cerebral_White_Matter 0 226 0 255 +220 Cerebral_Cortex 205 63 78 255 +221 Inf_Lat_Vent 197 58 250 255 +222 Ectorhinal 197 150 250 255 +222 Perirhinal 33 150 250 255 +223 Cerebral_White_Matter_Edge 226 0 0 255 +224 fMRI_Background 10 10 10 255 + + +# lymph node and vascular labels +331 Aorta 255 0 0 255 +332 Left-Common-IliacA 255 80 0 255 +333 Right-Common-IliacA 255 160 0 255 +334 Left-External-IliacA 255 255 0 255 +335 Right-External-IliacA 0 255 0 255 +336 Left-Internal-IliacA 255 0 160 255 +337 Right-Internal-IliacA 255 0 255 255 +338 Left-Lateral-SacralA 255 50 80 255 +339 Right-Lateral-SacralA 80 255 50 255 +340 Left-ObturatorA 160 255 50 255 +341 Right-ObturatorA 160 200 255 255 +342 Left-Internal-PudendalA 0 255 160 255 +343 Right-Internal-PudendalA 0 0 255 255 +344 Left-UmbilicalA 80 50 255 255 +345 Right-UmbilicalA 160 0 255 255 +346 Left-Inf-RectalA 255 210 0 255 +347 Right-Inf-RectalA 0 160 255 255 +348 Left-Common-IliacV 255 200 80 255 +349 Right-Common-IliacV 255 200 160 255 +350 Left-External-IliacV 255 80 200 255 +351 Right-External-IliacV 255 160 200 255 +352 Left-Internal-IliacV 30 255 80 255 +353 Right-Internal-IliacV 80 200 255 255 +354 Left-ObturatorV 80 255 200 255 +355 Right-ObturatorV 195 255 200 255 +356 Left-Internal-PudendalV 120 200 20 255 +357 Right-Internal-PudendalV 170 10 200 255 +358 Pos-Lymph 20 130 180 255 +359 Neg-Lymph 20 180 130 255 + +400 V1 206 62 78 255 +401 V2 121 18 134 255 +402 BA44 199 58 250 255 +403 BA45 1 148 0 255 +404 BA4a 221 248 164 255 +405 BA4p 231 148 34 255 +406 BA6 1 118 14 255 +407 BA2 120 118 14 255 +408 BAun1 123 186 220 255 +409 BAun2 238 13 176 255 + +# Below is the color table for the cortical labels of the seg volume +# created by mri_aparc2aseg in which the aseg cortex label is replaced +# by the labels in the aparc. It also supports wm labels that will +# eventually be created by mri_aparc2aseg. Otherwise, the aseg labels +# do not change from above. The cortical lables are the same as in +# colortable_desikan_killiany.txt, except that left hemisphere has +# 1000 added to the index and the right has 2000 added. The label +# names are also prepended with ctx-lh or ctx-rh. The white matter +# labels are the same as in colortable_desikan_killiany.txt, except +# that left hemisphere has 3000 added to the index and the right has +# 4000 added. The label names are also prepended with wm-lh or wm-rh. +# Centrum semiovale is also labled with 5001 (left) and 5002 (right). +# Even further below is the color table for aparc.a2005s. + +1000 ctx-lh-unknown 25 5 25 255 +1001 ctx-lh-bankssts 25 100 40 255 +1002 ctx-lh-caudalanteriorcingulate 125 100 160 255 +1003 ctx-lh-caudalmiddlefrontal 100 25 0 255 +1004 ctx-lh-corpuscallosum 120 70 50 255 +1005 ctx-lh-cuneus 220 20 100 255 +1006 ctx-lh-entorhinal 220 20 10 255 +1007 ctx-lh-fusiform 180 220 140 255 +1008 ctx-lh-inferiorparietal 220 60 220 255 +1009 ctx-lh-inferiortemporal 180 40 120 255 +1010 ctx-lh-isthmuscingulate 140 20 140 255 +1011 ctx-lh-lateraloccipital 20 30 140 255 +1012 ctx-lh-lateralorbitofrontal 35 75 50 255 +1013 ctx-lh-lingual 225 140 140 255 +1014 ctx-lh-medialorbitofrontal 200 35 75 255 +1015 ctx-lh-middletemporal 160 100 50 255 +1016 ctx-lh-parahippocampal 20 220 60 255 +1017 ctx-lh-paracentral 60 220 60 255 +1018 ctx-lh-parsopercularis 220 180 140 255 +1019 ctx-lh-parsorbitalis 20 100 50 255 +1020 ctx-lh-parstriangularis 220 60 20 255 +1021 ctx-lh-pericalcarine 120 100 60 255 +1022 ctx-lh-postcentral 220 20 20 255 +1023 ctx-lh-posteriorcingulate 220 180 220 255 +1024 ctx-lh-precentral 60 20 220 255 +1025 ctx-lh-precuneus 160 140 180 255 +1026 ctx-lh-rostralanteriorcingulate 80 20 140 255 +1027 ctx-lh-rostralmiddlefrontal 75 50 125 255 +1028 ctx-lh-superiorfrontal 20 220 160 255 +1029 ctx-lh-superiorparietal 20 180 140 255 +1030 ctx-lh-superiortemporal 140 220 220 255 +1031 ctx-lh-supramarginal 80 160 20 255 +1032 ctx-lh-frontalpole 100 0 100 255 +1033 ctx-lh-temporalpole 70 70 70 255 +1034 ctx-lh-transversetemporal 150 150 200 255 +1035 ctx-lh-Insula 80 196 98 255 + +2000 ctx-rh-unknown 25 5 25 255 +2001 ctx-rh-bankssts 25 100 40 255 +2002 ctx-rh-caudalanteriorcingulate 125 100 160 255 +2003 ctx-rh-caudalmiddlefrontal 100 25 0 255 +2004 ctx-rh-corpuscallosum 120 70 50 255 +2005 ctx-rh-cuneus 220 20 100 255 +2006 ctx-rh-entorhinal 220 20 10 255 +2007 ctx-rh-fusiform 180 220 140 255 +2008 ctx-rh-inferiorparietal 220 60 220 255 +2009 ctx-rh-inferiortemporal 180 40 120 255 +2010 ctx-rh-isthmuscingulate 140 20 140 255 +2011 ctx-rh-lateraloccipital 20 30 140 255 +2012 ctx-rh-lateralorbitofrontal 35 75 50 255 +2013 ctx-rh-lingual 225 140 140 255 +2014 ctx-rh-medialorbitofrontal 200 35 75 255 +2015 ctx-rh-middletemporal 160 100 50 255 +2016 ctx-rh-parahippocampal 20 220 60 255 +2017 ctx-rh-paracentral 60 220 60 255 +2018 ctx-rh-parsopercularis 220 180 140 255 +2019 ctx-rh-parsorbitalis 20 100 50 255 +2020 ctx-rh-parstriangularis 220 60 20 255 +2021 ctx-rh-pericalcarine 120 100 60 255 +2022 ctx-rh-postcentral 220 20 20 255 +2023 ctx-rh-posteriorcingulate 220 180 220 255 +2024 ctx-rh-precentral 60 20 220 255 +2025 ctx-rh-precuneus 160 140 180 255 +2026 ctx-rh-rostralanteriorcingulate 80 20 140 255 +2027 ctx-rh-rostralmiddlefrontal 75 50 125 255 +2028 ctx-rh-superiorfrontal 20 220 160 255 +2029 ctx-rh-superiorparietal 20 180 140 255 +2030 ctx-rh-superiortemporal 140 220 220 255 +2031 ctx-rh-supramarginal 80 160 20 255 +2032 ctx-rh-frontalpole 100 0 100 255 +2033 ctx-rh-temporalpole 70 70 70 255 +2034 ctx-rh-transversetemporal 150 150 200 255 +2035 ctx-rh-Insula 80 196 98 255 + +3000 wm-lh-unknown 230 250 230 255 +3001 wm-lh-bankssts 230 155 215 255 +3002 wm-lh-caudalanteriorcingulate 130 155 95 255 +3003 wm-lh-caudalmiddlefrontal 155 230 255 255 +3004 wm-lh-corpuscallosum 135 185 205 255 +3005 wm-lh-cuneus 35 235 155 255 +3006 wm-lh-entorhinal 35 235 245 255 +3007 wm-lh-fusiform 75 35 115 255 +3008 wm-lh-inferiorparietal 35 195 35 255 +3009 wm-lh-inferiortemporal 75 215 135 255 +3010 wm-lh-isthmuscingulate 115 235 115 255 +3011 wm-lh-lateraloccipital 235 225 115 255 +3012 wm-lh-lateralorbitofrontal 220 180 205 255 +3013 wm-lh-lingual 30 115 115 255 +3014 wm-lh-medialorbitofrontal 55 220 180 255 +3015 wm-lh-middletemporal 95 155 205 255 +3016 wm-lh-parahippocampal 235 35 195 255 +3017 wm-lh-paracentral 195 35 195 255 +3018 wm-lh-parsopercularis 35 75 115 255 +3019 wm-lh-parsorbitalis 235 155 205 255 +3020 wm-lh-parstriangularis 35 195 235 255 +3021 wm-lh-pericalcarine 135 155 195 255 +3022 wm-lh-postcentral 35 235 235 255 +3023 wm-lh-posteriorcingulate 35 75 35 255 +3024 wm-lh-precentral 195 235 35 255 +3025 wm-lh-precuneus 95 115 75 255 +3026 wm-lh-rostralanteriorcingulate 175 235 115 255 +3027 wm-lh-rostralmiddlefrontal 180 205 130 255 +3028 wm-lh-superiorfrontal 235 35 95 255 +3029 wm-lh-superiorparietal 235 75 115 255 +3030 wm-lh-superiortemporal 115 35 35 255 +3031 wm-lh-supramarginal 175 95 235 255 +3032 wm-lh-frontalpole 155 255 155 255 +3033 wm-lh-temporalpole 185 185 185 255 +3034 wm-lh-transversetemporal 105 105 55 255 +3035 wm-lh-Insula 80 196 98 255 + +4000 wm-rh-unknown 230 250 230 255 +4001 wm-rh-bankssts 230 155 215 255 +4002 wm-rh-caudalanteriorcingulate 130 155 95 255 +4003 wm-rh-caudalmiddlefrontal 155 230 255 255 +4004 wm-rh-corpuscallosum 135 185 205 255 +4005 wm-rh-cuneus 35 235 155 255 +4006 wm-rh-entorhinal 35 235 245 255 +4007 wm-rh-fusiform 75 35 115 255 +4008 wm-rh-inferiorparietal 35 195 35 255 +4009 wm-rh-inferiortemporal 75 215 135 255 +4010 wm-rh-isthmuscingulate 115 235 115 255 +4011 wm-rh-lateraloccipital 235 225 115 255 +4012 wm-rh-lateralorbitofrontal 220 180 205 255 +4013 wm-rh-lingual 30 115 115 255 +4014 wm-rh-medialorbitofrontal 55 220 180 255 +4015 wm-rh-middletemporal 95 155 205 255 +4016 wm-rh-parahippocampal 235 35 195 255 +4017 wm-rh-paracentral 195 35 195 255 +4018 wm-rh-parsopercularis 35 75 115 255 +4019 wm-rh-parsorbitalis 235 155 205 255 +4020 wm-rh-parstriangularis 35 195 235 255 +4021 wm-rh-pericalcarine 135 155 195 255 +4022 wm-rh-postcentral 35 235 235 255 +4023 wm-rh-posteriorcingulate 35 75 35 255 +4024 wm-rh-precentral 195 235 35 255 +4025 wm-rh-precuneus 95 115 75 255 +4026 wm-rh-rostralanteriorcingulate 175 235 115 255 +4027 wm-rh-rostralmiddlefrontal 180 205 130 255 +4028 wm-rh-superiorfrontal 235 35 95 255 +4029 wm-rh-superiorparietal 235 75 115 255 +4030 wm-rh-superiortemporal 115 35 35 255 +4031 wm-rh-supramarginal 175 95 235 255 +4032 wm-rh-frontalpole 155 255 155 255 +4033 wm-rh-temporalpole 185 185 185 255 +4034 wm-rh-transversetemporal 105 105 55 255 +4035 wm-rh-Insula 80 196 98 255 + +5001 wm-lh-centrum-semiovale 20 30 40 255 +5002 wm-rh-centrum-semiovale 20 30 40 255 + +# Below is the color table for the cortical labels of the seg volume +# created by mri_aparc2aseg (with --a2005 flag) in which the aseg +# cortex label is replaced by the labels in the aparc.a2005. The +# cortical lables are the same as in Simple_surface_labels2005.txt, +# except that left hemisphere has 1100 added to the index and the +# right has 2100 added. The label names are also prepended with +# ctx-lh or ctx-rh. + +1100 ctx-lh-Unknown 0 0 0 255 +1101 ctx-lh-Corpus_callosum 50 50 50 255 +1102 ctx-lh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 255 +1103 ctx-lh-G_cingulate-Isthmus 60 25 25 255 +1104 ctx-lh-G_cingulate-Main_part 25 60 60 255 +1105 ctx-lh-G_cuneus 180 20 20 255 +1106 ctx-lh-G_frontal_inf-Opercular_part 220 20 100 255 +1107 ctx-lh-G_frontal_inf-Orbital_part 140 60 60 255 +1108 ctx-lh-G_frontal_inf-Triangular_part 180 220 140 255 +1109 ctx-lh-G_frontal_middle 140 100 180 255 +1110 ctx-lh-G_frontal_superior 180 20 140 255 +1111 ctx-lh-G_frontomarginal 140 20 140 255 +1112 ctx-lh-G_insular_long 21 10 10 255 +1113 ctx-lh-G_insular_short 225 140 140 255 +1114 ctx-lh-G_and_S_occipital_inferior 23 60 180 255 +1115 ctx-lh-G_occipital_middle 180 60 180 255 +1116 ctx-lh-G_occipital_superior 20 220 60 255 +1117 ctx-lh-G_occipit-temp_lat-Or_fusiform 60 20 140 255 +1118 ctx-lh-G_occipit-temp_med-Lingual_part 220 180 140 255 +1119 ctx-lh-G_occipit-temp_med-Parahippocampal_part 65 100 20 255 +1120 ctx-lh-G_orbital 220 60 20 255 +1121 ctx-lh-G_paracentral 60 100 60 255 +1122 ctx-lh-G_parietal_inferior-Angular_part 20 60 220 255 +1123 ctx-lh-G_parietal_inferior-Supramarginal_part 100 100 60 255 +1124 ctx-lh-G_parietal_superior 220 180 220 255 +1125 ctx-lh-G_postcentral 20 180 140 255 +1126 ctx-lh-G_precentral 60 140 180 255 +1127 ctx-lh-G_precuneus 25 20 140 255 +1128 ctx-lh-G_rectus 20 60 100 255 +1129 ctx-lh-G_subcallosal 60 220 20 255 +1130 ctx-lh-G_subcentral 60 20 220 255 +1131 ctx-lh-G_temporal_inferior 220 220 100 255 +1132 ctx-lh-G_temporal_middle 180 60 60 255 +1133 ctx-lh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 255 +1134 ctx-lh-G_temp_sup-Lateral_aspect 220 60 220 255 +1135 ctx-lh-G_temp_sup-Planum_polare 65 220 60 255 +1136 ctx-lh-G_temp_sup-Planum_tempolare 25 140 20 255 +1137 ctx-lh-G_and_S_transverse_frontopolar 13 0 250 255 +1138 ctx-lh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 255 +1139 ctx-lh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 255 +1140 ctx-lh-Lat_Fissure-post_sgt 61 60 100 255 +1141 ctx-lh-Medial_wall 25 25 25 255 +1142 ctx-lh-Pole_occipital 140 20 60 255 +1143 ctx-lh-Pole_temporal 220 180 20 255 +1144 ctx-lh-S_calcarine 63 180 180 255 +1145 ctx-lh-S_central 221 20 10 255 +1146 ctx-lh-S_central_insula 21 220 20 255 +1147 ctx-lh-S_cingulate-Main_part_and_Intracingulate 183 100 20 255 +1148 ctx-lh-S_cingulate-Marginalis_part 221 20 100 255 +1149 ctx-lh-S_circular_insula_anterior 221 60 140 255 +1150 ctx-lh-S_circular_insula_inferior 221 20 220 255 +1151 ctx-lh-S_circular_insula_superior 61 220 220 255 +1152 ctx-lh-S_collateral_transverse_ant 100 200 200 255 +1153 ctx-lh-S_collateral_transverse_post 10 200 200 255 +1154 ctx-lh-S_frontal_inferior 221 220 20 255 +1155 ctx-lh-S_frontal_middle 141 20 100 255 +1156 ctx-lh-S_frontal_superior 61 220 100 255 +1157 ctx-lh-S_frontomarginal 21 220 60 255 +1158 ctx-lh-S_intermedius_primus-Jensen 141 60 20 255 +1159 ctx-lh-S_intraparietal-and_Parietal_transverse 143 20 220 255 +1160 ctx-lh-S_occipital_anterior 61 20 180 255 +1161 ctx-lh-S_occipital_middle_and_Lunatus 101 60 220 255 +1162 ctx-lh-S_occipital_superior_and_transversalis 21 20 140 255 +1163 ctx-lh-S_occipito-temporal_lateral 221 140 20 255 +1164 ctx-lh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 255 +1165 ctx-lh-S_orbital-H_shapped 101 20 20 255 +1166 ctx-lh-S_orbital_lateral 221 100 20 255 +1167 ctx-lh-S_orbital_medial-Or_olfactory 181 200 20 255 +1168 ctx-lh-S_paracentral 21 180 140 255 +1169 ctx-lh-S_parieto_occipital 101 100 180 255 +1170 ctx-lh-S_pericallosal 181 220 20 255 +1171 ctx-lh-S_postcentral 21 140 200 255 +1172 ctx-lh-S_precentral-Inferior-part 21 20 240 255 +1173 ctx-lh-S_precentral-Superior-part 21 20 200 255 +1174 ctx-lh-S_subcentral_ant 61 180 60 255 +1175 ctx-lh-S_subcentral_post 61 180 250 255 +1176 ctx-lh-S_suborbital 21 20 60 255 +1177 ctx-lh-S_subparietal 101 60 60 255 +1178 ctx-lh-S_supracingulate 21 220 220 255 +1179 ctx-lh-S_temporal_inferior 21 180 180 255 +1180 ctx-lh-S_temporal_superior 223 220 60 255 +1181 ctx-lh-S_temporal_transverse 221 60 60 255 + +2100 ctx-rh-Unknown 0 0 0 255 +2101 ctx-rh-Corpus_callosum 50 50 50 255 +2102 ctx-rh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 255 +2103 ctx-rh-G_cingulate-Isthmus 60 25 25 255 +2104 ctx-rh-G_cingulate-Main_part 25 60 60 255 +2105 ctx-rh-G_cuneus 180 20 20 255 +2106 ctx-rh-G_frontal_inf-Opercular_part 220 20 100 255 +2107 ctx-rh-G_frontal_inf-Orbital_part 140 60 60 255 +2108 ctx-rh-G_frontal_inf-Triangular_part 180 220 140 255 +2109 ctx-rh-G_frontal_middle 140 100 180 255 +2110 ctx-rh-G_frontal_superior 180 20 140 255 +2111 ctx-rh-G_frontomarginal 140 20 140 255 +2112 ctx-rh-G_insular_long 21 10 10 255 +2113 ctx-rh-G_insular_short 225 140 140 255 +2114 ctx-rh-G_and_S_occipital_inferior 23 60 180 255 +2115 ctx-rh-G_occipital_middle 180 60 180 255 +2116 ctx-rh-G_occipital_superior 20 220 60 255 +2117 ctx-rh-G_occipit-temp_lat-Or_fusiform 60 20 140 255 +2118 ctx-rh-G_occipit-temp_med-Lingual_part 220 180 140 255 +2119 ctx-rh-G_occipit-temp_med-Parahippocampal_part 65 100 20 255 +2120 ctx-rh-G_orbital 220 60 20 255 +2121 ctx-rh-G_paracentral 60 100 60 255 +2122 ctx-rh-G_parietal_inferior-Angular_part 20 60 220 255 +2123 ctx-rh-G_parietal_inferior-Supramarginal_part 100 100 60 255 +2124 ctx-rh-G_parietal_superior 220 180 220 255 +2125 ctx-rh-G_postcentral 20 180 140 255 +2126 ctx-rh-G_precentral 60 140 180 255 +2127 ctx-rh-G_precuneus 25 20 140 255 +2128 ctx-rh-G_rectus 20 60 100 255 +2129 ctx-rh-G_subcallosal 60 220 20 255 +2130 ctx-rh-G_subcentral 60 20 220 255 +2131 ctx-rh-G_temporal_inferior 220 220 100 255 +2132 ctx-rh-G_temporal_middle 180 60 60 255 +2133 ctx-rh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 255 +2134 ctx-rh-G_temp_sup-Lateral_aspect 220 60 220 255 +2135 ctx-rh-G_temp_sup-Planum_polare 65 220 60 255 +2136 ctx-rh-G_temp_sup-Planum_tempolare 25 140 20 255 +2137 ctx-rh-G_and_S_transverse_frontopolar 13 0 250 255 +2138 ctx-rh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 255 +2139 ctx-rh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 255 +2140 ctx-rh-Lat_Fissure-post_sgt 61 60 100 255 +2141 ctx-rh-Medial_wall 25 25 25 255 +2142 ctx-rh-Pole_occipital 140 20 60 255 +2143 ctx-rh-Pole_temporal 220 180 20 255 +2144 ctx-rh-S_calcarine 63 180 180 255 +2145 ctx-rh-S_central 221 20 10 255 +2146 ctx-rh-S_central_insula 21 220 20 255 +2147 ctx-rh-S_cingulate-Main_part_and_Intracingulate 183 100 20 255 +2148 ctx-rh-S_cingulate-Marginalis_part 221 20 100 255 +2149 ctx-rh-S_circular_insula_anterior 221 60 140 255 +2150 ctx-rh-S_circular_insula_inferior 221 20 220 255 +2151 ctx-rh-S_circular_insula_superior 61 220 220 255 +2152 ctx-rh-S_collateral_transverse_ant 100 200 200 255 +2153 ctx-rh-S_collateral_transverse_post 10 200 200 255 +2154 ctx-rh-S_frontal_inferior 221 220 20 255 +2155 ctx-rh-S_frontal_middle 141 20 100 255 +2156 ctx-rh-S_frontal_superior 61 220 100 255 +2157 ctx-rh-S_frontomarginal 21 220 60 255 +2158 ctx-rh-S_intermedius_primus-Jensen 141 60 20 255 +2159 ctx-rh-S_intraparietal-and_Parietal_transverse 143 20 220 255 +2160 ctx-rh-S_occipital_anterior 61 20 180 255 +2161 ctx-rh-S_occipital_middle_and_Lunatus 101 60 220 255 +2162 ctx-rh-S_occipital_superior_and_transversalis 21 20 140 255 +2163 ctx-rh-S_occipito-temporal_lateral 221 140 20 255 +2164 ctx-rh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 255 +2165 ctx-rh-S_orbital-H_shapped 101 20 20 255 +2166 ctx-rh-S_orbital_lateral 221 100 20 255 +2167 ctx-rh-S_orbital_medial-Or_olfactory 181 200 20 255 +2168 ctx-rh-S_paracentral 21 180 140 255 +2169 ctx-rh-S_parieto_occipital 101 100 180 255 +2170 ctx-rh-S_pericallosal 181 220 20 255 +2171 ctx-rh-S_postcentral 21 140 200 255 +2172 ctx-rh-S_precentral-Inferior-part 21 20 240 255 +2173 ctx-rh-S_precentral-Superior-part 21 20 200 255 +2174 ctx-rh-S_subcentral_ant 61 180 60 255 +2175 ctx-rh-S_subcentral_post 61 180 250 255 +2176 ctx-rh-S_suborbital 21 20 60 255 +2177 ctx-rh-S_subparietal 101 60 60 255 +2178 ctx-rh-S_supracingulate 21 220 220 255 +2179 ctx-rh-S_temporal_inferior 21 180 180 255 +2180 ctx-rh-S_temporal_superior 223 220 60 255 +2181 ctx-rh-S_temporal_transverse 221 60 60 255 + +3100 wm-lh-Unknown 0 0 0 255 +3101 wm-lh-Corpus_callosum 50 50 50 255 +3102 wm-lh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 255 +3103 wm-lh-G_cingulate-Isthmus 60 25 25 255 +3104 wm-lh-G_cingulate-Main_part 25 60 60 255 +3105 wm-lh-G_cuneus 180 20 20 255 +3106 wm-lh-G_frontal_inf-Opercular_part 220 20 100 255 +3107 wm-lh-G_frontal_inf-Orbital_part 140 60 60 255 +3108 wm-lh-G_frontal_inf-Triangular_part 180 220 140 255 +3109 wm-lh-G_frontal_middle 140 100 180 255 +3110 wm-lh-G_frontal_superior 180 20 140 255 +3111 wm-lh-G_frontomarginal 140 20 140 255 +3112 wm-lh-G_insular_long 21 10 10 255 +3113 wm-lh-G_insular_short 225 140 140 255 +3114 wm-lh-G_and_S_occipital_inferior 23 60 180 255 +3115 wm-lh-G_occipital_middle 180 60 180 255 +3116 wm-lh-G_occipital_superior 20 220 60 255 +3117 wm-lh-G_occipit-temp_lat-Or_fusiform 60 20 140 255 +3118 wm-lh-G_occipit-temp_med-Lingual_part 220 180 140 255 +3119 wm-lh-G_occipit-temp_med-Parahippocampal_part 65 100 20 255 +3120 wm-lh-G_orbital 220 60 20 255 +3121 wm-lh-G_paracentral 60 100 60 255 +3122 wm-lh-G_parietal_inferior-Angular_part 20 60 220 255 +3123 wm-lh-G_parietal_inferior-Supramarginal_part 100 100 60 255 +3124 wm-lh-G_parietal_superior 220 180 220 255 +3125 wm-lh-G_postcentral 20 180 140 255 +3126 wm-lh-G_precentral 60 140 180 255 +3127 wm-lh-G_precuneus 25 20 140 255 +3128 wm-lh-G_rectus 20 60 100 255 +3129 wm-lh-G_subcallosal 60 220 20 255 +3130 wm-lh-G_subcentral 60 20 220 255 +3131 wm-lh-G_temporal_inferior 220 220 100 255 +3132 wm-lh-G_temporal_middle 180 60 60 255 +3133 wm-lh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 255 +3134 wm-lh-G_temp_sup-Lateral_aspect 220 60 220 255 +3135 wm-lh-G_temp_sup-Planum_polare 65 220 60 255 +3136 wm-lh-G_temp_sup-Planum_tempolare 25 140 20 255 +3137 wm-lh-G_and_S_transverse_frontopolar 13 0 250 255 +3138 wm-lh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 255 +3139 wm-lh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 255 +3140 wm-lh-Lat_Fissure-post_sgt 61 60 100 255 +3141 wm-lh-Medial_wall 25 25 25 255 +3142 wm-lh-Pole_occipital 140 20 60 255 +3143 wm-lh-Pole_temporal 220 180 20 255 +3144 wm-lh-S_calcarine 63 180 180 255 +3145 wm-lh-S_central 221 20 10 255 +3146 wm-lh-S_central_insula 21 220 20 255 +3147 wm-lh-S_cingulate-Main_part_and_Intracingulate 183 100 20 255 +3148 wm-lh-S_cingulate-Marginalis_part 221 20 100 255 +3149 wm-lh-S_circular_insula_anterior 221 60 140 255 +3150 wm-lh-S_circular_insula_inferior 221 20 220 255 +3151 wm-lh-S_circular_insula_superior 61 220 220 255 +3152 wm-lh-S_collateral_transverse_ant 100 200 200 255 +3153 wm-lh-S_collateral_transverse_post 10 200 200 255 +3154 wm-lh-S_frontal_inferior 221 220 20 255 +3155 wm-lh-S_frontal_middle 141 20 100 255 +3156 wm-lh-S_frontal_superior 61 220 100 255 +3157 wm-lh-S_frontomarginal 21 220 60 255 +3158 wm-lh-S_intermedius_primus-Jensen 141 60 20 255 +3159 wm-lh-S_intraparietal-and_Parietal_transverse 143 20 220 255 +3160 wm-lh-S_occipital_anterior 61 20 180 255 +3161 wm-lh-S_occipital_middle_and_Lunatus 101 60 220 255 +3162 wm-lh-S_occipital_superior_and_transversalis 21 20 140 255 +3163 wm-lh-S_occipito-temporal_lateral 221 140 20 255 +3164 wm-lh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 255 +3165 wm-lh-S_orbital-H_shapped 101 20 20 255 +3166 wm-lh-S_orbital_lateral 221 100 20 255 +3167 wm-lh-S_orbital_medial-Or_olfactory 181 200 20 255 +3168 wm-lh-S_paracentral 21 180 140 255 +3169 wm-lh-S_parieto_occipital 101 100 180 255 +3170 wm-lh-S_pericallosal 181 220 20 255 +3171 wm-lh-S_postcentral 21 140 200 255 +3172 wm-lh-S_precentral-Inferior-part 21 20 240 255 +3173 wm-lh-S_precentral-Superior-part 21 20 200 255 +3174 wm-lh-S_subcentral_ant 61 180 60 255 +3175 wm-lh-S_subcentral_post 61 180 250 255 +3176 wm-lh-S_suborbital 21 20 60 255 +3177 wm-lh-S_subparietal 101 60 60 255 +3178 wm-lh-S_supracingulate 21 220 220 255 +3179 wm-lh-S_temporal_inferior 21 180 180 255 +3180 wm-lh-S_temporal_superior 223 220 60 255 +3181 wm-lh-S_temporal_transverse 221 60 60 255 + +4100 wm-rh-Unknown 0 0 0 255 +4101 wm-rh-Corpus_callosum 50 50 50 255 +4102 wm-rh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 255 +4103 wm-rh-G_cingulate-Isthmus 60 25 25 255 +4104 wm-rh-G_cingulate-Main_part 25 60 60 255 +4105 wm-rh-G_cuneus 180 20 20 255 +4106 wm-rh-G_frontal_inf-Opercular_part 220 20 100 255 +4107 wm-rh-G_frontal_inf-Orbital_part 140 60 60 255 +4108 wm-rh-G_frontal_inf-Triangular_part 180 220 140 255 +4109 wm-rh-G_frontal_middle 140 100 180 255 +4110 wm-rh-G_frontal_superior 180 20 140 255 +4111 wm-rh-G_frontomarginal 140 20 140 255 +4112 wm-rh-G_insular_long 21 10 10 255 +4113 wm-rh-G_insular_short 225 140 140 255 +4114 wm-rh-G_and_S_occipital_inferior 23 60 180 255 +4115 wm-rh-G_occipital_middle 180 60 180 255 +4116 wm-rh-G_occipital_superior 20 220 60 255 +4117 wm-rh-G_occipit-temp_lat-Or_fusiform 60 20 140 255 +4118 wm-rh-G_occipit-temp_med-Lingual_part 220 180 140 255 +4119 wm-rh-G_occipit-temp_med-Parahippocampal_part 65 100 20 255 +4120 wm-rh-G_orbital 220 60 20 255 +4121 wm-rh-G_paracentral 60 100 60 255 +4122 wm-rh-G_parietal_inferior-Angular_part 20 60 220 255 +4123 wm-rh-G_parietal_inferior-Supramarginal_part 100 100 60 255 +4124 wm-rh-G_parietal_superior 220 180 220 255 +4125 wm-rh-G_postcentral 20 180 140 255 +4126 wm-rh-G_precentral 60 140 180 255 +4127 wm-rh-G_precuneus 25 20 140 255 +4128 wm-rh-G_rectus 20 60 100 255 +4129 wm-rh-G_subcallosal 60 220 20 255 +4130 wm-rh-G_subcentral 60 20 220 255 +4131 wm-rh-G_temporal_inferior 220 220 100 255 +4132 wm-rh-G_temporal_middle 180 60 60 255 +4133 wm-rh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 255 +4134 wm-rh-G_temp_sup-Lateral_aspect 220 60 220 255 +4135 wm-rh-G_temp_sup-Planum_polare 65 220 60 255 +4136 wm-rh-G_temp_sup-Planum_tempolare 25 140 20 255 +4137 wm-rh-G_and_S_transverse_frontopolar 13 0 250 255 +4138 wm-rh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 255 +4139 wm-rh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 255 +4140 wm-rh-Lat_Fissure-post_sgt 61 60 100 255 +4141 wm-rh-Medial_wall 25 25 25 255 +4142 wm-rh-Pole_occipital 140 20 60 255 +4143 wm-rh-Pole_temporal 220 180 20 255 +4144 wm-rh-S_calcarine 63 180 180 255 +4145 wm-rh-S_central 221 20 10 255 +4146 wm-rh-S_central_insula 21 220 20 255 +4147 wm-rh-S_cingulate-Main_part_and_Intracingulate 183 100 20 255 +4148 wm-rh-S_cingulate-Marginalis_part 221 20 100 255 +4149 wm-rh-S_circular_insula_anterior 221 60 140 255 +4150 wm-rh-S_circular_insula_inferior 221 20 220 255 +4151 wm-rh-S_circular_insula_superior 61 220 220 255 +4152 wm-rh-S_collateral_transverse_ant 100 200 200 255 +4153 wm-rh-S_collateral_transverse_post 10 200 200 255 +4154 wm-rh-S_frontal_inferior 221 220 20 255 +4155 wm-rh-S_frontal_middle 141 20 100 255 +4156 wm-rh-S_frontal_superior 61 220 100 255 +4157 wm-rh-S_frontomarginal 21 220 60 255 +4158 wm-rh-S_intermedius_primus-Jensen 141 60 20 255 +4159 wm-rh-S_intraparietal-and_Parietal_transverse 143 20 220 255 +4160 wm-rh-S_occipital_anterior 61 20 180 255 +4161 wm-rh-S_occipital_middle_and_Lunatus 101 60 220 255 +4162 wm-rh-S_occipital_superior_and_transversalis 21 20 140 255 +4163 wm-rh-S_occipito-temporal_lateral 221 140 20 255 +4164 wm-rh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 255 +4165 wm-rh-S_orbital-H_shapped 101 20 20 255 +4166 wm-rh-S_orbital_lateral 221 100 20 255 +4167 wm-rh-S_orbital_medial-Or_olfactory 181 200 20 255 +4168 wm-rh-S_paracentral 21 180 140 255 +4169 wm-rh-S_parieto_occipital 101 100 180 255 +4170 wm-rh-S_pericallosal 181 220 20 255 +4171 wm-rh-S_postcentral 21 140 200 255 +4172 wm-rh-S_precentral-Inferior-part 21 20 240 255 +4173 wm-rh-S_precentral-Superior-part 21 20 200 255 +4174 wm-rh-S_subcentral_ant 61 180 60 255 +4175 wm-rh-S_subcentral_post 61 180 250 255 +4176 wm-rh-S_suborbital 21 20 60 255 +4177 wm-rh-S_subparietal 101 60 60 255 +4178 wm-rh-S_supracingulate 21 220 220 255 +4179 wm-rh-S_temporal_inferior 21 180 180 255 +4180 wm-rh-S_temporal_superior 223 220 60 255 +4181 wm-rh-S_temporal_transverse 221 60 60 255 diff --git a/tract_querier/tornado_server/__init__.py b/tract_querier/tornado_server/__init__.py new file mode 100644 index 0000000..e65b219 --- /dev/null +++ b/tract_querier/tornado_server/__init__.py @@ -0,0 +1,130 @@ +import os +import sys + +import tornado.ioloop +import tornado.web +import tornado.gen +import tornado.ioloop +import tornado.websocket + +websocket_clients = [] + + +class WSHandler(tornado.websocket.WebSocketHandler): + + def open(self): + global websocket_clients + websocket_clients.append(self) + + def on_message(self, message): + # self.write_message(u"You Said: " + message) + global change + change = message + + #self.write_message(message + "Response") + + def on_close(self): + global websocket_clients + print 'connection closed' + websocket_clients.remove(self) + + +class MainHandler(tornado.web.RequestHandler): + def initialize( + self, + host=None, port=None, path=None, + filename=None, colortable=None, + websocketsuffix='ws'): + self.filename = filename + self.colortable = colortable + self.host = host + self.port = port + self.path = path + self.websocketsuffix = websocketsuffix + + def get(self): + return self.render( + os.path.join(self.path, 'index.html'), + host=self.host, port=self.port, + websocket_server='ws://%(host)s:%(port)04d/%(websocketsuffix)s' % { + 'host': self.host, + 'port': self.port, + 'websocketsuffix': self.websocketsuffix + }, + filename=self.filename, colortable=self.colortable + ) + + +class AtlasHandler(tornado.web.StaticFileHandler): + def initialize( + self, + filename=None, colortable=None, + ): + super(AtlasHandler, self).initialize('/') + self.filename = filename + self.colortable = colortable + + def get(self, args): + print "GETTING", args + if args == 'atlas.nii.gz': + super(AtlasHandler, self).get(self.filename) + elif args == 'colortable.txt': + super(AtlasHandler, self).get(self.colortable) + else: + raise ValueError("Unidentified file") + + +class TractHandler(tornado.web.RequestHandler): + def post(self): + try: + arg = self.get_argument("file") + for client in websocket_clients: + client.write_message(arg) + except Exception, e: + print e + + +def xtk_server(atlas, colortable=None, port=9999, files_path=None): + print "Using atlas", atlas + global application + + static_folder = os.path.join( + sys.prefix, + 'tract_querier', 'tornado_server' + ) + + if colortable is None: + print "No color table specified, using FreeSurfer" + colortable = os.path.join( + sys.prefix, 'tract_querier', + 'tornado_server', 'FreeSurferColorLUT.txt' + ) + else: + colortable = os.path.abspath(colortable) + + application = tornado.web.Application([ + (r"/", MainHandler, { + 'host': 'localhost', 'port': 9999, + 'path': static_folder, + 'filename': atlas, + 'colortable': colortable + }), + ( + r"/static/(.*)", + tornado.web.StaticFileHandler, + {"path": static_folder} + ), + (r'/ws', WSHandler), + (r'/tracts', TractHandler), + ( + r'/atlas/(.*)', + AtlasHandler, { + 'filename': atlas, + 'colortable': colortable + } + + ), + (r'/files/(.*)', tornado.web.StaticFileHandler, {"path": files_path}) + ]) + application.listen(port) + tornado.ioloop.IOLoop.instance().start() diff --git a/tract_querier/tornado_server/css/default.css b/tract_querier/tornado_server/css/default.css new file mode 100644 index 0000000..60c4d81 --- /dev/null +++ b/tract_querier/tornado_server/css/default.css @@ -0,0 +1,7 @@ +html, body { + background-color:#000; + margin: 0; + padding: 0; + height: 100%; + overflow: hidden !important; +} diff --git a/tract_querier/tornado_server/css/viewer.css b/tract_querier/tornado_server/css/viewer.css new file mode 100644 index 0000000..b2b2837 --- /dev/null +++ b/tract_querier/tornado_server/css/viewer.css @@ -0,0 +1,61 @@ +.threeDRenderer { + background-color: #000; + position: absolute; + width: 100%; + height: 100%; +} + +.twoDRenderer { + border-left: thin solid #666; + background-color: #000; + position: absolute; + width: 20%; + height: 31%; + /*height: 33.333%;*/ + right: 0%; +} + +#sliceX { + top: 7%; +} + +#sliceY { + top: 38%; +} + +#sliceZ { + top: 69%; +} + + +#yellow_slider { + margin-top: auto; + background: yellow; +} + +#red_slider { + margin-top: auto; + background: red; +} + +#green_slider { + margin-top: 2px; + background: green; +} + +.xtk-progress-bar { + position: absolute; + top: 50%; + left: 50%; +} + +.ren2d_icon { + cursor: pointer; + position: absolute; + width: 28px; + height: 28px; + top: 12px; + border: thin dotted #484848; + opacity: 0.5; +} + diff --git a/tract_querier/tornado_server/index.html b/tract_querier/tornado_server/index.html new file mode 100644 index 0000000..fa3a936 --- /dev/null +++ b/tract_querier/tornado_server/index.html @@ -0,0 +1,56 @@ + + + + + +Test + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+

No Label Selected

+
+
+
+
+
+
+
+
+
+
+ + + + diff --git a/tract_querier/tornado_server/js/FreeSurferColorLUT.js b/tract_querier/tornado_server/js/FreeSurferColorLUT.js new file mode 100644 index 0000000..cfed7fa --- /dev/null +++ b/tract_querier/tornado_server/js/FreeSurferColorLUT.js @@ -0,0 +1,725 @@ +initializeFreesurferLabels = function (container) { + container.labels = { + "Unknown": 0, + "Left Cerebral Exterior": 1, + "Left Cerebral White Matter": 2, + "Left Cerebral Cortex": 3, + "Left Lateral Ventricle": 4, + "Left Inf Lat Vent": 5, + "Left Cerebellum Exterior": 6, + "Left Cerebellum White Matter": 7, + "Left Cerebellum Cortex": 8, + "Left Thalamus": 9, + "Left Thalamus Proper": 10, + "Left Caudate": 11, + "Left Putamen": 12, + "Left Pallidum": 13, + "3rd Ventricle": 14, + "4th Ventricle": 15, + "Brain Stem": 16, + "Left Hippocampus": 17, + "Left Amygdala": 18, + "Left Insula": 19, + "Left Operculum": 20, + "Line 1": 21, + "Line 2": 22, + "Line 3": 23, + "CSF": 24, + "Left Lesion": 25, + "Left Accumbens area": 26, + "Left Substancia Nigra": 27, + "Left VentralDC": 28, + "Left undetermined": 29, + "Left vessel": 30, + "Left choroid plexus": 31, + "Left F3orb": 32, + "Left lOg": 33, + "Left aOg": 34, + "Left mOg": 35, + "Left pOg": 36, + "Left Stellate": 37, + "Left Porg": 38, + "Left Aorg": 39, + "Right Cerebral Exterior": 40, + "Right Cerebral White Matter": 41, + "Right Cerebral Cortex": 42, + "Right Lateral Ventricle": 43, + "Right Inf Lat Vent": 44, + "Right Cerebellum Exterior": 45, + "Right Cerebellum White Matter": 46, + "Right Cerebellum Cortex": 47, + "Right Thalamus": 48, + "Right Thalamus Proper": 49, + "Right Caudate": 50, + "Right Putamen": 51, + "Right Pallidum": 52, + "Right Hippocampus": 53, + "Right Amygdala": 54, + "Right Insula": 55, + "Right Operculum": 56, + "Right Lesion": 57, + "Right Accumbens area": 58, + "Right Substancia Nigra": 59, + "Right VentralDC": 60, + "Right undetermined": 61, + "Right vessel": 62, + "Right choroid plexus": 63, + "Right F3orb": 64, + "Right lOg": 65, + "Right aOg": 66, + "Right mOg": 67, + "Right pOg": 68, + "Right Stellate": 69, + "Right Porg": 70, + "Right Aorg": 71, + "5th Ventricle": 72, + "Left Interior": 73, + "Right Interior": 74, + "Left Lateral Ventricles": 75, + "Right Lateral Ventricles": 76, + "WM hypointensities": 77, + "Left WM hypointensities": 78, + "Right WM hypointensities": 79, + "non WM hypointensities": 80, + "Left non WM hypointensities": 81, + "Right non WM hypointensities": 82, + "Left F1": 83, + "Right F1": 84, + "Optic Chiasm": 85, + "Corpus_Callosum": 86, + "Left Amygdala Anterior": 96, + "Right Amygdala Anterior": 97, + "Dura": 98, + "Left wm intensity abnormality": 100, + "Left caudate intensity abnormality": 101, + "Left putamen intensity abnormality": 102, + "Left accumbens intensity abnormality": 103, + "Left pallidum intensity abnormality": 104, + "Left amygdala intensity abnormality": 105, + "Left hippocampus intensity abnormality": 106, + "Left thalamus intensity abnormality": 107, + "Left VDC intensity abnormality": 108, + "Right wm intensity abnormality": 109, + "Right caudate intensity abnormality": 110, + "Right putamen intensity abnormality": 111, + "Right accumbens intensity abnormality": 112, + "Right pallidum intensity abnormality": 113, + "Right amygdala intensity abnormality": 114, + "Right hippocampus intensity abnormality": 115, + "Right thalamus intensity abnormality": 116, + "Right VDC intensity abnormality": 117, + "Epidermis": 118, + "Conn Tissue": 119, + "SC Fat_Muscle": 120, + "Cranium": 121, + "CSF SA": 122, + "Muscle": 123, + "Ear": 124, + "Adipose": 125, + "Spinal Cord": 126, + "Soft Tissue": 127, + "Nerve": 128, + "Bone": 129, + "Air": 130, + "Orbital Fat": 131, + "Tongue": 132, + "Nasal Structures": 133, + "Globe": 134, + "Teeth": 135, + "Left Caudate": 136, + "Right Caudate": 137, + "Left Claustrum": 138, + "Right Claustrum": 139, + "Cornea": 140, + "Diploe": 142, + "Vitreous Humor": 143, + "Lens": 144, + "Aqueous Humor": 145, + "Outer Table": 146, + "Inner Table": 147, + "Periosteum": 148, + "Endosteum": 149, + "R": 150, + "Iris": 151, + "SC Adipose": 152, + "SC Tissue": 153, + "Orbital Adipose": 154, + + + "Left hippocampal_fissure": 193, + "Left CADG head": 194, + "Left subiculum": 195, + "Left fimbria": 196, + "Right hippocampal_fissure": 197, + "Right CADG head": 198, + "Right subiculum": 199, + "Right fimbria": 200, + "alveus": 201, + "perforant_pathway": 202, + "parasubiculum": 203, + "presubiculum": 204, + "subiculum": 205, + "CA1": 206, + "CA2": 207, + "CA3": 208, + "CA4": 209, + "GC DG": 210, + "HATA": 211, + "fimbria": 212, + "lateral_ventricle": 213, + "molecular_layer_HP": 214, + "hippocampal_fissure": 215, + "entorhinal_cortex": 216, + "molecular_layer_subiculum": 217, + "Amygdala": 218, + "Cerebral_White_Matter": 219, + "Cerebral_Cortex": 220, + "Inf_Lat_Vent": 221, + "Ectorhinal": 222, + "Perirhinal": 222, + "Cerebral_White_Matter_Edge": 223, + "fMRI_Background": 224, + + +// lymph node and vascular labels + "Aorta": 331, + "Left Common IliacA": 332, + "Right Common IliacA": 333, + "Left External IliacA": 334, + "Right External IliacA": 335, + "Left Internal IliacA": 336, + "Right Internal IliacA": 337, + "Left Lateral SacralA": 338, + "Right Lateral SacralA": 339, + "Left ObturatorA": 340, + "Right ObturatorA": 341, + "Left Internal PudendalA": 342, + "Right Internal PudendalA": 343, + "Left UmbilicalA": 344, + "Right UmbilicalA": 345, + "Left Inf RectalA": 346, + "Right Inf RectalA": 347, + "Left Common IliacV": 348, + "Right Common IliacV": 349, + "Left External IliacV": 350, + "Right External IliacV": 351, + "Left Internal IliacV": 352, + "Right Internal IliacV": 353, + "Left ObturatorV": 354, + "Right ObturatorV": 355, + "Left Internal PudendalV": 356, + "Right Internal PudendalV": 357, + "Pos Lymph": 358, + "Neg Lymph": 359, + + "V1": 400, + "V2": 401, + "BA44": 402, + "BA45": 403, + "BA4a": 404, + "BA4p": 405, + "BA6": 406, + "BA2": 407, + "BAun1": 408, + "BAun2": 409, + +// Below is the color table for the cortical labels of the seg volume +// created by mri_aparc2aseg in which the aseg cortex label is replaced +// by the labels in the aparc. It also supports wm labels that will +// eventually be created by mri_aparc2aseg. Otherwise, the aseg labels +// do not change from above. The cortical lables are the same as in +// colortable_desikan_killiany.txt, except that left hemisphere has +// 1000 added to the index and the right has 2000 added. The label +// names are also prepended with ctx lh or ctx rh. The white matter +// labels are the same as in colortable_desikan_killiany.txt, except +// that left hemisphere has 3000 added to the index and the right has +// 4000 added. The label names are also prepended with wm lh or wm rh. +// Centrum semiovale is also labled with 5001 (left) and 5002 (right). +// Even further below is the color table for aparc.a2005s. + + "ctx lh unknown": 1000, + "ctx lh bankssts": 1001, + "ctx lh caudalanteriorcingulate": 1002, + "ctx lh caudalmiddlefrontal": 1003, + "ctx lh corpuscallosum": 1004, + "ctx lh cuneus": 1005, + "ctx lh entorhinal": 1006, + "ctx lh fusiform": 1007, + "ctx lh inferiorparietal": 1008, + "ctx lh inferiortemporal": 1009, + "ctx lh isthmuscingulate": 1010, + "ctx lh lateraloccipital": 1011, + "ctx lh lateralorbitofrontal": 1012, + "ctx lh lingual": 1013, + "ctx lh medialorbitofrontal": 1014, + "ctx lh middletemporal": 1015, + "ctx lh parahippocampal": 1016, + "ctx lh paracentral": 1017, + "ctx lh parsopercularis": 1018, + "ctx lh parsorbitalis": 1019, + "ctx lh parstriangularis": 1020, + "ctx lh pericalcarine": 1021, + "ctx lh postcentral": 1022, + "ctx lh posteriorcingulate": 1023, + "ctx lh precentral": 1024, + "ctx lh precuneus": 1025, + "ctx lh rostralanteriorcingulate": 1026, + "ctx lh rostralmiddlefrontal": 1027, + "ctx lh superiorfrontal": 1028, + "ctx lh superiorparietal": 1029, + "ctx lh superiortemporal": 1030, + "ctx lh supramarginal": 1031, + "ctx lh frontalpole": 1032, + "ctx lh temporalpole": 1033, + "ctx lh transversetemporal": 1034, + + "ctx rh unknown": 2000, + "ctx rh bankssts": 2001, + "ctx rh caudalanteriorcingulate": 2002, + "ctx rh caudalmiddlefrontal": 2003, + "ctx rh corpuscallosum": 2004, + "ctx rh cuneus": 2005, + "ctx rh entorhinal": 2006, + "ctx rh fusiform": 2007, + "ctx rh inferiorparietal": 2008, + "ctx rh inferiortemporal": 2009, + "ctx rh isthmuscingulate": 2010, + "ctx rh lateraloccipital": 2011, + "ctx rh lateralorbitofrontal": 2012, + "ctx rh lingual": 2013, + "ctx rh medialorbitofrontal": 2014, + "ctx rh middletemporal": 2015, + "ctx rh parahippocampal": 2016, + "ctx rh paracentral": 2017, + "ctx rh parsopercularis": 2018, + "ctx rh parsorbitalis": 2019, + "ctx rh parstriangularis": 2020, + "ctx rh pericalcarine": 2021, + "ctx rh postcentral": 2022, + "ctx rh posteriorcingulate": 2023, + "ctx rh precentral": 2024, + "ctx rh precuneus": 2025, + "ctx rh rostralanteriorcingulate": 2026, + "ctx rh rostralmiddlefrontal": 2027, + "ctx rh superiorfrontal": 2028, + "ctx rh superiorparietal": 2029, + "ctx rh superiortemporal": 2030, + "ctx rh supramarginal": 2031, + "ctx rh frontalpole": 2032, + "ctx rh temporalpole": 2033, + "ctx rh transversetemporal": 2034, + + "wm lh unknown": 3000, + "wm lh bankssts": 3001, + "wm lh caudalanteriorcingulate": 3002, + "wm lh caudalmiddlefrontal": 3003, + "wm lh corpuscallosum": 3004, + "wm lh cuneus": 3005, + "wm lh entorhinal": 3006, + "wm lh fusiform": 3007, + "wm lh inferiorparietal": 3008, + "wm lh inferiortemporal": 3009, + "wm lh isthmuscingulate": 3010, + "wm lh lateraloccipital": 3011, + "wm lh lateralorbitofrontal": 3012, + "wm lh lingual": 3013, + "wm lh medialorbitofrontal": 3014, + "wm lh middletemporal": 3015, + "wm lh parahippocampal": 3016, + "wm lh paracentral": 3017, + "wm lh parsopercularis": 3018, + "wm lh parsorbitalis": 3019, + "wm lh parstriangularis": 3020, + "wm lh pericalcarine": 3021, + "wm lh postcentral": 3022, + "wm lh posteriorcingulate": 3023, + "wm lh precentral": 3024, + "wm lh precuneus": 3025, + "wm lh rostralanteriorcingulate": 3026, + "wm lh rostralmiddlefrontal": 3027, + "wm lh superiorfrontal": 3028, + "wm lh superiorparietal": 3029, + "wm lh superiortemporal": 3030, + "wm lh supramarginal": 3031, + "wm lh frontalpole": 3032, + "wm lh temporalpole": 3033, + "wm lh transversetemporal": 3034, + "wm rh unknown": 4000, + "wm rh bankssts": 4001, + "wm rh caudalanteriorcingulate": 4002, + "wm rh caudalmiddlefrontal": 4003, + "wm rh corpuscallosum": 4004, + "wm rh cuneus": 4005, + "wm rh entorhinal": 4006, + "wm rh fusiform": 4007, + "wm rh inferiorparietal": 4008, + "wm rh inferiortemporal": 4009, + "wm rh isthmuscingulate": 4010, + "wm rh lateraloccipital": 4011, + "wm rh lateralorbitofrontal": 4012, + "wm rh lingual": 4013, + "wm rh medialorbitofrontal": 4014, + "wm rh middletemporal": 4015, + "wm rh parahippocampal": 4016, + "wm rh paracentral": 4017, + "wm rh parsopercularis": 4018, + "wm rh parsorbitalis": 4019, + "wm rh parstriangularis": 4020, + "wm rh pericalcarine": 4021, + "wm rh postcentral": 4022, + "wm rh posteriorcingulate": 4023, + "wm rh precentral": 4024, + "wm rh precuneus": 4025, + "wm rh rostralanteriorcingulate": 4026, + "wm rh rostralmiddlefrontal": 4027, + "wm rh superiorfrontal": 4028, + "wm rh superiorparietal": 4029, + "wm rh superiortemporal": 4030, + "wm rh supramarginal": 4031, + "wm rh frontalpole": 4032, + "wm rh temporalpole": 4033, + "wm rh transversetemporal": 4034, + "wm lh centrum semiovale": 5001, + "wm rh centrum semiovale": 5002, + +// Below is the color table for the cortical labels of the seg volume +// created by mri_aparc2aseg (with a2005 flag) in which the aseg +// cortex label is replaced by the labels in the aparc.a2005. The +// cortical lables are the same as in Simple_surface_labels2005.txt, +// except that left hemisphere has 1100 added to the index and the +// right has 2100 added. The label names are also prepended with +// ctx lh or ctx rh. + + "ctx lh Unknown": 1100, + "ctx lh Corpus_callosum": 1101, + "ctx lh G_and_S_Insula_ONLY_AVERAGE": 1102, + "ctx lh G_cingulate Isthmus": 1103, + "ctx lh G_cingulate Main_part": 1104, + "ctx lh G_cuneus": 1105, + "ctx lh G_frontal_inf Opercular_part": 1106, + "ctx lh G_frontal_inf Orbital_part": 1107, + "ctx lh G_frontal_inf Triangular_part": 1108, + "ctx lh G_frontal_middle": 1109, + "ctx lh G_frontal_superior": 1110, + "ctx lh G_frontomarginal": 1111, + "ctx lh G_insular_long": 1112, + "ctx lh G_insular_short": 1113, + "ctx lh G_and_S_occipital_inferior": 1114, + "ctx lh G_occipital_middle": 1115, + "ctx lh G_occipital_superior": 1116, + "ctx lh G_occipit temp_lat Or_fusiform": 1117, + "ctx lh G_occipit temp_med Lingual_part": 1118, + "ctx lh G_occipit temp_med Parahippocampal_part": 1119, + "ctx lh G_orbital": 1120, + "ctx lh G_paracentral": 1121, + "ctx lh G_parietal_inferior Angular_part": 1122, + "ctx lh G_parietal_inferior Supramarginal_part": 1123, + "ctx lh G_parietal_superior": 1124, + "ctx lh G_postcentral": 1125, + "ctx lh G_precentral": 1126, + "ctx lh G_precuneus": 1127, + "ctx lh G_rectus": 1128, + "ctx lh G_subcallosal": 1129, + "ctx lh G_subcentral": 1130, + "ctx lh G_temporal_inferior": 1131, + "ctx lh G_temporal_middle": 1132, + "ctx lh G_temp_sup G_temp_transv_and_interm_S": 1133, + "ctx lh G_temp_sup Lateral_aspect": 1134, + "ctx lh G_temp_sup Planum_polare": 1135, + "ctx lh G_temp_sup Planum_tempolare": 1136, + "ctx lh G_and_S_transverse_frontopolar": 1137, + "ctx lh Lat_Fissure ant_sgt ramus_horizontal": 1138, + "ctx lh Lat_Fissure ant_sgt ramus_vertical": 1139, + "ctx lh Lat_Fissure post_sgt": 1140, + "ctx lh Medial_wall": 1141, + "ctx lh Pole_occipital": 1142, + "ctx lh Pole_temporal": 1143, + "ctx lh S_calcarine": 1144, + "ctx lh S_central": 1145, + "ctx lh S_central_insula": 1146, + "ctx lh S_cingulate Main_part_and_Intracingulate": 1147, + "ctx lh S_cingulate Marginalis_part": 1148, + "ctx lh S_circular_insula_anterior": 1149, + "ctx lh S_circular_insula_inferior": 1150, + "ctx lh S_circular_insula_superior": 1151, + "ctx lh S_collateral_transverse_ant": 1152, + "ctx lh S_collateral_transverse_post": 1153, + "ctx lh S_frontal_inferior": 1154, + "ctx lh S_frontal_middle": 1155, + "ctx lh S_frontal_superior": 1156, + "ctx lh S_frontomarginal": 1157, + "ctx lh S_intermedius_primus Jensen": 1158, + "ctx lh S_intraparietal and_Parietal_transverse": 1159, + "ctx lh S_occipital_anterior": 1160, + "ctx lh S_occipital_middle_and_Lunatus": 1161, + "ctx lh S_occipital_superior_and_transversalis": 1162, + "ctx lh S_occipito temporal_lateral": 1163, + "ctx lh S_occipito temporal_medial_and_S_Lingual": 1164, + "ctx lh S_orbital H_shapped": 1165, + "ctx lh S_orbital_lateral": 1166, + "ctx lh S_orbital_medial Or_olfactory": 1167, + "ctx lh S_paracentral": 1168, + "ctx lh S_parieto_occipital": 1169, + "ctx lh S_pericallosal": 1170, + "ctx lh S_postcentral": 1171, + "ctx lh S_precentral Inferior part": 1172, + "ctx lh S_precentral Superior part": 1173, + "ctx lh S_subcentral_ant": 1174, + "ctx lh S_subcentral_post": 1175, + "ctx lh S_suborbital": 1176, + "ctx lh S_subparietal": 1177, + "ctx lh S_supracingulate": 1178, + "ctx lh S_temporal_inferior": 1179, + "ctx lh S_temporal_superior": 1180, + "ctx lh S_temporal_transverse": 1181, + + "ctx rh Unknown": 2100, + "ctx rh Corpus_callosum": 2101, + "ctx rh G_and_S_Insula_ONLY_AVERAGE": 2102, + "ctx rh G_cingulate Isthmus": 2103, + "ctx rh G_cingulate Main_part": 2104, + "ctx rh G_cuneus": 2105, + "ctx rh G_frontal_inf Opercular_part": 2106, + "ctx rh G_frontal_inf Orbital_part": 2107, + "ctx rh G_frontal_inf Triangular_part": 2108, + "ctx rh G_frontal_middle": 2109, + "ctx rh G_frontal_superior": 2110, + "ctx rh G_frontomarginal": 2111, + "ctx rh G_insular_long": 2112, + "ctx rh G_insular_short": 2113, + "ctx rh G_and_S_occipital_inferior": 2114, + "ctx rh G_occipital_middle": 2115, + "ctx rh G_occipital_superior": 2116, + "ctx rh G_occipit temp_lat Or_fusiform": 2117, + "ctx rh G_occipit temp_med Lingual_part": 2118, + "ctx rh G_occipit temp_med Parahippocampal_part": 2119, + "ctx rh G_orbital": 2120, + "ctx rh G_paracentral": 2121, + "ctx rh G_parietal_inferior Angular_part": 2122, + "ctx rh G_parietal_inferior Supramarginal_part": 2123, + "ctx rh G_parietal_superior": 2124, + "ctx rh G_postcentral": 2125, + "ctx rh G_precentral": 2126, + "ctx rh G_precuneus": 2127, + "ctx rh G_rectus": 2128, + "ctx rh G_subcallosal": 2129, + "ctx rh G_subcentral": 2130, + "ctx rh G_temporal_inferior": 2131, + "ctx rh G_temporal_middle": 2132, + "ctx rh G_temp_sup G_temp_transv_and_interm_S": 2133, + "ctx rh G_temp_sup Lateral_aspect": 2134, + "ctx rh G_temp_sup Planum_polare": 2135, + "ctx rh G_temp_sup Planum_tempolare": 2136, + "ctx rh G_and_S_transverse_frontopolar": 2137, + "ctx rh Lat_Fissure ant_sgt ramus_horizontal": 2138, + "ctx rh Lat_Fissure ant_sgt ramus_vertical": 2139, + "ctx rh Lat_Fissure post_sgt": 2140, + "ctx rh Medial_wall": 2141, + "ctx rh Pole_occipital": 2142, + "ctx rh Pole_temporal": 2143, + "ctx rh S_calcarine": 2144, + "ctx rh S_central": 2145, + "ctx rh S_central_insula": 2146, + "ctx rh S_cingulate Main_part_and_Intracingulate": 2147, + "ctx rh S_cingulate Marginalis_part": 2148, + "ctx rh S_circular_insula_anterior": 2149, + "ctx rh S_circular_insula_inferior": 2150, + "ctx rh S_circular_insula_superior": 2151, + "ctx rh S_collateral_transverse_ant": 2152, + "ctx rh S_collateral_transverse_post": 2153, + "ctx rh S_frontal_inferior": 2154, + "ctx rh S_frontal_middle": 2155, + "ctx rh S_frontal_superior": 2156, + "ctx rh S_frontomarginal": 2157, + "ctx rh S_intermedius_primus Jensen": 2158, + "ctx rh S_intraparietal and_Parietal_transverse": 2159, + "ctx rh S_occipital_anterior": 2160, + "ctx rh S_occipital_middle_and_Lunatus": 2161, + "ctx rh S_occipital_superior_and_transversalis": 2162, + "ctx rh S_occipito temporal_lateral": 2163, + "ctx rh S_occipito temporal_medial_and_S_Lingual": 2164, + "ctx rh S_orbital H_shapped": 2165, + "ctx rh S_orbital_lateral": 2166, + "ctx rh S_orbital_medial Or_olfactory": 2167, + "ctx rh S_paracentral": 2168, + "ctx rh S_parieto_occipital": 2169, + "ctx rh S_pericallosal": 2170, + "ctx rh S_postcentral": 2171, + "ctx rh S_precentral Inferior part": 2172, + "ctx rh S_precentral Superior part": 2173, + "ctx rh S_subcentral_ant": 2174, + "ctx rh S_subcentral_post": 2175, + "ctx rh S_suborbital": 2176, + "ctx rh S_subparietal": 2177, + "ctx rh S_supracingulate": 2178, + "ctx rh S_temporal_inferior": 2179, + "ctx rh S_temporal_superior": 2180, + "ctx rh S_temporal_transverse": 2181, + + "wm lh Unknown": 3100, + "wm lh Corpus_callosum": 3101, + "wm lh G_and_S_Insula_ONLY_AVERAGE": 3102, + "wm lh G_cingulate Isthmus": 3103, + "wm lh G_cingulate Main_part": 3104, + "wm lh G_cuneus": 3105, + "wm lh G_frontal_inf Opercular_part": 3106, + "wm lh G_frontal_inf Orbital_part": 3107, + "wm lh G_frontal_inf Triangular_part": 3108, + "wm lh G_frontal_middle": 3109, + "wm lh G_frontal_superior": 3110, + "wm lh G_frontomarginal": 3111, + "wm lh G_insular_long": 3112, + "wm lh G_insular_short": 3113, + "wm lh G_and_S_occipital_inferior": 3114, + "wm lh G_occipital_middle": 3115, + "wm lh G_occipital_superior": 3116, + "wm lh G_occipit temp_lat Or_fusiform": 3117, + "wm lh G_occipit temp_med Lingual_part": 3118, + "wm lh G_occipit temp_med Parahippocampal_part": 3119, + "wm lh G_orbital": 3120, + "wm lh G_paracentral": 3121, + "wm lh G_parietal_inferior Angular_part": 3122, + "wm lh G_parietal_inferior Supramarginal_part": 3123, + "wm lh G_parietal_superior": 3124, + "wm lh G_postcentral": 3125, + "wm lh G_precentral": 3126, + "wm lh G_precuneus": 3127, + "wm lh G_rectus": 3128, + "wm lh G_subcallosal": 3129, + "wm lh G_subcentral": 3130, + "wm lh G_temporal_inferior": 3131, + "wm lh G_temporal_middle": 3132, + "wm lh G_temp_sup G_temp_transv_and_interm_S": 3133, + "wm lh G_temp_sup Lateral_aspect": 3134, + "wm lh G_temp_sup Planum_polare": 3135, + "wm lh G_temp_sup Planum_tempolare": 3136, + "wm lh G_and_S_transverse_frontopolar": 3137, + "wm lh Lat_Fissure ant_sgt ramus_horizontal": 3138, + "wm lh Lat_Fissure ant_sgt ramus_vertical": 3139, + "wm lh Lat_Fissure post_sgt": 3140, + "wm lh Medial_wall": 3141, + "wm lh Pole_occipital": 3142, + "wm lh Pole_temporal": 3143, + "wm lh S_calcarine": 3144, + "wm lh S_central": 3145, + "wm lh S_central_insula": 3146, + "wm lh S_cingulate Main_part_and_Intracingulate": 3147, + "wm lh S_cingulate Marginalis_part": 3148, + "wm lh S_circular_insula_anterior": 3149, + "wm lh S_circular_insula_inferior": 3150, + "wm lh S_circular_insula_superior": 3151, + "wm lh S_collateral_transverse_ant": 3152, + "wm lh S_collateral_transverse_post": 3153, + "wm lh S_frontal_inferior": 3154, + "wm lh S_frontal_middle": 3155, + "wm lh S_frontal_superior": 3156, + "wm lh S_frontomarginal": 3157, + "wm lh S_intermedius_primus Jensen": 3158, + "wm lh S_intraparietal and_Parietal_transverse": 3159, + "wm lh S_occipital_anterior": 3160, + "wm lh S_occipital_middle_and_Lunatus": 3161, + "wm lh S_occipital_superior_and_transversalis": 3162, + "wm lh S_occipito temporal_lateral": 3163, + "wm lh S_occipito temporal_medial_and_S_Lingual": 3164, + "wm lh S_orbital H_shapped": 3165, + "wm lh S_orbital_lateral": 3166, + "wm lh S_orbital_medial Or_olfactory": 3167, + "wm lh S_paracentral": 3168, + "wm lh S_parieto_occipital": 3169, + "wm lh S_pericallosal": 3170, + "wm lh S_postcentral": 3171, + "wm lh S_precentral Inferior part": 3172, + "wm lh S_precentral Superior part": 3173, + "wm lh S_subcentral_ant": 3174, + "wm lh S_subcentral_post": 3175, + "wm lh S_suborbital": 3176, + "wm lh S_subparietal": 3177, + "wm lh S_supracingulate": 3178, + "wm lh S_temporal_inferior": 3179, + "wm lh S_temporal_superior": 3180, + "wm lh S_temporal_transverse": 3181, + + "wm rh Unknown": 4100, + "wm rh Corpus_callosum": 4101, + "wm rh G_and_S_Insula_ONLY_AVERAGE": 4102, + "wm rh G_cingulate Isthmus": 4103, + "wm rh G_cingulate Main_part": 4104, + "wm rh G_cuneus": 4105, + "wm rh G_frontal_inf Opercular_part": 4106, + "wm rh G_frontal_inf Orbital_part": 4107, + "wm rh G_frontal_inf Triangular_part": 4108, + "wm rh G_frontal_middle": 4109, + "wm rh G_frontal_superior": 4110, + "wm rh G_frontomarginal": 4111, + "wm rh G_insular_long": 4112, + "wm rh G_insular_short": 4113, + "wm rh G_and_S_occipital_inferior": 4114, + "wm rh G_occipital_middle": 4115, + "wm rh G_occipital_superior": 4116, + "wm rh G_occipit temp_lat Or_fusiform": 4117, + "wm rh G_occipit temp_med Lingual_part": 4118, + "wm rh G_occipit temp_med Parahippocampal_part": 4119, + "wm rh G_orbital": 4120, + "wm rh G_paracentral": 4121, + "wm rh G_parietal_inferior Angular_part": 4122, + "wm rh G_parietal_inferior Supramarginal_part": 4123, + "wm rh G_parietal_superior": 4124, + "wm rh G_postcentral": 4125, + "wm rh G_precentral": 4126, + "wm rh G_precuneus": 4127, + "wm rh G_rectus": 4128, + "wm rh G_subcallosal": 4129, + "wm rh G_subcentral": 4130, + "wm rh G_temporal_inferior": 4131, + "wm rh G_temporal_middle": 4132, + "wm rh G_temp_sup G_temp_transv_and_interm_S": 4133, + "wm rh G_temp_sup Lateral_aspect": 4134, + "wm rh G_temp_sup Planum_polare": 4135, + "wm rh G_temp_sup Planum_tempolare": 4136, + "wm rh G_and_S_transverse_frontopolar": 4137, + "wm rh Lat_Fissure ant_sgt ramus_horizontal": 4138, + "wm rh Lat_Fissure ant_sgt ramus_vertical": 4139, + "wm rh Lat_Fissure post_sgt": 4140, + "wm rh Medial_wall": 4141, + "wm rh Pole_occipital": 4142, + "wm rh Pole_temporal": 4143, + "wm rh S_calcarine": 4144, + "wm rh S_central": 4145, + "wm rh S_central_insula": 4146, + "wm rh S_cingulate Main_part_and_Intracingulate": 4147, + "wm rh S_cingulate Marginalis_part": 4148, + "wm rh S_circular_insula_anterior": 4149, + "wm rh S_circular_insula_inferior": 4150, + "wm rh S_circular_insula_superior": 4151, + "wm rh S_collateral_transverse_ant": 4152, + "wm rh S_collateral_transverse_post": 4153, + "wm rh S_frontal_inferior": 4154, + "wm rh S_frontal_middle": 4155, + "wm rh S_frontal_superior": 4156, + "wm rh S_frontomarginal": 4157, + "wm rh S_intermedius_primus Jensen": 4158, + "wm rh S_intraparietal and_Parietal_transverse": 4159, + "wm rh S_occipital_anterior": 4160, + "wm rh S_occipital_middle_and_Lunatus": 4161, + "wm rh S_occipital_superior_and_transversalis": 4162, + "wm rh S_occipito temporal_lateral": 4163, + "wm rh S_occipito temporal_medial_and_S_Lingual": 4164, + "wm rh S_orbital H_shapped": 4165, + "wm rh S_orbital_lateral": 4166, + "wm rh S_orbital_medial Or_olfactory": 4167, + "wm rh S_paracentral": 4168, + "wm rh S_parieto_occipital": 4169, + "wm rh S_pericallosal": 4170, + "wm rh S_postcentral": 4171, + "wm rh S_precentral Inferior part": 4172, + "wm rh S_precentral Superior part": 4173, + "wm rh S_subcentral_ant": 4174, + "wm rh S_subcentral_post": 4175, + "wm rh S_suborbital": 4176, + "wm rh S_subparietal": 4177, + "wm rh S_supracingulate": 4178, + "wm rh S_temporal_inferior": 4179, + "wm rh S_temporal_superior": 4180, + "wm rh S_temporal_transverse": 4181, + }; +}; diff --git a/tract_querier/tornado_server/js/jquery-1.8.3.min.js b/tract_querier/tornado_server/js/jquery-1.8.3.min.js new file mode 100644 index 0000000..3883779 --- /dev/null +++ b/tract_querier/tornado_server/js/jquery-1.8.3.min.js @@ -0,0 +1,2 @@ +/*! jQuery v1.8.3 jquery.com | jquery.org/license */ +(function(e,t){function _(e){var t=M[e]={};return v.each(e.split(y),function(e,n){t[n]=!0}),t}function H(e,n,r){if(r===t&&e.nodeType===1){var i="data-"+n.replace(P,"-$1").toLowerCase();r=e.getAttribute(i);if(typeof r=="string"){try{r=r==="true"?!0:r==="false"?!1:r==="null"?null:+r+""===r?+r:D.test(r)?v.parseJSON(r):r}catch(s){}v.data(e,n,r)}else r=t}return r}function B(e){var t;for(t in e){if(t==="data"&&v.isEmptyObject(e[t]))continue;if(t!=="toJSON")return!1}return!0}function et(){return!1}function tt(){return!0}function ut(e){return!e||!e.parentNode||e.parentNode.nodeType===11}function at(e,t){do e=e[t];while(e&&e.nodeType!==1);return e}function ft(e,t,n){t=t||0;if(v.isFunction(t))return v.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return v.grep(e,function(e,r){return e===t===n});if(typeof t=="string"){var r=v.grep(e,function(e){return e.nodeType===1});if(it.test(t))return v.filter(t,r,!n);t=v.filter(t,r)}return v.grep(e,function(e,r){return v.inArray(e,t)>=0===n})}function lt(e){var t=ct.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function At(e,t){if(t.nodeType!==1||!v.hasData(e))return;var n,r,i,s=v._data(e),o=v._data(t,s),u=s.events;if(u){delete o.handle,o.events={};for(n in u)for(r=0,i=u[n].length;r").appendTo(i.body),n=t.css("display");t.remove();if(n==="none"||n===""){Pt=i.body.appendChild(Pt||v.extend(i.createElement("iframe"),{frameBorder:0,width:0,height:0}));if(!Ht||!Pt.createElement)Ht=(Pt.contentWindow||Pt.contentDocument).document,Ht.write(""),Ht.close();t=Ht.body.appendChild(Ht.createElement(e)),n=Dt(t,"display"),i.body.removeChild(Pt)}return Wt[e]=n,n}function fn(e,t,n,r){var i;if(v.isArray(t))v.each(t,function(t,i){n||sn.test(e)?r(e,i):fn(e+"["+(typeof i=="object"?t:"")+"]",i,n,r)});else if(!n&&v.type(t)==="object")for(i in t)fn(e+"["+i+"]",t[i],n,r);else r(e,t)}function Cn(e){return function(t,n){typeof t!="string"&&(n=t,t="*");var r,i,s,o=t.toLowerCase().split(y),u=0,a=o.length;if(v.isFunction(n))for(;u)[^>]*$|#([\w\-]*)$)/,E=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,S=/^[\],:{}\s]*$/,x=/(?:^|:|,)(?:\s*\[)+/g,T=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,N=/"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g,C=/^-ms-/,k=/-([\da-z])/gi,L=function(e,t){return(t+"").toUpperCase()},A=function(){i.addEventListener?(i.removeEventListener("DOMContentLoaded",A,!1),v.ready()):i.readyState==="complete"&&(i.detachEvent("onreadystatechange",A),v.ready())},O={};v.fn=v.prototype={constructor:v,init:function(e,n,r){var s,o,u,a;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if(typeof e=="string"){e.charAt(0)==="<"&&e.charAt(e.length-1)===">"&&e.length>=3?s=[null,e,null]:s=w.exec(e);if(s&&(s[1]||!n)){if(s[1])return n=n instanceof v?n[0]:n,a=n&&n.nodeType?n.ownerDocument||n:i,e=v.parseHTML(s[1],a,!0),E.test(s[1])&&v.isPlainObject(n)&&this.attr.call(e,n,!0),v.merge(this,e);o=i.getElementById(s[2]);if(o&&o.parentNode){if(o.id!==s[2])return r.find(e);this.length=1,this[0]=o}return this.context=i,this.selector=e,this}return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e)}return v.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),v.makeArray(e,this))},selector:"",jquery:"1.8.3",length:0,size:function(){return this.length},toArray:function(){return l.call(this)},get:function(e){return e==null?this.toArray():e<0?this[this.length+e]:this[e]},pushStack:function(e,t,n){var r=v.merge(this.constructor(),e);return r.prevObject=this,r.context=this.context,t==="find"?r.selector=this.selector+(this.selector?" ":"")+n:t&&(r.selector=this.selector+"."+t+"("+n+")"),r},each:function(e,t){return v.each(this,e,t)},ready:function(e){return v.ready.promise().done(e),this},eq:function(e){return e=+e,e===-1?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(l.apply(this,arguments),"slice",l.call(arguments).join(","))},map:function(e){return this.pushStack(v.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:[].sort,splice:[].splice},v.fn.init.prototype=v.fn,v.extend=v.fn.extend=function(){var e,n,r,i,s,o,u=arguments[0]||{},a=1,f=arguments.length,l=!1;typeof u=="boolean"&&(l=u,u=arguments[1]||{},a=2),typeof u!="object"&&!v.isFunction(u)&&(u={}),f===a&&(u=this,--a);for(;a0)return;r.resolveWith(i,[v]),v.fn.trigger&&v(i).trigger("ready").off("ready")},isFunction:function(e){return v.type(e)==="function"},isArray:Array.isArray||function(e){return v.type(e)==="array"},isWindow:function(e){return e!=null&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return e==null?String(e):O[h.call(e)]||"object"},isPlainObject:function(e){if(!e||v.type(e)!=="object"||e.nodeType||v.isWindow(e))return!1;try{if(e.constructor&&!p.call(e,"constructor")&&!p.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||p.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw new Error(e)},parseHTML:function(e,t,n){var r;return!e||typeof e!="string"?null:(typeof t=="boolean"&&(n=t,t=0),t=t||i,(r=E.exec(e))?[t.createElement(r[1])]:(r=v.buildFragment([e],t,n?null:[]),v.merge([],(r.cacheable?v.clone(r.fragment):r.fragment).childNodes)))},parseJSON:function(t){if(!t||typeof t!="string")return null;t=v.trim(t);if(e.JSON&&e.JSON.parse)return e.JSON.parse(t);if(S.test(t.replace(T,"@").replace(N,"]").replace(x,"")))return(new Function("return "+t))();v.error("Invalid JSON: "+t)},parseXML:function(n){var r,i;if(!n||typeof n!="string")return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(s){r=t}return(!r||!r.documentElement||r.getElementsByTagName("parsererror").length)&&v.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&g.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(C,"ms-").replace(k,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,n,r){var i,s=0,o=e.length,u=o===t||v.isFunction(e);if(r){if(u){for(i in e)if(n.apply(e[i],r)===!1)break}else for(;s0&&e[0]&&e[a-1]||a===0||v.isArray(e));if(f)for(;u-1)a.splice(n,1),i&&(n<=o&&o--,n<=u&&u--)}),this},has:function(e){return v.inArray(e,a)>-1},empty:function(){return a=[],this},disable:function(){return a=f=n=t,this},disabled:function(){return!a},lock:function(){return f=t,n||c.disable(),this},locked:function(){return!f},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],a&&(!r||f)&&(i?f.push(t):l(t)),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},v.extend({Deferred:function(e){var t=[["resolve","done",v.Callbacks("once memory"),"resolved"],["reject","fail",v.Callbacks("once memory"),"rejected"],["notify","progress",v.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return v.Deferred(function(n){v.each(t,function(t,r){var s=r[0],o=e[t];i[r[1]](v.isFunction(o)?function(){var e=o.apply(this,arguments);e&&v.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[s+"With"](this===i?n:this,[e])}:n[s])}),e=null}).promise()},promise:function(e){return e!=null?v.extend(e,r):r}},i={};return r.pipe=r.then,v.each(t,function(e,s){var o=s[2],u=s[3];r[s[1]]=o.add,u&&o.add(function(){n=u},t[e^1][2].disable,t[2][2].lock),i[s[0]]=o.fire,i[s[0]+"With"]=o.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=l.call(arguments),r=n.length,i=r!==1||e&&v.isFunction(e.promise)?r:0,s=i===1?e:v.Deferred(),o=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?l.call(arguments):r,n===u?s.notifyWith(t,n):--i||s.resolveWith(t,n)}},u,a,f;if(r>1){u=new Array(r),a=new Array(r),f=new Array(r);for(;t
a",n=p.getElementsByTagName("*"),r=p.getElementsByTagName("a")[0];if(!n||!r||!n.length)return{};s=i.createElement("select"),o=s.appendChild(i.createElement("option")),u=p.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:r.getAttribute("href")==="/a",opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:u.value==="on",optSelected:o.selected,getSetAttribute:p.className!=="t",enctype:!!i.createElement("form").enctype,html5Clone:i.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",boxModel:i.compatMode==="CSS1Compat",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},u.checked=!0,t.noCloneChecked=u.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!o.disabled;try{delete p.test}catch(d){t.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",h=function(){t.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick"),p.detachEvent("onclick",h)),u=i.createElement("input"),u.value="t",u.setAttribute("type","radio"),t.radioValue=u.value==="t",u.setAttribute("checked","checked"),u.setAttribute("name","t"),p.appendChild(u),a=i.createDocumentFragment(),a.appendChild(p.lastChild),t.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,t.appendChecked=u.checked,a.removeChild(u),a.appendChild(p);if(p.attachEvent)for(l in{submit:!0,change:!0,focusin:!0})f="on"+l,c=f in p,c||(p.setAttribute(f,"return;"),c=typeof p[f]=="function"),t[l+"Bubbles"]=c;return v(function(){var n,r,s,o,u="padding:0;margin:0;border:0;display:block;overflow:hidden;",a=i.getElementsByTagName("body")[0];if(!a)return;n=i.createElement("div"),n.style.cssText="visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px",a.insertBefore(n,a.firstChild),r=i.createElement("div"),n.appendChild(r),r.innerHTML="
t
",s=r.getElementsByTagName("td"),s[0].style.cssText="padding:0;margin:0;border:0;display:none",c=s[0].offsetHeight===0,s[0].style.display="",s[1].style.display="none",t.reliableHiddenOffsets=c&&s[0].offsetHeight===0,r.innerHTML="",r.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=r.offsetWidth===4,t.doesNotIncludeMarginInBodyOffset=a.offsetTop!==1,e.getComputedStyle&&(t.pixelPosition=(e.getComputedStyle(r,null)||{}).top!=="1%",t.boxSizingReliable=(e.getComputedStyle(r,null)||{width:"4px"}).width==="4px",o=i.createElement("div"),o.style.cssText=r.style.cssText=u,o.style.marginRight=o.style.width="0",r.style.width="1px",r.appendChild(o),t.reliableMarginRight=!parseFloat((e.getComputedStyle(o,null)||{}).marginRight)),typeof r.style.zoom!="undefined"&&(r.innerHTML="",r.style.cssText=u+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=r.offsetWidth===3,r.style.display="block",r.style.overflow="visible",r.innerHTML="
",r.firstChild.style.width="5px",t.shrinkWrapBlocks=r.offsetWidth!==3,n.style.zoom=1),a.removeChild(n),n=r=s=o=null}),a.removeChild(p),n=r=s=o=u=a=p=null,t}();var D=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,P=/([A-Z])/g;v.extend({cache:{},deletedIds:[],uuid:0,expando:"jQuery"+(v.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?v.cache[e[v.expando]]:e[v.expando],!!e&&!B(e)},data:function(e,n,r,i){if(!v.acceptData(e))return;var s,o,u=v.expando,a=typeof n=="string",f=e.nodeType,l=f?v.cache:e,c=f?e[u]:e[u]&&u;if((!c||!l[c]||!i&&!l[c].data)&&a&&r===t)return;c||(f?e[u]=c=v.deletedIds.pop()||v.guid++:c=u),l[c]||(l[c]={},f||(l[c].toJSON=v.noop));if(typeof n=="object"||typeof n=="function")i?l[c]=v.extend(l[c],n):l[c].data=v.extend(l[c].data,n);return s=l[c],i||(s.data||(s.data={}),s=s.data),r!==t&&(s[v.camelCase(n)]=r),a?(o=s[n],o==null&&(o=s[v.camelCase(n)])):o=s,o},removeData:function(e,t,n){if(!v.acceptData(e))return;var r,i,s,o=e.nodeType,u=o?v.cache:e,a=o?e[v.expando]:v.expando;if(!u[a])return;if(t){r=n?u[a]:u[a].data;if(r){v.isArray(t)||(t in r?t=[t]:(t=v.camelCase(t),t in r?t=[t]:t=t.split(" ")));for(i=0,s=t.length;i1,null,!1))},removeData:function(e){return this.each(function(){v.removeData(this,e)})}}),v.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=v._data(e,t),n&&(!r||v.isArray(n)?r=v._data(e,t,v.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=v.queue(e,t),r=n.length,i=n.shift(),s=v._queueHooks(e,t),o=function(){v.dequeue(e,t)};i==="inprogress"&&(i=n.shift(),r--),i&&(t==="fx"&&n.unshift("inprogress"),delete s.stop,i.call(e,o,s)),!r&&s&&s.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return v._data(e,n)||v._data(e,n,{empty:v.Callbacks("once memory").add(function(){v.removeData(e,t+"queue",!0),v.removeData(e,n,!0)})})}}),v.fn.extend({queue:function(e,n){var r=2;return typeof e!="string"&&(n=e,e="fx",r--),arguments.length1)},removeAttr:function(e){return this.each(function(){v.removeAttr(this,e)})},prop:function(e,t){return v.access(this,v.prop,e,t,arguments.length>1)},removeProp:function(e){return e=v.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,s,o,u;if(v.isFunction(e))return this.each(function(t){v(this).addClass(e.call(this,t,this.className))});if(e&&typeof e=="string"){t=e.split(y);for(n=0,r=this.length;n=0)r=r.replace(" "+n[s]+" "," ");i.className=e?v.trim(r):""}}}return this},toggleClass:function(e,t){var n=typeof e,r=typeof t=="boolean";return v.isFunction(e)?this.each(function(n){v(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if(n==="string"){var i,s=0,o=v(this),u=t,a=e.split(y);while(i=a[s++])u=r?u:!o.hasClass(i),o[u?"addClass":"removeClass"](i)}else if(n==="undefined"||n==="boolean")this.className&&v._data(this,"__className__",this.className),this.className=this.className||e===!1?"":v._data(this,"__className__")||""})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;n=0)return!0;return!1},val:function(e){var n,r,i,s=this[0];if(!arguments.length){if(s)return n=v.valHooks[s.type]||v.valHooks[s.nodeName.toLowerCase()],n&&"get"in n&&(r=n.get(s,"value"))!==t?r:(r=s.value,typeof r=="string"?r.replace(R,""):r==null?"":r);return}return i=v.isFunction(e),this.each(function(r){var s,o=v(this);if(this.nodeType!==1)return;i?s=e.call(this,r,o.val()):s=e,s==null?s="":typeof s=="number"?s+="":v.isArray(s)&&(s=v.map(s,function(e){return e==null?"":e+""})),n=v.valHooks[this.type]||v.valHooks[this.nodeName.toLowerCase()];if(!n||!("set"in n)||n.set(this,s,"value")===t)this.value=s})}}),v.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,s=e.type==="select-one"||i<0,o=s?null:[],u=s?i+1:r.length,a=i<0?u:s?i:0;for(;a=0}),n.length||(e.selectedIndex=-1),n}}},attrFn:{},attr:function(e,n,r,i){var s,o,u,a=e.nodeType;if(!e||a===3||a===8||a===2)return;if(i&&v.isFunction(v.fn[n]))return v(e)[n](r);if(typeof e.getAttribute=="undefined")return v.prop(e,n,r);u=a!==1||!v.isXMLDoc(e),u&&(n=n.toLowerCase(),o=v.attrHooks[n]||(X.test(n)?F:j));if(r!==t){if(r===null){v.removeAttr(e,n);return}return o&&"set"in o&&u&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r)}return o&&"get"in o&&u&&(s=o.get(e,n))!==null?s:(s=e.getAttribute(n),s===null?t:s)},removeAttr:function(e,t){var n,r,i,s,o=0;if(t&&e.nodeType===1){r=t.split(y);for(;o=0}})});var $=/^(?:textarea|input|select)$/i,J=/^([^\.]*|)(?:\.(.+)|)$/,K=/(?:^|\s)hover(\.\S+|)\b/,Q=/^key/,G=/^(?:mouse|contextmenu)|click/,Y=/^(?:focusinfocus|focusoutblur)$/,Z=function(e){return v.event.special.hover?e:e.replace(K,"mouseenter$1 mouseleave$1")};v.event={add:function(e,n,r,i,s){var o,u,a,f,l,c,h,p,d,m,g;if(e.nodeType===3||e.nodeType===8||!n||!r||!(o=v._data(e)))return;r.handler&&(d=r,r=d.handler,s=d.selector),r.guid||(r.guid=v.guid++),a=o.events,a||(o.events=a={}),u=o.handle,u||(o.handle=u=function(e){return typeof v=="undefined"||!!e&&v.event.triggered===e.type?t:v.event.dispatch.apply(u.elem,arguments)},u.elem=e),n=v.trim(Z(n)).split(" ");for(f=0;f=0&&(y=y.slice(0,-1),a=!0),y.indexOf(".")>=0&&(b=y.split("."),y=b.shift(),b.sort());if((!s||v.event.customEvent[y])&&!v.event.global[y])return;n=typeof n=="object"?n[v.expando]?n:new v.Event(y,n):new v.Event(y),n.type=y,n.isTrigger=!0,n.exclusive=a,n.namespace=b.join("."),n.namespace_re=n.namespace?new RegExp("(^|\\.)"+b.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,h=y.indexOf(":")<0?"on"+y:"";if(!s){u=v.cache;for(f in u)u[f].events&&u[f].events[y]&&v.event.trigger(n,r,u[f].handle.elem,!0);return}n.result=t,n.target||(n.target=s),r=r!=null?v.makeArray(r):[],r.unshift(n),p=v.event.special[y]||{};if(p.trigger&&p.trigger.apply(s,r)===!1)return;m=[[s,p.bindType||y]];if(!o&&!p.noBubble&&!v.isWindow(s)){g=p.delegateType||y,l=Y.test(g+y)?s:s.parentNode;for(c=s;l;l=l.parentNode)m.push([l,g]),c=l;c===(s.ownerDocument||i)&&m.push([c.defaultView||c.parentWindow||e,g])}for(f=0;f=0:v.find(h,this,null,[s]).length),u[h]&&f.push(c);f.length&&w.push({elem:s,matches:f})}d.length>m&&w.push({elem:this,matches:d.slice(m)});for(r=0;r0?this.on(t,null,e,n):this.trigger(t)},Q.test(t)&&(v.event.fixHooks[t]=v.event.keyHooks),G.test(t)&&(v.event.fixHooks[t]=v.event.mouseHooks)}),function(e,t){function nt(e,t,n,r){n=n||[],t=t||g;var i,s,a,f,l=t.nodeType;if(!e||typeof e!="string")return n;if(l!==1&&l!==9)return[];a=o(t);if(!a&&!r)if(i=R.exec(e))if(f=i[1]){if(l===9){s=t.getElementById(f);if(!s||!s.parentNode)return n;if(s.id===f)return n.push(s),n}else if(t.ownerDocument&&(s=t.ownerDocument.getElementById(f))&&u(t,s)&&s.id===f)return n.push(s),n}else{if(i[2])return S.apply(n,x.call(t.getElementsByTagName(e),0)),n;if((f=i[3])&&Z&&t.getElementsByClassName)return S.apply(n,x.call(t.getElementsByClassName(f),0)),n}return vt(e.replace(j,"$1"),t,n,r,a)}function rt(e){return function(t){var n=t.nodeName.toLowerCase();return n==="input"&&t.type===e}}function it(e){return function(t){var n=t.nodeName.toLowerCase();return(n==="input"||n==="button")&&t.type===e}}function st(e){return N(function(t){return t=+t,N(function(n,r){var i,s=e([],n.length,t),o=s.length;while(o--)n[i=s[o]]&&(n[i]=!(r[i]=n[i]))})})}function ot(e,t,n){if(e===t)return n;var r=e.nextSibling;while(r){if(r===t)return-1;r=r.nextSibling}return 1}function ut(e,t){var n,r,s,o,u,a,f,l=L[d][e+" "];if(l)return t?0:l.slice(0);u=e,a=[],f=i.preFilter;while(u){if(!n||(r=F.exec(u)))r&&(u=u.slice(r[0].length)||u),a.push(s=[]);n=!1;if(r=I.exec(u))s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=r[0].replace(j," ");for(o in i.filter)(r=J[o].exec(u))&&(!f[o]||(r=f[o](r)))&&(s.push(n=new m(r.shift())),u=u.slice(n.length),n.type=o,n.matches=r);if(!n)break}return t?u.length:u?nt.error(e):L(e,a).slice(0)}function at(e,t,r){var i=t.dir,s=r&&t.dir==="parentNode",o=w++;return t.first?function(t,n,r){while(t=t[i])if(s||t.nodeType===1)return e(t,n,r)}:function(t,r,u){if(!u){var a,f=b+" "+o+" ",l=f+n;while(t=t[i])if(s||t.nodeType===1){if((a=t[d])===l)return t.sizset;if(typeof a=="string"&&a.indexOf(f)===0){if(t.sizset)return t}else{t[d]=l;if(e(t,r,u))return t.sizset=!0,t;t.sizset=!1}}}else while(t=t[i])if(s||t.nodeType===1)if(e(t,r,u))return t}}function ft(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function lt(e,t,n,r,i){var s,o=[],u=0,a=e.length,f=t!=null;for(;u-1&&(s[f]=!(o[f]=c))}}else g=lt(g===o?g.splice(d,g.length):g),i?i(null,o,g,a):S.apply(o,g)})}function ht(e){var t,n,r,s=e.length,o=i.relative[e[0].type],u=o||i.relative[" "],a=o?1:0,f=at(function(e){return e===t},u,!0),l=at(function(e){return T.call(t,e)>-1},u,!0),h=[function(e,n,r){return!o&&(r||n!==c)||((t=n).nodeType?f(e,n,r):l(e,n,r))}];for(;a1&&ft(h),a>1&&e.slice(0,a-1).join("").replace(j,"$1"),n,a0,s=e.length>0,o=function(u,a,f,l,h){var p,d,v,m=[],y=0,w="0",x=u&&[],T=h!=null,N=c,C=u||s&&i.find.TAG("*",h&&a.parentNode||a),k=b+=N==null?1:Math.E;T&&(c=a!==g&&a,n=o.el);for(;(p=C[w])!=null;w++){if(s&&p){for(d=0;v=e[d];d++)if(v(p,a,f)){l.push(p);break}T&&(b=k,n=++o.el)}r&&((p=!v&&p)&&y--,u&&x.push(p))}y+=w;if(r&&w!==y){for(d=0;v=t[d];d++)v(x,m,a,f);if(u){if(y>0)while(w--)!x[w]&&!m[w]&&(m[w]=E.call(l));m=lt(m)}S.apply(l,m),T&&!u&&m.length>0&&y+t.length>1&&nt.uniqueSort(l)}return T&&(b=k,c=N),x};return o.el=0,r?N(o):o}function dt(e,t,n){var r=0,i=t.length;for(;r2&&(f=u[0]).type==="ID"&&t.nodeType===9&&!s&&i.relative[u[1].type]){t=i.find.ID(f.matches[0].replace($,""),t,s)[0];if(!t)return n;e=e.slice(u.shift().length)}for(o=J.POS.test(e)?-1:u.length-1;o>=0;o--){f=u[o];if(i.relative[l=f.type])break;if(c=i.find[l])if(r=c(f.matches[0].replace($,""),z.test(u[0].type)&&t.parentNode||t,s)){u.splice(o,1),e=r.length&&u.join("");if(!e)return S.apply(n,x.call(r,0)),n;break}}}return a(e,h)(r,t,s,n,z.test(e)),n}function mt(){}var n,r,i,s,o,u,a,f,l,c,h=!0,p="undefined",d=("sizcache"+Math.random()).replace(".",""),m=String,g=e.document,y=g.documentElement,b=0,w=0,E=[].pop,S=[].push,x=[].slice,T=[].indexOf||function(e){var t=0,n=this.length;for(;ti.cacheLength&&delete e[t.shift()],e[n+" "]=r},e)},k=C(),L=C(),A=C(),O="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+",_=M.replace("w","w#"),D="([*^$|!~]?=)",P="\\["+O+"*("+M+")"+O+"*(?:"+D+O+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+_+")|)|)"+O+"*\\]",H=":("+M+")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:"+P+")|[^:]|\\\\.)*|.*))\\)|)",B=":(even|odd|eq|gt|lt|nth|first|last)(?:\\("+O+"*((?:-\\d)?\\d*)"+O+"*\\)|)(?=[^-]|$)",j=new RegExp("^"+O+"+|((?:^|[^\\\\])(?:\\\\.)*)"+O+"+$","g"),F=new RegExp("^"+O+"*,"+O+"*"),I=new RegExp("^"+O+"*([\\x20\\t\\r\\n\\f>+~])"+O+"*"),q=new RegExp(H),R=/^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/,U=/^:not/,z=/[\x20\t\r\n\f]*[+~]/,W=/:not\($/,X=/h\d/i,V=/input|select|textarea|button/i,$=/\\(?!\\)/g,J={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),NAME:new RegExp("^\\[name=['\"]?("+M+")['\"]?\\]"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+P),PSEUDO:new RegExp("^"+H),POS:new RegExp(B,"i"),CHILD:new RegExp("^:(only|nth|first|last)-child(?:\\("+O+"*(even|odd|(([+-]|)(\\d*)n|)"+O+"*(?:([+-]|)"+O+"*(\\d+)|))"+O+"*\\)|)","i"),needsContext:new RegExp("^"+O+"*[>+~]|"+B,"i")},K=function(e){var t=g.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}},Q=K(function(e){return e.appendChild(g.createComment("")),!e.getElementsByTagName("*").length}),G=K(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==p&&e.firstChild.getAttribute("href")==="#"}),Y=K(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return t!=="boolean"&&t!=="string"}),Z=K(function(e){return e.innerHTML="",!e.getElementsByClassName||!e.getElementsByClassName("e").length?!1:(e.lastChild.className="e",e.getElementsByClassName("e").length===2)}),et=K(function(e){e.id=d+0,e.innerHTML="
",y.insertBefore(e,y.firstChild);var t=g.getElementsByName&&g.getElementsByName(d).length===2+g.getElementsByName(d+0).length;return r=!g.getElementById(d),y.removeChild(e),t});try{x.call(y.childNodes,0)[0].nodeType}catch(tt){x=function(e){var t,n=[];for(;t=this[e];e++)n.push(t);return n}}nt.matches=function(e,t){return nt(e,null,null,t)},nt.matchesSelector=function(e,t){return nt(t,null,null,[e]).length>0},s=nt.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(i===1||i===9||i===11){if(typeof e.textContent=="string")return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=s(e)}else if(i===3||i===4)return e.nodeValue}else for(;t=e[r];r++)n+=s(t);return n},o=nt.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?t.nodeName!=="HTML":!1},u=nt.contains=y.contains?function(e,t){var n=e.nodeType===9?e.documentElement:e,r=t&&t.parentNode;return e===r||!!(r&&r.nodeType===1&&n.contains&&n.contains(r))}:y.compareDocumentPosition?function(e,t){return t&&!!(e.compareDocumentPosition(t)&16)}:function(e,t){while(t=t.parentNode)if(t===e)return!0;return!1},nt.attr=function(e,t){var n,r=o(e);return r||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):r||Y?e.getAttribute(t):(n=e.getAttributeNode(t),n?typeof e[t]=="boolean"?e[t]?t:null:n.specified?n.value:null:null)},i=nt.selectors={cacheLength:50,createPseudo:N,match:J,attrHandle:G?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},find:{ID:r?function(e,t,n){if(typeof t.getElementById!==p&&!n){var r=t.getElementById(e);return r&&r.parentNode?[r]:[]}}:function(e,n,r){if(typeof n.getElementById!==p&&!r){var i=n.getElementById(e);return i?i.id===e||typeof i.getAttributeNode!==p&&i.getAttributeNode("id").value===e?[i]:t:[]}},TAG:Q?function(e,t){if(typeof t.getElementsByTagName!==p)return t.getElementsByTagName(e)}:function(e,t){var n=t.getElementsByTagName(e);if(e==="*"){var r,i=[],s=0;for(;r=n[s];s++)r.nodeType===1&&i.push(r);return i}return n},NAME:et&&function(e,t){if(typeof t.getElementsByName!==p)return t.getElementsByName(name)},CLASS:Z&&function(e,t,n){if(typeof t.getElementsByClassName!==p&&!n)return t.getElementsByClassName(e)}},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace($,""),e[3]=(e[4]||e[5]||"").replace($,""),e[2]==="~="&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),e[1]==="nth"?(e[2]||nt.error(e[0]),e[3]=+(e[3]?e[4]+(e[5]||1):2*(e[2]==="even"||e[2]==="odd")),e[4]=+(e[6]+e[7]||e[2]==="odd")):e[2]&&nt.error(e[0]),e},PSEUDO:function(e){var t,n;if(J.CHILD.test(e[0]))return null;if(e[3])e[2]=e[3];else if(t=e[4])q.test(t)&&(n=ut(t,!0))&&(n=t.indexOf(")",t.length-n)-t.length)&&(t=t.slice(0,n),e[0]=e[0].slice(0,n)),e[2]=t;return e.slice(0,3)}},filter:{ID:r?function(e){return e=e.replace($,""),function(t){return t.getAttribute("id")===e}}:function(e){return e=e.replace($,""),function(t){var n=typeof t.getAttributeNode!==p&&t.getAttributeNode("id");return n&&n.value===e}},TAG:function(e){return e==="*"?function(){return!0}:(e=e.replace($,"").toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[d][e+" "];return t||(t=new RegExp("(^|"+O+")"+e+"("+O+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==p&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r,i){var s=nt.attr(r,e);return s==null?t==="!=":t?(s+="",t==="="?s===n:t==="!="?s!==n:t==="^="?n&&s.indexOf(n)===0:t==="*="?n&&s.indexOf(n)>-1:t==="$="?n&&s.substr(s.length-n.length)===n:t==="~="?(" "+s+" ").indexOf(n)>-1:t==="|="?s===n||s.substr(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r){return e==="nth"?function(e){var t,i,s=e.parentNode;if(n===1&&r===0)return!0;if(s){i=0;for(t=s.firstChild;t;t=t.nextSibling)if(t.nodeType===1){i++;if(e===t)break}}return i-=r,i===n||i%n===0&&i/n>=0}:function(t){var n=t;switch(e){case"only":case"first":while(n=n.previousSibling)if(n.nodeType===1)return!1;if(e==="first")return!0;n=t;case"last":while(n=n.nextSibling)if(n.nodeType===1)return!1;return!0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||nt.error("unsupported pseudo: "+e);return r[d]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?N(function(e,n){var i,s=r(e,t),o=s.length;while(o--)i=T.call(e,s[o]),e[i]=!(n[i]=s[o])}):function(e){return r(e,0,n)}):r}},pseudos:{not:N(function(e){var t=[],n=[],r=a(e.replace(j,"$1"));return r[d]?N(function(e,t,n,i){var s,o=r(e,null,i,[]),u=e.length;while(u--)if(s=o[u])e[u]=!(t[u]=s)}):function(e,i,s){return t[0]=e,r(t,null,s,n),!n.pop()}}),has:N(function(e){return function(t){return nt(e,t).length>0}}),contains:N(function(e){return function(t){return(t.textContent||t.innerText||s(t)).indexOf(e)>-1}}),enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&!!e.checked||t==="option"&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!i.pseudos.empty(e)},empty:function(e){var t;e=e.firstChild;while(e){if(e.nodeName>"@"||(t=e.nodeType)===3||t===4)return!1;e=e.nextSibling}return!0},header:function(e){return X.test(e.nodeName)},text:function(e){var t,n;return e.nodeName.toLowerCase()==="input"&&(t=e.type)==="text"&&((n=e.getAttribute("type"))==null||n.toLowerCase()===t)},radio:rt("radio"),checkbox:rt("checkbox"),file:rt("file"),password:rt("password"),image:rt("image"),submit:it("submit"),reset:it("reset"),button:function(e){var t=e.nodeName.toLowerCase();return t==="input"&&e.type==="button"||t==="button"},input:function(e){return V.test(e.nodeName)},focus:function(e){var t=e.ownerDocument;return e===t.activeElement&&(!t.hasFocus||t.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},active:function(e){return e===e.ownerDocument.activeElement},first:st(function(){return[0]}),last:st(function(e,t){return[t-1]}),eq:st(function(e,t,n){return[n<0?n+t:n]}),even:st(function(e,t){for(var n=0;n=0;)e.push(r);return e}),gt:st(function(e,t,n){for(var r=n<0?n+t:n;++r",e.querySelectorAll("[selected]").length||i.push("\\["+O+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||i.push(":checked")}),K(function(e){e.innerHTML="

",e.querySelectorAll("[test^='']").length&&i.push("[*^$]="+O+"*(?:\"\"|'')"),e.innerHTML="",e.querySelectorAll(":enabled").length||i.push(":enabled",":disabled")}),i=new RegExp(i.join("|")),vt=function(e,r,s,o,u){if(!o&&!u&&!i.test(e)){var a,f,l=!0,c=d,h=r,p=r.nodeType===9&&e;if(r.nodeType===1&&r.nodeName.toLowerCase()!=="object"){a=ut(e),(l=r.getAttribute("id"))?c=l.replace(n,"\\$&"):r.setAttribute("id",c),c="[id='"+c+"'] ",f=a.length;while(f--)a[f]=c+a[f].join("");h=z.test(e)&&r.parentNode||r,p=a.join(",")}if(p)try{return S.apply(s,x.call(h.querySelectorAll(p),0)),s}catch(v){}finally{l||r.removeAttribute("id")}}return t(e,r,s,o,u)},u&&(K(function(t){e=u.call(t,"div");try{u.call(t,"[test!='']:sizzle"),s.push("!=",H)}catch(n){}}),s=new RegExp(s.join("|")),nt.matchesSelector=function(t,n){n=n.replace(r,"='$1']");if(!o(t)&&!s.test(n)&&!i.test(n))try{var a=u.call(t,n);if(a||e||t.document&&t.document.nodeType!==11)return a}catch(f){}return nt(n,null,null,[t]).length>0})}(),i.pseudos.nth=i.pseudos.eq,i.filters=mt.prototype=i.pseudos,i.setFilters=new mt,nt.attr=v.attr,v.find=nt,v.expr=nt.selectors,v.expr[":"]=v.expr.pseudos,v.unique=nt.uniqueSort,v.text=nt.getText,v.isXMLDoc=nt.isXML,v.contains=nt.contains}(e);var nt=/Until$/,rt=/^(?:parents|prev(?:Until|All))/,it=/^.[^:#\[\.,]*$/,st=v.expr.match.needsContext,ot={children:!0,contents:!0,next:!0,prev:!0};v.fn.extend({find:function(e){var t,n,r,i,s,o,u=this;if(typeof e!="string")return v(e).filter(function(){for(t=0,n=u.length;t0)for(i=r;i=0:v.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,s=[],o=st.test(e)||typeof e!="string"?v(e,t||this.context):0;for(;r-1:v.find.matchesSelector(n,e)){s.push(n);break}n=n.parentNode}}return s=s.length>1?v.unique(s):s,this.pushStack(s,"closest",e)},index:function(e){return e?typeof e=="string"?v.inArray(this[0],v(e)):v.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var n=typeof e=="string"?v(e,t):v.makeArray(e&&e.nodeType?[e]:e),r=v.merge(this.get(),n);return this.pushStack(ut(n[0])||ut(r[0])?r:v.unique(r))},addBack:function(e){return this.add(e==null?this.prevObject:this.prevObject.filter(e))}}),v.fn.andSelf=v.fn.addBack,v.each({parent:function(e){var t=e.parentNode;return t&&t.nodeType!==11?t:null},parents:function(e){return v.dir(e,"parentNode")},parentsUntil:function(e,t,n){return v.dir(e,"parentNode",n)},next:function(e){return at(e,"nextSibling")},prev:function(e){return at(e,"previousSibling")},nextAll:function(e){return v.dir(e,"nextSibling")},prevAll:function(e){return v.dir(e,"previousSibling")},nextUntil:function(e,t,n){return v.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return v.dir(e,"previousSibling",n)},siblings:function(e){return v.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return v.sibling(e.firstChild)},contents:function(e){return v.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:v.merge([],e.childNodes)}},function(e,t){v.fn[e]=function(n,r){var i=v.map(this,t,n);return nt.test(e)||(r=n),r&&typeof r=="string"&&(i=v.filter(r,i)),i=this.length>1&&!ot[e]?v.unique(i):i,this.length>1&&rt.test(e)&&(i=i.reverse()),this.pushStack(i,e,l.call(arguments).join(","))}}),v.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),t.length===1?v.find.matchesSelector(t[0],e)?[t[0]]:[]:v.find.matches(e,t)},dir:function(e,n,r){var i=[],s=e[n];while(s&&s.nodeType!==9&&(r===t||s.nodeType!==1||!v(s).is(r)))s.nodeType===1&&i.push(s),s=s[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)e.nodeType===1&&e!==t&&n.push(e);return n}});var ct="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",ht=/ jQuery\d+="(?:null|\d+)"/g,pt=/^\s+/,dt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,vt=/<([\w:]+)/,mt=/]","i"),Et=/^(?:checkbox|radio)$/,St=/checked\s*(?:[^=]|=\s*.checked.)/i,xt=/\/(java|ecma)script/i,Tt=/^\s*\s*$/g,Nt={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},Ct=lt(i),kt=Ct.appendChild(i.createElement("div"));Nt.optgroup=Nt.option,Nt.tbody=Nt.tfoot=Nt.colgroup=Nt.caption=Nt.thead,Nt.th=Nt.td,v.support.htmlSerialize||(Nt._default=[1,"X
","
"]),v.fn.extend({text:function(e){return v.access(this,function(e){return e===t?v.text(this):this.empty().append((this[0]&&this[0].ownerDocument||i).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(v.isFunction(e))return this.each(function(t){v(this).wrapAll(e.call(this,t))});if(this[0]){var t=v(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&e.firstChild.nodeType===1)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return v.isFunction(e)?this.each(function(t){v(this).wrapInner(e.call(this,t))}):this.each(function(){var t=v(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=v.isFunction(e);return this.each(function(n){v(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){v.nodeName(this,"body")||v(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(this.nodeType===1||this.nodeType===11)&&this.insertBefore(e,this.firstChild)})},before:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(e,this),"before",this.selector)}},after:function(){if(!ut(this[0]))return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=v.clean(arguments);return this.pushStack(v.merge(this,e),"after",this.selector)}},remove:function(e,t){var n,r=0;for(;(n=this[r])!=null;r++)if(!e||v.filter(e,[n]).length)!t&&n.nodeType===1&&(v.cleanData(n.getElementsByTagName("*")),v.cleanData([n])),n.parentNode&&n.parentNode.removeChild(n);return this},empty:function(){var e,t=0;for(;(e=this[t])!=null;t++){e.nodeType===1&&v.cleanData(e.getElementsByTagName("*"));while(e.firstChild)e.removeChild(e.firstChild)}return this},clone:function(e,t){return e=e==null?!1:e,t=t==null?e:t,this.map(function(){return v.clone(this,e,t)})},html:function(e){return v.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return n.nodeType===1?n.innerHTML.replace(ht,""):t;if(typeof e=="string"&&!yt.test(e)&&(v.support.htmlSerialize||!wt.test(e))&&(v.support.leadingWhitespace||!pt.test(e))&&!Nt[(vt.exec(e)||["",""])[1].toLowerCase()]){e=e.replace(dt,"<$1>");try{for(;r1&&typeof f=="string"&&St.test(f))return this.each(function(){v(this).domManip(e,n,r)});if(v.isFunction(f))return this.each(function(i){var s=v(this);e[0]=f.call(this,i,n?s.html():t),s.domManip(e,n,r)});if(this[0]){i=v.buildFragment(e,this,l),o=i.fragment,s=o.firstChild,o.childNodes.length===1&&(o=s);if(s){n=n&&v.nodeName(s,"tr");for(u=i.cacheable||c-1;a0?this.clone(!0):this).get(),v(o[i])[t](r),s=s.concat(r);return this.pushStack(s,e,o.selector)}}),v.extend({clone:function(e,t,n){var r,i,s,o;v.support.html5Clone||v.isXMLDoc(e)||!wt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(kt.innerHTML=e.outerHTML,kt.removeChild(o=kt.firstChild));if((!v.support.noCloneEvent||!v.support.noCloneChecked)&&(e.nodeType===1||e.nodeType===11)&&!v.isXMLDoc(e)){Ot(e,o),r=Mt(e),i=Mt(o);for(s=0;r[s];++s)i[s]&&Ot(r[s],i[s])}if(t){At(e,o);if(n){r=Mt(e),i=Mt(o);for(s=0;r[s];++s)At(r[s],i[s])}}return r=i=null,o},clean:function(e,t,n,r){var s,o,u,a,f,l,c,h,p,d,m,g,y=t===i&&Ct,b=[];if(!t||typeof t.createDocumentFragment=="undefined")t=i;for(s=0;(u=e[s])!=null;s++){typeof u=="number"&&(u+="");if(!u)continue;if(typeof u=="string")if(!gt.test(u))u=t.createTextNode(u);else{y=y||lt(t),c=t.createElement("div"),y.appendChild(c),u=u.replace(dt,"<$1>"),a=(vt.exec(u)||["",""])[1].toLowerCase(),f=Nt[a]||Nt._default,l=f[0],c.innerHTML=f[1]+u+f[2];while(l--)c=c.lastChild;if(!v.support.tbody){h=mt.test(u),p=a==="table"&&!h?c.firstChild&&c.firstChild.childNodes:f[1]===""&&!h?c.childNodes:[];for(o=p.length-1;o>=0;--o)v.nodeName(p[o],"tbody")&&!p[o].childNodes.length&&p[o].parentNode.removeChild(p[o])}!v.support.leadingWhitespace&&pt.test(u)&&c.insertBefore(t.createTextNode(pt.exec(u)[0]),c.firstChild),u=c.childNodes,c.parentNode.removeChild(c)}u.nodeType?b.push(u):v.merge(b,u)}c&&(u=c=y=null);if(!v.support.appendChecked)for(s=0;(u=b[s])!=null;s++)v.nodeName(u,"input")?_t(u):typeof u.getElementsByTagName!="undefined"&&v.grep(u.getElementsByTagName("input"),_t);if(n){m=function(e){if(!e.type||xt.test(e.type))return r?r.push(e.parentNode?e.parentNode.removeChild(e):e):n.appendChild(e)};for(s=0;(u=b[s])!=null;s++)if(!v.nodeName(u,"script")||!m(u))n.appendChild(u),typeof u.getElementsByTagName!="undefined"&&(g=v.grep(v.merge([],u.getElementsByTagName("script")),m),b.splice.apply(b,[s+1,0].concat(g)),s+=g.length)}return b},cleanData:function(e,t){var n,r,i,s,o=0,u=v.expando,a=v.cache,f=v.support.deleteExpando,l=v.event.special;for(;(i=e[o])!=null;o++)if(t||v.acceptData(i)){r=i[u],n=r&&a[r];if(n){if(n.events)for(s in n.events)l[s]?v.event.remove(i,s):v.removeEvent(i,s,n.handle);a[r]&&(delete a[r],f?delete i[u]:i.removeAttribute?i.removeAttribute(u):i[u]=null,v.deletedIds.push(r))}}}}),function(){var e,t;v.uaMatch=function(e){e=e.toLowerCase();var t=/(chrome)[ \/]([\w.]+)/.exec(e)||/(webkit)[ \/]([\w.]+)/.exec(e)||/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(e)||/(msie) ([\w.]+)/.exec(e)||e.indexOf("compatible")<0&&/(mozilla)(?:.*? rv:([\w.]+)|)/.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},e=v.uaMatch(o.userAgent),t={},e.browser&&(t[e.browser]=!0,t.version=e.version),t.chrome?t.webkit=!0:t.webkit&&(t.safari=!0),v.browser=t,v.sub=function(){function e(t,n){return new e.fn.init(t,n)}v.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(r,i){return i&&i instanceof v&&!(i instanceof e)&&(i=e(i)),v.fn.init.call(this,r,i,t)},e.fn.init.prototype=e.fn;var t=e(i);return e}}();var Dt,Pt,Ht,Bt=/alpha\([^)]*\)/i,jt=/opacity=([^)]*)/,Ft=/^(top|right|bottom|left)$/,It=/^(none|table(?!-c[ea]).+)/,qt=/^margin/,Rt=new RegExp("^("+m+")(.*)$","i"),Ut=new RegExp("^("+m+")(?!px)[a-z%]+$","i"),zt=new RegExp("^([-+])=("+m+")","i"),Wt={BODY:"block"},Xt={position:"absolute",visibility:"hidden",display:"block"},Vt={letterSpacing:0,fontWeight:400},$t=["Top","Right","Bottom","Left"],Jt=["Webkit","O","Moz","ms"],Kt=v.fn.toggle;v.fn.extend({css:function(e,n){return v.access(this,function(e,n,r){return r!==t?v.style(e,n,r):v.css(e,n)},e,n,arguments.length>1)},show:function(){return Yt(this,!0)},hide:function(){return Yt(this)},toggle:function(e,t){var n=typeof e=="boolean";return v.isFunction(e)&&v.isFunction(t)?Kt.apply(this,arguments):this.each(function(){(n?e:Gt(this))?v(this).show():v(this).hide()})}}),v.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Dt(e,"opacity");return n===""?"1":n}}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":v.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(!e||e.nodeType===3||e.nodeType===8||!e.style)return;var s,o,u,a=v.camelCase(n),f=e.style;n=v.cssProps[a]||(v.cssProps[a]=Qt(f,a)),u=v.cssHooks[n]||v.cssHooks[a];if(r===t)return u&&"get"in u&&(s=u.get(e,!1,i))!==t?s:f[n];o=typeof r,o==="string"&&(s=zt.exec(r))&&(r=(s[1]+1)*s[2]+parseFloat(v.css(e,n)),o="number");if(r==null||o==="number"&&isNaN(r))return;o==="number"&&!v.cssNumber[a]&&(r+="px");if(!u||!("set"in u)||(r=u.set(e,r,i))!==t)try{f[n]=r}catch(l){}},css:function(e,n,r,i){var s,o,u,a=v.camelCase(n);return n=v.cssProps[a]||(v.cssProps[a]=Qt(e.style,a)),u=v.cssHooks[n]||v.cssHooks[a],u&&"get"in u&&(s=u.get(e,!0,i)),s===t&&(s=Dt(e,n)),s==="normal"&&n in Vt&&(s=Vt[n]),r||i!==t?(o=parseFloat(s),r||v.isNumeric(o)?o||0:s):s},swap:function(e,t,n){var r,i,s={};for(i in t)s[i]=e.style[i],e.style[i]=t[i];r=n.call(e);for(i in t)e.style[i]=s[i];return r}}),e.getComputedStyle?Dt=function(t,n){var r,i,s,o,u=e.getComputedStyle(t,null),a=t.style;return u&&(r=u.getPropertyValue(n)||u[n],r===""&&!v.contains(t.ownerDocument,t)&&(r=v.style(t,n)),Ut.test(r)&&qt.test(n)&&(i=a.width,s=a.minWidth,o=a.maxWidth,a.minWidth=a.maxWidth=a.width=r,r=u.width,a.width=i,a.minWidth=s,a.maxWidth=o)),r}:i.documentElement.currentStyle&&(Dt=function(e,t){var n,r,i=e.currentStyle&&e.currentStyle[t],s=e.style;return i==null&&s&&s[t]&&(i=s[t]),Ut.test(i)&&!Ft.test(t)&&(n=s.left,r=e.runtimeStyle&&e.runtimeStyle.left,r&&(e.runtimeStyle.left=e.currentStyle.left),s.left=t==="fontSize"?"1em":i,i=s.pixelLeft+"px",s.left=n,r&&(e.runtimeStyle.left=r)),i===""?"auto":i}),v.each(["height","width"],function(e,t){v.cssHooks[t]={get:function(e,n,r){if(n)return e.offsetWidth===0&&It.test(Dt(e,"display"))?v.swap(e,Xt,function(){return tn(e,t,r)}):tn(e,t,r)},set:function(e,n,r){return Zt(e,n,r?en(e,t,r,v.support.boxSizing&&v.css(e,"boxSizing")==="border-box"):0)}}}),v.support.opacity||(v.cssHooks.opacity={get:function(e,t){return jt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=v.isNumeric(t)?"alpha(opacity="+t*100+")":"",s=r&&r.filter||n.filter||"";n.zoom=1;if(t>=1&&v.trim(s.replace(Bt,""))===""&&n.removeAttribute){n.removeAttribute("filter");if(r&&!r.filter)return}n.filter=Bt.test(s)?s.replace(Bt,i):s+" "+i}}),v(function(){v.support.reliableMarginRight||(v.cssHooks.marginRight={get:function(e,t){return v.swap(e,{display:"inline-block"},function(){if(t)return Dt(e,"marginRight")})}}),!v.support.pixelPosition&&v.fn.position&&v.each(["top","left"],function(e,t){v.cssHooks[t]={get:function(e,n){if(n){var r=Dt(e,t);return Ut.test(r)?v(e).position()[t]+"px":r}}}})}),v.expr&&v.expr.filters&&(v.expr.filters.hidden=function(e){return e.offsetWidth===0&&e.offsetHeight===0||!v.support.reliableHiddenOffsets&&(e.style&&e.style.display||Dt(e,"display"))==="none"},v.expr.filters.visible=function(e){return!v.expr.filters.hidden(e)}),v.each({margin:"",padding:"",border:"Width"},function(e,t){v.cssHooks[e+t]={expand:function(n){var r,i=typeof n=="string"?n.split(" "):[n],s={};for(r=0;r<4;r++)s[e+$t[r]+t]=i[r]||i[r-2]||i[0];return s}},qt.test(e)||(v.cssHooks[e+t].set=Zt)});var rn=/%20/g,sn=/\[\]$/,on=/\r?\n/g,un=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,an=/^(?:select|textarea)/i;v.fn.extend({serialize:function(){return v.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?v.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||an.test(this.nodeName)||un.test(this.type))}).map(function(e,t){var n=v(this).val();return n==null?null:v.isArray(n)?v.map(n,function(e,n){return{name:t.name,value:e.replace(on,"\r\n")}}):{name:t.name,value:n.replace(on,"\r\n")}}).get()}}),v.param=function(e,n){var r,i=[],s=function(e,t){t=v.isFunction(t)?t():t==null?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};n===t&&(n=v.ajaxSettings&&v.ajaxSettings.traditional);if(v.isArray(e)||e.jquery&&!v.isPlainObject(e))v.each(e,function(){s(this.name,this.value)});else for(r in e)fn(r,e[r],n,s);return i.join("&").replace(rn,"+")};var ln,cn,hn=/#.*$/,pn=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,dn=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,vn=/^(?:GET|HEAD)$/,mn=/^\/\//,gn=/\?/,yn=/)<[^<]*)*<\/script>/gi,bn=/([?&])_=[^&]*/,wn=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,En=v.fn.load,Sn={},xn={},Tn=["*/"]+["*"];try{cn=s.href}catch(Nn){cn=i.createElement("a"),cn.href="",cn=cn.href}ln=wn.exec(cn.toLowerCase())||[],v.fn.load=function(e,n,r){if(typeof e!="string"&&En)return En.apply(this,arguments);if(!this.length)return this;var i,s,o,u=this,a=e.indexOf(" ");return a>=0&&(i=e.slice(a,e.length),e=e.slice(0,a)),v.isFunction(n)?(r=n,n=t):n&&typeof n=="object"&&(s="POST"),v.ajax({url:e,type:s,dataType:"html",data:n,complete:function(e,t){r&&u.each(r,o||[e.responseText,t,e])}}).done(function(e){o=arguments,u.html(i?v("
").append(e.replace(yn,"")).find(i):e)}),this},v.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){v.fn[t]=function(e){return this.on(t,e)}}),v.each(["get","post"],function(e,n){v[n]=function(e,r,i,s){return v.isFunction(r)&&(s=s||i,i=r,r=t),v.ajax({type:n,url:e,data:r,success:i,dataType:s})}}),v.extend({getScript:function(e,n){return v.get(e,t,n,"script")},getJSON:function(e,t,n){return v.get(e,t,n,"json")},ajaxSetup:function(e,t){return t?Ln(e,v.ajaxSettings):(t=e,e=v.ajaxSettings),Ln(e,t),e},ajaxSettings:{url:cn,isLocal:dn.test(ln[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":Tn},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":v.parseJSON,"text xml":v.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:Cn(Sn),ajaxTransport:Cn(xn),ajax:function(e,n){function T(e,n,s,a){var l,y,b,w,S,T=n;if(E===2)return;E=2,u&&clearTimeout(u),o=t,i=a||"",x.readyState=e>0?4:0,s&&(w=An(c,x,s));if(e>=200&&e<300||e===304)c.ifModified&&(S=x.getResponseHeader("Last-Modified"),S&&(v.lastModified[r]=S),S=x.getResponseHeader("Etag"),S&&(v.etag[r]=S)),e===304?(T="notmodified",l=!0):(l=On(c,w),T=l.state,y=l.data,b=l.error,l=!b);else{b=T;if(!T||e)T="error",e<0&&(e=0)}x.status=e,x.statusText=(n||T)+"",l?d.resolveWith(h,[y,T,x]):d.rejectWith(h,[x,T,b]),x.statusCode(g),g=t,f&&p.trigger("ajax"+(l?"Success":"Error"),[x,c,l?y:b]),m.fireWith(h,[x,T]),f&&(p.trigger("ajaxComplete",[x,c]),--v.active||v.event.trigger("ajaxStop"))}typeof e=="object"&&(n=e,e=t),n=n||{};var r,i,s,o,u,a,f,l,c=v.ajaxSetup({},n),h=c.context||c,p=h!==c&&(h.nodeType||h instanceof v)?v(h):v.event,d=v.Deferred(),m=v.Callbacks("once memory"),g=c.statusCode||{},b={},w={},E=0,S="canceled",x={readyState:0,setRequestHeader:function(e,t){if(!E){var n=e.toLowerCase();e=w[n]=w[n]||e,b[e]=t}return this},getAllResponseHeaders:function(){return E===2?i:null},getResponseHeader:function(e){var n;if(E===2){if(!s){s={};while(n=pn.exec(i))s[n[1].toLowerCase()]=n[2]}n=s[e.toLowerCase()]}return n===t?null:n},overrideMimeType:function(e){return E||(c.mimeType=e),this},abort:function(e){return e=e||S,o&&o.abort(e),T(0,e),this}};d.promise(x),x.success=x.done,x.error=x.fail,x.complete=m.add,x.statusCode=function(e){if(e){var t;if(E<2)for(t in e)g[t]=[g[t],e[t]];else t=e[x.status],x.always(t)}return this},c.url=((e||c.url)+"").replace(hn,"").replace(mn,ln[1]+"//"),c.dataTypes=v.trim(c.dataType||"*").toLowerCase().split(y),c.crossDomain==null&&(a=wn.exec(c.url.toLowerCase()),c.crossDomain=!(!a||a[1]===ln[1]&&a[2]===ln[2]&&(a[3]||(a[1]==="http:"?80:443))==(ln[3]||(ln[1]==="http:"?80:443)))),c.data&&c.processData&&typeof c.data!="string"&&(c.data=v.param(c.data,c.traditional)),kn(Sn,c,n,x);if(E===2)return x;f=c.global,c.type=c.type.toUpperCase(),c.hasContent=!vn.test(c.type),f&&v.active++===0&&v.event.trigger("ajaxStart");if(!c.hasContent){c.data&&(c.url+=(gn.test(c.url)?"&":"?")+c.data,delete c.data),r=c.url;if(c.cache===!1){var N=v.now(),C=c.url.replace(bn,"$1_="+N);c.url=C+(C===c.url?(gn.test(c.url)?"&":"?")+"_="+N:"")}}(c.data&&c.hasContent&&c.contentType!==!1||n.contentType)&&x.setRequestHeader("Content-Type",c.contentType),c.ifModified&&(r=r||c.url,v.lastModified[r]&&x.setRequestHeader("If-Modified-Since",v.lastModified[r]),v.etag[r]&&x.setRequestHeader("If-None-Match",v.etag[r])),x.setRequestHeader("Accept",c.dataTypes[0]&&c.accepts[c.dataTypes[0]]?c.accepts[c.dataTypes[0]]+(c.dataTypes[0]!=="*"?", "+Tn+"; q=0.01":""):c.accepts["*"]);for(l in c.headers)x.setRequestHeader(l,c.headers[l]);if(!c.beforeSend||c.beforeSend.call(h,x,c)!==!1&&E!==2){S="abort";for(l in{success:1,error:1,complete:1})x[l](c[l]);o=kn(xn,c,n,x);if(!o)T(-1,"No Transport");else{x.readyState=1,f&&p.trigger("ajaxSend",[x,c]),c.async&&c.timeout>0&&(u=setTimeout(function(){x.abort("timeout")},c.timeout));try{E=1,o.send(b,T)}catch(k){if(!(E<2))throw k;T(-1,k)}}return x}return x.abort()},active:0,lastModified:{},etag:{}});var Mn=[],_n=/\?/,Dn=/(=)\?(?=&|$)|\?\?/,Pn=v.now();v.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Mn.pop()||v.expando+"_"+Pn++;return this[e]=!0,e}}),v.ajaxPrefilter("json jsonp",function(n,r,i){var s,o,u,a=n.data,f=n.url,l=n.jsonp!==!1,c=l&&Dn.test(f),h=l&&!c&&typeof a=="string"&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Dn.test(a);if(n.dataTypes[0]==="jsonp"||c||h)return s=n.jsonpCallback=v.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,o=e[s],c?n.url=f.replace(Dn,"$1"+s):h?n.data=a.replace(Dn,"$1"+s):l&&(n.url+=(_n.test(f)?"&":"?")+n.jsonp+"="+s),n.converters["script json"]=function(){return u||v.error(s+" was not called"),u[0]},n.dataTypes[0]="json",e[s]=function(){u=arguments},i.always(function(){e[s]=o,n[s]&&(n.jsonpCallback=r.jsonpCallback,Mn.push(s)),u&&v.isFunction(o)&&o(u[0]),u=o=t}),"script"}),v.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return v.globalEval(e),e}}}),v.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),v.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=i.head||i.getElementsByTagName("head")[0]||i.documentElement;return{send:function(s,o){n=i.createElement("script"),n.async="async",e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,i){if(i||!n.readyState||/loaded|complete/.test(n.readyState))n.onload=n.onreadystatechange=null,r&&n.parentNode&&r.removeChild(n),n=t,i||o(200,"success")},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(0,1)}}}});var Hn,Bn=e.ActiveXObject?function(){for(var e in Hn)Hn[e](0,1)}:!1,jn=0;v.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&Fn()||In()}:Fn,function(e){v.extend(v.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(v.ajaxSettings.xhr()),v.support.ajax&&v.ajaxTransport(function(n){if(!n.crossDomain||v.support.cors){var r;return{send:function(i,s){var o,u,a=n.xhr();n.username?a.open(n.type,n.url,n.async,n.username,n.password):a.open(n.type,n.url,n.async);if(n.xhrFields)for(u in n.xhrFields)a[u]=n.xhrFields[u];n.mimeType&&a.overrideMimeType&&a.overrideMimeType(n.mimeType),!n.crossDomain&&!i["X-Requested-With"]&&(i["X-Requested-With"]="XMLHttpRequest");try{for(u in i)a.setRequestHeader(u,i[u])}catch(f){}a.send(n.hasContent&&n.data||null),r=function(e,i){var u,f,l,c,h;try{if(r&&(i||a.readyState===4)){r=t,o&&(a.onreadystatechange=v.noop,Bn&&delete Hn[o]);if(i)a.readyState!==4&&a.abort();else{u=a.status,l=a.getAllResponseHeaders(),c={},h=a.responseXML,h&&h.documentElement&&(c.xml=h);try{c.text=a.responseText}catch(p){}try{f=a.statusText}catch(p){f=""}!u&&n.isLocal&&!n.crossDomain?u=c.text?200:404:u===1223&&(u=204)}}}catch(d){i||s(-1,d)}c&&s(u,f,c,l)},n.async?a.readyState===4?setTimeout(r,0):(o=++jn,Bn&&(Hn||(Hn={},v(e).unload(Bn)),Hn[o]=r),a.onreadystatechange=r):r()},abort:function(){r&&r(0,1)}}}});var qn,Rn,Un=/^(?:toggle|show|hide)$/,zn=new RegExp("^(?:([-+])=|)("+m+")([a-z%]*)$","i"),Wn=/queueHooks$/,Xn=[Gn],Vn={"*":[function(e,t){var n,r,i=this.createTween(e,t),s=zn.exec(t),o=i.cur(),u=+o||0,a=1,f=20;if(s){n=+s[2],r=s[3]||(v.cssNumber[e]?"":"px");if(r!=="px"&&u){u=v.css(i.elem,e,!0)||n||1;do a=a||".5",u/=a,v.style(i.elem,e,u+r);while(a!==(a=i.cur()/o)&&a!==1&&--f)}i.unit=r,i.start=u,i.end=s[1]?u+(s[1]+1)*n:n}return i}]};v.Animation=v.extend(Kn,{tweener:function(e,t){v.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;r-1,f={},l={},c,h;a?(l=i.position(),c=l.top,h=l.left):(c=parseFloat(o)||0,h=parseFloat(u)||0),v.isFunction(t)&&(t=t.call(e,n,s)),t.top!=null&&(f.top=t.top-s.top+c),t.left!=null&&(f.left=t.left-s.left+h),"using"in t?t.using.call(e,f):i.css(f)}},v.fn.extend({position:function(){if(!this[0])return;var e=this[0],t=this.offsetParent(),n=this.offset(),r=er.test(t[0].nodeName)?{top:0,left:0}:t.offset();return n.top-=parseFloat(v.css(e,"marginTop"))||0,n.left-=parseFloat(v.css(e,"marginLeft"))||0,r.top+=parseFloat(v.css(t[0],"borderTopWidth"))||0,r.left+=parseFloat(v.css(t[0],"borderLeftWidth"))||0,{top:n.top-r.top,left:n.left-r.left}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||i.body;while(e&&!er.test(e.nodeName)&&v.css(e,"position")==="static")e=e.offsetParent;return e||i.body})}}),v.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);v.fn[e]=function(i){return v.access(this,function(e,i,s){var o=tr(e);if(s===t)return o?n in o?o[n]:o.document.documentElement[i]:e[i];o?o.scrollTo(r?v(o).scrollLeft():s,r?s:v(o).scrollTop()):e[i]=s},e,i,arguments.length,null)}}),v.each({Height:"height",Width:"width"},function(e,n){v.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){v.fn[i]=function(i,s){var o=arguments.length&&(r||typeof i!="boolean"),u=r||(i===!0||s===!0?"margin":"border");return v.access(this,function(n,r,i){var s;return v.isWindow(n)?n.document.documentElement["client"+e]:n.nodeType===9?(s=n.documentElement,Math.max(n.body["scroll"+e],s["scroll"+e],n.body["offset"+e],s["offset"+e],s["client"+e])):i===t?v.css(n,r,i,u):v.style(n,r,i,u)},n,o?i:t,o,null)}})}),e.jQuery=e.$=v,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return v})})(window); \ No newline at end of file diff --git a/tract_querier/tornado_server/js/jquery-ui-1.9.2.custom.min.js b/tract_querier/tornado_server/js/jquery-ui-1.9.2.custom.min.js new file mode 100644 index 0000000..7deba66 --- /dev/null +++ b/tract_querier/tornado_server/js/jquery-ui-1.9.2.custom.min.js @@ -0,0 +1,6 @@ +/*! jQuery UI - v1.9.2 - 2013-01-08 +* http://jqueryui.com +* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.mouse.js, jquery.ui.position.js, jquery.ui.draggable.js, jquery.ui.droppable.js, jquery.ui.resizable.js, jquery.ui.selectable.js, jquery.ui.sortable.js, jquery.ui.accordion.js, jquery.ui.autocomplete.js, jquery.ui.button.js, jquery.ui.datepicker.js, jquery.ui.dialog.js, jquery.ui.menu.js, jquery.ui.progressbar.js, jquery.ui.slider.js, jquery.ui.spinner.js, jquery.ui.tabs.js, jquery.ui.tooltip.js, jquery.ui.effect.js, jquery.ui.effect-blind.js, jquery.ui.effect-bounce.js, jquery.ui.effect-clip.js, jquery.ui.effect-drop.js, jquery.ui.effect-explode.js, jquery.ui.effect-fade.js, jquery.ui.effect-fold.js, jquery.ui.effect-highlight.js, jquery.ui.effect-pulsate.js, jquery.ui.effect-scale.js, jquery.ui.effect-shake.js, jquery.ui.effect-slide.js, jquery.ui.effect-transfer.js +* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */ + +(function(e,t){function i(t,n){var r,i,o,u=t.nodeName.toLowerCase();return"area"===u?(r=t.parentNode,i=r.name,!t.href||!i||r.nodeName.toLowerCase()!=="map"?!1:(o=e("img[usemap=#"+i+"]")[0],!!o&&s(o))):(/input|select|textarea|button|object/.test(u)?!t.disabled:"a"===u?t.href||n:n)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().andSelf().filter(function(){return e.css(this,"visibility")==="hidden"}).length}var n=0,r=/^ui-id-\d+$/;e.ui=e.ui||{};if(e.ui.version)return;e.extend(e.ui,{version:"1.9.2",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({_focus:e.fn.focus,focus:function(t,n){return typeof t=="number"?this.each(function(){var r=this;setTimeout(function(){e(r).focus(),n&&n.call(r)},t)}):this._focus.apply(this,arguments)},scrollParent:function(){var t;return e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?t=this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):t=this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(n){if(n!==t)return this.css("zIndex",n);if(this.length){var r=e(this[0]),i,s;while(r.length&&r[0]!==document){i=r.css("position");if(i==="absolute"||i==="relative"||i==="fixed"){s=parseInt(r.css("zIndex"),10);if(!isNaN(s)&&s!==0)return s}r=r.parent()}}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++n)})},removeUniqueId:function(){return this.each(function(){r.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(n){return!!e.data(n,t)}}):function(t,n,r){return!!e.data(t,r[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var n=e.attr(t,"tabindex"),r=isNaN(n);return(r||n>=0)&&i(t,!r)}}),e(function(){var t=document.body,n=t.appendChild(n=document.createElement("div"));n.offsetHeight,e.extend(n.style,{minHeight:"100px",height:"auto",padding:0,borderWidth:0}),e.support.minHeight=n.offsetHeight===100,e.support.selectstart="onselectstart"in n,t.removeChild(n).style.display="none"}),e("").outerWidth(1).jquery||e.each(["Width","Height"],function(n,r){function u(t,n,r,s){return e.each(i,function(){n-=parseFloat(e.css(t,"padding"+this))||0,r&&(n-=parseFloat(e.css(t,"border"+this+"Width"))||0),s&&(n-=parseFloat(e.css(t,"margin"+this))||0)}),n}var i=r==="Width"?["Left","Right"]:["Top","Bottom"],s=r.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+r]=function(n){return n===t?o["inner"+r].call(this):this.each(function(){e(this).css(s,u(this,n)+"px")})},e.fn["outer"+r]=function(t,n){return typeof t!="number"?o["outer"+r].call(this,t):this.each(function(){e(this).css(s,u(this,t,!0,n)+"px")})}}),e("").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(n){return arguments.length?t.call(this,e.camelCase(n)):t.call(this)}}(e.fn.removeData)),function(){var t=/msie ([\w.]+)/.exec(navigator.userAgent.toLowerCase())||[];e.ui.ie=t.length?!0:!1,e.ui.ie6=parseFloat(t[1],10)===6}(),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,n,r){var i,s=e.ui[t].prototype;for(i in r)s.plugins[i]=s.plugins[i]||[],s.plugins[i].push([n,r[i]])},call:function(e,t,n){var r,i=e.plugins[t];if(!i||!e.element[0].parentNode||e.element[0].parentNode.nodeType===11)return;for(r=0;r0?!0:(t[r]=1,i=t[r]>0,t[r]=0,i)},isOverAxis:function(e,t,n){return e>t&&e",options:{disabled:!1,create:null},_createWidget:function(t,r){r=e(r||this.defaultElement||this)[0],this.element=e(r),this.uuid=n++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),r!==this&&(e.data(r,this.widgetName,this),e.data(r,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===r&&this.destroy()}}),this.document=e(r.style?r.ownerDocument:r.document||r),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(n,r){var i=n,s,o,u;if(arguments.length===0)return e.widget.extend({},this.options);if(typeof n=="string"){i={},s=n.split("."),n=s.shift();if(s.length){o=i[n]=e.widget.extend({},this.options[n]);for(u=0;u=9||!!t.button?this._mouseStarted?(this._mouseDrag(t),t.preventDefault()):(this._mouseDistanceMet(t)&&this._mouseDelayMet(t)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,t)!==!1,this._mouseStarted?this._mouseDrag(t):this._mouseUp(t)),!this._mouseStarted):this._mouseUp(t)},_mouseUp:function(t){return e(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,t.target===this._mouseDownEvent.target&&e.data(t.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(t)),!1},_mouseDistanceMet:function(e){return Math.max(Math.abs(this._mouseDownEvent.pageX-e.pageX),Math.abs(this._mouseDownEvent.pageY-e.pageY))>=this.options.distance},_mouseDelayMet:function(e){return this.mouseDelayMet},_mouseStart:function(e){},_mouseDrag:function(e){},_mouseStop:function(e){},_mouseCapture:function(e){return!0}})})(jQuery);(function(e,t){function h(e,t,n){return[parseInt(e[0],10)*(l.test(e[0])?t/100:1),parseInt(e[1],10)*(l.test(e[1])?n/100:1)]}function p(t,n){return parseInt(e.css(t,n),10)||0}e.ui=e.ui||{};var n,r=Math.max,i=Math.abs,s=Math.round,o=/left|center|right/,u=/top|center|bottom/,a=/[\+\-]\d+%?/,f=/^\w+/,l=/%$/,c=e.fn.position;e.position={scrollbarWidth:function(){if(n!==t)return n;var r,i,s=e("
"),o=s.children()[0];return e("body").append(s),r=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,r===i&&(i=s[0].clientWidth),s.remove(),n=r-i},getScrollInfo:function(t){var n=t.isWindow?"":t.element.css("overflow-x"),r=t.isWindow?"":t.element.css("overflow-y"),i=n==="scroll"||n==="auto"&&t.width0?"right":"center",vertical:u<0?"top":o>0?"bottom":"middle"};lr(i(o),i(u))?h.important="horizontal":h.important="vertical",t.using.call(this,e,h)}),a.offset(e.extend(C,{using:u}))})},e.ui.position={fit:{left:function(e,t){var n=t.within,i=n.isWindow?n.scrollLeft:n.offset.left,s=n.width,o=e.left-t.collisionPosition.marginLeft,u=i-o,a=o+t.collisionWidth-s-i,f;t.collisionWidth>s?u>0&&a<=0?(f=e.left+u+t.collisionWidth-s-i,e.left+=u-f):a>0&&u<=0?e.left=i:u>a?e.left=i+s-t.collisionWidth:e.left=i:u>0?e.left+=u:a>0?e.left-=a:e.left=r(e.left-o,e.left)},top:function(e,t){var n=t.within,i=n.isWindow?n.scrollTop:n.offset.top,s=t.within.height,o=e.top-t.collisionPosition.marginTop,u=i-o,a=o+t.collisionHeight-s-i,f;t.collisionHeight>s?u>0&&a<=0?(f=e.top+u+t.collisionHeight-s-i,e.top+=u-f):a>0&&u<=0?e.top=i:u>a?e.top=i+s-t.collisionHeight:e.top=i:u>0?e.top+=u:a>0?e.top-=a:e.top=r(e.top-o,e.top)}},flip:{left:function(e,t){var n=t.within,r=n.offset.left+n.scrollLeft,s=n.width,o=n.isWindow?n.scrollLeft:n.offset.left,u=e.left-t.collisionPosition.marginLeft,a=u-o,f=u+t.collisionWidth-s-o,l=t.my[0]==="left"?-t.elemWidth:t.my[0]==="right"?t.elemWidth:0,c=t.at[0]==="left"?t.targetWidth:t.at[0]==="right"?-t.targetWidth:0,h=-2*t.offset[0],p,d;if(a<0){p=e.left+l+c+h+t.collisionWidth-s-r;if(p<0||p0){d=e.left-t.collisionPosition.marginLeft+l+c+h-o;if(d>0||i(d)a&&(v<0||v0&&(d=e.top-t.collisionPosition.marginTop+c+h+p-o,e.top+c+h+p>f&&(d>0||i(d)10&&i<11,t.innerHTML="",n.removeChild(t)}(),e.uiBackCompat!==!1&&function(e){var n=e.fn.position;e.fn.position=function(r){if(!r||!r.offset)return n.call(this,r);var i=r.offset.split(" "),s=r.at.split(" ");return i.length===1&&(i[1]=i[0]),/^\d/.test(i[0])&&(i[0]="+"+i[0]),/^\d/.test(i[1])&&(i[1]="+"+i[1]),s.length===1&&(/left|center|right/.test(s[0])?s[1]="center":(s[1]=s[0],s[0]="center")),n.call(this,e.extend(r,{at:s[0]+i[0]+" "+s[1]+i[1],offset:t}))}}(jQuery)})(jQuery);(function(e,t){e.widget("ui.draggable",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"drag",options:{addClasses:!0,appendTo:"parent",axis:!1,connectToSortable:!1,containment:!1,cursor:"auto",cursorAt:!1,grid:!1,handle:!1,helper:"original",iframeFix:!1,opacity:!1,refreshPositions:!1,revert:!1,revertDuration:500,scope:"default",scroll:!0,scrollSensitivity:20,scrollSpeed:20,snap:!1,snapMode:"both",snapTolerance:20,stack:!1,zIndex:!1},_create:function(){this.options.helper=="original"&&!/^(?:r|a|f)/.test(this.element.css("position"))&&(this.element[0].style.position="relative"),this.options.addClasses&&this.element.addClass("ui-draggable"),this.options.disabled&&this.element.addClass("ui-draggable-disabled"),this._mouseInit()},_destroy:function(){this.element.removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled"),this._mouseDestroy()},_mouseCapture:function(t){var n=this.options;return this.helper||n.disabled||e(t.target).is(".ui-resizable-handle")?!1:(this.handle=this._getHandle(t),this.handle?(e(n.iframeFix===!0?"iframe":n.iframeFix).each(function(){e('
').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1e3}).css(e(this).offset()).appendTo("body")}),!0):!1)},_mouseStart:function(t){var n=this.options;return this.helper=this._createHelper(t),this.helper.addClass("ui-draggable-dragging"),this._cacheHelperProportions(),e.ui.ddmanager&&(e.ui.ddmanager.current=this),this._cacheMargins(),this.cssPosition=this.helper.css("position"),this.scrollParent=this.helper.scrollParent(),this.offset=this.positionAbs=this.element.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.originalPosition=this.position=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,n.cursorAt&&this._adjustOffsetFromHelper(n.cursorAt),n.containment&&this._setContainment(),this._trigger("start",t)===!1?(this._clear(),!1):(this._cacheHelperProportions(),e.ui.ddmanager&&!n.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this._mouseDrag(t,!0),e.ui.ddmanager&&e.ui.ddmanager.dragStart(this,t),!0)},_mouseDrag:function(t,n){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute");if(!n){var r=this._uiHash();if(this._trigger("drag",t,r)===!1)return this._mouseUp({}),!1;this.position=r.position}if(!this.options.axis||this.options.axis!="y")this.helper[0].style.left=this.position.left+"px";if(!this.options.axis||this.options.axis!="x")this.helper[0].style.top=this.position.top+"px";return e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),!1},_mouseStop:function(t){var n=!1;e.ui.ddmanager&&!this.options.dropBehaviour&&(n=e.ui.ddmanager.drop(this,t)),this.dropped&&(n=this.dropped,this.dropped=!1);var r=this.element[0],i=!1;while(r&&(r=r.parentNode))r==document&&(i=!0);if(!i&&this.options.helper==="original")return!1;if(this.options.revert=="invalid"&&!n||this.options.revert=="valid"&&n||this.options.revert===!0||e.isFunction(this.options.revert)&&this.options.revert.call(this.element,n)){var s=this;e(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){s._trigger("stop",t)!==!1&&s._clear()})}else this._trigger("stop",t)!==!1&&this._clear();return!1},_mouseUp:function(t){return e("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)}),e.ui.ddmanager&&e.ui.ddmanager.dragStop(this,t),e.ui.mouse.prototype._mouseUp.call(this,t)},cancel:function(){return this.helper.is(".ui-draggable-dragging")?this._mouseUp({}):this._clear(),this},_getHandle:function(t){var n=!this.options.handle||!e(this.options.handle,this.element).length?!0:!1;return e(this.options.handle,this.element).find("*").andSelf().each(function(){this==t.target&&(n=!0)}),n},_createHelper:function(t){var n=this.options,r=e.isFunction(n.helper)?e(n.helper.apply(this.element[0],[t])):n.helper=="clone"?this.element.clone().removeAttr("id"):this.element;return r.parents("body").length||r.appendTo(n.appendTo=="parent"?this.element[0].parentNode:n.appendTo),r[0]!=this.element[0]&&!/(fixed|absolute)/.test(r.css("position"))&&r.css("position","absolute"),r},_adjustOffsetFromHelper:function(t){typeof t=="string"&&(t=t.split(" ")),e.isArray(t)&&(t={left:+t[0],top:+t[1]||0}),"left"in t&&(this.offset.click.left=t.left+this.margins.left),"right"in t&&(this.offset.click.left=this.helperProportions.width-t.right+this.margins.left),"top"in t&&(this.offset.click.top=t.top+this.margins.top),"bottom"in t&&(this.offset.click.top=this.helperProportions.height-t.bottom+this.margins.top)},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var t=this.offsetParent.offset();this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&e.contains(this.scrollParent[0],this.offsetParent[0])&&(t.left+=this.scrollParent.scrollLeft(),t.top+=this.scrollParent.scrollTop());if(this.offsetParent[0]==document.body||this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&e.ui.ie)t={top:0,left:0};return{top:t.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:t.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var e=this.element.position();return{top:e.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:e.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}return{top:0,left:0}},_cacheMargins:function(){this.margins={left:parseInt(this.element.css("marginLeft"),10)||0,top:parseInt(this.element.css("marginTop"),10)||0,right:parseInt(this.element.css("marginRight"),10)||0,bottom:parseInt(this.element.css("marginBottom"),10)||0}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var t=this.options;t.containment=="parent"&&(t.containment=this.helper[0].parentNode);if(t.containment=="document"||t.containment=="window")this.containment=[t.containment=="document"?0:e(window).scrollLeft()-this.offset.relative.left-this.offset.parent.left,t.containment=="document"?0:e(window).scrollTop()-this.offset.relative.top-this.offset.parent.top,(t.containment=="document"?0:e(window).scrollLeft())+e(t.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(t.containment=="document"?0:e(window).scrollTop())+(e(t.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top];if(!/^(document|window|parent)$/.test(t.containment)&&t.containment.constructor!=Array){var n=e(t.containment),r=n[0];if(!r)return;var i=n.offset(),s=e(r).css("overflow")!="hidden";this.containment=[(parseInt(e(r).css("borderLeftWidth"),10)||0)+(parseInt(e(r).css("paddingLeft"),10)||0),(parseInt(e(r).css("borderTopWidth"),10)||0)+(parseInt(e(r).css("paddingTop"),10)||0),(s?Math.max(r.scrollWidth,r.offsetWidth):r.offsetWidth)-(parseInt(e(r).css("borderLeftWidth"),10)||0)-(parseInt(e(r).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left-this.margins.right,(s?Math.max(r.scrollHeight,r.offsetHeight):r.offsetHeight)-(parseInt(e(r).css("borderTopWidth"),10)||0)-(parseInt(e(r).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top-this.margins.bottom],this.relative_container=n}else t.containment.constructor==Array&&(this.containment=t.containment)},_convertPositionTo:function(t,n){n||(n=this.position);var r=t=="absolute"?1:-1,i=this.options,s=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,o=/(html|body)/i.test(s[0].tagName);return{top:n.top+this.offset.relative.top*r+this.offset.parent.top*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():o?0:s.scrollTop())*r,left:n.left+this.offset.relative.left*r+this.offset.parent.left*r-(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():o?0:s.scrollLeft())*r}},_generatePosition:function(t){var n=this.options,r=this.cssPosition!="absolute"||this.scrollParent[0]!=document&&!!e.contains(this.scrollParent[0],this.offsetParent[0])?this.scrollParent:this.offsetParent,i=/(html|body)/i.test(r[0].tagName),s=t.pageX,o=t.pageY;if(this.originalPosition){var u;if(this.containment){if(this.relative_container){var a=this.relative_container.offset();u=[this.containment[0]+a.left,this.containment[1]+a.top,this.containment[2]+a.left,this.containment[3]+a.top]}else u=this.containment;t.pageX-this.offset.click.leftu[2]&&(s=u[2]+this.offset.click.left),t.pageY-this.offset.click.top>u[3]&&(o=u[3]+this.offset.click.top)}if(n.grid){var f=n.grid[1]?this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1]:this.originalPageY;o=u?f-this.offset.click.topu[3]?f-this.offset.click.topu[2]?l-this.offset.click.left=0;l--){var c=r.snapElements[l].left,h=c+r.snapElements[l].width,p=r.snapElements[l].top,d=p+r.snapElements[l].height;if(!(c-s=l&&o<=c||u>=l&&u<=c||oc)&&(i>=a&&i<=f||s>=a&&s<=f||if);default:return!1}},e.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(t,n){var r=e.ui.ddmanager.droppables[t.options.scope]||[],i=n?n.type:null,s=(t.currentItem||t.element).find(":data(droppable)").andSelf();e:for(var o=0;o
').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("resizable",this.element.data("resizable")),this.elementIsWrapper=!0,this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")}),this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0}),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css({margin:this.originalElement.css("margin")}),this._proportionallyResize()),this.handles=n.handles||(e(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se");if(this.handles.constructor==String){this.handles=="all"&&(this.handles="n,e,s,w,se,sw,ne,nw");var r=this.handles.split(",");this.handles={};for(var i=0;i');u.css({zIndex:n.zIndex}),"se"==s&&u.addClass("ui-icon ui-icon-gripsmall-diagonal-se"),this.handles[s]=".ui-resizable-"+s,this.element.append(u)}}this._renderAxis=function(t){t=t||this.element;for(var n in this.handles){this.handles[n].constructor==String&&(this.handles[n]=e(this.handles[n],this.element).show());if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var r=e(this.handles[n],this.element),i=0;i=/sw|ne|nw|se|n|s/.test(n)?r.outerHeight():r.outerWidth();var s=["padding",/ne|nw|n/.test(n)?"Top":/se|sw|s/.test(n)?"Bottom":/^e$/.test(n)?"Right":"Left"].join("");t.css(s,i),this._proportionallyResize()}if(!e(this.handles[n]).length)continue}},this._renderAxis(this.element),this._handles=e(".ui-resizable-handle",this.element).disableSelection(),this._handles.mouseover(function(){if(!t.resizing){if(this.className)var e=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);t.axis=e&&e[1]?e[1]:"se"}}),n.autoHide&&(this._handles.hide(),e(this.element).addClass("ui-resizable-autohide").mouseenter(function(){if(n.disabled)return;e(this).removeClass("ui-resizable-autohide"),t._handles.show()}).mouseleave(function(){if(n.disabled)return;t.resizing||(e(this).addClass("ui-resizable-autohide"),t._handles.hide())})),this._mouseInit()},_destroy:function(){this._mouseDestroy();var t=function(t){e(t).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").removeData("ui-resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){t(this.element);var n=this.element;this.originalElement.css({position:n.css("position"),width:n.outerWidth(),height:n.outerHeight(),top:n.css("top"),left:n.css("left")}).insertAfter(n),n.remove()}return this.originalElement.css("resize",this.originalResizeStyle),t(this.originalElement),this},_mouseCapture:function(t){var n=!1;for(var r in this.handles)e(this.handles[r])[0]==t.target&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(t){var r=this.options,i=this.element.position(),s=this.element;this.resizing=!0,this.documentScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()},(s.is(".ui-draggable")||/absolute/.test(s.css("position")))&&s.css({position:"absolute",top:i.top,left:i.left}),this._renderProxy();var o=n(this.helper.css("left")),u=n(this.helper.css("top"));r.containment&&(o+=e(r.containment).scrollLeft()||0,u+=e(r.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:o,top:u},this.size=this._helper?{width:s.outerWidth(),height:s.outerHeight()}:{width:s.width(),height:s.height()},this.originalSize=this._helper?{width:s.outerWidth(),height:s.outerHeight()}:{width:s.width(),height:s.height()},this.originalPosition={left:o,top:u},this.sizeDiff={width:s.outerWidth()-s.width(),height:s.outerHeight()-s.height()},this.originalMousePosition={left:t.pageX,top:t.pageY},this.aspectRatio=typeof r.aspectRatio=="number"?r.aspectRatio:this.originalSize.width/this.originalSize.height||1;var a=e(".ui-resizable-"+this.axis).css("cursor");return e("body").css("cursor",a=="auto"?this.axis+"-resize":a),s.addClass("ui-resizable-resizing"),this._propagate("start",t),!0},_mouseDrag:function(e){var t=this.helper,n=this.options,r={},i=this,s=this.originalMousePosition,o=this.axis,u=e.pageX-s.left||0,a=e.pageY-s.top||0,f=this._change[o];if(!f)return!1;var l=f.apply(this,[e,u,a]);this._updateVirtualBoundaries(e.shiftKey);if(this._aspectRatio||e.shiftKey)l=this._updateRatio(l,e);return l=this._respectSize(l,e),this._propagate("resize",e),t.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"}),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),this._updateCache(l),this._trigger("resize",e,this.ui()),!1},_mouseStop:function(t){this.resizing=!1;var n=this.options,r=this;if(this._helper){var i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),o=s&&e.ui.hasScroll(i[0],"left")?0:r.sizeDiff.height,u=s?0:r.sizeDiff.width,a={width:r.helper.width()-u,height:r.helper.height()-o},f=parseInt(r.element.css("left"),10)+(r.position.left-r.originalPosition.left)||null,l=parseInt(r.element.css("top"),10)+(r.position.top-r.originalPosition.top)||null;n.animate||this.element.css(e.extend(a,{top:l,left:f})),r.helper.height(r.size.height),r.helper.width(r.size.width),this._helper&&!n.animate&&this._proportionallyResize()}return e("body").css("cursor","auto"),this.element.removeClass("ui-resizable-resizing"),this._propagate("stop",t),this._helper&&this.helper.remove(),!1},_updateVirtualBoundaries:function(e){var t=this.options,n,i,s,o,u;u={minWidth:r(t.minWidth)?t.minWidth:0,maxWidth:r(t.maxWidth)?t.maxWidth:Infinity,minHeight:r(t.minHeight)?t.minHeight:0,maxHeight:r(t.maxHeight)?t.maxHeight:Infinity};if(this._aspectRatio||e)n=u.minHeight*this.aspectRatio,s=u.minWidth/this.aspectRatio,i=u.maxHeight*this.aspectRatio,o=u.maxWidth/this.aspectRatio,n>u.minWidth&&(u.minWidth=n),s>u.minHeight&&(u.minHeight=s),ie.width,l=r(e.height)&&i.minHeight&&i.minHeight>e.height;f&&(e.width=i.minWidth),l&&(e.height=i.minHeight),u&&(e.width=i.maxWidth),a&&(e.height=i.maxHeight);var c=this.originalPosition.left+this.originalSize.width,h=this.position.top+this.size.height,p=/sw|nw|w/.test(o),d=/nw|ne|n/.test(o);f&&p&&(e.left=c-i.minWidth),u&&p&&(e.left=c-i.maxWidth),l&&d&&(e.top=h-i.minHeight),a&&d&&(e.top=h-i.maxHeight);var v=!e.width&&!e.height;return v&&!e.left&&e.top?e.top=null:v&&!e.top&&e.left&&(e.left=null),e},_proportionallyResize:function(){var t=this.options;if(!this._proportionallyResizeElements.length)return;var n=this.helper||this.element;for(var r=0;r');var r=e.ui.ie6?1:0,i=e.ui.ie6?2:-1;this.helper.addClass(this._helper).css({width:this.element.outerWidth()+i,height:this.element.outerHeight()+i,position:"absolute",left:this.elementOffset.left-r+"px",top:this.elementOffset.top-r+"px",zIndex:++n.zIndex}),this.helper.appendTo("body").disableSelection()}else this.helper=this.element},_change:{e:function(e,t,n){return{width:this.originalSize.width+t}},w:function(e,t,n){var r=this.options,i=this.originalSize,s=this.originalPosition;return{left:s.left+t,width:i.width-t}},n:function(e,t,n){var r=this.options,i=this.originalSize,s=this.originalPosition;return{top:s.top+n,height:i.height-n}},s:function(e,t,n){return{height:this.originalSize.height+n}},se:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},sw:function(t,n,r){return e.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[t,n,r]))},ne:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[t,n,r]))},nw:function(t,n,r){return e.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[t,n,r]))}},_propagate:function(t,n){e.ui.plugin.call(this,t,[n,this.ui()]),t!="resize"&&this._trigger(t,n,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),e.ui.plugin.add("resizable","alsoResize",{start:function(t,n){var r=e(this).data("resizable"),i=r.options,s=function(t){e(t).each(function(){var t=e(this);t.data("resizable-alsoresize",{width:parseInt(t.width(),10),height:parseInt(t.height(),10),left:parseInt(t.css("left"),10),top:parseInt(t.css("top"),10)})})};typeof i.alsoResize=="object"&&!i.alsoResize.parentNode?i.alsoResize.length?(i.alsoResize=i.alsoResize[0],s(i.alsoResize)):e.each(i.alsoResize,function(e){s(e)}):s(i.alsoResize)},resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.originalSize,o=r.originalPosition,u={height:r.size.height-s.height||0,width:r.size.width-s.width||0,top:r.position.top-o.top||0,left:r.position.left-o.left||0},a=function(t,r){e(t).each(function(){var t=e(this),i=e(this).data("resizable-alsoresize"),s={},o=r&&r.length?r:t.parents(n.originalElement[0]).length?["width","height"]:["width","height","top","left"];e.each(o,function(e,t){var n=(i[t]||0)+(u[t]||0);n&&n>=0&&(s[t]=n||null)}),t.css(s)})};typeof i.alsoResize=="object"&&!i.alsoResize.nodeType?e.each(i.alsoResize,function(e,t){a(e,t)}):a(i.alsoResize)},stop:function(t,n){e(this).removeData("resizable-alsoresize")}}),e.ui.plugin.add("resizable","animate",{stop:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r._proportionallyResizeElements,o=s.length&&/textarea/i.test(s[0].nodeName),u=o&&e.ui.hasScroll(s[0],"left")?0:r.sizeDiff.height,a=o?0:r.sizeDiff.width,f={width:r.size.width-a,height:r.size.height-u},l=parseInt(r.element.css("left"),10)+(r.position.left-r.originalPosition.left)||null,c=parseInt(r.element.css("top"),10)+(r.position.top-r.originalPosition.top)||null;r.element.animate(e.extend(f,c&&l?{top:c,left:l}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var n={width:parseInt(r.element.css("width"),10),height:parseInt(r.element.css("height"),10),top:parseInt(r.element.css("top"),10),left:parseInt(r.element.css("left"),10)};s&&s.length&&e(s[0]).css({width:n.width,height:n.height}),r._updateCache(n),r._propagate("resize",t)}})}}),e.ui.plugin.add("resizable","containment",{start:function(t,r){var i=e(this).data("resizable"),s=i.options,o=i.element,u=s.containment,a=u instanceof e?u.get(0):/parent/.test(u)?o.parent().get(0):u;if(!a)return;i.containerElement=e(a);if(/document/.test(u)||u==document)i.containerOffset={left:0,top:0},i.containerPosition={left:0,top:0},i.parentData={element:e(document),left:0,top:0,width:e(document).width(),height:e(document).height()||document.body.parentNode.scrollHeight};else{var f=e(a),l=[];e(["Top","Right","Left","Bottom"]).each(function(e,t){l[e]=n(f.css("padding"+t))}),i.containerOffset=f.offset(),i.containerPosition=f.position(),i.containerSize={height:f.innerHeight()-l[3],width:f.innerWidth()-l[1]};var c=i.containerOffset,h=i.containerSize.height,p=i.containerSize.width,d=e.ui.hasScroll(a,"left")?a.scrollWidth:p,v=e.ui.hasScroll(a)?a.scrollHeight:h;i.parentData={element:a,left:c.left,top:c.top,width:d,height:v}}},resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.containerSize,o=r.containerOffset,u=r.size,a=r.position,f=r._aspectRatio||t.shiftKey,l={top:0,left:0},c=r.containerElement;c[0]!=document&&/static/.test(c.css("position"))&&(l=o),a.left<(r._helper?o.left:0)&&(r.size.width=r.size.width+(r._helper?r.position.left-o.left:r.position.left-l.left),f&&(r.size.height=r.size.width/r.aspectRatio),r.position.left=i.helper?o.left:0),a.top<(r._helper?o.top:0)&&(r.size.height=r.size.height+(r._helper?r.position.top-o.top:r.position.top),f&&(r.size.width=r.size.height*r.aspectRatio),r.position.top=r._helper?o.top:0),r.offset.left=r.parentData.left+r.position.left,r.offset.top=r.parentData.top+r.position.top;var h=Math.abs((r._helper?r.offset.left-l.left:r.offset.left-l.left)+r.sizeDiff.width),p=Math.abs((r._helper?r.offset.top-l.top:r.offset.top-o.top)+r.sizeDiff.height),d=r.containerElement.get(0)==r.element.parent().get(0),v=/relative|absolute/.test(r.containerElement.css("position"));d&&v&&(h-=r.parentData.left),h+r.size.width>=r.parentData.width&&(r.size.width=r.parentData.width-h,f&&(r.size.height=r.size.width/r.aspectRatio)),p+r.size.height>=r.parentData.height&&(r.size.height=r.parentData.height-p,f&&(r.size.width=r.size.height*r.aspectRatio))},stop:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.position,o=r.containerOffset,u=r.containerPosition,a=r.containerElement,f=e(r.helper),l=f.offset(),c=f.outerWidth()-r.sizeDiff.width,h=f.outerHeight()-r.sizeDiff.height;r._helper&&!i.animate&&/relative/.test(a.css("position"))&&e(this).css({left:l.left-u.left-o.left,width:c,height:h}),r._helper&&!i.animate&&/static/.test(a.css("position"))&&e(this).css({left:l.left-u.left-o.left,width:c,height:h})}}),e.ui.plugin.add("resizable","ghost",{start:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.size;r.ghost=r.originalElement.clone(),r.ghost.css({opacity:.25,display:"block",position:"relative",height:s.height,width:s.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof i.ghost=="string"?i.ghost:""),r.ghost.appendTo(r.helper)},resize:function(t,n){var r=e(this).data("resizable"),i=r.options;r.ghost&&r.ghost.css({position:"relative",height:r.size.height,width:r.size.width})},stop:function(t,n){var r=e(this).data("resizable"),i=r.options;r.ghost&&r.helper&&r.helper.get(0).removeChild(r.ghost.get(0))}}),e.ui.plugin.add("resizable","grid",{resize:function(t,n){var r=e(this).data("resizable"),i=r.options,s=r.size,o=r.originalSize,u=r.originalPosition,a=r.axis,f=i._aspectRatio||t.shiftKey;i.grid=typeof i.grid=="number"?[i.grid,i.grid]:i.grid;var l=Math.round((s.width-o.width)/(i.grid[0]||1))*(i.grid[0]||1),c=Math.round((s.height-o.height)/(i.grid[1]||1))*(i.grid[1]||1);/^(se|s|e)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c):/^(ne)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c,r.position.top=u.top-c):/^(sw)$/.test(a)?(r.size.width=o.width+l,r.size.height=o.height+c,r.position.left=u.left-l):(r.size.width=o.width+l,r.size.height=o.height+c,r.position.top=u.top-c,r.position.left=u.left-l)}});var n=function(e){return parseInt(e,10)||0},r=function(e){return!isNaN(parseInt(e,10))}})(jQuery);(function(e,t){e.widget("ui.selectable",e.ui.mouse,{version:"1.9.2",options:{appendTo:"body",autoRefresh:!0,distance:0,filter:"*",tolerance:"touch"},_create:function(){var t=this;this.element.addClass("ui-selectable"),this.dragged=!1;var n;this.refresh=function(){n=e(t.options.filter,t.element[0]),n.addClass("ui-selectee"),n.each(function(){var t=e(this),n=t.offset();e.data(this,"selectable-item",{element:this,$element:t,left:n.left,top:n.top,right:n.left+t.outerWidth(),bottom:n.top+t.outerHeight(),startselected:!1,selected:t.hasClass("ui-selected"),selecting:t.hasClass("ui-selecting"),unselecting:t.hasClass("ui-unselecting")})})},this.refresh(),this.selectees=n.addClass("ui-selectee"),this._mouseInit(),this.helper=e("
")},_destroy:function(){this.selectees.removeClass("ui-selectee").removeData("selectable-item"),this.element.removeClass("ui-selectable ui-selectable-disabled"),this._mouseDestroy()},_mouseStart:function(t){var n=this;this.opos=[t.pageX,t.pageY];if(this.options.disabled)return;var r=this.options;this.selectees=e(r.filter,this.element[0]),this._trigger("start",t),e(r.appendTo).append(this.helper),this.helper.css({left:t.clientX,top:t.clientY,width:0,height:0}),r.autoRefresh&&this.refresh(),this.selectees.filter(".ui-selected").each(function(){var r=e.data(this,"selectable-item");r.startselected=!0,!t.metaKey&&!t.ctrlKey&&(r.$element.removeClass("ui-selected"),r.selected=!1,r.$element.addClass("ui-unselecting"),r.unselecting=!0,n._trigger("unselecting",t,{unselecting:r.element}))}),e(t.target).parents().andSelf().each(function(){var r=e.data(this,"selectable-item");if(r){var i=!t.metaKey&&!t.ctrlKey||!r.$element.hasClass("ui-selected");return r.$element.removeClass(i?"ui-unselecting":"ui-selected").addClass(i?"ui-selecting":"ui-unselecting"),r.unselecting=!i,r.selecting=i,r.selected=i,i?n._trigger("selecting",t,{selecting:r.element}):n._trigger("unselecting",t,{unselecting:r.element}),!1}})},_mouseDrag:function(t){var n=this;this.dragged=!0;if(this.options.disabled)return;var r=this.options,i=this.opos[0],s=this.opos[1],o=t.pageX,u=t.pageY;if(i>o){var a=o;o=i,i=a}if(s>u){var a=u;u=s,s=a}return this.helper.css({left:i,top:s,width:o-i,height:u-s}),this.selectees.each(function(){var a=e.data(this,"selectable-item");if(!a||a.element==n.element[0])return;var f=!1;r.tolerance=="touch"?f=!(a.left>o||a.rightu||a.bottomi&&a.rights&&a.bottom *",opacity:!1,placeholder:!1,revert:!1,scroll:!0,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1e3},_create:function(){var e=this.options;this.containerCache={},this.element.addClass("ui-sortable"),this.refresh(),this.floating=this.items.length?e.axis==="x"||/left|right/.test(this.items[0].item.css("float"))||/inline|table-cell/.test(this.items[0].item.css("display")):!1,this.offset=this.element.offset(),this._mouseInit(),this.ready=!0},_destroy:function(){this.element.removeClass("ui-sortable ui-sortable-disabled"),this._mouseDestroy();for(var e=this.items.length-1;e>=0;e--)this.items[e].item.removeData(this.widgetName+"-item");return this},_setOption:function(t,n){t==="disabled"?(this.options[t]=n,this.widget().toggleClass("ui-sortable-disabled",!!n)):e.Widget.prototype._setOption.apply(this,arguments)},_mouseCapture:function(t,n){var r=this;if(this.reverting)return!1;if(this.options.disabled||this.options.type=="static")return!1;this._refreshItems(t);var i=null,s=e(t.target).parents().each(function(){if(e.data(this,r.widgetName+"-item")==r)return i=e(this),!1});e.data(t.target,r.widgetName+"-item")==r&&(i=e(t.target));if(!i)return!1;if(this.options.handle&&!n){var o=!1;e(this.options.handle,i).find("*").andSelf().each(function(){this==t.target&&(o=!0)});if(!o)return!1}return this.currentItem=i,this._removeCurrentsFromItems(),!0},_mouseStart:function(t,n,r){var i=this.options;this.currentContainer=this,this.refreshPositions(),this.helper=this._createHelper(t),this._cacheHelperProportions(),this._cacheMargins(),this.scrollParent=this.helper.scrollParent(),this.offset=this.currentItem.offset(),this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left},e.extend(this.offset,{click:{left:t.pageX-this.offset.left,top:t.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()}),this.helper.css("position","absolute"),this.cssPosition=this.helper.css("position"),this.originalPosition=this._generatePosition(t),this.originalPageX=t.pageX,this.originalPageY=t.pageY,i.cursorAt&&this._adjustOffsetFromHelper(i.cursorAt),this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]},this.helper[0]!=this.currentItem[0]&&this.currentItem.hide(),this._createPlaceholder(),i.containment&&this._setContainment(),i.cursor&&(e("body").css("cursor")&&(this._storedCursor=e("body").css("cursor")),e("body").css("cursor",i.cursor)),i.opacity&&(this.helper.css("opacity")&&(this._storedOpacity=this.helper.css("opacity")),this.helper.css("opacity",i.opacity)),i.zIndex&&(this.helper.css("zIndex")&&(this._storedZIndex=this.helper.css("zIndex")),this.helper.css("zIndex",i.zIndex)),this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"&&(this.overflowOffset=this.scrollParent.offset()),this._trigger("start",t,this._uiHash()),this._preserveHelperProportions||this._cacheHelperProportions();if(!r)for(var s=this.containers.length-1;s>=0;s--)this.containers[s]._trigger("activate",t,this._uiHash(this));return e.ui.ddmanager&&(e.ui.ddmanager.current=this),e.ui.ddmanager&&!i.dropBehaviour&&e.ui.ddmanager.prepareOffsets(this,t),this.dragging=!0,this.helper.addClass("ui-sortable-helper"),this._mouseDrag(t),!0},_mouseDrag:function(t){this.position=this._generatePosition(t),this.positionAbs=this._convertPositionTo("absolute"),this.lastPositionAbs||(this.lastPositionAbs=this.positionAbs);if(this.options.scroll){var n=this.options,r=!1;this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"?(this.overflowOffset.top+this.scrollParent[0].offsetHeight-t.pageY=0;i--){var s=this.items[i],o=s.item[0],u=this._intersectsWithPointer(s);if(!u)continue;if(s.instance!==this.currentContainer)continue;if(o!=this.currentItem[0]&&this.placeholder[u==1?"next":"prev"]()[0]!=o&&!e.contains(this.placeholder[0],o)&&(this.options.type=="semi-dynamic"?!e.contains(this.element[0],o):!0)){this.direction=u==1?"down":"up";if(this.options.tolerance!="pointer"&&!this._intersectsWithSides(s))break;this._rearrange(t,s),this._trigger("change",t,this._uiHash());break}}return this._contactContainers(t),e.ui.ddmanager&&e.ui.ddmanager.drag(this,t),this._trigger("sort",t,this._uiHash()),this.lastPositionAbs=this.positionAbs,!1},_mouseStop:function(t,n){if(!t)return;e.ui.ddmanager&&!this.options.dropBehaviour&&e.ui.ddmanager.drop(this,t);if(this.options.revert){var r=this,i=this.placeholder.offset();this.reverting=!0,e(this.helper).animate({left:i.left-this.offset.parent.left-this.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:i.top-this.offset.parent.top-this.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){r._clear(t)})}else this._clear(t,n);return!1},cancel:function(){if(this.dragging){this._mouseUp({target:null}),this.options.helper=="original"?this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper"):this.currentItem.show();for(var t=this.containers.length-1;t>=0;t--)this.containers[t]._trigger("deactivate",null,this._uiHash(this)),this.containers[t].containerCache.over&&(this.containers[t]._trigger("out",null,this._uiHash(this)),this.containers[t].containerCache.over=0)}return this.placeholder&&(this.placeholder[0].parentNode&&this.placeholder[0].parentNode.removeChild(this.placeholder[0]),this.options.helper!="original"&&this.helper&&this.helper[0].parentNode&&this.helper.remove(),e.extend(this,{helper:null,dragging:!1,reverting:!1,_noFinalSort:null}),this.domPosition.prev?e(this.domPosition.prev).after(this.currentItem):e(this.domPosition.parent).prepend(this.currentItem)),this},serialize:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},e(n).each(function(){var n=(e(t.item||this).attr(t.attribute||"id")||"").match(t.expression||/(.+)[-=_](.+)/);n&&r.push((t.key||n[1]+"[]")+"="+(t.key&&t.expression?n[1]:n[2]))}),!r.length&&t.key&&r.push(t.key+"="),r.join("&")},toArray:function(t){var n=this._getItemsAsjQuery(t&&t.connected),r=[];return t=t||{},n.each(function(){r.push(e(t.item||this).attr(t.attribute||"id")||"")}),r},_intersectsWith:function(e){var t=this.positionAbs.left,n=t+this.helperProportions.width,r=this.positionAbs.top,i=r+this.helperProportions.height,s=e.left,o=s+e.width,u=e.top,a=u+e.height,f=this.offset.click.top,l=this.offset.click.left,c=r+f>u&&r+fs&&t+le[this.floating?"width":"height"]?c:s0?"down":"up")},_getDragHorizontalDirection:function(){var e=this.positionAbs.left-this.lastPositionAbs.left;return e!=0&&(e>0?"right":"left")},refresh:function(e){return this._refreshItems(e),this.refreshPositions(),this},_connectWith:function(){var e=this.options;return e.connectWith.constructor==String?[e.connectWith]:e.connectWith},_getItemsAsjQuery:function(t){var n=[],r=[],i=this._connectWith();if(i&&t)for(var s=i.length-1;s>=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&r.push([e.isFunction(a.options.items)?a.options.items.call(a.element):e(a.options.items,a.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),a])}}r.push([e.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):e(this.options.items,this.element).not(".ui-sortable-helper").not(".ui-sortable-placeholder"),this]);for(var s=r.length-1;s>=0;s--)r[s][0].each(function(){n.push(this)});return e(n)},_removeCurrentsFromItems:function(){var t=this.currentItem.find(":data("+this.widgetName+"-item)");this.items=e.grep(this.items,function(e){for(var n=0;n=0;s--){var o=e(i[s]);for(var u=o.length-1;u>=0;u--){var a=e.data(o[u],this.widgetName);a&&a!=this&&!a.options.disabled&&(r.push([e.isFunction(a.options.items)?a.options.items.call(a.element[0],t,{item:this.currentItem}):e(a.options.items,a.element),a]),this.containers.push(a))}}for(var s=r.length-1;s>=0;s--){var f=r[s][1],l=r[s][0];for(var u=0,c=l.length;u=0;n--){var r=this.items[n];if(r.instance!=this.currentContainer&&this.currentContainer&&r.item[0]!=this.currentItem[0])continue;var i=this.options.toleranceElement?e(this.options.toleranceElement,r.item):r.item;t||(r.width=i.outerWidth(),r.height=i.outerHeight());var s=i.offset();r.left=s.left,r.top=s.top}if(this.options.custom&&this.options.custom.refreshContainers)this.options.custom.refreshContainers.call(this);else for(var n=this.containers.length-1;n>=0;n--){var s=this.containers[n].element.offset();this.containers[n].containerCache.left=s.left,this.containers[n].containerCache.top=s.top,this.containers[n].containerCache.width=this.containers[n].element.outerWidth(),this.containers[n].containerCache.height=this.containers[n].element.outerHeight()}return this},_createPlaceholder:function(t){t=t||this;var n=t.options;if(!n.placeholder||n.placeholder.constructor==String){var r=n.placeholder;n.placeholder={element:function(){var n=e(document.createElement(t.currentItem[0].nodeName)).addClass(r||t.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];return r||(n.style.visibility="hidden"),n},update:function(e,i){if(r&&!n.forcePlaceholderSize)return;i.height()||i.height(t.currentItem.innerHeight()-parseInt(t.currentItem.css("paddingTop")||0,10)-parseInt(t.currentItem.css("paddingBottom")||0,10)),i.width()||i.width(t.currentItem.innerWidth()-parseInt(t.currentItem.css("paddingLeft")||0,10)-parseInt(t.currentItem.css("paddingRight")||0,10))}}}t.placeholder=e(n.placeholder.element.call(t.element,t.currentItem)),t.currentItem.after(t.placeholder),n.placeholder.update(t,t.placeholder)},_contactContainers:function(t){var n=null,r=null;for(var i=this.containers.length-1;i>=0;i--){if(e.contains(this.currentItem[0],this.containers[i].element[0]))continue;if(this._intersectsWith(this.containers[i].containerCache)){if(n&&e.contains(this.containers[i].element[0],n.element[0]))continue;n=this.containers[i],r=i}else this.containers[i].containerCache.over&&(this.containers[i]._trigger("out",t,this._uiHash(this)),this.containers[i].containerCache.over=0)}if(!n)return;if(this.containers.length===1)this.containers[r]._trigger("over",t,this._uiHash(this)),this.containers[r].containerCache.over=1;else{var s=1e4,o=null,u=this.containers[r].floating?"left":"top",a=this.containers[r].floating?"width":"height",f=this.positionAbs[u]+this.offset.click[u];for(var l=this.items.length-1;l>=0;l--){if(!e.contains(this.containers[r].element[0],this.items[l].item[0]))continue;if(this.items[l].item[0]==this.currentItem[0])continue;var c=this.items[l].item.offset()[u],h=!1;Math.abs(c-f)>Math.abs(c+this.items[l][a]-f)&&(h=!0,c+=this.items[l][a]),Math.abs(c-f)this.containment[2]&&(s=this.containment[2]+this.offset.click.left),t.pageY-this.offset.click.top>this.containment[3]&&(o=this.containment[3]+this.offset.click.top));if(n.grid){var u=this.originalPageY+Math.round((o-this.originalPageY)/n.grid[1])*n.grid[1];o=this.containment?u-this.offset.click.topthis.containment[3]?u-this.offset.click.topthis.containment[2]?a-this.offset.click.left=0;i--)n||r.push(function(e){return function(t){e._trigger("deactivate",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over&&(r.push(function(e){return function(t){e._trigger("out",t,this._uiHash(this))}}.call(this,this.containers[i])),this.containers[i].containerCache.over=0);this._storedCursor&&e("body").css("cursor",this._storedCursor),this._storedOpacity&&this.helper.css("opacity",this._storedOpacity),this._storedZIndex&&this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex),this.dragging=!1;if(this.cancelHelperRemoval){if(!n){this._trigger("beforeStop",t,this._uiHash());for(var i=0;i li > :first-child,> :not(li):even",heightStyle:"auto",icons:{activeHeader:"ui-icon-triangle-1-s",header:"ui-icon-triangle-1-e"},activate:null,beforeActivate:null},_create:function(){var t=this.accordionId="ui-accordion-"+(this.element.attr("id")||++n),r=this.options;this.prevShow=this.prevHide=e(),this.element.addClass("ui-accordion ui-widget ui-helper-reset"),this.headers=this.element.find(r.header).addClass("ui-accordion-header ui-helper-reset ui-state-default ui-corner-all"),this._hoverable(this.headers),this._focusable(this.headers),this.headers.next().addClass("ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom").hide(),!r.collapsible&&(r.active===!1||r.active==null)&&(r.active=0),r.active<0&&(r.active+=this.headers.length),this.active=this._findActive(r.active).addClass("ui-accordion-header-active ui-state-active").toggleClass("ui-corner-all ui-corner-top"),this.active.next().addClass("ui-accordion-content-active").show(),this._createIcons(),this.refresh(),this.element.attr("role","tablist"),this.headers.attr("role","tab").each(function(n){var r=e(this),i=r.attr("id"),s=r.next(),o=s.attr("id");i||(i=t+"-header-"+n,r.attr("id",i)),o||(o=t+"-panel-"+n,s.attr("id",o)),r.attr("aria-controls",o),s.attr("aria-labelledby",i)}).next().attr("role","tabpanel"),this.headers.not(this.active).attr({"aria-selected":"false",tabIndex:-1}).next().attr({"aria-expanded":"false","aria-hidden":"true"}).hide(),this.active.length?this.active.attr({"aria-selected":"true",tabIndex:0}).next().attr({"aria-expanded":"true","aria-hidden":"false"}):this.headers.eq(0).attr("tabIndex",0),this._on(this.headers,{keydown:"_keydown"}),this._on(this.headers.next(),{keydown:"_panelKeyDown"}),this._setupEvents(r.event)},_getCreateEventData:function(){return{header:this.active,content:this.active.length?this.active.next():e()}},_createIcons:function(){var t=this.options.icons;t&&(e("").addClass("ui-accordion-header-icon ui-icon "+t.header).prependTo(this.headers),this.active.children(".ui-accordion-header-icon").removeClass(t.header).addClass(t.activeHeader),this.headers.addClass("ui-accordion-icons"))},_destroyIcons:function(){this.headers.removeClass("ui-accordion-icons").children(".ui-accordion-header-icon").remove()},_destroy:function(){var e;this.element.removeClass("ui-accordion ui-widget ui-helper-reset").removeAttr("role"),this.headers.removeClass("ui-accordion-header ui-accordion-header-active ui-helper-reset ui-state-default ui-corner-all ui-state-active ui-state-disabled ui-corner-top").removeAttr("role").removeAttr("aria-selected").removeAttr("aria-controls").removeAttr("tabIndex").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this._destroyIcons(),e=this.headers.next().css("display","").removeAttr("role").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeClass("ui-helper-reset ui-widget-content ui-corner-bottom ui-accordion-content ui-accordion-content-active ui-state-disabled").each(function(){/^ui-accordion/.test(this.id)&&this.removeAttribute("id")}),this.options.heightStyle!=="content"&&e.css("height","")},_setOption:function(e,t){if(e==="active"){this._activate(t);return}e==="event"&&(this.options.event&&this._off(this.headers,this.options.event),this._setupEvents(t)),this._super(e,t),e==="collapsible"&&!t&&this.options.active===!1&&this._activate(0),e==="icons"&&(this._destroyIcons(),t&&this._createIcons()),e==="disabled"&&this.headers.add(this.headers.next()).toggleClass("ui-state-disabled",!!t)},_keydown:function(t){if(t.altKey||t.ctrlKey)return;var n=e.ui.keyCode,r=this.headers.length,i=this.headers.index(t.target),s=!1;switch(t.keyCode){case n.RIGHT:case n.DOWN:s=this.headers[(i+1)%r];break;case n.LEFT:case n.UP:s=this.headers[(i-1+r)%r];break;case n.SPACE:case n.ENTER:this._eventHandler(t);break;case n.HOME:s=this.headers[0];break;case n.END:s=this.headers[r-1]}s&&(e(t.target).attr("tabIndex",-1),e(s).attr("tabIndex",0),s.focus(),t.preventDefault())},_panelKeyDown:function(t){t.keyCode===e.ui.keyCode.UP&&t.ctrlKey&&e(t.currentTarget).prev().focus()},refresh:function(){var t,n,r=this.options.heightStyle,i=this.element.parent();r==="fill"?(e.support.minHeight||(n=i.css("overflow"),i.css("overflow","hidden")),t=i.height(),this.element.siblings(":visible").each(function(){var n=e(this),r=n.css("position");if(r==="absolute"||r==="fixed")return;t-=n.outerHeight(!0)}),n&&i.css("overflow",n),this.headers.each(function(){t-=e(this).outerHeight(!0)}),this.headers.next().each(function(){e(this).height(Math.max(0,t-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):r==="auto"&&(t=0,this.headers.next().each(function(){t=Math.max(t,e(this).css("height","").height())}).height(t))},_activate:function(t){var n=this._findActive(t)[0];if(n===this.active[0])return;n=n||this.active[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return typeof t=="number"?this.headers.eq(t):e()},_setupEvents:function(t){var n={};if(!t)return;e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._on(this.headers,n)},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i[0]===r[0],o=s&&n.collapsible,u=o?e():i.next(),a=r.next(),f={oldHeader:r,oldPanel:a,newHeader:o?e():i,newPanel:u};t.preventDefault();if(s&&!n.collapsible||this._trigger("beforeActivate",t,f)===!1)return;n.active=o?!1:this.headers.index(i),this.active=s?e():i,this._toggle(f),r.removeClass("ui-accordion-header-active ui-state-active"),n.icons&&r.children(".ui-accordion-header-icon").removeClass(n.icons.activeHeader).addClass(n.icons.header),s||(i.removeClass("ui-corner-all").addClass("ui-accordion-header-active ui-state-active ui-corner-top"),n.icons&&i.children(".ui-accordion-header-icon").removeClass(n.icons.header).addClass(n.icons.activeHeader),i.next().addClass("ui-accordion-content-active"))},_toggle:function(t){var n=t.newPanel,r=this.prevShow.length?this.prevShow:t.oldPanel;this.prevShow.add(this.prevHide).stop(!0,!0),this.prevShow=n,this.prevHide=r,this.options.animate?this._animate(n,r,t):(r.hide(),n.show(),this._toggleComplete(t)),r.attr({"aria-expanded":"false","aria-hidden":"true"}),r.prev().attr("aria-selected","false"),n.length&&r.length?r.prev().attr("tabIndex",-1):n.length&&this.headers.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),n.attr({"aria-expanded":"true","aria-hidden":"false"}).prev().attr({"aria-selected":"true",tabIndex:0})},_animate:function(e,t,n){var s,o,u,a=this,f=0,l=e.length&&(!t.length||e.index()",options:{appendTo:"body",autoFocus:!1,delay:300,minLength:1,position:{my:"left top",at:"left bottom",collision:"none"},source:null,change:null,close:null,focus:null,open:null,response:null,search:null,select:null},pending:0,_create:function(){var t,n,r;this.isMultiLine=this._isMultiLine(),this.valueMethod=this.element[this.element.is("input,textarea")?"val":"text"],this.isNewMenu=!0,this.element.addClass("ui-autocomplete-input").attr("autocomplete","off"),this._on(this.element,{keydown:function(i){if(this.element.prop("readOnly")){t=!0,r=!0,n=!0;return}t=!1,r=!1,n=!1;var s=e.ui.keyCode;switch(i.keyCode){case s.PAGE_UP:t=!0,this._move("previousPage",i);break;case s.PAGE_DOWN:t=!0,this._move("nextPage",i);break;case s.UP:t=!0,this._keyEvent("previous",i);break;case s.DOWN:t=!0,this._keyEvent("next",i);break;case s.ENTER:case s.NUMPAD_ENTER:this.menu.active&&(t=!0,i.preventDefault(),this.menu.select(i));break;case s.TAB:this.menu.active&&this.menu.select(i);break;case s.ESCAPE:this.menu.element.is(":visible")&&(this._value(this.term),this.close(i),i.preventDefault());break;default:n=!0,this._searchTimeout(i)}},keypress:function(r){if(t){t=!1,r.preventDefault();return}if(n)return;var i=e.ui.keyCode;switch(r.keyCode){case i.PAGE_UP:this._move("previousPage",r);break;case i.PAGE_DOWN:this._move("nextPage",r);break;case i.UP:this._keyEvent("previous",r);break;case i.DOWN:this._keyEvent("next",r)}},input:function(e){if(r){r=!1,e.preventDefault();return}this._searchTimeout(e)},focus:function(){this.selectedItem=null,this.previous=this._value()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}clearTimeout(this.searching),this.close(e),this._change(e)}}),this._initSource(),this.menu=e("
'+"";var z=N?'":"";for(var W=0;W<7;W++){var X=(W+T)%7;z+="=5?' class="ui-datepicker-week-end"':"")+">"+''+L[X]+""}U+=z+"";var V=this._getDaysInMonth(d,p);d==e.selectedYear&&p==e.selectedMonth&&(e.selectedDay=Math.min(e.selectedDay,V));var J=(this._getFirstDayOfMonth(d,p)-T+7)%7,K=Math.ceil((J+V)/7),Q=f?this.maxRows>K?this.maxRows:K:K;this.maxRows=Q;var G=this._daylightSavingAdjust(new Date(d,p,1-J));for(var Y=0;Y";var Z=N?'":"";for(var W=0;W<7;W++){var et=M?M.apply(e.input?e.input[0]:null,[G]):[!0,""],tt=G.getMonth()!=p,nt=tt&&!D||!et[0]||c&&Gh;Z+='",G.setDate(G.getDate()+1),G=this._daylightSavingAdjust(G)}U+=Z+""}p++,p>11&&(p=0,d++),U+="
'+this._get(e,"weekHeader")+"
'+this._get(e,"calculateWeek")(G)+""+(tt&&!_?" ":nt?''+G.getDate()+"":''+G.getDate()+"")+"
"+(f?""+(o[0]>0&&I==o[1]-1?'
':""):""),F+=U}B+=F}return B+=x+($.ui.ie6&&!e.inline?'':""),e._keyEvent=!1,B},_generateMonthYearHeader:function(e,t,n,r,i,s,o,u){var a=this._get(e,"changeMonth"),f=this._get(e,"changeYear"),l=this._get(e,"showMonthAfterYear"),c='
',h="";if(s||!a)h+=''+o[t]+"";else{var p=r&&r.getFullYear()==n,d=i&&i.getFullYear()==n;h+='"}l||(c+=h+(s||!a||!f?" ":""));if(!e.yearshtml){e.yearshtml="";if(s||!f)c+=''+n+"";else{var m=this._get(e,"yearRange").split(":"),g=(new Date).getFullYear(),y=function(e){var t=e.match(/c[+-].*/)?n+parseInt(e.substring(1),10):e.match(/[+-].*/)?g+parseInt(e,10):parseInt(e,10);return isNaN(t)?g:t},b=y(m[0]),w=Math.max(b,y(m[1]||""));b=r?Math.max(b,r.getFullYear()):b,w=i?Math.min(w,i.getFullYear()):w,e.yearshtml+='",c+=e.yearshtml,e.yearshtml=null}}return c+=this._get(e,"yearSuffix"),l&&(c+=(s||!a||!f?" ":"")+h),c+="
",c},_adjustInstDate:function(e,t,n){var r=e.drawYear+(n=="Y"?t:0),i=e.drawMonth+(n=="M"?t:0),s=Math.min(e.selectedDay,this._getDaysInMonth(r,i))+(n=="D"?t:0),o=this._restrictMinMax(e,this._daylightSavingAdjust(new Date(r,i,s)));e.selectedDay=o.getDate(),e.drawMonth=e.selectedMonth=o.getMonth(),e.drawYear=e.selectedYear=o.getFullYear(),(n=="M"||n=="Y")&&this._notifyChange(e)},_restrictMinMax:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max"),i=n&&tr?r:i,i},_notifyChange:function(e){var t=this._get(e,"onChangeMonthYear");t&&t.apply(e.input?e.input[0]:null,[e.selectedYear,e.selectedMonth+1,e])},_getNumberOfMonths:function(e){var t=this._get(e,"numberOfMonths");return t==null?[1,1]:typeof t=="number"?[1,t]:t},_getMinMaxDate:function(e,t){return this._determineDate(e,this._get(e,t+"Date"),null)},_getDaysInMonth:function(e,t){return 32-this._daylightSavingAdjust(new Date(e,t,32)).getDate()},_getFirstDayOfMonth:function(e,t){return(new Date(e,t,1)).getDay()},_canAdjustMonth:function(e,t,n,r){var i=this._getNumberOfMonths(e),s=this._daylightSavingAdjust(new Date(n,r+(t<0?t:i[0]*i[1]),1));return t<0&&s.setDate(this._getDaysInMonth(s.getFullYear(),s.getMonth())),this._isInRange(e,s)},_isInRange:function(e,t){var n=this._getMinMaxDate(e,"min"),r=this._getMinMaxDate(e,"max");return(!n||t.getTime()>=n.getTime())&&(!r||t.getTime()<=r.getTime())},_getFormatConfig:function(e){var t=this._get(e,"shortYearCutoff");return t=typeof t!="string"?t:(new Date).getFullYear()%100+parseInt(t,10),{shortYearCutoff:t,dayNamesShort:this._get(e,"dayNamesShort"),dayNames:this._get(e,"dayNames"),monthNamesShort:this._get(e,"monthNamesShort"),monthNames:this._get(e,"monthNames")}},_formatDate:function(e,t,n,r){t||(e.currentDay=e.selectedDay,e.currentMonth=e.selectedMonth,e.currentYear=e.selectedYear);var i=t?typeof t=="object"?t:this._daylightSavingAdjust(new Date(r,n,t)):this._daylightSavingAdjust(new Date(e.currentYear,e.currentMonth,e.currentDay));return this.formatDate(this._get(e,"dateFormat"),i,this._getFormatConfig(e))}}),$.fn.datepicker=function(e){if(!this.length)return this;$.datepicker.initialized||($(document).mousedown($.datepicker._checkExternalClick).find(document.body).append($.datepicker.dpDiv),$.datepicker.initialized=!0);var t=Array.prototype.slice.call(arguments,1);return typeof e!="string"||e!="isDisabled"&&e!="getDate"&&e!="widget"?e=="option"&&arguments.length==2&&typeof arguments[1]=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t)):this.each(function(){typeof e=="string"?$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this].concat(t)):$.datepicker._attachDatepicker(this,e)}):$.datepicker["_"+e+"Datepicker"].apply($.datepicker,[this[0]].concat(t))},$.datepicker=new Datepicker,$.datepicker.initialized=!1,$.datepicker.uuid=(new Date).getTime(),$.datepicker.version="1.9.2",window["DP_jQuery_"+dpuuid]=$})(jQuery);(function(e,t){var n="ui-dialog ui-widget ui-widget-content ui-corner-all ",r={buttons:!0,height:!0,maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0,width:!0},i={maxHeight:!0,maxWidth:!0,minHeight:!0,minWidth:!0};e.widget("ui.dialog",{version:"1.9.2",options:{autoOpen:!0,buttons:{},closeOnEscape:!0,closeText:"close",dialogClass:"",draggable:!0,hide:null,height:"auto",maxHeight:!1,maxWidth:!1,minHeight:150,minWidth:150,modal:!1,position:{my:"center",at:"center",of:window,collision:"fit",using:function(t){var n=e(this).css(t).offset().top;n<0&&e(this).css("top",t.top-n)}},resizable:!0,show:null,stack:!0,title:"",width:300,zIndex:1e3},_create:function(){this.originalTitle=this.element.attr("title"),typeof this.originalTitle!="string"&&(this.originalTitle=""),this.oldPosition={parent:this.element.parent(),index:this.element.parent().children().index(this.element)},this.options.title=this.options.title||this.originalTitle;var t=this,r=this.options,i=r.title||" ",s,o,u,a,f;s=(this.uiDialog=e("
")).addClass(n+r.dialogClass).css({display:"none",outline:0,zIndex:r.zIndex}).attr("tabIndex",-1).keydown(function(n){r.closeOnEscape&&!n.isDefaultPrevented()&&n.keyCode&&n.keyCode===e.ui.keyCode.ESCAPE&&(t.close(n),n.preventDefault())}).mousedown(function(e){t.moveToTop(!1,e)}).appendTo("body"),this.element.show().removeAttr("title").addClass("ui-dialog-content ui-widget-content").appendTo(s),o=(this.uiDialogTitlebar=e("
")).addClass("ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix").bind("mousedown",function(){s.focus()}).prependTo(s),u=e("").addClass("ui-dialog-titlebar-close ui-corner-all").attr("role","button").click(function(e){e.preventDefault(),t.close(e)}).appendTo(o),(this.uiDialogTitlebarCloseText=e("")).addClass("ui-icon ui-icon-closethick").text(r.closeText).appendTo(u),a=e("").uniqueId().addClass("ui-dialog-title").html(i).prependTo(o),f=(this.uiDialogButtonPane=e("
")).addClass("ui-dialog-buttonpane ui-widget-content ui-helper-clearfix"),(this.uiButtonSet=e("
")).addClass("ui-dialog-buttonset").appendTo(f),s.attr({role:"dialog","aria-labelledby":a.attr("id")}),o.find("*").add(o).disableSelection(),this._hoverable(u),this._focusable(u),r.draggable&&e.fn.draggable&&this._makeDraggable(),r.resizable&&e.fn.resizable&&this._makeResizable(),this._createButtons(r.buttons),this._isOpen=!1,e.fn.bgiframe&&s.bgiframe(),this._on(s,{keydown:function(t){if(!r.modal||t.keyCode!==e.ui.keyCode.TAB)return;var n=e(":tabbable",s),i=n.filter(":first"),o=n.filter(":last");if(t.target===o[0]&&!t.shiftKey)return i.focus(1),!1;if(t.target===i[0]&&t.shiftKey)return o.focus(1),!1}})},_init:function(){this.options.autoOpen&&this.open()},_destroy:function(){var e,t=this.oldPosition;this.overlay&&this.overlay.destroy(),this.uiDialog.hide(),this.element.removeClass("ui-dialog-content ui-widget-content").hide().appendTo("body"),this.uiDialog.remove(),this.originalTitle&&this.element.attr("title",this.originalTitle),e=t.parent.children().eq(t.index),e.length&&e[0]!==this.element[0]?e.before(this.element):t.parent.append(this.element)},widget:function(){return this.uiDialog},close:function(t){var n=this,r,i;if(!this._isOpen)return;if(!1===this._trigger("beforeClose",t))return;return this._isOpen=!1,this.overlay&&this.overlay.destroy(),this.options.hide?this._hide(this.uiDialog,this.options.hide,function(){n._trigger("close",t)}):(this.uiDialog.hide(),this._trigger("close",t)),e.ui.dialog.overlay.resize(),this.options.modal&&(r=0,e(".ui-dialog").each(function(){this!==n.uiDialog[0]&&(i=e(this).css("z-index"),isNaN(i)||(r=Math.max(r,i)))}),e.ui.dialog.maxZ=r),this},isOpen:function(){return this._isOpen},moveToTop:function(t,n){var r=this.options,i;return r.modal&&!t||!r.stack&&!r.modal?this._trigger("focus",n):(r.zIndex>e.ui.dialog.maxZ&&(e.ui.dialog.maxZ=r.zIndex),this.overlay&&(e.ui.dialog.maxZ+=1,e.ui.dialog.overlay.maxZ=e.ui.dialog.maxZ,this.overlay.$el.css("z-index",e.ui.dialog.overlay.maxZ)),i={scrollTop:this.element.scrollTop(),scrollLeft:this.element.scrollLeft()},e.ui.dialog.maxZ+=1,this.uiDialog.css("z-index",e.ui.dialog.maxZ),this.element.attr(i),this._trigger("focus",n),this)},open:function(){if(this._isOpen)return;var t,n=this.options,r=this.uiDialog;return this._size(),this._position(n.position),r.show(n.show),this.overlay=n.modal?new e.ui.dialog.overlay(this):null,this.moveToTop(!0),t=this.element.find(":tabbable"),t.length||(t=this.uiDialogButtonPane.find(":tabbable"),t.length||(t=r)),t.eq(0).focus(),this._isOpen=!0,this._trigger("open"),this},_createButtons:function(t){var n=this,r=!1;this.uiDialogButtonPane.remove(),this.uiButtonSet.empty(),typeof t=="object"&&t!==null&&e.each(t,function(){return!(r=!0)}),r?(e.each(t,function(t,r){var i,s;r=e.isFunction(r)?{click:r,text:t}:r,r=e.extend({type:"button"},r),s=r.click,r.click=function(){s.apply(n.element[0],arguments)},i=e("",r).appendTo(n.uiButtonSet),e.fn.button&&i.button()}),this.uiDialog.addClass("ui-dialog-buttons"),this.uiDialogButtonPane.appendTo(this.uiDialog)):this.uiDialog.removeClass("ui-dialog-buttons")},_makeDraggable:function(){function r(e){return{position:e.position,offset:e.offset}}var t=this,n=this.options;this.uiDialog.draggable({cancel:".ui-dialog-content, .ui-dialog-titlebar-close",handle:".ui-dialog-titlebar",containment:"document",start:function(n,i){e(this).addClass("ui-dialog-dragging"),t._trigger("dragStart",n,r(i))},drag:function(e,n){t._trigger("drag",e,r(n))},stop:function(i,s){n.position=[s.position.left-t.document.scrollLeft(),s.position.top-t.document.scrollTop()],e(this).removeClass("ui-dialog-dragging"),t._trigger("dragStop",i,r(s)),e.ui.dialog.overlay.resize()}})},_makeResizable:function(n){function u(e){return{originalPosition:e.originalPosition,originalSize:e.originalSize,position:e.position,size:e.size}}n=n===t?this.options.resizable:n;var r=this,i=this.options,s=this.uiDialog.css("position"),o=typeof n=="string"?n:"n,e,s,w,se,sw,ne,nw";this.uiDialog.resizable({cancel:".ui-dialog-content",containment:"document",alsoResize:this.element,maxWidth:i.maxWidth,maxHeight:i.maxHeight,minWidth:i.minWidth,minHeight:this._minHeight(),handles:o,start:function(t,n){e(this).addClass("ui-dialog-resizing"),r._trigger("resizeStart",t,u(n))},resize:function(e,t){r._trigger("resize",e,u(t))},stop:function(t,n){e(this).removeClass("ui-dialog-resizing"),i.height=e(this).height(),i.width=e(this).width(),r._trigger("resizeStop",t,u(n)),e.ui.dialog.overlay.resize()}}).css("position",s).find(".ui-resizable-se").addClass("ui-icon ui-icon-grip-diagonal-se")},_minHeight:function(){var e=this.options;return e.height==="auto"?e.minHeight:Math.min(e.minHeight,e.height)},_position:function(t){var n=[],r=[0,0],i;if(t){if(typeof t=="string"||typeof t=="object"&&"0"in t)n=t.split?t.split(" "):[t[0],t[1]],n.length===1&&(n[1]=n[0]),e.each(["left","top"],function(e,t){+n[e]===n[e]&&(r[e]=n[e],n[e]=t)}),t={my:n[0]+(r[0]<0?r[0]:"+"+r[0])+" "+n[1]+(r[1]<0?r[1]:"+"+r[1]),at:n.join(" ")};t=e.extend({},e.ui.dialog.prototype.options.position,t)}else t=e.ui.dialog.prototype.options.position;i=this.uiDialog.is(":visible"),i||this.uiDialog.show(),this.uiDialog.position(t),i||this.uiDialog.hide()},_setOptions:function(t){var n=this,s={},o=!1;e.each(t,function(e,t){n._setOption(e,t),e in r&&(o=!0),e in i&&(s[e]=t)}),o&&this._size(),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option",s)},_setOption:function(t,r){var i,s,o=this.uiDialog;switch(t){case"buttons":this._createButtons(r);break;case"closeText":this.uiDialogTitlebarCloseText.text(""+r);break;case"dialogClass":o.removeClass(this.options.dialogClass).addClass(n+r);break;case"disabled":r?o.addClass("ui-dialog-disabled"):o.removeClass("ui-dialog-disabled");break;case"draggable":i=o.is(":data(draggable)"),i&&!r&&o.draggable("destroy"),!i&&r&&this._makeDraggable();break;case"position":this._position(r);break;case"resizable":s=o.is(":data(resizable)"),s&&!r&&o.resizable("destroy"),s&&typeof r=="string"&&o.resizable("option","handles",r),!s&&r!==!1&&this._makeResizable(r);break;case"title":e(".ui-dialog-title",this.uiDialogTitlebar).html(""+(r||" "))}this._super(t,r)},_size:function(){var t,n,r,i=this.options,s=this.uiDialog.is(":visible");this.element.show().css({width:"auto",minHeight:0,height:0}),i.minWidth>i.width&&(i.width=i.minWidth),t=this.uiDialog.css({height:"auto",width:i.width}).outerHeight(),n=Math.max(0,i.minHeight-t),i.height==="auto"?e.support.minHeight?this.element.css({minHeight:n,height:"auto"}):(this.uiDialog.show(),r=this.element.css("height","auto").height(),s||this.uiDialog.hide(),this.element.height(Math.max(r,n))):this.element.height(Math.max(i.height-t,0)),this.uiDialog.is(":data(resizable)")&&this.uiDialog.resizable("option","minHeight",this._minHeight())}}),e.extend(e.ui.dialog,{uuid:0,maxZ:0,getTitleId:function(e){var t=e.attr("id");return t||(this.uuid+=1,t=this.uuid),"ui-dialog-title-"+t},overlay:function(t){this.$el=e.ui.dialog.overlay.create(t)}}),e.extend(e.ui.dialog.overlay,{instances:[],oldInstances:[],maxZ:0,events:e.map("focus,mousedown,mouseup,keydown,keypress,click".split(","),function(e){return e+".dialog-overlay"}).join(" "),create:function(t){this.instances.length===0&&(setTimeout(function(){e.ui.dialog.overlay.instances.length&&e(document).bind(e.ui.dialog.overlay.events,function(t){if(e(t.target).zIndex()").addClass("ui-widget-overlay");return e(document).bind("keydown.dialog-overlay",function(r){var i=e.ui.dialog.overlay.instances;i.length!==0&&i[i.length-1]===n&&t.options.closeOnEscape&&!r.isDefaultPrevented()&&r.keyCode&&r.keyCode===e.ui.keyCode.ESCAPE&&(t.close(r),r.preventDefault())}),n.appendTo(document.body).css({width:this.width(),height:this.height()}),e.fn.bgiframe&&n.bgiframe(),this.instances.push(n),n},destroy:function(t){var n=e.inArray(t,this.instances),r=0;n!==-1&&this.oldInstances.push(this.instances.splice(n,1)[0]),this.instances.length===0&&e([document,window]).unbind(".dialog-overlay"),t.height(0).width(0).remove(),e.each(this.instances,function(){r=Math.max(r,this.css("z-index"))}),this.maxZ=r},height:function(){var t,n;return e.ui.ie?(t=Math.max(document.documentElement.scrollHeight,document.body.scrollHeight),n=Math.max(document.documentElement.offsetHeight,document.body.offsetHeight),t",delay:300,options:{icons:{submenu:"ui-icon-carat-1-e"},menus:"ul",position:{my:"left top",at:"right top"},role:"menu",blur:null,focus:null,select:null},_create:function(){this.activeMenu=this.element,this.element.uniqueId().addClass("ui-menu ui-widget ui-widget-content ui-corner-all").toggleClass("ui-menu-icons",!!this.element.find(".ui-icon").length).attr({role:this.options.role,tabIndex:0}).bind("click"+this.eventNamespace,e.proxy(function(e){this.options.disabled&&e.preventDefault()},this)),this.options.disabled&&this.element.addClass("ui-state-disabled").attr("aria-disabled","true"),this._on({"mousedown .ui-menu-item > a":function(e){e.preventDefault()},"click .ui-state-disabled > a":function(e){e.preventDefault()},"click .ui-menu-item:has(a)":function(t){var r=e(t.target).closest(".ui-menu-item");!n&&r.not(".ui-state-disabled").length&&(n=!0,this.select(t),r.has(".ui-menu").length?this.expand(t):this.element.is(":focus")||(this.element.trigger("focus",[!0]),this.active&&this.active.parents(".ui-menu").length===1&&clearTimeout(this.timer)))},"mouseenter .ui-menu-item":function(t){var n=e(t.currentTarget);n.siblings().children(".ui-state-active").removeClass("ui-state-active"),this.focus(t,n)},mouseleave:"collapseAll","mouseleave .ui-menu":"collapseAll",focus:function(e,t){var n=this.active||this.element.children(".ui-menu-item").eq(0);t||this.focus(e,n)},blur:function(t){this._delay(function(){e.contains(this.element[0],this.document[0].activeElement)||this.collapseAll(t)})},keydown:"_keydown"}),this.refresh(),this._on(this.document,{click:function(t){e(t.target).closest(".ui-menu").length||this.collapseAll(t),n=!1}})},_destroy:function(){this.element.removeAttr("aria-activedescendant").find(".ui-menu").andSelf().removeClass("ui-menu ui-widget ui-widget-content ui-corner-all ui-menu-icons").removeAttr("role").removeAttr("tabIndex").removeAttr("aria-labelledby").removeAttr("aria-expanded").removeAttr("aria-hidden").removeAttr("aria-disabled").removeUniqueId().show(),this.element.find(".ui-menu-item").removeClass("ui-menu-item").removeAttr("role").removeAttr("aria-disabled").children("a").removeUniqueId().removeClass("ui-corner-all ui-state-hover").removeAttr("tabIndex").removeAttr("role").removeAttr("aria-haspopup").children().each(function(){var t=e(this);t.data("ui-menu-submenu-carat")&&t.remove()}),this.element.find(".ui-menu-divider").removeClass("ui-menu-divider ui-widget-content")},_keydown:function(t){function a(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}var n,r,i,s,o,u=!0;switch(t.keyCode){case e.ui.keyCode.PAGE_UP:this.previousPage(t);break;case e.ui.keyCode.PAGE_DOWN:this.nextPage(t);break;case e.ui.keyCode.HOME:this._move("first","first",t);break;case e.ui.keyCode.END:this._move("last","last",t);break;case e.ui.keyCode.UP:this.previous(t);break;case e.ui.keyCode.DOWN:this.next(t);break;case e.ui.keyCode.LEFT:this.collapse(t);break;case e.ui.keyCode.RIGHT:this.active&&!this.active.is(".ui-state-disabled")&&this.expand(t);break;case e.ui.keyCode.ENTER:case e.ui.keyCode.SPACE:this._activate(t);break;case e.ui.keyCode.ESCAPE:this.collapse(t);break;default:u=!1,r=this.previousFilter||"",i=String.fromCharCode(t.keyCode),s=!1,clearTimeout(this.filterTimer),i===r?s=!0:i=r+i,o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())}),n=s&&n.index(this.active.next())!==-1?this.active.nextAll(".ui-menu-item"):n,n.length||(i=String.fromCharCode(t.keyCode),o=new RegExp("^"+a(i),"i"),n=this.activeMenu.children(".ui-menu-item").filter(function(){return o.test(e(this).children("a").text())})),n.length?(this.focus(t,n),n.length>1?(this.previousFilter=i,this.filterTimer=this._delay(function(){delete this.previousFilter},1e3)):delete this.previousFilter):delete this.previousFilter}u&&t.preventDefault()},_activate:function(e){this.active.is(".ui-state-disabled")||(this.active.children("a[aria-haspopup='true']").length?this.expand(e):this.select(e))},refresh:function(){var t,n=this.options.icons.submenu,r=this.element.find(this.options.menus);r.filter(":not(.ui-menu)").addClass("ui-menu ui-widget ui-widget-content ui-corner-all").hide().attr({role:this.options.role,"aria-hidden":"true","aria-expanded":"false"}).each(function(){var t=e(this),r=t.prev("a"),i=e("").addClass("ui-menu-icon ui-icon "+n).data("ui-menu-submenu-carat",!0);r.attr("aria-haspopup","true").prepend(i),t.attr("aria-labelledby",r.attr("id"))}),t=r.add(this.element),t.children(":not(.ui-menu-item):has(a)").addClass("ui-menu-item").attr("role","presentation").children("a").uniqueId().addClass("ui-corner-all").attr({tabIndex:-1,role:this._itemRole()}),t.children(":not(.ui-menu-item)").each(function(){var t=e(this);/[^\-—–\s]/.test(t.text())||t.addClass("ui-widget-content ui-menu-divider")}),t.children(".ui-state-disabled").attr("aria-disabled","true"),this.active&&!e.contains(this.element[0],this.active[0])&&this.blur()},_itemRole:function(){return{menu:"menuitem",listbox:"option"}[this.options.role]},focus:function(e,t){var n,r;this.blur(e,e&&e.type==="focus"),this._scrollIntoView(t),this.active=t.first(),r=this.active.children("a").addClass("ui-state-focus"),this.options.role&&this.element.attr("aria-activedescendant",r.attr("id")),this.active.parent().closest(".ui-menu-item").children("a:first").addClass("ui-state-active"),e&&e.type==="keydown"?this._close():this.timer=this._delay(function(){this._close()},this.delay),n=t.children(".ui-menu"),n.length&&/^mouse/.test(e.type)&&this._startOpening(n),this.activeMenu=t.parent(),this._trigger("focus",e,{item:t})},_scrollIntoView:function(t){var n,r,i,s,o,u;this._hasScroll()&&(n=parseFloat(e.css(this.activeMenu[0],"borderTopWidth"))||0,r=parseFloat(e.css(this.activeMenu[0],"paddingTop"))||0,i=t.offset().top-this.activeMenu.offset().top-n-r,s=this.activeMenu.scrollTop(),o=this.activeMenu.height(),u=t.height(),i<0?this.activeMenu.scrollTop(s+i):i+u>o&&this.activeMenu.scrollTop(s+i-o+u))},blur:function(e,t){t||clearTimeout(this.timer);if(!this.active)return;this.active.children("a").removeClass("ui-state-focus"),this.active=null,this._trigger("blur",e,{item:this.active})},_startOpening:function(e){clearTimeout(this.timer);if(e.attr("aria-hidden")!=="true")return;this.timer=this._delay(function(){this._close(),this._open(e)},this.delay)},_open:function(t){var n=e.extend({of:this.active},this.options.position);clearTimeout(this.timer),this.element.find(".ui-menu").not(t.parents(".ui-menu")).hide().attr("aria-hidden","true"),t.show().removeAttr("aria-hidden").attr("aria-expanded","true").position(n)},collapseAll:function(t,n){clearTimeout(this.timer),this.timer=this._delay(function(){var r=n?this.element:e(t&&t.target).closest(this.element.find(".ui-menu"));r.length||(r=this.element),this._close(r),this.blur(t),this.activeMenu=r},this.delay)},_close:function(e){e||(e=this.active?this.active.parent():this.element),e.find(".ui-menu").hide().attr("aria-hidden","true").attr("aria-expanded","false").end().find("a.ui-state-active").removeClass("ui-state-active")},collapse:function(e){var t=this.active&&this.active.parent().closest(".ui-menu-item",this.element);t&&t.length&&(this._close(),this.focus(e,t))},expand:function(e){var t=this.active&&this.active.children(".ui-menu ").children(".ui-menu-item").first();t&&t.length&&(this._open(t.parent()),this._delay(function(){this.focus(e,t)}))},next:function(e){this._move("next","first",e)},previous:function(e){this._move("prev","last",e)},isFirstItem:function(){return this.active&&!this.active.prevAll(".ui-menu-item").length},isLastItem:function(){return this.active&&!this.active.nextAll(".ui-menu-item").length},_move:function(e,t,n){var r;this.active&&(e==="first"||e==="last"?r=this.active[e==="first"?"prevAll":"nextAll"](".ui-menu-item").eq(-1):r=this.active[e+"All"](".ui-menu-item").eq(0));if(!r||!r.length||!this.active)r=this.activeMenu.children(".ui-menu-item")[t]();this.focus(n,r)},nextPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isLastItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.nextAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r-i<0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item")[this.active?"last":"first"]())},previousPage:function(t){var n,r,i;if(!this.active){this.next(t);return}if(this.isFirstItem())return;this._hasScroll()?(r=this.active.offset().top,i=this.element.height(),this.active.prevAll(".ui-menu-item").each(function(){return n=e(this),n.offset().top-r+i>0}),this.focus(t,n)):this.focus(t,this.activeMenu.children(".ui-menu-item").first())},_hasScroll:function(){return this.element.outerHeight()
").appendTo(this.element),this.oldValue=this._value(),this._refreshValue()},_destroy:function(){this.element.removeClass("ui-progressbar ui-widget ui-widget-content ui-corner-all").removeAttr("role").removeAttr("aria-valuemin").removeAttr("aria-valuemax").removeAttr("aria-valuenow"),this.valueDiv.remove()},value:function(e){return e===t?this._value():(this._setOption("value",e),this)},_setOption:function(e,t){e==="value"&&(this.options.value=t,this._refreshValue(),this._value()===this.options.max&&this._trigger("complete")),this._super(e,t)},_value:function(){var e=this.options.value;return typeof e!="number"&&(e=0),Math.min(this.options.max,Math.max(this.min,e))},_percentage:function(){return 100*this._value()/this.options.max},_refreshValue:function(){var e=this.value(),t=this._percentage();this.oldValue!==e&&(this.oldValue=e,this._trigger("change")),this.valueDiv.toggle(e>this.min).toggleClass("ui-corner-right",e===this.options.max).width(t.toFixed(0)+"%"),this.element.attr("aria-valuenow",e)}})})(jQuery);(function(e,t){var n=5;e.widget("ui.slider",e.ui.mouse,{version:"1.9.2",widgetEventPrefix:"slide",options:{animate:!1,distance:0,max:100,min:0,orientation:"horizontal",range:!1,step:1,value:0,values:null},_create:function(){var t,r,i=this.options,s=this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"),o="",u=[];this._keySliding=!1,this._mouseSliding=!1,this._animateOff=!0,this._handleIndex=null,this._detectOrientation(),this._mouseInit(),this.element.addClass("ui-slider ui-slider-"+this.orientation+" ui-widget"+" ui-widget-content"+" ui-corner-all"+(i.disabled?" ui-slider-disabled ui-disabled":"")),this.range=e([]),i.range&&(i.range===!0&&(i.values||(i.values=[this._valueMin(),this._valueMin()]),i.values.length&&i.values.length!==2&&(i.values=[i.values[0],i.values[0]])),this.range=e("
").appendTo(this.element).addClass("ui-slider-range ui-widget-header"+(i.range==="min"||i.range==="max"?" ui-slider-range-"+i.range:""))),r=i.values&&i.values.length||1;for(t=s.length;tn&&(i=n,s=e(this),o=t)}),c.range===!0&&this.values(1)===c.min&&(o+=1,s=e(this.handles[o])),u=this._start(t,o),u===!1?!1:(this._mouseSliding=!0,this._handleIndex=o,s.addClass("ui-state-active").focus(),a=s.offset(),f=!e(t.target).parents().andSelf().is(".ui-slider-handle"),this._clickOffset=f?{left:0,top:0}:{left:t.pageX-a.left-s.width()/2,top:t.pageY-a.top-s.height()/2-(parseInt(s.css("borderTopWidth"),10)||0)-(parseInt(s.css("borderBottomWidth"),10)||0)+(parseInt(s.css("marginTop"),10)||0)},this.handles.hasClass("ui-state-hover")||this._slide(t,o,r),this._animateOff=!0,!0))},_mouseStart:function(){return!0},_mouseDrag:function(e){var t={x:e.pageX,y:e.pageY},n=this._normValueFromMouse(t);return this._slide(e,this._handleIndex,n),!1},_mouseStop:function(e){return this.handles.removeClass("ui-state-active"),this._mouseSliding=!1,this._stop(e,this._handleIndex),this._change(e,this._handleIndex),this._handleIndex=null,this._clickOffset=null,this._animateOff=!1,!1},_detectOrientation:function(){this.orientation=this.options.orientation==="vertical"?"vertical":"horizontal"},_normValueFromMouse:function(e){var t,n,r,i,s;return this.orientation==="horizontal"?(t=this.elementSize.width,n=e.x-this.elementOffset.left-(this._clickOffset?this._clickOffset.left:0)):(t=this.elementSize.height,n=e.y-this.elementOffset.top-(this._clickOffset?this._clickOffset.top:0)),r=n/t,r>1&&(r=1),r<0&&(r=0),this.orientation==="vertical"&&(r=1-r),i=this._valueMax()-this._valueMin(),s=this._valueMin()+r*i,this._trimAlignValue(s)},_start:function(e,t){var n={handle:this.handles[t],value:this.value()};return this.options.values&&this.options.values.length&&(n.value=this.values(t),n.values=this.values()),this._trigger("start",e,n)},_slide:function(e,t,n){var r,i,s;this.options.values&&this.options.values.length?(r=this.values(t?0:1),this.options.values.length===2&&this.options.range===!0&&(t===0&&n>r||t===1&&n1){this.options.values[t]=this._trimAlignValue(n),this._refreshValue(),this._change(null,t);return}if(!arguments.length)return this._values();if(!e.isArray(arguments[0]))return this.options.values&&this.options.values.length?this._values(t):this.value();r=this.options.values,i=arguments[0];for(s=0;s=this._valueMax())return this._valueMax();var t=this.options.step>0?this.options.step:1,n=(e-this._valueMin())%t,r=e-n;return Math.abs(n)*2>=t&&(r+=n>0?t:-t),parseFloat(r.toFixed(5))},_valueMin:function(){return this.options.min},_valueMax:function(){return this.options.max},_refreshValue:function(){var t,n,r,i,s,o=this.options.range,u=this.options,a=this,f=this._animateOff?!1:u.animate,l={};this.options.values&&this.options.values.length?this.handles.each(function(r){n=(a.values(r)-a._valueMin())/(a._valueMax()-a._valueMin())*100,l[a.orientation==="horizontal"?"left":"bottom"]=n+"%",e(this).stop(1,1)[f?"animate":"css"](l,u.animate),a.options.range===!0&&(a.orientation==="horizontal"?(r===0&&a.range.stop(1,1)[f?"animate":"css"]({left:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({width:n-t+"%"},{queue:!1,duration:u.animate})):(r===0&&a.range.stop(1,1)[f?"animate":"css"]({bottom:n+"%"},u.animate),r===1&&a.range[f?"animate":"css"]({height:n-t+"%"},{queue:!1,duration:u.animate}))),t=n}):(r=this.value(),i=this._valueMin(),s=this._valueMax(),n=s!==i?(r-i)/(s-i)*100:0,l[this.orientation==="horizontal"?"left":"bottom"]=n+"%",this.handle.stop(1,1)[f?"animate":"css"](l,u.animate),o==="min"&&this.orientation==="horizontal"&&this.range.stop(1,1)[f?"animate":"css"]({width:n+"%"},u.animate),o==="max"&&this.orientation==="horizontal"&&this.range[f?"animate":"css"]({width:100-n+"%"},{queue:!1,duration:u.animate}),o==="min"&&this.orientation==="vertical"&&this.range.stop(1,1)[f?"animate":"css"]({height:n+"%"},u.animate),o==="max"&&this.orientation==="vertical"&&this.range[f?"animate":"css"]({height:100-n+"%"},{queue:!1,duration:u.animate}))}})})(jQuery);(function(e){function t(e){return function(){var t=this.element.val();e.apply(this,arguments),this._refresh(),t!==this.element.val()&&this._trigger("change")}}e.widget("ui.spinner",{version:"1.9.2",defaultElement:"",widgetEventPrefix:"spin",options:{culture:null,icons:{down:"ui-icon-triangle-1-s",up:"ui-icon-triangle-1-n"},incremental:!0,max:null,min:null,numberFormat:null,page:10,step:1,change:null,spin:null,start:null,stop:null},_create:function(){this._setOption("max",this.options.max),this._setOption("min",this.options.min),this._setOption("step",this.options.step),this._value(this.element.val(),!0),this._draw(),this._on(this._events),this._refresh(),this._on(this.window,{beforeunload:function(){this.element.removeAttr("autocomplete")}})},_getCreateOptions:function(){var t={},n=this.element;return e.each(["min","max","step"],function(e,r){var i=n.attr(r);i!==undefined&&i.length&&(t[r]=i)}),t},_events:{keydown:function(e){this._start(e)&&this._keydown(e)&&e.preventDefault()},keyup:"_stop",focus:function(){this.previous=this.element.val()},blur:function(e){if(this.cancelBlur){delete this.cancelBlur;return}this._refresh(),this.previous!==this.element.val()&&this._trigger("change",e)},mousewheel:function(e,t){if(!t)return;if(!this.spinning&&!this._start(e))return!1;this._spin((t>0?1:-1)*this.options.step,e),clearTimeout(this.mousewheelTimer),this.mousewheelTimer=this._delay(function(){this.spinning&&this._stop(e)},100),e.preventDefault()},"mousedown .ui-spinner-button":function(t){function r(){var e=this.element[0]===this.document[0].activeElement;e||(this.element.focus(),this.previous=n,this._delay(function(){this.previous=n}))}var n;n=this.element[0]===this.document[0].activeElement?this.previous:this.element.val(),t.preventDefault(),r.call(this),this.cancelBlur=!0,this._delay(function(){delete this.cancelBlur,r.call(this)});if(this._start(t)===!1)return;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseup .ui-spinner-button":"_stop","mouseenter .ui-spinner-button":function(t){if(!e(t.currentTarget).hasClass("ui-state-active"))return;if(this._start(t)===!1)return!1;this._repeat(null,e(t.currentTarget).hasClass("ui-spinner-up")?1:-1,t)},"mouseleave .ui-spinner-button":"_stop"},_draw:function(){var e=this.uiSpinner=this.element.addClass("ui-spinner-input").attr("autocomplete","off").wrap(this._uiSpinnerHtml()).parent().append(this._buttonHtml());this.element.attr("role","spinbutton"),this.buttons=e.find(".ui-spinner-button").attr("tabIndex",-1).button().removeClass("ui-corner-all"),this.buttons.height()>Math.ceil(e.height()*.5)&&e.height()>0&&e.height(e.height()),this.options.disabled&&this.disable()},_keydown:function(t){var n=this.options,r=e.ui.keyCode;switch(t.keyCode){case r.UP:return this._repeat(null,1,t),!0;case r.DOWN:return this._repeat(null,-1,t),!0;case r.PAGE_UP:return this._repeat(null,n.page,t),!0;case r.PAGE_DOWN:return this._repeat(null,-n.page,t),!0}return!1},_uiSpinnerHtml:function(){return""},_buttonHtml:function(){return""+""+""+""+""},_start:function(e){return!this.spinning&&this._trigger("start",e)===!1?!1:(this.counter||(this.counter=1),this.spinning=!0,!0)},_repeat:function(e,t,n){e=e||500,clearTimeout(this.timer),this.timer=this._delay(function(){this._repeat(40,t,n)},e),this._spin(t*this.options.step,n)},_spin:function(e,t){var n=this.value()||0;this.counter||(this.counter=1),n=this._adjustValue(n+e*this._increment(this.counter));if(!this.spinning||this._trigger("spin",t,{value:n})!==!1)this._value(n),this.counter++},_increment:function(t){var n=this.options.incremental;return n?e.isFunction(n)?n(t):Math.floor(t*t*t/5e4-t*t/500+17*t/200+1):1},_precision:function(){var e=this._precisionOf(this.options.step);return this.options.min!==null&&(e=Math.max(e,this._precisionOf(this.options.min))),e},_precisionOf:function(e){var t=e.toString(),n=t.indexOf(".");return n===-1?0:t.length-n-1},_adjustValue:function(e){var t,n,r=this.options;return t=r.min!==null?r.min:0,n=e-t,n=Math.round(n/r.step)*r.step,e=t+n,e=parseFloat(e.toFixed(this._precision())),r.max!==null&&e>r.max?r.max:r.min!==null&&e1&&e.href.replace(r,"")===location.href.replace(r,"").replace(/\s/g,"%20")}var n=0,r=/#.*$/;e.widget("ui.tabs",{version:"1.9.2",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var t=this,n=this.options,r=n.active,i=location.hash.substring(1);this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",n.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(t){e(this).is(".ui-state-disabled")&&t.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){e(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs();if(r===null){i&&this.tabs.each(function(t,n){if(e(n).attr("aria-controls")===i)return r=t,!1}),r===null&&(r=this.tabs.index(this.tabs.filter(".ui-tabs-active")));if(r===null||r===-1)r=this.tabs.length?0:!1}r!==!1&&(r=this.tabs.index(this.tabs.eq(r)),r===-1&&(r=n.collapsible?!1:0)),n.active=r,!n.collapsible&&n.active===!1&&this.anchors.length&&(n.active=0),e.isArray(n.disabled)&&(n.disabled=e.unique(n.disabled.concat(e.map(this.tabs.filter(".ui-state-disabled"),function(e){return t.tabs.index(e)}))).sort()),this.options.active!==!1&&this.anchors.length?this.active=this._findActive(this.options.active):this.active=e(),this._refresh(),this.active.length&&this.load(n.active)},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):e()}},_tabKeydown:function(t){var n=e(this.document[0].activeElement).closest("li"),r=this.tabs.index(n),i=!0;if(this._handlePageNav(t))return;switch(t.keyCode){case e.ui.keyCode.RIGHT:case e.ui.keyCode.DOWN:r++;break;case e.ui.keyCode.UP:case e.ui.keyCode.LEFT:i=!1,r--;break;case e.ui.keyCode.END:r=this.anchors.length-1;break;case e.ui.keyCode.HOME:r=0;break;case e.ui.keyCode.SPACE:t.preventDefault(),clearTimeout(this.activating),this._activate(r);return;case e.ui.keyCode.ENTER:t.preventDefault(),clearTimeout(this.activating),this._activate(r===this.options.active?!1:r);return;default:return}t.preventDefault(),clearTimeout(this.activating),r=this._focusNextTab(r,i),t.ctrlKey||(n.attr("aria-selected","false"),this.tabs.eq(r).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",r)},this.delay))},_panelKeydown:function(t){if(this._handlePageNav(t))return;t.ctrlKey&&t.keyCode===e.ui.keyCode.UP&&(t.preventDefault(),this.active.focus())},_handlePageNav:function(t){if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_UP)return this._activate(this._focusNextTab(this.options.active-1,!1)),!0;if(t.altKey&&t.keyCode===e.ui.keyCode.PAGE_DOWN)return this._activate(this._focusNextTab(this.options.active+1,!0)),!0},_findNextTab:function(t,n){function i(){return t>r&&(t=0),t<0&&(t=r),t}var r=this.tabs.length-1;while(e.inArray(i(),this.options.disabled)!==-1)t=n?t+1:t-1;return t},_focusNextTab:function(e,t){return e=this._findNextTab(e,t),this.tabs.eq(e).focus(),e},_setOption:function(e,t){if(e==="active"){this._activate(t);return}if(e==="disabled"){this._setupDisabled(t);return}this._super(e,t),e==="collapsible"&&(this.element.toggleClass("ui-tabs-collapsible",t),!t&&this.options.active===!1&&this._activate(0)),e==="event"&&this._setupEvents(t),e==="heightStyle"&&this._setupHeightStyle(t)},_tabId:function(e){return e.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(e){return e?e.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var t=this.options,n=this.tablist.children(":has(a[href])");t.disabled=e.map(n.filter(".ui-state-disabled"),function(e){return n.index(e)}),this._processTabs(),t.active===!1||!this.anchors.length?(t.active=!1,this.active=e()):this.active.length&&!e.contains(this.tablist[0],this.active[0])?this.tabs.length===t.disabled.length?(t.active=!1,this.active=e()):this._activate(this._findNextTab(Math.max(0,t.active-1),!1)):t.active=this.tabs.index(this.active),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var t=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return e("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=e(),this.anchors.each(function(n,r){var i,o,u,a=e(r).uniqueId().attr("id"),f=e(r).closest("li"),l=f.attr("aria-controls");s(r)?(i=r.hash,o=t.element.find(t._sanitizeSelector(i))):(u=t._tabId(f),i="#"+u,o=t.element.find(i),o.length||(o=t._createPanel(u),o.insertAfter(t.panels[n-1]||t.tablist)),o.attr("aria-live","polite")),o.length&&(t.panels=t.panels.add(o)),l&&f.data("ui-tabs-aria-controls",l),f.attr({"aria-controls":i.substring(1),"aria-labelledby":a}),o.attr("aria-labelledby",a)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(t){return e("
").attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(t){e.isArray(t)&&(t.length?t.length===this.anchors.length&&(t=!0):t=!1);for(var n=0,r;r=this.tabs[n];n++)t===!0||e.inArray(n,t)!==-1?e(r).addClass("ui-state-disabled").attr("aria-disabled","true"):e(r).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=t},_setupEvents:function(t){var n={click:function(e){e.preventDefault()}};t&&e.each(t.split(" "),function(e,t){n[t]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,n),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(t){var n,r,i=this.element.parent();t==="fill"?(e.support.minHeight||(r=i.css("overflow"),i.css("overflow","hidden")),n=i.height(),this.element.siblings(":visible").each(function(){var t=e(this),r=t.css("position");if(r==="absolute"||r==="fixed")return;n-=t.outerHeight(!0)}),r&&i.css("overflow",r),this.element.children().not(this.panels).each(function(){n-=e(this).outerHeight(!0)}),this.panels.each(function(){e(this).height(Math.max(0,n-e(this).innerHeight()+e(this).height()))}).css("overflow","auto")):t==="auto"&&(n=0,this.panels.each(function(){n=Math.max(n,e(this).height("").height())}).height(n))},_eventHandler:function(t){var n=this.options,r=this.active,i=e(t.currentTarget),s=i.closest("li"),o=s[0]===r[0],u=o&&n.collapsible,a=u?e():this._getPanelForTab(s),f=r.length?this._getPanelForTab(r):e(),l={oldTab:r,oldPanel:f,newTab:u?e():s,newPanel:a};t.preventDefault();if(s.hasClass("ui-state-disabled")||s.hasClass("ui-tabs-loading")||this.running||o&&!n.collapsible||this._trigger("beforeActivate",t,l)===!1)return;n.active=u?!1:this.tabs.index(s),this.active=o?e():s,this.xhr&&this.xhr.abort(),!f.length&&!a.length&&e.error("jQuery UI Tabs: Mismatching fragment identifier."),a.length&&this.load(this.tabs.index(s),t),this._toggle(t,l)},_toggle:function(t,n){function o(){r.running=!1,r._trigger("activate",t,n)}function u(){n.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),i.length&&r.options.show?r._show(i,r.options.show,o):(i.show(),o())}var r=this,i=n.newPanel,s=n.oldPanel;this.running=!0,s.length&&this.options.hide?this._hide(s,this.options.hide,function(){n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(n.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),s.hide(),u()),s.attr({"aria-expanded":"false","aria-hidden":"true"}),n.oldTab.attr("aria-selected","false"),i.length&&s.length?n.oldTab.attr("tabIndex",-1):i.length&&this.tabs.filter(function(){return e(this).attr("tabIndex")===0}).attr("tabIndex",-1),i.attr({"aria-expanded":"true","aria-hidden":"false"}),n.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(t){var n,r=this._findActive(t);if(r[0]===this.active[0])return;r.length||(r=this.active),n=r.find(".ui-tabs-anchor")[0],this._eventHandler({target:n,currentTarget:n,preventDefault:e.noop})},_findActive:function(t){return t===!1?e():this.tabs.eq(t)},_getIndex:function(e){return typeof e=="string"&&(e=this.anchors.index(this.anchors.filter("[href$='"+e+"']"))),e},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeData("href.tabs").removeData("load.tabs").removeUniqueId(),this.tabs.add(this.panels).each(function(){e.data(this,"ui-tabs-destroy")?e(this).remove():e(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var t=e(this),n=t.data("ui-tabs-aria-controls");n?t.attr("aria-controls",n):t.removeAttr("aria-controls")}),this.panels.show(),this.options.heightStyle!=="content"&&this.panels.css("height","")},enable:function(n){var r=this.options.disabled;if(r===!1)return;n===t?r=!1:(n=this._getIndex(n),e.isArray(r)?r=e.map(r,function(e){return e!==n?e:null}):r=e.map(this.tabs,function(e,t){return t!==n?t:null})),this._setupDisabled(r)},disable:function(n){var r=this.options.disabled;if(r===!0)return;if(n===t)r=!0;else{n=this._getIndex(n);if(e.inArray(n,r)!==-1)return;e.isArray(r)?r=e.merge([n],r).sort():r=[n]}this._setupDisabled(r)},load:function(t,n){t=this._getIndex(t);var r=this,i=this.tabs.eq(t),o=i.find(".ui-tabs-anchor"),u=this._getPanelForTab(i),a={tab:i,panel:u};if(s(o[0]))return;this.xhr=e.ajax(this._ajaxSettings(o,n,a)),this.xhr&&this.xhr.statusText!=="canceled"&&(i.addClass("ui-tabs-loading"),u.attr("aria-busy","true"),this.xhr.success(function(e){setTimeout(function(){u.html(e),r._trigger("load",n,a)},1)}).complete(function(e,t){setTimeout(function(){t==="abort"&&r.panels.stop(!1,!0),i.removeClass("ui-tabs-loading"),u.removeAttr("aria-busy"),e===r.xhr&&delete r.xhr},1)}))},_ajaxSettings:function(t,n,r){var i=this;return{url:t.attr("href"),beforeSend:function(t,s){return i._trigger("beforeLoad",n,e.extend({jqXHR:t,ajaxSettings:s},r))}}},_getPanelForTab:function(t){var n=e(t).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+n))}}),e.uiBackCompat!==!1&&(e.ui.tabs.prototype._ui=function(e,t){return{tab:e,panel:t,index:this.anchors.index(e)}},e.widget("ui.tabs",e.ui.tabs,{url:function(e,t){this.anchors.eq(e).attr("href",t)}}),e.widget("ui.tabs",e.ui.tabs,{options:{ajaxOptions:null,cache:!1},_create:function(){this._super();var t=this;this._on({tabsbeforeload:function(n,r){if(e.data(r.tab[0],"cache.tabs")){n.preventDefault();return}r.jqXHR.success(function(){t.options.cache&&e.data(r.tab[0],"cache.tabs",!0)})}})},_ajaxSettings:function(t,n,r){var i=this.options.ajaxOptions;return e.extend({},i,{error:function(e,t){try{i.error(e,t,r.tab.closest("li").index(),r.tab[0])}catch(n){}}},this._superApply(arguments))},_setOption:function(e,t){e==="cache"&&t===!1&&this.anchors.removeData("cache.tabs"),this._super(e,t)},_destroy:function(){this.anchors.removeData("cache.tabs"),this._super()},url:function(e){this.anchors.eq(e).removeData("cache.tabs"),this._superApply(arguments)}}),e.widget("ui.tabs",e.ui.tabs,{abort:function(){this.xhr&&this.xhr.abort()}}),e.widget("ui.tabs",e.ui.tabs,{options:{spinner:"Loading…"},_create:function(){this._super(),this._on({tabsbeforeload:function(e,t){if(e.target!==this.element[0]||!this.options.spinner)return;var n=t.tab.find("span"),r=n.html();n.html(this.options.spinner),t.jqXHR.complete(function(){n.html(r)})}})}}),e.widget("ui.tabs",e.ui.tabs,{options:{enable:null,disable:null},enable:function(t){var n=this.options,r;if(t&&n.disabled===!0||e.isArray(n.disabled)&&e.inArray(t,n.disabled)!==-1)r=!0;this._superApply(arguments),r&&this._trigger("enable",null,this._ui(this.anchors[t],this.panels[t]))},disable:function(t){var n=this.options,r;if(t&&n.disabled===!1||e.isArray(n.disabled)&&e.inArray(t,n.disabled)===-1)r=!0;this._superApply(arguments),r&&this._trigger("disable",null,this._ui(this.anchors[t],this.panels[t]))}}),e.widget("ui.tabs",e.ui.tabs,{options:{add:null,remove:null,tabTemplate:"
  • #{label}
  • "},add:function(n,r,i){i===t&&(i=this.anchors.length);var s,o,u=this.options,a=e(u.tabTemplate.replace(/#\{href\}/g,n).replace(/#\{label\}/g,r)),f=n.indexOf("#")?this._tabId(a):n.replace("#","");return a.addClass("ui-state-default ui-corner-top").data("ui-tabs-destroy",!0),a.attr("aria-controls",f),s=i>=this.tabs.length,o=this.element.find("#"+f),o.length||(o=this._createPanel(f),s?i>0?o.insertAfter(this.panels.eq(-1)):o.appendTo(this.element):o.insertBefore(this.panels[i])),o.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").hide(),s?a.appendTo(this.tablist):a.insertBefore(this.tabs[i]),u.disabled=e.map(u.disabled,function(e){return e>=i?++e:e}),this.refresh(),this.tabs.length===1&&u.active===!1&&this.option("active",0),this._trigger("add",null,this._ui(this.anchors[i],this.panels[i])),this},remove:function(t){t=this._getIndex(t);var n=this.options,r=this.tabs.eq(t).remove(),i=this._getPanelForTab(r).remove();return r.hasClass("ui-tabs-active")&&this.anchors.length>2&&this._activate(t+(t+1=t?--e:e}),this.refresh(),this._trigger("remove",null,this._ui(r.find("a")[0],i[0])),this}}),e.widget("ui.tabs",e.ui.tabs,{length:function(){return this.anchors.length}}),e.widget("ui.tabs",e.ui.tabs,{options:{idPrefix:"ui-tabs-"},_tabId:function(t){var n=t.is("li")?t.find("a[href]"):t;return n=n[0],e(n).closest("li").attr("aria-controls")||n.title&&n.title.replace(/\s/g,"_").replace(/[^\w\u00c0-\uFFFF\-]/g,"")||this.options.idPrefix+i()}}),e.widget("ui.tabs",e.ui.tabs,{options:{panelTemplate:"
    "},_createPanel:function(t){return e(this.options.panelTemplate).attr("id",t).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)}}),e.widget("ui.tabs",e.ui.tabs,{_create:function(){var e=this.options;e.active===null&&e.selected!==t&&(e.active=e.selected===-1?!1:e.selected),this._super(),e.selected=e.active,e.selected===!1&&(e.selected=-1)},_setOption:function(e,t){if(e!=="selected")return this._super(e,t);var n=this.options;this._super("active",t===-1?!1:t),n.selected=n.active,n.selected===!1&&(n.selected=-1)},_eventHandler:function(){this._superApply(arguments),this.options.selected=this.options.active,this.options.selected===!1&&(this.options.selected=-1)}}),e.widget("ui.tabs",e.ui.tabs,{options:{show:null,select:null},_create:function(){this._super(),this.options.active!==!1&&this._trigger("show",null,this._ui(this.active.find(".ui-tabs-anchor")[0],this._getPanelForTab(this.active)[0]))},_trigger:function(e,t,n){var r,i,s=this._superApply(arguments);return s?(e==="beforeActivate"?(r=n.newTab.length?n.newTab:n.oldTab,i=n.newPanel.length?n.newPanel:n.oldPanel,s=this._super("select",t,{tab:r.find(".ui-tabs-anchor")[0],panel:i[0],index:r.closest("li").index()})):e==="activate"&&n.newTab.length&&(s=this._super("show",t,{tab:n.newTab.find(".ui-tabs-anchor")[0],panel:n.newPanel[0],index:n.newTab.closest("li").index()})),s):!1}}),e.widget("ui.tabs",e.ui.tabs,{select:function(e){e=this._getIndex(e);if(e===-1){if(!this.options.collapsible||this.options.selected===-1)return;e=this.options.selected}this.anchors.eq(e).trigger(this.options.event+this.eventNamespace)}}),function(){var t=0;e.widget("ui.tabs",e.ui.tabs,{options:{cookie:null},_create:function(){var e=this.options,t;e.active==null&&e.cookie&&(t=parseInt(this._cookie(),10),t===-1&&(t=!1),e.active=t),this._super()},_cookie:function(n){var r=[this.cookie||(this.cookie=this.options.cookie.name||"ui-tabs-"+ ++t)];return arguments.length&&(r.push(n===!1?-1:n),r.push(this.options.cookie)),e.cookie.apply(null,r)},_refresh:function(){this._super(),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_eventHandler:function(){this._superApply(arguments),this.options.cookie&&this._cookie(this.options.active,this.options.cookie)},_destroy:function(){this._super(),this.options.cookie&&this._cookie(null,this.options.cookie)}})}(),e.widget("ui.tabs",e.ui.tabs,{_trigger:function(t,n,r){var i=e.extend({},r);return t==="load"&&(i.panel=i.panel[0],i.tab=i.tab.find(".ui-tabs-anchor")[0]),this._super(t,n,i)}}),e.widget("ui.tabs",e.ui.tabs,{options:{fx:null},_getFx:function(){var t,n,r=this.options.fx;return r&&(e.isArray(r)?(t=r[0],n=r[1]):t=n=r),r?{show:n,hide:t}:null},_toggle:function(e,t){function o(){n.running=!1,n._trigger("activate",e,t)}function u(){t.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),r.length&&s.show?r.animate(s.show,s.show.duration,function(){o()}):(r.show(),o())}var n=this,r=t.newPanel,i=t.oldPanel,s=this._getFx();if(!s)return this._super(e,t);n.running=!0,i.length&&s.hide?i.animate(s.hide,s.hide.duration,function(){t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),u()}):(t.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),i.hide(),u())}}))})(jQuery);(function(e){function n(t,n){var r=(t.attr("aria-describedby")||"").split(/\s+/);r.push(n),t.data("ui-tooltip-id",n).attr("aria-describedby",e.trim(r.join(" ")))}function r(t){var n=t.data("ui-tooltip-id"),r=(t.attr("aria-describedby")||"").split(/\s+/),i=e.inArray(n,r);i!==-1&&r.splice(i,1),t.removeData("ui-tooltip-id"),r=e.trim(r.join(" ")),r?t.attr("aria-describedby",r):t.removeAttr("aria-describedby")}var t=0;e.widget("ui.tooltip",{version:"1.9.2",options:{content:function(){return e(this).attr("title")},hide:!0,items:"[title]:not([disabled])",position:{my:"left top+15",at:"left bottom",collision:"flipfit flip"},show:!0,tooltipClass:null,track:!1,close:null,open:null},_create:function(){this._on({mouseover:"open",focusin:"open"}),this.tooltips={},this.parents={},this.options.disabled&&this._disable()},_setOption:function(t,n){var r=this;if(t==="disabled"){this[n?"_disable":"_enable"](),this.options[t]=n;return}this._super(t,n),t==="content"&&e.each(this.tooltips,function(e,t){r._updateContent(t)})},_disable:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0)}),this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.is("[title]")&&t.data("ui-tooltip-title",t.attr("title")).attr("title","")})},_enable:function(){this.element.find(this.options.items).andSelf().each(function(){var t=e(this);t.data("ui-tooltip-title")&&t.attr("title",t.data("ui-tooltip-title"))})},open:function(t){var n=this,r=e(t?t.target:this.element).closest(this.options.items);if(!r.length||r.data("ui-tooltip-id"))return;r.attr("title")&&r.data("ui-tooltip-title",r.attr("title")),r.data("ui-tooltip-open",!0),t&&t.type==="mouseover"&&r.parents().each(function(){var t=e(this),r;t.data("ui-tooltip-open")&&(r=e.Event("blur"),r.target=r.currentTarget=this,n.close(r,!0)),t.attr("title")&&(t.uniqueId(),n.parents[this.id]={element:this,title:t.attr("title")},t.attr("title",""))}),this._updateContent(r,t)},_updateContent:function(e,t){var n,r=this.options.content,i=this,s=t?t.type:null;if(typeof r=="string")return this._open(t,e,r);n=r.call(e[0],function(n){if(!e.data("ui-tooltip-open"))return;i._delay(function(){t&&(t.type=s),this._open(t,e,n)})}),n&&this._open(t,e,n)},_open:function(t,r,i){function f(e){a.of=e;if(s.is(":hidden"))return;s.position(a)}var s,o,u,a=e.extend({},this.options.position);if(!i)return;s=this._find(r);if(s.length){s.find(".ui-tooltip-content").html(i);return}r.is("[title]")&&(t&&t.type==="mouseover"?r.attr("title",""):r.removeAttr("title")),s=this._tooltip(r),n(r,s.attr("id")),s.find(".ui-tooltip-content").html(i),this.options.track&&t&&/^mouse/.test(t.type)?(this._on(this.document,{mousemove:f}),f(t)):s.position(e.extend({of:r},this.options.position)),s.hide(),this._show(s,this.options.show),this.options.show&&this.options.show.delay&&(u=setInterval(function(){s.is(":visible")&&(f(a.of),clearInterval(u))},e.fx.interval)),this._trigger("open",t,{tooltip:s}),o={keyup:function(t){if(t.keyCode===e.ui.keyCode.ESCAPE){var n=e.Event(t);n.currentTarget=r[0],this.close(n,!0)}},remove:function(){this._removeTooltip(s)}};if(!t||t.type==="mouseover")o.mouseleave="close";if(!t||t.type==="focusin")o.focusout="close";this._on(!0,r,o)},close:function(t){var n=this,i=e(t?t.currentTarget:this.element),s=this._find(i);if(this.closing)return;i.data("ui-tooltip-title")&&i.attr("title",i.data("ui-tooltip-title")),r(i),s.stop(!0),this._hide(s,this.options.hide,function(){n._removeTooltip(e(this))}),i.removeData("ui-tooltip-open"),this._off(i,"mouseleave focusout keyup"),i[0]!==this.element[0]&&this._off(i,"remove"),this._off(this.document,"mousemove"),t&&t.type==="mouseleave"&&e.each(this.parents,function(t,r){e(r.element).attr("title",r.title),delete n.parents[t]}),this.closing=!0,this._trigger("close",t,{tooltip:s}),this.closing=!1},_tooltip:function(n){var r="ui-tooltip-"+t++,i=e("
    ").attr({id:r,role:"tooltip"}).addClass("ui-tooltip ui-widget ui-corner-all ui-widget-content "+(this.options.tooltipClass||""));return e("
    ").addClass("ui-tooltip-content").appendTo(i),i.appendTo(this.document[0].body),e.fn.bgiframe&&i.bgiframe(),this.tooltips[r]=n,i},_find:function(t){var n=t.data("ui-tooltip-id");return n?e("#"+n):e()},_removeTooltip:function(e){e.remove(),delete this.tooltips[e.attr("id")]},_destroy:function(){var t=this;e.each(this.tooltips,function(n,r){var i=e.Event("blur");i.target=i.currentTarget=r[0],t.close(i,!0),e("#"+n).remove(),r.data("ui-tooltip-title")&&(r.attr("title",r.data("ui-tooltip-title")),r.removeData("ui-tooltip-title"))})}})})(jQuery);jQuery.effects||function(e,t){var n=e.uiBackCompat!==!1,r="ui-effects-";e.effects={effect:{}},function(t,n){function p(e,t,n){var r=a[t.type]||{};return e==null?n||!t.def?null:t.def:(e=r.floor?~~e:parseFloat(e),isNaN(e)?t.def:r.mod?(e+r.mod)%r.mod:0>e?0:r.max")[0],c,h=t.each;l.style.cssText="background-color:rgba(1,1,1,.5)",f.rgba=l.style.backgroundColor.indexOf("rgba")>-1,h(u,function(e,t){t.cache="_"+e,t.props.alpha={idx:3,type:"percent",def:1}}),o.fn=t.extend(o.prototype,{parse:function(r,i,s,a){if(r===n)return this._rgba=[null,null,null,null],this;if(r.jquery||r.nodeType)r=t(r).css(i),i=n;var f=this,l=t.type(r),v=this._rgba=[];i!==n&&(r=[r,i,s,a],l="array");if(l==="string")return this.parse(d(r)||c._default);if(l==="array")return h(u.rgba.props,function(e,t){v[t.idx]=p(r[t.idx],t)}),this;if(l==="object")return r instanceof o?h(u,function(e,t){r[t.cache]&&(f[t.cache]=r[t.cache].slice())}):h(u,function(t,n){var i=n.cache;h(n.props,function(e,t){if(!f[i]&&n.to){if(e==="alpha"||r[e]==null)return;f[i]=n.to(f._rgba)}f[i][t.idx]=p(r[e],t,!0)}),f[i]&&e.inArray(null,f[i].slice(0,3))<0&&(f[i][3]=1,n.from&&(f._rgba=n.from(f[i])))}),this},is:function(e){var t=o(e),n=!0,r=this;return h(u,function(e,i){var s,o=t[i.cache];return o&&(s=r[i.cache]||i.to&&i.to(r._rgba)||[],h(i.props,function(e,t){if(o[t.idx]!=null)return n=o[t.idx]===s[t.idx],n})),n}),n},_space:function(){var e=[],t=this;return h(u,function(n,r){t[r.cache]&&e.push(n)}),e.pop()},transition:function(e,t){var n=o(e),r=n._space(),i=u[r],s=this.alpha()===0?o("transparent"):this,f=s[i.cache]||i.to(s._rgba),l=f.slice();return n=n[i.cache],h(i.props,function(e,r){var i=r.idx,s=f[i],o=n[i],u=a[r.type]||{};if(o===null)return;s===null?l[i]=o:(u.mod&&(o-s>u.mod/2?s+=u.mod:s-o>u.mod/2&&(s-=u.mod)),l[i]=p((o-s)*t+s,r))}),this[r](l)},blend:function(e){if(this._rgba[3]===1)return this;var n=this._rgba.slice(),r=n.pop(),i=o(e)._rgba;return o(t.map(n,function(e,t){return(1-r)*i[t]+r*e}))},toRgbaString:function(){var e="rgba(",n=t.map(this._rgba,function(e,t){return e==null?t>2?1:0:e});return n[3]===1&&(n.pop(),e="rgb("),e+n.join()+")"},toHslaString:function(){var e="hsla(",n=t.map(this.hsla(),function(e,t){return e==null&&(e=t>2?1:0),t&&t<3&&(e=Math.round(e*100)+"%"),e});return n[3]===1&&(n.pop(),e="hsl("),e+n.join()+")"},toHexString:function(e){var n=this._rgba.slice(),r=n.pop();return e&&n.push(~~(r*255)),"#"+t.map(n,function(e){return e=(e||0).toString(16),e.length===1?"0"+e:e}).join("")},toString:function(){return this._rgba[3]===0?"transparent":this.toRgbaString()}}),o.fn.parse.prototype=o.fn,u.hsla.to=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/255,n=e[1]/255,r=e[2]/255,i=e[3],s=Math.max(t,n,r),o=Math.min(t,n,r),u=s-o,a=s+o,f=a*.5,l,c;return o===s?l=0:t===s?l=60*(n-r)/u+360:n===s?l=60*(r-t)/u+120:l=60*(t-n)/u+240,f===0||f===1?c=f:f<=.5?c=u/a:c=u/(2-a),[Math.round(l)%360,c,f,i==null?1:i]},u.hsla.from=function(e){if(e[0]==null||e[1]==null||e[2]==null)return[null,null,null,e[3]];var t=e[0]/360,n=e[1],r=e[2],i=e[3],s=r<=.5?r*(1+n):r+n-r*n,o=2*r-s;return[Math.round(v(o,s,t+1/3)*255),Math.round(v(o,s,t)*255),Math.round(v(o,s,t-1/3)*255),i]},h(u,function(e,r){var s=r.props,u=r.cache,a=r.to,f=r.from;o.fn[e]=function(e){a&&!this[u]&&(this[u]=a(this._rgba));if(e===n)return this[u].slice();var r,i=t.type(e),l=i==="array"||i==="object"?e:arguments,c=this[u].slice();return h(s,function(e,t){var n=l[i==="object"?e:t.idx];n==null&&(n=c[t.idx]),c[t.idx]=p(n,t)}),f?(r=o(f(c)),r[u]=c,r):o(c)},h(s,function(n,r){if(o.fn[n])return;o.fn[n]=function(s){var o=t.type(s),u=n==="alpha"?this._hsla?"hsla":"rgba":e,a=this[u](),f=a[r.idx],l;return o==="undefined"?f:(o==="function"&&(s=s.call(this,f),o=t.type(s)),s==null&&r.empty?this:(o==="string"&&(l=i.exec(s),l&&(s=f+parseFloat(l[2])*(l[1]==="+"?1:-1))),a[r.idx]=s,this[u](a)))}})}),h(r,function(e,n){t.cssHooks[n]={set:function(e,r){var i,s,u="";if(t.type(r)!=="string"||(i=d(r))){r=o(i||r);if(!f.rgba&&r._rgba[3]!==1){s=n==="backgroundColor"?e.parentNode:e;while((u===""||u==="transparent")&&s&&s.style)try{u=t.css(s,"backgroundColor"),s=s.parentNode}catch(a){}r=r.blend(u&&u!=="transparent"?u:"_default")}r=r.toRgbaString()}try{e.style[n]=r}catch(l){}}},t.fx.step[n]=function(e){e.colorInit||(e.start=o(e.elem,n),e.end=o(e.end),e.colorInit=!0),t.cssHooks[n].set(e.elem,e.start.transition(e.end,e.pos))}}),t.cssHooks.borderColor={expand:function(e){var t={};return h(["Top","Right","Bottom","Left"],function(n,r){t["border"+r+"Color"]=e}),t}},c=t.Color.names={aqua:"#00ffff",black:"#000000",blue:"#0000ff",fuchsia:"#ff00ff",gray:"#808080",green:"#008000",lime:"#00ff00",maroon:"#800000",navy:"#000080",olive:"#808000",purple:"#800080",red:"#ff0000",silver:"#c0c0c0",teal:"#008080",white:"#ffffff",yellow:"#ffff00",transparent:[null,null,null,0],_default:"#ffffff"}}(jQuery),function(){function i(){var t=this.ownerDocument.defaultView?this.ownerDocument.defaultView.getComputedStyle(this,null):this.currentStyle,n={},r,i;if(t&&t.length&&t[0]&&t[t[0]]){i=t.length;while(i--)r=t[i],typeof t[r]=="string"&&(n[e.camelCase(r)]=t[r])}else for(r in t)typeof t[r]=="string"&&(n[r]=t[r]);return n}function s(t,n){var i={},s,o;for(s in n)o=n[s],t[s]!==o&&!r[s]&&(e.fx.step[s]||!isNaN(parseFloat(o)))&&(i[s]=o);return i}var n=["add","remove","toggle"],r={border:1,borderBottom:1,borderColor:1,borderLeft:1,borderRight:1,borderTop:1,borderWidth:1,margin:1,padding:1};e.each(["borderLeftStyle","borderRightStyle","borderBottomStyle","borderTopStyle"],function(t,n){e.fx.step[n]=function(e){if(e.end!=="none"&&!e.setAttr||e.pos===1&&!e.setAttr)jQuery.style(e.elem,n,e.end),e.setAttr=!0}}),e.effects.animateClass=function(t,r,o,u){var a=e.speed(r,o,u);return this.queue(function(){var r=e(this),o=r.attr("class")||"",u,f=a.children?r.find("*").andSelf():r;f=f.map(function(){var t=e(this);return{el:t,start:i.call(this)}}),u=function(){e.each(n,function(e,n){t[n]&&r[n+"Class"](t[n])})},u(),f=f.map(function(){return this.end=i.call(this.el[0]),this.diff=s(this.start,this.end),this}),r.attr("class",o),f=f.map(function(){var t=this,n=e.Deferred(),r=jQuery.extend({},a,{queue:!1,complete:function(){n.resolve(t)}});return this.el.animate(this.diff,r),n.promise()}),e.when.apply(e,f.get()).done(function(){u(),e.each(arguments,function(){var t=this.el;e.each(this.diff,function(e){t.css(e,"")})}),a.complete.call(r[0])})})},e.fn.extend({_addClass:e.fn.addClass,addClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{add:t},n,r,i):this._addClass(t)},_removeClass:e.fn.removeClass,removeClass:function(t,n,r,i){return n?e.effects.animateClass.call(this,{remove:t},n,r,i):this._removeClass(t)},_toggleClass:e.fn.toggleClass,toggleClass:function(n,r,i,s,o){return typeof r=="boolean"||r===t?i?e.effects.animateClass.call(this,r?{add:n}:{remove:n},i,s,o):this._toggleClass(n,r):e.effects.animateClass.call(this,{toggle:n},r,i,s)},switchClass:function(t,n,r,i,s){return e.effects.animateClass.call(this,{add:n,remove:t},r,i,s)}})}(),function(){function i(t,n,r,i){e.isPlainObject(t)&&(n=t,t=t.effect),t={effect:t},n==null&&(n={}),e.isFunction(n)&&(i=n,r=null,n={});if(typeof n=="number"||e.fx.speeds[n])i=r,r=n,n={};return e.isFunction(r)&&(i=r,r=null),n&&e.extend(t,n),r=r||n.duration,t.duration=e.fx.off?0:typeof r=="number"?r:r in e.fx.speeds?e.fx.speeds[r]:e.fx.speeds._default,t.complete=i||n.complete,t}function s(t){return!t||typeof t=="number"||e.fx.speeds[t]?!0:typeof t=="string"&&!e.effects.effect[t]?n&&e.effects[t]?!1:!0:!1}e.extend(e.effects,{version:"1.9.2",save:function(e,t){for(var n=0;n
    ").addClass("ui-effects-wrapper").css({fontSize:"100%",background:"transparent",border:"none",margin:0,padding:0}),i={width:t.width(),height:t.height()},s=document.activeElement;try{s.id}catch(o){s=document.body}return t.wrap(r),(t[0]===s||e.contains(t[0],s))&&e(s).focus(),r=t.parent(),t.css("position")==="static"?(r.css({position:"relative"}),t.css({position:"relative"})):(e.extend(n,{position:t.css("position"),zIndex:t.css("z-index")}),e.each(["top","left","bottom","right"],function(e,r){n[r]=t.css(r),isNaN(parseInt(n[r],10))&&(n[r]="auto")}),t.css({position:"relative",top:0,left:0,right:"auto",bottom:"auto"})),t.css(i),r.css(n).show()},removeWrapper:function(t){var n=document.activeElement;return t.parent().is(".ui-effects-wrapper")&&(t.parent().replaceWith(t),(t[0]===n||e.contains(t[0],n))&&e(n).focus()),t},setTransition:function(t,n,r,i){return i=i||{},e.each(n,function(e,n){var s=t.cssUnit(n);s[0]>0&&(i[n]=s[0]*r+s[1])}),i}}),e.fn.extend({effect:function(){function a(n){function u(){e.isFunction(i)&&i.call(r[0]),e.isFunction(n)&&n()}var r=e(this),i=t.complete,s=t.mode;(r.is(":hidden")?s==="hide":s==="show")?u():o.call(r[0],t,u)}var t=i.apply(this,arguments),r=t.mode,s=t.queue,o=e.effects.effect[t.effect],u=!o&&n&&e.effects[t.effect];return e.fx.off||!o&&!u?r?this[r](t.duration,t.complete):this.each(function(){t.complete&&t.complete.call(this)}):o?s===!1?this.each(a):this.queue(s||"fx",a):u.call(this,{options:t,duration:t.duration,callback:t.complete,mode:t.mode})},_show:e.fn.show,show:function(e){if(s(e))return this._show.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="show",this.effect.call(this,t)},_hide:e.fn.hide,hide:function(e){if(s(e))return this._hide.apply(this,arguments);var t=i.apply(this,arguments);return t.mode="hide",this.effect.call(this,t)},__toggle:e.fn.toggle,toggle:function(t){if(s(t)||typeof t=="boolean"||e.isFunction(t))return this.__toggle.apply(this,arguments);var n=i.apply(this,arguments);return n.mode="toggle",this.effect.call(this,n)},cssUnit:function(t){var n=this.css(t),r=[];return e.each(["em","px","%","pt"],function(e,t){n.indexOf(t)>0&&(r=[parseFloat(n),t])}),r}})}(),function(){var t={};e.each(["Quad","Cubic","Quart","Quint","Expo"],function(e,n){t[n]=function(t){return Math.pow(t,e+2)}}),e.extend(t,{Sine:function(e){return 1-Math.cos(e*Math.PI/2)},Circ:function(e){return 1-Math.sqrt(1-e*e)},Elastic:function(e){return e===0||e===1?e:-Math.pow(2,8*(e-1))*Math.sin(((e-1)*80-7.5)*Math.PI/15)},Back:function(e){return e*e*(3*e-2)},Bounce:function(e){var t,n=4;while(e<((t=Math.pow(2,--n))-1)/11);return 1/Math.pow(4,3-n)-7.5625*Math.pow((t*3-2)/22-e,2)}}),e.each(t,function(t,n){e.easing["easeIn"+t]=n,e.easing["easeOut"+t]=function(e){return 1-n(1-e)},e.easing["easeInOut"+t]=function(e){return e<.5?n(e*2)/2:1-n(e*-2+2)/2}})}()}(jQuery);(function(e,t){var n=/up|down|vertical/,r=/up|left|vertical|horizontal/;e.effects.effect.blind=function(t,i){var s=e(this),o=["position","top","bottom","left","right","height","width"],u=e.effects.setMode(s,t.mode||"hide"),a=t.direction||"up",f=n.test(a),l=f?"height":"width",c=f?"top":"left",h=r.test(a),p={},d=u==="show",v,m,g;s.parent().is(".ui-effects-wrapper")?e.effects.save(s.parent(),o):e.effects.save(s,o),s.show(),v=e.effects.createWrapper(s).css({overflow:"hidden"}),m=v[l](),g=parseFloat(v.css(c))||0,p[l]=d?m:0,h||(s.css(f?"bottom":"right",0).css(f?"top":"left","auto").css({position:"absolute"}),p[c]=d?g:m+g),d&&(v.css(l,0),h||v.css(c,g+m)),v.animate(p,{duration:t.duration,easing:t.easing,queue:!1,complete:function(){u==="hide"&&s.hide(),e.effects.restore(s,o),e.effects.removeWrapper(s),i()}})}})(jQuery);(function(e,t){e.effects.effect.bounce=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=s==="hide",u=s==="show",a=t.direction||"up",f=t.distance,l=t.times||5,c=l*2+(u||o?1:0),h=t.duration/c,p=t.easing,d=a==="up"||a==="down"?"top":"left",v=a==="up"||a==="left",m,g,y,b=r.queue(),w=b.length;(u||o)&&i.push("opacity"),e.effects.save(r,i),r.show(),e.effects.createWrapper(r),f||(f=r[d==="top"?"outerHeight":"outerWidth"]()/3),u&&(y={opacity:1},y[d]=0,r.css("opacity",0).css(d,v?-f*2:f*2).animate(y,h,p)),o&&(f/=Math.pow(2,l-1)),y={},y[d]=0;for(m=0;m1&&b.splice.apply(b,[1,0].concat(b.splice(w,c+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.clip=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"vertical",a=u==="vertical",f=a?"height":"width",l=a?"top":"left",c={},h,p,d;e.effects.save(r,i),r.show(),h=e.effects.createWrapper(r).css({overflow:"hidden"}),p=r[0].tagName==="IMG"?h:r,d=p[f](),o&&(p.css(f,0),p.css(l,d/2)),c[f]=o?d:0,c[l]=o?0:d/2,p.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o||r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.drop=function(t,n){var r=e(this),i=["position","top","bottom","left","right","opacity","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left"?"pos":"neg",l={opacity:o?1:0},c;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),c=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0)/2,o&&r.css("opacity",0).css(a,f==="pos"?-c:c),l[a]=(o?f==="pos"?"+=":"-=":f==="pos"?"-=":"+=")+c,r.animate(l,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.explode=function(t,n){function y(){c.push(this),c.length===r*i&&b()}function b(){s.css({visibility:"visible"}),e(c).remove(),u||s.hide(),n()}var r=t.pieces?Math.round(Math.sqrt(t.pieces)):3,i=r,s=e(this),o=e.effects.setMode(s,t.mode||"hide"),u=o==="show",a=s.show().css("visibility","hidden").offset(),f=Math.ceil(s.outerWidth()/i),l=Math.ceil(s.outerHeight()/r),c=[],h,p,d,v,m,g;for(h=0;h
    ").css({position:"absolute",visibility:"visible",left:-p*f,top:-h*l}).parent().addClass("ui-effects-explode").css({position:"absolute",overflow:"hidden",width:f,height:l,left:d+(u?m*f:0),top:v+(u?g*l:0),opacity:u?0:1}).animate({left:d+(u?0:m*f),top:v+(u?0:g*l),opacity:u?1:0},t.duration||500,t.easing,y)}}})(jQuery);(function(e,t){e.effects.effect.fade=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"toggle");r.animate({opacity:i},{queue:!1,duration:t.duration,easing:t.easing,complete:n})}})(jQuery);(function(e,t){e.effects.effect.fold=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"hide"),o=s==="show",u=s==="hide",a=t.size||15,f=/([0-9]+)%/.exec(a),l=!!t.horizFirst,c=o!==l,h=c?["width","height"]:["height","width"],p=t.duration/2,d,v,m={},g={};e.effects.save(r,i),r.show(),d=e.effects.createWrapper(r).css({overflow:"hidden"}),v=c?[d.width(),d.height()]:[d.height(),d.width()],f&&(a=parseInt(f[1],10)/100*v[u?0:1]),o&&d.css(l?{height:0,width:a}:{height:a,width:0}),m[h[0]]=o?v[0]:a,g[h[1]]=o?v[1]:0,d.animate(m,p,t.easing).animate(g,p,t.easing,function(){u&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()})}})(jQuery);(function(e,t){e.effects.effect.highlight=function(t,n){var r=e(this),i=["backgroundImage","backgroundColor","opacity"],s=e.effects.setMode(r,t.mode||"show"),o={backgroundColor:r.css("backgroundColor")};s==="hide"&&(o.opacity=0),e.effects.save(r,i),r.show().css({backgroundImage:"none",backgroundColor:t.color||"#ffff99"}).animate(o,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),n()}})}})(jQuery);(function(e,t){e.effects.effect.pulsate=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"show"),s=i==="show",o=i==="hide",u=s||i==="hide",a=(t.times||5)*2+(u?1:0),f=t.duration/a,l=0,c=r.queue(),h=c.length,p;if(s||!r.is(":visible"))r.css("opacity",0).show(),l=1;for(p=1;p1&&c.splice.apply(c,[1,0].concat(c.splice(h,a+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.puff=function(t,n){var r=e(this),i=e.effects.setMode(r,t.mode||"hide"),s=i==="hide",o=parseInt(t.percent,10)||150,u=o/100,a={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()};e.extend(t,{effect:"scale",queue:!1,fade:!0,mode:i,complete:n,percent:s?o:100,from:s?a:{height:a.height*u,width:a.width*u,outerHeight:a.outerHeight*u,outerWidth:a.outerWidth*u}}),r.effect(t)},e.effects.effect.scale=function(t,n){var r=e(this),i=e.extend(!0,{},t),s=e.effects.setMode(r,t.mode||"effect"),o=parseInt(t.percent,10)||(parseInt(t.percent,10)===0?0:s==="hide"?0:100),u=t.direction||"both",a=t.origin,f={height:r.height(),width:r.width(),outerHeight:r.outerHeight(),outerWidth:r.outerWidth()},l={y:u!=="horizontal"?o/100:1,x:u!=="vertical"?o/100:1};i.effect="size",i.queue=!1,i.complete=n,s!=="effect"&&(i.origin=a||["middle","center"],i.restore=!0),i.from=t.from||(s==="show"?{height:0,width:0,outerHeight:0,outerWidth:0}:f),i.to={height:f.height*l.y,width:f.width*l.x,outerHeight:f.outerHeight*l.y,outerWidth:f.outerWidth*l.x},i.fade&&(s==="show"&&(i.from.opacity=0,i.to.opacity=1),s==="hide"&&(i.from.opacity=1,i.to.opacity=0)),r.effect(i)},e.effects.effect.size=function(t,n){var r,i,s,o=e(this),u=["position","top","bottom","left","right","width","height","overflow","opacity"],a=["position","top","bottom","left","right","overflow","opacity"],f=["width","height","overflow"],l=["fontSize"],c=["borderTopWidth","borderBottomWidth","paddingTop","paddingBottom"],h=["borderLeftWidth","borderRightWidth","paddingLeft","paddingRight"],p=e.effects.setMode(o,t.mode||"effect"),d=t.restore||p!=="effect",v=t.scale||"both",m=t.origin||["middle","center"],g=o.css("position"),y=d?u:a,b={height:0,width:0,outerHeight:0,outerWidth:0};p==="show"&&o.show(),r={height:o.height(),width:o.width(),outerHeight:o.outerHeight(),outerWidth:o.outerWidth()},t.mode==="toggle"&&p==="show"?(o.from=t.to||b,o.to=t.from||r):(o.from=t.from||(p==="show"?b:r),o.to=t.to||(p==="hide"?b:r)),s={from:{y:o.from.height/r.height,x:o.from.width/r.width},to:{y:o.to.height/r.height,x:o.to.width/r.width}};if(v==="box"||v==="both")s.from.y!==s.to.y&&(y=y.concat(c),o.from=e.effects.setTransition(o,c,s.from.y,o.from),o.to=e.effects.setTransition(o,c,s.to.y,o.to)),s.from.x!==s.to.x&&(y=y.concat(h),o.from=e.effects.setTransition(o,h,s.from.x,o.from),o.to=e.effects.setTransition(o,h,s.to.x,o.to));(v==="content"||v==="both")&&s.from.y!==s.to.y&&(y=y.concat(l).concat(f),o.from=e.effects.setTransition(o,l,s.from.y,o.from),o.to=e.effects.setTransition(o,l,s.to.y,o.to)),e.effects.save(o,y),o.show(),e.effects.createWrapper(o),o.css("overflow","hidden").css(o.from),m&&(i=e.effects.getBaseline(m,r),o.from.top=(r.outerHeight-o.outerHeight())*i.y,o.from.left=(r.outerWidth-o.outerWidth())*i.x,o.to.top=(r.outerHeight-o.to.outerHeight)*i.y,o.to.left=(r.outerWidth-o.to.outerWidth)*i.x),o.css(o.from);if(v==="content"||v==="both")c=c.concat(["marginTop","marginBottom"]).concat(l),h=h.concat(["marginLeft","marginRight"]),f=u.concat(c).concat(h),o.find("*[width]").each(function(){var n=e(this),r={height:n.height(),width:n.width(),outerHeight:n.outerHeight(),outerWidth:n.outerWidth()};d&&e.effects.save(n,f),n.from={height:r.height*s.from.y,width:r.width*s.from.x,outerHeight:r.outerHeight*s.from.y,outerWidth:r.outerWidth*s.from.x},n.to={height:r.height*s.to.y,width:r.width*s.to.x,outerHeight:r.height*s.to.y,outerWidth:r.width*s.to.x},s.from.y!==s.to.y&&(n.from=e.effects.setTransition(n,c,s.from.y,n.from),n.to=e.effects.setTransition(n,c,s.to.y,n.to)),s.from.x!==s.to.x&&(n.from=e.effects.setTransition(n,h,s.from.x,n.from),n.to=e.effects.setTransition(n,h,s.to.x,n.to)),n.css(n.from),n.animate(n.to,t.duration,t.easing,function(){d&&e.effects.restore(n,f)})});o.animate(o.to,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){o.to.opacity===0&&o.css("opacity",o.from.opacity),p==="hide"&&o.hide(),e.effects.restore(o,y),d||(g==="static"?o.css({position:"relative",top:o.to.top,left:o.to.left}):e.each(["top","left"],function(e,t){o.css(t,function(t,n){var r=parseInt(n,10),i=e?o.to.left:o.to.top;return n==="auto"?i+"px":r+i+"px"})})),e.effects.removeWrapper(o),n()}})}})(jQuery);(function(e,t){e.effects.effect.shake=function(t,n){var r=e(this),i=["position","top","bottom","left","right","height","width"],s=e.effects.setMode(r,t.mode||"effect"),o=t.direction||"left",u=t.distance||20,a=t.times||3,f=a*2+1,l=Math.round(t.duration/f),c=o==="up"||o==="down"?"top":"left",h=o==="up"||o==="left",p={},d={},v={},m,g=r.queue(),y=g.length;e.effects.save(r,i),r.show(),e.effects.createWrapper(r),p[c]=(h?"-=":"+=")+u,d[c]=(h?"+=":"-=")+u*2,v[c]=(h?"-=":"+=")+u*2,r.animate(p,l,t.easing);for(m=1;m1&&g.splice.apply(g,[1,0].concat(g.splice(y,f+1))),r.dequeue()}})(jQuery);(function(e,t){e.effects.effect.slide=function(t,n){var r=e(this),i=["position","top","bottom","left","right","width","height"],s=e.effects.setMode(r,t.mode||"show"),o=s==="show",u=t.direction||"left",a=u==="up"||u==="down"?"top":"left",f=u==="up"||u==="left",l,c={};e.effects.save(r,i),r.show(),l=t.distance||r[a==="top"?"outerHeight":"outerWidth"](!0),e.effects.createWrapper(r).css({overflow:"hidden"}),o&&r.css(a,f?isNaN(l)?"-"+l:-l:l),c[a]=(o?f?"+=":"-=":f?"-=":"+=")+l,r.animate(c,{queue:!1,duration:t.duration,easing:t.easing,complete:function(){s==="hide"&&r.hide(),e.effects.restore(r,i),e.effects.removeWrapper(r),n()}})}})(jQuery);(function(e,t){e.effects.effect.transfer=function(t,n){var r=e(this),i=e(t.to),s=i.css("position")==="fixed",o=e("body"),u=s?o.scrollTop():0,a=s?o.scrollLeft():0,f=i.offset(),l={top:f.top-u,left:f.left-a,height:i.innerHeight(),width:i.innerWidth()},c=r.offset(),h=e('
    ').appendTo(document.body).addClass(t.className).css({top:c.top-u,left:c.left-a,height:r.innerHeight(),width:r.innerWidth(),position:s?"fixed":"absolute"}).animate(l,t.duration,t.easing,function(){h.remove(),n()})}})(jQuery); \ No newline at end of file diff --git a/tract_querier/tornado_server/js/jquery.ui.slider.js b/tract_querier/tornado_server/js/jquery.ui.slider.js new file mode 100644 index 0000000..cf7affe --- /dev/null +++ b/tract_querier/tornado_server/js/jquery.ui.slider.js @@ -0,0 +1,114 @@ +// +// http://stackoverflow.com/questions/5955343/drag-the-range-of-a-ui-input-range-slider/6095941#6095941 +// +(function(jQuery, undefined) { + + jQuery + .widget( + "ui.dragslider", + jQuery.ui.slider, + { + + options: jQuery.extend({}, jQuery.ui.slider.prototype.options, { + rangeDrag: false + }), + + _create: function() { + + jQuery.ui.slider.prototype._create.apply(this, arguments); + this._rangeCapture = false; + }, + + _mouseCapture: function(event) { + + var o = this.options; + + if (o.disabled) { + return false; + } + + if (event.target == this.range.get(0) && o.rangeDrag == true && + o.range == true) { + this._rangeCapture = true; + this._rangeStart = null; + } else { + this._rangeCapture = false; + } + + jQuery.ui.slider.prototype._mouseCapture.apply(this, arguments); + + if (this._rangeCapture == true) { + this.handles.removeClass("ui-state-active").blur(); + } + + return true; + }, + + _mouseStop: function(event) { + + this._rangeStart = null; + return jQuery.ui.slider.prototype._mouseStop.apply(this, + arguments); + }, + + _slide: function(event, index, newVal) { + + if (!this._rangeCapture) { + return jQuery.ui.slider.prototype._slide.apply(this, arguments); + } + + if (this._rangeStart == null) { + this._rangeStart = newVal; + } + + var oldValLeft = this.options.values[0], oldValRight = this.options.values[1], slideDist = newVal - + this._rangeStart, newValueLeft = oldValLeft + slideDist, newValueRight = oldValRight + + slideDist, allowed; + + if (this.options.values && this.options.values.length) { + if (newValueRight > this._valueMax() && slideDist > 0) { + slideDist -= (newValueRight - this._valueMax()); + newValueLeft = oldValLeft + slideDist; + newValueRight = oldValRight + slideDist; + } + + if (newValueLeft < this._valueMin()) { + slideDist += (this._valueMin() - newValueLeft); + newValueLeft = oldValLeft + slideDist; + newValueRight = oldValRight + slideDist; + } + + if (slideDist != 0) { + newValues = this.values(); + newValues[0] = newValueLeft; + newValues[1] = newValueRight; + + // A slide can be canceled by returning false from the slide + // callback + allowed = this._trigger("slide", event, { + handle: this.handles[index], + value: slideDist, + values: newValues + }); + + if (allowed !== false) { + this.values(0, newValueLeft, true); + this.values(1, newValueRight, true); + } + this._rangeStart = newVal; + } + } + + + + }, + + + /* + * //only for testing purpose value: function(input) { + * console.log("this is working!"); + * jQuery.ui.slider.prototype.value.apply(this,arguments); } + */ + }); + +})(jQuery); diff --git a/tract_querier/tornado_server/js/wmqlviz.js b/tract_querier/tornado_server/js/wmqlviz.js new file mode 100644 index 0000000..02308dc --- /dev/null +++ b/tract_querier/tornado_server/js/wmqlviz.js @@ -0,0 +1,198 @@ +$(function() { + + // create the sliders for the 2D sliders + $("#yellow_slider").slider({ + slide: volumeslicingX + }); + $("#yellow_slider .ui-slider-handle").unbind('keydown'); + + $("#red_slider").slider({ + slide: volumeslicingY + }); + $("#red_slider .ui-slider-handle").unbind('keydown'); + + $("#green_slider").slider({ + slide: volumeslicingZ + }); + $("#green_slider .ui-slider-handle").unbind('keydown'); + +}); + +function init_viewer2d() { + + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + + // X Slice + if (sliceX) { + sliceX.destroy(); + } + sliceX = new X.renderer2D(); + sliceX.container = 'sliceX'; + sliceX.orientation = 'X'; + sliceX.init(); + sliceX.add(volume); + sliceX.render(); + sliceX.interactor.onMouseMove = function() { + if (_ATLAS_.hover){ + clearTimeout(_ATLAS_.hover); + } + _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceX), 100); + }; + + // Y Slice + if (sliceY) { + sliceY.destroy(); + } + sliceY = new X.renderer2D(); + sliceY.container = 'sliceY'; + sliceY.orientation = 'Y'; + sliceY.init(); + sliceY.add(volume); + sliceY.render(); + sliceY.interactor.onMouseMove = function() { + if (_ATLAS_.hover){ + clearTimeout(_ATLAS_.hover); + } + _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceY), 100); + }; + + // Z Slice + if (sliceZ) { + sliceZ.destroy(); + } + sliceZ = new X.renderer2D(); + sliceZ.container = 'sliceZ'; + sliceZ.orientation = 'Z'; + sliceZ.init(); + sliceZ.add(volume); + sliceZ.render(); + sliceZ.interactor.onMouseMove = function() { + if (_ATLAS_.hover){ + clearTimeout(_ATLAS_.hover); + } + _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceZ), 100); + }; + + // update 2d slice sliders + var dim = volume.dimensions; + $("#yellow_slider").slider("option", "disabled", false); + $("#yellow_slider").slider("option", "min", 0); + $("#yellow_slider").slider("option", "max", dim[0] - 1); + $("#yellow_slider").slider("option", "value", volume.indexX); + $("#red_slider").slider("option", "disabled", false); + $("#red_slider").slider("option", "min", 0); + $("#red_slider").slider("option", "max", dim[1] - 1); + $("#red_slider").slider("option", "value", volume.indexY); + $("#green_slider").slider("option", "disabled", false); + $("#green_slider").slider("option", "min", 0); + $("#green_slider").slider("option", "max", dim[2] - 1); + $("#green_slider").slider("option", "value", volume.indexZ); +}//init_viewer2d() + +// show labels on hover +function on2DHover(renderer) { + + // check that feature is enabled + if (!_ATLAS_.hoverLabelSelect){ + return; + } + + // get cursor position + var mousepos = renderer.interactor.mousePosition; + var ijk = renderer.xy2ijk(mousepos[0], mousepos[1]); + if (!ijk) { + return; + } + + // + var orientedIJK = ijk.slice(); + orientedIJK[0] = ijk[2]; + orientedIJK[1] = ijk[1]; + orientedIJK[2] = ijk[0]; + + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + + // get the number associated with the label + var labelvalue = volume.labelmap.image[orientedIJK[0]][orientedIJK[1]][orientedIJK[2]]; + if (!labelvalue || labelvalue == 0) { + return; + } + + var labelname = volume.labelmap.colortable.get(labelvalue)[0]; + var _r = parseInt(volume.labelmap.colortable.get(labelvalue)[1] * 255, 10); + var _g = parseInt(volume.labelmap.colortable.get(labelvalue)[2] * 255, 10); + var _b = parseInt(volume.labelmap.colortable.get(labelvalue)[3] * 255, 10); + $('#anatomy_caption').html(labelname); + $('#anatomy_caption').css('color', 'rgb( ' + _r + ',' + _g + ',' + _b + ' )' ); +} + + +sliceX = null; +sliceY = null; +sliceZ = null; + +function init_volume(filename, colortable) { + volume = new X.volume(); + volume.file = filename; //'MNI152_T1_1mm_brain.nii.gz'; + volume.labelmap.file = filename; //'MNI152_wmparc_1mm_small.nii.gz'; + volume.labelmap.colortable.file = colortable; //'FreeSurferColorLUT.txt'; + + _ATLAS_ = {}; + _ATLAS_.volumes = {}; + _ATLAS_.currentMesh = 0; + _ATLAS_.meshOpacity = 0.9; + _ATLAS_.labelOpacity = 0.5; + _ATLAS_.hover = null; + _ATLAS_.hoverLabelSelect = true; + + _ATLAS_.currentVolume = volume; + _ATLAS_.volumes[_ATLAS_.currentVolume] = volume +}; + +function init_websocket(host) { + console.info("websocket start"); + + _fibers_ = {}; + + $(document).ready(function () { + _WS_ = new WebSocket(host); + console.info("Activating stuff"); + _WS_.onopen = function () { + console.info("websocket engage"); + }; + + _WS_.onmessage = function(evt){ + console.info(evt.data) + + if (evt.data in _fibers_) { + console.info("Removing tract " + evt.data); + render3D.remove(_fibers_[evt.data]); + }; + + _fibers_[evt.data] = new X.fibers() + _fibers_[evt.data].file = 'files/' + evt.data + render3D.add(_fibers_[evt.data]) + }; + _WS_.onclose = function () { + console.info("connection closed"); + }; + + }); +}; + +window.onload = function() { + + render3D = new X.renderer3D(); + render3D.init(); + + render3D.onShowtime = function() { + init_viewer2d(); + } + + render3D.add(_ATLAS_.currentVolume) + render3D.render(); + +} + + + diff --git a/tract_querier/tornado_server/js/wmqlviz.js.in b/tract_querier/tornado_server/js/wmqlviz.js.in new file mode 100644 index 0000000..f40e05e --- /dev/null +++ b/tract_querier/tornado_server/js/wmqlviz.js.in @@ -0,0 +1,214 @@ +$(function() { + + // create the sliders for the 2D sliders + $("#yellow_slider").slider({ + slide: volumeslicingX + }); + $("#yellow_slider .ui-slider-handle").unbind('keydown'); + + $("#red_slider").slider({ + slide: volumeslicingY + }); + $("#red_slider .ui-slider-handle").unbind('keydown'); + + $("#green_slider").slider({ + slide: volumeslicingZ + }); + $("#green_slider .ui-slider-handle").unbind('keydown'); + +}); + +function init_viewer2d() { + + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + + // X Slice + if (sliceX) { + sliceX.destroy(); + } + sliceX = new X.renderer2D(); + sliceX.container = 'sliceX'; + sliceX.orientation = 'X'; + sliceX.init(); + sliceX.add(volume); + sliceX.render(); + sliceX.interactor.onMouseMove = function() { + if (_ATLAS_.hover){ + clearTimeout(_ATLAS_.hover); + } + _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceX), 100); + }; + + // Y Slice + if (sliceY) { + sliceY.destroy(); + } + sliceY = new X.renderer2D(); + sliceY.container = 'sliceY'; + sliceY.orientation = 'Y'; + sliceY.init(); + sliceY.add(volume); + sliceY.render(); + sliceY.interactor.onMouseMove = function() { + if (_ATLAS_.hover){ + clearTimeout(_ATLAS_.hover); + } + _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceY), 100); + }; + + // Z Slice + if (sliceZ) { + sliceZ.destroy(); + } + sliceZ = new X.renderer2D(); + sliceZ.container = 'sliceZ'; + sliceZ.orientation = 'Z'; + sliceZ.init(); + sliceZ.add(volume); + sliceZ.render(); + sliceZ.interactor.onMouseMove = function() { + if (_ATLAS_.hover){ + clearTimeout(_ATLAS_.hover); + } + _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceZ), 100); + }; + + // update 2d slice sliders + var dim = volume.dimensions; + $("#yellow_slider").slider("option", "disabled", false); + $("#yellow_slider").slider("option", "min", 0); + $("#yellow_slider").slider("option", "max", dim[0] - 1); + $("#yellow_slider").slider("option", "value", volume.indexX); + $("#red_slider").slider("option", "disabled", false); + $("#red_slider").slider("option", "min", 0); + $("#red_slider").slider("option", "max", dim[1] - 1); + $("#red_slider").slider("option", "value", volume.indexY); + $("#green_slider").slider("option", "disabled", false); + $("#green_slider").slider("option", "min", 0); + $("#green_slider").slider("option", "max", dim[2] - 1); + $("#green_slider").slider("option", "value", volume.indexZ); +}//init_viewer2d() + +// show labels on hover +function on2DHover(renderer) { + + // check that feature is enabled + if (!_ATLAS_.hoverLabelSelect){ + return; + } + + // get cursor position + var mousepos = renderer.interactor.mousePosition; + var ijk = renderer.xy2ijk(mousepos[0], mousepos[1]); + if (!ijk) { + return; + } + + // + var orientedIJK = ijk.slice(); + orientedIJK[0] = ijk[2]; + orientedIJK[1] = ijk[1]; + orientedIJK[2] = ijk[0]; + + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + + // get the number associated with the label + var labelvalue = volume.labelmap.image[orientedIJK[0]][orientedIJK[1]][orientedIJK[2]]; + if (!labelvalue || labelvalue == 0) { + return; + } + + //volume.labelmap.opacity = 0.6; + //volume.labelmap.showOnly = labelvalue; + console.info(labelvalue); + _WS_.send(labelvalue) + var labelname = volume.labelmap.colortable.get(labelvalue)[0]; + var _r = parseInt(volume.labelmap.colortable.get(labelvalue)[1] * 255, 10); + var _g = parseInt(volume.labelmap.colortable.get(labelvalue)[2] * 255, 10); + var _b = parseInt(volume.labelmap.colortable.get(labelvalue)[3] * 255, 10); + $('#anatomy_caption').html(labelname); + $('#anatomy_caption').css('color', 'rgb( ' + _r + ',' + _g + ',' + _b + ' )' ); +} + + +sliceX = null; +sliceY = null; +sliceZ = null; + +function init_websocket(localsocket) { + Error("test"); + console.info("websocket start"); + + $(document).ready(function () { + _WS_=new WebSocket(localsocket); + +// _WS_=new WebSocket("ws://localhost:%(port)d/ws"); + console.info("Activating stuff") + _WS_.onopen = function () { + console.info("websocket engage"); + }; + + _WS_.onmessage = function(evt){ + console.info(evt.data) + new_fibers = new X.fibers() + new_fibers.file = evt.data + render3D.add(new_fibers) + //the received content is in evt.data, set it where you want + }; + + _WS_.onclose = function () { + console.info("connection closed"); + }; + + $(".column li").on("mouseup") //the function that sends data + { + pid = $(this).attr("id"); + oldCid = $(this).parent().parent().attr("id"); + newCid = $(this).parent().attr("id"); + message = pid + " " + oldCid + " " + newCid; + _WS_.send(message); + }; + }); + + _WS_.send("test inside"); +}; + +window.onload = function() { + +init_websocket(); + +render3D = new X.renderer3D(); +render3D.init(); + +// create a mesh from a .vtk file +// // create a new X.fibers +volume = new X.volume(); +volume.file = '%(volume)s'; +volume.labelmap.file = '%(volume)s'; +volume.labelmap.colortable.file = '%(colortable)s'; + +_ATLAS_ = {}; +_ATLAS_.currentVolume = volume; +_ATLAS_.volumes = {}; +_ATLAS_.volumes[_ATLAS_.currentVolume] = volume +_ATLAS_.currentMesh = 0; +_ATLAS_.meshOpacity = 0.9; +_ATLAS_.labelOpacity = 0.5; +_ATLAS_.hover = null; +_ATLAS_.hoverLabelSelect = true; + +render3D.add(volume); + +// .. and render it +// +render3D.onShowtime = function() { + init_viewer2d(); +} + + +render3D.render(); + +} + + + diff --git a/tract_querier/tornado_server/js/wmqlviz_scratch.js b/tract_querier/tornado_server/js/wmqlviz_scratch.js new file mode 100644 index 0000000..dbdb1c5 --- /dev/null +++ b/tract_querier/tornado_server/js/wmqlviz_scratch.js @@ -0,0 +1,302 @@ +$(function() { + + // create the sliders for the 2D sliders + $("#yellow_slider").slider({ + slide: volumeslicingX + }); + $("#yellow_slider .ui-slider-handle").unbind('keydown'); + + $("#red_slider").slider({ + slide: volumeslicingY + }); + $("#red_slider .ui-slider-handle").unbind('keydown'); + + $("#green_slider").slider({ + slide: volumeslicingZ + }); + $("#green_slider .ui-slider-handle").unbind('keydown'); + +}); + +function init_viewer2d() { + + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + + // X Slice + if (sliceX) { + sliceX.destroy(); + } + sliceX = new X.renderer2D(); + sliceX.container = 'sliceX'; + sliceX.orientation = 'X'; + sliceX.init(); + sliceX.add(volume); + sliceX.render(); + sliceX.interactor.onMouseMove = function() { + if (_ATLAS_.hover){ + clearTimeout(_ATLAS_.hover); + } + _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceX), 100); + }; + + // Y Slice + if (sliceY) { + sliceY.destroy(); + } + sliceY = new X.renderer2D(); + sliceY.container = 'sliceY'; + sliceY.orientation = 'Y'; + sliceY.init(); + sliceY.add(volume); + sliceY.render(); + sliceY.interactor.onMouseMove = function() { + if (_ATLAS_.hover){ + clearTimeout(_ATLAS_.hover); + } + _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceY), 100); + }; + + // Z Slice + if (sliceZ) { + sliceZ.destroy(); + } + sliceZ = new X.renderer2D(); + sliceZ.container = 'sliceZ'; + sliceZ.orientation = 'Z'; + sliceZ.init(); + sliceZ.add(volume); + sliceZ.render(); + sliceZ.interactor.onMouseMove = function() { + if (_ATLAS_.hover){ + clearTimeout(_ATLAS_.hover); + } + _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceZ), 100); + }; + + // update 2d slice sliders + var dim = volume.dimensions; + $("#yellow_slider").slider("option", "disabled", false); + $("#yellow_slider").slider("option", "min", 0); + $("#yellow_slider").slider("option", "max", dim[0] - 1); + $("#yellow_slider").slider("option", "value", volume.indexX); + $("#red_slider").slider("option", "disabled", false); + $("#red_slider").slider("option", "min", 0); + $("#red_slider").slider("option", "max", dim[1] - 1); + $("#red_slider").slider("option", "value", volume.indexY); + $("#green_slider").slider("option", "disabled", false); + $("#green_slider").slider("option", "min", 0); + $("#green_slider").slider("option", "max", dim[2] - 1); + $("#green_slider").slider("option", "value", volume.indexZ); +}//init_viewer2d() + +// show labels on hover +function on2DHover(renderer) { + + // check that feature is enabled + if (!_ATLAS_.hoverLabelSelect){ + return; + } + + // get cursor position + var mousepos = renderer.interactor.mousePosition; + var ijk = renderer.xy2ijk(mousepos[0], mousepos[1]); + if (!ijk) { + return; + } + + // + var orientedIJK = ijk.slice(); + orientedIJK[0] = ijk[2]; + orientedIJK[1] = ijk[1]; + orientedIJK[2] = ijk[0]; + + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + + // get the number associated with the label + var labelvalue = volume.labelmap.image[orientedIJK[0]][orientedIJK[1]][orientedIJK[2]]; + if (!labelvalue || labelvalue == 0) { + return; + } + //console.info(labelvalue); + + + //volume.labelmap.opacity = 0.6; + //volume.labelmap.showOnly = labelvalue; + console.info(labelvalue); + _WS_.send(labelvalue) + var labelname = volume.labelmap.colortable.get(labelvalue)[0]; + var _r = parseInt(volume.labelmap.colortable.get(labelvalue)[1] * 255, 10); + var _g = parseInt(volume.labelmap.colortable.get(labelvalue)[2] * 255, 10); + var _b = parseInt(volume.labelmap.colortable.get(labelvalue)[3] * 255, 10); + $('#anatomy_caption').html(labelname); + $('#anatomy_caption').css('color', 'rgb( ' + _r + ',' + _g + ',' + _b + ' )' ); +} + + +sliceX = null; +sliceY = null; +sliceZ = null; + +function init_websocket() { + Error("test"); + console.info("websocket start"); + + $(document).ready(function () { + _WS_=new WebSocket("_WS_://localhost:9999/_WS_"); + console.info("Activating stuff") + _WS_.onopen = function () { + console.info("websocket engage"); + }; + + _WS_.onmessage = function(evt){ + console.info(evt.data) + new_fibers = new X.fibers() + new_fibers.file = evt.data + render3D.add(new_fibers) + //the received content is in evt.data, set it where you want + }; + + _WS_.onclose = function () { + console.info("connection closed"); + }; + + $(".column li").on("mouseup") //the function that sends data + { + pid = $(this).attr("id"); + oldCid = $(this).parent().parent().attr("id"); + newCid = $(this).parent().attr("id"); + message = pid + " " + oldCid + " " + newCid; + _WS_.send(message); + }; + }); + + _WS_.send("test inside"); +}; + +window.onload = function() { +console.info("OnLoad"); +init_websocket(); + +render3D = new X.renderer3D(); +render3D.init(); + +// create a mesh from a .vtk file +// // create a new X.fibers +volume = new X.volume(); +volume.file = 'MNI152_T1_1mm_brain.nii.gz'; +//volume.file = 't1_very_small_2.nii.gz'; +//volume.color = [1, 0, 0]; +//volume.labelmap.file = 'MNI152_wmparc_1mm.nii.gz'; +volume.labelmap.file = 'MNI152_wmparc_1mm_small.nii.gz'; +volume.labelmap.colortable.file = 'FreeSurferColorLUT.txt'; +//volume.visible = false; +//volume.labelmap.visible = true; + +_ATLAS_ = {}; +_ATLAS_.currentVolume = volume; +_ATLAS_.volumes = {}; +_ATLAS_.volumes[_ATLAS_.currentVolume] = volume +_ATLAS_.currentMesh = 0; +_ATLAS_.meshOpacity = 0.9; +_ATLAS_.labelOpacity = 0.5; +_ATLAS_.hover = null; +_ATLAS_.hoverLabelSelect = true; + +// create dictionary "label name" : "label value" +//initializeFreesurferLabels(_ATLAS_); +/*_ATLAS_.labels4 = { + "Accumbens area": 26, + "Amygdala": 18, + "Caudate": 11, + "Cerebellum Cortex": 8, + "Cerebral Cortex": 3, + "Hippocampus": 17, + "Lateral Ventricle": 4, + "Medulla": 175, + "Midbrain": 173, + "Pallidum": 13, + "Pons": 174, + "Putamen": 12, + "Thalamus": 9, + "Ventral DC": 28, + "Vermis": 172, + "3rd Ventricle": 14, + "4th Ventricle": 15 +};*/ + + + + +//var fibers = new X.fibers(); + + +//render3D.camera.position = [120, 80, 160]; + +render3D.add(volume); +//render3D.add(volume.labelmap); +var fibers = new X.fibers(); +fibers.file = +render3D.add(fibers); + +// .. and render it +// +render3D.onShowtime = function() { + init_viewer2d(); +} +/*render3D.onShowtime = function() { + + // + // The GUI panel + // + // (we need to create this during onShowtime(..) since we do not know the + // volume dimensions before the loading was completed) + + // indicate if the mesh was loaded + var gui = new dat.GUI(); + + var labelmapgui = gui.addFolder('Label Map'); + var labelMapVisibleController = labelmapgui.add(volume.labelmap, 'visible'); + + // the following configures the gui for interacting with the X.volume + var volumegui = gui.addFolder('Volume'); + // now we can configure controllers which.. + var visibilityControler = volumegui.add(volume, 'visible') + + // .. switch between slicing and volume rendering + //var vrController = volumegui.add(volume, 'volumeRendering'); + // the min and max color which define the linear gradient mapping + var minColorController = volumegui.addColor(volume, 'minColor'); + var maxColorController = volumegui.addColor(volume, 'maxColor'); + // .. configure the volume rendering opacity + var opacityController = volumegui.add(volume, 'opacity', 0, 1).listen(); + // .. and the threshold in the min..max range + var lowerThresholdController = volumegui.add(volume, 'lowerThreshold', + volume.min, volume.max); + var upperThresholdController = volumegui.add(volume, 'upperThreshold', + volume.min, volume.max); + var lowerWindowController = volumegui.add(volume, 'windowLow', volume.min, + volume.max); + var upperWindowController = volumegui.add(volume, 'windowHigh', volume.min, + volume.max); + // the indexX,Y,Z are the currently displayed slice indices in the range + // 0..dimensions-1 + var sliceXController = volumegui.add(volume, 'indexX', 0, + volume.dimensions[0] - 1); + var sliceYController = volumegui.add(volume, 'indexY', 0, + volume.dimensions[1] - 1); + var sliceZController = volumegui.add(volume, 'indexZ', 0, + volume.dimensions[2] - 1); + + //var fibergui = gui.addFolder('Fiber'); + //trackVisibleController = fibergui.add(fibers, 'visible'); + + //fibergui.open() + volumegui.open(); +};*/ + +render3D.render(); + +} + + + diff --git a/tract_querier/tornado_server/js/x.controller.js b/tract_querier/tornado_server/js/x.controller.js new file mode 100644 index 0000000..3dedaa5 --- /dev/null +++ b/tract_querier/tornado_server/js/x.controller.js @@ -0,0 +1,360 @@ +/* + + .----. _..._ .-'''-. + / .--./ .---. .-'_..._''. _______ ' _ \ + ' ' | |.--. .' .' '.\ __.....__ \ ___ `'. / /` '. \_________ _...._ + \ \ | ||__| / .' .-'' '. ,.--. ' |--.\ \ . | \ '\ |.' '-. + `.`'--. | |.--.. ' / .-''"'-. `. // \| | \ ' .-,.--.| ' | '\ .'```'. '. + `'-. `. | || || | / /________\ \\\ /| | | '| .-. \ \ / / \ | \ \ + `. \ | || || | | | `'--' | | | || | | |`. ` ..' / | | | | + \ '| || |. ' \ .-------------' ,.--. | | ' .'| | | | '-...-'` | \ / . + | | || | \ '. .\ '-.____...---.// \| |___.' /' | | '- | |\`'-.-' .' + | | ||__| '. `._____.-'/ `. .' \\ /_______.'/ | | | | '-....-'` + / /'---' `-.______ / `''-...... -' `'--'\_______|/ | | .' '. + /...-'.' ` |_| '-----------' + /--...-' + + Slice:Drop - Instantly view scientific and medical imaging data in 3D. + + http://slicedrop.com + + Copyright (c) 2012 The Slice:Drop and X Toolkit Developers + + Slice:Drop is licensed under the MIT License: + http://www.opensource.org/licenses/mit-license.php + + CREDITS: http://slicedrop.com/LICENSE + +*/ + +/** + * Setup all UI elements once the loading was completed. + */ +function setupUi() { + +} + +function toggleVolumeRendering() { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + volume.volumeRendering = !volume.volumeRendering; +} + +function thresholdVolume(event, ui) { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + if (!volume) { + return; + } + if (event == null){ + if (ui[0] != null){ + volume.lowerThreshold = ui[0]; + volume.upperThreshold = ui[1]; + } + if (ui[1] != null){ + volume.lowerThreshold = ui[0]; + volume.upperThreshold = ui[1]; + } + } else { + volume.lowerThreshold = ui.values[0]; + volume.upperThreshold = ui.values[1]; + } +} + +function windowLevelVolume(event, ui) { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + if (!volume) { + return; + } + + volume.windowLow = ui.values[0]; + volume.windowHigh = ui.values[1]; +} + +function opacity3dVolume(event, ui) { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + if (!volume) { + return; + } + if (event == null){ + volume.opacity = ui; + } else { + volume.opacity = ui.value / 100; + } +} + +function toggleAxialSliceVisibility() { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + volume.children[2].children[Math.floor(volume.indexZ)].visible = !volume.children[2].children[Math.floor(volume.indexZ)].visible; +} + +function toggleCoronalSliceVisibility() { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + volume.children[1].children[Math.floor(volume.indexY)].visible = !volume.children[1].children[Math.floor(volume.indexY)].visible; +} + +function toggleSagittalSliceVisibility() { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + volume.children[0].children[Math.floor(volume.indexX)].visible = !volume.children[0].children[Math.floor(volume.indexX)].visible; +} + +function volumeslicingX(event, ui) { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + if (!volume) { + return; + } + volume.indexX = Math.floor($('#yellow_slider').slider("option", "value")); +} + +function volumeslicingY(event, ui) { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + if (!volume) { + return; + } + volume.indexY = Math.floor($('#red_slider').slider("option", "value")); +} + +function volumeslicingZ(event, ui) { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + if (!volume) { + return; + } + volume.indexZ = Math.floor($('#green_slider').slider("option", "value")); +} + +function fgColorVolume(hex, rgb) { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + if (!volume) { + return; + } + + volume.maxColor = [rgb.r / 255, rgb.g / 255, rgb.b / 255]; + + if (RT.linked) { + + clearTimeout(RT._updater); + RT._updater = setTimeout(RT.pushVolume.bind(RT, 'maxColor', volume.maxColor), 150); + + } + +} + +function bgColorVolume(hex, rgb) { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + if (!volume) { + return; + } + + volume.minColor = [rgb.r / 255, rgb.g / 255, rgb.b / 255]; + + if (RT.linked) { + + clearTimeout(RT._updater); + RT._updater = setTimeout(RT.pushVolume.bind(RT, 'minColor', volume.minColor), 150); + + } + +} + +// +// LABELMAP +// +function opacityLabelmap(event, ui) { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + if (!volume) { + return; + } + if (event == null){ + volume.labelmap.opacity = ui; + } else { + volume.labelmap.opacity = ui.value / 100; + } +} + +function toggleLabelmapVisibility(label) { + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + if (!volume) { + return; + } + if (label == "all") { + label = null; + volume.labelmap.opacity = 0.5; + } else if (label == "none") { + label = null; + volume.labelmap.opacity = 0; + } else { + volume.labelmap.opacity = 0.5; + } + volume.labelmap.showOnly = label; + + // remember opacity + _ATLAS_.labelOpacity = volume.labelmap.opacity; + + // update label caption + var labelname = volume.labelmap.colortable.get(label)[0]; + var _r = parseInt(volume.labelmap.colortable.get(label)[1] * 255, 10); + var _g = parseInt(volume.labelmap.colortable.get(label)[2] * 255, 10); + var _b = parseInt(volume.labelmap.colortable.get(label)[3] * 255, 10); + $('#anatomy_caption').html(labelname); + $('#anatomy_caption').css('color', 'rgb( ' + _r + ',' + _g + ',' + _b + ' )' ); +} + +// +// MESH +// +function toggleMeshVisibility(label) { + + if (!_ATLAS_.meshes[_ATLAS_.currentVolume][label]) { + // load mesh + var m = new X.mesh(); + m.file = "data/"+_ATLAS_.steps[_ATLAS_.currentVolume]+"/"+label; + m.caption = label.replace(".vtk","").split("_")[2].split();//.replace("Model_","") + console.log(label); + r0.add(m); + // grab label value + var labelvalue = label.replace("Model_","").split("_")[0]; + m.color = _ATLAS_.volumes[0].labelmap.colortable.get(labelvalue).slice(0).splice(1,3); + _ATLAS_.meshes[_ATLAS_.currentVolume][label] = m; + _ATLAS_.meshes[_ATLAS_.currentVolume][label].visible = false; + _ATLAS_.meshes[_ATLAS_.currentVolume][label].opacity = _ATLAS_.meshOpacity; + } + // show the mesh + _ATLAS_.meshes[_ATLAS_.currentVolume][label].visible = !_ATLAS_.meshes[_ATLAS_.currentVolume][label].visible; +} + +function meshColor(hex, rgb) { + + if (!mesh) { + return; + } + + mesh.color = [rgb.r / 255, rgb.g / 255, rgb.b / 255]; + + if (RT.linked) { + + clearTimeout(RT._updater); + RT._updater = setTimeout(RT.pushMesh.bind(RT, 'color', mesh.color), 150); + + } +} + +function opacityMesh(event, ui) { + + for (var m in _ATLAS_.meshes[_ATLAS_.currentVolume]) { + if (_ATLAS_.meshes[_ATLAS_.currentVolume][m] != null) { + _ATLAS_.meshes[_ATLAS_.currentVolume][m].opacity = ui.value / 100; + } + } + + _ATLAS_.meshOpacity = ui.value / 100; + + //_ATLAS_.meshes[_ATLAS_.currentVolume]['Model_3_Left-Cerebral-Cortex.vtk'].opacity = ui.value / 100; +/* if (RT.linked) { + + clearTimeout(RT._updater); + RT._updater = setTimeout(RT.pushMesh.bind(RT, 'opacity', mesh.opacity), 150); + + } + */ +} + +function thresholdScalars(event, ui) { + + if (!mesh) { + return; + } + + mesh.scalars.lowerThreshold = ui.values[0] / 100; + mesh.scalars.upperThreshold = ui.values[1] / 100; + + if (RT.linked) { + + clearTimeout(RT._updater); + RT._updater = setTimeout(RT.pushScalars.bind(RT, 'lowerThreshold', mesh.scalars.lowerThreshold), 150); + clearTimeout(RT._updater2); + RT._updater2 = setTimeout(RT.pushScalars.bind(RT, 'upperThreshold', mesh.scalars.upperThreshold), 150); + + } + +} + +function scalarsMinColor(hex, rgb) { + + if (!mesh) { + return; + } + + mesh.scalars.minColor = [rgb.r / 255, rgb.g / 255, rgb.b / 255]; + + if (RT.linked) { + + clearTimeout(RT._updater); + RT._updater = setTimeout(RT.pushScalars.bind(RT, 'minColor', mesh.scalars.minColor), 150); + + } + +} + +function scalarsMaxColor(hex, rgb) { + + if (!mesh) { + return; + } + + mesh.scalars.maxColor = [rgb.r / 255, rgb.g / 255, rgb.b / 255]; + + if (RT.linked) { + + clearTimeout(RT._updater); + RT._updater = setTimeout(RT.pushScalars.bind(RT, 'maxColor', mesh.scalars.maxColor), 150); + + } + +} + +// +// Fibers +// +function toggleFibersVisibility() { + + if (!fibers) { + return; + } + + fibers.visible = !fibers.visible; + + if (RT.linked) { + + clearTimeout(RT._updater); + RT._updater = setTimeout(RT.pushFibers.bind(RT, 'visible', fibers.visible), 150); + + } + + +} + +function thresholdFibers(event, ui) { + + if (!fibers) { + return; + } + + fibers.scalars.lowerThreshold = ui.values[0]; + fibers.scalars.upperThreshold = ui.values[1]; + if (RT.linked) { + + clearTimeout(RT._updater); + RT._updater = setTimeout(RT.pushFibersScalars.bind(RT, 'lowerThreshold', fibers.scalars.lowerThreshold), 150); + clearTimeout(RT._updater2); + RT._updater2 = setTimeout(RT.pushFibersScalars.bind(RT, 'upperThreshold', fibers.scalars.upperThreshold), 150); + + } + +} + + + +function scene_picking_check() { + + // return the currently picked model + return $('.scene_picker').filter(':visible').html(); + +} \ No newline at end of file diff --git a/tract_querier/tornado_server/js/x.viewer2d.js b/tract_querier/tornado_server/js/x.viewer2d.js new file mode 100644 index 0000000..a2fc780 --- /dev/null +++ b/tract_querier/tornado_server/js/x.viewer2d.js @@ -0,0 +1,139 @@ + + +// create 2D viewer controls + +/*$(function() { + + // create the sliders for the 2D sliders + $("#yellow_slider").slider({ + slide: volumeslicingX + }); + $("#yellow_slider .ui-slider-handle").unbind('keydown'); + + $("#red_slider").slider({ + slide: volumeslicingY + }); + $("#red_slider .ui-slider-handle").unbind('keydown'); + + $("#green_slider").slider({ + slide: volumeslicingZ + }); + $("#green_slider .ui-slider-handle").unbind('keydown'); + +});*/ + + +// initialize the 2D viewers +function init_viewer2d() { + + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + + // X Slice + if (sliceX) { + sliceX.destroy(); + } + sliceX = new X.renderer2D(); + sliceX.container = 'sliceX'; + sliceX.orientation = 'X'; + sliceX.init(); + sliceX.add(volume); + sliceX.render(); + sliceX.interactor.onMouseMove = function() { + if (_ATLAS_.hover){ + clearTimeout(_ATLAS_.hover); + } + _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceX), 100); + }; + + // Y Slice + if (sliceY) { + sliceY.destroy(); + } + sliceY = new X.renderer2D(); + sliceY.container = 'sliceY'; + sliceY.orientation = 'Y'; + sliceY.init(); + sliceY.add(volume); + sliceY.render(); + sliceY.interactor.onMouseMove = function() { + if (_ATLAS_.hover){ + clearTimeout(_ATLAS_.hover); + } + _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceY), 100); + }; + + // Z Slice + if (sliceZ) { + sliceZ.destroy(); + } + sliceZ = new X.renderer2D(); + sliceZ.container = 'sliceZ'; + sliceZ.orientation = 'Z'; + sliceZ.init(); + sliceZ.add(volume); + sliceZ.render(); + sliceZ.interactor.onMouseMove = function() { + if (_ATLAS_.hover){ + clearTimeout(_ATLAS_.hover); + } + _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceZ), 100); + }; + + // update 2d slice sliders + var dim = volume.dimensions; + $("#yellow_slider").slider("option", "disabled", false); + $("#yellow_slider").slider("option", "min", 0); + $("#yellow_slider").slider("option", "max", dim[0] - 1); + $("#yellow_slider").slider("option", "value", volume.indexX); + $("#red_slider").slider("option", "disabled", false); + $("#red_slider").slider("option", "min", 0); + $("#red_slider").slider("option", "max", dim[1] - 1); + $("#red_slider").slider("option", "value", volume.indexY); + $("#green_slider").slider("option", "disabled", false); + $("#green_slider").slider("option", "min", 0); + $("#green_slider").slider("option", "max", dim[2] - 1); + $("#green_slider").slider("option", "value", volume.indexZ); + +}//init_viewer2d() + + +// show labels on hover +function on2DHover(renderer) { + + // check that feature is enabled + if (!_ATLAS_.hoverLabelSelect){ + return; + } + + // get cursor position + var mousepos = renderer.interactor.mousePosition; + var ijk = renderer.xy2ijk(mousepos[0], mousepos[1]); + if (!ijk) { + return; + } + + // + var orientedIJK = ijk.slice(); + orientedIJK[0] = ijk[2]; + orientedIJK[1] = ijk[1]; + orientedIJK[2] = ijk[0]; + + var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + + // get the number associated with the label + var labelvalue = volume.labelmap.image[orientedIJK[0]][orientedIJK[1]][orientedIJK[2]]; + if (!labelvalue || labelvalue == 0) { + return; + } + //console.log(labelvalue); + + + volume.labelmap.opacity = 0.6; + volume.labelmap.showOnly = labelvalue; + var labelname = volume.labelmap.colortable.get(labelvalue)[0]; + var _r = parseInt(volume.labelmap.colortable.get(labelvalue)[1] * 255, 10); + var _g = parseInt(volume.labelmap.colortable.get(labelvalue)[2] * 255, 10); + var _b = parseInt(volume.labelmap.colortable.get(labelvalue)[3] * 255, 10); + $('#anatomy_caption').html(labelname); + $('#anatomy_caption').css('color', 'rgb( ' + _r + ',' + _g + ',' + _b + ' )' ); +} diff --git a/tract_querier/tornado_server/js/xtk.js b/tract_querier/tornado_server/js/xtk.js new file mode 100644 index 0000000..d9bab45 --- /dev/null +++ b/tract_querier/tornado_server/js/xtk.js @@ -0,0 +1,348 @@ +/* + * + * xxxxxxx xxxxxxx + * x:::::x x:::::x + * x:::::x x:::::x + * x:::::xx:::::x + * x::::::::::x + * x::::::::x + * x::::::::x + * x::::::::::x + * x:::::xx:::::x + * x:::::x x:::::x + * x:::::x x:::::x + * THE xxxxxxx xxxxxxx TOOLKIT + * + * http://www.goXTK.com + * + * Copyright (c) 2012 The X Toolkit Developers + * + * The X Toolkit (XTK) is licensed under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + * "Free software" is a matter of liberty, not price. + * "Free" as in "free speech", not as in "free beer". + * - Richard M. Stallman + * + * FUELED BY: + * - the wonderful Constructive Solid Geometry library by Evan Wallace (http://madebyevan.com) + * LICENSE: https://raw.github.com/xtk/X/master/lib/csg/LICENSE + * + * - parts of the Google Closure Library (http://code.google.com/closure/library) + * LICENSE: https://raw.github.com/xtk/google-closure-library/master/LICENSE + * + * - zlib.js, the ultimate gzip/zlib javascript implementation (https://github.com/imaya/zlib.js) + * LICENSE: https://raw.github.com/imaya/zlib.js/master/LICENSE + * + * MORE CREDITS: https://raw.github.com/xtk/X/master/LICENSE + * + */ +function m(a){throw a;}var n=void 0,q=!0,r=null,s=!1;function ba(){return function(){}}function ea(a){return function(b){this[a]=b}}function t(a){return function(){return this[a]}}var w,fa=this;function ga(){} +function ia(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null"; +else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function ja(a){return a!==n}function y(a){return"array"==ia(a)}function la(a){var b=ia(a);return"array"==b||"object"==b&&"number"==typeof a.length}function ma(a){return"string"==typeof a}function D(a){return"number"==typeof a}function na(a){return"function"==ia(a)}function oa(a){var b=typeof a;return"object"==b&&a!=r||"function"==b}function pa(a){return a[qa]||(a[qa]=++ra)}var qa="closure_uid_"+(1E9*Math.random()>>>0),ra=0; +function sa(a,b,c){return a.call.apply(a.bind,arguments)}function ta(a,b,c){a||m(Error());if(2a&&(a=this.byteLength+a);0>c&&(c=this.byteLength+c);ca&&(a=0);0>c&&(c=0);a>this.byteLength&&(a=this.byteLength);c>this.byteLength&&(c=this.byteLength);for(var d=new ArrayBuffer(c-a),e=new Uint8Array(this),f=new Uint8Array(d),g=a,h=0;g")&&(a=a.replace(Ta,">"));-1!=a.indexOf('"')&&(a=a.replace(Ua,"""));return a}var Ra=/&/g,Sa=//g,Ua=/\"/g,Qa=/[&<>\"]/;var Va,Xa,Ya,Za,$a,bb,cb;function db(){return fa.navigator?fa.navigator.userAgent:r}function eb(){return fa.navigator}Za=Ya=Xa=Va=s;var gb;if(gb=db()){var hb=eb();Va=0==gb.indexOf("Opera");Xa=!Va&&-1!=gb.indexOf("MSIE");Ya=!Va&&-1!=gb.indexOf("WebKit");Za=!Va&&!Ya&&"Gecko"==hb.product}var ib=Va,M=Xa,jb=Za,kb=Ya,lb,mb=eb();lb=mb&&mb.platform||"";$a=-1!=lb.indexOf("Mac");bb=-1!=lb.indexOf("Win");cb=-1!=lb.indexOf("Linux");var nb=!!eb()&&-1!=(eb().appVersion||"").indexOf("X11"); +function ob(){var a=fa.document;return a?a.documentMode:n}var pb;a:{var qb="",rb;if(ib&&fa.opera)var sb=fa.opera.version,qb="function"==typeof sb?sb():sb;else if(jb?rb=/rv\:([^\);]+)(\)|;)/:M?rb=/MSIE\s+([^\);]+)(\)|;)/:kb&&(rb=/WebKit\/(\S+)/),rb)var tb=rb.exec(db()),qb=tb?tb[1]:"";if(M){var ub=ob();if(ub>parseFloat(qb)){pb=String(ub);break a}}pb=qb}var vb={}; +function xb(a){var b;if(!(b=vb[a])){b=0;for(var c=String(pb).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),d=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),e=Math.max(c.length,d.length),f=0;0==b&&f(0==p[1].length?0:parseInt(p[1],10))?1:0)||((0==l[2].length)<(0==p[2].length)?-1:(0==l[2].length)>(0==p[2].length)?1:0)||(l[2]p[2]?1:0)}while(0==b)}b=vb[a]=0<=b}return b}var yb=fa.document,zb=!yb||!M?n:ob()||("CSS1Compat"==yb.compatMode?parseInt(pb,10):5);var Ab=!M||M&&9<=zb,Bb=M&&!xb("9");!kb||xb("528");jb&&xb("1.9b")||M&&xb("8")||ib&&xb("9.5")||kb&&xb("528");jb&&!xb("8")||M&&xb("9");var Cb=Array.prototype,Db=Cb.indexOf?function(a,b,c){return Cb.indexOf.call(a,b,c)}:function(a,b,c){c=c==r?0:0>c?Math.max(0,a.length+c):c;if(ma(a))return!ma(b)||1!=b.length?-1:a.indexOf(b,c);for(;c=arguments.length?Cb.slice.call(a,b):Cb.slice.call(a,b,c)};function Jb(){0!=Kb&&(this.Sj=Error().stack,pa(this))}var Kb=0;function Lb(a,b){this.type=a;this.currentTarget=this.target=b}w=Lb.prototype;w.cc=s;w.defaultPrevented=s;w.Md=q;w.stopPropagation=function(){this.cc=q};w.preventDefault=function(){this.defaultPrevented=q;this.Md=s};function Mb(a){Mb[" "](a);return a}Mb[" "]=ga;function Nb(a,b){a&&this.ha(a,b)}G(Nb,Lb);w=Nb.prototype;w.target=r;w.relatedTarget=r;w.offsetX=0;w.offsetY=0;w.clientX=0;w.clientY=0;w.screenX=0;w.screenY=0;w.button=0;w.keyCode=0;w.charCode=0;w.ctrlKey=s;w.altKey=s;w.shiftKey=s;w.metaKey=s;w.ni=s;w.Pa=r; +w.ha=function(a,b){var c=this.type=a.type;Lb.call(this,c);this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;if(d){if(jb){var e;a:{try{Mb(d.nodeName);e=q;break a}catch(f){}e=s}e||(d=r)}}else"mouseover"==c?d=a.fromElement:"mouseout"==c&&(d=a.toElement);this.relatedTarget=d;this.offsetX=kb||a.offsetX!==n?a.offsetX:a.layerX;this.offsetY=kb||a.offsetY!==n?a.offsetY:a.layerY;this.clientX=a.clientX!==n?a.clientX:a.pageX;this.clientY=a.clientY!==n?a.clientY:a.pageY;this.screenX= +a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=a.metaKey;this.ni=$a?a.metaKey:a.ctrlKey;this.state=a.state;this.Pa=a;a.defaultPrevented&&this.preventDefault();delete this.cc};w.stopPropagation=function(){Nb.r.stopPropagation.call(this);this.Pa.stopPropagation?this.Pa.stopPropagation():this.Pa.cancelBubble=q}; +w.preventDefault=function(){Nb.r.preventDefault.call(this);var a=this.Pa;if(a.preventDefault)a.preventDefault();else if(a.returnValue=s,Bb)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};w.kh=t("Pa");var Ob={},Pb={},Qb={},Rb={};function P(a,b,c,d,e){if(y(b)){for(var f=0;fe.keyCode||e.returnValue!=n)return q;a:{var j=s;if(0==e.keyCode)try{e.keyCode=-1;break a}catch(k){j=q}if(j||e.returnValue==n)e.returnValue=q}}j=new Nb;j.ha(e,this);e=q;try{if(g){for(var l=[],p=j.currentTarget;p;p=p.parentNode)l.push(p);f=d[q];f.sa=f.Y;for(var u=l.length- +1;!j.cc&&0<=u&&f.sa;u--)j.currentTarget=l[u],e&=Yb(f,l[u],c,q,j);if(h){f=d[s];f.sa=f.Y;for(u=0;!j.cc&&uk?2:1E-52*this.Y&&sc(this),q):s};function sc(a){if(a.Y!=a.A.length){for(var b=0,c=0;ba||360a||360a||360a)&&m(Error("Invalid opacity."));for(var b=this.e,c=b.length,d=0,d=0;db.M?-1:1}F("X.object",U);F("X.object.prototype.modified",U.prototype.n);function Tc(){}function Uc(a){for(var b=a.i.count,c=[],d=0,d=0;dg;f--,g++){var h=b[g];b[g]=b[f];b[f]=h}b=a}return 1==c?b[0]:b} +function sd(a,b,c){L.Ga(a.c+".reslice");var d=b.R,e=c.max,f=c.data,g=d[2],h=d[1],d=d[0],j=b.l!=r,k=h*d,l=Array(g),p=Array(g),u=0,v=r;b.Q&&(v=b.Q.Ya);for(var x=0,z=0,C=0,E=0,A=4*k,x=0;xe&&m(Error("Could not find scalar for vertex.")),j=g[j],f[h++]=j,f[h++]=j,f[h++]=j;b.v.t= +g;b.v.zc=f;b.v.f=q;L.ta(this.c+".parse");d=new Rc;d.aa=b;d.u=a;this.dispatchEvent(d)};F("X.parserLBL",xd);F("X.parserLBL.prototype.parse",xd.prototype.parse);function yd(a,b){this.x=ja(a)?a:0;this.y=ja(b)?b:0}w=yd.prototype;w.h=function(){return new yd(this.x,this.y)};function zd(a,b){return new yd(a.x-b.x,a.y-b.y)}w.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};w.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};w.translate=function(a,b){a instanceof yd?(this.x+=a.x,this.y+=a.y):(this.x+=a,D(b)&&(this.y+=b));return this};w.scale=function(a,b){var c=D(b)?b:a;this.x*=a;this.y*=c;return this};function Ad(a,b,c,d){this.top=a;this.right=b;this.bottom=c;this.left=d}w=Ad.prototype;w.h=function(){return new Ad(this.top,this.right,this.bottom,this.left)};w.contains=function(a){return!this||!a?s:a instanceof Ad?a.left>=this.left&&a.right<=this.right&&a.top>=this.top&&a.bottom<=this.bottom:a.x>=this.left&&a.x<=this.right&&a.y>=this.top&&a.y<=this.bottom}; +w.floor=function(){this.top=Math.floor(this.top);this.right=Math.floor(this.right);this.bottom=Math.floor(this.bottom);this.left=Math.floor(this.left);return this};w.round=function(){this.top=Math.round(this.top);this.right=Math.round(this.right);this.bottom=Math.round(this.bottom);this.left=Math.round(this.left);return this};w.translate=function(a,b){a instanceof yd?(this.left+=a.x,this.right+=a.x,this.top+=a.y,this.bottom+=a.y):(this.left+=a,this.right+=a,D(b)&&(this.top+=b,this.bottom+=b));return this}; +w.scale=function(a,b){var c=D(b)?b:a;this.left*=a;this.right*=a;this.top*=c;this.bottom*=c;return this};function Bd(a,b){this.width=a;this.height=b}Bd.prototype.h=function(){return new Bd(this.width,this.height)};Bd.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};Bd.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};Bd.prototype.scale=function(a,b){var c=D(b)?b:a;this.width*=a;this.height*=c;return this};function Cd(a,b,c,d){this.left=a;this.top=b;this.width=c;this.height=d}w=Cd.prototype;w.h=function(){return new Cd(this.left,this.top,this.width,this.height)};w.Uf=function(a){var b=Math.max(this.left,a.left),c=Math.min(this.left+this.width,a.left+a.width);if(b<=c){var d=Math.max(this.top,a.top);a=Math.min(this.top+this.height,a.top+a.height);if(d<=a)return this.left=b,this.top=d,this.width=c-b,this.height=a-d,q}return s}; +w.contains=function(a){return a instanceof Cd?this.left<=a.left&&this.left+this.width>=a.left+a.width&&this.top<=a.top&&this.top+this.height>=a.top+a.height:a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this.top+this.height};function Dd(a,b){var c=b.x");c=c.join("")}var f=a.createElement(c);if(d)if(ma(d))f.className=d;else if(y(d))Fd.apply(r,[f].concat(d));else{var c=function(a,b){"style"==b?f.style.cssText=a:"class"==b?f.className=a:"for"==b?f.htmlFor=a:b in Ld?f.setAttribute(Ld[b],a):0==b.lastIndexOf("aria-",0)||0==b.lastIndexOf("data-",0)?f.setAttribute(b, +a):f[b]=a},g;for(g in d)c.call(n,d[g],g)}if(2a.clientWidth||a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return r} +function Yd(a){for(var b=new Ad(0,Infinity,Infinity,0),c=Hd(a),d=c.O.body,e=c.O.documentElement,f=!kb&&"CSS1Compat"==c.O.compatMode?c.O.documentElement:c.O.body;a=Xd(a);)if((!M||0!=a.clientWidth)&&(!kb||0!=a.clientHeight||a!=d)&&a!=d&&a!=e&&"visible"!=Ud(a,"overflow")){var g=Zd(a),h;h=a;if(jb&&!xb("1.9")){var j=parseFloat(Td(h,"borderLeftWidth"));if($d(h))var k=h.offsetWidth-h.clientWidth-j-parseFloat(Td(h,"borderRightWidth")),j=j+k;h=new yd(j,parseFloat(Td(h,"borderTopWidth")))}else h=new yd(h.clientLeft, +h.clientTop);g.x+=h.x;g.y+=h.y;b.top=Math.max(b.top,g.y);b.right=Math.min(b.right,g.x+a.clientWidth);b.bottom=Math.min(b.bottom,g.y+a.clientHeight);b.left=Math.max(b.left,g.x)}d=f.scrollLeft;f=f.scrollTop;b.left=Math.max(b.left,d);b.top=Math.max(b.top,f);c=(c.O.parentWindow||c.O.defaultView||window).document;c="CSS1Compat"==c.compatMode?c.documentElement:c.body;c=new Bd(c.clientWidth,c.clientHeight);b.right=Math.min(b.right,d+c.width);b.bottom=Math.min(b.bottom,f+c.height);return 0<=b.top&&0<=b.left&& +b.bottom>b.top&&b.right>b.left?b:r} +function Zd(a){var b,c=Jd(a),d=Ud(a,"position"),e=jb&&c.getBoxObjectFor&&!a.getBoundingClientRect&&"absolute"==d&&(b=c.getBoxObjectFor(a))&&(0>b.screenX||0>b.screenY),f=new yd(0,0),g=Vd(c);if(a==g)return f;if(a.getBoundingClientRect)b=Wd(a),a=Sd(Hd(c)),f.x=b.left+a.x,f.y=b.top+a.y;else if(c.getBoxObjectFor&&!e)b=c.getBoxObjectFor(a),a=c.getBoxObjectFor(g),f.x=b.screenX-a.screenX,f.y=b.screenY-a.screenY;else{b=a;do{f.x+=b.offsetLeft;f.y+=b.offsetTop;b!=a&&(f.x+=b.clientLeft||0,f.y+=b.clientTop||0); +if(kb&&"fixed"==Ud(b,"position")){f.x+=c.body.scrollLeft;f.y+=c.body.scrollTop;break}b=b.offsetParent}while(b&&b!=a);if(ib||kb&&"absolute"==d)f.y-=c.body.offsetTop;for(b=a;(b=Xd(b))&&b!=c.body&&b!=g;)if(f.x-=b.scrollLeft,!ib||"TR"!=b.tagName)f.y-=b.scrollTop}return f} +function ae(a){var b=new yd;if(1==a.nodeType){if(a.getBoundingClientRect){var c=Wd(a);b.x=c.left;b.y=c.top}else{var c=Sd(Hd(a)),d=Zd(a);b.x=d.x-c.x;b.y=d.y-c.y}if(jb&&!xb(12)){var e;M?e="-ms-transform":kb?e="-webkit-transform":ib?e="-o-transform":jb&&(e="-moz-transform");var f;e&&(f=Ud(a,e));f||(f=Ud(a,"transform"));f?(a=f.match(be),a=!a?new yd(0,0):new yd(parseFloat(a[1]),parseFloat(a[2]))):a=new yd(0,0);b=new yd(b.x+a.x,b.y+a.y)}}else e=na(a.kh),f=a,a.targetTouches?f=a.targetTouches[0]:e&&a.Pa.targetTouches&& +(f=a.Pa.targetTouches[0]),b.x=f.clientX,b.y=f.clientY;return b}function ce(a,b){"number"==typeof a&&(a=(b?Math.round(a):a)+"px");return a}function de(a){if("none"!=Ud(a,"display"))return ee(a);var b=a.style,c=b.display,d=b.visibility,e=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";a=ee(a);b.display=c;b.position=e;b.visibility=d;return a} +function ee(a){var b=a.offsetWidth,c=a.offsetHeight,d=kb&&!b&&!c;return(!ja(b)||d)&&a.getBoundingClientRect?(a=Wd(a),new Bd(a.right-a.left,a.bottom-a.top)):new Bd(b,c)}function fe(a,b){a.style.display=b?"":"none"}function $d(a){return"rtl"==Ud(a,"direction")}function ge(a,b){if(/^\d+px?$/.test(b))return parseInt(b,10);var c=a.style.left,d=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;a.style.left=b;var e=a.style.pixelLeft;a.style.left=c;a.runtimeStyle.left=d;return e} +function he(a,b){var c=a.currentStyle?a.currentStyle[b]:r;return c?ge(a,c):0}var ie={thin:2,medium:4,thick:6};function je(a,b){if("none"==(a.currentStyle?a.currentStyle[b+"Style"]:r))return 0;var c=a.currentStyle?a.currentStyle[b+"Width"]:r;return c in ie?ie[c]:ge(a,c)}var be=/matrix\([0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, ([0-9\.\-]+)p?x?, ([0-9\.\-]+)p?x?\)/;function ke(a,b){bc.call(this);this.s=a;var c=oa(this.s)&&1==this.s.nodeType?this.s:this.s?this.s.body:r;this.Dh=!!c&&$d(c);this.Xj=P(this.s,jb?"DOMMouseScroll":"mousewheel",this,b)}G(ke,bc); +ke.prototype.handleEvent=function(a){var b=0,c=0,d=0;a=a.Pa;if("mousewheel"==a.type){c=1;if(M||kb&&(bb||xb("532.0")))c=40;d=le(-a.wheelDelta,c);ja(a.wheelDeltaX)?(b=le(-a.wheelDeltaX,c),c=le(-a.wheelDeltaY,c)):c=d}else d=a.detail,100d&&(d=-3),ja(a.axis)&&a.axis===a.HORIZONTAL_AXIS?b=d:c=d;D(this.$f)&&(b=Math.min(Math.max(b,-this.$f),this.$f));D(this.ag)&&(c=Math.min(Math.max(c,-this.ag),this.ag));this.Dh&&(b=-b);b=new me(d,a,b,c);this.dispatchEvent(b)}; +function le(a,b){return kb&&($a||cb)&&0!=a%b?a:a/b}function me(a,b,c,d){b&&this.ha(b,n);this.type="mousewheel";this.detail=a;this.Tj=c;this.vc=d}G(me,Nb);M||kb&&xb("525");function ne(a){(a==r||!(a instanceof Element))&&m(Error("Could not add interactor to the given element."));Q.call(this);this.c="interactor";this.ua=a;this.fe=this.of=this.nf=this.pf=this.mf=this.qf=r;this.kd=q;this.Eb=this.wb=this.Xa=s;this.gb=[0,0];this.ae=new L.g(0,0,0);this.Dc=new L.g(0,0,0);this.Wf=0;this.yf=this.fd=r;this.xf=s;this.D={MOUSEWHEEL_ENABLED:q,MOUSECLICKS_ENABLED:q,KEYBOARD_ENABLED:q,HOVERING_ENABLED:q,CONTEXTMENU_ENABLED:s,TOUCH_ENABLED:q,TOUCH_BOUNCING_ENABLED:s}}G(ne,Q); +ne.prototype.__defineGetter__("config",t("D"));ne.prototype.__defineGetter__("leftButtonDown",t("Xa"));ne.prototype.__defineGetter__("middleButtonDown",t("wb"));ne.prototype.__defineGetter__("rightButtonDown",t("Eb")); +ne.prototype.ha=function(){this.D.MOUSEWHEEL_ENABLED?(this.fe=new ke(this.ua),this.qf=P(this.fe,"mousewheel",this.Xc.bind(this))):(Wb(this.qf),this.fe=r);this.D.MOUSECLICKS_ENABLED?(this.mf=P(this.ua,"mousedown",this.Qh.bind(this)),this.pf=P(this.ua,"mouseup",this.Vh.bind(this))):(Wb(this.mf),Wb(this.pf));this.ua.oncontextmenu=this.D.CONTEXTMENU_ENABLED?r:function(){return s};window.onkeydown=this.D.KEYBOARD_ENABLED?this.fg.bind(this):r;this.D.TOUCH_ENABLED?(this.D.TOUCH_BOUNCING_ENABLED||document.body.addEventListener("touchmove", +function(a){a.preventDefault()},s),this.Lg=P(this.ua,"touchstart",this.hi.bind(this)),this.Kg=P(this.ua,"touchmove",this.fi.bind(this)),this.Jg=P(this.ua,"touchend",this.bi.bind(this))):(Wb(this.Lg),Wb(this.Kg),Wb(this.Jg));Wb(this.nf);Wb(this.of);this.nf=P(this.ua,"mousemove",this.Sh.bind(this));this.of=P(this.ua,"mouseout",this.Th.bind(this))}; +ne.prototype.Qh=function(a){0==a.button?this.Xa=q:1==a.button?this.wb=q:2==a.button&&(this.Eb=q);eval("this.onMouseDown("+this.Xa+","+this.wb+","+this.Eb+")");oe(this);a.preventDefault()};ne.prototype.Ph=ba();ne.prototype.Vh=function(a){0==a.button?this.Xa=s:1==a.button?this.wb=s:2==a.button&&(this.Eb=s);eval("this.onMouseUp("+this.Xa+","+this.wb+","+this.Eb+")");oe(this);a.preventDefault()};ne.prototype.__defineGetter__("mousePosition",t("gb"));w=ne.prototype;w.Uh=ba(); +w.Th=function(a){this.kd=s;this.D.KEYBOARD_ENABLED&&(window.onkeydown=r);this.Eb=this.wb=this.Xa=s;oe(this);this.ae=new L.g(0,0,0);a.preventDefault()};w.Rh=ba();w.hi=function(a){a.preventDefault();a.ha(a.Pa.targetTouches[0],a.currentTarget);eval("this.onTouchStart("+a.clientX+","+a.clientY+")");this.Dc=new L.g(a.clientX,a.clientY,0);this.yf=setTimeout(this.di.bind(this,a),500)};w.gi=ba(); +w.di=function(a){eval("this.onTouchHover("+a.clientX+","+a.clientY+")");a=new jd;a.Ta=q;a.Ja=this instanceof pe;this.dispatchEvent(a);this.pd=q};w.ci=ba();function qe(a){clearTimeout(a.yf);if(a.pd){var b=new jd;b.Ta=s;b.Ja=a instanceof pe;a.dispatchEvent(b)}a.pd=s}w.bi=function(a){a.preventDefault();eval("this.onTouchEnd()");qe(this)};w.ai=ba(); +w.fi=function(a){a.preventDefault();this.pd||qe(this);this.touchmoveEvent=a=a.Pa;eval("this.onTouchMove(this['touchmoveEvent'])");var b=a.targetTouches;if(1==b.length){a=b[0];var c=[a.clientX,a.clientY];a=new L.g(c[0],c[1],0);var b=c[0]>3*this.ua.clientWidth/4,d=c[0]3*this.ua.clientHeight/4,c=!b&&!d&&!e&&!c,e=this.Dc.na(a);this.Dc=a.h();if(this.pd)a=new hd,5e.x&&(e.x=-1),5e.y&&(e.y=-1),a.M=e,this.dispatchEvent(a); +else if(this instanceof re&&(b||d))a=new kd,a.K=0>e.y,this.dispatchEvent(a);else if(this instanceof pe||c)e.scale(3),a=new id,a.M=e,this.dispatchEvent(a)}else 2==b.length&&(a=b[0],b=b[1],a=[a.clientX,a.clientY],b=[b.clientX,b.clientY],a=new L.g(a[0],a[1],0),b=new L.g(b[0],b[1],0),e=xc(a,b),b=e-this.Wf,this.Wf=e,this.Dc.na(a),this.Dc=a.h(),10Math.abs(a.x)&&(a.x=0);2>Math.abs(a.y)&&(a.y=0);0!=a.nb()&&(this.Xa&&!b?(b=new id,a.scale(3),b.M=a,this.dispatchEvent(b)):this.wb||this.Xa&&b?(b=new hd,5a.x&&(a.x=-5),5a.y&&(a.y=-5),b.M=a,this.dispatchEvent(b)):this.Eb&&(b=new jd,b.Ta=0=f&&(a.preventDefault(),e?a=new hd:b?a=new jd:(a=new id,this instanceof re&&(a=new kd)),a&&(c=new L.g(0,0,0),37==f?(c.x=5,a.K=s,b&&(a.K=q,a.Ta=q,a.Ja=s)):39==f?(c.x=-5,a.K=q,b&&(a.Ta=s,a.Ja=s)):38==f?(c.y=5,a.K=q,b&&(a.Ta=q,a.Ja=q)):40==f&&(c.y=-5,a.K=s,b&&(a.Ta= +s,a.Ja=q)),a.M=c,this.dispatchEvent(a)))}};F("X.interactor",ne);F("X.interactor.prototype.init",ne.prototype.ha);F("X.interactor.prototype.onMouseDown",ne.prototype.Ph);F("X.interactor.prototype.onMouseUp",ne.prototype.Uh);F("X.interactor.prototype.onMouseMove",ne.prototype.Rh);F("X.interactor.prototype.onMouseWheel",ne.prototype.Wh);F("X.interactor.prototype.onKey",ne.prototype.Nh);F("X.interactor.prototype.onTouchStart",ne.prototype.gi);F("X.interactor.prototype.onTouchMove",ne.prototype.ei); +F("X.interactor.prototype.onTouchEnd",ne.prototype.ai);F("X.interactor.prototype.onTouchHover",ne.prototype.ci);function re(a){ne.call(this,a);this.c="interactor2D"}G(re,ne);re.prototype.Xc=function(a){re.r.Xc.call(this,a);var b=new kd;a.vc==r&&(a.vc=0);b.K=0>a.vc;this.dispatchEvent(b)};function ue(a){U.call(this);this.c="slice";this.k=[0,0,0];this.kc=[0,0,1];this.K=[0,1,0];this.B=this.H=10;this.Fb=[0,1,0,0,1,1,1,1,1,0,0,0];this.l=this.jb=r;this.Sa=q;this.gc=[1,1,1];a!=r&&this.Zb(a)}G(ue,U);ue.prototype.Zb=function(a){this.k=a.k.slice();this.kc=a.kc.slice();this.K=a.K.slice();this.H=a.H;this.B=a.B;this.jb=a.jb;this.l=a.l;this.Sa=a.Sa;this.gc=a.gc;this.Gg=a.Gg;ue.r.Zb.call(this,a)}; +ue.prototype.uc=function(){var a=new S(this.kc[0],this.kc[1],this.kc[2]),b=new S(this.K[0],this.K[1],this.K[2]),c=zc(b,a),d=new S(this.k[0],this.k[1],this.k[2]),e=new S(1,1,1);1==a.x?(e=new S(this.k[0],this.B/2,this.H/2),this.Fb=[0,0,1,0,0,1,0,1,1,1,1,0]):1==a.y?(e=new S(this.H/2,this.k[1],this.B/2),this.Fb=[0,0,0,1,1,0,1,0,1,1,0,1]):1==a.b&&(e=new S(this.H/2,this.B/2,this.k[2]));var f=yc(c.h().I(),b.h().I()),f=new S(f.x*e.x,f.y*e.y,f.b*e.b);f.add(d);var g=yc(c.h().I(),b),g=new S(g.x*e.x,g.y*e.y, +g.b*e.b);g.add(d);var h=yc(c,b.h().I()),h=new S(h.x*e.x,h.y*e.y,h.b*e.b);h.add(d);var j=h,b=yc(c,b),b=new S(b.x*e.x,b.y*e.y,b.b*e.b);b.add(d);d=g;this.i=new T(18);this.j=new T(18);this.i.add(f.x,f.y,f.b);this.i.add(g.x,g.y,g.b);this.i.add(h.x,h.y,h.b);this.i.add(j.x,j.y,j.b);this.i.add(b.x,b.y,b.b);this.i.add(d.x,d.y,d.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.Sa&&(a=new U,a.i=new T(24),a.j= +new T(24),a.i.add(f.x,f.y,f.b),a.i.add(g.x,g.y,g.b),a.i.add(g.x,g.y,g.b),a.i.add(b.x,b.y,b.b),a.i.add(b.x,b.y,b.b),a.i.add(h.x,h.y,h.b),a.i.add(h.x,h.y,h.b),a.i.add(f.x,f.y,f.b),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.Nb=[this.gc[0],this.gc[1],this.gc[2]],a.la="LINES",a.mc=2,this.e.push(a))};F("X.slice",ue);function R(a){U.call(this);this.c="volume";this.k=[0,0,0];this.R=[10,10,10];this.J=[1,1,1];this.sb=[];this.Cc=this.Wa=this.Bc=this.Va=this.Ac=this.Ua=0;this.T=new U;this.U=new U;this.hb=new U;this.rd=this.Na=s;this.Hb=0;this.l=r;this.Sa=q;this.X=Infinity;this.W=-Infinity;this.ie=q;Ea(this,new pc);Ea(this,new Pc);a!=r&&this.Zb(a)}G(R,U); +R.prototype.Zb=function(a){window.console.log(a);this.k=a.k.slice();this.R=a.R.slice();this.J=a.J.slice();this.Ua=a.Ua;this.Ac=a.Ac;this.Va=a.Va;this.Bc=a.Bc;this.Wa=a.Wa;this.Cc=a.Cc;this.T=new U(a.T);this.U=new U(a.U);this.hb=new U(a.hb);this.Na=a.Na;this.rd=a.rd;this.Hb=a.Hb;this.l=a.l;this.Sa=a.Sa;R.r.Zb.call(this,a)}; +R.prototype.uc=function(){this.e.length=0;this.T.e.length=0;this.U.e.length=0;this.hb.e.length=0;this.e.push(this.T);this.e.push(this.U);this.e.push(this.hb);for(var a=0,a=0;3>a;a++){for(var b=(this.R[a]-1)/2,c=b,d=0,d=0;db;b++){var c=this.e[b],d=0,e=0;0==b?(d=this.Ua,e=this.Ac,this.Ac=this.Ua):1==b?(d=this.Va,e=this.Bc,this.Bc=this.Va):2==b&&(d=this.Wa,e=this.Cc, +this.Cc=this.Wa);c.e[parseInt(e,10)].visible=s;c=c.e[parseInt(d,10)];c.visible=q;c.ba=1}}a&&R.r.n.call(this)};R.prototype.__defineGetter__("dimensions",t("R"));R.prototype.__defineGetter__("volumeRendering",t("Na"));R.prototype.__defineSetter__("volumeRendering",function(a){this.Na=a;this.n(s)});R.prototype.__defineGetter__("visible",t("qa")); +R.prototype.__defineSetter__("visible",function(a){if(a)this.qa=a,this.n(s);else{for(var b=this.e,c=b.length,d=0,d=0;d>8,c+=String.fromCharCode(p),c+=String.fromCharCode(l),c=parseInt(c,10);k--}else if(4161==f){j++;for(var d=h[j++],e="",f=0;f>8,e+=String.fromCharCode(p),e+=String.fromCharCode(l);g.ma=[g.ma[0],g.ma[1],Math.min(Math.abs(g.Yf-e),g.ma[2])];g.Yf= +e;k--}g.za[2]++}else{var g={rows:0,cols:0,ma:r,qe:0,Qg:0,$a:1,Lh:1,Yf:r,Id:0,eb:0,Tc:r,Qe:0,We:[],data:r,min:Infinity,max:-Infinity};g.$a=b.o.length;g.$a==r&&(g.$a=1);for(var h=Y(this,"ushort",this.$.byteLength),j=66,d=r,f=r,d=r,k=7;0>8,e=e+String.fromCharCode(p),e=e+String.fromCharCode(l);e=e.split("\\");g.ma=[+e[0],+e[1],Infinity];k--}else if(32==d&&(f=h[j++],19==f)){j++;d=h[j++];for(f=0;f>8,c+=String.fromCharCode(p),c+=String.fromCharCode(l),c=parseInt(c,10);k--}b.fc=g;g.za=[g.cols,g.rows,1];g.eb=g.rows*g.cols;switch(g.qe){case 8:g.Tc=new Uint8Array(g.cols*g.rows*g.$a);g.data=new Uint8Array(g.cols*g.rows*g.$a);break;case 16:g.Tc=new Uint16Array(g.cols*g.rows*g.$a);g.data=new Uint16Array(g.cols* +g.rows*g.$a);break;case 32:g.Tc=new Uint32Array(g.cols*g.rows*g.$a),g.data=new Uint32Array(g.cols*g.rows*g.$a)}}this.F=this.$.byteLength-2*g.eb;h=r;switch(g.qe){case 8:h=Y(this,"uchar",g.eb);break;case 16:h=Y(this,"ushort",g.eb);break;case 32:h=Y(this,"uint",g.eb)}g.We[c]=g.Qe;g.Tc.set(h,g.Qe*g.eb);g.Qe++;++g.Id;return g};F("X.parserDCM",ye);F("X.parserDCM.prototype.parse",ye.prototype.parse);function ze(){pd.call(this);this.c="parserVTK"}G(ze,pd); +ze.prototype.parse=function(a,b,c){L.Ga(this.c+".parse");var d=b.i,e=b.j,f=new Uint8Array(c),g="";b.i=d=new T(c.byteLength);b.j=e=new T(c.byteLength);c=0;for(var h=f.length;c=l);p++){var u=parseInt(k[p],10),v=c.get(u);d.add(v[0],v[1],v[2]);var x=u,z=v;"LINES"==this.va?(x=parseInt(k[p+1],10),z=c.get(x),d.add(z[0],z[1],z[2])):"TRIANGLE_STRIPS"==this.va&&(0==p||p==l-1)&&d.add(v[0],v[1],v[2]);uc&&10!=g);Y(this,"uchar");e=Y(this,"uint");c=Y(this,"uint");var h=Y(this,"float",3*e);g=Y(this,"uint",3*c);var j=new Uint32Array(e),k=new Float32Array(9*c);b.i=d=new T(9*c);b.j=e=new T(9*c);var l;for(l=0;l>>8^e[(b^a[c])&255];for(f=d>>3;f--;c+=8)b=b>>>8^e[(b^a[c])&255],b=b>>>8^e[(b^a[c+1])&255],b=b>>>8^e[(b^a[c+2])&255],b=b>>>8^e[(b^a[c+3])&255],b=b>>>8^e[(b^a[c+4])&255],b=b>>>8^e[(b^a[c+5])&255],b=b>>>8^e[(b^a[c+6])&255],b=b>>>8^e[(b^a[c+7])&255];return(b^4294967295)>>>0}}; +Ce.yg=new Uint32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101, +3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271, +366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376, +3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954, +1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836, +1088359270,936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]);function De(a){var b=a.length,c=0,d=Number.POSITIVE_INFINITY,e,f,g,h,j,k,l,p,u;for(p=0;pc&&(c=a[p]),a[p]>=1;for(u=k;u>>=1;switch(a){case 0:var a=this.input,b=this.ia,c=this.Aa,d=this.P,e=n,f=n,g=n,h=c.length,e=n;this.Oa=this.Rc=0;e=a[b++];e===n&&m(Error("invalid uncompressed block header: LEN (first byte)"));f=e;e=a[b++];e===n&&m(Error("invalid uncompressed block header: LEN (second byte)"));f|=e<<8;e=a[b++];e===n&&m(Error("invalid uncompressed block header: NLEN (first byte)"));g=e;e=a[b++];e===n&&m(Error("invalid uncompressed block header: NLEN (second byte)"));g|= +e<<8;f===~g&&m(Error("invalid uncompressed block header: length verify"));b+f>a.length&&m(Error("input buffer is broken"));switch(this.te){case Ge:for(;d+f>c.length;)e=h-d,f-=e,c.set(a.subarray(b,b+e),d),d+=e,b+=e,this.P=d,c=this.ac(),d=this.P;break;case Fe:for(;d+f>c.length;)c=this.ac({Kf:2});break;default:m(Error("invalid inflate mode"))}c.set(a.subarray(b,b+f),d);d+=f;this.ia=b+=f;this.P=d;this.Aa=c;break;case 1:this.Ae(Ie,Je);break;case 2:Ke(this);break;default:m(Error("unknown BTYPE: "+a))}}return this.Ef()}; +var Le=new Uint16Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Me=new Uint16Array([3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258]),Ne=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0]),Oe=new Uint16Array([1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577]),Pe=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),Qe=new Uint8Array(288), +Re,Se;Re=0;for(Se=Qe.length;Re=Re?8:255>=Re?9:279>=Re?7:8;var Ie=De(Qe),Te=new Uint8Array(30),Ue,Ve;Ue=0;for(Ve=Te.length;Ue>>b;a.Oa=d-b;a.ia=f;return g} +function We(a,b){for(var c=a.Rc,d=a.Oa,e=a.input,f=a.ia,g=b[0],h=b[1],j;d>>16;a.Rc=c>>g;a.Oa=d-g;a.ia=f;return e&65535} +function Ke(a){function b(a,b,c){var d,e,f;for(f=0;ff)d>=e&&(this.P=d,c=this.ac(),d=this.P),c[d++]=f;else{f-=257;h=Me[f];0=e&&(this.P=d,c=this.ac(),d=this.P);for(;h--;)c[d]=c[d++-g]}for(;8<=this.Oa;)this.Oa-=8,this.ia--;this.P=d}; +w.Xg=function(a,b){var c=this.Aa,d=this.P;this.Hf=a;for(var e=c.length,f,g,h;256!==(f=We(this,a));)if(256>f)d>=e&&(c=this.ac(),e=c.length),c[d++]=f;else{f-=257;h=Me[f];0e&&(c=this.ac(),e=c.length);for(;h--;)c[d]=c[d++-g]}for(;8<=this.Oa;)this.Oa-=8,this.ia--;this.P=d}; +w.ac=function(){var a=new Uint8Array(this.P-32768),b=this.P-32768,c=this.Aa;a.set(c.subarray(32768,a.length));this.re.push(a);this.Ze+=a.length;c.set(c.subarray(b,b+32768));this.P=32768;return c};w.dh=function(a){var b=this.input.length/this.ia+1|0,c=this.input,d=this.Aa;a&&("number"===typeof a.Kf&&(b=a.Kf),"number"===typeof a.Mg&&(b+=a.Mg));2>b?(a=(c.length-this.ia)/this.Hf[2],a=258*(a/2)|0,a=aXe;++Xe)for(var Ye=Xe,Ze=7,Ye=Ye>>>1;Ye;Ye>>>=1)--Ze;var $e=[],af;for(af=0;288>af;af++)switch(q){case 143>=af:$e.push([af+48,8]);break;case 255>=af:$e.push([af-144+400,9]);break;case 279>=af:$e.push([af-256+0,7]);break;case 287>=af:$e.push([af-280+192,8]);break;default:m("invalid literal: "+af)} +function bf(){var a=cf;switch(q){case 3===a:return[257,a-3,0];case 4===a:return[258,a-4,0];case 5===a:return[259,a-5,0];case 6===a:return[260,a-6,0];case 7===a:return[261,a-7,0];case 8===a:return[262,a-8,0];case 9===a:return[263,a-9,0];case 10===a:return[264,a-10,0];case 12>=a:return[265,a-11,1];case 14>=a:return[266,a-13,1];case 16>=a:return[267,a-15,1];case 18>=a:return[268,a-17,1];case 22>=a:return[269,a-19,2];case 26>=a:return[270,a-23,2];case 30>=a:return[271,a-27,2];case 34>=a:return[272,a- +31,2];case 42>=a:return[273,a-35,3];case 50>=a:return[274,a-43,3];case 58>=a:return[275,a-51,3];case 66>=a:return[276,a-59,3];case 82>=a:return[277,a-67,4];case 98>=a:return[278,a-83,4];case 114>=a:return[279,a-99,4];case 130>=a:return[280,a-115,4];case 162>=a:return[281,a-131,5];case 194>=a:return[282,a-163,5];case 226>=a:return[283,a-195,5];case 257>=a:return[284,a-227,5];case 258===a:return[285,a-258,0];default:m("invalid length: "+a)}}var df=[],cf,ef; +for(cf=3;258>=cf;cf++)ef=bf(),df[cf]=ef[2]<<24|ef[1]<<16|ef[0];new Uint32Array(df);function ff(){};function gf(a){this.input=a;this.ia=0;this.member=[]} +gf.prototype.Uc=function(){for(var a=this.input.length;this.ia>>0;Ce.ue(e)!==c&&m(Error("invalid CRC-32 checksum: 0x"+Ce.ue(e).toString(16)+ +" / 0x"+c.toString(16)));b.Wj=c=(h[d++]|h[d++]<<8|h[d++]<<16|h[d++]<<24)>>>0;(e.length&4294967295)!==c&&m(Error("invalid input size: "+(e.length&4294967295)+" / "+c));this.member.push(b);this.ia=d}a=this.member;b=e=d=0;for(h=a.length;bx)x=H;if(!z||KC)C=O;if(!d||aae)e=ca;l.push(I);p.push(N)}g=(v+x)/2;z=(z+C)/2;h=(d+e)/2;C=new Float32Array(f);b.i=d=new T(f);b.j=e=new T(f);b.Z=f=new T(f);for(k=v=0;k=l;l++)d.push(!isNaN(this.Xe[l])?this.Ia[l].scale(this.Xe[l]):n)}f=c.subarray(f);if("gzip"==this.encoding||"gz"==this.encoding)f=(new gf(new Uint8Array(f))).Uc();f=f.buffer;c={data:r,min:Infinity,max:-Infinity};c.data=new this.Mb(f);l=qd(c.data);f=c.min=l[0];l=c.max=l[1];b.R=[this.Ue[0],this.Ue[1],this.Ue[2]];d=(new S(this.Ia[0][0],this.Ia[0][1],this.Ia[0][2])).nb(); +e=(new S(this.Ia[1][0],this.Ia[1][1],this.Ia[1][2])).nb();g=(new S(this.Ia[2][0],this.Ia[2][1],this.Ia[2][2])).nb();b.J=[d,e,g];b.Ka=b.X=f;b.Ha=b.W=l;-Infinity==b.S&&(b.S=f);Infinity==b.V&&(b.V=l);b.uc();L.ta(this.c+".parse");b.sb=sd(this,b,c);c=new Rc;c.aa=b;c.u=a;this.dispatchEvent(c)}; +nf.prototype.fh={type:function(a){switch(a){case "uchar":case "unsigned char":case "uint8":case "uint8_t":this.Mb=Uint8Array;break;case "signed char":case "int8":case "int8_t":this.Mb=Int8Array;break;case "short":case "short int":case "signed short":case "signed short int":case "int16":case "int16_t":this.Mb=Int16Array;break;case "ushort":case "unsigned short":case "unsigned short int":case "uint16":case "uint16_t":this.Mb=Uint16Array;break;case "int":case "signed int":case "int32":case "int32_t":this.Mb= +Int32Array;break;case "uint":case "unsigned int":case "uint32":case "uint32_t":this.Mb=Uint32Array;break;case "float":this.Mb=Float32Array;break;default:m(Error("Unsupported NRRD data type: "+a))}return this.type=a},endian:function(a){return this.Uj=a},encoding:function(a){return this.encoding=a},dimension:function(a){return this.za=parseInt(a,10)},sizes:function(a){var b,c,d,e;d=a.split(/\s+/);e=[];b=0;for(c=d.length;ba.vc;b.Ja=q;this.dispatchEvent(b)};function Bf(a){Q.call(this);this.c="array";this.t=[];this.ef=a}G(Bf,Q);function Cf(a,b,c){for(var d=0;4>d;d++)if(a[d+0]!==b[d+c])return s;return q}Bf.prototype.add=function(a){this.t.push(a);return q};Bf.prototype.remove=function(a){a=this.t.indexOf(a);-1d)){d=b+Math.floor(d/2);Df(a,b,d);for(Df(a,d,c);bf.ef(f.t[g+1],e);){var j=f,k=g+1,l=j.t[g];j.t[g]=j.t[k];j.t[k]=l;++g}f.t[g]=e}}}Bf.prototype.sort=function(){Df(this,0,this.t.length)};function Ef(a,b){uf.call(this,a,b);this.c="camera2D"}G(Ef,uf);Ef.prototype.rotate=function(a){a=Ef.r.rotate.call(this,a);var b=new gd;0a.x&&b.oe++;0a.y&&b.ee--;this.dispatchEvent(b)};function Ff(a,b){uf.call(this,a,b);this.c="camera3D";this.gf=45;this.tf=L.d.Fe(L.d.Vc(),this.gf,a/b,1,1E4)}G(Ff,uf);Ff.prototype.rotate=function(a){a=Ff.r.rotate.call(this,a);var b=-a.x/5*Math.PI/180;a=-a.y/5*Math.PI/180;var c=new L.g(this.p[1],this.p[5],this.p[9]),d=new L.g(this.p[0],this.p[4],this.p[8]);c.normalize();d.normalize();L.d.rotate(this.p,b,c.x,c.y,c.b);L.d.rotate(this.p,a,d.x,d.y,d.b)};Ff.prototype.Kd=function(a,b){var c=Ff.r.Kd.call(this,a,b);L.d.Zf(c,a,b,this.K);return c}; +F("X.camera3D",Ff);function Gf(a){Jb.call(this);this.mb=a;this.A=[]}G(Gf,Jb);var Hf=[];function If(a,b,c,d,e){y(c)||(Hf[0]=c,c=Hf);for(var f=0;fthis.Ge?this.Ge-this.If:apb&&P(this.m(),"resize",this.Vd,s,this);this.Vd();var a=this.m();a.setAttribute("role","progressbar");a.setAttribute("aria-live","polite")};w.yd=function(){Of.r.yd.call(this);M&&7>pb&&Vb(this.m(),"resize",this.Vd,s,this)};w.Ed=function(){return this.$c.Ed()};w.Sd=function(a){this.$c.Sd(a);this.m()&&Rf(this)};function Rf(a){var b=a.Ed();a.m().setAttribute("aria-valuenow",b)}w.Dd=function(){return this.$c.Dd()};w.Cd=function(){return this.$c.Cd()};w.jg="horizontal"; +w.oh=function(){this.Vd();this.dispatchEvent("change")};w.Vd=function(){if(this.bb){var a=this.Dd(),b=this.Cd(),a=(this.Ed()-a)/(b-a),b=Math.round(100*a);"vertical"==this.jg?M&&7>pb?(this.bb.style.top=0,this.bb.style.height="100%",b=this.bb.offsetHeight,a=Math.round(a*b),this.bb.style.top=b-a+"px",this.bb.style.height=a+"px"):(this.bb.style.top=100-b+"%",this.bb.style.height=b+"%"):this.bb.style.width=b+"%"}};function Sf(a,b){a==r&&m(Error("No valid parent element."));b==r&&m(Error("Invalid initial value."));Of.call(this);this.c="progressbar";this.oa=a;this.sf="";this.dd=this.ib=r;this.Ob=[];var c;c=".progress-bar-horizontal {\n position: relative;\n border: 1px solid #949dad;\n";c+=" background: white;\n";c+=" padding: 1px;\n";c+=" overflow: hidden;\n";c+=" margin: 2px;\n";c+=" width: 100px;\n";c+=" height: 5px;\n";c+="}";var d;d=".progress-bar-thumb {\n position: relative;\n background: #F62217;\n"; +d+=" overflow: hidden;\n";d+=" width: 0%;\n";d+=" height: 100%;\n";d+="}";var e;e=".progress-bar-thumb-done {\n background: #57E964;\n}";this.Ob=[c,d,e];this.Sd(b);this.Ce()}G(Sf,Of); +Sf.prototype.Ce=function(){if("static"==this.oa.style.position||""==this.oa.style.position)this.sf=this.oa.style.position,this.oa.style.position="relative";var a=document.getElementsByTagName("head")[0],b=Md("style");b.type="text/css";b.media="screen";var c=document.createTextNode(String(this.Ob[0])),d=document.createTextNode(String(this.Ob[1])),e=document.createTextNode(String(this.Ob[2]));a.appendChild(b);b.appendChild(c);b.appendChild(d);b.appendChild(e);this.ib=b;this.ec(this.oa);a=this.m();a.style.position= +"absolute";a.style.top=(this.oa.clientHeight-5)/2+"px";a.style.left=(this.oa.clientWidth-100)/2+"px";a.classList.add("xtk-progress-bar")};function Tf(a){var b=a.m().style.top,c=a.m().style.left;Od(a.m());var d=new Sf(a.oa,100),e=d.m();e.style.position="absolute";e.style.top=b;e.style.left=c;e.classList.add("xtk-progress-bar");(e.firstElementChild!=n?e.firstElementChild:Pd(e.firstChild)).classList.add("progress-bar-thumb-done");a.dd=d} +Sf.prototype.Gd=function(){this.ib&&Od(this.ib);this.m()&&Od(this.m());this.dd&&Od(this.dd.m());this.dd=this.ib=r;this.oa.style.position=this.sf};function Uf(a,b,c){na(a)?c&&(a=va(a,c)):a&&"function"==typeof a.handleEvent?a=va(a.handleEvent,a):m(Error("Invalid listener argument"));return 2147483647..) is required."));var b=a;ma(b)&&(b=Kd(a));oa(b)&&1==b.nodeType||m(Error("Could not find the given container."));this.u=b});w=Vf.prototype; +w.ad=function(){this.q.reset()}; +w.ha=function(a){var b=Md("canvas");this.u.appendChild(b);this.H=this.u.clientWidth;this.B=this.u.clientHeight;b.width=this.H;b.height=this.B;try{var c=b.getContext(a);c||m(Error())}catch(d){var e="Sorry, "+a+' context is not supported on this machine! See http://crash.goXTK.com for requirements..';this.u.innerHTML='

    Oooops..

    '+e+"

    "; +m(Error(e))}this.G=new qf;P(this.G,dd,this.Yh.bind(this));this.da=b;this.a=c;b=new pe(this.da);"2d"==a&&(b=new re(this.da));b.ha();P(b,ad,this.ad.bind(this));P(b,ed,this.Me.bind(this));P(b,$c,this.Oe.bind(this));this.ja=b;b=new Ff(this.H,this.B);"2d"==a&&(b=new Ef(this.H,this.B));b.observe(this.ja);this.q=b;P(window,"resize",this.Ne,s,this)};w.add=function(a){(a instanceof Af||a instanceof yf||a instanceof wf)&&a.n();this.Ma.push(a);this.cb(a)}; +w.remove=function(a){(!this.da||!this.a)&&m(Error("The renderer was not initialized properly."));a==r&&m(Error("Illegal object."));return s};w.cb=function(a){(!this.da||!this.a)&&m(Error("The renderer was not initialized properly."));a==r&&(window.console.log(a),m(Error("Illegal object.")));var b;b=pa(a);var c=Qb[b];if(c){var d=ja(cd),e=ja(n);d&&e?(c=Pb[cd],b=!!c&&!!c[n]&&b in c[n]):b=!d&&!e?q:Gb(c,function(a){return d&&a.type==cd||e&&a.capture==n})}else b=s;b||P(a,cd,this.Oh.bind(this))}; +w.get=function(a){a==r&&m(Error("Invalid object id."));for(var b=this.Za.t,c=b.length,d=0,d=0;d=e.right))f&=-2;if(132==(f&132)&&(h.y=e.bottom))f&=-5;h.xe.right&&f&16)&&(g.width=Math.max(g.width-(h.x+g.width-e.right),0),d|=4);h.x+g.width>e.right&&f&1&&(h.x=Math.max(e.right-g.width, +e.left),d|=1);f&2&&(d|=(h.xe.right?32:0));h.y=e.top&&(h.y+g.height>e.bottom&&f&32)&&(g.height=Math.max(g.height-(h.y+g.height-e.bottom),0),d|=8);h.y+g.height>e.bottom&&f&4&&(h.y=Math.max(e.bottom-g.height,e.top),d|=2);f&8&&(d|=(h.ye.bottom?128:0));h=d}else h=256;if(h&496)return h}f=a;e=jb&&($a||nb)&&xb("1.9");f instanceof +yd?(a=f.x,f=f.y):(a=f,f=n);b.style.left=ce(a,e);b.style.top=ce(f,e);if(!(c==g||(!c||!g?0:c.width==g.width&&c.height==g.height)))a=Rd(Hd(Jd(b))),M&&(!a||!xb("8"))?(c=b.style,a?(M?(a=he(b,"paddingLeft"),e=he(b,"paddingRight"),f=he(b,"paddingTop"),d=he(b,"paddingBottom"),a=new Ad(f,e,d,a)):(a=Td(b,"paddingLeft"),e=Td(b,"paddingRight"),f=Td(b,"paddingTop"),d=Td(b,"paddingBottom"),a=new Ad(parseFloat(f),parseFloat(e),parseFloat(d),parseFloat(a))),M?(e=je(b,"borderLeft"),f=je(b,"borderRight"),d=je(b,"borderTop"), +b=je(b,"borderBottom"),b=new Ad(d,f,b,e)):(e=Td(b,"borderLeftWidth"),f=Td(b,"borderRightWidth"),d=Td(b,"borderTopWidth"),b=Td(b,"borderBottomWidth"),b=new Ad(parseFloat(d),parseFloat(f),parseFloat(b),parseFloat(e))),c.pixelWidth=g.width-b.left-a.left-a.right-b.right,c.pixelHeight=g.height-b.top-a.top-a.bottom-b.bottom):(c.pixelWidth=g.width,c.pixelHeight=g.height)):(b=b.style,jb?b.MozBoxSizing="border-box":kb?b.WebkitBoxSizing="border-box":b.boxSizing="border-box",b.width=Math.max(g.width,0)+"px", +b.height=Math.max(g.height,0)+"px");return h};function bg(){}bg.prototype.Ra=ba();function cg(a,b,c){this.element=a;this.Gf=b;this.li=c}G(cg,bg);cg.prototype.Ra=function(a,b,c){$f(this.element,this.Gf,a,b,n,c,this.li)};function dg(a,b){bc.call(this);this.mb=new Gf(this);this.Se(a||r);b&&(this.yc=b)}G(dg,bc);w=dg.prototype;w.s=r;w.Ng=q;w.Af=r;w.ra=s;w.Ei=s;w.Ee=-1;w.Xf=-1;w.th=s;w.bh=q;w.yc="toggle_display";w.m=t("s");w.Se=function(a){this.ra&&m(Error("Can not change this state of the popup while showing."));this.s=a}; +function eg(a,b){a.Ud&&a.Ud.stop();a.Fd&&a.Fd.stop();if(b){if(!a.ra&&a.Ke()){a.s||m(Error("Caller must call setElement before trying to show the popup"));a.Ra();var c=Jd(a.s);a.th&&If(a.mb,c,"keydown",a.Mh,q);if(a.Ng)if(If(a.mb,c,"mousedown",a.eg,q),M){var d;try{d=c.activeElement}catch(e){}for(;d&&"IFRAME"==d.nodeName;){try{var f=d.contentDocument||d.contentWindow.document}catch(g){break}c=f;d=c.activeElement}If(a.mb,c,"mousedown",a.eg,q);If(a.mb,c,"deactivate",a.dg)}else If(a.mb,c,"blur",a.dg);"toggle_display"== +a.yc?(a.s.style.visibility="visible",fe(a.s,q)):"move_offscreen"==a.yc&&a.Ra();a.ra=q;a.Ud?(Ub(a.Ud,"end",a.hg,s,a),a.Ud.play()):a.hg()}}else fg(a)}w.Ra=ga;function fg(a,b){if(!a.ra||!a.dispatchEvent({type:"beforehide",target:b}))return s;a.mb&&a.mb.Re();a.ra=s;a.Xf=xa();a.Fd?(Ub(a.Fd,"end",wa(a.Ff,b),s,a),a.Fd.play()):a.Ff(b);return q}w.Ff=function(a){"toggle_display"==this.yc?this.Ei?Uf(this.Pf,0,this):this.Pf():"move_offscreen"==this.yc&&(this.s.style.top="-10000px");this.Le(a)}; +w.Pf=function(){this.s.style.visibility="hidden";fe(this.s,s)};w.Ke=function(){return this.dispatchEvent("beforeshow")};w.hg=function(){this.Ee=xa();this.Xf=-1;this.dispatchEvent("show")};w.Le=function(a){this.dispatchEvent({type:"hide",target:a})};w.eg=function(a){a=a.target;!Qd(this.s,a)&&((!this.Af||Qd(this.Af,a))&&!(150>xa()-this.Ee))&&fg(this,a)};w.Mh=function(a){27==a.keyCode&&fg(this,a.target)&&(a.preventDefault(),a.stopPropagation())}; +w.dg=function(a){if(this.bh){var b=Jd(this.s);if(M||ib){if(a=b.activeElement,!a||Qd(this.s,a)||"BODY"==a.tagName)return}else if(a.target!=b)return;150>xa()-this.Ee||fg(this)}};function gg(a,b){this.xe=a instanceof yd?a:new yd(a,b)}G(gg,bg);gg.prototype.Ra=function(a,b,c,d){$f(Vd(a),0,a,b,this.xe,c,r,d)};function hg(a,b){this.oi=4;this.Ld=b||n;dg.call(this,a)}G(hg,dg);hg.prototype.Ra=function(){if(this.Ld){var a=!this.ra&&"move_offscreen"!=this.yc,b=this.m();a&&(b.style.visibility="hidden",fe(b,q));this.Ld.Ra(b,this.oi,this.Yj);a&&fe(b,s)}};function ig(a){this.L=new rc;a&&this.pe(a)}function jg(a){var b=typeof a;return"object"==b&&a||"function"==b?"o"+pa(a):b.substr(0,1)+a}w=ig.prototype;w.Ad=function(){return this.L.Ad()};w.add=function(a){this.L.set(jg(a),a)};w.pe=function(a){a=qc(a);for(var b=a.length,c=0;cthis.Fc)this.Fc=k.x;if(this.Jc===r||g.ythis.Gc)this.Gc=k.y;if(this.Kc===r||g.bthis.Hc)this.Hc=k.b;this.k=[(this.Ic+this.Fc)/2,(this.Jc+this.Gc)/2,(this.Kc+this.Hc)/2];j.f=s}b&&d.f&&(j=this.Gb.get(c),j!=r&&this.a.isBuffer(j.w)&&this.a.deleteBuffer(j.w)); +j=r;!b||d.f?(j=this.a.createBuffer(),d.ob(),this.a.bindBuffer(this.a.ARRAY_BUFFER,j),this.a.bufferData(this.a.ARRAY_BUFFER,d.N,this.a.STATIC_DRAW),j=new Zf(j,d.count,3),d.f=s):j=this.Gb.get(c);rf(this.G,0.3);b&&e.f&&(g=this.Gb.get(c),g!=r&&this.a.isBuffer(g.w)&&this.a.deleteBuffer(g.w));g=r;!b||e.f?(g=this.a.createBuffer(),e.ob(),this.a.bindBuffer(this.a.ARRAY_BUFFER,g),this.a.bufferData(this.a.ARRAY_BUFFER,e.N,this.a.STATIC_DRAW),g=new Zf(g,e.count,3),e.f=s):g=this.ld.get(c);rf(this.G,0.3);b&&(f&& +f.f)&&(e=this.ic.get(c),e!=r&&this.a.isBuffer(e.w)&&this.a.deleteBuffer(e.w));e=r;f&&(!b||f.f?(f.length!=d.length&&m(Error("Mismatch between points and point colors.")),e=this.a.createBuffer(),f.ob(),this.a.bindBuffer(this.a.ARRAY_BUFFER,e),this.a.bufferData(this.a.ARRAY_BUFFER,f.N,this.a.STATIC_DRAW),e=new Zf(e,f.count,3),f.f=s):e=this.ic.get(c));rf(this.G,0.2);b&&(p&&p.f)&&(f=this.oc.get(c),f!=r&&this.a.isBuffer(f.w)&&this.a.deleteBuffer(f.w));f=r;p&&(f=p.zc,!b||p.f?(f.length!=d.length&&m(Error("Mismatch between points and scalars.")), +d=this.a.createBuffer(),this.a.bindBuffer(this.a.ARRAY_BUFFER,d),this.a.bufferData(this.a.ARRAY_BUFFER,f,this.a.STATIC_DRAW),f=new Zf(d,f.length,3),p.f=s):f=this.oc.get(c));rf(this.G,0.1);b||this.Za.add(a);this.Gb.set(c,j);this.ld.set(c,g);this.ic.set(c,e);this.rc.set(c,h);this.oc.set(c,f);this.jd=a.f=s}}else a.f=s}};function zg(a,b){var c=b.i.cd,c=L.d.Qa(b.Yb.ka,c[0],c[1],c[2]),c=L.d.Qa(a.q.p,c.x,c.y,c.b),c=L.g.kb(a.q.wa,c);return Math.round(1E3*c)/1E3} +w.mg=function(a,b){if(this.D.PICKING_ENABLED){this.Lb(q,s);var c=new Uint8Array(4);this.a.readPixels(a,this.B-b,1,1,this.a.RGBA,this.a.UNSIGNED_BYTE,c);return c[0]+255*c[1]+65025*c[2]}return-1}; +w.Lb=function(a,b){yg.r.Lb.call(this,a,b);this.a.viewport(0,0,this.H,this.B);this.a.clear(this.a.COLOR_BUFFER_BIT|this.a.DEPTH_BUFFER_BIT);var c=this.Za.t,d=c.length;if(0!=d){a?this.a.bindFramebuffer(this.a.FRAMEBUFFER,this.uf):this.a.bindFramebuffer(this.a.FRAMEBUFFER,r);var e=this.q.tf,f=this.q.p;this.a.uniformMatrix4fv(this.Oc.get("perspective"),s,e);this.a.uniformMatrix4fv(this.Oc.get("view"),s,f);e=this.k;this.a.uniform3f(this.Oc.get("center"),parseFloat(e[0]),parseFloat(e[1]),parseFloat(e[2])); +f=this.Ma.length;for(e=0;el||l>=v||0>p||p>=c)return r;u[this.yb]=l;u[this.zb]=p;return u}; +w.Lb=function(a,b){Ag.r.Lb.call(this,a,b);if(0!=this.Za.t.length){var c=this.H,d=this.B,e=this.q.p;this.a.save();this.a.clearRect(-c,-d,2*c,2*d);this.a.restore();var f=1*e[12],g=-1*e[13],h=Math.max(e[14],0.6);this.a.setTransform(h,0,0,h,0,0);var j=this.Ma[0],k=r;j.l&&(k=j.l.le);var l=j["index"+this.La],p=this.Xb[parseInt(l,10)],u=p.z.xa,p=p.l,v=r;p&&(v=p.xa);var x=this.od,z=this.nd,C=this.hf,E=this.kf,A=C.getImageData(0,0,x,z),B=E.getImageData(0,0,x,z),H=A.data,I=B.data,N=H.length,J=j.Ha,K=j.S,O= +j.V,aa=j.X/J,ca=j.W/J;if(this.ff!=l||this.S!=K||this.V!=O||this.X!=aa||this.W!=ca||k&&!Cf(k,this.lf,0)){var W=0;do{var da=[0,0,0,0],V=[0,0,0,0],ab=u[W]/255*J,ka=u[W],ka=(ka/255-aa)/(ca-aa),ka=255*ka;ab>=K&&ab<=O&&(da=new S(j.xb[0],j.xb[1],j.xb[2]),da=(new S(j.vb[0],j.vb[1],j.vb[2])).scale(ka).add(da.scale(255-ka)),da=[Math.floor(da.x),Math.floor(da.y),Math.floor(da.b),255],p&&(-255==k[3]?V=[v[W],v[W+1],v[W+2],v[W+3]]:Cf(k,v,W)&&(V=[v[W],v[W+1],v[W+2],v[W+3]])));ka=N-1-W;H[ka-3]=da[0];H[ka-2]=da[1]; +H[ka-1]=da[2];H[ka]=da[3];I[ka-3]=V[0];I[ka-2]=V[1];I[ka-1]=V[2];I[ka]=V[3];W+=4}while(W + * + * The X Toolkit (XTK) is licensed under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + * "Free software" is a matter of liberty, not price. + * "Free" as in "free speech", not as in "free beer". + * - Richard M. Stallman + * + * FUELED BY: + * - the wonderful Constructive Solid Geometry library by Evan Wallace (http://madebyevan.com) + * LICENSE: https://raw.github.com/xtk/X/master/lib/csg/LICENSE + * + * - parts of the Google Closure Library (http://code.google.com/closure/library) + * LICENSE: https://raw.github.com/xtk/google-closure-library/master/LICENSE + * + * - zlib.js, the ultimate gzip/zlib javascript implementation (https://github.com/imaya/zlib.js) + * LICENSE: https://raw.github.com/imaya/zlib.js/master/LICENSE + * + * MORE CREDITS: https://raw.github.com/xtk/X/master/LICENSE + * + */ +function l(a){throw a;}var n=void 0,q=!0,r=null,s=!1;function aa(){return function(){}}function ba(a){return function(b){this[a]=b}}function t(a){return function(){return this[a]}}var w,da=this;function ea(){} +function fa(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null"; +else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function ga(a){return a!==n}function ka(a){return"array"==fa(a)}function la(a){var b=fa(a);return"array"==b||"object"==b&&"number"==typeof a.length}function ma(a){return"string"==typeof a}function y(a){return"number"==typeof a}function na(a){return"function"==fa(a)}function oa(a){var b=typeof a;return"object"==b&&a!=r||"function"==b}function pa(a){return a[qa]||(a[qa]=++ra)}var qa="closure_uid_"+(1E9*Math.random()>>>0),ra=0; +function sa(a,b,c){return a.call.apply(a.bind,arguments)}function ta(a,b,c){a||l(Error());if(2a&&(a=this.byteLength+a);0>c&&(c=this.byteLength+c);ca&&(a=0);0>c&&(c=0);a>this.byteLength&&(a=this.byteLength);c>this.byteLength&&(c=this.byteLength);for(var d=new ArrayBuffer(c-a),e=new Uint8Array(this),f=new Uint8Array(d),g=a,h=0;g")&&(a=a.replace(Ua,">"));-1!=a.indexOf('"')&&(a=a.replace(Va,"""));return a}var Sa=/&/g,Ta=//g,Va=/\"/g,Ra=/[&<>\"]/;var Wa,Xa,Ya,$a,ab,bb,cb;function db(){return da.navigator?da.navigator.userAgent:r}function eb(){return da.navigator}$a=Ya=Xa=Wa=s;var fb;if(fb=db()){var jb=eb();Wa=0==fb.indexOf("Opera");Xa=!Wa&&-1!=fb.indexOf("MSIE");Ya=!Wa&&-1!=fb.indexOf("WebKit");$a=!Wa&&!Ya&&"Gecko"==jb.product}var kb=Wa,L=Xa,lb=$a,mb=Ya,nb,ob=eb();nb=ob&&ob.platform||"";ab=-1!=nb.indexOf("Mac");bb=-1!=nb.indexOf("Win");cb=-1!=nb.indexOf("Linux");var pb=!!eb()&&-1!=(eb().appVersion||"").indexOf("X11"); +function qb(){var a=da.document;return a?a.documentMode:n}var rb;a:{var sb="",tb;if(kb&&da.opera)var ub=da.opera.version,sb="function"==typeof ub?ub():ub;else if(lb?tb=/rv\:([^\);]+)(\)|;)/:L?tb=/MSIE\s+([^\);]+)(\)|;)/:mb&&(tb=/WebKit\/(\S+)/),tb)var vb=tb.exec(db()),sb=vb?vb[1]:"";if(L){var wb=qb();if(wb>parseFloat(sb)){rb=String(wb);break a}}rb=sb}var xb={}; +function yb(a){var b;if(!(b=xb[a])){b=0;for(var c=String(rb).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),d=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),e=Math.max(c.length,d.length),f=0;0==b&&f(0==p[1].length?0:parseInt(p[1],10))?1:0)||((0==m[2].length)<(0==p[2].length)?-1:(0==m[2].length)>(0==p[2].length)?1:0)||(m[2]p[2]?1:0)}while(0==b)}b=xb[a]=0<=b}return b}var zb=da.document,Bb=!zb||!L?n:qb()||("CSS1Compat"==zb.compatMode?parseInt(rb,10):5);var Cb=!L||L&&9<=Bb,Db=L&&!yb("9");!mb||yb("528");lb&&yb("1.9b")||L&&yb("8")||kb&&yb("9.5")||mb&&yb("528");lb&&!yb("8")||L&&yb("9");var Eb=Array.prototype,Fb=Eb.indexOf?function(a,b,c){return Eb.indexOf.call(a,b,c)}:function(a,b,c){c=c==r?0:0>c?Math.max(0,a.length+c):c;if(ma(a))return!ma(b)||1!=b.length?-1:a.indexOf(b,c);for(;c=arguments.length?Eb.slice.call(a,b):Eb.slice.call(a,b,c)};function Lb(){0!=Mb&&(this.dk=Error().stack,pa(this))}var Mb=0;function Nb(a,b){this.type=a;this.currentTarget=this.target=b}w=Nb.prototype;w.cc=s;w.defaultPrevented=s;w.Zd=q;w.stopPropagation=function(){this.cc=q};w.preventDefault=function(){this.defaultPrevented=q;this.Zd=s};function Ob(a){Ob[" "](a);return a}Ob[" "]=ea;function Pb(a,b){a&&this.ka(a,b)}D(Pb,Nb);w=Pb.prototype;w.target=r;w.relatedTarget=r;w.offsetX=0;w.offsetY=0;w.clientX=0;w.clientY=0;w.screenX=0;w.screenY=0;w.button=0;w.keyCode=0;w.charCode=0;w.ctrlKey=s;w.altKey=s;w.shiftKey=s;w.metaKey=s;w.Oi=s;w.Sa=r; +w.ka=function(a,b){var c=this.type=a.type;Nb.call(this,c);this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;if(d){if(lb){var e;a:{try{Ob(d.nodeName);e=q;break a}catch(f){}e=s}e||(d=r)}}else"mouseover"==c?d=a.fromElement:"mouseout"==c&&(d=a.toElement);this.relatedTarget=d;this.offsetX=mb||a.offsetX!==n?a.offsetX:a.layerX;this.offsetY=mb||a.offsetY!==n?a.offsetY:a.layerY;this.clientX=a.clientX!==n?a.clientX:a.pageX;this.clientY=a.clientY!==n?a.clientY:a.pageY;this.screenX= +a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=a.metaKey;this.Oi=ab?a.metaKey:a.ctrlKey;this.state=a.state;this.Sa=a;a.defaultPrevented&&this.preventDefault();delete this.cc};w.stopPropagation=function(){Pb.q.stopPropagation.call(this);this.Sa.stopPropagation?this.Sa.stopPropagation():this.Sa.cancelBubble=q}; +w.preventDefault=function(){Pb.q.preventDefault.call(this);var a=this.Sa;if(a.preventDefault)a.preventDefault();else if(a.returnValue=s,Db)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};w.Lh=t("Sa");var Qb={},Sb={},Tb={},Ub={};function Vb(a,b,c,d,e){if(ka(b)){for(var f=0;fe.keyCode||e.returnValue!=n)return q;a:{var j=s;if(0==e.keyCode)try{e.keyCode=-1;break a}catch(k){j=q}if(j||e.returnValue==n)e.returnValue=q}}j=new Pb;j.ka(e,this);e=q;try{if(g){for(var m=[],p=j.currentTarget;p;p=p.parentNode)m.push(p);f=d[q];f.ua=f.Y;for(var u=m.length- +1;!j.cc&&0<=u&&f.ua;u--)j.currentTarget=m[u],e&=bc(f,m[u],c,q,j);if(h){f=d[s];f.ua=f.Y;for(u=0;!j.cc&&uk?2:1E-52*this.Y&&xc(this),q):s};function xc(a){if(a.Y!=a.C.length){for(var b=0,c=0;ba||360a||360a||360a)&&l(Error("Invalid opacity."));for(var b=this.h,c=b.length,d=0,d=0;db.O?-1:1}C("X.object",Y);C("X.object.prototype.modified",Y.prototype.l);function Zc(){}function $c(a){for(var b=a.j.count,c=[],d=0,d=0;d +g;f--,g++){var h=b[g];b[g]=b[f];b[f]=h}b=a}return 1==c?b[0]:b}function yd(a,b){"right"!=a[0]&&(b[0]=-b[0],b[3]=-b[3],b[6]=-b[6]);"anterior"!=a[1]&&(b[1]=-b[1],b[4]=-b[4],b[7]=-b[7]);"superior"!=a[2]&&(b[2]=-b[2],b[5]=-b[5],b[8]=-b[8]);return b} +function zd(a,b){I.va(a.c+".orientnormalize");var c=b.slice(0,3),d=c.map(function(a){return Math.abs(a)}),e=d.indexOf(Math.max.apply(Math,d)),d=[0,0,0];d[e]=0>c[e]?-1:1;var f=b.slice(3,6),c=f.map(function(a){return Math.abs(a)}),g=c.indexOf(Math.max.apply(Math,c)),c=[0,0,0];c[g]=0>f[g]?-1:1;var f=b.slice(6,9),h=f.map(function(a){return Math.abs(a)}),j=h.indexOf(Math.max.apply(Math,h)),h=[0,0,0];h[j]=0>f[j]?-1:1;e=[d[e],c[g],h[j]];d=[d,c,h];I.qa(a.c+".orientnormalize");return[e,d]} +function Ad(a,b){I.va(a.c+".reslice");var c=b.P!=r,d=r;b.gb&&(d=b.gb.zb);for(var e=b.Ia,f=b.Gb,g=b.z,h=Array(e[2]),j=Array(e[2]),k=b.G,m=e[0]*e[1],p=0,u=0,x=0,v=0,z=0,v=0;vg;g++){var H=g,v=(H+1)%3,h=(H+2)%3,m=4*e[H]*e[v],p=e[H],z=e[v],F=e[h],B=(F- +1)/2,G=k[H],J=k[v],U=k[h],N=[1,1,1],N=0!=k[h][2]?[1,0,0]:0!=k[h][1]?[0,1,0]:[1,1,0],H=p*f[H],K=z*f[v];0!=k[2][1]&&(v=H,H=K,K=v);for(v=0;ve&&l(Error("Could not find scalar for vertex.")),j=g[j],f[h++]=j,f[h++]=j,f[h++]=j;b.w.u= +g;b.w.Fc=f;b.w.e=q;I.qa(this.c+".parse");d=new Xc;d.aa=b;d.v=a;this.dispatchEvent(d)};C("X.parserLBL",Cd);C("X.parserLBL.prototype.parse",Cd.prototype.parse);function Dd(a,b){this.x=ga(a)?a:0;this.y=ga(b)?b:0}w=Dd.prototype;w.g=function(){return new Dd(this.x,this.y)};function Ed(a,b){return new Dd(a.x-b.x,a.y-b.y)}w.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};w.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};w.translate=function(a,b){a instanceof Dd?(this.x+=a.x,this.y+=a.y):(this.x+=a,y(b)&&(this.y+=b));return this};w.scale=function(a,b){var c=y(b)?b:a;this.x*=a;this.y*=c;return this};function Fd(a,b,c,d){this.top=a;this.right=b;this.bottom=c;this.left=d}w=Fd.prototype;w.g=function(){return new Fd(this.top,this.right,this.bottom,this.left)};w.contains=function(a){return!this||!a?s:a instanceof Fd?a.left>=this.left&&a.right<=this.right&&a.top>=this.top&&a.bottom<=this.bottom:a.x>=this.left&&a.x<=this.right&&a.y>=this.top&&a.y<=this.bottom}; +w.floor=function(){this.top=Math.floor(this.top);this.right=Math.floor(this.right);this.bottom=Math.floor(this.bottom);this.left=Math.floor(this.left);return this};w.round=function(){this.top=Math.round(this.top);this.right=Math.round(this.right);this.bottom=Math.round(this.bottom);this.left=Math.round(this.left);return this};w.translate=function(a,b){a instanceof Dd?(this.left+=a.x,this.right+=a.x,this.top+=a.y,this.bottom+=a.y):(this.left+=a,this.right+=a,y(b)&&(this.top+=b,this.bottom+=b));return this}; +w.scale=function(a,b){var c=y(b)?b:a;this.left*=a;this.right*=a;this.top*=c;this.bottom*=c;return this};function Gd(a,b){this.width=a;this.height=b}Gd.prototype.g=function(){return new Gd(this.width,this.height)};Gd.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};Gd.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};Gd.prototype.scale=function(a,b){var c=y(b)?b:a;this.width*=a;this.height*=c;return this};function Hd(a,b,c,d){this.left=a;this.top=b;this.width=c;this.height=d}w=Hd.prototype;w.g=function(){return new Hd(this.left,this.top,this.width,this.height)};w.mg=function(a){var b=Math.max(this.left,a.left),c=Math.min(this.left+this.width,a.left+a.width);if(b<=c){var d=Math.max(this.top,a.top);a=Math.min(this.top+this.height,a.top+a.height);if(d<=a)return this.left=b,this.top=d,this.width=c-b,this.height=a-d,q}return s}; +w.contains=function(a){return a instanceof Hd?this.left<=a.left&&this.left+this.width>=a.left+a.width&&this.top<=a.top&&this.top+this.height>=a.top+a.height:a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this.top+this.height};function Id(a,b){var c=b.x");c=c.join("")}var f=a.createElement(c);if(d)if(ma(d))f.className=d;else if(ka(d))Kd.apply(r,[f].concat(d));else{var c=function(a,b){"style"==b?f.style.cssText=a:"class"==b?f.className=a:"for"==b?f.htmlFor=a:b in Rd?f.setAttribute(Rd[b],a):0==b.lastIndexOf("aria-",0)||0==b.lastIndexOf("data-",0)? +f.setAttribute(b,a):f[b]=a},g;for(g in d)c.call(n,d[g],g)}if(2a.clientWidth||a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return r} +function de(a){for(var b=new Fd(0,Infinity,Infinity,0),c=Md(a),d=c.R.body,e=c.R.documentElement,f=!mb&&"CSS1Compat"==c.R.compatMode?c.R.documentElement:c.R.body;a=ce(a);)if((!L||0!=a.clientWidth)&&(!mb||0!=a.clientHeight||a!=d)&&a!=d&&a!=e&&"visible"!=$d(a,"overflow")){var g=ee(a),h;h=a;if(lb&&!yb("1.9")){var j=parseFloat(Zd(h,"borderLeftWidth"));if(fe(h))var k=h.offsetWidth-h.clientWidth-j-parseFloat(Zd(h,"borderRightWidth")),j=j+k;h=new Dd(j,parseFloat(Zd(h,"borderTopWidth")))}else h=new Dd(h.clientLeft, +h.clientTop);g.x+=h.x;g.y+=h.y;b.top=Math.max(b.top,g.y);b.right=Math.min(b.right,g.x+a.clientWidth);b.bottom=Math.min(b.bottom,g.y+a.clientHeight);b.left=Math.max(b.left,g.x)}d=f.scrollLeft;f=f.scrollTop;b.left=Math.max(b.left,d);b.top=Math.max(b.top,f);c=(c.R.parentWindow||c.R.defaultView||window).document;c="CSS1Compat"==c.compatMode?c.documentElement:c.body;c=new Gd(c.clientWidth,c.clientHeight);b.right=Math.min(b.right,d+c.width);b.bottom=Math.min(b.bottom,f+c.height);return 0<=b.top&&0<=b.left&& +b.bottom>b.top&&b.right>b.left?b:r} +function ee(a){var b,c=Pd(a),d=$d(a,"position"),e=lb&&c.getBoxObjectFor&&!a.getBoundingClientRect&&"absolute"==d&&(b=c.getBoxObjectFor(a))&&(0>b.screenX||0>b.screenY),f=new Dd(0,0),g=ae(c);if(a==g)return f;if(a.getBoundingClientRect)b=be(a),a=Yd(Md(c)),f.x=b.left+a.x,f.y=b.top+a.y;else if(c.getBoxObjectFor&&!e)b=c.getBoxObjectFor(a),a=c.getBoxObjectFor(g),f.x=b.screenX-a.screenX,f.y=b.screenY-a.screenY;else{b=a;do{f.x+=b.offsetLeft;f.y+=b.offsetTop;b!=a&&(f.x+=b.clientLeft||0,f.y+=b.clientTop||0); +if(mb&&"fixed"==$d(b,"position")){f.x+=c.body.scrollLeft;f.y+=c.body.scrollTop;break}b=b.offsetParent}while(b&&b!=a);if(kb||mb&&"absolute"==d)f.y-=c.body.offsetTop;for(b=a;(b=ce(b))&&b!=c.body&&b!=g;)if(f.x-=b.scrollLeft,!kb||"TR"!=b.tagName)f.y-=b.scrollTop}return f} +function ge(a){var b=new Dd;if(1==a.nodeType){if(a.getBoundingClientRect){var c=be(a);b.x=c.left;b.y=c.top}else{var c=Yd(Md(a)),d=ee(a);b.x=d.x-c.x;b.y=d.y-c.y}if(lb&&!yb(12)){var e;L?e="-ms-transform":mb?e="-webkit-transform":kb?e="-o-transform":lb&&(e="-moz-transform");var f;e&&(f=$d(a,e));f||(f=$d(a,"transform"));f?(a=f.match(he),a=!a?new Dd(0,0):new Dd(parseFloat(a[1]),parseFloat(a[2]))):a=new Dd(0,0);b=new Dd(b.x+a.x,b.y+a.y)}}else e=na(a.Lh),f=a,a.targetTouches?f=a.targetTouches[0]:e&&a.Sa.targetTouches&& +(f=a.Sa.targetTouches[0]),b.x=f.clientX,b.y=f.clientY;return b}function ie(a,b){"number"==typeof a&&(a=(b?Math.round(a):a)+"px");return a}function je(a){if("none"!=$d(a,"display"))return ke(a);var b=a.style,c=b.display,d=b.visibility,e=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";a=ke(a);b.display=c;b.position=e;b.visibility=d;return a} +function ke(a){var b=a.offsetWidth,c=a.offsetHeight,d=mb&&!b&&!c;return(!ga(b)||d)&&a.getBoundingClientRect?(a=be(a),new Gd(a.right-a.left,a.bottom-a.top)):new Gd(b,c)}function le(a,b){a.style.display=b?"":"none"}function fe(a){return"rtl"==$d(a,"direction")}function me(a,b){if(/^\d+px?$/.test(b))return parseInt(b,10);var c=a.style.left,d=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;a.style.left=b;var e=a.style.pixelLeft;a.style.left=c;a.runtimeStyle.left=d;return e} +function ne(a,b){var c=a.currentStyle?a.currentStyle[b]:r;return c?me(a,c):0}var oe={thin:2,medium:4,thick:6};function pe(a,b){if("none"==(a.currentStyle?a.currentStyle[b+"Style"]:r))return 0;var c=a.currentStyle?a.currentStyle[b+"Width"]:r;return c in oe?oe[c]:me(a,c)}var he=/matrix\([0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, ([0-9\.\-]+)p?x?, ([0-9\.\-]+)p?x?\)/;function qe(a,b){fc.call(this);this.s=a;var c=oa(this.s)&&1==this.s.nodeType?this.s:this.s?this.s.body:r;this.di=!!c&&fe(c);this.ik=Vb(this.s,lb?"DOMMouseScroll":"mousewheel",this,b)}D(qe,fc); +qe.prototype.handleEvent=function(a){var b=0,c=0,d=0;a=a.Sa;if("mousewheel"==a.type){c=1;if(L||mb&&(bb||yb("532.0")))c=40;d=re(-a.wheelDelta,c);ga(a.wheelDeltaX)?(b=re(-a.wheelDeltaX,c),c=re(-a.wheelDeltaY,c)):c=d}else d=a.detail,100d&&(d=-3),ga(a.axis)&&a.axis===a.HORIZONTAL_AXIS?b=d:c=d;y(this.sg)&&(b=Math.min(Math.max(b,-this.sg),this.sg));y(this.tg)&&(c=Math.min(Math.max(c,-this.tg),this.tg));this.di&&(b=-b);b=new se(d,a,b,c);this.dispatchEvent(b)}; +function re(a,b){return mb&&(ab||cb)&&0!=a%b?a:a/b}function se(a,b,c,d){b&&this.ka(b,n);this.type="mousewheel";this.detail=a;this.ek=c;this.Bc=d}D(se,Pb);L||mb&&yb("525");function te(a){(a==r||!(a instanceof Element))&&l(Error("Could not add interactor to the given element."));M.call(this);this.c="interactor";this.wa=a;this.se=this.Ff=this.Ef=this.Gf=this.Df=this.Hf=r;this.vd=q;this.Fb=this.Bb=this.Ya=s;this.hb=[0,0];this.ne=new I.f(0,0,0);this.Jc=new I.f(0,0,0);this.og=0;this.Rf=this.rd=r;this.Pf=s;this.I={MOUSEWHEEL_ENABLED:q,MOUSECLICKS_ENABLED:q,KEYBOARD_ENABLED:q,HOVERING_ENABLED:q,CONTEXTMENU_ENABLED:s,TOUCH_ENABLED:q,TOUCH_BOUNCING_ENABLED:s}}D(te,M); +te.prototype.__defineGetter__("config",t("I"));te.prototype.__defineGetter__("leftButtonDown",t("Ya"));te.prototype.__defineGetter__("middleButtonDown",t("Bb"));te.prototype.__defineGetter__("rightButtonDown",t("Fb")); +te.prototype.ka=function(){this.I.MOUSEWHEEL_ENABLED?(this.se=new qe(this.wa),this.Hf=Vb(this.se,"mousewheel",this.ed.bind(this))):($b(this.Hf),this.se=r);this.I.MOUSECLICKS_ENABLED?(this.Df=Vb(this.wa,"mousedown",this.qi.bind(this)),this.Gf=Vb(this.wa,"mouseup",this.vi.bind(this))):($b(this.Df),$b(this.Gf));this.wa.oncontextmenu=this.I.CONTEXTMENU_ENABLED?r:function(){return s};window.onkeydown=this.I.KEYBOARD_ENABLED?this.yg.bind(this):r;this.I.TOUCH_ENABLED?(this.I.TOUCH_BOUNCING_ENABLED||document.body.addEventListener("touchmove", +function(a){a.preventDefault()},s),this.mh=Vb(this.wa,"touchstart",this.Ii.bind(this)),this.lh=Vb(this.wa,"touchmove",this.Gi.bind(this)),this.kh=Vb(this.wa,"touchend",this.Ci.bind(this))):($b(this.mh),$b(this.lh),$b(this.kh));$b(this.Ef);$b(this.Ff);this.Ef=Vb(this.wa,"mousemove",this.si.bind(this));this.Ff=Vb(this.wa,"mouseout",this.ti.bind(this))}; +te.prototype.qi=function(a){0==a.button?this.Ya=q:1==a.button?this.Bb=q:2==a.button&&(this.Fb=q);eval("this.onMouseDown("+this.Ya+","+this.Bb+","+this.Fb+")");ue(this);a.preventDefault()};te.prototype.pi=aa();te.prototype.vi=function(a){0==a.button?this.Ya=s:1==a.button?this.Bb=s:2==a.button&&(this.Fb=s);eval("this.onMouseUp("+this.Ya+","+this.Bb+","+this.Fb+")");ue(this);a.preventDefault()};te.prototype.__defineGetter__("mousePosition",t("hb"));w=te.prototype;w.ui=aa(); +w.ti=function(a){this.vd=s;this.I.KEYBOARD_ENABLED&&(window.onkeydown=r);this.Fb=this.Bb=this.Ya=s;ue(this);this.ne=new I.f(0,0,0);a.preventDefault()};w.ri=aa();w.Ii=function(a){a.preventDefault();a.ka(a.Sa.targetTouches[0],a.currentTarget);eval("this.onTouchStart("+a.clientX+","+a.clientY+")");this.Jc=new I.f(a.clientX,a.clientY,0);this.Rf=setTimeout(this.Ei.bind(this,a),500)};w.Hi=aa(); +w.Ei=function(a){eval("this.onTouchHover("+a.clientX+","+a.clientY+")");a=new pd;a.Xa=q;a.Ma=this instanceof ve;this.dispatchEvent(a);this.Cd=q};w.Di=aa();function we(a){clearTimeout(a.Rf);if(a.Cd){var b=new pd;b.Xa=s;b.Ma=a instanceof ve;a.dispatchEvent(b)}a.Cd=s}w.Ci=function(a){a.preventDefault();eval("this.onTouchEnd()");we(this)};w.Bi=aa(); +w.Gi=function(a){a.preventDefault();this.Cd||we(this);this.touchmoveEvent=a=a.Sa;eval("this.onTouchMove(this['touchmoveEvent'])");var b=a.targetTouches;if(1==b.length){a=b[0];var c=[a.clientX,a.clientY];a=new I.f(c[0],c[1],0);var b=c[0]>3*this.wa.clientWidth/4,d=c[0]3*this.wa.clientHeight/4,c=!b&&!d&&!e&&!c,e=this.Jc.pa(a);this.Jc=a.g();if(this.Cd)a=new nd,5e.x&&(e.x=-1),5e.y&&(e.y=-1),a.O=e,this.dispatchEvent(a); +else if(this instanceof xe&&(b||d))a=new qd,a.M=0>e.y,this.dispatchEvent(a);else if(this instanceof ve||c)e.scale(3),a=new od,a.O=e,this.dispatchEvent(a)}else 2==b.length&&(a=b[0],b=b[1],a=[a.clientX,a.clientY],b=[b.clientX,b.clientY],a=new I.f(a[0],a[1],0),b=new I.f(b[0],b[1],0),e=Cc(a,b),b=e-this.og,this.og=e,this.Jc.pa(a),this.Jc=a.g(),10Math.abs(a.x)&&(a.x=0);2>Math.abs(a.y)&&(a.y=0);0!=a.mb()&&(this.Ya&&!b?(b=new od,a.scale(3),b.O=a,this.dispatchEvent(b)):this.Bb||this.Ya&&b?(b=new nd,5a.x&&(a.x=-5),5a.y&&(a.y=-5),b.O=a,this.dispatchEvent(b)):this.Fb&&(b=new pd,b.Xa=0=f&&(a.preventDefault(),e?a=new nd:b?a=new pd:(a=new od,this instanceof xe&&(a=new qd)),a&&(c=new I.f(0,0,0),37==f?(c.x=5,a.M=s,b&&(a.M=q,a.Xa=q,a.Ma=s)):39==f?(c.x=-5,a.M=q,b&&(a.Xa=s,a.Ma=s)):38==f?(c.y=5,a.M=q,b&&(a.Xa=q,a.Ma=q)):40==f&&(c.y=-5,a.M=s,b&&(a.Xa= +s,a.Ma=q)),a.O=c,this.dispatchEvent(a)))}};C("X.interactor",te);C("X.interactor.prototype.init",te.prototype.ka);C("X.interactor.prototype.onMouseDown",te.prototype.pi);C("X.interactor.prototype.onMouseUp",te.prototype.ui);C("X.interactor.prototype.onMouseMove",te.prototype.ri);C("X.interactor.prototype.onMouseWheel",te.prototype.wi);C("X.interactor.prototype.onKey",te.prototype.ni);C("X.interactor.prototype.onTouchStart",te.prototype.Hi);C("X.interactor.prototype.onTouchMove",te.prototype.Fi); +C("X.interactor.prototype.onTouchEnd",te.prototype.Bi);C("X.interactor.prototype.onTouchHover",te.prototype.Di);function xe(a){te.call(this,a);this.c="interactor2D"}D(xe,te);xe.prototype.ed=function(a){xe.q.ed.call(this,a);var b=new qd;a.Bc==r&&(a.Bc=0);b.M=0>a.Bc;this.dispatchEvent(b)};function Bd(a){Y.call(this);this.c="slice";this.o=[0,0,0];this.lc=[0,0,1];this.M=[0,1,0];this.zd=[1,0,0];this.F=this.K=10;this.wc=[0,1,0,0,1,1,1,1,1,0,0,0];this.P=this.jb=r;this.fb=q;this.gc=[1,1,1];a!=r&&this.Zb(a)}D(Bd,Y);Bd.prototype.Zb=function(a){this.o=a.o.slice();this.lc=a.lc.slice();this.M=a.M.slice();this.K=a.K;this.F=a.F;this.jb=a.jb;this.P=a.P;this.fb=a.fb;this.gc=a.gc;this.hh=a.hh;Bd.q.Zb.call(this,a)}; +Bd.prototype.Ac=function(){var a=new Q(this.lc[0],this.lc[1],this.lc[2]),b=new Q(this.M[0],this.M[1],this.M[2]),c=new Q(this.zd[0],this.zd[1],this.zd[2]),d=new Q(this.o[0],this.o[1],this.o[2]),e=new Q(1,1,1);if(1==a.x||-1==a.x)e=new Q(this.o[0],this.K/2,this.F/2);else if(1==a.y||-1==a.y)e=new Q(this.F/2,this.o[1],this.K/2);else if(1==a.b||-1==a.b)e=new Q(this.K/2,this.F/2,this.o[2]);var f=Dc(c.g().L(),b.g().L()),f=new Q(f.x*e.x,f.y*e.y,f.b*e.b);f.add(d);var g=Dc(c.g().L(),b),g=new Q(g.x*e.x,g.y*e.y, +g.b*e.b);g.add(d);var h=Dc(c,b.g().L()),h=new Q(h.x*e.x,h.y*e.y,h.b*e.b);h.add(d);var j=h,b=Dc(c,b),b=new Q(b.x*e.x,b.y*e.y,b.b*e.b);b.add(d);d=g;this.j=new W(18);this.k=new W(18);this.j.add(f.x,f.y,f.b);this.j.add(g.x,g.y,g.b);this.j.add(h.x,h.y,h.b);this.j.add(j.x,j.y,j.b);this.j.add(b.x,b.y,b.b);this.j.add(d.x,d.y,d.b);this.k.add(a.x,a.y,a.b);this.k.add(a.x,a.y,a.b);this.k.add(a.x,a.y,a.b);this.k.add(a.x,a.y,a.b);this.k.add(a.x,a.y,a.b);this.k.add(a.x,a.y,a.b);this.fb&&(a=new Y,a.j=new W(24),a.k= +new W(24),a.j.add(f.x,f.y,f.b),a.j.add(g.x,g.y,g.b),a.j.add(g.x,g.y,g.b),a.j.add(b.x,b.y,b.b),a.j.add(b.x,b.y,b.b),a.j.add(h.x,h.y,h.b),a.j.add(h.x,h.y,h.b),a.j.add(f.x,f.y,f.b),a.k.add(0,0,0),a.k.add(0,0,0),a.k.add(0,0,0),a.k.add(0,0,0),a.k.add(0,0,0),a.k.add(0,0,0),a.k.add(0,0,0),a.k.add(0,0,0),a.Nb=[this.gc[0],this.gc[1],this.gc[2]],a.oa="LINES",a.nc=2,this.h.push(a))};C("X.slice",Bd);function P(a){Y.call(this);this.c="volume";this.o=[0,0,0];this.Ia=[10,10,10];this.Gb=[1,1,1];this.tb=[];this.ub=this.wb=this.vb=this.Ic=this.da=this.Hc=this.ca=this.Gc=this.T=0;this.jc=[10,10,10];this.tc=new Y;this.uc=new Y;this.vc=new Y;this.Ed=this.Qa=s;this.Ib=0;this.P=r;this.fb=q;this.X=Infinity;this.W=-Infinity;this.we=q;this.Qf=["left","posterior","superior"];this.Ae=[1,0,0,0,1,0,0,0,1];this.ve=[-1,0,0,0,-1,0,0,0,1];this.Oa=[-1,-1,1];this.G=[[-1,0,0],[0,-1,0],[0,0,1]];this.$=0;this.z=r;Fa(this, +new uc);Fa(this,new Vc);a!=r&&this.Zb(a)}D(P,Y);P.prototype.Zb=function(a){this.o=a.o.slice();this.Ia=a.Ia.slice();this.Gb=a.Gb.slice();this.T=a.T;this.Gc=a.Gc;this.ca=a.ca;this.Hc=a.Hc;this.da=a.da;this.Ic=a.Ic;this.vb=a.vb;this.wb=a.wb;this.ub=a.ub;this.jc=a.jc.slice();this.tc=new Y(a.tc);this.uc=new Y(a.uc);this.vc=new Y(a.vc);this.Qf=a.ma;this.Ae=a.Ae;this.ve=a.ve;this.Oa=a.Oa;this.G=a.G;this.$=a.$;this.z=a.z;this.Qa=a.Qa;this.Ed=a.Ed;this.Ib=a.Ib;this.P=a.P;this.fb=a.fb;P.q.Zb.call(this,a)}; +P.prototype.Ac=function(a){this.h.length=0;this.tc.h.length=0;this.uc.h.length=0;this.vc.h.length=0;this.h.push(this.tc);this.h.push(this.uc);this.h.push(this.vc);this.Qf=a.ma;this.Ae=a.i;this.ve=a.La;this.Oa=a.orientation;this.G=a.nb;this.$=a.max;this.z=a.data;this.e=q}; +P.prototype.A=function(){var a=this.G[2],b=this.Ia;0!=a[0]?(this.vb=this.T,this.wb=this.ca,this.ub=this.da,this.jc=[b[2],b[0],b[1]]):0!=a[1]?(this.vb=this.ca,this.wb=this.T,this.ub=this.da,this.jc=[b[0],b[2],b[1]]):(this.vb=this.ca,this.wb=this.da,this.ub=this.T,this.jc=b)}; +P.prototype.l=function(a){a="undefined"!==typeof a?a:q;if(0b;b++){var c=this.h[b],d=0,e=0;0==b?(d=this.T,e=this.Gc,this.Gc=this.T):1==b?(d=this.ca,e=this.Hc,this.Hc=this.ca):2==b&&(d=this.da,e=this.Ic,this.Ic= +this.da);c.h[parseInt(e,10)].visible=s;c=c.h[parseInt(d,10)];c.visible=q;c.ba=1}}a&&P.q.l.call(this)};P.prototype.__defineGetter__("dimensions",t("Ia"));P.prototype.__defineGetter__("dimensionsRAS",t("jc"));P.prototype.__defineGetter__("volumeRendering",t("Qa"));P.prototype.__defineSetter__("volumeRendering",function(a){this.Qa=a;this.l(s)});P.prototype.__defineGetter__("visible",t("sa")); +P.prototype.__defineSetter__("visible",function(a){if(a)this.sa=a,this.l(s);else{for(var b=this.h,c=b.length,d=0,d=0;d>8,c+=String.fromCharCode(p),c+=String.fromCharCode(m),c=parseInt(c,10);k--}else if(4161==f){j++;for(var d=h[j++],e="",f=0;f>8,e+=String.fromCharCode(p),e+=String.fromCharCode(m);g.t=[g.t[0],g.t[1],Math.min(Math.abs(g.qg-e),g.t[2])];g.qg=e; +k--}g.Ba[2]++}else{var g={rows:0,cols:0,t:r,Fe:0,rh:0,$a:1,li:1,qg:r,Vd:0,eb:0,$c:r,ef:0,mf:[],data:r,min:Infinity,max:-Infinity,origin:r,ma:r,i:r,La:r,orientation:r,nb:r};g.$a=b.m.length;g.$a==r&&(g.$a=1);for(var h=Z(this,"ushort",this.z.byteLength),j=66,d=r,f=r,d=r,k=9;0>8,e=e+String.fromCharCode(p),e=e+String.fromCharCode(m);e=e.split("\\");g.t=[+e[0],+e[1],Infinity];k--}else if(32==d)switch(f=h[j++],j++,d=h[j++],f){case 19:for(f=0;f>8,c+=String.fromCharCode(p),c+=String.fromCharCode(m),c=parseInt(c,10);k--;break;case 50:e="";for(f=0;f>8,e+=String.fromCharCode(p),e+=String.fromCharCode(m);e=e.split("\\");g.origin=[+e[0],+e[1],+e[2]];k--;break; +case 55:e="";for(f=0;f>8,e+=String.fromCharCode(p),e+=String.fromCharCode(m);e=e.split("\\");g.i=[+e[0],+e[1],+e[2],+e[3],+e[4],+e[5]];k--}else if(16==d)switch(f=h[j++],j++,d=h[j++],f){case 8720:for(f=0;f=m);p++){var u=parseInt(k[p],10),x=c.get(u);d.add(x[0],x[1],x[2]);var v=u,z=x;"LINES"==this.xa?(v=parseInt(k[p+1],10),z=c.get(v),d.add(z[0],z[1],z[2])):"TRIANGLE_STRIPS"==this.xa&&(0==p||p==m-1)&&d.add(x[0],x[1],x[2]);uc&&10!=g);Z(this,"uchar");e=Z(this,"uint");c=Z(this,"uint");var h=Z(this,"float",3*e);g=Z(this,"uint",3*c);var j=new Uint32Array(e),k=new Float32Array(9*c);b.j=d=new W(9*c);b.k=e=new W(9*c);var m;for(m=0;m>>8^e[(b^a[c])&255];for(f=d>>3;f--;c+=8)b=b>>>8^e[(b^a[c])&255],b=b>>>8^e[(b^a[c+1])&255],b=b>>>8^e[(b^a[c+2])&255],b=b>>>8^e[(b^a[c+3])&255],b=b>>>8^e[(b^a[c+4])&255],b=b>>>8^e[(b^a[c+5])&255],b=b>>>8^e[(b^a[c+6])&255],b=b>>>8^e[(b^a[c+7])&255];return(b^4294967295)>>>0}}; +He.Zg=new Uint32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101, +3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271, +366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376, +3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954, +1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836, +1088359270,936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]);function Ie(a){var b=a.length,c=0,d=Number.POSITIVE_INFINITY,e,f,g,h,j,k,m,p,u;for(p=0;pc&&(c=a[p]),a[p]>=1;for(u=k;u>>=1;switch(a){case 0:var a=this.input,b=this.la,c=this.Ca,d=this.S,e=n,f=n,g=n,h=c.length,e=n;this.Ra=this.Yc=0;e=a[b++];e===n&&l(Error("invalid uncompressed block header: LEN (first byte)"));f=e;e=a[b++];e===n&&l(Error("invalid uncompressed block header: LEN (second byte)"));f|=e<<8;e=a[b++];e===n&&l(Error("invalid uncompressed block header: NLEN (first byte)"));g=e;e=a[b++];e===n&&l(Error("invalid uncompressed block header: NLEN (second byte)"));g|= +e<<8;f===~g&&l(Error("invalid uncompressed block header: length verify"));b+f>a.length&&l(Error("input buffer is broken"));switch(this.Ie){case Le:for(;d+f>c.length;)e=h-d,f-=e,c.set(a.subarray(b,b+e),d),d+=e,b+=e,this.S=d,c=this.ac(),d=this.S;break;case Ke:for(;d+f>c.length;)c=this.ac({cg:2});break;default:l(Error("invalid inflate mode"))}c.set(a.subarray(b,b+f),d);d+=f;this.la=b+=f;this.S=d;this.Ca=c;break;case 1:this.Pe(Ne,Oe);break;case 2:Pe(this);break;default:l(Error("unknown BTYPE: "+a))}}return this.Xf()}; +var Qe=new Uint16Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Re=new Uint16Array([3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258]),Se=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0]),Te=new Uint16Array([1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577]),Ue=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),Ve=new Uint8Array(288), +We,Xe;We=0;for(Xe=Ve.length;We=We?8:255>=We?9:279>=We?7:8;var Ne=Ie(Ve),Ye=new Uint8Array(30),Ze,$e;Ze=0;for($e=Ye.length;Ze<$e;++Ze)Ye[Ze]=5;var Oe=Ie(Ye);function Me(a,b){for(var c=a.Yc,d=a.Ra,e=a.input,f=a.la,g;d>>b;a.Ra=d-b;a.la=f;return g} +function af(a,b){for(var c=a.Yc,d=a.Ra,e=a.input,f=a.la,g=b[0],h=b[1],j;d>>16;a.Yc=c>>g;a.Ra=d-g;a.la=f;return e&65535} +function Pe(a){function b(a,b,c){var d,e,f;for(f=0;ff)d>=e&&(this.S=d,c=this.ac(),d=this.S),c[d++]=f;else{f-=257;h=Re[f];0=e&&(this.S=d,c=this.ac(),d=this.S);for(;h--;)c[d]=c[d++-g]}for(;8<=this.Ra;)this.Ra-=8,this.la--;this.S=d}; +w.yh=function(a,b){var c=this.Ca,d=this.S;this.$f=a;for(var e=c.length,f,g,h;256!==(f=af(this,a));)if(256>f)d>=e&&(c=this.ac(),e=c.length),c[d++]=f;else{f-=257;h=Re[f];0e&&(c=this.ac(),e=c.length);for(;h--;)c[d]=c[d++-g]}for(;8<=this.Ra;)this.Ra-=8,this.la--;this.S=d}; +w.ac=function(){var a=new Uint8Array(this.S-32768),b=this.S-32768,c=this.Ca;a.set(c.subarray(32768,a.length));this.Ge.push(a);this.pf+=a.length;c.set(c.subarray(b,b+32768));this.S=32768;return c};w.Eh=function(a){var b=this.input.length/this.la+1|0,c=this.input,d=this.Ca;a&&("number"===typeof a.cg&&(b=a.cg),"number"===typeof a.nh&&(b+=a.nh));2>b?(a=(c.length-this.la)/this.$f[2],a=258*(a/2)|0,a=abf;++bf)for(var cf=bf,df=7,cf=cf>>>1;cf;cf>>>=1)--df;var ef=[],ff;for(ff=0;288>ff;ff++)switch(q){case 143>=ff:ef.push([ff+48,8]);break;case 255>=ff:ef.push([ff-144+400,9]);break;case 279>=ff:ef.push([ff-256+0,7]);break;case 287>=ff:ef.push([ff-280+192,8]);break;default:l("invalid literal: "+ff)} +function gf(){var a=hf;switch(q){case 3===a:return[257,a-3,0];case 4===a:return[258,a-4,0];case 5===a:return[259,a-5,0];case 6===a:return[260,a-6,0];case 7===a:return[261,a-7,0];case 8===a:return[262,a-8,0];case 9===a:return[263,a-9,0];case 10===a:return[264,a-10,0];case 12>=a:return[265,a-11,1];case 14>=a:return[266,a-13,1];case 16>=a:return[267,a-15,1];case 18>=a:return[268,a-17,1];case 22>=a:return[269,a-19,2];case 26>=a:return[270,a-23,2];case 30>=a:return[271,a-27,2];case 34>=a:return[272,a- +31,2];case 42>=a:return[273,a-35,3];case 50>=a:return[274,a-43,3];case 58>=a:return[275,a-51,3];case 66>=a:return[276,a-59,3];case 82>=a:return[277,a-67,4];case 98>=a:return[278,a-83,4];case 114>=a:return[279,a-99,4];case 130>=a:return[280,a-115,4];case 162>=a:return[281,a-131,5];case 194>=a:return[282,a-163,5];case 226>=a:return[283,a-195,5];case 257>=a:return[284,a-227,5];case 258===a:return[285,a-258,0];default:l("invalid length: "+a)}}var jf=[],hf,kf; +for(hf=3;258>=hf;hf++)kf=gf(),jf[hf]=kf[2]<<24|kf[1]<<16|kf[0];new Uint32Array(jf);function lf(){};function mf(a){this.input=a;this.la=0;this.member=[]} +mf.prototype.ad=function(){for(var a=this.input.length;this.la>>0;He.Je(e)!==c&&l(Error("invalid CRC-32 checksum: 0x"+He.Je(e).toString(16)+ +" / 0x"+c.toString(16)));b.hk=c=(h[d++]|h[d++]<<8|h[d++]<<16|h[d++]<<24)>>>0;(e.length&4294967295)!==c&&l(Error("invalid input size: "+(e.length&4294967295)+" / "+c));this.member.push(b);this.la=d}a=this.member;b=e=d=0;for(h=a.length;bz)z=J;if(!F||OE)E=R;if(!d||Se)e=V;m.push(U);p.push(N)}g=(v+z)/2;F=(F+E)/2;h=(d+e)/2;E=new Float32Array(f);b.j=d=new W(f);b.k=e=new W(f);b.Z=f=new W(f);for(k=v=0;k=m;m++)d.push(!isNaN(this.nf[m])?this.N[m].scale(this.nf[m]):n)}f=c.subarray(f);if("gzip"==this.encoding||"gz"==this.encoding)f=(new mf(new Uint8Array(f))).ad();f=f.buffer;c={data:r,min:Infinity,max:-Infinity,ma:r,i:r,La:r,orientation:r,nb:r};c.data=new this.rb(f);m=wd(c.data);f=c.min=m[0];m=c.max=m[1];b.Na=b.X=f;b.$=b.W=m;b.Ia=[this.kf[0],this.kf[1],this.kf[2]]; +d=(new Q(this.N[0][0],this.N[0][1],this.N[0][2])).mb();e=(new Q(this.N[1][0],this.N[1][1],this.N[1][2])).mb();g=(new Q(this.N[2][0],this.N[2][1],this.N[2][2])).mb();b.Gb=[d,e,g];-Infinity==b.U&&(b.U=f);Infinity==b.V&&(b.V=m);c.ma=c.ma=this.ma;c.i=[];c.i.push(this.N[0][0]);c.i.push(this.N[0][1]);c.i.push(this.N[0][2]);c.i.push(this.N[1][0]);c.i.push(this.N[1][1]);c.i.push(this.N[1][2]);c.i.push(this.N[2][0]);c.i.push(this.N[2][1]);c.i.push(this.N[2][2]);c.i=c.i;c.La=yd(c.ma,c.i);f=zd(this,c.La);c.orientation= +c.orientation=f[0];c.nb=c.nb=f[1];b.Ac(c);I.qa(this.c+".parse");b.tb=Ad(this,b);b.A();c=new Xc;c.aa=b;c.v=a;this.dispatchEvent(c)}; +sf.prototype.Gh={type:function(a){switch(a){case "uchar":case "unsigned char":case "uint8":case "uint8_t":this.rb=Uint8Array;break;case "signed char":case "int8":case "int8_t":this.rb=Int8Array;break;case "short":case "short int":case "signed short":case "signed short int":case "int16":case "int16_t":this.rb=Int16Array;break;case "ushort":case "unsigned short":case "unsigned short int":case "uint16":case "uint16_t":this.rb=Uint16Array;break;case "int":case "signed int":case "int32":case "int32_t":this.rb= +Int32Array;break;case "uint":case "unsigned int":case "uint32":case "uint32_t":this.rb=Uint32Array;break;case "float":this.rb=Float32Array;break;case "double":this.rb=Float64Array;break;default:l(Error("Unsupported NRRD data type: "+a))}return this.type=a},endian:function(a){return this.fk=a},encoding:function(a){return this.encoding=a},dimension:function(a){return this.Ba=parseInt(a,10)},sizes:function(a){var b,c,d,e;d=a.split(/\s+/);e=[];b=0;for(c=d.length;bg?(g=1/Math.sqrt(h*h+j*j+k*k),h*=g,j*=g,k*=g,g=0):g=Math.sqrt(g);0c.t[0]&&(u=-u);Mc(d,0,(g*g+h*h-j*j-k*k)*m,2*(h*j-g*k)*p,2*(h*k+g*j)*u,x);Mc(d,1,2*(h*j+g*k)*m,(g*g+j*j-h*h-k*k)*p,2*(j*k-g*h)*u,v);Mc(d,2,2*(h*k-g*j)*m,2*(j*k+g*h)*p,(g*g+k*k-j*j-h*h)*u,z);f.push((g*g+h*h-j*j-k*k)*m);f.push(2*(h*j+g*k)*m);f.push(2*(h*k+g*j)*u);f.push(2*(h*j-g*k)*p);f.push((g*g+j*j-h*h-k*k)*p);f.push(2*(j*k-g*h)*u);f.push(2*(h*k+g*j)*u);f.push(2*(j*k+g*h)*p);f.push((g*g+k*k-j*j-h*h)*u)}else 0a.Bc;b.Ma=q;this.dispatchEvent(b)};function Gf(a){M.call(this);this.c="array";this.u=[];this.wf=a}D(Gf,M);function Hf(a,b,c){for(var d=0;4>d;d++)if(a[d+0]!==b[d+c])return s;return q}Gf.prototype.add=function(a){this.u.push(a);return q};Gf.prototype.remove=function(a){a=this.u.indexOf(a);-1d)){d=b+Math.floor(d/2);If(a,b,d);for(If(a,d,c);bf.wf(f.u[g+1],e);){var j=f,k=g+1,m=j.u[g];j.u[g]=j.u[k];j.u[k]=m;++g}f.u[g]=e}}}Gf.prototype.sort=function(){If(this,0,this.u.length)};function Jf(a,b){zf.call(this,a,b);this.c="camera2D"}D(Jf,zf);Jf.prototype.rotate=function(a){a=Jf.q.rotate.call(this,a);var b=new md;0a.x&&b.De++;0a.y&&b.re--;this.dispatchEvent(b)};function Kf(a,b){zf.call(this,a,b);this.c="camera3D";this.yf=45;this.Jf=I.d.Ue(I.d.cd(),this.yf,a/b,1,1E4)}D(Kf,zf);Kf.prototype.rotate=function(a){a=Kf.q.rotate.call(this,a);var b=-a.x/5*Math.PI/180;a=-a.y/5*Math.PI/180;var c=new I.f(this.p[1],this.p[5],this.p[9]),d=new I.f(this.p[0],this.p[4],this.p[8]);c.normalize();d.normalize();I.d.rotate(this.p,b,c.x,c.y,c.b);I.d.rotate(this.p,a,d.x,d.y,d.b)};Kf.prototype.Xd=function(a,b){var c=Kf.q.Xd.call(this,a,b);I.d.rg(c,a,b,this.M);return c}; +C("X.camera3D",Kf);function Lf(a){Lb.call(this);this.lb=a;this.C=[]}D(Lf,Lb);var Mf=[];function Nf(a,b,c,d,e){ka(c)||(Mf[0]=c,c=Mf);for(var f=0;fthis.Ve?this.Ve-this.ag:arb&&Vb(this.n(),"resize",this.he,s,this);this.he();var a=this.n();a.setAttribute("role","progressbar");a.setAttribute("aria-live","polite")};w.Ld=function(){Tf.q.Ld.call(this);L&&7>rb&&Zb(this.n(),"resize",this.he,s,this)};w.Rd=function(){return this.hd.Rd()};w.ee=function(a){this.hd.ee(a);this.n()&&Wf(this)};function Wf(a){var b=a.Rd();a.n().setAttribute("aria-valuenow",b)}w.Qd=function(){return this.hd.Qd()};w.Pd=function(){return this.hd.Pd()};w.Cg="horizontal"; +w.Ph=function(){this.he();this.dispatchEvent("change")};w.he=function(){if(this.bb){var a=this.Qd(),b=this.Pd(),a=(this.Rd()-a)/(b-a),b=Math.round(100*a);"vertical"==this.Cg?L&&7>rb?(this.bb.style.top=0,this.bb.style.height="100%",b=this.bb.offsetHeight,a=Math.round(a*b),this.bb.style.top=b-a+"px",this.bb.style.height=a+"px"):(this.bb.style.top=100-b+"%",this.bb.style.height=b+"%"):this.bb.style.width=b+"%"}};function Xf(a,b){a==r&&l(Error("No valid parent element."));b==r&&l(Error("Invalid initial value."));Tf.call(this);this.c="progressbar";this.Ja=a;this.If="";this.pd=this.ib=r;this.Ob=[];var c;c=".progress-bar-horizontal {\n position: relative;\n border: 1px solid #949dad;\n";c+=" background: white;\n";c+=" padding: 1px;\n";c+=" overflow: hidden;\n";c+=" margin: 2px;\n";c+=" width: 100px;\n";c+=" height: 5px;\n";c+="}";var d;d=".progress-bar-thumb {\n position: relative;\n background: #F62217;\n"; +d+=" overflow: hidden;\n";d+=" width: 0%;\n";d+=" height: 100%;\n";d+="}";var e;e=".progress-bar-thumb-done {\n background: #57E964;\n}";this.Ob=[c,d,e];this.ee(b);this.Re()}D(Xf,Tf); +Xf.prototype.Re=function(){var a=Zd(this.Ja,"position");if("static"==a||""==a)this.If=this.Ja.style.position,this.Ja.style.position="relative";var a=document.getElementsByTagName("head")[0],b=Sd("style");b.type="text/css";b.media="screen";var c=document.createTextNode(String(this.Ob[0])),d=document.createTextNode(String(this.Ob[1])),e=document.createTextNode(String(this.Ob[2]));a.appendChild(b);b.appendChild(c);b.appendChild(d);b.appendChild(e);this.ib=b;this.ec(this.Ja);a=this.n();a.style.position= +"absolute";a.style.top=(this.Ja.clientHeight-5)/2+"px";a.style.left=(this.Ja.clientWidth-100)/2+"px";a.classList.add("xtk-progress-bar")};function Yf(a){var b=a.n().style.top,c=a.n().style.left;Ud(a.n());var d=new Xf(a.Ja,100),e=d.n();e.style.position="absolute";e.style.top=b;e.style.left=c;e.classList.add("xtk-progress-bar");(e.firstElementChild!=n?e.firstElementChild:Vd(e.firstChild)).classList.add("progress-bar-thumb-done");a.pd=d} +Xf.prototype.Td=function(){this.ib&&Ud(this.ib);this.n()&&Ud(this.n());this.pd&&Ud(this.pd.n());this.pd=this.ib=r;this.Ja.style.position=this.If};function Zf(a,b,c){na(a)?c&&(a=ua(a,c)):a&&"function"==typeof a.handleEvent?a=ua(a.handleEvent,a):l(Error("Invalid listener argument"));return 2147483647..) is required."));var b=a;ma(b)&&(b=Qd(a));oa(b)&&1==b.nodeType||l(Error("Could not find the given container."));this.v=b});w=$f.prototype; +w.jd=function(){this.r.reset()}; +w.ka=function(a){var b=Sd("canvas");this.v.appendChild(b);this.K=this.v.clientWidth;this.F=this.v.clientHeight;b.width=this.K;b.height=this.F;try{var c=b.getContext(a);c||l(Error())}catch(d){var e="Sorry, "+a+' context is not supported on this machine! See http://crash.goXTK.com for requirements..';this.v.innerHTML='

    Oooops..

    '+e+"

    "; +l(Error(e))}this.J=new vf;Vb(this.J,jd,this.yi.bind(this));this.fa=b;this.a=c;b=new ve(this.fa);"2d"==a&&(b=new xe(this.fa));b.ka();Vb(b,gd,this.jd.bind(this));Vb(b,kd,this.af.bind(this));Vb(b,fd,this.cf.bind(this));this.na=b;b=new Kf(this.K,this.F);"2d"==a&&(b=new Jf(this.K,this.F));b.observe(this.na);this.r=b;Vb(window,"resize",this.bf,s,this)};w.add=function(a){(a instanceof Ff||a instanceof Df||a instanceof Bf)&&a.l();this.Ka.push(a);this.cb(a)}; +w.remove=function(a){(!this.fa||!this.a)&&l(Error("The renderer was not initialized properly."));a==r&&l(Error("Illegal object."));return s};w.cb=function(a){(!this.fa||!this.a)&&l(Error("The renderer was not initialized properly."));a==r&&(window.console.log(a),l(Error("Illegal object.")));var b;b=pa(a);var c=Tb[b];if(c){var d=ga(id),e=ga(n);d&&e?(c=Sb[id],b=!!c&&!!c[n]&&b in c[n]):b=!d&&!e?q:Ib(c,function(a){return d&&a.type==id||e&&a.capture==n})}else b=s;b||Vb(a,id,this.oi.bind(this))}; +w.get=function(a){a==r&&l(Error("Invalid object id."));for(var b=this.Za.u,c=b.length,d=0,d=0;d=e.right))f&=-2;if(132==(f&132)&&(h.y=e.bottom))f&=-5;h.xe.right&&f&16)&&(g.width=Math.max(g.width-(h.x+g.width-e.right),0),d|=4);h.x+g.width>e.right&&f&1&&(h.x=Math.max(e.right-g.width, +e.left),d|=1);f&2&&(d|=(h.xe.right?32:0));h.y=e.top&&(h.y+g.height>e.bottom&&f&32)&&(g.height=Math.max(g.height-(h.y+g.height-e.bottom),0),d|=8);h.y+g.height>e.bottom&&f&4&&(h.y=Math.max(e.bottom-g.height,e.top),d|=2);f&8&&(d|=(h.ye.bottom?128:0));h=d}else h=256;if(h&496)return h}f=a;e=lb&&(ab||pb)&&yb("1.9");f instanceof +Dd?(a=f.x,f=f.y):(a=f,f=n);b.style.left=ie(a,e);b.style.top=ie(f,e);if(!(c==g||(!c||!g?0:c.width==g.width&&c.height==g.height)))a=Xd(Md(Pd(b))),L&&(!a||!yb("8"))?(c=b.style,a?(L?(a=ne(b,"paddingLeft"),e=ne(b,"paddingRight"),f=ne(b,"paddingTop"),d=ne(b,"paddingBottom"),a=new Fd(f,e,d,a)):(a=Zd(b,"paddingLeft"),e=Zd(b,"paddingRight"),f=Zd(b,"paddingTop"),d=Zd(b,"paddingBottom"),a=new Fd(parseFloat(f),parseFloat(e),parseFloat(d),parseFloat(a))),L?(e=pe(b,"borderLeft"),f=pe(b,"borderRight"),d=pe(b,"borderTop"), +b=pe(b,"borderBottom"),b=new Fd(d,f,b,e)):(e=Zd(b,"borderLeftWidth"),f=Zd(b,"borderRightWidth"),d=Zd(b,"borderTopWidth"),b=Zd(b,"borderBottomWidth"),b=new Fd(parseFloat(d),parseFloat(f),parseFloat(b),parseFloat(e))),c.pixelWidth=g.width-b.left-a.left-a.right-b.right,c.pixelHeight=g.height-b.top-a.top-a.bottom-b.bottom):(c.pixelWidth=g.width,c.pixelHeight=g.height)):(b=b.style,lb?b.MozBoxSizing="border-box":mb?b.WebkitBoxSizing="border-box":b.boxSizing="border-box",b.width=Math.max(g.width,0)+"px", +b.height=Math.max(g.height,0)+"px");return h};function gg(){}gg.prototype.Ua=aa();function hg(a,b){this.Me=a instanceof Dd?a:new Dd(a,b)}D(hg,gg);hg.prototype.Ua=function(a,b,c,d){eg(ae(a),0,a,b,this.Me,c,r,d)};function ig(a,b,c){this.element=a;this.Zf=b;this.Mi=c}D(ig,gg);ig.prototype.Ua=function(a,b,c){eg(this.element,this.Zf,a,b,n,c,this.Mi)};function jg(a,b){fc.call(this);this.lb=new Lf(this);this.hf(a||r);b&&(this.Ec=b)}D(jg,fc);w=jg.prototype;w.s=r;w.oh=q;w.Tf=r;w.ta=s;w.Wi=s;w.Te=-1;w.pg=-1;w.Uh=s;w.Dh=q;w.Ec="toggle_display";w.n=t("s");w.hf=function(a){this.ta&&l(Error("Can not change this state of the popup while showing."));this.s=a}; +function kg(a,b){a.ge&&a.ge.stop();a.Sd&&a.Sd.stop();if(b){if(!a.ta&&a.Ze()){a.s||l(Error("Caller must call setElement before trying to show the popup"));a.Ua();var c=Pd(a.s);a.Uh&&Nf(a.lb,c,"keydown",a.mi,q);if(a.oh)if(Nf(a.lb,c,"mousedown",a.xg,q),L){var d;try{d=c.activeElement}catch(e){}for(;d&&"IFRAME"==d.nodeName;){try{var f=d.contentDocument||d.contentWindow.document}catch(g){break}c=f;d=c.activeElement}Nf(a.lb,c,"mousedown",a.xg,q);Nf(a.lb,c,"deactivate",a.wg)}else Nf(a.lb,c,"blur",a.wg);"toggle_display"== +a.Ec?(a.s.style.visibility="visible",le(a.s,q)):"move_offscreen"==a.Ec&&a.Ua();a.ta=q;a.ge?(Yb(a.ge,"end",a.Ag,s,a),a.ge.play()):a.Ag()}}else lg(a)}w.Ua=ea;function lg(a,b){if(!a.ta||!a.dispatchEvent({type:"beforehide",target:b}))return s;a.lb&&a.lb.gf();a.ta=s;a.pg=xa();a.Sd?(Yb(a.Sd,"end",wa(a.Yf,b),s,a),a.Sd.play()):a.Yf(b);return q}w.Yf=function(a){"toggle_display"==this.Ec?this.Wi?Zf(this.hg,0,this):this.hg():"move_offscreen"==this.Ec&&(this.s.style.top="-10000px");this.$e(a)}; +w.hg=function(){this.s.style.visibility="hidden";le(this.s,s)};w.Ze=function(){return this.dispatchEvent("beforeshow")};w.Ag=function(){this.Te=xa();this.pg=-1;this.dispatchEvent("show")};w.$e=function(a){this.dispatchEvent({type:"hide",target:a})};w.xg=function(a){a=a.target;!Wd(this.s,a)&&((!this.Tf||Wd(this.Tf,a))&&!(150>xa()-this.Te))&&lg(this,a)};w.mi=function(a){27==a.keyCode&&lg(this,a.target)&&(a.preventDefault(),a.stopPropagation())}; +w.wg=function(a){if(this.Dh){var b=Pd(this.s);if(L||kb){if(a=b.activeElement,!a||Wd(this.s,a)||"BODY"==a.tagName)return}else if(a.target!=b)return;150>xa()-this.Te||lg(this)}};function mg(a,b){this.Pi=4;this.Yd=b||n;jg.call(this,a)}D(mg,jg);mg.prototype.Ua=function(){if(this.Yd){var a=!this.ta&&"move_offscreen"!=this.Ec,b=this.n();a&&(b.style.visibility="hidden",le(b,q));this.Yd.Ua(b,this.Pi,this.jk);a&&le(b,s)}};function ng(a){this.A=new wc;a&&this.Ee(a)}function og(a){var b=typeof a;return"object"==b&&a||"function"==b?"o"+pa(a):b.substr(0,1)+a}w=ng.prototype;w.Nd=function(){return this.A.Nd()};w.add=function(a){this.A.set(og(a),a)};w.Ee=function(a){a=vc(a);for(var b=a.length,c=0;cthis.Lc)this.Lc=k.x;if(this.Pc===r||g.ythis.Mc)this.Mc=k.y;if(this.Qc===r||g.bthis.Nc)this.Nc=k.b;this.o=[(this.Oc+this.Lc)/2,(this.Pc+this.Mc)/2,(this.Qc+this.Nc)/2];j.e=s}b&&d.e&&(j=this.Hb.get(c),j!=r&&this.a.isBuffer(j.B)&&this.a.deleteBuffer(j.B)); +j=r;!b||d.e?(j=this.a.createBuffer(),d.ob(),this.a.bindBuffer(this.a.ARRAY_BUFFER,j),this.a.bufferData(this.a.ARRAY_BUFFER,d.Q,this.a.STATIC_DRAW),j=new dg(j,d.count,3),d.e=s):j=this.Hb.get(c);wf(this.J,0.3);b&&e.e&&(g=this.Hb.get(c),g!=r&&this.a.isBuffer(g.B)&&this.a.deleteBuffer(g.B));g=r;!b||e.e?(g=this.a.createBuffer(),e.ob(),this.a.bindBuffer(this.a.ARRAY_BUFFER,g),this.a.bufferData(this.a.ARRAY_BUFFER,e.Q,this.a.STATIC_DRAW),g=new dg(g,e.count,3),e.e=s):g=this.wd.get(c);wf(this.J,0.3);b&&(f&& +f.e)&&(e=this.ic.get(c),e!=r&&this.a.isBuffer(e.B)&&this.a.deleteBuffer(e.B));e=r;f&&(!b||f.e?(f.length!=d.length&&l(Error("Mismatch between points and point colors.")),e=this.a.createBuffer(),f.ob(),this.a.bindBuffer(this.a.ARRAY_BUFFER,e),this.a.bufferData(this.a.ARRAY_BUFFER,f.Q,this.a.STATIC_DRAW),e=new dg(e,f.count,3),f.e=s):e=this.ic.get(c));wf(this.J,0.2);b&&(p&&p.e)&&(f=this.qc.get(c),f!=r&&this.a.isBuffer(f.B)&&this.a.deleteBuffer(f.B));f=r;p&&(f=p.Fc,!b||p.e?(f.length!=d.length&&l(Error("Mismatch between points and scalars.")), +d=this.a.createBuffer(),this.a.bindBuffer(this.a.ARRAY_BUFFER,d),this.a.bufferData(this.a.ARRAY_BUFFER,f,this.a.STATIC_DRAW),f=new dg(d,f.length,3),p.e=s):f=this.qc.get(c));wf(this.J,0.1);b||this.Za.add(a);this.Hb.set(c,j);this.wd.set(c,g);this.ic.set(c,e);this.xc.set(c,h);this.qc.set(c,f);this.ud=a.e=s}}else a.e=s}};function Dg(a,b){var c=b.j.od,c=I.d.Ta(b.Pa.ha,c[0],c[1],c[2]),c=I.d.Ta(a.r.p,c.x,c.y,c.b),c=I.f.kb(a.r.ya,c);return Math.round(1E3*c)/1E3} +w.Fg=function(a,b){if(this.I.PICKING_ENABLED){this.Mb(q,s);var c=new Uint8Array(4);this.a.readPixels(a,this.F-b,1,1,this.a.RGBA,this.a.UNSIGNED_BYTE,c);return c[0]+255*c[1]+65025*c[2]}return-1}; +w.Mb=function(a,b){Cg.q.Mb.call(this,a,b);this.a.viewport(0,0,this.K,this.F);this.a.clear(this.a.COLOR_BUFFER_BIT|this.a.DEPTH_BUFFER_BIT);var c=this.Za.u,d=c.length;if(0!=d){a?this.a.bindFramebuffer(this.a.FRAMEBUFFER,this.Kf):this.a.bindFramebuffer(this.a.FRAMEBUFFER,r);var e=this.r.Jf,f=this.r.p;this.a.uniformMatrix4fv(this.Vc.get("perspective"),s,e);this.a.uniformMatrix4fv(this.Vc.get("view"),s,f);e=this.o;this.a.uniform3f(this.Vc.get("center"),parseFloat(e[0]),parseFloat(e[1]),parseFloat(e[2])); +f=this.Ka.length;for(e=0;em||m>=u||0>p||p>=v)return r;c[e]=m;c[x]=p;return c}; +w.Mb=function(a,b){Eg.q.Mb.call(this,a,b);if(0!=this.Za.u.length){var c=this.K,d=this.F,e=this.r.p;this.a.save();this.a.clearRect(-c,-d,2*c,2*d);this.a.restore();var f=1*e[12],g=-1*e[13],h=Math.max(e[14],0.6);this.a.setTransform(h,0,0,h,0,0);var e=this.Ka[0],j=r;e.P&&(j=e.P.ze);var k=this.Wb,m=r,m=0==k?e.indexX:1==k?e.indexY:e.indexZ,p=this.Uc[parseInt(m,10)],u=p.za.Yb,p=p.P,x=r;p&&(x=p.Yb);var v=this.Bd,z=this.Ad,F=this.zf,E=this.Bf,H=F.getImageData(0,0,v,z),B=E.getImageData(0,0,v,z),G=H.data,J= +B.data,U=G.length,N=e.Oa,K=e.G,O=e.$,R=e.U,S=e.V,V=e.X/O,ja=e.W/O;if(this.xf!=m||this.U!=R||this.V!=S||this.X!=V||this.W!=ja||j&&!Hf(j,this.Cf,0)){var A=0;do{var T=[0,0,0,0],ha=[0,0,0,0],Ca=u[A]/255*O,gb=u[A],gb=(gb/255-V)/(ja-V),gb=255*gb;Ca>=R&&Ca<=S&&(T=new Q(e.Cb[0],e.Cb[1],e.Cb[2]),T=(new Q(e.Ab[0],e.Ab[1],e.Ab[2])).scale(gb).add(T.scale(255-gb)),T=[Math.floor(T.x),Math.floor(T.y),Math.floor(T.b),255],p&&(-255==j[3]?ha=[x[A],x[A+1],x[A+2],x[A+3]]:Hf(j,x,A)&&(ha=[x[A],x[A+1],x[A+2],x[A+3]]))); +var Ca=k,mc=(Ca+1)%3,Od=(Ca+2)%3,gb=A,hb=N[Ca],Rb=N[mc];0!=K[Od][0]?0!=K[2][1]?(A=4*(A/4%z*v+Math.floor(A/4/z)),hb=-N[mc],Rb=N[Ca]):hb*=-1:(0!=K[Od][1]?0==K[2][1]&&(A=4*(A/4%z*v+Math.floor(A/4/z)),hb=N[mc],Rb=N[Ca]):0!=K[2][1]&&(A=4*(A/4%z*v+Math.floor(A/4/z)),hb=N[mc],Rb=N[Ca]),this.yd&&(hb*=-1));1==hb?(1==Rb&&(A=4*v*(z-Math.floor(A/(4*v)))+A%(4*v)),G[A]=T[0],G[A+1]=T[1],G[A+2]=T[2],G[A+3]=T[3],J[A]=ha[0],J[A+1]=ha[1],J[A+2]=ha[2],J[A+3]=ha[3]):1==Rb?(A=U-1-A,G[A-3]=T[0],G[A-2]=T[1],G[A-1]=T[2], +G[A]=T[3],J[A-3]=ha[0],J[A-2]=ha[1],J[A-1]=ha[2],J[A]=ha[3]):(A=4*v*Math.floor(A/(4*v))-A%(4*v),G[A]=T[0],G[A+1]=T[1],G[A+2]=T[2],G[A+3]=T[3],J[A]=ha[0],J[A+1]=ha[1],J[A+2]=ha[2],J[A+3]=ha[3]);A=gb+4}while(A Date: Sat, 22 Jun 2013 13:27:21 -0400 Subject: [PATCH 05/53] ENH: Added the capbility of adding or removing a tract from the viz --- scripts/tract_querier | 26 +- tract_querier/tornado_server/__init__.py | 51 +- .../css/jquery-ui-1.9.2.custom.css | 466 ++++++++++++++++++ tract_querier/tornado_server/css/viewer.css | 3 + tract_querier/tornado_server/index.html | 14 +- tract_querier/tornado_server/js/wmqlviz.js | 68 ++- 6 files changed, 587 insertions(+), 41 deletions(-) create mode 100644 tract_querier/tornado_server/css/jquery-ui-1.9.2.custom.css diff --git a/scripts/tract_querier b/scripts/tract_querier index 5b2b320..a6a63e1 100644 --- a/scripts/tract_querier +++ b/scripts/tract_querier @@ -195,26 +195,43 @@ def main(): query_name, tr, options, {query_name: query_result}, extension=tractography_extension, extra_kwargs=tractography_extra_kwargs ) + query_del = None else: + import urllib def query_save(query_name, query_result): - import urllib filename = save_query( query_name, tr, options, {query_name: query_result}, extension=tractography_extension, extra_kwargs=tractography_extra_kwargs ) if filename is not None: try: - params = urllib.urlencode({'file': filename}) + params = urllib.urlencode({ + 'name': query_name, + 'file': filename, + 'action': 'add' + }) f = urllib.urlopen(options.interactive_url, params) f.close() except Exception, e: print "Interactive URL error:", e return filename + def query_del(query_name): + try: + params = urllib.urlencode({ + 'name': query_name, + 'action': 'remove' + }) + f = urllib.urlopen(options.interactive_url, params) + f.close() + except Exception, e: + print "Interactive URL error:", e + interactive_shell = tract_querier.TractQuerierCmd( tractography_spatial_indexing, initial_body=query_script, save_query_callback=query_save, + del_query_callback=query_del, eof_callback=kill_server_callback, include_folders=folders ) @@ -277,7 +294,8 @@ def activate_webserver(options): import os from multiprocessing import Process from tract_querier import tornado_server - + from uuid import uuid4 + suffix = str(uuid4()).replace('-', '') options.interactive = True if options.interactive_url is None: @@ -292,7 +310,7 @@ def activate_webserver(options): 'colortable': options.interactive_colortable, 'port': 9999, 'files_path': os.getcwd(), - + 'suffix': suffix } ) diff --git a/tract_querier/tornado_server/__init__.py b/tract_querier/tornado_server/__init__.py index e65b219..cd7c2d1 100644 --- a/tract_querier/tornado_server/__init__.py +++ b/tract_querier/tornado_server/__init__.py @@ -1,5 +1,6 @@ import os import sys +import json import tornado.ioloop import tornado.web @@ -34,12 +35,14 @@ def initialize( self, host=None, port=None, path=None, filename=None, colortable=None, + suffix='', websocketsuffix='ws'): self.filename = filename self.colortable = colortable self.host = host self.port = port self.path = path + self.suffix = suffix self.websocketsuffix = websocketsuffix def get(self): @@ -51,40 +54,64 @@ def get(self): 'port': self.port, 'websocketsuffix': self.websocketsuffix }, - filename=self.filename, colortable=self.colortable + filename=self.filename, colortable=self.colortable, + suffix=self.suffix ) class AtlasHandler(tornado.web.StaticFileHandler): def initialize( self, - filename=None, colortable=None, + filename=None, colortable=None, suffix='' ): super(AtlasHandler, self).initialize('/') self.filename = filename self.colortable = colortable + self.suffix = suffix def get(self, args): - print "GETTING", args - if args == 'atlas.nii.gz': + if args == 'atlas_%s.nii.gz' % self.suffix: super(AtlasHandler, self).get(self.filename) - elif args == 'colortable.txt': + elif args == 'colortable_%s.txt' % self.suffix: super(AtlasHandler, self).get(self.colortable) else: raise ValueError("Unidentified file") +class NoCacheStaticHandler(tornado.web.StaticFileHandler): + """ Request static file handlers for development and debug only. + It disables any caching for static file. + """ + def set_extra_headers(self, path): + self.set_header('Cache-Control', 'no-cache') + #self.set_header('Expires', '0') + #now = datetime.datetime.now() + #expiration = datetime.datetime(now.year - 1, now.month, now.day) + #self.set_header('Last-Modified', expiration) + + class TractHandler(tornado.web.RequestHandler): + def initialize(self): + self.json_encoder = json.JSONEncoder() + def post(self): try: - arg = self.get_argument("file") + action = { + 'action': self.get_argument('action'), + 'name': self.get_argument('name') + } + + if action['action'] == 'add': + action['file'] = self.get_argument("file") + + action_json = self.json_encoder.encode(action) for client in websocket_clients: - client.write_message(arg) + client.write_message(action_json) except Exception, e: print e -def xtk_server(atlas, colortable=None, port=9999, files_path=None): +def xtk_server(atlas, colortable=None, port=9999, files_path=None, suffix=''): print "Using atlas", atlas global application @@ -107,7 +134,8 @@ def xtk_server(atlas, colortable=None, port=9999, files_path=None): 'host': 'localhost', 'port': 9999, 'path': static_folder, 'filename': atlas, - 'colortable': colortable + 'colortable': colortable, + 'suffix': suffix }), ( r"/static/(.*)", @@ -120,11 +148,12 @@ def xtk_server(atlas, colortable=None, port=9999, files_path=None): r'/atlas/(.*)', AtlasHandler, { 'filename': atlas, - 'colortable': colortable + 'colortable': colortable, + 'suffix': suffix } ), - (r'/files/(.*)', tornado.web.StaticFileHandler, {"path": files_path}) + (r'/files/(.*)', NoCacheStaticHandler, {"path": files_path}) ]) application.listen(port) tornado.ioloop.IOLoop.instance().start() diff --git a/tract_querier/tornado_server/css/jquery-ui-1.9.2.custom.css b/tract_querier/tornado_server/css/jquery-ui-1.9.2.custom.css new file mode 100644 index 0000000..e2631b8 --- /dev/null +++ b/tract_querier/tornado_server/css/jquery-ui-1.9.2.custom.css @@ -0,0 +1,466 @@ +/*! jQuery UI - v1.9.2 - 2013-01-08 +* http://jqueryui.com +* Includes: jquery.ui.core.css, jquery.ui.resizable.css, jquery.ui.selectable.css, jquery.ui.accordion.css, jquery.ui.autocomplete.css, jquery.ui.button.css, jquery.ui.datepicker.css, jquery.ui.dialog.css, jquery.ui.menu.css, jquery.ui.progressbar.css, jquery.ui.slider.css, jquery.ui.spinner.css, jquery.ui.tabs.css, jquery.ui.tooltip.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Verdana%2CArial%2Csans-serif&fwDefault=normal&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=cccccc&bgTextureHeader=03_highlight_soft.png&bgImgOpacityHeader=75&borderColorHeader=aaaaaa&fcHeader=222222&iconColorHeader=222222&bgColorContent=ffffff&bgTextureContent=01_flat.png&bgImgOpacityContent=75&borderColorContent=aaaaaa&fcContent=222222&iconColorContent=222222&bgColorDefault=e6e6e6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=75&borderColorDefault=d3d3d3&fcDefault=555555&iconColorDefault=888888&bgColorHover=dadada&bgTextureHover=02_glass.png&bgImgOpacityHover=75&borderColorHover=999999&fcHover=212121&iconColorHover=454545&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=aaaaaa&fcActive=212121&iconColorActive=454545&bgColorHighlight=fbf9ee&bgTextureHighlight=02_glass.png&bgImgOpacityHighlight=55&borderColorHighlight=fcefa1&fcHighlight=363636&iconColorHighlight=2e83ff&bgColorError=fef1ec&bgTextureError=02_glass.png&bgImgOpacityError=95&borderColorError=cd0a0a&fcError=cd0a0a&iconColorError=cd0a0a&bgColorOverlay=aaaaaa&bgTextureOverlay=01_flat.png&bgImgOpacityOverlay=0&opacityOverlay=30&bgColorShadow=aaaaaa&bgTextureShadow=01_flat.png&bgImgOpacityShadow=0&opacityShadow=30&thicknessShadow=8px&offsetTopShadow=-8px&offsetLeftShadow=-8px&cornerRadiusShadow=8px +* Copyright (c) 2013 jQuery Foundation and other contributors Licensed MIT */ + +/* Layout helpers +----------------------------------*/ +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px; overflow: hidden; padding: 0; position: absolute; width: 1px; } +.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; } +.ui-helper-clearfix:before, .ui-helper-clearfix:after { content: ""; display: table; } +.ui-helper-clearfix:after { clear: both; } +.ui-helper-clearfix { zoom: 1; } +.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); } + + +/* Interaction Cues +----------------------------------*/ +.ui-state-disabled { cursor: default !important; } + + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + + +/* Misc visuals +----------------------------------*/ + +/* Overlays */ +.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; } +.ui-resizable { position: relative;} +.ui-resizable-handle { position: absolute;font-size: 0.1px; display: block; } +.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; } +.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; } +.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; } +.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; } +.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; } +.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; } +.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; } +.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; } +.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}.ui-selectable-helper { position: absolute; z-index: 100; border:1px dotted black; } +.ui-accordion .ui-accordion-header { display: block; cursor: pointer; position: relative; margin-top: 2px; padding: .5em .5em .5em .7em; zoom: 1; } +.ui-accordion .ui-accordion-icons { padding-left: 2.2em; } +.ui-accordion .ui-accordion-noicons { padding-left: .7em; } +.ui-accordion .ui-accordion-icons .ui-accordion-icons { padding-left: 2.2em; } +.ui-accordion .ui-accordion-header .ui-accordion-header-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; } +.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; overflow: auto; zoom: 1; } +.ui-autocomplete { + position: absolute; + top: 0; + left: 0; + cursor: default; +} + +/* workarounds */ +* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */ +.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */ +.ui-button, .ui-button:link, .ui-button:visited, .ui-button:hover, .ui-button:active { text-decoration: none; } +.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */ +button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */ +.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } + +/*button text element */ +.ui-button .ui-button-text { display: block; line-height: 1.4; } +.ui-button-text-only .ui-button-text { padding: .4em 1em; } +.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; } +.ui-button-text-icon-primary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; } +.ui-button-text-icon-secondary .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 2.1em .4em 1em; } +.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; } +/* no icon support for input elements, provide padding by default */ +input.ui-button { padding: .4em 1em; } + +/*button icon element(s) */ +.ui-button-icon-only .ui-icon, .ui-button-text-icon-primary .ui-icon, .ui-button-text-icon-secondary .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; } +.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; } +.ui-button-text-icon-primary .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; } +.ui-button-text-icon-secondary .ui-button-icon-secondary, .ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } +.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; } + +/*button sets*/ +.ui-buttonset { margin-right: 7px; } +.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; } + +/* workarounds */ +button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; display: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left:2px; } +.ui-datepicker .ui-datepicker-next { right:2px; } +.ui-datepicker .ui-datepicker-prev-hover { left:1px; } +.ui-datepicker .ui-datepicker-next-hover { right:1px; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } + +/* with multiple calendars */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; font-size:0em; } + +/* RTL support */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */ +.ui-datepicker-cover { + position: absolute; /*must have*/ + z-index: -1; /*must have*/ + filter: mask(); /*must have*/ + top: -4px; /*must have*/ + left: -4px; /*must have*/ + width: 200px; /*must have*/ + height: 200px; /*must have*/ +}.ui-dialog { position: absolute; top: 0; left: 0; padding: .2em; width: 300px; overflow: hidden; } +.ui-dialog .ui-dialog-titlebar { background: black; padding: .4em 1em; position: relative; } +.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .1em 0; } +.ui-dialog .ui-dialog-titlebar-close { visibility: hidden; position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; } +.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; } +.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; } +.ui-dialog .ui-dialog-content { position: relative; border: 0; padding: .5em 1em; background: url('gfx/b50.png'); overflow: auto; zoom: 1; } +.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; } +.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset { float: right; } +.ui-dialog .ui-dialog-buttonpane button { margin: .5em .4em .5em 0; cursor: pointer; } +.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; } +.ui-draggable .ui-dialog-titlebar { cursor: move; } +.ui-menu { list-style:none; padding: 2px; margin: 0; display:block; outline: none; } +.ui-menu .ui-menu { margin-top: -3px; position: absolute; } +.ui-menu .ui-menu-item { margin: 0; padding: 0; zoom: 1; width: 100%; } +.ui-menu .ui-menu-divider { margin: 5px -2px 5px -2px; height: 0; font-size: 0; line-height: 0; border-width: 1px 0 0 0; } +.ui-menu .ui-menu-item a { text-decoration: none; display: block; padding: 2px .4em; line-height: 1.5; zoom: 1; font-weight: normal; } +.ui-menu .ui-menu-item a.ui-state-focus, +.ui-menu .ui-menu-item a.ui-state-active { font-weight: normal; margin: -1px; } + +.ui-menu .ui-state-disabled { font-weight: normal; margin: .4em 0 .2em; line-height: 1.5; } +.ui-menu .ui-state-disabled a { cursor: default; } + +/* icon support */ +.ui-menu-icons { position: relative; } +.ui-menu-icons .ui-menu-item a { position: relative; padding-left: 2em; } + +/* left-aligned */ +.ui-menu .ui-icon { position: absolute; top: .2em; left: .2em; } + +/* right-aligned */ +.ui-menu .ui-menu-icon { position: static; float: right; } +.ui-progressbar { height:2em; text-align: left; overflow: hidden; } +.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }.ui-slider { position: relative; text-align: left; } +.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 0.8em; height: 1.2em; cursor: default; } +.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; } + +.ui-slider-horizontal { height: .8em; margin-top: 0.2em;} +.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.4em; } +.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; } +.ui-slider-horizontal .ui-slider-range-min { left: 0; } +.ui-slider-horizontal .ui-slider-range-max { right: 0; } + +.ui-slider-vertical { width: .8em; height: 100px; } +.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; } +.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; } +.ui-slider-vertical .ui-slider-range-min { bottom: 0; } +.ui-slider-vertical .ui-slider-range-max { top: 0; }.ui-spinner { position:relative; display: inline-block; overflow: hidden; padding: 0; vertical-align: middle; } +.ui-spinner-input { border: none; background: none; padding: 0; margin: .2em 0; vertical-align: middle; margin-left: .4em; margin-right: 22px; } +.ui-spinner-button { width: 16px; height: 50%; font-size: .5em; padding: 0; margin: 0; text-align: center; position: absolute; cursor: default; display: block; overflow: hidden; right: 0; } +.ui-spinner a.ui-spinner-button { border-top: none; border-bottom: none; border-right: none; } /* more specificity required here to overide default borders */ +.ui-spinner .ui-icon { position: absolute; margin-top: -8px; top: 50%; left: 0; } /* vertical centre icon */ +.ui-spinner-up { top: 0; } +.ui-spinner-down { bottom: 0; } + +/* TR overrides */ +.ui-spinner .ui-icon-triangle-1-s { + /* need to fix icons sprite */ + background-position:-65px -16px; +} +.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */ +.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; } +.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 0; margin: 1px .2em 0 0; border-bottom: 0; padding: 0; white-space: nowrap; } +.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; } +.ui-tabs .ui-tabs-nav li.ui-tabs-active { margin-bottom: -1px; padding-bottom: 1px; } +.ui-tabs .ui-tabs-nav li.ui-tabs-active a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-tabs-loading a { cursor: text; } +.ui-tabs .ui-tabs-nav li a, .ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */ +.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; } +.ui-tooltip { + padding: 8px; + position: absolute; + z-index: 9999; + max-width: 300px; + -webkit-box-shadow: 0 0 5px #aaa; + box-shadow: 0 0 5px #aaa; +} +/* Fades and background-images don't work well together in IE6, drop the image */ +* html .ui-tooltip { + background-image: none; +} +body .ui-tooltip { border-width: 2px; } + +/* Component containers +----------------------------------*/ +.ui-widget { font-family: Verdana,Arial,sans-serif; font-size: 11px; } +.ui-widget .ui-widget { font-size: 1em; } +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Verdana,Arial,sans-serif; font-size: 1em; } +.ui-widget-content { border: 1px solid #aaaaaa; } +.ui-widget-content a { color: #fff; } +.ui-widget-header { background: url('gfx/b50.png'); color: white; font-weight: bold; } +.ui-widget-header a { color: #222222; } + +/* Interaction states +----------------------------------*/ +.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #d3d3d3; background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #555555; } +.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #555555; text-decoration: none; } +.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #999999; background: #dadada url(images/ui-bg_glass_75_dadada_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; } +.ui-state-hover a, .ui-state-hover a:hover, .ui-state-hover a:link, .ui-state-hover a:visited { color: #212121; text-decoration: none; } +.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #aaaaaa; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: normal; color: #212121; +-moz-box-shadow: 0 0 10px #9FC54E; +-webkit-box-shadow: 0 0 10px #9FC54E; +box-shadow: 0 0 10px #9FC54E; +} +.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #212121; text-decoration: none; } + +/* Interaction Cues +----------------------------------*/ +.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fcefa1; background: #fbf9ee url(images/ui-bg_glass_55_fbf9ee_1x400.png) 50% 50% repeat-x; color: #363636; } +.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } +.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #fef1ec url(images/ui-bg_glass_95_fef1ec_1x400.png) 50% 50% repeat-x; color: #cd0a0a; } +.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #cd0a0a; } +.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #cd0a0a; } +.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; } +.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; } +.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; } +.ui-state-disabled .ui-icon { filter:Alpha(Opacity=35); } /* For IE8 - See #6059 */ + +/* Icons +----------------------------------*/ + +/* states and images */ +.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(images/ui-icons_888888_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-active .ui-icon {background-image: url(images/ui-icons_454545_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_2e83ff_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_cd0a0a_256x240.png); } + +/* positioning */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-on { background-position: -96px -144px; } +.ui-icon-radio-off { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + + +/* Misc visuals +----------------------------------*/ + +/* Corner radius */ +.ui-corner-all, .ui-corner-top, .ui-corner-left, .ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; -khtml-border-top-left-radius: 4px; border-top-left-radius: 4px; } +.ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; -khtml-border-top-right-radius: 4px; border-top-right-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-left, .ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; -khtml-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; } +.ui-corner-all, .ui-corner-bottom, .ui-corner-right, .ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; -khtml-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; } + +/* Overlays */ +.ui-widget-overlay { background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .3;filter:Alpha(Opacity=30); } +.ui-widget-shadow { margin: -8px 0 0 -8px; padding: 8px; background: #aaaaaa url(images/ui-bg_flat_0_aaaaaa_40x100.png) 50% 50% repeat-x; opacity: .3;filter:Alpha(Opacity=30); -moz-border-radius: 8px; -khtml-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; } \ No newline at end of file diff --git a/tract_querier/tornado_server/css/viewer.css b/tract_querier/tornado_server/css/viewer.css index b2b2837..a65086d 100644 --- a/tract_querier/tornado_server/css/viewer.css +++ b/tract_querier/tornado_server/css/viewer.css @@ -59,3 +59,6 @@ opacity: 0.5; } +#anatomy_caption { + font-family:"Helvetica"; +} diff --git a/tract_querier/tornado_server/index.html b/tract_querier/tornado_server/index.html index fa3a936..5ccee03 100644 --- a/tract_querier/tornado_server/index.html +++ b/tract_querier/tornado_server/index.html @@ -4,10 +4,12 @@ -Test +White Matter Query Language Vizualization - + + + @@ -16,17 +18,13 @@ - - - - + diff --git a/tract_querier/tornado_server/js/wmqlviz.js b/tract_querier/tornado_server/js/wmqlviz.js index 02308dc..65b3838 100644 --- a/tract_querier/tornado_server/js/wmqlviz.js +++ b/tract_querier/tornado_server/js/wmqlviz.js @@ -100,17 +100,18 @@ function on2DHover(renderer) { // get cursor position var mousepos = renderer.interactor.mousePosition; var ijk = renderer.xy2ijk(mousepos[0], mousepos[1]); + console.info(ijk) if (!ijk) { return; } // var orientedIJK = ijk.slice(); - orientedIJK[0] = ijk[2]; + orientedIJK[0] = ijk[0]; orientedIJK[1] = ijk[1]; - orientedIJK[2] = ijk[0]; + orientedIJK[2] = ijk[2]; - var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; + var volume = _ATLAS_.currentVolume; // get the number associated with the label var labelvalue = volume.labelmap.image[orientedIJK[0]][orientedIJK[1]][orientedIJK[2]]; @@ -133,9 +134,9 @@ sliceZ = null; function init_volume(filename, colortable) { volume = new X.volume(); - volume.file = filename; //'MNI152_T1_1mm_brain.nii.gz'; - volume.labelmap.file = filename; //'MNI152_wmparc_1mm_small.nii.gz'; - volume.labelmap.colortable.file = colortable; //'FreeSurferColorLUT.txt'; + volume.file = filename; + volume.labelmap.file = filename; + volume.labelmap.colortable.file = colortable; _ATLAS_ = {}; _ATLAS_.volumes = {}; @@ -152,7 +153,7 @@ function init_volume(filename, colortable) { function init_websocket(host) { console.info("websocket start"); - _fibers_ = {}; + _tracts_ = {}; $(document).ready(function () { _WS_ = new WebSocket(host); @@ -162,16 +163,37 @@ function init_websocket(host) { }; _WS_.onmessage = function(evt){ - console.info(evt.data) - - if (evt.data in _fibers_) { - console.info("Removing tract " + evt.data); - render3D.remove(_fibers_[evt.data]); - }; - - _fibers_[evt.data] = new X.fibers() - _fibers_[evt.data].file = 'files/' + evt.data - render3D.add(_fibers_[evt.data]) + var tract = JSON.parse(evt.data); + var name = tract['name']; + var file = tract['file']; + var action = tract['action']; + if (action == 'add') { + if (name in _tracts_) { + console.info("Removing tract " + name); + _tracts_gui_.remove(_tracts_[name].control); + render3D.remove(_tracts_[name]); + }; + + delete _tracts_[name]; + + _tracts_[name] = new X.fibers(); + _tracts_[name].file = 'files/' + file; + _tracts_[name].caption = name; + + _tracts_[name].control = _tracts_gui_.add(_tracts_[name], 'visible'); + _tracts_[name].control.name(name); + + render3D.add(_tracts_[name]); + } + + if (action == 'remove') { + if (name in _tracts_) { + console.info("Removing tract " + name); + _tracts_gui_.remove(_tracts_[name].control); + render3D.remove(_tracts_[name]); + delete _tracts_[name]; + } + } }; _WS_.onclose = function () { console.info("connection closed"); @@ -187,7 +209,17 @@ window.onload = function() { render3D.onShowtime = function() { init_viewer2d(); - } + }; + + // The GUI panel + + // indicate if the mesh was loaded + var gui = new dat.GUI(); + + var labelmapgui = gui.addFolder('Label Map'); + var labelMapVisibleController = labelmapgui.add(_ATLAS_.currentVolume, 'visible'); + + _tracts_gui_ = gui.addFolder('Tracts'); render3D.add(_ATLAS_.currentVolume) render3D.render(); From 585853d4e99048f0631109427726171746af1599 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Mon, 1 Jul 2013 13:58:43 -0400 Subject: [PATCH 06/53] ENH: Online refreshing works --- tract_querier/tornado_server/js/wmqlviz.js | 29 ++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/tract_querier/tornado_server/js/wmqlviz.js b/tract_querier/tornado_server/js/wmqlviz.js index 65b3838..a04aed0 100644 --- a/tract_querier/tornado_server/js/wmqlviz.js +++ b/tract_querier/tornado_server/js/wmqlviz.js @@ -1,3 +1,4 @@ +/* $(function() { // create the sliders for the 2D sliders @@ -17,7 +18,7 @@ $(function() { $("#green_slider .ui-slider-handle").unbind('keydown'); }); - +*/ function init_viewer2d() { var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; @@ -74,19 +75,23 @@ function init_viewer2d() { }; // update 2d slice sliders + /* var dim = volume.dimensions; $("#yellow_slider").slider("option", "disabled", false); $("#yellow_slider").slider("option", "min", 0); $("#yellow_slider").slider("option", "max", dim[0] - 1); $("#yellow_slider").slider("option", "value", volume.indexX); + $("#red_slider").slider("option", "disabled", false); $("#red_slider").slider("option", "min", 0); - $("#red_slider").slider("option", "max", dim[1] - 1); - $("#red_slider").slider("option", "value", volume.indexY); + $("#red_slider").slider("option", "max", dim[2] - 1); + $("#red_slider").slider("option", "value", volume.indexZ); + $("#green_slider").slider("option", "disabled", false); $("#green_slider").slider("option", "min", 0); - $("#green_slider").slider("option", "max", dim[2] - 1); - $("#green_slider").slider("option", "value", volume.indexZ); + $("#green_slider").slider("option", "max", dim[1] - 1); + $("#green_slider").slider("option", "value", volume.indexY); + */ }//init_viewer2d() // show labels on hover @@ -107,9 +112,9 @@ function on2DHover(renderer) { // var orientedIJK = ijk.slice(); - orientedIJK[0] = ijk[0]; - orientedIJK[1] = ijk[1]; - orientedIJK[2] = ijk[2]; + orientedIJK[0] = ijk[1]; + orientedIJK[1] = ijk[2]; + orientedIJK[2] = ijk[0]; var volume = _ATLAS_.currentVolume; @@ -123,8 +128,9 @@ function on2DHover(renderer) { var _r = parseInt(volume.labelmap.colortable.get(labelvalue)[1] * 255, 10); var _g = parseInt(volume.labelmap.colortable.get(labelvalue)[2] * 255, 10); var _b = parseInt(volume.labelmap.colortable.get(labelvalue)[3] * 255, 10); - $('#anatomy_caption').html(labelname); - $('#anatomy_caption').css('color', 'rgb( ' + _r + ',' + _g + ',' + _b + ' )' ); + $('#anatomy_caption').html(""); + //$('#anatomy_caption').html(labelname); + //$('#anatomy_caption').css('color', 'rgb( ' + _r + ',' + _g + ',' + _b + ' )' ); } @@ -183,7 +189,10 @@ function init_websocket(host) { _tracts_[name].control = _tracts_gui_.add(_tracts_[name], 'visible'); _tracts_[name].control.name(name); + _tracts_[name].modified(); + render3D.add(_tracts_[name]); + } if (action == 'remove') { From 42b39886311a9894b97393d571f7a89025da5108 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Tue, 2 Jul 2013 11:33:57 -0400 Subject: [PATCH 07/53] ENH: freesurfer_queries.qry --- tract_querier/data/freesurfer_queries.qry | 169 +++++++++++++++++++++- 1 file changed, 167 insertions(+), 2 deletions(-) diff --git a/tract_querier/data/freesurfer_queries.qry b/tract_querier/data/freesurfer_queries.qry index c63c231..cfb857a 100644 --- a/tract_querier/data/freesurfer_queries.qry +++ b/tract_querier/data/freesurfer_queries.qry @@ -67,13 +67,111 @@ inferior_frontal_gyrus.side |= parsopercularis.side or parstriangularis.side or middle_frontal_gyrus.side |= caudalmiddlefrontal.side or rostralmiddlefrontal.side -internal_capsule.side = ((frontal.side and thalamus_proper.side and (parietal.side or occipital.side)) + +#Commisural tracts +#cc_bankssts = endpoints_in(bankssts.left) and endpoints_in(bankssts.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_caudalanteriorcingulate = endpoints_in(caudalanteriorcingulate.left) and endpoints_in(caudalanteriorcingulate.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_cuneus = endpoints_in(cuneus.left) and endpoints_in(cuneus.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_entorhinal = endpoints_in(entorhinal.left) and endpoints_in(entorhinal.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_fusiform = endpoints_in(fusiform.left) and endpoints_in(fusiform.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_inferiorparietal = endpoints_in(inferiorparietal.left) and endpoints_in(inferiorparietal.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_inferiortemporal = endpoints_in(inferiortemporal.left) and endpoints_in(inferiortemporal.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_isthmuscingulate = endpoints_in(isthmuscingulate.left) and endpoints_in(isthmuscingulate.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_lateraloccipital = endpoints_in(lateraloccipital.left) and endpoints_in(lateraloccipital.right) not in subcortical.left not in subcortical.right not in cerebellum + +#cc_lingual = endpoints_in(lingual.left) and endpoints_in(lingual.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_parahippocampal = endpoints_in(parahippocampal.left) and endpoints_in(parahippocampal.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_paracentral = endpoints_in(paracentral.left) and endpoints_in(paracentral.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_parsopercularis = endpoints_in(parsopercularis.left) and endpoints_in(parsopercularis.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_parsorbitalis = endpoints_in(parsorbitalis.left) and endpoints_in(parsorbitalis.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_parstriangularis = endpoints_in(parstriangularis.left) and endpoints_in(parstriangularis.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_pericalcarine = endpoints_in(pericalcarine.left) and endpoints_in(pericalcarine.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_postcentral = endpoints_in(postcentral.left) and endpoints_in(postcentral.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_posteriorcingulate = endpoints_in(posteriorcingulate.left) and endpoints_in(posteriorcingulate.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_precentral = endpoints_in(precentral.left) and endpoints_in(precentral.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_precuneus = endpoints_in(precuneus.left) and endpoints_in(precuneus.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_rostralanteriorcingulate = endpoints_in(rostralanteriorcingulate.left) and endpoints_in(rostralanteriorcingulate.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_superiorparietal = endpoints_in(superiorparietal.left) and endpoints_in(superiorparietal.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_supramarginal = endpoints_in(supramarginal.left) and endpoints_in(supramarginal.right) not in subcortical.left not in subcortical.right not in cerebellum +#cc_insula = endpoints_in(insula.left) and endpoints_in(insula.right) not in subcortical.left not in subcortical.right not in cerebellum + +#Temporal Transcallosal +#cc_middletemporal = middletemporal.left and middletemporal.right not in subcortical.left not in subcortical.right not in cerebellum +#cc_superiortemporal = superiortemporal.left and superiortemporal.right not in subcortical.left not in subcortical.right not in cerebellum +#cc_temporalpole = temporalpole.left and temporalpole.right not in subcortical.left not in subcortical.right not in cerebellum +#cc_transversetemporal = transversetemporal.left and transversetemporal.right not in subcortical.left not in subcortical.right not in cerebellum + +#Frontal corpus callosum +#cc_caudalmiddlefrontal = caudalmiddlefrontal.left and caudalmiddlefrontal.right not in subcortical.left not in subcortical.right not in cerebellum not in temporal.right not in temporal.left not in parietal.right not in parietal.left not in occipital.right not in occipital.left +#cc_lateralorbitofrontal = lateralorbitofrontal.left and lateralorbitofrontal.right not in subcortical.left not in subcortical.right not in cerebellum not in temporal.right not in temporal.left not in parietal.right not in parietal.left not in occipital.right not in occipital.left +#cc_medialorbitofrontal = medialorbitofrontal.left and medialorbitofrontal.right not in subcortical.left not in subcortical.right not in cerebellum not in temporal.right not in temporal.left not in parietal.right not in parietal.left not in occipital.right not in occipital.left +#cc_rostralmiddlefrontal = rostralmiddlefrontal.left and rostralmiddlefrontal.right not in subcortical.left not in subcortical.right not in cerebellum not in temporal.right not in temporal.left not in parietal.right not in parietal.left not in occipital.right not in occipital.left +#cc_superiorfrontal = superiorfrontal.left and superiorfrontal.right not in subcortical.left not in subcortical.right not in cerebellum not in temporal.right not in temporal.left not in parietal.right not in parietal.left not in occipital.right not in occipital.left +#cc_frontalpole = frontalpole.left and frontalpole.right not in subcortical.left not in subcortical.right not in cerebellum not in temporal.right not in temporal.left not in parietal.right not in parietal.left not in occipital.right not in occipital.left + +##Projection +#thalamo_bankssts.side = endpoints_in(thalamus_proper.side) and endpoints_in(bankssts.side) +#thalamo_caudalanteriorcingulate.side = endpoints_in(thalamus_proper.side) and endpoints_in(caudalanteriorcingulate.side) +#thalamo_cuneus.side = endpoints_in(thalamus_proper.side) and endpoints_in(cuneus.side) +#thalamo_entorhinal.side = endpoints_in(thalamus_proper.side) and endpoints_in(entorhinal.side) +#thalamo_fusiform.side = endpoints_in(thalamus_proper.side) and endpoints_in(fusiform.side) +#thalamo_inferiorparietal.side = endpoints_in(thalamus_proper.side) and endpoints_in(inferiorparietal.side) +#thalamo_inferiortemporal.side = endpoints_in(thalamus_proper.side) and endpoints_in(inferiortemporal.side) +#thalamo_isthmuscingulate.side = endpoints_in(thalamus_proper.side) and endpoints_in(isthmuscingulate.side) +#thalamo_lateraloccipital.side = endpoints_in(thalamus_proper.side) and endpoints_in(lateraloccipital.side) + +#thalamo_lingual.side = endpoints_in(thalamus_proper.side) and endpoints_in(lingual.side) +#thalamo_parahippocampal.side = endpoints_in(thalamus_proper.side) and endpoints_in(parahippocampal.side) +#thalamo_paracentral.side = endpoints_in(thalamus_proper.side) and endpoints_in(paracentral.side) +#thalamo_parsopercularis.side = endpoints_in(thalamus_proper.side) and endpoints_in(parsopercularis.side) +#thalamo_parsorbitalis.side = endpoints_in(thalamus_proper.side) and endpoints_in(parsorbitalis.side) +#thalamo_parstriangularis.side = endpoints_in(thalamus_proper.side) and endpoints_in(parstriangularis.side) +#thalamo_pericalcarine.side = endpoints_in(thalamus_proper.side) and endpoints_in(pericalcarine.side) +#thalamo_postcentral.side = endpoints_in(thalamus_proper.side) and endpoints_in(postcentral.side) +#thalamo_posteriorcingulate.side = endpoints_in(thalamus_proper.side) and endpoints_in(posteriorcingulate.side) +#thalamo_precentral.side = endpoints_in(thalamus_proper.side) and endpoints_in(precentral.side) +#thalamo_precuneus.side = endpoints_in(thalamus_proper.side) and endpoints_in(precuneus.side) +#thalamo_rostralanteriorcingulate.side = endpoints_in(thalamus_proper.side) and endpoints_in(rostralanteriorcingulate.side) +#thalamo_superiorparietal.side = endpoints_in(thalamus_proper.side) and endpoints_in(superiorparietal.side) +#thalamo_supramarginal.side = endpoints_in(thalamus_proper.side) and endpoints_in(supramarginal.side) +#thalamo_insula.side = endpoints_in(thalamus_proper.side) and endpoints_in(insula.side) + +##Temporal thalamical +#thalamo_middletemporal.side = endpoints_in(thalamus_proper.side) and endpoints_in(middletemporal.side) +#thalamo_superiortemporal.side = endpoints_in(thalamus_proper.side) and endpoints_in(superiortemporal.side) +#thalamo_temporalpole.side = endpoints_in(thalamus_proper.side) and endpoints_in(temporalpole.side) +#thalamo_transversetemporal.side = endpoints_in(thalamus_proper.side) and endpoints_in(transversetemporal.side) + +##Frontal thalamical +#thalamo_caudalmiddlefrontal.side = endpoints_in(thalamus_proper.side) and endpoints_in(caudalmiddlefrontal.side) +#thalamo_lateralorbitofrontal.side = endpoints_in(thalamus_proper.side) and endpoints_in(lateralorbitofrontal.side) +#thalamo_medialorbitofrontal.side = endpoints_in(thalamus_proper.side) and endpoints_in(medialorbitofrontal.side) +#thalamo_rostralmiddlefrontal.side = endpoints_in(thalamus_proper.side) and endpoints_in(rostralmiddlefrontal.side) +#thalamo_superiorfrontal.side = endpoints_in(thalamus_proper.side) and endpoints_in(superiorfrontal.side) +#thalamo_frontalpole.side = endpoints_in(thalamus_proper.side) and endpoints_in(frontalpole.side) + +#ioff.side |= ((frontal.side and occipital.side) +# not in cingular.side +# not in precentral.side not in postcentral.side +# not in hemisphere.opposite) + + +internal_capsule_new.side = ((frontal.side and thalamus_proper.side and (parietal.side or occipital.side)) not in cingular.side not in precentral.side not in postcentral.side not in hemisphere.opposite not in brain_stem ) + +#ioff_dorsal_claustrum.side = ((frontal.side and superiorparietal.side and putamen.side) +# not in cingular.side +# not in precentral.side not in postcentral.side +# not in superiorfrontal.side +# not in hemisphere.opposite) + + +#cst_pre_dirty.side = (precentral.side and brain_stem) cst_pre.side |= ((precentral.side and brain_stem) not in superiorfrontal.side not in cerebellum_white_matter.side not in thalamus_proper.side @@ -86,6 +184,7 @@ cst_post.side |= ((postcentral.side and brain_stem) cst.side = cst_pre.side or cst_post.side +# cb updated per nikos' suggestion - done cb.side = only((cingular.side or cingular_cortex.side) and (middle_frontal_gyrus.side or cuneus.side or entorhinal.side or superiorfrontal.side or inferiorparietal.side or fusiform.side or medialorbitofrontal.side or lateralorbitofrontal.side or unsegmentedwhitematter.side or parahippocampal.side or precuneus.side or lingual.side)) ioff.side = ( @@ -97,7 +196,16 @@ ioff.side = ( not in hemisphere.opposite ) -uf.side = ( +soff.side = ( + (lateralorbitofrontal.side and occipital.side) + not in temporal.side + not in subcortical.side + not in cingular.side + not in hemisphere.opposite +) + +# updated uf per nikos' suggestions by adding a general definition for the middle_frontal_gyrus.side and inferior_frontal_gyrus.side and adding them to UF definition, also added IOFF as exclusion +UF.side = ( ( (orbitofrontalgyrus.side or middle_frontal_gyrus.side or inferior_frontal_gyrus.side) and endpoints_in(temporalpole.side) @@ -108,6 +216,9 @@ uf.side = ( not in HEMISPHERE.opposite) +#IOFF_section.side = ((medialorbitofrontal.side or lateralorbitofrontal.side or middle_frontal_gyrus.side or inferior_frontal_gyrus.side) and temporalpole.side and inferiortemporal.side) not in ioff.side not in ec.side not in subcortical.side not in hemisphere.opposite not in cingular.side not in occipital.side not in parietal.side not in superiorfrontal.side not in precentral.side + +# need to make it continuous but otherwise OK MDLF.side = only( ( temporalpole.side or superiortemporal.side @@ -136,6 +247,10 @@ ec.side = ( not in cingular.side ) + + + +#SLF_I and SLF_II_III should be extended further back if possible SLF_I.side = ( ((superiorparietal.side and precuneus.side and superiorfrontal.side) or (superiorparietal.side and precuneus.side and superiorfrontal.side @@ -166,6 +281,11 @@ extreme_capsule.side = (((superiortemporal.side or temporalpole.side) not in HEMISPHERE.opposite ) + + + + + #Commisural tracts CC = ( ( @@ -177,6 +297,29 @@ CC = ( (corpuscallosum.left or corpuscallosum.right) ) + +#AC = ( +# (temporalpole.left and temporalpole.right) or +# (middletemporal.left and middletemporal.right) or +# (inferiortemporal.left and inferiortemporal.right) or +# (Amygdala.left and Amygdala.right) +# not in (corpuscallosum.left or corpuscallosum.right) +# ) + +#DHC = ( +# parahippocampal.left and parahippocampal.right +# not in (corpuscallosum.left or corpuscallosum.right) +# ) + +internal_capsule.side |= ((rostralmiddlefrontal.side and temporal.side and Putamen.side and UnsegmentedWhiteMatter.side) + not in occipital.side not in corpus_callosum not in cerebellum + +not in HEMISPHERE.opposite + not in subcortical.side not in cingular.side) + + +mdlf_probable_sections.side |= only( (precentral.side or paracentral.side or postcentral.side or superiorparietal.side) and unsegmentedwhitematter.side and temporal.side) + af.side = ( (inferior_frontal_gyrus.side or middle_frontal_gyrus.side or precentral.side) and (superiortemporal.side or middletemporal.side) not in hemisphere.opposite @@ -187,6 +330,28 @@ af.side = ( not in parstriangularis.side not in superiorfrontal.side not in parsopercularis.side ) +#AF.side = (( (inferior_frontal_gyrus.side or middle_frontal_gyrus.side or precentral.side) +# and (superiortemporal.side or middletemporal.side)) +# not in SLF_II_III.side not in MDLF.side not in IOFF.side not in ILF.side +# not in extreme_capsule.side +# not in wm_unknown.side not in UnsegmentedWhiteMatter.side +# not in occipital.side not in temporalpole.side not in medialorbitofrontal.side +# not in lateralorbitofrontal.side +#) + + +#Projection fibers +#Optic_Radiation = ( +# +#) + +#EC.side = ( +# (caudalanteriorcingulate.side or rostralanteriorcingulate.side) and (superiortemporal.side) +# not in HEMISPHERE.opposite not in temporalpole.side +# not in ventricles +# not in posteriorcingulate.side +#) + thalamo_frontal.side = endpoints_in(thalamus_proper.side) and endpoints_in(frontal.side) thalamo_parietal.side = endpoints_in(thalamus_proper.side) and endpoints_in(parietal.side) thalamo_occipital.side = endpoints_in(thalamus_proper.side) and endpoints_in(occipital.side) From 264559b19af19312fce94a881d54c2bb6d1d1624 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Tue, 2 Jul 2013 14:44:26 -0400 Subject: [PATCH 08/53] ENH: Added the requirements for the tornado server --- requirements.txt | 1 + setup.py | 13 +++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/requirements.txt b/requirements.txt index bd7a2a8..68365a7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ numpy>=1.6 nose>=1.2 nibabel>=1.3 +tornado>=3.1 diff --git a/setup.py b/setup.py index 32f0804..f9eb675 100644 --- a/setup.py +++ b/setup.py @@ -24,6 +24,14 @@ def configuration(parent_package='', top_path=None): if __name__ == "__main__": + requires = open('requirements.txt').readlines() + for i, req in enumerate(requires): + req = req.strip() + if '>' in req: + req = req.replace('>', '(>') + req += ')' + requires[i] = req + setup( name=DISTNAME, maintainer=MAINTAINER, @@ -34,10 +42,7 @@ def configuration(parent_package='', top_path=None): version=VERSION, download_url=DOWNLOAD_URL, long_description=LONG_DESCRIPTION, - requires=[ - 'numpy(>=1.6)', - 'nibabel(>=1.3)' - ], + requires=requires, classifiers=[ 'Intended Audience :: Science/Research', 'Programming Language :: Python', From 3277672362962d574effe247cbd3673d679df9b5 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Tue, 2 Jul 2013 15:03:22 -0400 Subject: [PATCH 09/53] ENH: Port number configuration for the webserver --- scripts/tract_querier | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/scripts/tract_querier b/scripts/tract_querier index a6a63e1..1f00892 100644 --- a/scripts/tract_querier +++ b/scripts/tract_querier @@ -50,7 +50,13 @@ def main(): ) parser.add_option( '--interactive-webdisplay-url', dest='interactive_url', - help='Enables interactive display of the results' + help='Server port for the interactive display of the results: default: http://localhost:9999', + ) + + parser.add_option( + '--interactive-webdisplay-port', dest='interactive_port', + help='Server port for the interactive display of the results: default $(default)d', + default=9999 ) (options, args) = parser.parse_args() @@ -298,17 +304,19 @@ def activate_webserver(options): suffix = str(uuid4()).replace('-', '') options.interactive = True + options.interactive_port = int(options.interactive_port) + if options.interactive_url is None: - options.interactive_url = 'http://localhost:9999/tracts' + options.interactive_url = 'http://localhost:%04d/tracts' % options.interactive_port - print "Starting web server, please direct your browser to http://localhost:%04d" % 9999 + print "Starting web server, please direct your browser to http://localhost:%04d" % options.interactive_port p = Process( target=tornado_server.xtk_server, args=(os.path.abspath(options.atlas_file_name),), kwargs={ 'colortable': options.interactive_colortable, - 'port': 9999, + 'port': options.interactive_port, 'files_path': os.getcwd(), 'suffix': suffix } From 461bff6b329a27ccf226ed938033dcc122e594c6 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 5 Jul 2013 08:17:06 -0400 Subject: [PATCH 10/53] ENH: Corrected path to the main queries for different installation scenarios on the server too --- tract_querier/__init__.py | 7 +++---- tract_querier/tornado_server/__init__.py | 11 +++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/tract_querier/__init__.py b/tract_querier/__init__.py index 4fd38e7..c6d8bc9 100644 --- a/tract_querier/__init__.py +++ b/tract_querier/__init__.py @@ -7,11 +7,10 @@ default_queries_folder = os.path.abspath(os.path.join( - os.path.dirname(__file__), - '..', '..', '..', '..', - 'tract_querier', 'queries' + *([os.path.dirname(__file__)] + ['..'] * 4 + + ['tract_querier', 'queries']) )) - +print default_queries_folder #import tract_metrics __version__ = 0.1 diff --git a/tract_querier/tornado_server/__init__.py b/tract_querier/tornado_server/__init__.py index cd7c2d1..76084ae 100644 --- a/tract_querier/tornado_server/__init__.py +++ b/tract_querier/tornado_server/__init__.py @@ -115,15 +115,22 @@ def xtk_server(atlas, colortable=None, port=9999, files_path=None, suffix=''): print "Using atlas", atlas global application + folder_prefix = os.path.abspath(os.path.join( + *( + [os.path.dirname(__file__)] + + ['..'] * 5 + ) + )) + static_folder = os.path.join( - sys.prefix, + folder_prefix, 'tract_querier', 'tornado_server' ) if colortable is None: print "No color table specified, using FreeSurfer" colortable = os.path.join( - sys.prefix, 'tract_querier', + folder_prefix, 'tract_querier', 'tornado_server', 'FreeSurferColorLUT.txt' ) else: From 874d9e8ff3983c69acc24967f6fb99efd7b7bf6c Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 5 Jul 2013 18:38:27 -0400 Subject: [PATCH 11/53] RFR: Removing debug information --- tract_querier/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tract_querier/__init__.py b/tract_querier/__init__.py index c6d8bc9..dea1db2 100644 --- a/tract_querier/__init__.py +++ b/tract_querier/__init__.py @@ -10,7 +10,6 @@ *([os.path.dirname(__file__)] + ['..'] * 4 + ['tract_querier', 'queries']) )) -print default_queries_folder #import tract_metrics __version__ = 0.1 From 46c6d316e90a6e622406d7340f50031c8b0b20e9 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Sun, 7 Jul 2013 13:23:38 -0400 Subject: [PATCH 12/53] DOC: Added the tensor module to the documentation --- doc/tract_querier.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/tract_querier.rst b/doc/tract_querier.rst index d1bb641..a13378a 100644 --- a/doc/tract_querier.rst +++ b/doc/tract_querier.rst @@ -20,3 +20,4 @@ tract_querier Package query_processor tractography tract_label_indices + tensor From e2fcf550bd25e579654bb5caab5c84185da35d27 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Mon, 8 Jul 2013 16:02:43 -0400 Subject: [PATCH 13/53] BUG: Corrected bug in tract_math to handle several tracts on input --- scripts/tract_math | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/tract_math b/scripts/tract_math index 0773b3b..c5f2dc0 100644 --- a/scripts/tract_math +++ b/scripts/tract_math @@ -37,7 +37,9 @@ def main(): usage += '\t%s %s\n' % (f, operations[f].help_text) #The first arguments, except for the last one, might be tractography files + n_tracts = len([ + tract for tract in itertools.takewhile( lambda x: x not in operations_names, sys.argv[1:-1] ) From 70f14e75abe62ba8e40871dfde99319415bf7777 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Mon, 22 Jul 2013 20:28:25 -0400 Subject: [PATCH 14/53] ENH: Added first attempt at prototype finding --- tract_querier/tract_math/operations.py | 79 +- tract_querier/tract_math/tract_obb.py | 1280 ++++++++++++++++++++++++ 2 files changed, 1353 insertions(+), 6 deletions(-) create mode 100644 tract_querier/tract_math/tract_obb.py diff --git a/tract_querier/tract_math/operations.py b/tract_querier/tract_math/operations.py index 1f58380..2ca5e6e 100644 --- a/tract_querier/tract_math/operations.py +++ b/tract_querier/tract_math/operations.py @@ -1,9 +1,11 @@ from .decorator import tract_math_operation +from warnings import warn + try: - from collections import OrderedDict + from collections import OrderedDict except ImportError: # Python 2.6 fix - from ordereddict import OrderedDict + from ordereddict import OrderedDict import numpy @@ -17,8 +19,8 @@ def count(tractographies): results = {'tract file #': [], 'number of tracts': []} for i, tractography in enumerate(tractographies): - results['tract file #'].append(i) - results['number of tracts'].append(len(tractography.tracts())) + results['tract file #'].append(i) + results['number of tracts'].append(len(tractography.tracts())) return results @@ -167,6 +169,15 @@ def tract_subsample(tractography, points_per_tract, file_output): ) +@tract_math_operation(' : resamples tracts to a fixed number of points') +def tract_resubsample(tractography, points_per_tract, file_output): + tractography.subsample_tracts(int(points_per_tract), True) + + return Tractography( + tractography.tracts(), tractography.tracts_data() + ) + + @tract_math_operation(' : subsamples tracts to a maximum number of points') def tract_remove_short_tracts(tractography, min_tract_length, file_output): @@ -270,8 +281,8 @@ def tract_generate_probability_map(tractographies, image, file_output): prob_map = tract_probability_map(image, tractographies[0]).astype(float) for tract in tractographies[1:]: - if len(tract.tracts()) == 0: - continue + if len(tract.tracts()) == 0: + continue new_prob_map = tract_mask(image, tract) prob_map = prob_map + new_prob_map - (prob_map * new_prob_map) @@ -525,3 +536,59 @@ def tract_in_ijk(image, tractography): numpy.ones((len(ras_points), 1)) )).T).T[:, :-1] return ijk_points + + +@tract_math_operation(': compute the protoype tract') +def tract_prototype_median(tractography, file_output): + from .tract_obb import prototype_tract + + tracts = tractography.tracts() + data = tractography.tracts_data() + prototype_ix = prototype_tract(tracts) + + selected_tracts = [tracts[prototype_ix]] + selected_data = dict() + for key, item in data.items(): + if len(item) == len(tracts): + selected_data_items = [item[prototype_ix]] + selected_data[key] = selected_data_items + else: + selected_data[key] = item + + return Tractography(selected_tracts, selected_data) + + +@tract_math_operation(' : compute the protoype tract') +def tract_prototype_mean(tractography, smooth_order, file_output): + from .tract_obb import prototype_tract + + tracts = tractography.tracts() + prototype_ix, leave_centers = prototype_tract(tracts, return_leave_centers=True) + + median_tract = tracts[prototype_ix] + + mean_tract = numpy.empty_like(median_tract) + centers_used = set() + for point in median_tract: + closest_leave_center_ix = ( + ((leave_centers - point[None, :]) ** 2).sum(1) + ).argmin() + + if closest_leave_center_ix in centers_used: + continue + + mean_tract[len(centers_used)] = leave_centers[closest_leave_center_ix] + centers_used.add(closest_leave_center_ix) + + mean_tract = mean_tract[:len(centers_used)] + + if smooth_order > 0: + try: + from scipy import interpolate + + tck, u = interpolate.splprep(mean_tract.T) + mean_tract = numpy.transpose(interpolate.splev(u, tck)) + except ImportError: + warn("A smooth order larger than 0 needs scipy installed") + + return Tractography([mean_tract], {}) diff --git a/tract_querier/tract_math/tract_obb.py b/tract_querier/tract_math/tract_obb.py new file mode 100644 index 0000000..4dfa0fa --- /dev/null +++ b/tract_querier/tract_math/tract_obb.py @@ -0,0 +1,1280 @@ +from numpy import ( + vstack, where, intersect1d, in1d, unique, + cross, abs, arccos, sign, + dot, array, cov, nan_to_num, inf, pi, + hstack, repeat, bincount, arange +) +from numpy.linalg import norm, solve + + +class Box2D: + + def __init__(self, *args, **kwargs): + if len(args) <= 5: + self._compute_bounding_box(*args, **kwargs) + else: + self._set_variables(*args) + + def _compute_bounding_box(self, points, point_ids, vectors, labels=None, level=None): + center = points.mean(0) + centered_points = points - center + + orientation = vectors.sum(0) + orientation /= norm(orientation) + + orthogonal_direction = orthogonal_vector(orientation) + orthogonal_direction /= norm(orthogonal_direction) + + points_orthogonal = dot( + orthogonal_direction, + centered_points.T + ) + + points_orientation = dot(orientation, centered_points.T) + + max_main = points_orientation.max() + min_main = points_orientation.min() + max_orthogonal = points_orthogonal.max() + min_orthogonal = points_orthogonal.min() + + bounding_box_corners = (vstack(( + orientation * max_main + orthogonal_direction * max_orthogonal, + orientation * max_main + orthogonal_direction * min_orthogonal, + orientation * min_main + orthogonal_direction * min_orthogonal, + orientation * min_main + orthogonal_direction * max_orthogonal, + )) + center) + + center = bounding_box_corners.mean(0) + + volume = (max_main - min_main) * (max_orthogonal - min_orthogonal) + + self.orthogonal = orthogonal_direction + self.points_orientation = points_orientation + self.points_orthogonal = points_orthogonal + + self._set_variables( + bounding_box_corners, center, orientation, + labels, points, vectors, volume, + None, None, None, level + ) + + def _set_variables(self, + box, + center, + orientation, + labels, + points, + point_ids, + vectors, + volume, + parent, + left, + right, + level + ): + self.box = box + self.center = center + self.orientation = orientation + self.labels = labels + self.points = points + self.point_ids = point_ids + self.vectors = vectors + self.volume = volume + self.parent = parent + self.left = left + self.right = right + self.level = level + + self._calculate_orientation_limits() + self._calculate_orthogonal_limits() + + def _calculate_orientation_limits(self): + projections = [dot(self.orientation, point) for point in self.box] + self.orientation_limits = (min(projections), max(projections)) + + def _calculate_orthogonal_limits(self): + projections = [dot(self.orthogonal, point) for point in self.box] + self.orthogonal_limits = (min(projections), max(projections)) + + def siblings(self, generations_up=0, generations_down=0): + if generations_up == 0 and generations_down == 1: + left = [self.left] if self.left is not None else [] + right = [self.right] if self.right is not None else [] + return left + right + + elif generations_up > 0: + if self.parent is None: + return [] + return self.parent.siblings(generations_up - 1, generations_down + 1) + elif generations_down > 1: + if self.left is not None: + left = self.left.siblings(0, generations_down - 1) + else: + left = [] + if self.right is not None: + right = self.right.siblings(0, generations_down - 1) + else: + right = [] + + return left + right + + def swap_direction(self): + self.orientation *= -1 + self._calculate_orientation_limits() + + def overlap_main(self, box): + projections = [dot(self.orientation, point) for point in box.box] + orientation_limits = (min(projections), max(projections)) + + if ( + self.orientation_limits[0] <= orientation_limits[0] <= self.orientation_limits[1] or + self.orientation_limits[0] <= orientation_limits[1] <= self.orientation_limits[1] or + orientation_limits[0] <= self.orientation_limits[0] <= orientation_limits[1] or + orientation_limits[0] <= self.orientation_limits[1] <= orientation_limits[1] + ): + return True + return False + + def center_signed_orientational_distance(self, box): + return dot(self.orientation, self.center - box.center) + + def center_distance(self, box): + return norm(box.center - self.center) + + def __repr__(self): + return self.box.__repr__() + '\n' +\ + 'level:' + repr(self.level) + + def __str__(self): + return self.box.__str__() + '\n' +\ + 'level:' + str(self.level) + + +class Box3D(Box2D): + + def _compute_bounding_box(self, points, point_ids, vectors, labels=None, level=None): + original_points = points + original_point_ids = point_ids + original_labels = labels + original_vectors = vectors + + orientation = vectors.mean(0) + orientation /= norm(orientation) + + orthogonal_direction1 = orthogonal_vector(orientation) + orthogonal_direction2 = cross(orientation, orthogonal_direction1) + + orthogonal_direction1 /= norm(orthogonal_direction1) + orthogonal_direction2 /= norm(orthogonal_direction2) + + center = points.mean(0) + centered_points = points - center + + points_orientation = dot(orientation, centered_points.T) + points_orthogonal1 = dot( + orthogonal_direction1, + centered_points.T + ) + points_orthogonal2 = dot( + orthogonal_direction2, + centered_points.T + ) + + max_main, min_main = points_orientation.max(), points_orientation.min() + max_orthogonal1, min_orthogonal1 = ( + points_orthogonal1.max(), + points_orthogonal1.min() + ) + max_orthogonal2, min_orthogonal2 = ( + points_orthogonal2.max(), + points_orthogonal2.min() + ) + + bounding_box_corners = (vstack(( + orientation * max_main + orthogonal_direction1 * + max_orthogonal1 + orthogonal_direction2 * max_orthogonal2, + orientation * max_main + orthogonal_direction1 * + max_orthogonal1 + orthogonal_direction2 * min_orthogonal2, + orientation * max_main + orthogonal_direction1 * + min_orthogonal1 + orthogonal_direction2 * min_orthogonal2, + orientation * max_main + orthogonal_direction1 * + min_orthogonal1 + orthogonal_direction2 * max_orthogonal2, + orientation * min_main + orthogonal_direction1 * + max_orthogonal1 + orthogonal_direction2 * max_orthogonal2, + orientation * min_main + orthogonal_direction1 * + max_orthogonal1 + orthogonal_direction2 * min_orthogonal2, + orientation * min_main + orthogonal_direction1 * + min_orthogonal1 + orthogonal_direction2 * min_orthogonal2, + orientation * min_main + orthogonal_direction1 * + min_orthogonal1 + orthogonal_direction2 * max_orthogonal2, + )) + center) + + center = bounding_box_corners.mean(0) + + volume = ( + (max_main - min_main) * + (max_orthogonal1 - min_orthogonal1) * + (max_orthogonal2 - min_orthogonal2) + ) + + self.orthogonal1 = orthogonal_direction1 + self.orthogonal2 = orthogonal_direction2 + self.points_orientation = points_orientation + self.points_orthogonal1 = points_orthogonal1 + self.points_orthogonal2 = points_orthogonal2 + + self._set_variables( + bounding_box_corners, center, orientation, + original_labels, original_points, original_point_ids, original_vectors, volume, + None, None, None, level + ) + + def _calculate_orthogonal_limits(self): + projections = dot(self.orthogonal1, self.box.T).T + self.orthogonal1_limits = (min(projections), max(projections)) + projections = dot(self.orthogonal2, self.box.T).T + self.orthogonal2_limits = (min(projections), max(projections)) + + def overlap_main(self, box): + projections = dot(self.orientation, box.box.T).T + orientation_limits = (min(projections), max(projections)) + + return ( + self.orientation_limits[0] <= orientation_limits[0] <= self.orientation_limits[1] or + self.orientation_limits[0] <= orientation_limits[1] <= self.orientation_limits[1] or + orientation_limits[0] <= self.orientation_limits[0] <= orientation_limits[1] or + orientation_limits[0] <= self.orientation_limits[1] <= orientation_limits[1] + ) + + def overlap_orthogonal(self, box): + projections = dot(self.orthogonal1, box.box.T).T + orthogonal1_limits = (min(projections), max(projections)) + + if ( + self.orthogonal1_limits[0] <= orthogonal1_limits[0] <= self.orthogonal1_limits[1] or + self.orthogonal1_limits[0] <= orthogonal1_limits[1] <= self.orthogonal1_limits[1] or + orthogonal1_limits[0] <= self.orthogonal1_limits[0] <= orthogonal1_limits[1] or + orthogonal1_limits[0] <= self.orthogonal1_limits[1] <= orthogonal1_limits[1] + ): + overlap_orthogonal1 = True + + if not overlap_orthogonal1: + return False + + projections = dot(self.orthogonal2, box.box.T).T + orthogonal2_limits = (min(projections), max(projections)) + + if ( + self.orthogonal2_limits[0] <= orthogonal2_limits[0] <= self.orthogonal2_limits[1] or + self.orthogonal2_limits[0] <= orthogonal2_limits[1] <= self.orthogonal2_limits[1] or + orthogonal2_limits[0] <= self.orthogonal2_limits[0] <= orthogonal2_limits[1] or + orthogonal2_limits[0] <= self.orthogonal2_limits[1] <= orthogonal2_limits[1] + ): + overlap_orthogonal2 = True + + return overlap_orthogonal1 and overlap_orthogonal2 + + def overlap(self, box): + return self.overlap_main(box) and self.overlap_orthogonal(box) + + def overlap_volume(self, box): + projections = dot(self.orientation, box.box.T).T + orientation_limits = (min(projections), max(projections)) + + if not ( + self.orientation_limits[0] <= orientation_limits[0] <= self.orientation_limits[1] or + self.orientation_limits[0] <= orientation_limits[1] <= self.orientation_limits[1] or + orientation_limits[0] <= self.orientation_limits[0] <= orientation_limits[1] or + orientation_limits[0] <= self.orientation_limits[1] <= orientation_limits[1] + ): + return 0 + + overlap_main_length =\ + min(orientation_limits[1], self.orientation_limits[1]) -\ + max(orientation_limits[0], self.orientation_limits[0]) + + projections = dot(self.orthogonal1, box.box.T).T + orthogonal1_limits = (min(projections), max(projections)) + + if not\ + (self.orthogonal1_limits[0] <= orthogonal1_limits[0] <= self.orthogonal1_limits[1] or + self.orthogonal1_limits[0] <= orthogonal1_limits[1] <= self.orthogonal1_limits[1] or + orthogonal1_limits[0] <= self.orthogonal1_limits[0] <= orthogonal1_limits[1] or + orthogonal1_limits[0] <= self.orthogonal1_limits[1] <= orthogonal1_limits[1]): + return 0 + + overlap_orthogonal1_length = \ + min(orthogonal1_limits[1], self.orthogonal1_limits[1]) -\ + max(orthogonal1_limits[0], self.orthogonal1_limits[0]) + + projections = dot(self.orthogonal2, box.box.T) + orthogonal2_limits = (min(projections), max(projections)) + + if not\ + (self.orthogonal2_limits[0] <= orthogonal2_limits[0] <= self.orthogonal2_limits[1] or + self.orthogonal2_limits[0] <= orthogonal2_limits[1] <= self.orthogonal2_limits[1] or + orthogonal2_limits[0] <= self.orthogonal2_limits[0] <= orthogonal2_limits[1] or + orthogonal2_limits[0] <= self.orthogonal2_limits[1] <= orthogonal2_limits[1]): + return 0 + + overlap_orthogonal2_length = \ + min(orthogonal2_limits[1], self.orthogonal2_limits[1]) -\ + max(orthogonal2_limits[0], self.orthogonal2_limits[0]) + + return overlap_main_length * overlap_orthogonal1_length * overlap_orthogonal2_length + + + +class Box3DRich(Box2D): + + def _compute_bounding_box(self, points, point_ids, vectors, labels=None, level=None, robustify=None): + original_points = points + original_point_ids = point_ids + original_labels = labels + original_vectors = vectors + if robustify == 'points' and len(points) > 4: + p_mean = points.mean(0) + p_cov = cov(points.T) + + c_points = points - p_mean + + z = (solve(p_cov, c_points.T) * c_points.T).sum(0) + + cutoff = 9.3484036044961485 # chi2.ppf(.975, 3) + + points = points[z < cutoff] + point_ids = point_ids[z < cutoff] + print 'Discarded', (len(original_points) - len(points)) * 1. / len(points) + vectors = vectors[z < cutoff] + if labels is not None: + labels = labels[z < cutoff] + + orientation = vectors.mean(0) + orientation /= norm(orientation) + + orthogonal_direction1 = orthogonal_vector(orientation) + orthogonal_direction2 = cross(orientation, orthogonal_direction1) + + orthogonal_direction1 /= norm(orthogonal_direction1) + orthogonal_direction2 /= norm(orthogonal_direction2) + + center = points.mean(0) + centered_points = points - center + + points_orientation = dot(orientation, centered_points.T) + points_orthogonal1 = dot( + orthogonal_direction1, centered_points.T) + points_orthogonal2 = dot( + orthogonal_direction2, centered_points.T) + + max_main, min_main = points_orientation.max(), points_orientation.min() + max_orthogonal1, min_orthogonal1 = points_orthogonal1.max( + ), points_orthogonal1.min() + max_orthogonal2, min_orthogonal2 = points_orthogonal2.max( + ), points_orthogonal2.min() + + bounding_box_corners = (vstack(( + orientation * max_main + orthogonal_direction1 * + max_orthogonal1 + orthogonal_direction2 * max_orthogonal2, + orientation * max_main + orthogonal_direction1 * + max_orthogonal1 + orthogonal_direction2 * min_orthogonal2, + orientation * max_main + orthogonal_direction1 * + min_orthogonal1 + orthogonal_direction2 * min_orthogonal2, + orientation * max_main + orthogonal_direction1 * + min_orthogonal1 + orthogonal_direction2 * max_orthogonal2, + orientation * min_main + orthogonal_direction1 * + max_orthogonal1 + orthogonal_direction2 * max_orthogonal2, + orientation * min_main + orthogonal_direction1 * + max_orthogonal1 + orthogonal_direction2 * min_orthogonal2, + orientation * min_main + orthogonal_direction1 * + min_orthogonal1 + orthogonal_direction2 * min_orthogonal2, + orientation * min_main + orthogonal_direction1 * + min_orthogonal1 + orthogonal_direction2 * max_orthogonal2, + )) + center) + + center = bounding_box_corners.mean(0) + + volume = ( + (max_main - min_main) * + (max_orthogonal1 - min_orthogonal1) * + (max_orthogonal2 - min_orthogonal2) + ) + + self.orthogonal1 = orthogonal_direction1 + self.orthogonal2 = orthogonal_direction2 + self.points_orientation = points_orientation + self.points_orthogonal1 = points_orthogonal1 + self.points_orthogonal2 = points_orthogonal2 + + self._set_variables( + bounding_box_corners, center, orientation, + original_labels, original_points, original_point_ids, original_vectors, volume, + None, None, None, level + ) + + def _calculate_orthogonal_limits(self): + projections = dot(self.orthogonal1, self.box.T).T + self.orthogonal1_limits = (min(projections), max(projections)) + projections = dot(self.orthogonal2, self.box.T).T + self.orthogonal2_limits = (min(projections), max(projections)) + + def overlap_main(self, box): + projections = dot(self.orientation, box.box.T).T + orientation_limits = (min(projections), max(projections)) + + return ( + self.orientation_limits[0] <= orientation_limits[0] <= self.orientation_limits[1] or + self.orientation_limits[0] <= orientation_limits[1] <= self.orientation_limits[1] or + orientation_limits[0] <= self.orientation_limits[0] <= orientation_limits[1] or + orientation_limits[0] <= self.orientation_limits[1] <= orientation_limits[1] + ) + + def overlap_orthogonal(self, box): + projections = dot(self.orthogonal1, box.box.T).T + orthogonal1_limits = (min(projections), max(projections)) + + if ( + self.orthogonal1_limits[0] <= orthogonal1_limits[0] <= self.orthogonal1_limits[1] or + self.orthogonal1_limits[0] <= orthogonal1_limits[1] <= self.orthogonal1_limits[1] or + orthogonal1_limits[0] <= self.orthogonal1_limits[0] <= orthogonal1_limits[1] or + orthogonal1_limits[0] <= self.orthogonal1_limits[1] <= orthogonal1_limits[1] + ): + overlap_orthogonal1 = True + + if not overlap_orthogonal1: + return False + + projections = dot(self.orthogonal2, box.box.T).T + orthogonal2_limits = (min(projections), max(projections)) + + if ( + self.orthogonal2_limits[0] <= orthogonal2_limits[0] <= self.orthogonal2_limits[1] or + self.orthogonal2_limits[0] <= orthogonal2_limits[1] <= self.orthogonal2_limits[1] or + orthogonal2_limits[0] <= self.orthogonal2_limits[0] <= orthogonal2_limits[1] or + orthogonal2_limits[0] <= self.orthogonal2_limits[1] <= orthogonal2_limits[1] + ): + overlap_orthogonal2 = True + + return overlap_orthogonal1 and overlap_orthogonal2 + + def overlap(self, box): + return self.overlap_main(box) and self.overlap_orthogonal(box) + + def overlap_volume(self, box): + projections = dot(self.orientation, box.box.T).T + orientation_limits = (min(projections), max(projections)) + + if not ( + self.orientation_limits[0] <= orientation_limits[0] <= self.orientation_limits[1] or + self.orientation_limits[0] <= orientation_limits[1] <= self.orientation_limits[1] or + orientation_limits[0] <= self.orientation_limits[0] <= orientation_limits[1] or + orientation_limits[0] <= self.orientation_limits[1] <= orientation_limits[1] + ): + return 0 + + overlap_main_length =\ + min(orientation_limits[1], self.orientation_limits[1]) -\ + max(orientation_limits[0], self.orientation_limits[0]) + + projections = dot(self.orthogonal1, box.box.T).T + orthogonal1_limits = (min(projections), max(projections)) + + if not\ + (self.orthogonal1_limits[0] <= orthogonal1_limits[0] <= self.orthogonal1_limits[1] or + self.orthogonal1_limits[0] <= orthogonal1_limits[1] <= self.orthogonal1_limits[1] or + orthogonal1_limits[0] <= self.orthogonal1_limits[0] <= orthogonal1_limits[1] or + orthogonal1_limits[0] <= self.orthogonal1_limits[1] <= orthogonal1_limits[1]): + return 0 + + overlap_orthogonal1_length = \ + min(orthogonal1_limits[1], self.orthogonal1_limits[1]) -\ + max(orthogonal1_limits[0], self.orthogonal1_limits[0]) + + projections = dot(self.orthogonal2, box.box.T) + orthogonal2_limits = (min(projections), max(projections)) + + if not\ + (self.orthogonal2_limits[0] <= orthogonal2_limits[0] <= self.orthogonal2_limits[1] or + self.orthogonal2_limits[0] <= orthogonal2_limits[1] <= self.orthogonal2_limits[1] or + orthogonal2_limits[0] <= self.orthogonal2_limits[0] <= orthogonal2_limits[1] or + orthogonal2_limits[0] <= self.orthogonal2_limits[1] <= orthogonal2_limits[1]): + return 0 + + overlap_orthogonal2_length = \ + min(orthogonal2_limits[1], self.orthogonal2_limits[1]) -\ + max(orthogonal2_limits[0], self.orthogonal2_limits[0]) + + return overlap_main_length * overlap_orthogonal1_length * overlap_orthogonal2_length + + +def orthogonal_vector(vector, tol=1e-8): + a_vector = abs(vector) + if len(vector) == 3: + if a_vector[0] > tol: + orthogonal = vector[::-1] * (1, 0, -1) + elif a_vector[2] > tol: + orthogonal = vector[::-1] * (-1, 0, 1) + elif a_vector[1] > tol: + orthogonal = vector[::-1] * (-1, 0, 0) + else: + raise ValueError('vector must have non-null norm') + else: + if a_vector[0] > tol: + orthogonal = vector[::-1] * (-1, 1) + elif a_vector[1] > tol: + orthogonal = vector[::-1] * (1, -1) + else: + raise ValueError('vector must have non-null norm') + + orthogonal /= norm(orthogonal) + return orthogonal + + +def box_cut(points, direction, mapped_points=None, max_main=None, min_main=None): + if mapped_points is None: + mapped_points = dot(direction, points.T) + + if max_main is None: + max_main = mapped_points.max() + if min_main is None: + min_main = mapped_points.min() + + mid_main = (max_main + min_main) / 2. + split1 = where(mapped_points <= mid_main) + split2 = where(mapped_points > mid_main) + + return split1, split2 + + +def all_obb_2d(points, vectors, labels, tol=1e-8, level=0, intersection_threshold=.8, split_threshold=.2, box=None): + + if (box is not None) and (points is box.points) and (vectors is box.vectors) and (labels is box.labels): + box_center = box + box.level = level + else: + box_center = Box2D(points, vectors, labels, level) + level += 1 + + if len(unique(labels)) == 1: + return [box_center] + + # First compute the splitting across the fibers + split_along_fiber = True + + left, right = box_cut(points, box_center.orthogonal, + mapped_points=box_center.points_orthogonal) + labels_left = labels[left] + labels_right = labels[right] + + if len(intersect1d(labels_left, labels_right)) >= len(unique(labels)) * intersection_threshold: + split_along_fiber = True + else: + points_left = points[left] + vectors_left = vectors[left] + box_left = Box2D(points_left, vectors_left, labels_left) + + points_right = points[right] + vectors_right = vectors[right] + box_right = Box2D(points_left, vectors_left, labels_left) + + if (box_left.volume + box_right.volume) < (1 - split_threshold) * box_center.volume: + split_along_fiber = False + left = all_obb_2d( + points_left, vectors_left, labels_left, tol=tol, level=level, + intersection_threshold=intersection_threshold, box=box_left) + right = all_obb_2d( + points_right, vectors_right, labels_right, tol=tol, level=level, + intersection_threshold=intersection_threshold, box=box_right) + else: + split_along_fiber = True + + if split_along_fiber: # If we could not split across we split along + + left, right = box_cut( + points, box_center.orientation, mapped_points=box_center.points_orientation) + labels_left = labels[left] + labels_right = labels[right] + if len(intersect1d(labels_left, labels_right)) <= len(unique(labels)) * intersection_threshold: + return [box_center] + + points_left = points[left] + vectors_left = vectors[left] + left = all_obb_2d( + points_left, vectors_left, labels_left, tol=tol, level=level, + intersection_threshold=intersection_threshold) + + points_right = points[right] + vectors_right = vectors[right] + right = all_obb_2d( + points_right, vectors_right, labels_right, tol=tol, level=level, + intersection_threshold=intersection_threshold) + + box_center.left = left[0] + box_center.right = right[0] + left[0].parent = box_center + right[0].parent = box_center + + return [box_center] + left + right + + +def all_obb_3d_along_tract( + points, vectors, labels, tol=1e-8, level=0, + intersection_threshold=.8, split_threshold=.2, + box=None, clean=False, point_ids=None +): + if point_ids is None: + point_ids = arange(len(points)) + + if ( + (box is not None) and (points is box.points) and + (vectors is box.vectors) and (labels is box.labels) + ): + box_center = box + box.level = level + else: + box_center = Box3D(points, point_ids, vectors, labels, level) + level += 1 + + if len(points) == 1: + return [box_center] + + unique_labels = unique(labels) + + left, right = box_cut( + points, box_center.orientation, + mapped_points=box_center.points_orientation + ) + + masks = { + 'left': left, + 'right': right + } + + split_labels = { + 'left': labels[left], + 'right': labels[right] + } + + labels_both = intersect1d(split_labels['left'], split_labels['right']) + + if clean: + labels_count = bincount(labels) + labels_count = { + side: bincount(split_labels[side]) + for side in split_labels + } + + labels_ratio = { + side: nan_to_num( + labels_count[side] * 1. / labels_count[:len(labels_count(side))] + ) for side in labels_count + } + + new_results = [box_center] + + if ( + (len(labels_both) <= len(unique_labels) * intersection_threshold) and + (box_center.points_orientation.ptp() / 2. < min((norm(v) for v in vectors))) + ): + return new_results + + for side in ('left', 'right'): + mask = masks[side] + new_labels = split_labels[side] + if len(new_labels) > 0: + new_points = points[mask] + new_point_ids = point_ids[mask] + new_vectors = vectors[mask] + + if clean: + clean_labels = in1d( + labels[side], + intersect1d(labels_both, (labels_ratio[side] > .2).nonzero()[0]), + ) + new_points = new_points[clean_labels] + new_point_ids = new_point_ids[clean_labels] + new_vectors = new_vectors[clean_labels] + new_labels = new_labels[clean_labels] + + if len(new_points) > 1: + new_tree = all_obb_3d_along_tract( + new_points, new_vectors, new_labels, + tol=tol, level=level, point_ids=new_point_ids, + intersection_threshold=intersection_threshold, clean=clean + ) + + setattr(box_center, side, new_tree[0]) + getattr(box_center, side).parent = box_center + + new_results += new_tree + + return new_results + + +def all_obb_3d(points, vectors, labels, tol=1e-8, level=0, intersection_threshold=.8, split_threshold=.2, box=None, clean=False, point_ids=None): + if point_ids is None: + point_ids = arange(len(points)) + + if ( + (box is not None) and (points is box.points) and + (vectors is box.vectors) and (labels is box.labels) + ): + box_center = box + box.level = level + else: + box_center = Box3D( + points, point_ids, vectors, + labels, level + ) + level += 1 + + if len(points) == 1: + return [box_center] + + unique_labels = unique(labels) + + for orientation in ('orthogonal1', 'orthogonal2', 'orientation'): + left, right = box_cut( + points, getattr(box_center, orientation), + mapped_points=getattr(box_center, 'points_' + orientation) + ) + + masks = { + 'left': left, + 'right': right + } + + split_labels = { + 'left': labels[left], + 'right': labels[right] + } + + labels_both = intersect1d(split_labels['left'], split_labels['right']) + + if len(labels_both) == 0: + break + + if clean: + labels_count = bincount(labels) + labels_count = { + side: bincount(split_labels[side]) + for side in split_labels + } + + labels_ratio = { + side: nan_to_num( + labels_count[side] * 1. / labels_count[:len(labels_count(side))] + ) for side in labels_count + } + + new_results = [box_center] + print level + if ( + orientation == 'orientation' and + (len(labels_both) <= len(unique_labels) * intersection_threshold) # and + #(box_center.points_orientation.ptp() / 2. > min((norm(v) for v in vectors))) + ): + return new_results + + for side in ('left', 'right'): + mask = masks[side] + new_labels = split_labels[side] + if len(new_labels) > 0: + new_points = points[mask] + new_point_ids = point_ids[mask] + new_vectors = vectors[mask] + + if clean: + clean_labels = in1d( + labels[side], + intersect1d(labels_both, (labels_ratio[side] > .2).nonzero()[0]), + ) + new_points = new_points[clean_labels] + new_point_ids = new_point_ids[clean_labels] + new_vectors = new_vectors[clean_labels] + new_labels = new_labels[clean_labels] + + if len(new_points) > 1: + new_tree = all_obb_3d( + new_points, new_vectors, new_labels, tol=tol, level=level, point_ids=new_point_ids, + intersection_threshold=intersection_threshold, clean=clean) + + setattr(box_center, side, new_tree[0]) + getattr(box_center, side).parent = box_center + + new_results += new_tree + + return new_results + + +def all_obb_3d_nr(points_, vectors_, labels_, tol=1e-8, level_=0, intersection_threshold=.8, split_threshold=.2, robustify=None, point_ids_=None): + if point_ids_ is None: + point_ids_ = arange(len(points_)) + + root = Box3D(points_, point_ids_, vectors_, labels_, level_, robustify=robustify) + stack = [root] + + total_points = len(points_) + points_done = 0 + + while len(stack): + box = stack.pop() + level = box.level + 1 + + if len(box.points) == 1: + continue + + unique_labels = unique(box.labels) + + for orientation in ('orthogonal1', 'orthogonal2', 'orientation'): + left, right = box_cut( + box.points, getattr(box, orientation), + mapped_points=getattr(box, 'points_' + orientation) + ) + + masks = { + 'left': left, + 'right': right + } + + split_labels = { + 'left': box.labels[left], + 'right': box.labels[right] + } + + labels_both = intersect1d(split_labels['left'], split_labels['right']) + + if len(labels_both) == 0: + break + + print level, len(unique_labels), len(box.points), total_points - points_done + if ( + orientation == 'orientation' and + (len(labels_both) <= len(unique_labels) * intersection_threshold) # and + #(box_center.points_orientation.ptp() / 2. > min((norm(v) for v in vectors))) + ): + points_done += len(box.points) + continue + + for side in ('left', 'right'): + mask = masks[side] + new_labels = split_labels[side] + if len(new_labels) > 0: + new_points = box.points[mask] + new_point_ids = box.point_ids[mask] + new_vectors = box.vectors[mask] + + if len(new_points) > 1 and len(new_points) < len(box.points): + new_box = Box3D(new_points, new_point_ids, new_vectors, new_labels, level, robustify=robustify) + setattr(box, side, new_box) + getattr(box, side).parent = box + + print "\tAdded to stack ", side + stack.append(new_box) + else: + points_done += len(new_points) + + return root + + +def all_obb_3d_old(points, vectors, labels, tol=1e-8, level=0, intersection_threshold=.8, split_threshold=.2, box=None, point_ids=None): + if point_ids is None: + point_ids = arange(len(points)) + + if (box is not None) and (points is box.points) and (vectors is box.vectors) and (labels is box.labels): + box_center = box + box.level = level + else: + box_center = Box3D(points, point_ids, vectors, labels, level) + level += 1 + + if len(points) == 1: + return [box_center] + + # First compute the splitting across the fibers + split_along_fiber = True + + o1_left, o1_right = box_cut( + points, box_center.orthogonal1, mapped_points=box_center.points_orthogonal1) + o2_left, o2_right = box_cut( + points, box_center.orthogonal2, mapped_points=box_center.points_orthogonal2) + o1_labels_left = labels[o1_left] + o1_labels_right = labels[o1_right] + o2_labels_left = labels[o2_left] + o2_labels_right = labels[o2_right] + + unique_labels = unique(labels) + if ( + len(intersect1d(o1_labels_left, o1_labels_right)) > 0 and + len(intersect1d(o2_labels_left, o2_labels_right)) > 0 + ): + split_along_fiber = True + else: + o1_box_left = Box3D(points[o1_left], vectors[o1_left], o1_labels_left) + o1_box_right = Box3D(points[ + o1_right], vectors[o1_right], o1_labels_right) + + o2_box_left = Box3D(points[o2_left], vectors[o2_left], o2_labels_left) + o2_box_right = Box3D(points[ + o2_right], vectors[o2_right], o2_labels_right) + + if (o1_box_left.volume + o1_box_right.volume) < (o1_box_left.volume + o2_box_right.volume): + box_left = o1_box_left + box_right = o1_box_right + else: + box_left = o2_box_left + box_right = o2_box_right + + if (box_left.volume + box_right.volume) < (1 - split_threshold) * box_center.volume: + split_along_fiber = False + left = all_obb_3d( + box_left.points, box_left.vectors, box_left.labels, tol=tol, level=level, + intersection_threshold=intersection_threshold, box=box_left) + right = all_obb_3d( + box_right.points, box_right.vectors, box_right.labels, tol=tol, level=level, + intersection_threshold=intersection_threshold, box=box_right) + else: + split_along_fiber = True + + if split_along_fiber: # If we could not split across we split along + + left, right = box_cut( + points, box_center.orientation, mapped_points=box_center.points_orientation) + labels_left = labels[left] + labels_right = labels[right] + if len(intersect1d(labels_left, labels_right)) <= len(unique_labels) * intersection_threshold: + return [box_center] + + points_left = points[left] + point_ids_left = point_ids[left] + vectors_left = vectors[left] + left = all_obb_3d( + points_left, point_ids_left, vectors_left, labels_left, tol=tol, level=level, + intersection_threshold=intersection_threshold) + + points_right = points[right] + point_ids_right = point_ids[left] + vectors_right = vectors[right] + right = all_obb_3d( + points_right, point_ids_right, vectors_right, labels_right, tol=tol, level=level, + intersection_threshold=intersection_threshold) + + box_center.left = left[0] + box_center.right = right[0] + left[0].parent = box_center + right[0].parent = box_center + + return [box_center] + left + right + + +def point_coverage_by_level(obbs, points): + level = 0 + points_level = [obb.points for obb in obbs if obb.level == level] + level_coverage = [] + while len(points_level) > 0: + level_coverage.append(sum((len( + points) for points in points_level)) * 1. / len(points)) + level += 1 + points_level = [obb.points for obb in obbs if obb.level == level if len( + obb.points) > 0] + + return array(level_coverage) + + +def draw_boxes_2d(obbs, level, color=None, **args): + from pylab import plot, cm + + for i, obb in enumerate(obbs): + if obb.level != level: + continue + box = vstack([obb.box, obb.box[0]]) + if color is None: + plot(box.T[0], box.T[1], lw=5, hold=True, **args) + else: + plot(box.T[0], box.T[ + 1], lw=5, hold=True, c=cm.jet(color[i]), **args) + + +def draw_box_2d(obbs, **args): + from pylab import plot, quiver + if isinstance(obbs, Box2D): + obbs = [obbs] + for obb in obbs: + box = vstack([obb.box, obb.box[0]]) + plot(box.T[0], box.T[1], lw=5, hold=True, **args) + quiver([obb.center[0]], [obb.center[1]], [obb.orientation[ + 0]], [obb.orientation[1]], pivot='middle', hold=True, **args) + + +def draw_box_3d(obbs, tube_radius=1, color=None, **kwargs): + from mayavi.mlab import plot3d + from numpy.random import rand + if isinstance(obbs, Box2D): + obbs = [obbs] + for obb in obbs: + if color is None: + color_ = tuple(rand(3)) + else: + color_ = color + box = obb.box + b1 = vstack([box[:4], box[0]]).T + b2 = vstack([box[4:], box[4]]).T + es = [vstack([b1.T[i], b2.T[i]]).T for i in xrange(4)] + plot3d(b1[0], b1[1], b1[ + 2], tube_radius=tube_radius, color=color_, **kwargs) + plot3d(b2[0], b2[1], b2[ + 2], tube_radius=tube_radius, color=color_, **kwargs) + [plot3d(e[0], e[1], e[ + 2], tube_radius=tube_radius, color=color_, **kwargs) for e in es] + + +def oriented_trace(obb, positive=True, generations=2, angle_threshold=pi / 4): + tract = [obb] + center = obb + candidates = center.siblings(generations) + if positive: + sg = 1 + else: + sg = -1 + while len(candidates) > 0: + next_candidate_distance = inf + for c in candidates: + signed_distance = sg *\ + sign(center.center_signed_orientational_distance(c)) *\ + center.center_distance(c) + if (signed_distance <= 0) or\ + not center.overlap_orthogonal(c) or\ + arccos(dot(center.orientation, c.orientation)) > angle_threshold: + continue + + if signed_distance < next_candidate_distance: + next_candidate_distance = signed_distance + next_candidate = c + + if next_candidate_distance < inf: + if next_candidate in tract: + break + tract.append(next_candidate) + if dot(center.orientation, next_candidate.orientation) < 0: + next_candidate.swap_direction() + center = next_candidate + candidates = center.siblings(generations) + else: + break + + return tract + + +def trace(obb, generations=2, angle_threshold=pi / 4): + trace_positive = oriented_trace(obb, True, generations, angle_threshold) + trace_negative = oriented_trace(obb, False, generations, angle_threshold) + + return trace_negative[::-1] + trace_positive + + +def get_most_probable_trace(obbs, generations=2, angle_threshold=pi / 4, return_all=True): + traces_list = [trace(obb, generations=generations, + angle_threshold=angle_threshold) for obb in obbs] + traces_w_set = [(t, set(t)) for t in traces_list] + n = 1. * len(traces_w_set) + + traces_with_frequency = [] + while len(traces_w_set) > 0: + trace_ = traces_w_set.pop() + traces_w_set_new = [] + count = 1 + for t in traces_w_set: + if t[1] == trace_[1]: + count += 1 + else: + traces_w_set_new.append(t) + traces_with_frequency.append((count / n, trace_[0])) + traces_w_set = traces_w_set_new + + traces_with_frequency.sort(cmp=lambda x, y: int(sign(y[0] - x[0]))) + return traces_with_frequency + + +def get_level(tree, level): + if tree is None or tree.level > level: + return [] + elif tree.level == level: + return [tree] + else: + return get_level(tree.left, level) + get_level(tree.right, level) + + +def overlapping_boxes(tree, box, levels=None, threshold=0.): + if tree is None: + return [] + + overlap = tree.overlap_volume(box) + + if overlap < threshold: + return [] + else: + left = overlapping_boxes( + tree.left, box, levels=levels, threshold=threshold) + right = overlapping_boxes( + tree.right, box, levels=levels, threshold=threshold) + if levels is None or tree.level in levels: + return [tree] + left + right + else: + return left + right + + +def containing_boxes(tree, box, levels=None, threshold=1.): + if tree is None or tree.level > max(levels): + return [] + + normalized_overlap = tree.overlap_volume(box) / box.volume + + if normalized_overlap < threshold: + return [] + else: + left = overlapping_boxes( + tree.left, box, levels=levels, threshold=threshold) + right = overlapping_boxes( + tree.right, box, levels=levels, threshold=threshold) + if levels is None or tree.level in levels: + return [tree] + left + right + else: + return left + right + + +def min_max(vector, axis=None): + return array((vector.min(axis), vector.max(axis))) + + +def overlap_vtk(self, box): + a = self + b = box + + axes_a = vstack((a.orientation, a.orthogonal1, a.orthogonal2)) + axes_b = vstack((b.orientation, b.orthogonal1, b.orthogonal2)) + + a2b = b.center - a.center + + a_a2b_limits = min_max(dot(a2b, a.box.T)) + b_a2b_limits = min_max(dot(a2b, a.box.T)) + + if ( + a_a2b_limits[0] < b_a2b_limits[1] or + b_a2b_limits[1] < a_a2b_limits[0] + ): + return False + + +def obb_tree_dfs(obb_tree): + for obb in obb_tree: + if obb.level == 0: + root = obb + break + else: + raise ValueError('No root in the tree') + return obb_tree_dfs_recursive(root) + + +def obb_tree_dfs_recursive(obb_node): + if obb_node is None: + return [] + if obb_node.left is None and obb_node.right is None: + return [obb_node] + + return obb_tree_dfs_recursive(obb_node.left) + obb_tree_dfs_recursive(obb_node.right) + + +def prototype_tract( + tracts, obb_tree=None, intersection_threshold=.01, minimum_level=0, + clean=False, return_obb_tree=False, return_leave_centers=False +): + if obb_tree is None: + points = vstack([t[:-1] for t in tracts]) + vectors = vstack([t[1:] - t[:-1] for t in tracts]) + labels = hstack([repeat(i, len(t) - 1) for i, t in enumerate(tracts)]) + + obb_tree = all_obb_3d_along_tract( + points, vectors, labels, + intersection_threshold=intersection_threshold, clean=clean + ) + + if minimum_level < 0: + max_level = max((obb.level for obb in obb_tree)) + minimum_level = max_level + 1 - minimum_level + + leave_centers = array( + [obb.center for obb in obb_tree if obb.left is None and obb.right is None and obb.level > + minimum_level] + ) + + mse_tract = array([ + ((t[..., None] - leave_centers[..., None].T) ** 2).sum(1).min(0).sum() + for t in tracts + ]) + + tract_index = mse_tract.argmin() + + if return_obb_tree or return_leave_centers: + res = (tract_index,) + if return_obb_tree: + res += (obb_tree,) + if return_leave_centers: + res += (leave_centers,) + return res + else: + return tract_index + + +def obb_tree_level(obb_tree, level, include_superior_leaves=True): + if not isinstance(obb_tree, Box3D): + node = obb_tree[0] + for n in obb_tree: + if n.level < node.level: + node = n + else: + node = obb_tree + + return obb_tree_level_dfs(node, level, include_superior_leaves=include_superior_leaves) + + +def obb_tree_level_dfs(obb_node, level, include_superior_leaves=True): + if obb_node is None or obb_node.level > level: + return [] + + if ( + obb_node.level == level or + ( + include_superior_leaves and + obb_node.level < level and + obb_node.left is None and obb_node.right is None + ) + ): + return [obb_node] + + return ( + obb_tree_level_dfs(obb_node.left, level, include_superior_leaves=include_superior_leaves) + + obb_tree_level_dfs( + obb_node.right, level, include_superior_leaves=include_superior_leaves) + ) + + +def obb_from_tractography(tractography, *args, **kwargs): + along_tract = False + if 'along_tract' in kwargs and kwargs['along_tract']: + along_tract = True + + fibers = tractography.tracts() + points = vstack([f[:-1] for f in fibers]) + vectors = vstack([f[1:] - f[:-1] for f in fibers]) + labels = hstack([repeat(i, len(f) - 1) for i, f in enumerate(fibers)]) + + if along_tract: + obbs3d = all_obb_3d_along_tract( + points, vectors, labels, **kwargs + ) + else: + obbs3d = all_obb_3d_nr( + points, vectors, labels, **kwargs + ) + + return obbs3d From a288059cf9bcc576b9e44825b493004405816106 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Mon, 22 Jul 2013 20:29:20 -0400 Subject: [PATCH 15/53] ENH: Added first attempt to project tracts onto prototype --- scripts/tract_math | 2 +- tract_querier/tract_math/__init__.py | 15 +- tract_querier/tract_math/decorator.py | 63 +++--- tract_querier/tract_math/tests/__init__.py | 1 + .../tract_math/tests/test_tract_stats.py | 101 +++++++++ tract_querier/tract_math/tract_stats.py | 194 ++++++++++++++++++ tract_querier/tractography/tractography.py | 60 ++++-- 7 files changed, 386 insertions(+), 50 deletions(-) create mode 100644 tract_querier/tract_math/tests/__init__.py create mode 100644 tract_querier/tract_math/tests/test_tract_stats.py create mode 100644 tract_querier/tract_math/tract_stats.py diff --git a/scripts/tract_math b/scripts/tract_math index b6486ae..d6ca5b1 100644 --- a/scripts/tract_math +++ b/scripts/tract_math @@ -23,7 +23,7 @@ def tract_math_operation(help_text, needs_one_tract=True): def main(): - from tract_querier.tract_math import operations + from tract_querier.tract_math import tract_math_operations as operations usage = r""" usage: %(prog)s ... operation ... diff --git a/tract_querier/tract_math/__init__.py b/tract_querier/tract_math/__init__.py index 88e63d5..f04af6f 100644 --- a/tract_querier/tract_math/__init__.py +++ b/tract_querier/tract_math/__init__.py @@ -2,8 +2,17 @@ from decorator import tract_math_operation +tract_math_operations = dict() + import operations as _operations -operations = dict(( - (f[0], f[1]) for f in getmembers(_operations) if hasattr(f[1], 'help_text') -)) +for f in getmembers(_operations): + if hasattr(f[1], 'help_text'): + tract_math_operations[f[0]] = f[1] + + +import tract_stats as _tract_stats + +for f in getmembers(_tract_stats): + if hasattr(f[1], 'help_text'): + tract_math_operations[f[0]] = f[1] diff --git a/tract_querier/tract_math/decorator.py b/tract_querier/tract_math/decorator.py index b38a115..23bc3d5 100644 --- a/tract_querier/tract_math/decorator.py +++ b/tract_querier/tract_math/decorator.py @@ -28,53 +28,50 @@ def tract_math_operation(help_text, needs_one_tract=True): def internal_decorator(func): def wrapper(*args): - total_args = len(args) argspec = inspect.getargspec(func) - func_total_args = len(argspec.args) + func_args = argspec.args - if argspec.varargs: - func_total_args += 1 + has_file_output = 'file_output' in func_args - func_args = func_total_args - - if argspec.defaults: - func_args = func_total_args - len(argspec.defaults) - - has_file_output = 'file_output' in argspec.args + if argspec.defaults is None: + defaults = tuple() + else: + defaults = argspec.defaults - if ( - (total_args > func_total_args and args[-1] != '-') or - has_file_output - ): - if has_file_output: - ix = argspec.args.index('file_output') + if has_file_output: + if func_args[-1] != 'file_output': + raise TractMathWrongArgumentsError('Output file reserved parameter file_output must be the last one') - if ix >= len(args): - raise TractMathWrongArgumentsError( - 'Wrong number of parameters for the operation' - ) - file_output = args[ix] + func_args = func_args[:-1] + if args[-1] == '-': + file_output = None else: file_output = args[-1] - args = args[:-1] - out = func(*args) + args = args[:-1] + defaults = defaults[:-1] + else: + file_output = None - process_output(out, file_output=file_output) - elif ( - total_args >= func_total_args or - len(args) == func_args - ): if args[-1] == '-': args = args[:-1] - process_output(func(*args)) - else: - raise TractMathWrongArgumentsError( - 'Wrong number of arguments for the operation' - ) + + needed_defaults = len(func_args) - len(args) + if needed_defaults > len(defaults): + raise TractMathWrongArgumentsError('Wrong number of arguments') + elif needed_defaults == -1: + file_output = args[-1] + args = args[:-1] + + if needed_defaults > 0: + args += defaults[-needed_defaults:] + + out = func(*args) + process_output(out, file_output=file_output) wrapper.help_text = help_text wrapper.needs_one_tract = needs_one_tract + wrapper.original_function = func return wrapper diff --git a/tract_querier/tract_math/tests/__init__.py b/tract_querier/tract_math/tests/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tract_querier/tract_math/tests/__init__.py @@ -0,0 +1 @@ + diff --git a/tract_querier/tract_math/tests/test_tract_stats.py b/tract_querier/tract_math/tests/test_tract_stats.py new file mode 100644 index 0000000..46f17ec --- /dev/null +++ b/tract_querier/tract_math/tests/test_tract_stats.py @@ -0,0 +1,101 @@ +from ... import tractography +from .. import tract_stats + +import os +import tempfile + +import numpy +from numpy.testing import assert_array_equal +from nose import tools + + +def test_tract_scalar_to_prototype_one_to_one(random=numpy.random.RandomState(0), length=50, bundle_size=50): + prototype_tract = numpy.c_[ + numpy.zeros(length), + numpy.zeros(length), + numpy.linspace(0, 1, length) + ] + + bundle_tracts = [] + data = {'point_id': []} + for i in xrange(bundle_size): + x, y = random.randn(2) + bundle_tract = prototype_tract.copy() + bundle_tract[:, 0] = x + bundle_tract[:, 1] = y + bundle_tracts.append(bundle_tract) + data['point_id'].append(numpy.arange(length)[:, None]) + + tractography_prototype = tractography.Tractography([prototype_tract]) + tractography_bundle = tractography.Tractography(bundle_tracts, data) + + fname_proto = tempfile.mkstemp(suffix='.vtk', prefix='proto')[1] + + tractography.tractography_to_file( + fname_proto, tractography_prototype + ) + + projected_tractography = tract_stats.tract_scalar_to_prototype.original_function( + [tractography_bundle], fname_proto, 'point_id' + ) + + os.remove(fname_proto) + + enumeration = numpy.arange(length)[:, None] + + tools.eq_(len(projected_tractography.tracts()), 1) + assert_array_equal(prototype_tract, projected_tractography.tracts()[0]) + + for k, v in projected_tractography.tracts_data().iteritems(): + if k.startswith('point_id') and k.endswith('mean'): + assert_array_equal(enumeration, v[0]) + elif k.startswith('point_id') and k.endswith('std'): + assert_array_equal(v[0], v[0] * 0) + + +def test_tract_scalar_to_prototype_one_to_many(random=numpy.random.RandomState(0), length=50, bundle_size=50): + prototype_tract = numpy.c_[ + numpy.zeros(length), + numpy.zeros(length), + numpy.linspace(0, 1, length) + ] + + bundle_tracts = [] + data = {'point_id': []} + for i in xrange(bundle_size): + x, y = random.randn(2) + bundle_tract = prototype_tract[::2].copy() + bundle_tract[:, 0] = x + bundle_tract[:, 1] = y + bundle_tracts.append(bundle_tract) + data['point_id'].append(numpy.arange(length)[::2, None]) + + tractography_prototype = tractography.Tractography([prototype_tract]) + tractography_bundle = tractography.Tractography(bundle_tracts, data) + + fname_proto = tempfile.mkstemp(suffix='.vtk', prefix='proto')[1] + + tractography.tractography_to_file( + fname_proto, tractography_prototype + ) + + projected_tractography = tract_stats.tract_scalar_to_prototype.original_function( + [tractography_bundle], fname_proto, 'point_id' + ) + + os.remove(fname_proto) + + enumeration = numpy.arange(length)[:, None] + nanarray = numpy.repeat(numpy.nan, length)[:, None] + + tools.eq_(len(projected_tractography.tracts()), 1) + assert_array_equal(prototype_tract, projected_tractography.tracts()[0]) + + for k, v in projected_tractography.tracts_data().iteritems(): + v = v[0] + if k.startswith('point_id') and k.endswith('mean'): + assert_array_equal(v[0::2], enumeration[0::2]) + assert_array_equal(v[1::2], nanarray[1::2]) + elif k.startswith('point_id') and k.endswith('std'): + assert_array_equal(v[0::2], v[0::2] * 0) + assert_array_equal(v[1::2], nanarray[1::2]) diff --git a/tract_querier/tract_math/tract_stats.py b/tract_querier/tract_math/tract_stats.py new file mode 100644 index 0000000..bd8885c --- /dev/null +++ b/tract_querier/tract_math/tract_stats.py @@ -0,0 +1,194 @@ +from .decorator import tract_math_operation, TractMathWrongArgumentsError +from warnings import warn + + +try: + from collections import OrderedDict +except ImportError: # Python 2.6 fix + from ordereddict import OrderedDict + +import numpy + +import nibabel +from nibabel.spatialimages import SpatialImage + +from ..tractography import Tractography, tractography_to_file, tractography_from_files +from ..tensor import scalar_measures + + +@tract_math_operation(' [distance threshold=8.] : projects a scalar value of the tract to the prototype', needs_one_tract=False) +def tract_scalar_to_prototype(tractographies, prototype_tract, scalar_name, dist_threshold=8., file_output=None): + divide_by_zero_err = numpy.geterr() + numpy.seterr(divide='ignore', invalid='ignore') + + prototype = tractography_from_files([prototype_tract]) + if len(prototype.tracts()) != 1: + raise TractMathWrongArgumentsError('Prototype file %s must have a single tract' % prototype_tract) + for i, tractography in enumerate(tractographies): + if scalar_name not in tractography.tracts_data(): + raise TractMathWrongArgumentsError( + 'Input tractography %d does not have ' + 'the required scalar property' % i + ) + + prototype_tract = prototype.tracts()[0] + tangents = numpy.r_[(prototype_tract[:-1] - prototype_tract[1:]), (prototype_tract[-2] - prototype_tract[-1])[None, :]] + prototype_arc_length = numpy.r_[0, numpy.cumsum(numpy.sqrt((tangents ** 2).sum(1))[:-1])] + tangent_tensor = tangents[..., None] * tangents[:, None, ...] + + output_scalar_name = scalar_name + '_%04d' + output_data = prototype.tracts_data() + for i, tractography in enumerate(tractographies): + output_scalar_name_ = output_scalar_name % i + if output_scalar_name_ in output_data: + warn('Warning, scalar data %s exists in the prototype tractography' % output_scalar_name_) + + prototype_value_count, prototype_value_sqr_buffer, prototype_value_buffer = project_tractography_to_prototype( + tractography, scalar_name, + prototype_tract, tangent_tensor, + dist_threshold=dist_threshold + ) + + mean_value = numpy.nan_to_num(prototype_value_buffer / prototype_value_count) + mean_value[prototype_value_count == 0] = numpy.nan + std_value = numpy.sqrt(numpy.nan_to_num( + prototype_value_sqr_buffer / prototype_value_count - + mean_value ** 2 + )) + std_value[prototype_value_count == 0] = numpy.nan + + output_data[output_scalar_name_ + '_mean'] = [mean_value] + output_data[output_scalar_name_ + '_std'] = [std_value] + + output_data['arc_length'] = [prototype_arc_length[:, None]] + output_tractography = Tractography(prototype.tracts(), output_data) + + numpy.seterr(**divide_by_zero_err) + return output_tractography + + +@tract_math_operation(' [distance threshold=8.] : projects the prototype arc-length to the tractography', needs_one_tract=True) +def tract_prototype_arclength(tractography, prototype_tract, output_scalar_name, dist_threshold=8., file_output=None): + if isinstance(dist_threshold, str): + dist_threshold = float(dist_threshold) + prototype = tractography_from_files([prototype_tract]) + if len(prototype.tracts()) != 1: + raise TractMathWrongArgumentsError('Prototype file %s must have a single tract' % prototype_tract) + + prototype_tract = prototype.tracts()[0] + tangents = numpy.r_[(prototype_tract[:-1] - prototype_tract[1:]), (prototype_tract[-2] - prototype_tract[-1])[None, :]] + prototype_arc_length = (numpy.r_[0, numpy.cumsum(numpy.sqrt((tangents ** 2).sum(1))[:-1])])[:, None] + tangent_tensor = tangents[..., None] * tangents[:, None, ...] + + scalar_data = project_prototype_to_tractography( + tractography, prototype_tract, tangent_tensor, + prototype_arc_length, dist_threshold=dist_threshold + ) + + tracts_data = tractography.tracts_data() + tracts_data[output_scalar_name] = scalar_data + return Tractography(tractography.tracts(), tracts_data) + + +@tract_math_operation(' [distance threshold=8.] : projects the prototype arc-length to the tractography', needs_one_tract=True) +def tract_prototype_scalar_to_tract(tractography, prototype_tract, scalar, output_scalar_name, dist_threshold=8., file_output=None): + try: + prototype = tractography_from_files([prototype_tract]) + if len(prototype.tracts()) != 1: + raise TractMathWrongArgumentsError('Prototype file %s must have a single tract' % prototype_tract) + + prototype_tract = prototype.tracts()[0] + tangents = numpy.r_[(prototype_tract[:-1] - prototype_tract[1:]), (prototype_tract[-2] - prototype_tract[-1])[None, :]] + tangent_tensor = tangents[..., None] * tangents[:, None, ...] + + scalar_data = project_prototype_to_tractography( + tractography, prototype_tract, + tangent_tensor, prototype.tracts_data()[scalar][0], + dist_threshold=dist_threshold + ) + + tracts_data = tractography.tracts_data() + tracts_data[output_scalar_name] = scalar_data + return Tractography(tractography.tracts(), tracts_data) + except KeyError: + raise TractMathWrongArgumentsError('Scalar value %s not found in prototype' % scalar) + + +def project_tractography_to_prototype(tractography, scalar_name, prototype_tract, tangent_tensor, dist_threshold=8.): + dist_threshold2 = dist_threshold ** 2 + prototype_value_buffer = numpy.zeros((len(prototype_tract), 1)) + prototype_value_sqr_buffer = numpy.zeros((len(prototype_tract), 1)) + prototype_value_count = numpy.zeros((len(prototype_tract), 1), dtype=int) + tracts = tractography.tracts() + scalar_data = tractography.tracts_data()[scalar_name] + for i, tract in enumerate(tracts): + scalar_data_point = scalar_data[i] + for j, point in enumerate(tract): + ix = prototype_index_for_point(tangent_tensor, dist_threshold2, prototype_tract, point) + if ix is None: + continue + value = scalar_data_point[j] + prototype_value_buffer[ix, 0] += value + prototype_value_sqr_buffer[ix, 0] += value ** 2 + prototype_value_count[ix, 0] += 1 + return prototype_value_count, prototype_value_sqr_buffer, prototype_value_buffer + + +def project_prototype_to_tractography(tractography, prototype_tract, tangent_tensor, prototype_data, dist_threshold=8.): + dist_threshold2 = dist_threshold ** 2 + tracts = tractography.tracts() + output_data = [] + nan_vector = numpy.repeat(numpy.nan, prototype_data.shape[1], axis=0)[None, :] + for i, tract in enumerate(tracts): + tract_data = numpy.repeat(nan_vector, len(tract), axis=0) + for j, point in enumerate(tract): + ix = prototype_index_for_point(tangent_tensor, dist_threshold2, prototype_tract, point) + if ix is None: + continue + tract_data[j] = prototype_data[ix] + output_data.append(tract_data) + return output_data + + +def prototype_index_for_point(tangent_tensor, dist_threshold2, prototype_tract, point): + differences = (prototype_tract - point[None, :]) + differences = (prototype_tract - point[None, :]) + distances2 = (differences ** 2).sum(1) + sel_points = distances2 < dist_threshold2 + if not numpy.any(sel_points): + return None + + differences_sel_points = differences[sel_points] + + mh_differences = ( + (tangent_tensor[sel_points] * differences_sel_points[:, None, :]).sum(2) * + differences_sel_points + ).sum(1) + min_points_ix = (mh_differences == mh_differences.min()).nonzero() + sel_points_ix = sel_points.nonzero()[0] + if len(min_points_ix[0]) == 1: + ix = sel_points_ix[min_points_ix[0][0]] + else: + ix = sel_points_ix[min_points_ix[0][((differences[min_points_ix, :] ** 2).sum(1)).argmin()]] + return ix + +@tract_math_operation(' : calculates a tensor-derived measure', needs_one_tract=True) +def tract_tensor_measure(tractography, measure, scalar_name, file_output=None): + try: + tensors = tractography.tracts_data()['tensors'] + + if measure == 'FA': + measure_func = scalar_measures.fractional_anisotropy + + measure = [] + for td in tensors: + t = td.reshape(len(td), 3, 3) + measure.append(measure_func(t)) + + tractography.tracts_data()[scalar_name] = measure + + return tractography + + except KeyError: + raise TractMathWrongArgumentsError('Tensor data should be in the tractography and named "tensors"') + diff --git a/tract_querier/tractography/tractography.py b/tract_querier/tractography/tractography.py index bf28157..5521793 100644 --- a/tract_querier/tractography/tractography.py +++ b/tract_querier/tractography/tractography.py @@ -1,7 +1,14 @@ +from warnings import warn import numpy as np __all__ = ['Tractography'] +try: + from scipy import interpolate + scipy_interpolate = True +except ImportError: + scipy_interpolate = False + class Tractography: r""" @@ -127,7 +134,7 @@ def unfilter_tracts(self): self._tract_map = None - def subsample_tracts(self, points_per_tract): + def subsample_tracts(self, points_per_tract, interpolate_points=False): r""" Subsample the tracts in the dataset to a maximum number of points per tract @@ -145,21 +152,48 @@ def subsample_tracts(self, points_per_tract): for k in self._tracts_data: self._subsampled_data[k] = [] - for i in xrange(len(self._tracts)): - f = self._tracts[i] - s = np.linspace( - 0, - f.shape[0] - 1, - min(f.shape[0], self._quantity_of_points_per_tract) - ).round().astype(int) + if interpolate_points and not scipy_interpolate: + warn( + 'Scipy is needed for interpolated subsampling,' + ' switching to non-interpolated subsampling' + ) + + if not interpolate_points: + for i in xrange(len(self._tracts)): + f = self._tracts[i] + s = np.linspace( + 0, + f.shape[0] - 1, + min(f.shape[0], self._quantity_of_points_per_tract) + ).round().astype(int) - self._subsampled_tracts.append(f[s, :]) + self._subsampled_tracts.append(f[s, :]) - for k, v in self._tracts_data.iteritems(): - if not isinstance(v, str): - self._subsampled_data[k].append(v[i][s]) + for k, v in self._tracts_data.iteritems(): + if not isinstance(v, str): + self._subsampled_data[k].append(v[i][s]) - self._interpolated = False + self._interpolated = False + else: + for i in xrange(len(self._tracts)): + f = self._tracts[i] + segments_length = np.sqrt( + (np.diff(f, axis=0) ** 2).sum(1) + ) + arclength = np.r_[0, np.cumsum(segments_length)] + + spline = interpolate.splprep(f.T, u=arclength)[0] + s = np.linspace(0, arclength[-1], points_per_tract) + new_f = np.r_[interpolate.splev(s, spline)].T + self._subsampled_tracts.append(new_f) + + for k, v in self._tracts_data.iteritems(): + if not isinstance(v, str): + spline_data = interpolate.splprep(v[i].T, u=arclength)[0] + new_data = np.r_[interpolate.splev(s, spline_data)].T + self._subsampled_data[k].append(new_data) + + self._interpolated = True def filter_tracts(self, criterium): r""" From f135b6bbf29f986d91a6cec4e80898bb95993d37 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 26 Jul 2013 08:09:06 -0400 Subject: [PATCH 16/53] ENH: Added the tract_math function to export tracts --- tract_querier/tract_math/tract_stats.py | 42 +++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tract_querier/tract_math/tract_stats.py b/tract_querier/tract_math/tract_stats.py index bd8885c..b0c8bc1 100644 --- a/tract_querier/tract_math/tract_stats.py +++ b/tract_querier/tract_math/tract_stats.py @@ -114,6 +114,48 @@ def tract_prototype_scalar_to_tract(tractography, prototype_tract, scalar, outpu raise TractMathWrongArgumentsError('Scalar value %s not found in prototype' % scalar) +@tract_math_operation(' : Output a csv file per tract with the x,y,z coordinates, the arc-length and a set of scalar values') +def tract_export(tractography, scalar_name, file_output=None): + import re + + output = OrderedDict([ + ('tract_number', []), + ('x', []), + ('y', []), + ('z', []), + ('arc_length', []), + ]) + + scalar_names = [ + scalar_name_ for scalar_name_ in tractography.tracts_data() + if re.match(scalar_name, scalar_name_) + ] + + if len(scalar_names) == 0: + raise TractMathWrongArgumentsError('Scalar attribute %s not found' % scalar_name) + + for scalar_name_ in scalar_names: + output[scalar_name_] = [] + + for i, tract in enumerate(tractography.tracts()): + x, y, z = tract.T + + tangents = numpy.r_[(tract[:-1] - tract[1:]), (tract[-2] - tract[-1])[None, :]] + arc_length = numpy.r_[0, numpy.cumsum(numpy.sqrt((tangents ** 2).sum(1))[:-1])] + + output['x'] += x.tolist() + output['y'] += y.tolist() + output['z'] += z.tolist() + output['arc_length'] += arc_length.tolist() + output['tract_number'] += [i] * len(tract) + + for scalar_name_ in scalar_names: + tract_data = tractography.tracts_data()[scalar_name_][i] + output[scalar_name_] += tract_data.squeeze().tolist() + + return output + + def project_tractography_to_prototype(tractography, scalar_name, prototype_tract, tangent_tensor, dist_threshold=8.): dist_threshold2 = dist_threshold ** 2 prototype_value_buffer = numpy.zeros((len(prototype_tract), 1)) From 3b746bc7cc187a6586fef0f384da596e26dbeaff Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 26 Jul 2013 08:43:28 -0400 Subject: [PATCH 17/53] BUG: Bug due to tract_math refactoring --- tract_querier/tract_math/operations.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tract_querier/tract_math/operations.py b/tract_querier/tract_math/operations.py index 2ca5e6e..8fcf4f4 100644 --- a/tract_querier/tract_math/operations.py +++ b/tract_querier/tract_math/operations.py @@ -161,7 +161,7 @@ def tract_point_distance_min_max(tractography): @tract_math_operation(' : subsamples tracts to a maximum number of points') -def tract_subsample(tractography, points_per_tract, file_output): +def tract_subsample(tractography, points_per_tract, file_output=None): tractography.subsample_tracts(int(points_per_tract)) return Tractography( @@ -170,7 +170,7 @@ def tract_subsample(tractography, points_per_tract, file_output): @tract_math_operation(' : resamples tracts to a fixed number of points') -def tract_resubsample(tractography, points_per_tract, file_output): +def tract_resubsample(tractography, points_per_tract, file_output=None): tractography.subsample_tracts(int(points_per_tract), True) return Tractography( @@ -179,7 +179,7 @@ def tract_resubsample(tractography, points_per_tract, file_output): @tract_math_operation(' : subsamples tracts to a maximum number of points') -def tract_remove_short_tracts(tractography, min_tract_length, file_output): +def tract_remove_short_tracts(tractography, min_tract_length, file_output=None): min_tract_length = float(min_tract_length) @@ -205,7 +205,7 @@ def tract_remove_short_tracts(tractography, min_tract_length, file_output): @tract_math_operation(' : maps the values of an image to the tract points') -def tract_map_image(tractography, image, quantity_name, file_output): +def tract_map_image(tractography, image, quantity_name, file_output=None): from os import path from scipy import ndimage @@ -243,7 +243,7 @@ def tract_map_image(tractography, image, quantity_name, file_output): @tract_math_operation(' : calculates the mask image from a tract on the space of the given image') -def tract_generate_mask(tractography, image, file_output): +def tract_generate_mask(tractography, image, file_output=None): image = nibabel.load(image) mask = tract_mask(image, tractography) @@ -275,7 +275,7 @@ def tract_generate_population_probability_map(tractographies, image, smoothing=0 @tract_math_operation(' : calculates the probabilistic tract image for these tracts', needs_one_tract=False) -def tract_generate_probability_map(tractographies, image, file_output): +def tract_generate_probability_map(tractographies, image, file_output=None): image = nibabel.load(image) prob_map = tract_probability_map(image, tractographies[0]).astype(float) @@ -290,14 +290,14 @@ def tract_generate_probability_map(tractographies, image, file_output): @tract_math_operation(': strips the data from the tracts', needs_one_tract=True) -def tract_strip(tractography, file_output): +def tract_strip(tractography, file_output=None): tractography_out = Tractography(tractography.tracts()) return tractography_out @tract_math_operation(': takes the union of all tractographies', needs_one_tract=False) -def tract_merge(tractographies, file_output): +def tract_merge(tractographies, file_output=None): all_tracts = [] all_data = {} keys = [set(t.tracts_data().keys()) for t in tractographies] @@ -421,7 +421,7 @@ def voxelized_tract(tractography, resolution): @tract_math_operation(' : smoothes the tract by convolving with a sliding window') -def tract_smooth(tractography, var, file_output): +def tract_smooth(tractography, var, file_output=None): from sklearn.neighbors import BallTree var = float(var) @@ -539,7 +539,7 @@ def tract_in_ijk(image, tractography): @tract_math_operation(': compute the protoype tract') -def tract_prototype_median(tractography, file_output): +def tract_prototype_median(tractography, file_output=None): from .tract_obb import prototype_tract tracts = tractography.tracts() @@ -559,7 +559,7 @@ def tract_prototype_median(tractography, file_output): @tract_math_operation(' : compute the protoype tract') -def tract_prototype_mean(tractography, smooth_order, file_output): +def tract_prototype_mean(tractography, smooth_order, file_output=None): from .tract_obb import prototype_tract tracts = tractography.tracts() From 4640ecd70e9176e96a0c05277f1a4483386cde33 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 26 Jul 2013 11:13:30 -0400 Subject: [PATCH 18/53] COMP: Changed for compatibilty with python 2.6 --- tract_querier/tract_math/ordereddict.py | 258 ++++++++++++++++++++++++ tract_querier/tract_math/tract_obb.py | 28 +-- 2 files changed, 272 insertions(+), 14 deletions(-) create mode 100644 tract_querier/tract_math/ordereddict.py diff --git a/tract_querier/tract_math/ordereddict.py b/tract_querier/tract_math/ordereddict.py new file mode 100644 index 0000000..d817797 --- /dev/null +++ b/tract_querier/tract_math/ordereddict.py @@ -0,0 +1,258 @@ +# Backport of OrderedDict() class that runs on Python 2.4, 2.5, 2.6, 2.7 and pypy. +# Passes Python2.7's test suite and incorporates all the latest updates. + +try: + from thread import get_ident as _get_ident +except ImportError: + from dummy_thread import get_ident as _get_ident + +try: + from _abcoll import KeysView, ValuesView, ItemsView +except ImportError: + pass + + +class OrderedDict(dict): + 'Dictionary that remembers insertion order' + # An inherited dict maps keys to values. + # The inherited dict provides __getitem__, __len__, __contains__, and get. + # The remaining methods are order-aware. + # Big-O running times for all methods are the same as for regular dictionaries. + + # The internal self.__map dictionary maps keys to links in a doubly linked list. + # The circular doubly linked list starts and ends with a sentinel element. + # The sentinel element never gets deleted (this simplifies the algorithm). + # Each link is stored as a list of length three: [PREV, NEXT, KEY]. + + def __init__(self, *args, **kwds): + '''Initialize an ordered dictionary. Signature is the same as for + regular dictionaries, but keyword arguments are not recommended + because their insertion order is arbitrary. + + ''' + if len(args) > 1: + raise TypeError('expected at most 1 arguments, got %d' % len(args)) + try: + self.__root + except AttributeError: + self.__root = root = [] # sentinel node + root[:] = [root, root, None] + self.__map = {} + self.__update(*args, **kwds) + + def __setitem__(self, key, value, dict_setitem=dict.__setitem__): + 'od.__setitem__(i, y) <==> od[i]=y' + # Setting a new item creates a new link which goes at the end of the linked + # list, and the inherited dictionary is updated with the new key/value pair. + if key not in self: + root = self.__root + last = root[0] + last[1] = root[0] = self.__map[key] = [last, root, key] + dict_setitem(self, key, value) + + def __delitem__(self, key, dict_delitem=dict.__delitem__): + 'od.__delitem__(y) <==> del od[y]' + # Deleting an existing item uses self.__map to find the link which is + # then removed by updating the links in the predecessor and successor nodes. + dict_delitem(self, key) + link_prev, link_next, key = self.__map.pop(key) + link_prev[1] = link_next + link_next[0] = link_prev + + def __iter__(self): + 'od.__iter__() <==> iter(od)' + root = self.__root + curr = root[1] + while curr is not root: + yield curr[2] + curr = curr[1] + + def __reversed__(self): + 'od.__reversed__() <==> reversed(od)' + root = self.__root + curr = root[0] + while curr is not root: + yield curr[2] + curr = curr[0] + + def clear(self): + 'od.clear() -> None. Remove all items from od.' + try: + for node in self.__map.itervalues(): + del node[:] + root = self.__root + root[:] = [root, root, None] + self.__map.clear() + except AttributeError: + pass + dict.clear(self) + + def popitem(self, last=True): + '''od.popitem() -> (k, v), return and remove a (key, value) pair. + Pairs are returned in LIFO order if last is true or FIFO order if false. + + ''' + if not self: + raise KeyError('dictionary is empty') + root = self.__root + if last: + link = root[0] + link_prev = link[0] + link_prev[1] = root + root[0] = link_prev + else: + link = root[1] + link_next = link[1] + root[1] = link_next + link_next[0] = root + key = link[2] + del self.__map[key] + value = dict.pop(self, key) + return key, value + + # -- the following methods do not depend on the internal structure -- + + def keys(self): + 'od.keys() -> list of keys in od' + return list(self) + + def values(self): + 'od.values() -> list of values in od' + return [self[key] for key in self] + + def items(self): + 'od.items() -> list of (key, value) pairs in od' + return [(key, self[key]) for key in self] + + def iterkeys(self): + 'od.iterkeys() -> an iterator over the keys in od' + return iter(self) + + def itervalues(self): + 'od.itervalues -> an iterator over the values in od' + for k in self: + yield self[k] + + def iteritems(self): + 'od.iteritems -> an iterator over the (key, value) items in od' + for k in self: + yield (k, self[k]) + + def update(*args, **kwds): + '''od.update(E, **F) -> None. Update od from dict/iterable E and F. + + If E is a dict instance, does: for k in E: od[k] = E[k] + If E has a .keys() method, does: for k in E.keys(): od[k] = E[k] + Or if E is an iterable of items, does: for k, v in E: od[k] = v + In either case, this is followed by: for k, v in F.items(): od[k] = v + + ''' + if len(args) > 2: + raise TypeError('update() takes at most 2 positional ' + 'arguments (%d given)' % (len(args),)) + elif not args: + raise TypeError('update() takes at least 1 argument (0 given)') + self = args[0] + # Make progressively weaker assumptions about "other" + other = () + if len(args) == 2: + other = args[1] + if isinstance(other, dict): + for key in other: + self[key] = other[key] + elif hasattr(other, 'keys'): + for key in other.keys(): + self[key] = other[key] + else: + for key, value in other: + self[key] = value + for key, value in kwds.items(): + self[key] = value + + __update = update # let subclasses override update without breaking __init__ + + __marker = object() + + def pop(self, key, default=__marker): + '''od.pop(k[,d]) -> v, remove specified key and return the corresponding value. + If key is not found, d is returned if given, otherwise KeyError is raised. + + ''' + if key in self: + result = self[key] + del self[key] + return result + if default is self.__marker: + raise KeyError(key) + return default + + def setdefault(self, key, default=None): + 'od.setdefault(k[,d]) -> od.get(k,d), also set od[k]=d if k not in od' + if key in self: + return self[key] + self[key] = default + return default + + def __repr__(self, _repr_running={}): + 'od.__repr__() <==> repr(od)' + call_key = id(self), _get_ident() + if call_key in _repr_running: + return '...' + _repr_running[call_key] = 1 + try: + if not self: + return '%s()' % (self.__class__.__name__,) + return '%s(%r)' % (self.__class__.__name__, self.items()) + finally: + del _repr_running[call_key] + + def __reduce__(self): + 'Return state information for pickling' + items = [[k, self[k]] for k in self] + inst_dict = vars(self).copy() + for k in vars(OrderedDict()): + inst_dict.pop(k, None) + if inst_dict: + return (self.__class__, (items,), inst_dict) + return self.__class__, (items,) + + def copy(self): + 'od.copy() -> a shallow copy of od' + return self.__class__(self) + + @classmethod + def fromkeys(cls, iterable, value=None): + '''OD.fromkeys(S[, v]) -> New ordered dictionary with keys from S + and values equal to v (which defaults to None). + + ''' + d = cls() + for key in iterable: + d[key] = value + return d + + def __eq__(self, other): + '''od.__eq__(y) <==> od==y. Comparison to another OD is order-sensitive + while comparison to a regular mapping is order-insensitive. + + ''' + if isinstance(other, OrderedDict): + return len(self)==len(other) and self.items() == other.items() + return dict.__eq__(self, other) + + def __ne__(self, other): + return not self == other + + # -- the following methods are only used in Python 2.7 -- + + def viewkeys(self): + "od.viewkeys() -> a set-like object providing a view on od's keys" + return KeysView(self) + + def viewvalues(self): + "od.viewvalues() -> an object providing a view on od's values" + return ValuesView(self) + + def viewitems(self): + "od.viewitems() -> a set-like object providing a view on od's items" + return ItemsView(self) diff --git a/tract_querier/tract_math/tract_obb.py b/tract_querier/tract_math/tract_obb.py index 4dfa0fa..83488b7 100644 --- a/tract_querier/tract_math/tract_obb.py +++ b/tract_querier/tract_math/tract_obb.py @@ -659,16 +659,16 @@ def all_obb_3d_along_tract( if clean: labels_count = bincount(labels) - labels_count = { - side: bincount(split_labels[side]) + labels_count = dict([ + (side, bincount(split_labels[side])) for side in split_labels - } + ]) - labels_ratio = { - side: nan_to_num( + labels_ratio = dict([ + (sider, nan_to_num( labels_count[side] * 1. / labels_count[:len(labels_count(side))] - ) for side in labels_count - } + )) for side in labels_count + ]) new_results = [box_center] @@ -756,16 +756,16 @@ def all_obb_3d(points, vectors, labels, tol=1e-8, level=0, intersection_threshol if clean: labels_count = bincount(labels) - labels_count = { - side: bincount(split_labels[side]) + labels_count = dict([ + (side, bincount(split_labels[side])) for side in split_labels - } + ]) - labels_ratio = { - side: nan_to_num( + labels_ratio = dict([ + (side, nan_to_num( labels_count[side] * 1. / labels_count[:len(labels_count(side))] - ) for side in labels_count - } + )) for side in labels_count + ]) new_results = [box_center] print level From 9ce0d4e37de9ae5146e76c3e23c42f06993b0a52 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 26 Jul 2013 13:57:37 -0400 Subject: [PATCH 19/53] ENH: Added tensor measures and other tools to tract_math --- tract_querier/tensor/scalar_measures.py | 26 ++++++++++++++++- .../tensor/tests/test_scalar_measures.py | 24 +++++++++++++++ tract_querier/tract_math/tract_stats.py | 29 +++++++++++++++++-- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/tract_querier/tensor/scalar_measures.py b/tract_querier/tensor/scalar_measures.py index 2fd45f4..ad8921c 100644 --- a/tract_querier/tensor/scalar_measures.py +++ b/tract_querier/tensor/scalar_measures.py @@ -5,7 +5,8 @@ __all__ = [ - 'fractional_anisotropy', 'volume_fraction', + 'fractional_anisotropy', 'volume_fraction', 'axial_diffusivity', + 'radial_diffusivity', 'eigenvalues', 'tensor_trace', 'tensor_contraction', 'tensor_det' ] @@ -83,3 +84,26 @@ def tensor_contraction(tensor_array_1, tensor_array_2): Return the contraction of each tensor pair ''' return (tensor_array_1 * tensor_array_2).sum(-1).sum(-1) + + +def radial_diffusivity(tensor_array): + r''' + Radial diffusivity + + + .. math:: + RA = \frac{\lambda_2 + \lambda_3} 2 + ''' + ev = eigenvalues(tensor_array) + return (ev.sum(1) - ev.max(1)) / 2. + + +def axial_diffusivity(tensor_array): + r''' + Axial diffusivity + + .. math:: + RA = \frac{\lambda_2 + \lambda_3} 2 + ''' + ev = eigenvalues(tensor_array) + return ev.max(1) diff --git a/tract_querier/tensor/tests/test_scalar_measures.py b/tract_querier/tensor/tests/test_scalar_measures.py index a67bb8c..39b855d 100644 --- a/tract_querier/tensor/tests/test_scalar_measures.py +++ b/tract_querier/tensor/tests/test_scalar_measures.py @@ -17,6 +17,30 @@ def test_fractional_anisotropy(N=10, random=numpy.random.RandomState(0)): assert_array_almost_equal(fa, scalar_measures.fractional_anisotropy(tensors)) +def test_axial_diffusivity(N=10, random=numpy.random.RandomState(0)): + tensors = random.randn(N, 3, 3) + d = numpy.empty(N) + for i, t in enumerate(tensors): + tt = numpy.dot(t, t.T) + tensors[i] = tt + ev = numpy.linalg.eigvalsh(tt) + d[i] = ev.max() + + assert_array_almost_equal(d, scalar_measures.axial_diffusivity(tensors)) + + +def test_radial_diffusivity(N=10, random=numpy.random.RandomState(0)): + tensors = random.randn(N, 3, 3) + d = numpy.empty(N) + for i, t in enumerate(tensors): + tt = numpy.dot(t, t.T) + tensors[i] = tt + ev = numpy.linalg.eigvalsh(tt) + d[i] = (ev.sum() - ev.max()) / 2. + + assert_array_almost_equal(d, scalar_measures.radial_diffusivity(tensors)) + + def test_volume_fraction(N=10, random=numpy.random.RandomState(0)): tensors = random.randn(N, 3, 3) vf = numpy.empty(N) diff --git a/tract_querier/tract_math/tract_stats.py b/tract_querier/tract_math/tract_stats.py index b0c8bc1..e93c19f 100644 --- a/tract_querier/tract_math/tract_stats.py +++ b/tract_querier/tract_math/tract_stats.py @@ -214,13 +214,38 @@ def prototype_index_for_point(tangent_tensor, dist_threshold2, prototype_tract, ix = sel_points_ix[min_points_ix[0][((differences[min_points_ix, :] ** 2).sum(1)).argmin()]] return ix -@tract_math_operation(' : calculates a tensor-derived measure', needs_one_tract=True) -def tract_tensor_measure(tractography, measure, scalar_name, file_output=None): + +@tract_math_operation(' [output_scalar_name] : calculates a tensor-derived measure', needs_one_tract=True) +def tract_tensor_measure(tractography, measure, scalar_name=None, file_output=None): try: tensors = tractography.tracts_data()['tensors'] + measure = measure.upper() + + if scalar_name is None: + scalar_name = measure if measure == 'FA': measure_func = scalar_measures.fractional_anisotropy + elif measure == 'RD': + measure_func = scalar_measures.radial_diffusivity + elif measure == 'AD': + measure_func = scalar_measures.axial_diffusivity + elif measure == 'TR': + measure_func = scalar_measures.tensor_trace + elif measure == 'DET': + measure_func = scalar_measures.tensor_det + elif measure == 'VF': + measure_func = scalar_measures.volume_fraction + else: + raise TractMathWrongArgumentsError( + 'Wrong anisotropy measure, avaliable measures are\n' + '\tFA: Fractional anisotropy\n' + '\tRD: Radial diffusivity\n' + '\tAD: Axial diffusivity\n' + '\tTR: Tract\n' + '\tDET: Determinant\n' + '\tVF: Volume fraction' + ) measure = [] for td in tensors: From a559652e6ff2cecd17ebfda4eab583c6f74a2db7 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 26 Jul 2013 15:05:05 -0400 Subject: [PATCH 20/53] ENH: Added a tool to import values from a CSV file to a tractography --- tract_querier/tract_math/tract_stats.py | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tract_querier/tract_math/tract_stats.py b/tract_querier/tract_math/tract_stats.py index e93c19f..3410c1c 100644 --- a/tract_querier/tract_math/tract_stats.py +++ b/tract_querier/tract_math/tract_stats.py @@ -156,6 +156,35 @@ def tract_export(tractography, scalar_name, file_output=None): return output +@tract_math_operation(' : Input a column of a csv file to the tractography') +def tract_import(tractography, scalar_name, csv_input, file_output=None): + if len(tractography.tracts()) != 1: + raise TractMathWrongArgumentsError('The input tractography for this operation can only have one tract') + import re + import csv + + reader = csv.DictReader(open(csv_input)) + + scalar_names = [ + name for name in reader.fieldnames + if re.match(scalar_name, name) + ] + + tracts_data = tractography.tracts_data() + tract = tractography.tracts()[0] + for name in scalar_names: + tracts_data[name] = [numpy.empty(len(tract))[:, None]] + + for i, row in enumerate(reader): + for name in scalar_names: + tracts_data[name][0][i] = float(row[name]) + + if i < len(tract[0]): + raise TractMathWrongArgumentsError('The input CSV needs to have %d rows' % len(tract)) + + return tractography + + def project_tractography_to_prototype(tractography, scalar_name, prototype_tract, tangent_tensor, dist_threshold=8.): dist_threshold2 = dist_threshold ** 2 prototype_value_buffer = numpy.zeros((len(prototype_tract), 1)) From 3d90e46af6dae1838dcbe9fac1b182e20b82ed95 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Mon, 12 Aug 2013 16:39:05 -0400 Subject: [PATCH 21/53] ENH: Refactored tract_math support --- tract_querier/tract_math/__init__.py | 7 + tract_querier/tract_math/operations.py | 14 +- ...ract_stats.py => test_tract_pojections.py} | 6 +- tract_querier/tract_math/tract_projections.py | 256 +++++++++++++ tract_querier/tract_math/tract_stats.py | 362 +++++++----------- 5 files changed, 402 insertions(+), 243 deletions(-) rename tract_querier/tract_math/tests/{test_tract_stats.py => test_tract_pojections.py} (93%) create mode 100644 tract_querier/tract_math/tract_projections.py diff --git a/tract_querier/tract_math/__init__.py b/tract_querier/tract_math/__init__.py index 49b9227..d5ac5a8 100644 --- a/tract_querier/tract_math/__init__.py +++ b/tract_querier/tract_math/__init__.py @@ -16,3 +16,10 @@ for f in getmembers(_tract_stats): if hasattr(f[1], 'help_text'): tract_math_operations[f[0]] = f[1] + + +import tract_projections as _tract_projections + +for f in getmembers(_tract_projections): + if hasattr(f[1], 'help_text'): + tract_math_operations[f[0]] = f[1] diff --git a/tract_querier/tract_math/operations.py b/tract_querier/tract_math/operations.py index 8fcf4f4..ca1968f 100644 --- a/tract_querier/tract_math/operations.py +++ b/tract_querier/tract_math/operations.py @@ -206,25 +206,23 @@ def tract_remove_short_tracts(tractography, min_tract_length, file_output=None): @tract_math_operation(' : maps the values of an image to the tract points') def tract_map_image(tractography, image, quantity_name, file_output=None): - from os import path from scipy import ndimage image = nibabel.load(image) ijk_points = tract_in_ijk(image, tractography) - image_data = image.get_data() + image_data = image.get_data().squeeze() if image_data.ndim > 3: - output_name, ext = path.splitext(file_output) - output_name = output_name + '_%04d' + ext - for i, image in enumerate(image_data): + for i in xrange(image_data.shape[-1]): + image = image_data[..., i] new_scalar_data = ndimage.map_coordinates( image.T, ijk_points.T )[:, None] tractography.original_tracts_data()[ - quantity_name] = new_scalar_data - tractography_to_file(output_name % i, Tractography( - tractography.original_tracts(), tractography.original_tracts_data())) + quantity_name + '_%04d' % i + ] = new_scalar_data + return tractography else: new_scalar_data_flat = ndimage.map_coordinates( image_data.T, ijk_points.T diff --git a/tract_querier/tract_math/tests/test_tract_stats.py b/tract_querier/tract_math/tests/test_tract_pojections.py similarity index 93% rename from tract_querier/tract_math/tests/test_tract_stats.py rename to tract_querier/tract_math/tests/test_tract_pojections.py index 46f17ec..eb0d5fa 100644 --- a/tract_querier/tract_math/tests/test_tract_stats.py +++ b/tract_querier/tract_math/tests/test_tract_pojections.py @@ -1,5 +1,5 @@ from ... import tractography -from .. import tract_stats +from .. import tract_projections import os import tempfile @@ -35,7 +35,7 @@ def test_tract_scalar_to_prototype_one_to_one(random=numpy.random.RandomState(0) fname_proto, tractography_prototype ) - projected_tractography = tract_stats.tract_scalar_to_prototype.original_function( + projected_tractography = tract_projections.tract_scalar_to_prototype.original_function( [tractography_bundle], fname_proto, 'point_id' ) @@ -79,7 +79,7 @@ def test_tract_scalar_to_prototype_one_to_many(random=numpy.random.RandomState(0 fname_proto, tractography_prototype ) - projected_tractography = tract_stats.tract_scalar_to_prototype.original_function( + projected_tractography = tract_projections.tract_scalar_to_prototype.original_function( [tractography_bundle], fname_proto, 'point_id' ) diff --git a/tract_querier/tract_math/tract_projections.py b/tract_querier/tract_math/tract_projections.py new file mode 100644 index 0000000..7c83208 --- /dev/null +++ b/tract_querier/tract_math/tract_projections.py @@ -0,0 +1,256 @@ +from .decorator import tract_math_operation, TractMathWrongArgumentsError +from warnings import warn + + +try: + from collections import OrderedDict +except ImportError: # Python 2.6 fix + from ordereddict import OrderedDict + +import numpy + + +from ..tractography import Tractography, tractography_from_files + + +@tract_math_operation(' [distance threshold=8.] : projects a scalar value of the tract to the prototype', needs_one_tract=False) +def tract_scalar_to_prototype(tractographies, prototype_tract, scalar_name, dist_threshold=8., file_output=None): + import re + + divide_by_zero_err = numpy.geterr() + numpy.seterr(divide='ignore', invalid='ignore') + + prototype = tractography_from_files([prototype_tract]) + if len(prototype.tracts()) != 1: + raise TractMathWrongArgumentsError('Prototype file %s must have a single tract' % prototype_tract) + + scalar_names = [ + scalar_name_ for scalar_name_ in tractographies[0].tracts_data() + if re.match('^' + scalar_name + '$', scalar_name_) + ] + scalar_names_set = set(scalar_names) + for i, tractography in enumerate(tractographies): + if not set(tractography.tracts_data().keys()).issuperset(scalar_names_set): + raise TractMathWrongArgumentsError( + 'Input tractography %d does not have ' + 'the required scalar property' % i + ) + + prototype_tract = prototype.tracts()[0] + tangents = numpy.r_[(prototype_tract[:-1] - prototype_tract[1:]), (prototype_tract[-2] - prototype_tract[-1])[None, :]] + prototype_arc_length = numpy.r_[0, numpy.cumsum(numpy.sqrt((tangents ** 2).sum(1))[:-1])] + tangent_tensor = tangents[..., None] * tangents[:, None, ...] + + for scalar_name in scalar_names: + output_scalar_name = scalar_name + output_data = prototype.tracts_data() + for i, tractography in enumerate(tractographies): + if len(tractographies) > 1: + output_scalar_name_ = output_scalar_name + '_%04d' % i + else: + output_scalar_name_ = output_scalar_name + + if output_scalar_name_ in output_data: + warn('Warning, scalar data %s exists in the prototype tractography' % output_scalar_name_) + + prototype_value_count, prototype_value_sqr_buffer, prototype_value_buffer = project_tractography_to_prototype( + tractography, scalar_name, + prototype_tract, tangent_tensor, + dist_threshold=dist_threshold + ) + + mean_value = numpy.nan_to_num(prototype_value_buffer / prototype_value_count) + mean_value[prototype_value_count == 0] = numpy.nan + std_value = numpy.sqrt(numpy.nan_to_num( + prototype_value_sqr_buffer / prototype_value_count - + mean_value ** 2 + )) + std_value[prototype_value_count == 0] = numpy.nan + + output_data[output_scalar_name_ + '_mean'] = [mean_value] + output_data[output_scalar_name_ + '_std'] = [std_value] + + output_data['arc_length'] = [prototype_arc_length[:, None]] + output_tractography = Tractography(prototype.tracts(), output_data) + + numpy.seterr(**divide_by_zero_err) + return output_tractography + + +@tract_math_operation(' [distance threshold=8.] : projects the prototype arc-length to the tractography', needs_one_tract=True) +def tract_prototype_arclength(tractography, prototype_tract, output_scalar_name, dist_threshold=8., file_output=None): + if isinstance(dist_threshold, str): + dist_threshold = float(dist_threshold) + prototype = tractography_from_files([prototype_tract]) + if len(prototype.tracts()) != 1: + raise TractMathWrongArgumentsError('Prototype file %s must have a single tract' % prototype_tract) + + prototype_tract = prototype.tracts()[0] + tangents = numpy.r_[(prototype_tract[:-1] - prototype_tract[1:]), (prototype_tract[-2] - prototype_tract[-1])[None, :]] + prototype_arc_length = (numpy.r_[0, numpy.cumsum(numpy.sqrt((tangents ** 2).sum(1))[:-1])])[:, None] + tangent_tensor = tangents[..., None] * tangents[:, None, ...] + + scalar_data = project_prototype_to_tractography( + tractography, prototype_tract, tangent_tensor, + prototype_arc_length, dist_threshold=dist_threshold + ) + + tracts_data = tractography.tracts_data() + tracts_data[output_scalar_name] = scalar_data + return Tractography(tractography.tracts(), tracts_data) + + +@tract_math_operation(' [distance threshold=8.] : projects the prototype arc-length to the tractography', needs_one_tract=True) +def tract_prototype_scalar_to_tract(tractography, prototype_tract, scalar, output_scalar_name, dist_threshold=8., file_output=None): + try: + prototype = tractography_from_files([prototype_tract]) + if len(prototype.tracts()) != 1: + raise TractMathWrongArgumentsError('Prototype file %s must have a single tract' % prototype_tract) + + prototype_tract = prototype.tracts()[0] + tangents = numpy.r_[(prototype_tract[:-1] - prototype_tract[1:]), (prototype_tract[-2] - prototype_tract[-1])[None, :]] + tangent_tensor = tangents[..., None] * tangents[:, None, ...] + + scalar_data = project_prototype_to_tractography( + tractography, prototype_tract, + tangent_tensor, prototype.tracts_data()[scalar][0], + dist_threshold=dist_threshold + ) + + tracts_data = tractography.tracts_data() + tracts_data[output_scalar_name] = scalar_data + return Tractography(tractography.tracts(), tracts_data) + except KeyError: + raise TractMathWrongArgumentsError('Scalar value %s not found in prototype' % scalar) + + +@tract_math_operation(' : Output a csv file per tract with the x,y,z coordinates, the arc-length and a set of scalar values') +def tract_export(tractography, scalar_name, file_output=None): + import re + + output = OrderedDict([ + ('tract_number', []), + ('x', []), + ('y', []), + ('z', []), + ('arc_length', []), + ]) + + scalar_names = [ + scalar_name_ for scalar_name_ in tractography.tracts_data() + if re.match('^' + scalar_name + '$', scalar_name_) + ] + + if len(scalar_names) == 0: + raise TractMathWrongArgumentsError('Scalar attribute %s not found' % scalar_name) + + for scalar_name_ in scalar_names: + output[scalar_name_] = [] + + for i, tract in enumerate(tractography.tracts()): + x, y, z = tract.T + + tangents = numpy.r_[(tract[:-1] - tract[1:]), (tract[-2] - tract[-1])[None, :]] + arc_length = numpy.r_[0, numpy.cumsum(numpy.sqrt((tangents ** 2).sum(1))[:-1])] + + output['x'] += x.tolist() + output['y'] += y.tolist() + output['z'] += z.tolist() + output['arc_length'] += arc_length.tolist() + output['tract_number'] += [i] * len(tract) + + for scalar_name_ in scalar_names: + tract_data = tractography.tracts_data()[scalar_name_][i] + output[scalar_name_] += tract_data.squeeze().tolist() + + return output + + +@tract_math_operation(' : Input a column of a csv file to the tractography') +def tract_import(tractography, scalar_name, csv_input, file_output=None): + if len(tractography.tracts()) != 1: + raise TractMathWrongArgumentsError('The input tractography for this operation can only have one tract') + import re + import csv + + reader = csv.DictReader(open(csv_input)) + + scalar_names = [ + name for name in reader.fieldnames + if re.match('^' + scalar_name + '$', name) + ] + + tracts_data = tractography.tracts_data() + tract = tractography.tracts()[0] + for name in scalar_names: + tracts_data[name] = [numpy.empty(len(tract))[:, None]] + + for i, row in enumerate(reader): + for name in scalar_names: + tracts_data[name][0][i] = float(row[name]) + + if i < len(tract[0]): + raise TractMathWrongArgumentsError('The input CSV needs to have %d rows' % len(tract)) + + return tractography + + +def project_tractography_to_prototype(tractography, scalar_name, prototype_tract, tangent_tensor, dist_threshold=8.): + dist_threshold2 = dist_threshold ** 2 + prototype_value_buffer = numpy.zeros((len(prototype_tract), 1)) + prototype_value_sqr_buffer = numpy.zeros((len(prototype_tract), 1)) + prototype_value_count = numpy.zeros((len(prototype_tract), 1), dtype=int) + tracts = tractography.tracts() + scalar_data = tractography.tracts_data()[scalar_name] + for i, tract in enumerate(tracts): + scalar_data_point = scalar_data[i] + for j, point in enumerate(tract): + ix = prototype_index_for_point(tangent_tensor, dist_threshold2, prototype_tract, point) + if ix is None: + continue + value = scalar_data_point[j] + prototype_value_buffer[ix, 0] += value + prototype_value_sqr_buffer[ix, 0] += value ** 2 + prototype_value_count[ix, 0] += 1 + return prototype_value_count, prototype_value_sqr_buffer, prototype_value_buffer + + +def project_prototype_to_tractography(tractography, prototype_tract, tangent_tensor, prototype_data, dist_threshold=8.): + dist_threshold2 = dist_threshold ** 2 + tracts = tractography.tracts() + output_data = [] + nan_vector = numpy.repeat(numpy.nan, prototype_data.shape[1], axis=0)[None, :] + for i, tract in enumerate(tracts): + tract_data = numpy.repeat(nan_vector, len(tract), axis=0) + for j, point in enumerate(tract): + ix = prototype_index_for_point(tangent_tensor, dist_threshold2, prototype_tract, point) + if ix is None: + continue + tract_data[j] = prototype_data[ix] + output_data.append(tract_data) + return output_data + + +def prototype_index_for_point(tangent_tensor, dist_threshold2, prototype_tract, point): + differences = (prototype_tract - point[None, :]) + differences = (prototype_tract - point[None, :]) + distances2 = (differences ** 2).sum(1) + sel_points = distances2 < dist_threshold2 + if not numpy.any(sel_points): + return None + + differences_sel_points = differences[sel_points] + + mh_differences = ( + (tangent_tensor[sel_points] * differences_sel_points[:, None, :]).sum(2) * + differences_sel_points + ).sum(1) + min_points_ix = (mh_differences == mh_differences.min()).nonzero() + sel_points_ix = sel_points.nonzero()[0] + if len(min_points_ix[0]) == 1: + ix = sel_points_ix[min_points_ix[0][0]] + else: + ix = sel_points_ix[min_points_ix[0][((differences[min_points_ix, :] ** 2).sum(1)).argmin()]] + return ix + + diff --git a/tract_querier/tract_math/tract_stats.py b/tract_querier/tract_math/tract_stats.py index 3410c1c..f380b12 100644 --- a/tract_querier/tract_math/tract_stats.py +++ b/tract_querier/tract_math/tract_stats.py @@ -1,247 +1,19 @@ from .decorator import tract_math_operation, TractMathWrongArgumentsError from warnings import warn +import numpy + try: from collections import OrderedDict except ImportError: # Python 2.6 fix from ordereddict import OrderedDict -import numpy import nibabel -from nibabel.spatialimages import SpatialImage - -from ..tractography import Tractography, tractography_to_file, tractography_from_files -from ..tensor import scalar_measures - - -@tract_math_operation(' [distance threshold=8.] : projects a scalar value of the tract to the prototype', needs_one_tract=False) -def tract_scalar_to_prototype(tractographies, prototype_tract, scalar_name, dist_threshold=8., file_output=None): - divide_by_zero_err = numpy.geterr() - numpy.seterr(divide='ignore', invalid='ignore') - - prototype = tractography_from_files([prototype_tract]) - if len(prototype.tracts()) != 1: - raise TractMathWrongArgumentsError('Prototype file %s must have a single tract' % prototype_tract) - for i, tractography in enumerate(tractographies): - if scalar_name not in tractography.tracts_data(): - raise TractMathWrongArgumentsError( - 'Input tractography %d does not have ' - 'the required scalar property' % i - ) - - prototype_tract = prototype.tracts()[0] - tangents = numpy.r_[(prototype_tract[:-1] - prototype_tract[1:]), (prototype_tract[-2] - prototype_tract[-1])[None, :]] - prototype_arc_length = numpy.r_[0, numpy.cumsum(numpy.sqrt((tangents ** 2).sum(1))[:-1])] - tangent_tensor = tangents[..., None] * tangents[:, None, ...] - - output_scalar_name = scalar_name + '_%04d' - output_data = prototype.tracts_data() - for i, tractography in enumerate(tractographies): - output_scalar_name_ = output_scalar_name % i - if output_scalar_name_ in output_data: - warn('Warning, scalar data %s exists in the prototype tractography' % output_scalar_name_) - - prototype_value_count, prototype_value_sqr_buffer, prototype_value_buffer = project_tractography_to_prototype( - tractography, scalar_name, - prototype_tract, tangent_tensor, - dist_threshold=dist_threshold - ) - - mean_value = numpy.nan_to_num(prototype_value_buffer / prototype_value_count) - mean_value[prototype_value_count == 0] = numpy.nan - std_value = numpy.sqrt(numpy.nan_to_num( - prototype_value_sqr_buffer / prototype_value_count - - mean_value ** 2 - )) - std_value[prototype_value_count == 0] = numpy.nan - - output_data[output_scalar_name_ + '_mean'] = [mean_value] - output_data[output_scalar_name_ + '_std'] = [std_value] - - output_data['arc_length'] = [prototype_arc_length[:, None]] - output_tractography = Tractography(prototype.tracts(), output_data) - - numpy.seterr(**divide_by_zero_err) - return output_tractography - - -@tract_math_operation(' [distance threshold=8.] : projects the prototype arc-length to the tractography', needs_one_tract=True) -def tract_prototype_arclength(tractography, prototype_tract, output_scalar_name, dist_threshold=8., file_output=None): - if isinstance(dist_threshold, str): - dist_threshold = float(dist_threshold) - prototype = tractography_from_files([prototype_tract]) - if len(prototype.tracts()) != 1: - raise TractMathWrongArgumentsError('Prototype file %s must have a single tract' % prototype_tract) - - prototype_tract = prototype.tracts()[0] - tangents = numpy.r_[(prototype_tract[:-1] - prototype_tract[1:]), (prototype_tract[-2] - prototype_tract[-1])[None, :]] - prototype_arc_length = (numpy.r_[0, numpy.cumsum(numpy.sqrt((tangents ** 2).sum(1))[:-1])])[:, None] - tangent_tensor = tangents[..., None] * tangents[:, None, ...] - - scalar_data = project_prototype_to_tractography( - tractography, prototype_tract, tangent_tensor, - prototype_arc_length, dist_threshold=dist_threshold - ) - - tracts_data = tractography.tracts_data() - tracts_data[output_scalar_name] = scalar_data - return Tractography(tractography.tracts(), tracts_data) - - -@tract_math_operation(' [distance threshold=8.] : projects the prototype arc-length to the tractography', needs_one_tract=True) -def tract_prototype_scalar_to_tract(tractography, prototype_tract, scalar, output_scalar_name, dist_threshold=8., file_output=None): - try: - prototype = tractography_from_files([prototype_tract]) - if len(prototype.tracts()) != 1: - raise TractMathWrongArgumentsError('Prototype file %s must have a single tract' % prototype_tract) - - prototype_tract = prototype.tracts()[0] - tangents = numpy.r_[(prototype_tract[:-1] - prototype_tract[1:]), (prototype_tract[-2] - prototype_tract[-1])[None, :]] - tangent_tensor = tangents[..., None] * tangents[:, None, ...] - - scalar_data = project_prototype_to_tractography( - tractography, prototype_tract, - tangent_tensor, prototype.tracts_data()[scalar][0], - dist_threshold=dist_threshold - ) - - tracts_data = tractography.tracts_data() - tracts_data[output_scalar_name] = scalar_data - return Tractography(tractography.tracts(), tracts_data) - except KeyError: - raise TractMathWrongArgumentsError('Scalar value %s not found in prototype' % scalar) - - -@tract_math_operation(' : Output a csv file per tract with the x,y,z coordinates, the arc-length and a set of scalar values') -def tract_export(tractography, scalar_name, file_output=None): - import re - - output = OrderedDict([ - ('tract_number', []), - ('x', []), - ('y', []), - ('z', []), - ('arc_length', []), - ]) - - scalar_names = [ - scalar_name_ for scalar_name_ in tractography.tracts_data() - if re.match(scalar_name, scalar_name_) - ] - - if len(scalar_names) == 0: - raise TractMathWrongArgumentsError('Scalar attribute %s not found' % scalar_name) - - for scalar_name_ in scalar_names: - output[scalar_name_] = [] - - for i, tract in enumerate(tractography.tracts()): - x, y, z = tract.T - - tangents = numpy.r_[(tract[:-1] - tract[1:]), (tract[-2] - tract[-1])[None, :]] - arc_length = numpy.r_[0, numpy.cumsum(numpy.sqrt((tangents ** 2).sum(1))[:-1])] - - output['x'] += x.tolist() - output['y'] += y.tolist() - output['z'] += z.tolist() - output['arc_length'] += arc_length.tolist() - output['tract_number'] += [i] * len(tract) - for scalar_name_ in scalar_names: - tract_data = tractography.tracts_data()[scalar_name_][i] - output[scalar_name_] += tract_data.squeeze().tolist() - - return output - - -@tract_math_operation(' : Input a column of a csv file to the tractography') -def tract_import(tractography, scalar_name, csv_input, file_output=None): - if len(tractography.tracts()) != 1: - raise TractMathWrongArgumentsError('The input tractography for this operation can only have one tract') - import re - import csv - - reader = csv.DictReader(open(csv_input)) - - scalar_names = [ - name for name in reader.fieldnames - if re.match(scalar_name, name) - ] - - tracts_data = tractography.tracts_data() - tract = tractography.tracts()[0] - for name in scalar_names: - tracts_data[name] = [numpy.empty(len(tract))[:, None]] - - for i, row in enumerate(reader): - for name in scalar_names: - tracts_data[name][0][i] = float(row[name]) - - if i < len(tract[0]): - raise TractMathWrongArgumentsError('The input CSV needs to have %d rows' % len(tract)) - - return tractography - - -def project_tractography_to_prototype(tractography, scalar_name, prototype_tract, tangent_tensor, dist_threshold=8.): - dist_threshold2 = dist_threshold ** 2 - prototype_value_buffer = numpy.zeros((len(prototype_tract), 1)) - prototype_value_sqr_buffer = numpy.zeros((len(prototype_tract), 1)) - prototype_value_count = numpy.zeros((len(prototype_tract), 1), dtype=int) - tracts = tractography.tracts() - scalar_data = tractography.tracts_data()[scalar_name] - for i, tract in enumerate(tracts): - scalar_data_point = scalar_data[i] - for j, point in enumerate(tract): - ix = prototype_index_for_point(tangent_tensor, dist_threshold2, prototype_tract, point) - if ix is None: - continue - value = scalar_data_point[j] - prototype_value_buffer[ix, 0] += value - prototype_value_sqr_buffer[ix, 0] += value ** 2 - prototype_value_count[ix, 0] += 1 - return prototype_value_count, prototype_value_sqr_buffer, prototype_value_buffer - - -def project_prototype_to_tractography(tractography, prototype_tract, tangent_tensor, prototype_data, dist_threshold=8.): - dist_threshold2 = dist_threshold ** 2 - tracts = tractography.tracts() - output_data = [] - nan_vector = numpy.repeat(numpy.nan, prototype_data.shape[1], axis=0)[None, :] - for i, tract in enumerate(tracts): - tract_data = numpy.repeat(nan_vector, len(tract), axis=0) - for j, point in enumerate(tract): - ix = prototype_index_for_point(tangent_tensor, dist_threshold2, prototype_tract, point) - if ix is None: - continue - tract_data[j] = prototype_data[ix] - output_data.append(tract_data) - return output_data - - -def prototype_index_for_point(tangent_tensor, dist_threshold2, prototype_tract, point): - differences = (prototype_tract - point[None, :]) - differences = (prototype_tract - point[None, :]) - distances2 = (differences ** 2).sum(1) - sel_points = distances2 < dist_threshold2 - if not numpy.any(sel_points): - return None - - differences_sel_points = differences[sel_points] - - mh_differences = ( - (tangent_tensor[sel_points] * differences_sel_points[:, None, :]).sum(2) * - differences_sel_points - ).sum(1) - min_points_ix = (mh_differences == mh_differences.min()).nonzero() - sel_points_ix = sel_points.nonzero()[0] - if len(min_points_ix[0]) == 1: - ix = sel_points_ix[min_points_ix[0][0]] - else: - ix = sel_points_ix[min_points_ix[0][((differences[min_points_ix, :] ** 2).sum(1)).argmin()]] - return ix +from tract_querier.tensor import scalar_measures +from tract_querier.tract_math.decorator import tract_math_operation, TractMathWrongArgumentsError @tract_math_operation(' [output_scalar_name] : calculates a tensor-derived measure', needs_one_tract=True) @@ -288,3 +60,129 @@ def tract_tensor_measure(tractography, measure, scalar_name=None, file_output=No except KeyError: raise TractMathWrongArgumentsError('Tensor data should be in the tractography and named "tensors"') + +@tract_math_operation( + ' : fit a design matrix to a set of scalars on the tract', + needs_one_tract=True +) +def tract_stat_ttest(tractography, scalars, design_matrix_fname, contrast_fname, output_scalar_prefix, file_output=None): + import statsmodels.api as sm + + tract_data = tractography.tracts_data() + + if ' ' in scalars: + scalars = scalars.split(' ') + elif ',' in scalars: + scalars = scalars.split(',') + else: + import re + scalars = [ + scalar for scalar in tract_data.keys() + if re.match('^' + scalars + '$', scalar) + ] + scalars.sort() + + try: + design_matrix = numpy.atleast_2d(numpy.loadtxt(design_matrix_fname, comments='/')) + except IOError: + raise TractMathWrongArgumentsError('Error reading design matrix file %s' % design_matrix_fname) + + if design_matrix.shape[0] == 1: + design_matrix = design_matrix.T + + if design_matrix.shape[0] != len(scalars): + raise TractMathWrongArgumentsError('The number of rows in the matrix must be the same as scalar values') + + try: + contrasts = numpy.atleast_2d(numpy.loadtxt(contrast_fname, comments='/')) + except IOError: + raise TractMathWrongArgumentsError('Error reading contrast file %s' % contrast_fname) + + if contrasts.shape[1] != design_matrix.shape[1]: + raise TractMathWrongArgumentsError('The number of columns in the contrasts must be the same columns in the design matrix') + + tract_lengths = numpy.array([len(tract) for tract in tractography.tracts()]) + per_scalar_data = numpy.empty((tract_lengths.sum(), len(scalars))) + + for i, scalar in enumerate(scalars): + try: + value = tract_data[scalar] + per_scalar_data[:, i] = numpy.hstack(value).squeeze() + except KeyError: + raise TractMathWrongArgumentsError('Scalar %s not found in the tractography' % scalar) + + for i, contrast in enumerate(contrasts): + output_scalar = output_scalar_prefix + '_%04d' % i + tract_data[output_scalar + '_t_score'] = [] + tract_data[output_scalar + '_t_pvalue'] = [] + tract_data[output_scalar + '_t_df'] = [] + tract_data[output_scalar + '_t_df'] = [] + tract_data[output_scalar + '_t_effect'] = [] + tract_data[output_scalar + '_t_sd'] = [] + point = 0 + for tract_length in tract_lengths: + current_t = numpy.empty((tract_length, 1)) + current_p = numpy.empty((tract_length, 1)) + current_d = numpy.empty((tract_length, 1)) + current_e = numpy.empty((tract_length, 1)) + current_s = numpy.empty((tract_length, 1)) + + for p in xrange(tract_length): + glm = sm.GLM(per_scalar_data[point], design_matrix) + t_test = glm.fit().t_test(contrast) + current_t[p, :] = t_test.tvalue + current_p[p, :] = t_test.pvalue + current_d[p, :] = t_test.df_denom + current_e[p, :] = t_test.effect + current_s[p, :] = t_test.sd + point += 1 + tract_data[output_scalar + '_t_score'].append(current_t) + tract_data[output_scalar + '_t_pvalue'].append(current_p) + tract_data[output_scalar + '_t_df'].append(current_d) + tract_data[output_scalar + '_t_effect'].append(current_e) + tract_data[output_scalar + '_t_sd'].append(current_s) + + return tractography + + +@tract_math_operation( + ' : correct the p-values with FDR', + needs_one_tract=True +) +def tract_stat_multiple_correction(tractography, method, scalar, threshold, file_output=None): + method = method.strip() + threshold = float(threshold) + methods = ( + 'bonferroni', 'sidak', + 'holm-sidak', 'holm', + 'simes-hochberg', 'hommel', + 'fdr_bh', 'fdr_by' + ) + + if method not in methods: + methods_list = reduce( + lambda x, y: x + '\t' + y + '\n', + methods, '' + )[:-1] + raise TractMathWrongArgumentsError( + 'Method %s not in the list: \n' % scalar + + methods_list + ) + + try: + from statsmodels.stats.multitest import multipletests + tracts_data = tractography.tracts_data()[scalar] + new_tracts_data = [] + for tract_data in tracts_data: + _, corr_pvalues, _, _ = multipletests( + tract_data.squeeze(), alpha=threshold, + method=method + ) + new_tracts_data.append(corr_pvalues[:, None]) + tractography.tracts_data()['%s_corr_%s' % (scalar, method)] = new_tracts_data + + return tractography + except KeyError: + raise TractMathWrongArgumentsError('Scalar %s not in tractography' % scalar) + except ImportError: + raise TractMathWrongArgumentsError('statsmodule package not installed') From bdaac87a1f149a5c25672686688f36b3ff2c6fa4 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Thu, 10 Oct 2013 10:56:38 -0300 Subject: [PATCH 22/53] BUG: Corrected bug in refactoring --- tract_querier/tract_math/operations.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tract_querier/tract_math/operations.py b/tract_querier/tract_math/operations.py index ca1968f..b755632 100644 --- a/tract_querier/tract_math/operations.py +++ b/tract_querier/tract_math/operations.py @@ -269,7 +269,7 @@ def tract_generate_population_probability_map(tractographies, image, smoothing=0 prob_map /= len(tractographies) - return SpatialImage(prob_map, image.get_affine()), + return SpatialImage(prob_map, image.get_affine()) @tract_math_operation(' : calculates the probabilistic tract image for these tracts', needs_one_tract=False) From f4ce2a02d75155a9339cea6ad4b9fc61dcaf1529 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Thu, 10 Oct 2013 10:57:04 -0300 Subject: [PATCH 23/53] BUG: Corrected problem with the tests --- tract_querier/tractography/tests/test_tractography.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tract_querier/tractography/tests/test_tractography.py b/tract_querier/tractography/tests/test_tractography.py index a48365f..6b01a86 100644 --- a/tract_querier/tractography/tests/test_tractography.py +++ b/tract_querier/tractography/tests/test_tractography.py @@ -23,6 +23,8 @@ def equal_tracts(a, b): for t1, t2 in izip(a, b): + if len(t1) != len(t2): + return False if not allclose(t1, t2): return False @@ -40,6 +42,8 @@ def equal_tracts_data(a, b): continue elif not isinstance(v1, str) and not isinstance(v2, str): for t1, t2 in izip(a[k], b[k]): + if len(t1) != len(t2): + return False if not allclose(t1, t2): return False else: From 3b8a4781eece274fcafbe92594e07ed21738fab1 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Thu, 10 Oct 2013 12:37:09 -0300 Subject: [PATCH 24/53] BUG: Corrected bug for the 0-tract tractography case --- tract_querier/tract_math/operations.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tract_querier/tract_math/operations.py b/tract_querier/tract_math/operations.py index b755632..937e4c0 100644 --- a/tract_querier/tract_math/operations.py +++ b/tract_querier/tract_math/operations.py @@ -489,14 +489,17 @@ def tract_smooth(tractography, var, file_output=None): def tract_mask(image, tractography): - ijk_points = tract_in_ijk(image, tractography) image_data = image.get_data() + mask = numpy.zeros_like(image_data, dtype=float) + if len(tractography.tracts()) == 0: + return mask + + ijk_points = tract_in_ijk(image, tractography) ijk_clipped = ijk_points.clip( (0, 0, 0), numpy.array(image_data.shape) - 1 ).astype(int) - mask = numpy.zeros_like(image_data, dtype=float) mask[tuple(ijk_clipped.T)] = 1 return mask From 4828d9cb6ac8d330ef415a32a33648c8428eb17d Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Tue, 18 Feb 2014 10:44:01 +0100 Subject: [PATCH 25/53] ENH: fixed problem in tract math --- tract_querier/tract_math/operations.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tract_querier/tract_math/operations.py b/tract_querier/tract_math/operations.py index 937e4c0..b7ae84c 100644 --- a/tract_querier/tract_math/operations.py +++ b/tract_querier/tract_math/operations.py @@ -35,7 +35,6 @@ def scalars(tractography): @tract_math_operation(': calculates mean and std of tract length') def length_mean_std(tractography): lengths = numpy.empty(len(tractography.tracts())) - for i, tract in enumerate(tractography.tracts()): lengths[i] = tract_length(tract) @@ -50,7 +49,7 @@ def length_mean_std(tractography): def tract_length(tract): d2 = numpy.sqrt((numpy.diff(tract, axis=0) ** 2).sum(1)) - return {'Tract length': d2.sum()} + return d2.sum() @tract_math_operation(': calculates the volume of a tract based on voxel occupancy of a certain voxel volume') From 0b7187ab8b6699a3bf0bb15a69bcbd3222c910bc Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Tue, 18 Feb 2014 13:36:03 +0100 Subject: [PATCH 26/53] ENH: Added support for varargs in tract_math operations --- tract_querier/tract_math/decorator.py | 32 ++++++++++++++++++--------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/tract_querier/tract_math/decorator.py b/tract_querier/tract_math/decorator.py index 86ee444..7195935 100644 --- a/tract_querier/tract_math/decorator.py +++ b/tract_querier/tract_math/decorator.py @@ -38,8 +38,18 @@ def wrapper(*args): else: defaults = argspec.defaults - if has_file_output: - if func_args[-1] != 'file_output': + kwargs = {} + + if argspec.keywords is not None: + kwargs['file_output'] = args[-1] + args = args[:-1] + elif argspec.varargs is not None: + file_output = None + elif has_file_output: + if ( + func_args[-1] != 'file_output' and + argspec.keywords is None + ): raise TractMathWrongArgumentsError('Output file reserved parameter file_output must be the last one') func_args = func_args[:-1] @@ -52,19 +62,19 @@ def wrapper(*args): defaults = defaults[:-1] else: file_output = None - if args[-1] == '-': args = args[:-1] - needed_defaults = len(func_args) - len(args) - if needed_defaults > len(defaults): - raise TractMathWrongArgumentsError('Wrong number of arguments') - elif needed_defaults == -1: - file_output = args[-1] - args = args[:-1] + if argspec.varargs is None: + needed_defaults = len(func_args) - len(args) + if needed_defaults > len(defaults): + raise TractMathWrongArgumentsError('Wrong number of arguments') + elif needed_defaults == -1: + file_output = args[-1] + args = args[:-1] - if needed_defaults > 0: - args += defaults[-needed_defaults:] + if needed_defaults > 0: + args += defaults[-needed_defaults:] out = func(*args) process_output(out, file_output=file_output) From 5b49740eca2529d255bcdd80bc8048e07ef977a6 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Tue, 25 Feb 2014 08:43:23 +0100 Subject: [PATCH 27/53] ENH: Now the tractography from file stores the filename --- tract_querier/tractography/__init__.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tract_querier/tractography/__init__.py b/tract_querier/tractography/__init__.py index 46d514f..3908df4 100644 --- a/tract_querier/tractography/__init__.py +++ b/tract_querier/tractography/__init__.py @@ -43,10 +43,14 @@ def tractography_from_files(filenames): def tractography_from_file(filename): if filename.endswith('trk'): - return tractography_from_trackvis_file(filename) + tract = tractography_from_trackvis_file(filename) + tract.filename = filename + return tract elif filename.endswith('vtk') or filename.endswith('vtp'): if 'tractography_from_vtk_files' in __all__: - return tractography_from_vtk_files(filename) + tract = tractography_from_vtk_files(filename) + tract.filename = filename + return tract else: raise IOError("No VTK support installed, VTK files could not be read") else: From 301643affca6e129e8cb2855c6f4d03e9397ec39 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Wed, 19 Mar 2014 10:03:44 -0400 Subject: [PATCH 28/53] ENH: Slices can be expressed in mm --- scripts/sliced_probmap_viz | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/scripts/sliced_probmap_viz b/scripts/sliced_probmap_viz index e85fac6..577f05e 100755 --- a/scripts/sliced_probmap_viz +++ b/scripts/sliced_probmap_viz @@ -9,7 +9,7 @@ import argparse def main(): parser = argparse.ArgumentParser(description='Superimposed slices viz') - parser.add_argument('-s', dest='slices', type=int, nargs='+', + parser.add_argument('-s', dest='slices', type=float, nargs='+', help='Slices to show')#, required=True) parser.add_argument('-i', dest='base_image', type=str, help='base image to show')#, required=True) @@ -28,6 +28,10 @@ def main(): parser.add_argument('--mip', dest='mip', action='store_true', help='show maximum intensity projections') + parser.add_argument('--mm', dest='mm', action='store_true', + help='slices are in millimeters') + + parser.add_argument( '--displacement', dest='displacement', type=float, default=.1, help='displacement between axes between 0. and 1.') @@ -60,7 +64,8 @@ def main(): parser.exit(0) fig = figure(frameon=False) - fa = nibabel.load(args.base_image).get_data() + fa_img = nibabel.load(args.base_image) + fa = fa_img.get_data() if isinstance(args.tract_image, str): args.tract_image = [args.tract_image] @@ -83,8 +88,22 @@ def main(): fa_cm = cm.gray fa_cm.set_under(alpha=0) + if args.step: - args.slices = xrange(args.slices[0], args.slices[1], args.slices[2]) + args.slices = np.linspace(args.slices[0], args.slices[1], (args.slices[1] - args.slices[0]) / args.slices[2]) + + if args.mm: + ras_pos = zeros(4) + ras_pos[-1] = 1. + if any(np.diag(np.diag(fa_img.get_affine()[:3, :3])) != fa_img.get_affine()[:3, :3]): + raise ValueError("Affine matrix is not diagonal, we don't handle this case") + for i, s in enumerate(args.slices): + ras_pos[args.axis] = s + ijk_pos = np.linalg.solve(fa_img.get_affine(), ras_pos) + args.slices[i] = int(round(ijk_pos[args.axis])) + else: + args.slices = [int(s) for s in args.slices] + for i, y in enumerate(args.slices): if args.inverse_order: pos = len(args.slices) - 1 - i From 92a478dc8cc68682609f7ce2e877c3e64296f327 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Wed, 19 Mar 2014 10:04:10 -0400 Subject: [PATCH 29/53] ENH: Small modifications to tract_math operations --- tract_querier/tract_math/operations.py | 195 +++++++++++++++++++++++-- 1 file changed, 180 insertions(+), 15 deletions(-) diff --git a/tract_querier/tract_math/operations.py b/tract_querier/tract_math/operations.py index b7ae84c..a1ff2c5 100644 --- a/tract_querier/tract_math/operations.py +++ b/tract_querier/tract_math/operations.py @@ -52,11 +52,12 @@ def tract_length(tract): return d2.sum() -@tract_math_operation(': calculates the volume of a tract based on voxel occupancy of a certain voxel volume') -def tract_volume(tractography, resolution): +@tract_math_operation(': calculates the volume of a tract based on voxel occupancy of a certain voxel volume', needs_one_tract=False) +def tract_volume(tractographies, resolution): + results = OrderedDict() + results['tract name'] = [] + results['tract volume'] = [] resolution = float(resolution) - voxels = voxelized_tract(tractography, resolution) - neighbors = numpy.array([ [0, 1, 0], [0, -1, 0], @@ -65,20 +66,25 @@ def tract_volume(tractography, resolution): [0, 0, 1], [0, 0, -1] ]) - dilated_voxels = set() - dilated_voxels.update(voxels) - eroded_voxels = set() - for voxel in voxels: - neighbors_list = zip(*(neighbors + voxel).T) - dilated_voxels.update(neighbors_list) - if len(voxels.intersection(neighbors_list)) == len(neighbors): - eroded_voxels.add(voxel) - # print len(dilated_voxels), len(voxels), len(eroded_voxels) - approx_voxels = (len(dilated_voxels) - len(eroded_voxels)) / 2. + for tractography in tractographies: + voxels = voxelized_tract(tractography, resolution) + + dilated_voxels = set() + dilated_voxels.update(voxels) + eroded_voxels = set() + for voxel in voxels: + neighbors_list = zip(*(neighbors + voxel).T) + dilated_voxels.update(neighbors_list) + if len(voxels.intersection(neighbors_list)) == len(neighbors): + eroded_voxels.add(voxel) - return {'tract volume': approx_voxels * (resolution ** 3)} + # print len(dilated_voxels), len(voxels), len(eroded_voxels) + approx_voxels = (len(dilated_voxels) - len(eroded_voxels)) / 2. + results['tract name'].append(tractography.filename) + results['tract volume'].append(approx_voxels * (resolution ** 3)) + return results @tract_math_operation(': calculates mean and std of a scalar quantity for each tract') def scalar_tract_mean_std(tractography, scalar): @@ -239,6 +245,43 @@ def tract_map_image(tractography, image, quantity_name, file_output=None): ) +@tract_math_operation(' ') +def tract_tract_confidence(tractography, bins, qty, file_output=None): + bins = int(bins) + lengths = numpy.empty(len(tractography.tracts())) + tracts = tractography.tracts() + tracts_prob_data = [] + tracts_length_bin = [] + for i, tract in enumerate(tracts): + lengths[i] = tract_length(tract) + tracts_prob_data.append(numpy.zeros(len(tract))) + tracts_length_bin.append(numpy.zeros(len(tract))) + + length_histogram_counts, length_histogram_bins = numpy.histogram(lengths, normed=True, bins=bins) + + for i in xrange(1, bins): + tract_log_prob = [] + indices_bin = ((length_histogram_bins[i - 1] < lengths) * (lengths < length_histogram_bins[i])).nonzero()[0] + if len(indices_bin) == 0: + continue + + for j in indices_bin: + tract_log_prob.append(numpy.log(tractography.tracts_data()[qty][j]).sum()) + tract_log_prob = numpy.array(tract_log_prob) + tract_log_prob = numpy.nan_to_num(tract_log_prob) + lp_a0 = tract_log_prob[tract_log_prob < 0].max() + tract_log_prob_total = numpy.log(numpy.exp(tract_log_prob - lp_a0).sum()) + lp_a0 + tract_prob = numpy.exp(tract_log_prob - tract_log_prob_total) + + for tract_number, tract_prob in zip(indices_bin, tract_prob): + tracts_prob_data[tract_number][:] = tract_prob + tracts_length_bin[tract_number][:] = length_histogram_bins[i - 1] + + tractography.tracts_data()['tprob'] = tracts_prob_data + tractography.tracts_data()['tprob_bin'] = tracts_length_bin + + return tractography + @tract_math_operation(' : calculates the mask image from a tract on the space of the given image') def tract_generate_mask(tractography, image, file_output=None): image = nibabel.load(image) @@ -314,6 +357,71 @@ def tract_merge(tractographies, file_output=None): return Tractography(all_tracts, all_data) + +@tract_math_operation('r ICC') +def tract_icc(tractography, resolution, *other_tracts): + import rpy2.robjects as robjects + from rpy2.robjects.numpy2ri import numpy2ri + r = robjects.r + r.library('irr') + + result = OrderedDict(( + ('tract file', []), + ('kappa value', []), + ('totals', []), + )) + + resolution = float(resolution) + voxels = voxelized_tract(tractography, resolution) + for other_tract_fname in other_tracts: + other_tract = tractography_from_files(other_tract_fname) + other_voxels = voxelized_tract(other_tract, resolution) + + all_voxels = voxels.union(other_voxels) + + for _ in xrange(1): + all_voxels = dilate_voxels(all_voxels) + + #all_voxels = dilated_voxels + all_voxels = list(all_voxels) + mask = numpy.zeros((len(all_voxels), 2), dtype=int) + + for i, vx in enumerate(all_voxels): + if vx in voxels: + mask[i, 0] = 1 + if vx in other_voxels: + mask[i, 1] = 1 + + r_mask = numpy2ri(mask) + res = r.icc(r_mask, model='twoway', type='agreement') + #res = r.icc(r_mask, model='twoway') + result['totals'].append((mask.all(1).sum() + (~mask.any(1)).sum()) * 1. / len(all_voxels)) + #res = r.kappa2(r_mask, "equal") + result['tract file'].append(other_tract_fname) + for t in res.iteritems(): + if t[0] == 'value': + result['kappa value'].append(numpy.round(t[1][0],2)) + + return result + +def dilate_voxels(voxels): + neighbors = numpy.array([ + [0, 1, 0], + [0, -1, 0], + [1, 0, 0], + [-1, 0, 0], + [0, 0, 1], + [0, 0, -1] + ]) + + dilated_voxels = set() + dilated_voxels.update(voxels) + for voxel in voxels: + neighbors_list = zip(*(neighbors + voxel).T) + dilated_voxels.update(neighbors_list) + return dilated_voxels + + @tract_math_operation(' ... : calculates the kappa value of the first tract with the rest in the space of the reference image') def tract_kappa(tractography, resolution, *other_tracts): resolution = float(resolution) @@ -592,3 +700,60 @@ def tract_prototype_mean(tractography, smooth_order, file_output=None): warn("A smooth order larger than 0 needs scipy installed") return Tractography([mean_tract], {}) + + +@tract_math_operation(' ... : calculates the Bhattacharyya coefficient of the first tract with the rest in the space of the reference image') +def tract_bhattacharyya_coefficient(tractography, resolution, *other_tracts): + resolution = float(resolution) + coord = ('X', 'Y', 'Z') + result = OrderedDict( + [('tract file', [])] + + [ + ('bhattacharyya %s value' % coord[i], []) + for i in xrange(3) + ] + ) + + tractography_points = numpy.vstack(tractography.tracts()) + + other_tracts_tractographies = [tractography_from_files(t_) + for t_ in other_tracts + ] + + other_tracts_points = [ + numpy.vstack(t_.tracts()) + for t_ in other_tracts_tractographies + ] + + mn_ = tractography_points.min(0) + mx_ = tractography_points.max(0) + + for pts in other_tracts_points: + mn_ = numpy.minimum(mn_, pts.min(0)) + mx_ = numpy.maximum(mn_, pts.max(0)) + + bins = numpy.ceil((mx_ - mn_) * 1. / resolution) + hists_tract = [ + numpy.histogram(tractography_points[:, i], bins=bins[i], density=True, range=(mn_[i], mx_[i]))[0] + for i in xrange(3) + ] + + for tract, tract_points in zip(other_tracts, other_tracts_points): + hists_other_tract = [ + numpy.histogram(tract_points[:, i], bins=bins[i], density=True, range=(mn_[i], mx_[i]))[0] + for i in xrange(3) + ] + + distances = [ + numpy.sqrt( + hists_other_tract[i] * hists_tract[i] / + (hists_other_tract[i].sum() * hists_tract[i].sum()) + ).sum() + for i in xrange(3) + ] + for i in xrange(3): + result['tract file'].append(tract) + result['bhattacharyya %s value' % coord[i]].append(numpy.nan_to_num(distances[i])) + + return result + From d5203afbd9dc65d97908e4ecb139e482f6993dfa Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 25 Apr 2014 13:18:22 +0200 Subject: [PATCH 30/53] BUG: Corrected merge problem --- scripts/tract_querier | 4 ---- 1 file changed, 4 deletions(-) diff --git a/scripts/tract_querier b/scripts/tract_querier index 3234248..2eceb76 100755 --- a/scripts/tract_querier +++ b/scripts/tract_querier @@ -256,13 +256,9 @@ def main(): tractography_spatial_indexing, initial_body=query_script, save_query_callback=query_save, -<<<<<<< HEAD del_query_callback=query_del, eof_callback=kill_server_callback, include_folders=folders -======= - include_folders=qry_search_folders ->>>>>>> master ) interactive_shell.cmdloop() From 03ef08a65e15b2922d82978545b598506b2d7aa3 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Sun, 27 Apr 2014 09:19:33 +0200 Subject: [PATCH 31/53] ENH: Bug derived from the merging --- scripts/tract_querier | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/tract_querier b/scripts/tract_querier index 8f8a687..0cfd7fb 100755 --- a/scripts/tract_querier +++ b/scripts/tract_querier @@ -283,7 +283,7 @@ def main(): save_query_callback=query_save, del_query_callback=query_del, eof_callback=kill_server_callback, - include_folders=folders + include_folders=qry_search_folders ) interactive_shell.cmdloop() From 13e673d116009a4788b2b98c91391316e81afc9f Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Thu, 10 Jul 2014 20:46:28 +0200 Subject: [PATCH 32/53] ENH: Shell now can handle I/O redirection --- tract_querier/shell.py | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/tract_querier/shell.py b/tract_querier/shell.py index 16e71f3..8559a4a 100644 --- a/tract_querier/shell.py +++ b/tract_querier/shell.py @@ -99,9 +99,11 @@ def __init__( save_query_callback=None, del_query_callback=None, eof_callback=None, - include_folders=['.'] + include_folders=['.'], + stdin=None, + stdout=None ): - cmd.Cmd.__init__(self, 'Tab') + cmd.Cmd.__init__(self, 'Tab', stdin=stdin, stdout=stdout) self.prompt = '[wmql] ' self.include_folders = include_folders self.tractography = tractography @@ -127,6 +129,10 @@ def __init__( else: self.querier.visit(initial_body) + def _print(self, test): + self.stdout.write(test + '\n') + self.stdout.flush() + @safe_method def do_dir(self, patterns): if patterns == '': @@ -142,15 +148,15 @@ def do_dir(self, patterns): else: keys = k for k in keys: - print k + self._print(k) @safe_method def do_del(self, name): if self.del_query_callback is None: - print "Can not delete a query in this mode" + self._print("Can not delete a query in this mode") return if name not in self.names(): - print "Error, query does not exist" + self._print("Error, query does not exist") else: self.del_query_callback(name) @@ -162,16 +168,16 @@ def do_save(self, line): ) self.save_query_visitor.visit(ast.Module(body=body)) except SyntaxError, e: - print e.value + self._print(e.value) except TractQuerierSyntaxError, e: - print e.value + self._print(e.value) except KeyError, e: - print "Query name not recognized: %s" % e + self._print("Query name not recognized: %s" % e) return False def do_help(self, line): - print '''WMQL Help + self._print('''WMQL Help Commands: dir : list the available queries according to the pattern @@ -183,7 +189,7 @@ def do_help(self, line): |= : execute a query without saving its result Exit pressing Ctrl+D - ''' + ''') return def emptyline(self): @@ -191,7 +197,7 @@ def emptyline(self): @safe_method def default(self, line): - print line + self._print(line) if len(line) == 0: return False @@ -204,9 +210,9 @@ def default(self, line): self.querier.visit(body) self.save_query_visitor.visit(body) except SyntaxError, e: - print e.value + self._print(e.value) except TractQuerierSyntaxError, e: - print e.value + self._print(e.value) return False From 6272e60981743b0699e6f5c403cf9fa36444f486 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Thu, 10 Jul 2014 22:56:52 +0200 Subject: [PATCH 33/53] ENH: First version of the in-web terminal works --- scripts/tract_querier | 65 ++- tract_querier/tornado_server/__init__.py | 24 +- tract_querier/tornado_server/css/viewer.css | 14 + tract_querier/tornado_server/index.html | 6 +- tract_querier/tornado_server/js/wmqlviz.js | 147 +++-- tract_querier/tornado_server/js/xtk.js | 582 ++++++++++---------- 6 files changed, 493 insertions(+), 345 deletions(-) diff --git a/scripts/tract_querier b/scripts/tract_querier index 0cfd7fb..829c807 100755 --- a/scripts/tract_querier +++ b/scripts/tract_querier @@ -80,7 +80,8 @@ def main(): import tract_querier if options.interactive_web: - kill_server_callback = activate_webserver(options) + #kill_server_callback = activate_webserver(options) + kill_server_callback = None options.interactive = True else: kill_server_callback = None @@ -248,6 +249,8 @@ def main(): query_del = None else: import urllib + from multiprocessing import Process + def query_save(query_name, query_result): filename = save_query( query_name, tr, options, {query_name: query_result}, @@ -260,8 +263,16 @@ def main(): 'file': filename, 'action': 'add' }) - f = urllib.urlopen(options.interactive_url, params) - f.close() + + p = Process( + target=urllib.urlopen, + args=(options.interactive_url, params), + #kwargs=params + ) + p.start() + + #f = urllib.urlopen(options.interactive_url, params) + #f.close() except Exception, e: print "Interactive URL error:", e return filename @@ -272,8 +283,15 @@ def main(): 'name': query_name, 'action': 'remove' }) - f = urllib.urlopen(options.interactive_url, params) - f.close() + p = Process( + target=urllib.urlopen, + args=(options.interactive_url, params), + #kwargs=params + ) + p.start() + + #f = urllib.urlopen(options.interactive_url, params) + #f.close() except Exception, e: print "Interactive URL error:", e @@ -286,7 +304,12 @@ def main(): include_folders=qry_search_folders ) - interactive_shell.cmdloop() + if options.interactive_web: + activate_webserver(options, interactive_shell) + else: + interactive_shell.cmdloop() + #kill_server_callback = activate_webserver(options) + def save_query(query_name, tractography, options, evaluated_queries, extension='.vtk', extra_kwargs={}): @@ -340,7 +363,7 @@ def save_tractography_file( ) -def activate_webserver(options): +def activate_webserver(options, shell): import os from multiprocessing import Process from tract_querier import tornado_server @@ -362,16 +385,28 @@ def activate_webserver(options): 'colortable': options.interactive_colortable, 'port': options.interactive_port, 'files_path': os.getcwd(), - 'suffix': suffix + 'suffix': suffix, + 'shell': shell } ) - - p.start() - - def kill_server(): - p.terminate() - - return kill_server + #args=(os.path.abspath(options.atlas_file_name),), + args = tuple() + kwargs = { + 'atlas': os.path.abspath(options.atlas_file_name), + 'colortable': options.interactive_colortable, + 'port': options.interactive_port, + 'files_path': os.getcwd(), + 'suffix': suffix, + 'shell': shell + } + tornado_server.xtk_server(*args, **kwargs) + + #p.start() + + #def kill_server(): + # p.terminate() + + #return kill_server def affine_transform_tract(affine_transform, tract): diff --git a/tract_querier/tornado_server/__init__.py b/tract_querier/tornado_server/__init__.py index 76084ae..f79e0f0 100644 --- a/tract_querier/tornado_server/__init__.py +++ b/tract_querier/tornado_server/__init__.py @@ -1,6 +1,7 @@ import os import sys import json +from StringIO import StringIO import tornado.ioloop import tornado.web @@ -13,6 +14,12 @@ class WSHandler(tornado.websocket.WebSocketHandler): + def initialize(self, shell=None): + self.shell = shell + self.sio = StringIO() + self.shell.stdout = self.sio + self.json_encoder = json.JSONEncoder() + def open(self): global websocket_clients websocket_clients.append(self) @@ -21,6 +28,16 @@ def on_message(self, message): # self.write_message(u"You Said: " + message) global change change = message + self.sio.seek(0) + self.shell.onecmd(message) + self.sio.seek(0) + result = self.sio.getvalue() + term_output = { + 'receiver': 'terminal', + 'output': result + } + self.write_message(self.json_encoder.encode(term_output)) + self.sio.truncate(0) #self.write_message(message + "Response") @@ -97,6 +114,7 @@ def initialize(self): def post(self): try: action = { + 'receiver': 'tract', 'action': self.get_argument('action'), 'name': self.get_argument('name') } @@ -111,7 +129,7 @@ def post(self): print e -def xtk_server(atlas, colortable=None, port=9999, files_path=None, suffix=''): +def xtk_server(atlas=None, colortable=None, port=9999, files_path=None, suffix='', shell=None): print "Using atlas", atlas global application @@ -149,7 +167,9 @@ def xtk_server(atlas, colortable=None, port=9999, files_path=None, suffix=''): tornado.web.StaticFileHandler, {"path": static_folder} ), - (r'/ws', WSHandler), + (r'/ws', WSHandler, { + 'shell': shell, + }), (r'/tracts', TractHandler), ( r'/atlas/(.*)', diff --git a/tract_querier/tornado_server/css/viewer.css b/tract_querier/tornado_server/css/viewer.css index a65086d..70b7113 100644 --- a/tract_querier/tornado_server/css/viewer.css +++ b/tract_querier/tornado_server/css/viewer.css @@ -8,6 +8,7 @@ .twoDRenderer { border-left: thin solid #666; background-color: #000; + text-color: #FF0; position: absolute; width: 20%; height: 31%; @@ -15,6 +16,19 @@ right: 0%; } +.footer { + border-left: thin solid #F00; + background-color: #F0F; + position: fixed; + bottom: 0; + right: 0; + height: 5%; +} + +#shell { + bottom: 5%; +} + #sliceX { top: 7%; } diff --git a/tract_querier/tornado_server/index.html b/tract_querier/tornado_server/index.html index 5ccee03..226e40a 100644 --- a/tract_querier/tornado_server/index.html +++ b/tract_querier/tornado_server/index.html @@ -9,6 +9,7 @@ + @@ -19,18 +20,21 @@ + + - +
    diff --git a/tract_querier/tornado_server/js/wmqlviz.js b/tract_querier/tornado_server/js/wmqlviz.js index a04aed0..9f88f8b 100644 --- a/tract_querier/tornado_server/js/wmqlviz.js +++ b/tract_querier/tornado_server/js/wmqlviz.js @@ -169,38 +169,40 @@ function init_websocket(host) { }; _WS_.onmessage = function(evt){ - var tract = JSON.parse(evt.data); - var name = tract['name']; - var file = tract['file']; - var action = tract['action']; - if (action == 'add') { - if (name in _tracts_) { - console.info("Removing tract " + name); - _tracts_gui_.remove(_tracts_[name].control); - render3D.remove(_tracts_[name]); - }; - - delete _tracts_[name]; - - _tracts_[name] = new X.fibers(); - _tracts_[name].file = 'files/' + file; - _tracts_[name].caption = name; - - _tracts_[name].control = _tracts_gui_.add(_tracts_[name], 'visible'); - _tracts_[name].control.name(name); - - _tracts_[name].modified(); - - render3D.add(_tracts_[name]); + var ev = JSON.parse(evt.data); + if (ev['receiver'] == 'tract') { + var name = ev['name']; + var file = ev['file']; + var action = ev['action']; + if (action == 'add') { + if (name in _tracts_) { + console.info("Removing tract " + name); + _tracts_gui_.remove(_tracts_[name].control); + render3D.remove(_tracts_[name]); + }; - } - - if (action == 'remove') { - if (name in _tracts_) { - console.info("Removing tract " + name); - _tracts_gui_.remove(_tracts_[name].control); - render3D.remove(_tracts_[name]); delete _tracts_[name]; + + _tracts_[name] = new X.fibers(); + _tracts_[name].file = 'files/' + file; + _tracts_[name].caption = name; + + _tracts_[name].control = _tracts_gui_.add(_tracts_[name], 'visible'); + _tracts_[name].control.name(name); + + _tracts_[name].modified(); + + render3D.add(_tracts_[name]); + + } + + if (action == 'remove') { + if (name in _tracts_) { + console.info("Removing tract " + name); + _tracts_gui_.remove(_tracts_[name].control); + render3D.remove(_tracts_[name]); + delete _tracts_[name]; + } } } }; @@ -211,6 +213,89 @@ function init_websocket(host) { }); }; +function init_terminal(host) { + jQuery(function($, undefined) { + var _WS_ = new WebSocket(host); + + function waitForSocketConnection(socket, callback){ + setTimeout( + function () { + if (socket.readyState === 1) { + console.log("Connection is made") + if(callback != null){ + callback(); + } + return; + + } else { + console.log("wait for connection...") + waitForSocketConnection(socket, callback); + } + + }, 5); // wait 5 milisecond for the connection... + } + + waitForSocketConnection(_WS_, function(){ + console.log("terminal connected!"); + }); + + var wait = 0; + function waitForShell() { + setTimeout( + function () { + if (wait === 0) { + console.log("Shell back") + return; + } else { + console.log("wait for shell to come back...") + waitForShell(); + } + + }, 5); // wait 5 milisecond for the connection... + }; + $('#wmql_console').terminal(function(command, term) { + _WS_.onmessage = function(evt){ + console.log("Received!"); + var ev = JSON.parse(evt.data); + var receiver = ev['receiver'] + if (receiver == 'terminal') { + term.echo(ev['output']); + }; + wait = 0; + }; + + console.log("Sending command"); + console.log(command); + + _WS_.send(command); + wait = 1; + waitForShell(); + + + /* + function sendMessage(msg){ + // Wait until the state of the socket is not ready and send the message when it is... + waitForSocketConnection(_WS_, function(){ + console.log("message sent!!!"); + _WS_.send(msg); + }); + } + + // Make the function wait until the connection is made... + sendMessage(command); + */ + + + }, { + greetings: 'White Matter Query Language Console', + name: 'wmql_console', + height: 80, + prompt: '[WMQL] '}); + }); +}; + + + window.onload = function() { render3D = new X.renderer3D(); @@ -235,5 +320,3 @@ window.onload = function() { } - - diff --git a/tract_querier/tornado_server/js/xtk.js b/tract_querier/tornado_server/js/xtk.js index d9bab45..ee00663 100644 --- a/tract_querier/tornado_server/js/xtk.js +++ b/tract_querier/tornado_server/js/xtk.js @@ -37,312 +37,304 @@ * MORE CREDITS: https://raw.github.com/xtk/X/master/LICENSE * */ -function m(a){throw a;}var n=void 0,q=!0,r=null,s=!1;function ba(){return function(){}}function ea(a){return function(b){this[a]=b}}function t(a){return function(){return this[a]}}var w,fa=this;function ga(){} -function ia(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null"; -else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function ja(a){return a!==n}function y(a){return"array"==ia(a)}function la(a){var b=ia(a);return"array"==b||"object"==b&&"number"==typeof a.length}function ma(a){return"string"==typeof a}function D(a){return"number"==typeof a}function na(a){return"function"==ia(a)}function oa(a){var b=typeof a;return"object"==b&&a!=r||"function"==b}function pa(a){return a[qa]||(a[qa]=++ra)}var qa="closure_uid_"+(1E9*Math.random()>>>0),ra=0; -function sa(a,b,c){return a.call.apply(a.bind,arguments)}function ta(a,b,c){a||m(Error());if(2>>0),qa=0; +function ra(a,b,c){return a.call.apply(a.bind,arguments)}function sa(a,b,c){a||m(Error());if(2a&&(a=this.byteLength+a);0>c&&(c=this.byteLength+c);ca&&(a=0);0>c&&(c=0);a>this.byteLength&&(a=this.byteLength);c>this.byteLength&&(c=this.byteLength);for(var d=new ArrayBuffer(c-a),e=new Uint8Array(this),f=new Uint8Array(d),g=a,h=0;g")&&(a=a.replace(Ta,">"));-1!=a.indexOf('"')&&(a=a.replace(Ua,"""));return a}var Ra=/&/g,Sa=//g,Ua=/\"/g,Qa=/[&<>\"]/;var Va,Xa,Ya,Za,$a,bb,cb;function db(){return fa.navigator?fa.navigator.userAgent:r}function eb(){return fa.navigator}Za=Ya=Xa=Va=s;var gb;if(gb=db()){var hb=eb();Va=0==gb.indexOf("Opera");Xa=!Va&&-1!=gb.indexOf("MSIE");Ya=!Va&&-1!=gb.indexOf("WebKit");Za=!Va&&!Ya&&"Gecko"==hb.product}var ib=Va,M=Xa,jb=Za,kb=Ya,lb,mb=eb();lb=mb&&mb.platform||"";$a=-1!=lb.indexOf("Mac");bb=-1!=lb.indexOf("Win");cb=-1!=lb.indexOf("Linux");var nb=!!eb()&&-1!=(eb().appVersion||"").indexOf("X11"); -function ob(){var a=fa.document;return a?a.documentMode:n}var pb;a:{var qb="",rb;if(ib&&fa.opera)var sb=fa.opera.version,qb="function"==typeof sb?sb():sb;else if(jb?rb=/rv\:([^\);]+)(\)|;)/:M?rb=/MSIE\s+([^\);]+)(\)|;)/:kb&&(rb=/WebKit\/(\S+)/),rb)var tb=rb.exec(db()),qb=tb?tb[1]:"";if(M){var ub=ob();if(ub>parseFloat(qb)){pb=String(ub);break a}}pb=qb}var vb={}; -function xb(a){var b;if(!(b=vb[a])){b=0;for(var c=String(pb).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),d=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),e=Math.max(c.length,d.length),f=0;0==b&&f(0==p[1].length?0:parseInt(p[1],10))?1:0)||((0==l[2].length)<(0==p[2].length)?-1:(0==l[2].length)>(0==p[2].length)?1:0)||(l[2]p[2]?1:0)}while(0==b)}b=vb[a]=0<=b}return b}var yb=fa.document,zb=!yb||!M?n:ob()||("CSS1Compat"==yb.compatMode?parseInt(pb,10):5);var Ab=!M||M&&9<=zb,Bb=M&&!xb("9");!kb||xb("528");jb&&xb("1.9b")||M&&xb("8")||ib&&xb("9.5")||kb&&xb("528");jb&&!xb("8")||M&&xb("9");var Cb=Array.prototype,Db=Cb.indexOf?function(a,b,c){return Cb.indexOf.call(a,b,c)}:function(a,b,c){c=c==r?0:0>c?Math.max(0,a.length+c):c;if(ma(a))return!ma(b)||1!=b.length?-1:a.indexOf(b,c);for(;c=arguments.length?Cb.slice.call(a,b):Cb.slice.call(a,b,c)};function Jb(){0!=Kb&&(this.Sj=Error().stack,pa(this))}var Kb=0;function Lb(a,b){this.type=a;this.currentTarget=this.target=b}w=Lb.prototype;w.cc=s;w.defaultPrevented=s;w.Md=q;w.stopPropagation=function(){this.cc=q};w.preventDefault=function(){this.defaultPrevented=q;this.Md=s};function Mb(a){Mb[" "](a);return a}Mb[" "]=ga;function Nb(a,b){a&&this.ha(a,b)}G(Nb,Lb);w=Nb.prototype;w.target=r;w.relatedTarget=r;w.offsetX=0;w.offsetY=0;w.clientX=0;w.clientY=0;w.screenX=0;w.screenY=0;w.button=0;w.keyCode=0;w.charCode=0;w.ctrlKey=s;w.altKey=s;w.shiftKey=s;w.metaKey=s;w.ni=s;w.Pa=r; -w.ha=function(a,b){var c=this.type=a.type;Lb.call(this,c);this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;if(d){if(jb){var e;a:{try{Mb(d.nodeName);e=q;break a}catch(f){}e=s}e||(d=r)}}else"mouseover"==c?d=a.fromElement:"mouseout"==c&&(d=a.toElement);this.relatedTarget=d;this.offsetX=kb||a.offsetX!==n?a.offsetX:a.layerX;this.offsetY=kb||a.offsetY!==n?a.offsetY:a.layerY;this.clientX=a.clientX!==n?a.clientX:a.pageX;this.clientY=a.clientY!==n?a.clientY:a.pageY;this.screenX= -a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=a.metaKey;this.ni=$a?a.metaKey:a.ctrlKey;this.state=a.state;this.Pa=a;a.defaultPrevented&&this.preventDefault();delete this.cc};w.stopPropagation=function(){Nb.r.stopPropagation.call(this);this.Pa.stopPropagation?this.Pa.stopPropagation():this.Pa.cancelBubble=q}; -w.preventDefault=function(){Nb.r.preventDefault.call(this);var a=this.Pa;if(a.preventDefault)a.preventDefault();else if(a.returnValue=s,Bb)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};w.kh=t("Pa");var Ob={},Pb={},Qb={},Rb={};function P(a,b,c,d,e){if(y(b)){for(var f=0;fe.keyCode||e.returnValue!=n)return q;a:{var j=s;if(0==e.keyCode)try{e.keyCode=-1;break a}catch(k){j=q}if(j||e.returnValue==n)e.returnValue=q}}j=new Nb;j.ha(e,this);e=q;try{if(g){for(var l=[],p=j.currentTarget;p;p=p.parentNode)l.push(p);f=d[q];f.sa=f.Y;for(var u=l.length- -1;!j.cc&&0<=u&&f.sa;u--)j.currentTarget=l[u],e&=Yb(f,l[u],c,q,j);if(h){f=d[s];f.sa=f.Y;for(u=0;!j.cc&&uk?2:1E-52*this.Y&&sc(this),q):s};function sc(a){if(a.Y!=a.A.length){for(var b=0,c=0;ba||360a||360a||360a)&&m(Error("Invalid opacity."));for(var b=this.e,c=b.length,d=0,d=0;db.M?-1:1}F("X.object",U);F("X.object.prototype.modified",U.prototype.n);function Tc(){}function Uc(a){for(var b=a.i.count,c=[],d=0,d=0;da&&(a=this.byteLength+a);0>c&&(c=this.byteLength+c);ca&&(a=0);0>c&&(c=0);a>this.byteLength&&(a=this.byteLength);c>this.byteLength&&(c=this.byteLength);for(var d=new ArrayBuffer(c-a),e=new Uint8Array(this),f=new Uint8Array(d),g=a,h=0;g")&&(a=a.replace(Na,">"));-1!=a.indexOf('"')&&(a=a.replace(Oa,"""));return a}var La=/&/g,Ma=//g,Oa=/\"/g,Ka=/[&<>\"]/;var Pa,Qa,Ra,Sa,Ta,Va,Wa;function Xa(){return ca.navigator?ca.navigator.userAgent:r}function Ya(){return ca.navigator}Sa=Ra=Qa=Pa=s;var Za;if(Za=Xa()){var $a=Ya();Pa=0==Za.indexOf("Opera");Qa=!Pa&&-1!=Za.indexOf("MSIE");Ra=!Pa&&-1!=Za.indexOf("WebKit");Sa=!Pa&&!Ra&&"Gecko"==$a.product}var ab=Pa,L=Qa,bb=Sa,db=Ra,eb,fb=Ya();eb=fb&&fb.platform||"";Ta=-1!=eb.indexOf("Mac");Va=-1!=eb.indexOf("Win");Wa=-1!=eb.indexOf("Linux");var gb=!!Ya()&&-1!=(Ya().appVersion||"").indexOf("X11"); +function hb(){var a=ca.document;return a?a.documentMode:n}var ib;a:{var jb="",kb;if(ab&&ca.opera)var lb=ca.opera.version,jb="function"==typeof lb?lb():lb;else if(bb?kb=/rv\:([^\);]+)(\)|;)/:L?kb=/MSIE\s+([^\);]+)(\)|;)/:db&&(kb=/WebKit\/(\S+)/),kb)var mb=kb.exec(Xa()),jb=mb?mb[1]:"";if(L){var nb=hb();if(nb>parseFloat(jb)){ib=String(nb);break a}}ib=jb}var ob={}; +function pb(a){var b;if(!(b=ob[a])){b=0;for(var c=String(ib).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),d=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),e=Math.max(c.length,d.length),f=0;0==b&&f(0==p[1].length?0:parseInt(p[1],10))?1:0)||((0==k[2].length)<(0==p[2].length)?-1:(0==k[2].length)>(0==p[2].length)?1:0)||(k[2]p[2]?1:0)}while(0==b)}b=ob[a]=0<=b}return b}var qb=ca.document,rb=!qb||!L?n:hb()||("CSS1Compat"==qb.compatMode?parseInt(ib,10):5);function sb(){0!=tb&&(this.Jj=Error().stack,oa(this))}var tb=0;function ub(a,b){this.type=a;this.currentTarget=this.target=b}w=ub.prototype;w.ac=s;w.defaultPrevented=s;w.Gd=q;w.stopPropagation=function(){this.ac=q};w.preventDefault=function(){this.defaultPrevented=q;this.Gd=s};var vb=0;function wb(){}w=wb.prototype;w.key=0;w.bc=s;w.od=s;w.ea=function(a,b,c,d,e,f){ma(a)?this.Pf=q:a&&a.handleEvent&&ma(a.handleEvent)?this.Pf=s:m(Error("Invalid listener argument"));this.Db=a;this.hg=b;this.src=c;this.type=d;this.capture=!!e;this.ye=f;this.od=s;this.key=++vb;this.bc=s};w.handleEvent=function(a){return this.Pf?this.Db.call(this.ye||this.src,a):this.Db.handleEvent.call(this.Db,a)};function xb(a){var b=[],c=0,d;for(d in a)b[c++]=a[d];return b}var yb="constructor hasOwnProperty isPrototypeOf propertyIsEnumerable toLocaleString toString valueOf".split(" ");function zb(a,b){for(var c,d,e=1;ec?Math.max(0,a.length+c):c;if(la(a))return!la(b)||1!=b.length?-1:a.indexOf(b,c);for(;c=arguments.length?Cb.slice.call(a,b):Cb.slice.call(a,b,c)};function Jb(a){Jb[" "](a);return a}Jb[" "]=ea;function Kb(a,b){a&&this.ea(a,b)}F(Kb,ub);w=Kb.prototype;w.target=r;w.relatedTarget=r;w.offsetX=0;w.offsetY=0;w.clientX=0;w.clientY=0;w.screenX=0;w.screenY=0;w.button=0;w.keyCode=0;w.charCode=0;w.ctrlKey=s;w.altKey=s;w.shiftKey=s;w.metaKey=s;w.hi=s;w.Ma=r; +w.ea=function(a,b){var c=this.type=a.type;ub.call(this,c);this.target=a.target||a.srcElement;this.currentTarget=b;var d=a.relatedTarget;if(d){if(bb){var e;a:{try{Jb(d.nodeName);e=q;break a}catch(f){}e=s}e||(d=r)}}else"mouseover"==c?d=a.fromElement:"mouseout"==c&&(d=a.toElement);this.relatedTarget=d;this.offsetX=db||a.offsetX!==n?a.offsetX:a.layerX;this.offsetY=db||a.offsetY!==n?a.offsetY:a.layerY;this.clientX=a.clientX!==n?a.clientX:a.pageX;this.clientY=a.clientY!==n?a.clientY:a.pageY;this.screenX= +a.screenX||0;this.screenY=a.screenY||0;this.button=a.button;this.keyCode=a.keyCode||0;this.charCode=a.charCode||("keypress"==c?a.keyCode:0);this.ctrlKey=a.ctrlKey;this.altKey=a.altKey;this.shiftKey=a.shiftKey;this.metaKey=a.metaKey;this.hi=Ta?a.metaKey:a.ctrlKey;this.state=a.state;this.Ma=a;a.defaultPrevented&&this.preventDefault();delete this.ac};w.stopPropagation=function(){Kb.s.stopPropagation.call(this);this.Ma.stopPropagation?this.Ma.stopPropagation():this.Ma.cancelBubble=q}; +w.preventDefault=function(){Kb.s.preventDefault.call(this);var a=this.Ma;if(a.preventDefault)a.preventDefault();else if(a.returnValue=s,Bb)try{if(a.ctrlKey||112<=a.keyCode&&123>=a.keyCode)a.keyCode=-1}catch(b){}};w.dh=u("Ma");var Lb={},Nb={},Ob={},Pb={};function O(a,b,c,d,e){if(ha(b)){for(var f=0;fe.keyCode||e.returnValue!=n)return q;a:{var l=s;if(0==e.keyCode)try{e.keyCode=-1;break a}catch(j){l=q}if(l||e.returnValue==n)e.returnValue=q}}l=new Kb;l.ea(e,this);e=q;try{if(g){for(var k=[],p=l.currentTarget;p;p=p.parentNode)k.push(p);f=d[q];f.pa=f.V;for(var t=k.length- +1;!l.ac&&0<=t&&f.pa;t--)l.currentTarget=k[t],e&=Yb(f,k[t],c,q,l);if(h){f=d[s];f.pa=f.V;for(t=0;!l.ac&&tj?2:1E-52*this.V&&sc(this),q):s};function sc(a){if(a.V!=a.w.length){for(var b=0,c=0;ba||360a||360a||360a)&&m(Error("Invalid opacity."));for(var b=this.e,c=b.length,d=0,d=0;db.K?-1:1}D("X.object",W);D("X.object.prototype.modified",W.prototype.n);function Tc(){}function Uc(a){for(var b=a.i.count,c=[],d=0,d=0;dg;f--,g++){var h=b[g];b[g]=b[f];b[f]=h}b=a}return 1==c?b[0]:b} -function sd(a,b,c){L.Ga(a.c+".reslice");var d=b.R,e=c.max,f=c.data,g=d[2],h=d[1],d=d[0],j=b.l!=r,k=h*d,l=Array(g),p=Array(g),u=0,v=r;b.Q&&(v=b.Q.Ya);for(var x=0,z=0,C=0,E=0,A=4*k,x=0;xe&&m(Error("Could not find scalar for vertex.")),j=g[j],f[h++]=j,f[h++]=j,f[h++]=j;b.v.t= -g;b.v.zc=f;b.v.f=q;L.ta(this.c+".parse");d=new Rc;d.aa=b;d.u=a;this.dispatchEvent(d)};F("X.parserLBL",xd);F("X.parserLBL.prototype.parse",xd.prototype.parse);function yd(a,b){this.x=ja(a)?a:0;this.y=ja(b)?b:0}w=yd.prototype;w.h=function(){return new yd(this.x,this.y)};function zd(a,b){return new yd(a.x-b.x,a.y-b.y)}w.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};w.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};w.translate=function(a,b){a instanceof yd?(this.x+=a.x,this.y+=a.y):(this.x+=a,D(b)&&(this.y+=b));return this};w.scale=function(a,b){var c=D(b)?b:a;this.x*=a;this.y*=c;return this};function Ad(a,b,c,d){this.top=a;this.right=b;this.bottom=c;this.left=d}w=Ad.prototype;w.h=function(){return new Ad(this.top,this.right,this.bottom,this.left)};w.contains=function(a){return!this||!a?s:a instanceof Ad?a.left>=this.left&&a.right<=this.right&&a.top>=this.top&&a.bottom<=this.bottom:a.x>=this.left&&a.x<=this.right&&a.y>=this.top&&a.y<=this.bottom}; -w.floor=function(){this.top=Math.floor(this.top);this.right=Math.floor(this.right);this.bottom=Math.floor(this.bottom);this.left=Math.floor(this.left);return this};w.round=function(){this.top=Math.round(this.top);this.right=Math.round(this.right);this.bottom=Math.round(this.bottom);this.left=Math.round(this.left);return this};w.translate=function(a,b){a instanceof yd?(this.left+=a.x,this.right+=a.x,this.top+=a.y,this.bottom+=a.y):(this.left+=a,this.right+=a,D(b)&&(this.top+=b,this.bottom+=b));return this}; -w.scale=function(a,b){var c=D(b)?b:a;this.left*=a;this.right*=a;this.top*=c;this.bottom*=c;return this};function Bd(a,b){this.width=a;this.height=b}Bd.prototype.h=function(){return new Bd(this.width,this.height)};Bd.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};Bd.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};Bd.prototype.scale=function(a,b){var c=D(b)?b:a;this.width*=a;this.height*=c;return this};function Cd(a,b,c,d){this.left=a;this.top=b;this.width=c;this.height=d}w=Cd.prototype;w.h=function(){return new Cd(this.left,this.top,this.width,this.height)};w.Uf=function(a){var b=Math.max(this.left,a.left),c=Math.min(this.left+this.width,a.left+a.width);if(b<=c){var d=Math.max(this.top,a.top);a=Math.min(this.top+this.height,a.top+a.height);if(d<=a)return this.left=b,this.top=d,this.width=c-b,this.height=a-d,q}return s}; -w.contains=function(a){return a instanceof Cd?this.left<=a.left&&this.left+this.width>=a.left+a.width&&this.top<=a.top&&this.top+this.height>=a.top+a.height:a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this.top+this.height};function Dd(a,b){var c=b.x");c=c.join("")}var f=a.createElement(c);if(d)if(ma(d))f.className=d;else if(y(d))Fd.apply(r,[f].concat(d));else{var c=function(a,b){"style"==b?f.style.cssText=a:"class"==b?f.className=a:"for"==b?f.htmlFor=a:b in Ld?f.setAttribute(Ld[b],a):0==b.lastIndexOf("aria-",0)||0==b.lastIndexOf("data-",0)?f.setAttribute(b, -a):f[b]=a},g;for(g in d)c.call(n,d[g],g)}if(2a.clientWidth||a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return r} -function Yd(a){for(var b=new Ad(0,Infinity,Infinity,0),c=Hd(a),d=c.O.body,e=c.O.documentElement,f=!kb&&"CSS1Compat"==c.O.compatMode?c.O.documentElement:c.O.body;a=Xd(a);)if((!M||0!=a.clientWidth)&&(!kb||0!=a.clientHeight||a!=d)&&a!=d&&a!=e&&"visible"!=Ud(a,"overflow")){var g=Zd(a),h;h=a;if(jb&&!xb("1.9")){var j=parseFloat(Td(h,"borderLeftWidth"));if($d(h))var k=h.offsetWidth-h.clientWidth-j-parseFloat(Td(h,"borderRightWidth")),j=j+k;h=new yd(j,parseFloat(Td(h,"borderTopWidth")))}else h=new yd(h.clientLeft, -h.clientTop);g.x+=h.x;g.y+=h.y;b.top=Math.max(b.top,g.y);b.right=Math.min(b.right,g.x+a.clientWidth);b.bottom=Math.min(b.bottom,g.y+a.clientHeight);b.left=Math.max(b.left,g.x)}d=f.scrollLeft;f=f.scrollTop;b.left=Math.max(b.left,d);b.top=Math.max(b.top,f);c=(c.O.parentWindow||c.O.defaultView||window).document;c="CSS1Compat"==c.compatMode?c.documentElement:c.body;c=new Bd(c.clientWidth,c.clientHeight);b.right=Math.min(b.right,d+c.width);b.bottom=Math.min(b.bottom,f+c.height);return 0<=b.top&&0<=b.left&& +function Y(a,b,c){c!=r||(c=1);var d=1,e=Uint8Array;switch(b){case "schar":e=Int8Array;break;case "ushort":e=Uint16Array;d=2;break;case "sshort":e=Int16Array;d=2;break;case "uint":e=Uint32Array;d=4;break;case "sint":e=Int32Array;d=4;break;case "float":e=Float32Array,d=4}b=new e(a.X.slice(a.B,a.B+=c*d));if(a.Ag!=a.$c){a=b;b=new Uint8Array(a.buffer,a.byteOffset,a.byteLength);for(e=0;eg;f--,g++){var h=b[g];b[g]=b[f];b[f]=h}b=a}return 1==c?b[0]:b} +function sd(a,b,c){H.Ea(a.c+".reslice");var d=b.aa,e=c.max,f=c.data,g=d[2],h=d[1],d=d[0],l=b.m!=r,j=h*d,k=Array(g),p=Array(g),t=0,v=r;b.$&&(v=b.$.pb);for(var z=0,A=0,C=0,E=0,x=4*j,z=0;ze&&m(Error("Could not find scalar for vertex.")),l=g[l],f[h++]=l,f[h++]=l,f[h++]=l;b.u.v= +g;b.u.sc=f;b.u.g=q;H.qa(this.c+".parse");d=new Rc;d.Y=b;d.q=a;this.dispatchEvent(d)};D("X.parserLBL",xd);D("X.parserLBL.prototype.parse",xd.prototype.parse);function yd(a,b){this.x=ga(a)?a:0;this.y=ga(b)?b:0}w=yd.prototype;w.h=function(){return new yd(this.x,this.y)};function zd(a,b){return new yd(a.x-b.x,a.y-b.y)}w.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};w.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};w.translate=function(a,b){a instanceof yd?(this.x+=a.x,this.y+=a.y):(this.x+=a,y(b)&&(this.y+=b));return this};w.scale=function(a,b){var c=y(b)?b:a;this.x*=a;this.y*=c;return this};function Ad(a,b,c,d){this.top=a;this.right=b;this.bottom=c;this.left=d}w=Ad.prototype;w.h=function(){return new Ad(this.top,this.right,this.bottom,this.left)};w.contains=function(a){return!this||!a?s:a instanceof Ad?a.left>=this.left&&a.right<=this.right&&a.top>=this.top&&a.bottom<=this.bottom:a.x>=this.left&&a.x<=this.right&&a.y>=this.top&&a.y<=this.bottom}; +w.floor=function(){this.top=Math.floor(this.top);this.right=Math.floor(this.right);this.bottom=Math.floor(this.bottom);this.left=Math.floor(this.left);return this};w.round=function(){this.top=Math.round(this.top);this.right=Math.round(this.right);this.bottom=Math.round(this.bottom);this.left=Math.round(this.left);return this};w.translate=function(a,b){a instanceof yd?(this.left+=a.x,this.right+=a.x,this.top+=a.y,this.bottom+=a.y):(this.left+=a,this.right+=a,y(b)&&(this.top+=b,this.bottom+=b));return this}; +w.scale=function(a,b){var c=y(b)?b:a;this.left*=a;this.right*=a;this.top*=c;this.bottom*=c;return this};function Bd(a,b){this.width=a;this.height=b}Bd.prototype.h=function(){return new Bd(this.width,this.height)};Bd.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};Bd.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};Bd.prototype.scale=function(a,b){var c=y(b)?b:a;this.width*=a;this.height*=c;return this};function Cd(a,b,c,d){this.left=a;this.top=b;this.width=c;this.height=d}w=Cd.prototype;w.h=function(){return new Cd(this.left,this.top,this.width,this.height)};w.Of=function(a){var b=Math.max(this.left,a.left),c=Math.min(this.left+this.width,a.left+a.width);if(b<=c){var d=Math.max(this.top,a.top);a=Math.min(this.top+this.height,a.top+a.height);if(d<=a)return this.left=b,this.top=d,this.width=c-b,this.height=a-d,q}return s}; +w.contains=function(a){return a instanceof Cd?this.left<=a.left&&this.left+this.width>=a.left+a.width&&this.top<=a.top&&this.top+this.height>=a.top+a.height:a.x>=this.left&&a.x<=this.left+this.width&&a.y>=this.top&&a.y<=this.top+this.height};w.floor=function(){this.left=Math.floor(this.left);this.top=Math.floor(this.top);this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this}; +w.round=function(){this.left=Math.round(this.left);this.top=Math.round(this.top);this.width=Math.round(this.width);this.height=Math.round(this.height);return this};w.translate=function(a,b){a instanceof yd?(this.left+=a.x,this.top+=a.y):(this.left+=a,y(b)&&(this.top+=b));return this};w.scale=function(a,b){var c=y(b)?b:a;this.left*=a;this.width*=a;this.top*=c;this.height*=c;return this};var Dd;function Ed(a,b){var c;c=a.className;c=la(c)&&c.match(/\S+/g)||[];for(var d=Ib(arguments,1),e=c.length+d.length,f=c,g=0;g");c=c.join("")}var f=a.createElement(c);if(d)if(la(d))f.className=d;else if(ha(d))Ed.apply(r,[f].concat(d));else{var c=function(a,b){"style"==b?f.style.cssText=a:"class"==b?f.className=a:"for"==b?f.htmlFor=a:b in Kd?f.setAttribute(Kd[b],a):0==b.lastIndexOf("aria-",0)||0==b.lastIndexOf("data-",0)? +f.setAttribute(b,a):f[b]=a},g;for(g in d)c.call(n,d[g],g)}if(2a.clientWidth||a.scrollHeight>a.clientHeight||"fixed"==c||"absolute"==c||"relative"==c))return a;return r} +function Xd(a){for(var b=new Ad(0,Infinity,Infinity,0),c=Gd(a),d=c.N.body,e=c.N.documentElement,f=!db&&"CSS1Compat"==c.N.compatMode?c.N.documentElement:c.N.body;a=Wd(a);)if((!L||0!=a.clientWidth)&&(!db||0!=a.clientHeight||a!=d)&&a!=d&&a!=e&&"visible"!=Td(a,"overflow")){var g=Yd(a),h;h=a;if(bb&&!pb("1.9")){var l=parseFloat(Sd(h,"borderLeftWidth"));if(Zd(h))var j=h.offsetWidth-h.clientWidth-l-parseFloat(Sd(h,"borderRightWidth")),l=l+j;h=new yd(l,parseFloat(Sd(h,"borderTopWidth")))}else h=new yd(h.clientLeft, +h.clientTop);g.x+=h.x;g.y+=h.y;b.top=Math.max(b.top,g.y);b.right=Math.min(b.right,g.x+a.clientWidth);b.bottom=Math.min(b.bottom,g.y+a.clientHeight);b.left=Math.max(b.left,g.x)}d=f.scrollLeft;f=f.scrollTop;b.left=Math.max(b.left,d);b.top=Math.max(b.top,f);c=(c.N.parentWindow||c.N.defaultView||window).document;c="CSS1Compat"==c.compatMode?c.documentElement:c.body;c=new Bd(c.clientWidth,c.clientHeight);b.right=Math.min(b.right,d+c.width);b.bottom=Math.min(b.bottom,f+c.height);return 0<=b.top&&0<=b.left&& b.bottom>b.top&&b.right>b.left?b:r} -function Zd(a){var b,c=Jd(a),d=Ud(a,"position"),e=jb&&c.getBoxObjectFor&&!a.getBoundingClientRect&&"absolute"==d&&(b=c.getBoxObjectFor(a))&&(0>b.screenX||0>b.screenY),f=new yd(0,0),g=Vd(c);if(a==g)return f;if(a.getBoundingClientRect)b=Wd(a),a=Sd(Hd(c)),f.x=b.left+a.x,f.y=b.top+a.y;else if(c.getBoxObjectFor&&!e)b=c.getBoxObjectFor(a),a=c.getBoxObjectFor(g),f.x=b.screenX-a.screenX,f.y=b.screenY-a.screenY;else{b=a;do{f.x+=b.offsetLeft;f.y+=b.offsetTop;b!=a&&(f.x+=b.clientLeft||0,f.y+=b.clientTop||0); -if(kb&&"fixed"==Ud(b,"position")){f.x+=c.body.scrollLeft;f.y+=c.body.scrollTop;break}b=b.offsetParent}while(b&&b!=a);if(ib||kb&&"absolute"==d)f.y-=c.body.offsetTop;for(b=a;(b=Xd(b))&&b!=c.body&&b!=g;)if(f.x-=b.scrollLeft,!ib||"TR"!=b.tagName)f.y-=b.scrollTop}return f} -function ae(a){var b=new yd;if(1==a.nodeType){if(a.getBoundingClientRect){var c=Wd(a);b.x=c.left;b.y=c.top}else{var c=Sd(Hd(a)),d=Zd(a);b.x=d.x-c.x;b.y=d.y-c.y}if(jb&&!xb(12)){var e;M?e="-ms-transform":kb?e="-webkit-transform":ib?e="-o-transform":jb&&(e="-moz-transform");var f;e&&(f=Ud(a,e));f||(f=Ud(a,"transform"));f?(a=f.match(be),a=!a?new yd(0,0):new yd(parseFloat(a[1]),parseFloat(a[2]))):a=new yd(0,0);b=new yd(b.x+a.x,b.y+a.y)}}else e=na(a.kh),f=a,a.targetTouches?f=a.targetTouches[0]:e&&a.Pa.targetTouches&& -(f=a.Pa.targetTouches[0]),b.x=f.clientX,b.y=f.clientY;return b}function ce(a,b){"number"==typeof a&&(a=(b?Math.round(a):a)+"px");return a}function de(a){if("none"!=Ud(a,"display"))return ee(a);var b=a.style,c=b.display,d=b.visibility,e=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";a=ee(a);b.display=c;b.position=e;b.visibility=d;return a} -function ee(a){var b=a.offsetWidth,c=a.offsetHeight,d=kb&&!b&&!c;return(!ja(b)||d)&&a.getBoundingClientRect?(a=Wd(a),new Bd(a.right-a.left,a.bottom-a.top)):new Bd(b,c)}function fe(a,b){a.style.display=b?"":"none"}function $d(a){return"rtl"==Ud(a,"direction")}function ge(a,b){if(/^\d+px?$/.test(b))return parseInt(b,10);var c=a.style.left,d=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;a.style.left=b;var e=a.style.pixelLeft;a.style.left=c;a.runtimeStyle.left=d;return e} -function he(a,b){var c=a.currentStyle?a.currentStyle[b]:r;return c?ge(a,c):0}var ie={thin:2,medium:4,thick:6};function je(a,b){if("none"==(a.currentStyle?a.currentStyle[b+"Style"]:r))return 0;var c=a.currentStyle?a.currentStyle[b+"Width"]:r;return c in ie?ie[c]:ge(a,c)}var be=/matrix\([0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, ([0-9\.\-]+)p?x?, ([0-9\.\-]+)p?x?\)/;function ke(a,b){bc.call(this);this.s=a;var c=oa(this.s)&&1==this.s.nodeType?this.s:this.s?this.s.body:r;this.Dh=!!c&&$d(c);this.Xj=P(this.s,jb?"DOMMouseScroll":"mousewheel",this,b)}G(ke,bc); -ke.prototype.handleEvent=function(a){var b=0,c=0,d=0;a=a.Pa;if("mousewheel"==a.type){c=1;if(M||kb&&(bb||xb("532.0")))c=40;d=le(-a.wheelDelta,c);ja(a.wheelDeltaX)?(b=le(-a.wheelDeltaX,c),c=le(-a.wheelDeltaY,c)):c=d}else d=a.detail,100d&&(d=-3),ja(a.axis)&&a.axis===a.HORIZONTAL_AXIS?b=d:c=d;D(this.$f)&&(b=Math.min(Math.max(b,-this.$f),this.$f));D(this.ag)&&(c=Math.min(Math.max(c,-this.ag),this.ag));this.Dh&&(b=-b);b=new me(d,a,b,c);this.dispatchEvent(b)}; -function le(a,b){return kb&&($a||cb)&&0!=a%b?a:a/b}function me(a,b,c,d){b&&this.ha(b,n);this.type="mousewheel";this.detail=a;this.Tj=c;this.vc=d}G(me,Nb);M||kb&&xb("525");function ne(a){(a==r||!(a instanceof Element))&&m(Error("Could not add interactor to the given element."));Q.call(this);this.c="interactor";this.ua=a;this.fe=this.of=this.nf=this.pf=this.mf=this.qf=r;this.kd=q;this.Eb=this.wb=this.Xa=s;this.gb=[0,0];this.ae=new L.g(0,0,0);this.Dc=new L.g(0,0,0);this.Wf=0;this.yf=this.fd=r;this.xf=s;this.D={MOUSEWHEEL_ENABLED:q,MOUSECLICKS_ENABLED:q,KEYBOARD_ENABLED:q,HOVERING_ENABLED:q,CONTEXTMENU_ENABLED:s,TOUCH_ENABLED:q,TOUCH_BOUNCING_ENABLED:s}}G(ne,Q); -ne.prototype.__defineGetter__("config",t("D"));ne.prototype.__defineGetter__("leftButtonDown",t("Xa"));ne.prototype.__defineGetter__("middleButtonDown",t("wb"));ne.prototype.__defineGetter__("rightButtonDown",t("Eb")); -ne.prototype.ha=function(){this.D.MOUSEWHEEL_ENABLED?(this.fe=new ke(this.ua),this.qf=P(this.fe,"mousewheel",this.Xc.bind(this))):(Wb(this.qf),this.fe=r);this.D.MOUSECLICKS_ENABLED?(this.mf=P(this.ua,"mousedown",this.Qh.bind(this)),this.pf=P(this.ua,"mouseup",this.Vh.bind(this))):(Wb(this.mf),Wb(this.pf));this.ua.oncontextmenu=this.D.CONTEXTMENU_ENABLED?r:function(){return s};window.onkeydown=this.D.KEYBOARD_ENABLED?this.fg.bind(this):r;this.D.TOUCH_ENABLED?(this.D.TOUCH_BOUNCING_ENABLED||document.body.addEventListener("touchmove", -function(a){a.preventDefault()},s),this.Lg=P(this.ua,"touchstart",this.hi.bind(this)),this.Kg=P(this.ua,"touchmove",this.fi.bind(this)),this.Jg=P(this.ua,"touchend",this.bi.bind(this))):(Wb(this.Lg),Wb(this.Kg),Wb(this.Jg));Wb(this.nf);Wb(this.of);this.nf=P(this.ua,"mousemove",this.Sh.bind(this));this.of=P(this.ua,"mouseout",this.Th.bind(this))}; -ne.prototype.Qh=function(a){0==a.button?this.Xa=q:1==a.button?this.wb=q:2==a.button&&(this.Eb=q);eval("this.onMouseDown("+this.Xa+","+this.wb+","+this.Eb+")");oe(this);a.preventDefault()};ne.prototype.Ph=ba();ne.prototype.Vh=function(a){0==a.button?this.Xa=s:1==a.button?this.wb=s:2==a.button&&(this.Eb=s);eval("this.onMouseUp("+this.Xa+","+this.wb+","+this.Eb+")");oe(this);a.preventDefault()};ne.prototype.__defineGetter__("mousePosition",t("gb"));w=ne.prototype;w.Uh=ba(); -w.Th=function(a){this.kd=s;this.D.KEYBOARD_ENABLED&&(window.onkeydown=r);this.Eb=this.wb=this.Xa=s;oe(this);this.ae=new L.g(0,0,0);a.preventDefault()};w.Rh=ba();w.hi=function(a){a.preventDefault();a.ha(a.Pa.targetTouches[0],a.currentTarget);eval("this.onTouchStart("+a.clientX+","+a.clientY+")");this.Dc=new L.g(a.clientX,a.clientY,0);this.yf=setTimeout(this.di.bind(this,a),500)};w.gi=ba(); -w.di=function(a){eval("this.onTouchHover("+a.clientX+","+a.clientY+")");a=new jd;a.Ta=q;a.Ja=this instanceof pe;this.dispatchEvent(a);this.pd=q};w.ci=ba();function qe(a){clearTimeout(a.yf);if(a.pd){var b=new jd;b.Ta=s;b.Ja=a instanceof pe;a.dispatchEvent(b)}a.pd=s}w.bi=function(a){a.preventDefault();eval("this.onTouchEnd()");qe(this)};w.ai=ba(); -w.fi=function(a){a.preventDefault();this.pd||qe(this);this.touchmoveEvent=a=a.Pa;eval("this.onTouchMove(this['touchmoveEvent'])");var b=a.targetTouches;if(1==b.length){a=b[0];var c=[a.clientX,a.clientY];a=new L.g(c[0],c[1],0);var b=c[0]>3*this.ua.clientWidth/4,d=c[0]3*this.ua.clientHeight/4,c=!b&&!d&&!e&&!c,e=this.Dc.na(a);this.Dc=a.h();if(this.pd)a=new hd,5e.x&&(e.x=-1),5e.y&&(e.y=-1),a.M=e,this.dispatchEvent(a); -else if(this instanceof re&&(b||d))a=new kd,a.K=0>e.y,this.dispatchEvent(a);else if(this instanceof pe||c)e.scale(3),a=new id,a.M=e,this.dispatchEvent(a)}else 2==b.length&&(a=b[0],b=b[1],a=[a.clientX,a.clientY],b=[b.clientX,b.clientY],a=new L.g(a[0],a[1],0),b=new L.g(b[0],b[1],0),e=xc(a,b),b=e-this.Wf,this.Wf=e,this.Dc.na(a),this.Dc=a.h(),10Math.abs(a.x)&&(a.x=0);2>Math.abs(a.y)&&(a.y=0);0!=a.nb()&&(this.Xa&&!b?(b=new id,a.scale(3),b.M=a,this.dispatchEvent(b)):this.wb||this.Xa&&b?(b=new hd,5a.x&&(a.x=-5),5a.y&&(a.y=-5),b.M=a,this.dispatchEvent(b)):this.Eb&&(b=new jd,b.Ta=0=f&&(a.preventDefault(),e?a=new hd:b?a=new jd:(a=new id,this instanceof re&&(a=new kd)),a&&(c=new L.g(0,0,0),37==f?(c.x=5,a.K=s,b&&(a.K=q,a.Ta=q,a.Ja=s)):39==f?(c.x=-5,a.K=q,b&&(a.Ta=s,a.Ja=s)):38==f?(c.y=5,a.K=q,b&&(a.Ta=q,a.Ja=q)):40==f&&(c.y=-5,a.K=s,b&&(a.Ta= -s,a.Ja=q)),a.M=c,this.dispatchEvent(a)))}};F("X.interactor",ne);F("X.interactor.prototype.init",ne.prototype.ha);F("X.interactor.prototype.onMouseDown",ne.prototype.Ph);F("X.interactor.prototype.onMouseUp",ne.prototype.Uh);F("X.interactor.prototype.onMouseMove",ne.prototype.Rh);F("X.interactor.prototype.onMouseWheel",ne.prototype.Wh);F("X.interactor.prototype.onKey",ne.prototype.Nh);F("X.interactor.prototype.onTouchStart",ne.prototype.gi);F("X.interactor.prototype.onTouchMove",ne.prototype.ei); -F("X.interactor.prototype.onTouchEnd",ne.prototype.ai);F("X.interactor.prototype.onTouchHover",ne.prototype.ci);function re(a){ne.call(this,a);this.c="interactor2D"}G(re,ne);re.prototype.Xc=function(a){re.r.Xc.call(this,a);var b=new kd;a.vc==r&&(a.vc=0);b.K=0>a.vc;this.dispatchEvent(b)};function ue(a){U.call(this);this.c="slice";this.k=[0,0,0];this.kc=[0,0,1];this.K=[0,1,0];this.B=this.H=10;this.Fb=[0,1,0,0,1,1,1,1,1,0,0,0];this.l=this.jb=r;this.Sa=q;this.gc=[1,1,1];a!=r&&this.Zb(a)}G(ue,U);ue.prototype.Zb=function(a){this.k=a.k.slice();this.kc=a.kc.slice();this.K=a.K.slice();this.H=a.H;this.B=a.B;this.jb=a.jb;this.l=a.l;this.Sa=a.Sa;this.gc=a.gc;this.Gg=a.Gg;ue.r.Zb.call(this,a)}; -ue.prototype.uc=function(){var a=new S(this.kc[0],this.kc[1],this.kc[2]),b=new S(this.K[0],this.K[1],this.K[2]),c=zc(b,a),d=new S(this.k[0],this.k[1],this.k[2]),e=new S(1,1,1);1==a.x?(e=new S(this.k[0],this.B/2,this.H/2),this.Fb=[0,0,1,0,0,1,0,1,1,1,1,0]):1==a.y?(e=new S(this.H/2,this.k[1],this.B/2),this.Fb=[0,0,0,1,1,0,1,0,1,1,0,1]):1==a.b&&(e=new S(this.H/2,this.B/2,this.k[2]));var f=yc(c.h().I(),b.h().I()),f=new S(f.x*e.x,f.y*e.y,f.b*e.b);f.add(d);var g=yc(c.h().I(),b),g=new S(g.x*e.x,g.y*e.y, -g.b*e.b);g.add(d);var h=yc(c,b.h().I()),h=new S(h.x*e.x,h.y*e.y,h.b*e.b);h.add(d);var j=h,b=yc(c,b),b=new S(b.x*e.x,b.y*e.y,b.b*e.b);b.add(d);d=g;this.i=new T(18);this.j=new T(18);this.i.add(f.x,f.y,f.b);this.i.add(g.x,g.y,g.b);this.i.add(h.x,h.y,h.b);this.i.add(j.x,j.y,j.b);this.i.add(b.x,b.y,b.b);this.i.add(d.x,d.y,d.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.Sa&&(a=new U,a.i=new T(24),a.j= -new T(24),a.i.add(f.x,f.y,f.b),a.i.add(g.x,g.y,g.b),a.i.add(g.x,g.y,g.b),a.i.add(b.x,b.y,b.b),a.i.add(b.x,b.y,b.b),a.i.add(h.x,h.y,h.b),a.i.add(h.x,h.y,h.b),a.i.add(f.x,f.y,f.b),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.Nb=[this.gc[0],this.gc[1],this.gc[2]],a.la="LINES",a.mc=2,this.e.push(a))};F("X.slice",ue);function R(a){U.call(this);this.c="volume";this.k=[0,0,0];this.R=[10,10,10];this.J=[1,1,1];this.sb=[];this.Cc=this.Wa=this.Bc=this.Va=this.Ac=this.Ua=0;this.T=new U;this.U=new U;this.hb=new U;this.rd=this.Na=s;this.Hb=0;this.l=r;this.Sa=q;this.X=Infinity;this.W=-Infinity;this.ie=q;Ea(this,new pc);Ea(this,new Pc);a!=r&&this.Zb(a)}G(R,U); -R.prototype.Zb=function(a){window.console.log(a);this.k=a.k.slice();this.R=a.R.slice();this.J=a.J.slice();this.Ua=a.Ua;this.Ac=a.Ac;this.Va=a.Va;this.Bc=a.Bc;this.Wa=a.Wa;this.Cc=a.Cc;this.T=new U(a.T);this.U=new U(a.U);this.hb=new U(a.hb);this.Na=a.Na;this.rd=a.rd;this.Hb=a.Hb;this.l=a.l;this.Sa=a.Sa;R.r.Zb.call(this,a)}; -R.prototype.uc=function(){this.e.length=0;this.T.e.length=0;this.U.e.length=0;this.hb.e.length=0;this.e.push(this.T);this.e.push(this.U);this.e.push(this.hb);for(var a=0,a=0;3>a;a++){for(var b=(this.R[a]-1)/2,c=b,d=0,d=0;db;b++){var c=this.e[b],d=0,e=0;0==b?(d=this.Ua,e=this.Ac,this.Ac=this.Ua):1==b?(d=this.Va,e=this.Bc,this.Bc=this.Va):2==b&&(d=this.Wa,e=this.Cc, -this.Cc=this.Wa);c.e[parseInt(e,10)].visible=s;c=c.e[parseInt(d,10)];c.visible=q;c.ba=1}}a&&R.r.n.call(this)};R.prototype.__defineGetter__("dimensions",t("R"));R.prototype.__defineGetter__("volumeRendering",t("Na"));R.prototype.__defineSetter__("volumeRendering",function(a){this.Na=a;this.n(s)});R.prototype.__defineGetter__("visible",t("qa")); -R.prototype.__defineSetter__("visible",function(a){if(a)this.qa=a,this.n(s);else{for(var b=this.e,c=b.length,d=0,d=0;d>8,c+=String.fromCharCode(p),c+=String.fromCharCode(l),c=parseInt(c,10);k--}else if(4161==f){j++;for(var d=h[j++],e="",f=0;f>8,e+=String.fromCharCode(p),e+=String.fromCharCode(l);g.ma=[g.ma[0],g.ma[1],Math.min(Math.abs(g.Yf-e),g.ma[2])];g.Yf= -e;k--}g.za[2]++}else{var g={rows:0,cols:0,ma:r,qe:0,Qg:0,$a:1,Lh:1,Yf:r,Id:0,eb:0,Tc:r,Qe:0,We:[],data:r,min:Infinity,max:-Infinity};g.$a=b.o.length;g.$a==r&&(g.$a=1);for(var h=Y(this,"ushort",this.$.byteLength),j=66,d=r,f=r,d=r,k=7;0>8,e=e+String.fromCharCode(p),e=e+String.fromCharCode(l);e=e.split("\\");g.ma=[+e[0],+e[1],Infinity];k--}else if(32==d&&(f=h[j++],19==f)){j++;d=h[j++];for(f=0;f>8,c+=String.fromCharCode(p),c+=String.fromCharCode(l),c=parseInt(c,10);k--}b.fc=g;g.za=[g.cols,g.rows,1];g.eb=g.rows*g.cols;switch(g.qe){case 8:g.Tc=new Uint8Array(g.cols*g.rows*g.$a);g.data=new Uint8Array(g.cols*g.rows*g.$a);break;case 16:g.Tc=new Uint16Array(g.cols*g.rows*g.$a);g.data=new Uint16Array(g.cols* -g.rows*g.$a);break;case 32:g.Tc=new Uint32Array(g.cols*g.rows*g.$a),g.data=new Uint32Array(g.cols*g.rows*g.$a)}}this.F=this.$.byteLength-2*g.eb;h=r;switch(g.qe){case 8:h=Y(this,"uchar",g.eb);break;case 16:h=Y(this,"ushort",g.eb);break;case 32:h=Y(this,"uint",g.eb)}g.We[c]=g.Qe;g.Tc.set(h,g.Qe*g.eb);g.Qe++;++g.Id;return g};F("X.parserDCM",ye);F("X.parserDCM.prototype.parse",ye.prototype.parse);function ze(){pd.call(this);this.c="parserVTK"}G(ze,pd); -ze.prototype.parse=function(a,b,c){L.Ga(this.c+".parse");var d=b.i,e=b.j,f=new Uint8Array(c),g="";b.i=d=new T(c.byteLength);b.j=e=new T(c.byteLength);c=0;for(var h=f.length;c=l);p++){var u=parseInt(k[p],10),v=c.get(u);d.add(v[0],v[1],v[2]);var x=u,z=v;"LINES"==this.va?(x=parseInt(k[p+1],10),z=c.get(x),d.add(z[0],z[1],z[2])):"TRIANGLE_STRIPS"==this.va&&(0==p||p==l-1)&&d.add(v[0],v[1],v[2]);uc&&10!=g);Y(this,"uchar");e=Y(this,"uint");c=Y(this,"uint");var h=Y(this,"float",3*e);g=Y(this,"uint",3*c);var j=new Uint32Array(e),k=new Float32Array(9*c);b.i=d=new T(9*c);b.j=e=new T(9*c);var l;for(l=0;l>>8^e[(b^a[c])&255];for(f=d>>3;f--;c+=8)b=b>>>8^e[(b^a[c])&255],b=b>>>8^e[(b^a[c+1])&255],b=b>>>8^e[(b^a[c+2])&255],b=b>>>8^e[(b^a[c+3])&255],b=b>>>8^e[(b^a[c+4])&255],b=b>>>8^e[(b^a[c+5])&255],b=b>>>8^e[(b^a[c+6])&255],b=b>>>8^e[(b^a[c+7])&255];return(b^4294967295)>>>0}}; -Ce.yg=new Uint32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101, +function Yd(a){var b,c=Id(a),d=Td(a,"position"),e=bb&&c.getBoxObjectFor&&!a.getBoundingClientRect&&"absolute"==d&&(b=c.getBoxObjectFor(a))&&(0>b.screenX||0>b.screenY),f=new yd(0,0),g=Ud(c);if(a==g)return f;if(a.getBoundingClientRect)b=Vd(a),a=Rd(Gd(c)),f.x=b.left+a.x,f.y=b.top+a.y;else if(c.getBoxObjectFor&&!e)b=c.getBoxObjectFor(a),a=c.getBoxObjectFor(g),f.x=b.screenX-a.screenX,f.y=b.screenY-a.screenY;else{b=a;do{f.x+=b.offsetLeft;f.y+=b.offsetTop;b!=a&&(f.x+=b.clientLeft||0,f.y+=b.clientTop||0); +if(db&&"fixed"==Td(b,"position")){f.x+=c.body.scrollLeft;f.y+=c.body.scrollTop;break}b=b.offsetParent}while(b&&b!=a);if(ab||db&&"absolute"==d)f.y-=c.body.offsetTop;for(b=a;(b=Wd(b))&&b!=c.body&&b!=g;)if(f.x-=b.scrollLeft,!ab||"TR"!=b.tagName)f.y-=b.scrollTop}return f}function $d(a,b){"number"==typeof a&&(a=(b?Math.round(a):a)+"px");return a} +function ae(a){if("none"!=Td(a,"display"))return be(a);var b=a.style,c=b.display,d=b.visibility,e=b.position;b.visibility="hidden";b.position="absolute";b.display="inline";a=be(a);b.display=c;b.position=e;b.visibility=d;return a}function be(a){var b=a.offsetWidth,c=a.offsetHeight,d=db&&!b&&!c;return(!ga(b)||d)&&a.getBoundingClientRect?(a=Vd(a),new Bd(a.right-a.left,a.bottom-a.top)):new Bd(b,c)}function ce(a,b){a.style.display=b?"":"none"}function Zd(a){return"rtl"==Td(a,"direction")} +function de(a,b){if(/^\d+px?$/.test(b))return parseInt(b,10);var c=a.style.left,d=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;a.style.left=b;var e=a.style.pixelLeft;a.style.left=c;a.runtimeStyle.left=d;return e}function ee(a,b){var c=a.currentStyle?a.currentStyle[b]:r;return c?de(a,c):0}var fe={thin:2,medium:4,thick:6};function ge(a,b){if("none"==(a.currentStyle?a.currentStyle[b+"Style"]:r))return 0;var c=a.currentStyle?a.currentStyle[b+"Width"]:r;return c in fe?fe[c]:de(a,c)} +var he=/matrix\([0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, [0-9\.\-]+, ([0-9\.\-]+)p?x?, ([0-9\.\-]+)p?x?\)/;function ie(a,b){sb.call(this);this.r=a;var c=na(this.r)&&1==this.r.nodeType?this.r:this.r?this.r.body:r;this.wh=!!c&&Zd(c);this.Nj=O(this.r,bb?"DOMMouseScroll":"mousewheel",this,b)}F(ie,bc); +ie.prototype.handleEvent=function(a){var b=0,c=0,d=0;a=a.Ma;if("mousewheel"==a.type){c=1;if(L||db&&(Va||pb("532.0")))c=40;d=je(-a.wheelDelta,c);ga(a.wheelDeltaX)?(b=je(-a.wheelDeltaX,c),c=je(-a.wheelDeltaY,c)):c=d}else d=a.detail,100d&&(d=-3),ga(a.axis)&&a.axis===a.HORIZONTAL_AXIS?b=d:c=d;y(this.Uf)&&(b=Math.min(Math.max(b,-this.Uf),this.Uf));y(this.Vf)&&(c=Math.min(Math.max(c,-this.Vf),this.Vf));this.wh&&(b=-b);b=new ke(d,a,b,c);this.dispatchEvent(b)}; +function je(a,b){return db&&(Ta||Wa)&&0!=a%b?a:a/b}function ke(a,b,c,d){b&&this.ea(b,n);this.type="mousewheel";this.detail=a;this.Kj=c;this.nc=d}F(ke,Kb);L||db&&pb("525");function le(a){(a==r||!(a instanceof Element))&&m(Error("Could not add interactor to the given element."));Q.call(this);this.c="interactor";this.ra=a;this.ae=this.jf=this.hf=this.kf=this.gf=this.lf=r;this.$d=q;this.yb=this.rb=this.Xa=s;this.cd=[0,0];this.Vd=new H.f(0,0,0);this.wc=new H.f(0,0,0);this.Qf=0;this.rf=this.Zc=r;this.F={MOUSEWHEEL_ENABLED:q,MOUSECLICKS_ENABLED:q,KEYBOARD_ENABLED:q,HOVERING_ENABLED:q,CONTEXTMENU_ENABLED:s,TOUCH_ENABLED:q,TOUCH_BOUNCING_ENABLED:s}}F(le,Q); +le.prototype.__defineGetter__("config",u("F"));le.prototype.__defineGetter__("leftButtonDown",u("Xa"));le.prototype.__defineGetter__("middleButtonDown",u("rb"));le.prototype.__defineGetter__("rightButtonDown",u("yb")); +le.prototype.ea=function(){this.F.MOUSEWHEEL_ENABLED?(this.ae=new ie(this.ra),this.lf=O(this.ae,"mousewheel",this.Qc.bind(this))):(Wb(this.lf),this.ae=r);this.F.MOUSECLICKS_ENABLED?(this.gf=O(this.ra,"mousedown",this.Jh.bind(this)),this.kf=O(this.ra,"mouseup",this.Oh.bind(this))):(Wb(this.gf),Wb(this.kf));this.ra.oncontextmenu=this.F.CONTEXTMENU_ENABLED?r:function(){return s};window.onkeydown=this.F.KEYBOARD_ENABLED?this.$f.bind(this):r;this.F.TOUCH_ENABLED?(this.F.TOUCH_BOUNCING_ENABLED||document.body.addEventListener("touchmove", +function(a){a.preventDefault()},s),this.Eg=O(this.ra,"touchstart",this.bi.bind(this)),this.Dg=O(this.ra,"touchmove",this.$h.bind(this)),this.Cg=O(this.ra,"touchend",this.Wh.bind(this))):(Wb(this.Eg),Wb(this.Dg),Wb(this.Cg));Wb(this.hf);Wb(this.jf);this.hf=O(this.ra,"mousemove",this.Lh.bind(this));this.jf=O(this.ra,"mouseout",this.Mh.bind(this))}; +le.prototype.Jh=function(a){0==a.button?this.Xa=q:1==a.button?this.rb=q:2==a.button&&(this.yb=q);eval("this.onMouseDown("+this.Xa+","+this.rb+","+this.yb+")");me(this);a.preventDefault()};le.prototype.Ih=aa();le.prototype.Oh=function(a){0==a.button?this.Xa=s:1==a.button?this.rb=s:2==a.button&&(this.yb=s);eval("this.onMouseUp("+this.Xa+","+this.rb+","+this.yb+")");me(this);a.preventDefault()};le.prototype.__defineGetter__("mousePosition",u("cd"));w=le.prototype;w.Nh=aa(); +w.Mh=function(a){this.$d=s;this.F.KEYBOARD_ENABLED&&(window.onkeydown=r);this.yb=this.rb=this.Xa=s;me(this);this.Vd=new H.f(0,0,0);a.preventDefault()};w.Kh=aa();w.bi=function(a){a.preventDefault();a.ea(a.Ma.targetTouches[0],a.currentTarget);eval("this.onTouchStart("+a.clientX+","+a.clientY+")");this.wc=new H.f(a.clientX,a.clientY,0);this.rf=setTimeout(this.Yh.bind(this,a),500)};w.ai=aa(); +w.Yh=function(a){eval("this.onTouchHover("+a.clientX+","+a.clientY+")");a=new jd;a.Qa=q;a.Ha=this instanceof ne;this.dispatchEvent(a);this.jd=q};w.Xh=aa();function oe(a){clearTimeout(a.rf);if(a.jd){var b=new jd;b.Qa=s;b.Ha=a instanceof ne;a.dispatchEvent(b)}a.jd=s}w.Wh=function(a){a.preventDefault();eval("this.onTouchEnd()");oe(this)};w.Vh=aa(); +w.$h=function(a){a.preventDefault();this.jd||oe(this);this.touchmoveEvent=a=a.Ma;eval("this.onTouchMove(this['touchmoveEvent'])");var b=a.targetTouches;if(1==b.length){a=b[0];var c=[a.clientX,a.clientY];a=new H.f(c[0],c[1],0);var b=c[0]>3*this.ra.clientWidth/4,d=c[0]3*this.ra.clientHeight/4,c=!b&&!d&&!e&&!c,e=this.wc.la(a);this.wc=a.h();if(this.jd)a=new hd,5e.x&&(e.x=-1),5e.y&&(e.y=-1),a.K=e,this.dispatchEvent(a); +else if(this instanceof pe&&(b||d))a=new kd,a.I=0>e.y,this.dispatchEvent(a);else if(this instanceof ne||c)e.scale(3),a=new id,a.K=e,this.dispatchEvent(a)}else 2==b.length&&(a=b[0],b=b[1],a=[a.clientX,a.clientY],b=[b.clientX,b.clientY],a=new H.f(a[0],a[1],0),b=new H.f(b[0],b[1],0),e=xc(a,b),b=e-this.Qf,this.Qf=e,this.wc.la(a),this.wc=a.h(),10Math.abs(a.x)&&(a.x=0);2>Math.abs(a.y)&&(a.y=0);0!=a.eb()&&(this.Xa&&!b?(b=new id,a.scale(3),b.K=a,this.dispatchEvent(b)):this.rb||this.Xa&&b?(b=new hd,5a.x&&(a.x=-5),5a.y&&(a.y=-5),b.K=a,this.dispatchEvent(b)):this.yb&&(b=new jd,b.Qa=0=f&&(a.preventDefault(),e?a=new hd:b?a=new jd:(a=new id,this instanceof pe&&(a=new kd)),a&&(c=new H.f(0,0,0),37==f?(c.x=5,a.I=s,b&&(a.I=q,a.Qa=q,a.Ha=s)):39==f?(c.x=-5,a.I=q,b&&(a.Qa=s,a.Ha=s)):38==f?(c.y=5,a.I=q,b&&(a.Qa=q,a.Ha=q)):40==f&&(c.y=-5,a.I=s,b&&(a.Qa= +s,a.Ha=q)),a.K=c,this.dispatchEvent(a)))}};D("X.interactor",le);D("X.interactor.prototype.init",le.prototype.ea);D("X.interactor.prototype.onMouseDown",le.prototype.Ih);D("X.interactor.prototype.onMouseUp",le.prototype.Nh);D("X.interactor.prototype.onMouseMove",le.prototype.Kh);D("X.interactor.prototype.onMouseWheel",le.prototype.Ph);D("X.interactor.prototype.onKey",le.prototype.Gh);D("X.interactor.prototype.onTouchStart",le.prototype.ai);D("X.interactor.prototype.onTouchMove",le.prototype.Zh); +D("X.interactor.prototype.onTouchEnd",le.prototype.Vh);D("X.interactor.prototype.onTouchHover",le.prototype.Xh);function pe(a){le.call(this,a);this.c="interactor2D"}F(pe,le);pe.prototype.Qc=function(a){pe.s.Qc.call(this,a);var b=new kd;a.nc==r&&(a.nc=0);b.I=0>a.nc;this.dispatchEvent(b)};function qe(a){W.call(this);this.c="slice";this.k=[0,0,0];this.hc=[0,0,1];this.I=[0,1,0];this.G=this.M=10;this.Vb=[0,1,0,0,1,1,1,1,1,0,0,0];this.m=this.ab=r;this.Pa=q;this.ec=[1,1,1];a!=r&&this.Xb(a)}F(qe,W);qe.prototype.Xb=function(a){this.k=a.k.slice();this.hc=a.hc.slice();this.I=a.I.slice();this.M=a.M;this.G=a.G;this.ab=a.ab;this.m=a.m;this.Pa=a.Pa;this.ec=a.ec;this.zg=a.zg;qe.s.Xb.call(this,a)}; +qe.prototype.mc=function(){var a=new S(this.hc[0],this.hc[1],this.hc[2]),b=new S(this.I[0],this.I[1],this.I[2]),c=zc(b,a),d=new S(this.k[0],this.k[1],this.k[2]),e=new S(1,1,1);1==a.x?(e=new S(this.k[0],this.G/2,this.M/2),this.Vb=[0,0,1,0,0,1,0,1,1,1,1,0]):1==a.y?(e=new S(this.M/2,this.k[1],this.G/2),this.Vb=[0,0,0,1,1,0,1,0,1,1,0,1]):1==a.b&&(e=new S(this.M/2,this.G/2,this.k[2]));var f=yc(c.h().D(),b.h().D()),f=new S(f.x*e.x,f.y*e.y,f.b*e.b);f.add(d);var g=yc(c.h().D(),b),g=new S(g.x*e.x,g.y*e.y, +g.b*e.b);g.add(d);var h=yc(c,b.h().D()),h=new S(h.x*e.x,h.y*e.y,h.b*e.b);h.add(d);var l=h,b=yc(c,b),b=new S(b.x*e.x,b.y*e.y,b.b*e.b);b.add(d);d=g;this.i=new U(18);this.j=new U(18);this.i.add(f.x,f.y,f.b);this.i.add(g.x,g.y,g.b);this.i.add(h.x,h.y,h.b);this.i.add(l.x,l.y,l.b);this.i.add(b.x,b.y,b.b);this.i.add(d.x,d.y,d.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.j.add(a.x,a.y,a.b);this.Pa&&(a=new W,a.i=new U(24),a.j= +new U(24),a.i.add(f.x,f.y,f.b),a.i.add(g.x,g.y,g.b),a.i.add(g.x,g.y,g.b),a.i.add(b.x,b.y,b.b),a.i.add(b.x,b.y,b.b),a.i.add(h.x,h.y,h.b),a.i.add(h.x,h.y,h.b),a.i.add(f.x,f.y,f.b),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.j.add(0,0,0),a.Gb=[this.ec[0],this.ec[1],this.ec[2]],a.ja="LINES",a.jc=2,this.e.push(a))};D("X.slice",qe);function R(a){W.call(this);this.c="volume";this.k=[0,0,0];this.aa=[10,10,10];this.H=[1,1,1];this.jb=[];this.vc=this.mb=this.uc=this.lb=this.tc=this.kb=0;this.Q=new W;this.R=new W;this.Za=new W;this.ld=this.Ka=s;this.zb=0;this.m=r;this.Pa=q;this.U=Infinity;this.T=-Infinity;this.ee=q;Ea(this,new pc);Ea(this,new Pc);a!=r&&this.Xb(a)}F(R,W); +R.prototype.Xb=function(a){window.console.log(a);this.k=a.k.slice();this.aa=a.aa.slice();this.H=a.H.slice();this.kb=a.kb;this.tc=a.tc;this.lb=a.lb;this.uc=a.uc;this.mb=a.mb;this.vc=a.vc;this.Q=new W(a.Q);this.R=new W(a.R);this.Za=new W(a.Za);this.Ka=a.Ka;this.ld=a.ld;this.zb=a.zb;this.m=a.m;this.Pa=a.Pa;R.s.Xb.call(this,a)}; +R.prototype.mc=function(){this.e.length=0;this.Q.e.length=0;this.R.e.length=0;this.Za.e.length=0;this.e.push(this.Q);this.e.push(this.R);this.e.push(this.Za);for(var a=0,a=0;3>a;a++){for(var b=(this.aa[a]-1)/2,c=b,d=0,d=0;db;b++){var c=this.e[b],d=0,e=0;0==b?(d=this.kb,e=this.tc,this.tc=this.kb):1==b?(d=this.lb,e=this.uc,this.uc=this.lb):2==b&&(d=this.mb,e=this.vc,this.vc=this.mb);c.e[parseInt(e, +10)].visible=s;c=c.e[parseInt(d,10)];c.visible=q;c.Z=1}a&&R.s.n.call(this)};R.prototype.__defineGetter__("dimensions",u("aa"));R.prototype.__defineGetter__("volumeRendering",u("Ka"));R.prototype.__defineSetter__("volumeRendering",function(a){this.Ka=a;this.n(s)});R.prototype.__defineSetter__("visible",ba("Ja"));R.prototype.__defineGetter__("center",u("k"));R.prototype.__defineSetter__("center",function(a){(a==r||!ha(a)||3!=a.length)&&m(Error("Invalid center."));this.k=a}); +R.prototype.__defineGetter__("image",u("jb"));R.prototype.__defineGetter__("labelmap",function(){this.m||(this.m=new ue(this));return this.m});R.prototype.__defineGetter__("indexX",u("kb"));R.prototype.__defineSetter__("indexX",function(a){y(a)&&(0<=a&&a>8,c+=String.fromCharCode(p),c+=String.fromCharCode(k),c=parseInt(c,10);j--}else if(4161==f){l++;for(var d=h[l++],e="",f=0;f>8,e+=String.fromCharCode(p),e+=String.fromCharCode(k);g.ka=[g.ka[0],g.ka[1],Math.min(Math.abs(g.Sf-e),g.ka[2])];g.Sf= +e;j--}g.xa[2]++}else{var g={rows:0,cols:0,ka:r,ne:0,Jg:0,Sa:1,Eh:1,Sf:r,Cd:0,Wa:0,Mc:r,Me:0,Se:[],data:r,min:Infinity,max:-Infinity};g.Sa=b.o.length;g.Sa==r&&(g.Sa=1);for(var h=Y(this,"ushort",this.X.byteLength),l=66,d=r,f=r,d=r,j=7;0>8,e=e+String.fromCharCode(p),e=e+String.fromCharCode(k);e=e.split("\\");g.ka=[+e[0],+e[1],Infinity];j--}else if(32==d&&(f=h[l++],19==f)){l++;d=h[l++];for(f=0;f>8,c+=String.fromCharCode(p),c+=String.fromCharCode(k),c=parseInt(c,10);j--}b.dc=g;g.xa=[g.cols,g.rows,1];g.Wa=g.rows*g.cols;switch(g.ne){case 8:g.Mc=new Uint8Array(g.cols*g.rows*g.Sa);g.data=new Uint8Array(g.cols*g.rows*g.Sa);break;case 16:g.Mc=new Uint16Array(g.cols*g.rows*g.Sa);g.data=new Uint16Array(g.cols* +g.rows*g.Sa);break;case 32:g.Mc=new Uint32Array(g.cols*g.rows*g.Sa),g.data=new Uint32Array(g.cols*g.rows*g.Sa)}}this.B=this.X.byteLength-2*g.Wa;h=r;switch(g.ne){case 8:h=Y(this,"uchar",g.Wa);break;case 16:h=Y(this,"ushort",g.Wa);break;case 32:h=Y(this,"uint",g.Wa)}g.Se[c]=g.Me;g.Mc.set(h,g.Me*g.Wa);g.Me++;++g.Cd;return g};D("X.parserDCM",we);D("X.parserDCM.prototype.parse",we.prototype.parse);function xe(){pd.call(this);this.c="parserVTK"}F(xe,pd); +xe.prototype.parse=function(a,b,c){H.Ea(this.c+".parse");var d=b.i,e=b.j,f=new Uint8Array(c),g="";b.i=d=new U(c.byteLength);b.j=e=new U(c.byteLength);c=0;for(var h=f.length;c=k);p++){var t=parseInt(j[p],10),v=c.get(t);d.add(v[0],v[1],v[2]);var z=t,A=v;"LINES"==this.ta?(z=parseInt(j[p+1],10),A=c.get(z),d.add(A[0],A[1],A[2])):"TRIANGLE_STRIPS"==this.ta&&(0==p||p==k-1)&&d.add(v[0],v[1],v[2]);tc&&10!=g);Y(this,"uchar");e=Y(this,"uint");c=Y(this,"uint");var h=Y(this,"float",3*e);g=Y(this,"uint",3*c);var l=new Uint32Array(e),j=new Float32Array(9*c);b.i=d=new U(9*c);b.j=e=new U(9*c);var k;for(k=0;k>>8^e[(b^a[c])&255];for(f=d>>3;f--;c+=8)b=b>>>8^e[(b^a[c])&255],b=b>>>8^e[(b^a[c+1])&255],b=b>>>8^e[(b^a[c+2])&255],b=b>>>8^e[(b^a[c+3])&255],b=b>>>8^e[(b^a[c+4])&255],b=b>>>8^e[(b^a[c+5])&255],b=b>>>8^e[(b^a[c+6])&255],b=b>>>8^e[(b^a[c+7])&255];return(b^4294967295)>>>0}}; +Ae.rg=new Uint32Array([0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101, 3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271, 366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376, 3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954, 1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836, -1088359270,936918E3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117]);function De(a){var b=a.length,c=0,d=Number.POSITIVE_INFINITY,e,f,g,h,j,k,l,p,u;for(p=0;pc&&(c=a[p]),a[p]>=1;for(u=k;u>>=1;switch(a){case 0:var a=this.input,b=this.ia,c=this.Aa,d=this.P,e=n,f=n,g=n,h=c.length,e=n;this.Oa=this.Rc=0;e=a[b++];e===n&&m(Error("invalid uncompressed block header: LEN (first byte)"));f=e;e=a[b++];e===n&&m(Error("invalid uncompressed block header: LEN (second byte)"));f|=e<<8;e=a[b++];e===n&&m(Error("invalid uncompressed block header: NLEN (first byte)"));g=e;e=a[b++];e===n&&m(Error("invalid uncompressed block header: NLEN (second byte)"));g|= -e<<8;f===~g&&m(Error("invalid uncompressed block header: length verify"));b+f>a.length&&m(Error("input buffer is broken"));switch(this.te){case Ge:for(;d+f>c.length;)e=h-d,f-=e,c.set(a.subarray(b,b+e),d),d+=e,b+=e,this.P=d,c=this.ac(),d=this.P;break;case Fe:for(;d+f>c.length;)c=this.ac({Kf:2});break;default:m(Error("invalid inflate mode"))}c.set(a.subarray(b,b+f),d);d+=f;this.ia=b+=f;this.P=d;this.Aa=c;break;case 1:this.Ae(Ie,Je);break;case 2:Ke(this);break;default:m(Error("unknown BTYPE: "+a))}}return this.Ef()}; -var Le=new Uint16Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Me=new Uint16Array([3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258]),Ne=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0]),Oe=new Uint16Array([1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577]),Pe=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),Qe=new Uint8Array(288), -Re,Se;Re=0;for(Se=Qe.length;Re=Re?8:255>=Re?9:279>=Re?7:8;var Ie=De(Qe),Te=new Uint8Array(30),Ue,Ve;Ue=0;for(Ve=Te.length;Ue>>b;a.Oa=d-b;a.ia=f;return g} -function We(a,b){for(var c=a.Rc,d=a.Oa,e=a.input,f=a.ia,g=b[0],h=b[1],j;d>>16;a.Rc=c>>g;a.Oa=d-g;a.ia=f;return e&65535} -function Ke(a){function b(a,b,c){var d,e,f;for(f=0;ff)d>=e&&(this.P=d,c=this.ac(),d=this.P),c[d++]=f;else{f-=257;h=Me[f];0=e&&(this.P=d,c=this.ac(),d=this.P);for(;h--;)c[d]=c[d++-g]}for(;8<=this.Oa;)this.Oa-=8,this.ia--;this.P=d}; -w.Xg=function(a,b){var c=this.Aa,d=this.P;this.Hf=a;for(var e=c.length,f,g,h;256!==(f=We(this,a));)if(256>f)d>=e&&(c=this.ac(),e=c.length),c[d++]=f;else{f-=257;h=Me[f];0e&&(c=this.ac(),e=c.length);for(;h--;)c[d]=c[d++-g]}for(;8<=this.Oa;)this.Oa-=8,this.ia--;this.P=d}; -w.ac=function(){var a=new Uint8Array(this.P-32768),b=this.P-32768,c=this.Aa;a.set(c.subarray(32768,a.length));this.re.push(a);this.Ze+=a.length;c.set(c.subarray(b,b+32768));this.P=32768;return c};w.dh=function(a){var b=this.input.length/this.ia+1|0,c=this.input,d=this.Aa;a&&("number"===typeof a.Kf&&(b=a.Kf),"number"===typeof a.Mg&&(b+=a.Mg));2>b?(a=(c.length-this.ia)/this.Hf[2],a=258*(a/2)|0,a=aXe;++Xe)for(var Ye=Xe,Ze=7,Ye=Ye>>>1;Ye;Ye>>>=1)--Ze;var $e=[],af;for(af=0;288>af;af++)switch(q){case 143>=af:$e.push([af+48,8]);break;case 255>=af:$e.push([af-144+400,9]);break;case 279>=af:$e.push([af-256+0,7]);break;case 287>=af:$e.push([af-280+192,8]);break;default:m("invalid literal: "+af)} -function bf(){var a=cf;switch(q){case 3===a:return[257,a-3,0];case 4===a:return[258,a-4,0];case 5===a:return[259,a-5,0];case 6===a:return[260,a-6,0];case 7===a:return[261,a-7,0];case 8===a:return[262,a-8,0];case 9===a:return[263,a-9,0];case 10===a:return[264,a-10,0];case 12>=a:return[265,a-11,1];case 14>=a:return[266,a-13,1];case 16>=a:return[267,a-15,1];case 18>=a:return[268,a-17,1];case 22>=a:return[269,a-19,2];case 26>=a:return[270,a-23,2];case 30>=a:return[271,a-27,2];case 34>=a:return[272,a- -31,2];case 42>=a:return[273,a-35,3];case 50>=a:return[274,a-43,3];case 58>=a:return[275,a-51,3];case 66>=a:return[276,a-59,3];case 82>=a:return[277,a-67,4];case 98>=a:return[278,a-83,4];case 114>=a:return[279,a-99,4];case 130>=a:return[280,a-115,4];case 162>=a:return[281,a-131,5];case 194>=a:return[282,a-163,5];case 226>=a:return[283,a-195,5];case 257>=a:return[284,a-227,5];case 258===a:return[285,a-258,0];default:m("invalid length: "+a)}}var df=[],cf,ef; -for(cf=3;258>=cf;cf++)ef=bf(),df[cf]=ef[2]<<24|ef[1]<<16|ef[0];new Uint32Array(df);function ff(){};function gf(a){this.input=a;this.ia=0;this.member=[]} -gf.prototype.Uc=function(){for(var a=this.input.length;this.ia>>0;Ce.ue(e)!==c&&m(Error("invalid CRC-32 checksum: 0x"+Ce.ue(e).toString(16)+ -" / 0x"+c.toString(16)));b.Wj=c=(h[d++]|h[d++]<<8|h[d++]<<16|h[d++]<<24)>>>0;(e.length&4294967295)!==c&&m(Error("invalid input size: "+(e.length&4294967295)+" / "+c));this.member.push(b);this.ia=d}a=this.member;b=e=d=0;for(h=a.length;bx)x=H;if(!z||KC)C=O;if(!d||aae)e=ca;l.push(I);p.push(N)}g=(v+x)/2;z=(z+C)/2;h=(d+e)/2;C=new Float32Array(f);b.i=d=new T(f);b.j=e=new T(f);b.Z=f=new T(f);for(k=v=0;k=l;l++)d.push(!isNaN(this.Xe[l])?this.Ia[l].scale(this.Xe[l]):n)}f=c.subarray(f);if("gzip"==this.encoding||"gz"==this.encoding)f=(new gf(new Uint8Array(f))).Uc();f=f.buffer;c={data:r,min:Infinity,max:-Infinity};c.data=new this.Mb(f);l=qd(c.data);f=c.min=l[0];l=c.max=l[1];b.R=[this.Ue[0],this.Ue[1],this.Ue[2]];d=(new S(this.Ia[0][0],this.Ia[0][1],this.Ia[0][2])).nb(); -e=(new S(this.Ia[1][0],this.Ia[1][1],this.Ia[1][2])).nb();g=(new S(this.Ia[2][0],this.Ia[2][1],this.Ia[2][2])).nb();b.J=[d,e,g];b.Ka=b.X=f;b.Ha=b.W=l;-Infinity==b.S&&(b.S=f);Infinity==b.V&&(b.V=l);b.uc();L.ta(this.c+".parse");b.sb=sd(this,b,c);c=new Rc;c.aa=b;c.u=a;this.dispatchEvent(c)}; -nf.prototype.fh={type:function(a){switch(a){case "uchar":case "unsigned char":case "uint8":case "uint8_t":this.Mb=Uint8Array;break;case "signed char":case "int8":case "int8_t":this.Mb=Int8Array;break;case "short":case "short int":case "signed short":case "signed short int":case "int16":case "int16_t":this.Mb=Int16Array;break;case "ushort":case "unsigned short":case "unsigned short int":case "uint16":case "uint16_t":this.Mb=Uint16Array;break;case "int":case "signed int":case "int32":case "int32_t":this.Mb= -Int32Array;break;case "uint":case "unsigned int":case "uint32":case "uint32_t":this.Mb=Uint32Array;break;case "float":this.Mb=Float32Array;break;default:m(Error("Unsupported NRRD data type: "+a))}return this.type=a},endian:function(a){return this.Uj=a},encoding:function(a){return this.encoding=a},dimension:function(a){return this.za=parseInt(a,10)},sizes:function(a){var b,c,d,e;d=a.split(/\s+/);e=[];b=0;for(c=d.length;ba.vc;b.Ja=q;this.dispatchEvent(b)};function Bf(a){Q.call(this);this.c="array";this.t=[];this.ef=a}G(Bf,Q);function Cf(a,b,c){for(var d=0;4>d;d++)if(a[d+0]!==b[d+c])return s;return q}Bf.prototype.add=function(a){this.t.push(a);return q};Bf.prototype.remove=function(a){a=this.t.indexOf(a);-1d)){d=b+Math.floor(d/2);Df(a,b,d);for(Df(a,d,c);bf.ef(f.t[g+1],e);){var j=f,k=g+1,l=j.t[g];j.t[g]=j.t[k];j.t[k]=l;++g}f.t[g]=e}}}Bf.prototype.sort=function(){Df(this,0,this.t.length)};function Ef(a,b){uf.call(this,a,b);this.c="camera2D"}G(Ef,uf);Ef.prototype.rotate=function(a){a=Ef.r.rotate.call(this,a);var b=new gd;0a.x&&b.oe++;0a.y&&b.ee--;this.dispatchEvent(b)};function Ff(a,b){uf.call(this,a,b);this.c="camera3D";this.gf=45;this.tf=L.d.Fe(L.d.Vc(),this.gf,a/b,1,1E4)}G(Ff,uf);Ff.prototype.rotate=function(a){a=Ff.r.rotate.call(this,a);var b=-a.x/5*Math.PI/180;a=-a.y/5*Math.PI/180;var c=new L.g(this.p[1],this.p[5],this.p[9]),d=new L.g(this.p[0],this.p[4],this.p[8]);c.normalize();d.normalize();L.d.rotate(this.p,b,c.x,c.y,c.b);L.d.rotate(this.p,a,d.x,d.y,d.b)};Ff.prototype.Kd=function(a,b){var c=Ff.r.Kd.call(this,a,b);L.d.Zf(c,a,b,this.K);return c}; -F("X.camera3D",Ff);function Gf(a){Jb.call(this);this.mb=a;this.A=[]}G(Gf,Jb);var Hf=[];function If(a,b,c,d,e){y(c)||(Hf[0]=c,c=Hf);for(var f=0;fthis.Ge?this.Ge-this.If:apb&&P(this.m(),"resize",this.Vd,s,this);this.Vd();var a=this.m();a.setAttribute("role","progressbar");a.setAttribute("aria-live","polite")};w.yd=function(){Of.r.yd.call(this);M&&7>pb&&Vb(this.m(),"resize",this.Vd,s,this)};w.Ed=function(){return this.$c.Ed()};w.Sd=function(a){this.$c.Sd(a);this.m()&&Rf(this)};function Rf(a){var b=a.Ed();a.m().setAttribute("aria-valuenow",b)}w.Dd=function(){return this.$c.Dd()};w.Cd=function(){return this.$c.Cd()};w.jg="horizontal"; -w.oh=function(){this.Vd();this.dispatchEvent("change")};w.Vd=function(){if(this.bb){var a=this.Dd(),b=this.Cd(),a=(this.Ed()-a)/(b-a),b=Math.round(100*a);"vertical"==this.jg?M&&7>pb?(this.bb.style.top=0,this.bb.style.height="100%",b=this.bb.offsetHeight,a=Math.round(a*b),this.bb.style.top=b-a+"px",this.bb.style.height=a+"px"):(this.bb.style.top=100-b+"%",this.bb.style.height=b+"%"):this.bb.style.width=b+"%"}};function Sf(a,b){a==r&&m(Error("No valid parent element."));b==r&&m(Error("Invalid initial value."));Of.call(this);this.c="progressbar";this.oa=a;this.sf="";this.dd=this.ib=r;this.Ob=[];var c;c=".progress-bar-horizontal {\n position: relative;\n border: 1px solid #949dad;\n";c+=" background: white;\n";c+=" padding: 1px;\n";c+=" overflow: hidden;\n";c+=" margin: 2px;\n";c+=" width: 100px;\n";c+=" height: 5px;\n";c+="}";var d;d=".progress-bar-thumb {\n position: relative;\n background: #F62217;\n"; -d+=" overflow: hidden;\n";d+=" width: 0%;\n";d+=" height: 100%;\n";d+="}";var e;e=".progress-bar-thumb-done {\n background: #57E964;\n}";this.Ob=[c,d,e];this.Sd(b);this.Ce()}G(Sf,Of); -Sf.prototype.Ce=function(){if("static"==this.oa.style.position||""==this.oa.style.position)this.sf=this.oa.style.position,this.oa.style.position="relative";var a=document.getElementsByTagName("head")[0],b=Md("style");b.type="text/css";b.media="screen";var c=document.createTextNode(String(this.Ob[0])),d=document.createTextNode(String(this.Ob[1])),e=document.createTextNode(String(this.Ob[2]));a.appendChild(b);b.appendChild(c);b.appendChild(d);b.appendChild(e);this.ib=b;this.ec(this.oa);a=this.m();a.style.position= -"absolute";a.style.top=(this.oa.clientHeight-5)/2+"px";a.style.left=(this.oa.clientWidth-100)/2+"px";a.classList.add("xtk-progress-bar")};function Tf(a){var b=a.m().style.top,c=a.m().style.left;Od(a.m());var d=new Sf(a.oa,100),e=d.m();e.style.position="absolute";e.style.top=b;e.style.left=c;e.classList.add("xtk-progress-bar");(e.firstElementChild!=n?e.firstElementChild:Pd(e.firstChild)).classList.add("progress-bar-thumb-done");a.dd=d} -Sf.prototype.Gd=function(){this.ib&&Od(this.ib);this.m()&&Od(this.m());this.dd&&Od(this.dd.m());this.dd=this.ib=r;this.oa.style.position=this.sf};function Uf(a,b,c){na(a)?c&&(a=va(a,c)):a&&"function"==typeof a.handleEvent?a=va(a.handleEvent,a):m(Error("Invalid listener argument"));return 2147483647..) is required."));var b=a;ma(b)&&(b=Kd(a));oa(b)&&1==b.nodeType||m(Error("Could not find the given container."));this.u=b});w=Vf.prototype; -w.ad=function(){this.q.reset()}; -w.ha=function(a){var b=Md("canvas");this.u.appendChild(b);this.H=this.u.clientWidth;this.B=this.u.clientHeight;b.width=this.H;b.height=this.B;try{var c=b.getContext(a);c||m(Error())}catch(d){var e="Sorry, "+a+' context is not supported on this machine! See http://crash.goXTK.com for requirements..';this.u.innerHTML='

    Oooops..

    '+e+"

    "; -m(Error(e))}this.G=new qf;P(this.G,dd,this.Yh.bind(this));this.da=b;this.a=c;b=new pe(this.da);"2d"==a&&(b=new re(this.da));b.ha();P(b,ad,this.ad.bind(this));P(b,ed,this.Me.bind(this));P(b,$c,this.Oe.bind(this));this.ja=b;b=new Ff(this.H,this.B);"2d"==a&&(b=new Ef(this.H,this.B));b.observe(this.ja);this.q=b;P(window,"resize",this.Ne,s,this)};w.add=function(a){(a instanceof Af||a instanceof yf||a instanceof wf)&&a.n();this.Ma.push(a);this.cb(a)}; -w.remove=function(a){(!this.da||!this.a)&&m(Error("The renderer was not initialized properly."));a==r&&m(Error("Illegal object."));return s};w.cb=function(a){(!this.da||!this.a)&&m(Error("The renderer was not initialized properly."));a==r&&(window.console.log(a),m(Error("Illegal object.")));var b;b=pa(a);var c=Qb[b];if(c){var d=ja(cd),e=ja(n);d&&e?(c=Pb[cd],b=!!c&&!!c[n]&&b in c[n]):b=!d&&!e?q:Gb(c,function(a){return d&&a.type==cd||e&&a.capture==n})}else b=s;b||P(a,cd,this.Oh.bind(this))}; -w.get=function(a){a==r&&m(Error("Invalid object id."));for(var b=this.Za.t,c=b.length,d=0,d=0;dc&&(c=a[p]),a[p]>=1;for(t=j;t>>=1;switch(a){case 0:var a=this.input,b=this.fa,c=this.ya,d=this.O,e=n,f=n,g=n,h=c.length,e=n;this.La=this.Kc=0;e=a[b++];e===n&&m(Error("invalid uncompressed block header: LEN (first byte)"));f=e;e=a[b++];e===n&&m(Error("invalid uncompressed block header: LEN (second byte)"));f|=e<<8;e=a[b++];e===n&&m(Error("invalid uncompressed block header: NLEN (first byte)"));g=e;e=a[b++];e===n&&m(Error("invalid uncompressed block header: NLEN (second byte)"));g|= +e<<8;f===~g&&m(Error("invalid uncompressed block header: length verify"));b+f>a.length&&m(Error("input buffer is broken"));switch(this.qe){case Ee:for(;d+f>c.length;)e=h-d,f-=e,c.set(a.subarray(b,b+e),d),d+=e,b+=e,this.O=d,c=this.Zb(),d=this.O;break;case De:for(;d+f>c.length;)c=this.Zb({Ef:2});break;default:m(Error("invalid inflate mode"))}c.set(a.subarray(b,b+f),d);d+=f;this.fa=b+=f;this.O=d;this.ya=c;break;case 1:this.xe(Ge,He);break;case 2:Ie(this);break;default:m(Error("unknown BTYPE: "+a))}}return this.xf()}; +var Je=new Uint16Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Ke=new Uint16Array([3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,258,258]),Le=new Uint8Array([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0]),Me=new Uint16Array([1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577]),Ne=new Uint8Array([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13]),Oe=new Uint8Array(288), +Pe,Qe;Pe=0;for(Qe=Oe.length;Pe=Pe?8:255>=Pe?9:279>=Pe?7:8;var Ge=Be(Oe),Re=new Uint8Array(30),Se,Te;Se=0;for(Te=Re.length;Se>>b;a.La=d-b;a.fa=f;return g} +function Ue(a,b){for(var c=a.Kc,d=a.La,e=a.input,f=a.fa,g=b[0],h=b[1],l;d>>16;a.Kc=c>>g;a.La=d-g;a.fa=f;return e&65535} +function Ie(a){function b(a,b,c){var d,e,f;for(f=0;ff)d>=e&&(this.O=d,c=this.Zb(),d=this.O),c[d++]=f;else{f-=257;h=Ke[f];0=e&&(this.O=d,c=this.Zb(),d=this.O);for(;h--;)c[d]=c[d++-g]}for(;8<=this.La;)this.La-=8,this.fa--;this.O=d}; +w.Qg=function(a,b){var c=this.ya,d=this.O;this.Af=a;for(var e=c.length,f,g,h;256!==(f=Ue(this,a));)if(256>f)d>=e&&(c=this.Zb(),e=c.length),c[d++]=f;else{f-=257;h=Ke[f];0e&&(c=this.Zb(),e=c.length);for(;h--;)c[d]=c[d++-g]}for(;8<=this.La;)this.La-=8,this.fa--;this.O=d}; +w.Zb=function(){var a=new Uint8Array(this.O-32768),b=this.O-32768,c=this.ya;a.set(c.subarray(32768,a.length));this.oe.push(a);this.Ve+=a.length;c.set(c.subarray(b,b+32768));this.O=32768;return c};w.Wg=function(a){var b=this.input.length/this.fa+1|0,c=this.input,d=this.ya;a&&("number"===typeof a.Ef&&(b=a.Ef),"number"===typeof a.Fg&&(b+=a.Fg));2>b?(a=(c.length-this.fa)/this.Af[2],a=258*(a/2)|0,a=aVe;++Ve)for(var We=Ve,Xe=7,We=We>>>1;We;We>>>=1)--Xe;var Ye=[],Ze;for(Ze=0;288>Ze;Ze++)switch(q){case 143>=Ze:Ye.push([Ze+48,8]);break;case 255>=Ze:Ye.push([Ze-144+400,9]);break;case 279>=Ze:Ye.push([Ze-256+0,7]);break;case 287>=Ze:Ye.push([Ze-280+192,8]);break;default:m("invalid literal: "+Ze)} +function $e(){var a=af;switch(q){case 3===a:return[257,a-3,0];case 4===a:return[258,a-4,0];case 5===a:return[259,a-5,0];case 6===a:return[260,a-6,0];case 7===a:return[261,a-7,0];case 8===a:return[262,a-8,0];case 9===a:return[263,a-9,0];case 10===a:return[264,a-10,0];case 12>=a:return[265,a-11,1];case 14>=a:return[266,a-13,1];case 16>=a:return[267,a-15,1];case 18>=a:return[268,a-17,1];case 22>=a:return[269,a-19,2];case 26>=a:return[270,a-23,2];case 30>=a:return[271,a-27,2];case 34>=a:return[272,a- +31,2];case 42>=a:return[273,a-35,3];case 50>=a:return[274,a-43,3];case 58>=a:return[275,a-51,3];case 66>=a:return[276,a-59,3];case 82>=a:return[277,a-67,4];case 98>=a:return[278,a-83,4];case 114>=a:return[279,a-99,4];case 130>=a:return[280,a-115,4];case 162>=a:return[281,a-131,5];case 194>=a:return[282,a-163,5];case 226>=a:return[283,a-195,5];case 257>=a:return[284,a-227,5];case 258===a:return[285,a-258,0];default:m("invalid length: "+a)}}var bf=[],af,cf; +for(af=3;258>=af;af++)cf=$e(),bf[af]=cf[2]<<24|cf[1]<<16|cf[0];new Uint32Array(bf);function df(){};function ef(a){this.input=a;this.fa=0;this.member=[]} +ef.prototype.Nc=function(){for(var a=this.input.length;this.fa>>0;Ae.re(e)!==c&&m(Error("invalid CRC-32 checksum: 0x"+Ae.re(e).toString(16)+ +" / 0x"+c.toString(16)));b.Mj=c=(h[d++]|h[d++]<<8|h[d++]<<16|h[d++]<<24)>>>0;(e.length&4294967295)!==c&&m(Error("invalid input size: "+(e.length&4294967295)+" / "+c));this.member.push(b);this.fa=d}a=this.member;b=e=d=0;for(h=a.length;bz)z=G;if(!A||KC)C=P;if(!d||Ve)e=T;k.push(I);p.push(N)}g=(v+z)/2;A=(A+C)/2;h=(d+e)/2;C=new Float32Array(f);b.i=d=new U(f);b.j=e=new U(f);b.W=f=new U(f);for(j=v=0;j=k;k++)d.push(!isNaN(this.Te[k])?this.Ga[k].scale(this.Te[k]):n)}f=c.subarray(f);if("gzip"==this.encoding||"gz"==this.encoding)f=(new ef(new Uint8Array(f))).Nc();f=f.buffer;c={data:r,min:Infinity,max:-Infinity};c.data=new this.Fb(f);k=qd(c.data);f=c.min=k[0];k=c.max=k[1];b.aa=[this.Qe[0],this.Qe[1],this.Qe[2]];d=(new S(this.Ga[0][0],this.Ga[0][1],this.Ga[0][2])).eb(); +e=(new S(this.Ga[1][0],this.Ga[1][1],this.Ga[1][2])).eb();g=(new S(this.Ga[2][0],this.Ga[2][1],this.Ga[2][2])).eb();b.H=[d,e,g];b.Ia=b.U=f;b.Fa=b.T=k;-Infinity==b.P&&(b.P=f);Infinity==b.S&&(b.S=k);b.mc();H.qa(this.c+".parse");b.jb=sd(this,b,c);c=new Rc;c.Y=b;c.q=a;this.dispatchEvent(c)}; +lf.prototype.Yg={type:function(a){switch(a){case "uchar":case "unsigned char":case "uint8":case "uint8_t":this.Fb=Uint8Array;break;case "signed char":case "int8":case "int8_t":this.Fb=Int8Array;break;case "short":case "short int":case "signed short":case "signed short int":case "int16":case "int16_t":this.Fb=Int16Array;break;case "ushort":case "unsigned short":case "unsigned short int":case "uint16":case "uint16_t":this.Fb=Uint16Array;break;case "int":case "signed int":case "int32":case "int32_t":this.Fb= +Int32Array;break;case "uint":case "unsigned int":case "uint32":case "uint32_t":this.Fb=Uint32Array;break;case "float":this.Fb=Float32Array;break;default:m(Error("Unsupported NRRD data type: "+a))}return this.type=a},endian:function(a){return this.Lj=a},encoding:function(a){return this.encoding=a},dimension:function(a){return this.xa=parseInt(a,10)},sizes:function(a){var b,c,d,e;d=a.split(/\s+/);e=[];b=0;for(c=d.length;ba.nc;b.Ha=q;this.dispatchEvent(b)};function zf(a){Q.call(this);this.c="array";this.v=[];this.af=a}F(zf,Q);zf.prototype.add=function(a){this.v.push(a);return q};zf.prototype.clear=function(){this.v.length=0};function Af(a,b,c){var d=c-b;if(!(2>d)){d=b+Math.floor(d/2);Af(a,b,d);for(Af(a,d,c);bf.af(f.v[g+1],e);){var l=f,j=g+1,k=l.v[g];l.v[g]=l.v[j];l.v[j]=k;++g}f.v[g]=e}}}zf.prototype.sort=function(){Af(this,0,this.v.length)};function Bf(a,b){sf.call(this,a,b);this.c="camera2D"}F(Bf,sf);Bf.prototype.rotate=function(a){a=Bf.s.rotate.call(this,a);var b=new gd;0a.x&&b.le++;0a.y&&b.Zd--;this.dispatchEvent(b)};function Cf(a,b){sf.call(this,a,b);this.c="camera3D";this.cf=45;this.nf=H.d.Ce(H.d.Oc(),this.cf,a/b,1,1E4)}F(Cf,sf);Cf.prototype.rotate=function(a){a=Cf.s.rotate.call(this,a);var b=-a.x/5*Math.PI/180;a=-a.y/5*Math.PI/180;var c=new H.f(this.p[1],this.p[5],this.p[9]),d=new H.f(this.p[0],this.p[4],this.p[8]);c.normalize();d.normalize();H.d.rotate(this.p,b,c.x,c.y,c.b);H.d.rotate(this.p,a,d.x,d.y,d.b)};Cf.prototype.Ed=function(a,b){var c=Cf.s.Ed.call(this,a,b);H.d.Tf(c,a,b,this.I);return c}; +D("X.camera3D",Cf);function Df(a){sb.call(this);this.cb=a;this.w=[]}F(Df,sb);var Ef=[];function Ff(a,b,c,d,e){ha(c)||(Ef[0]=c,c=Ef);for(var f=0;fthis.De?this.De-this.Cf:aib&&O(this.l(),"resize",this.Pd,s,this);this.Pd();var a=this.l();a.setAttribute("role","progressbar");a.setAttribute("aria-live","polite")};w.sd=function(){Lf.s.sd.call(this);L&&7>ib&&Vb(this.l(),"resize",this.Pd,s,this)};w.yd=function(){return this.Tc.yd()};w.Md=function(a){this.Tc.Md(a);this.l()&&Of(this)};function Of(a){var b=a.yd();a.l().setAttribute("aria-valuenow",b)}w.xd=function(){return this.Tc.xd()};w.wd=function(){return this.Tc.wd()};w.dg="horizontal"; +w.hh=function(){this.Pd();this.dispatchEvent("change")};w.Pd=function(){if(this.Ua){var a=this.xd(),b=this.wd(),a=(this.yd()-a)/(b-a),b=Math.round(100*a);"vertical"==this.dg?L&&7>ib?(this.Ua.style.top=0,this.Ua.style.height="100%",b=this.Ua.offsetHeight,a=Math.round(a*b),this.Ua.style.top=b-a+"px",this.Ua.style.height=a+"px"):(this.Ua.style.top=100-b+"%",this.Ua.style.height=b+"%"):this.Ua.style.width=b+"%"}};function Pf(a,b){a==r&&m(Error("No valid parent element."));b==r&&m(Error("Invalid initial value."));Lf.call(this);this.c="progressbar";this.ma=a;this.mf="";this.Xc=this.$a=r;this.Hb=[];var c;c=".progress-bar-horizontal {\n position: relative;\n border: 1px solid #949dad;\n";c+=" background: white;\n";c+=" padding: 1px;\n";c+=" overflow: hidden;\n";c+=" margin: 2px;\n";c+=" width: 100px;\n";c+=" height: 5px;\n";c+="}";var d;d=".progress-bar-thumb {\n position: relative;\n background: #F62217;\n"; +d+=" overflow: hidden;\n";d+=" width: 0%;\n";d+=" height: 100%;\n";d+="}";var e;e=".progress-bar-thumb-done {\n background: #57E964;\n}";this.Hb=[c,d,e];this.Md(b);this.ze()}F(Pf,Lf); +Pf.prototype.ze=function(){if("static"==this.ma.style.position||""==this.ma.style.position)this.mf=this.ma.style.position,this.ma.style.position="relative";var a=document.getElementsByTagName("head")[0],b=Ld("style");b.type="text/css";b.media="screen";var c=document.createTextNode(String(this.Hb[0])),d=document.createTextNode(String(this.Hb[1])),e=document.createTextNode(String(this.Hb[2]));a.appendChild(b);b.appendChild(c);b.appendChild(d);b.appendChild(e);this.$a=b;this.cc(this.ma);a=this.l();a.style.position= +"absolute";a.style.top=(this.ma.clientHeight-5)/2+"px";a.style.left=(this.ma.clientWidth-100)/2+"px";a.classList.add("xtk-progress-bar")};function Qf(a){var b=a.l().style.top,c=a.l().style.left;Nd(a.l());var d=new Pf(a.ma,100),e=d.l();e.style.position="absolute";e.style.top=b;e.style.left=c;e.classList.add("xtk-progress-bar");(e.firstElementChild!=n?e.firstElementChild:Od(e.firstChild)).classList.add("progress-bar-thumb-done");a.Xc=d} +Pf.prototype.Ad=function(){this.$a&&Nd(this.$a);this.l()&&Nd(this.l());this.Xc&&Nd(this.Xc.l());this.Xc=this.$a=r;this.ma.style.position=this.mf};function Rf(a,b,c){ma(a)?c&&(a=ua(a,c)):a&&"function"==typeof a.handleEvent?a=ua(a.handleEvent,a):m(Error("Invalid listener argument"));return 2147483647..) is required."));var b=a;la(b)&&(b=Jd(a));na(b)&&1==b.nodeType||m(Error("Could not find the given container."));this.q=b});w=Sf.prototype; +w.qc=function(){this.t.reset()}; +w.ea=function(a){var b=Ld("canvas");this.q.appendChild(b);this.M=this.q.clientWidth;this.G=this.q.clientHeight;b.width=this.M;b.height=this.G;try{var c=b.getContext(a);c||m(Error())}catch(d){var e="Sorry, "+a+' context is not supported on this machine! See http://crash.goXTK.com for requirements..';this.q.innerHTML='

    Oooops..

    '+e+"

    "; +m(Error(e))}this.C=new of;O(this.C,dd,this.Rh.bind(this));this.ga=b;this.a=c;b=new ne(this.ga);"2d"==a&&(b=new pe(this.ga));b.ea();O(b,ad,this.qc.bind(this));O(b,ed,this.Je.bind(this));O(b,$c,this.Ke.bind(this));this.Kb=b;b=new Cf(this.M,this.G);"2d"==a&&(b=new Bf(this.M,this.G));b.observe(this.Kb);this.t=b;O(window,"resize",this.Sh,s,this)};w.add=function(a){(a instanceof yf||a instanceof wf||a instanceof uf)&&a.n();this.Ra.push(a);this.Va(a)}; +w.Va=function(a){(!this.ga||!this.a)&&m(Error("The renderer was not initialized properly."));a==r&&(window.console.log(a),m(Error("Illegal object.")));var b;b=oa(a);var c=Ob[b];if(c){var d=ga(cd),e=ga(n);d&&e?(c=Nb[cd],b=!!c&&!!c[n]&&b in c[n]):b=!d&&!e?q:Gb(c,function(a){return d&&a.type==cd||e&&a.capture==n})}else b=s;b||O(a,cd,this.Hh.bind(this))};w.get=function(a){a==r&&m(Error("Invalid object id."));for(var b=this.Ya.v,c=b.length,d=0,d=0;d=e.right))f&=-2;if(132==(f&132)&&(h.y=e.bottom))f&=-5;h.xe.right&&f&16)&&(g.width=Math.max(g.width-(h.x+g.width-e.right),0),d|=4);h.x+g.width>e.right&&f&1&&(h.x=Math.max(e.right-g.width, -e.left),d|=1);f&2&&(d|=(h.xe.right?32:0));h.y=e.top&&(h.y+g.height>e.bottom&&f&32)&&(g.height=Math.max(g.height-(h.y+g.height-e.bottom),0),d|=8);h.y+g.height>e.bottom&&f&4&&(h.y=Math.max(e.bottom-g.height,e.top),d|=2);f&8&&(d|=(h.ye.bottom?128:0));h=d}else h=256;if(h&496)return h}f=a;e=jb&&($a||nb)&&xb("1.9");f instanceof -yd?(a=f.x,f=f.y):(a=f,f=n);b.style.left=ce(a,e);b.style.top=ce(f,e);if(!(c==g||(!c||!g?0:c.width==g.width&&c.height==g.height)))a=Rd(Hd(Jd(b))),M&&(!a||!xb("8"))?(c=b.style,a?(M?(a=he(b,"paddingLeft"),e=he(b,"paddingRight"),f=he(b,"paddingTop"),d=he(b,"paddingBottom"),a=new Ad(f,e,d,a)):(a=Td(b,"paddingLeft"),e=Td(b,"paddingRight"),f=Td(b,"paddingTop"),d=Td(b,"paddingBottom"),a=new Ad(parseFloat(f),parseFloat(e),parseFloat(d),parseFloat(a))),M?(e=je(b,"borderLeft"),f=je(b,"borderRight"),d=je(b,"borderTop"), -b=je(b,"borderBottom"),b=new Ad(d,f,b,e)):(e=Td(b,"borderLeftWidth"),f=Td(b,"borderRightWidth"),d=Td(b,"borderTopWidth"),b=Td(b,"borderBottomWidth"),b=new Ad(parseFloat(d),parseFloat(f),parseFloat(b),parseFloat(e))),c.pixelWidth=g.width-b.left-a.left-a.right-b.right,c.pixelHeight=g.height-b.top-a.top-a.bottom-b.bottom):(c.pixelWidth=g.width,c.pixelHeight=g.height)):(b=b.style,jb?b.MozBoxSizing="border-box":kb?b.WebkitBoxSizing="border-box":b.boxSizing="border-box",b.width=Math.max(g.width,0)+"px", -b.height=Math.max(g.height,0)+"px");return h};function bg(){}bg.prototype.Ra=ba();function cg(a,b,c){this.element=a;this.Gf=b;this.li=c}G(cg,bg);cg.prototype.Ra=function(a,b,c){$f(this.element,this.Gf,a,b,n,c,this.li)};function dg(a,b){bc.call(this);this.mb=new Gf(this);this.Se(a||r);b&&(this.yc=b)}G(dg,bc);w=dg.prototype;w.s=r;w.Ng=q;w.Af=r;w.ra=s;w.Ei=s;w.Ee=-1;w.Xf=-1;w.th=s;w.bh=q;w.yc="toggle_display";w.m=t("s");w.Se=function(a){this.ra&&m(Error("Can not change this state of the popup while showing."));this.s=a}; -function eg(a,b){a.Ud&&a.Ud.stop();a.Fd&&a.Fd.stop();if(b){if(!a.ra&&a.Ke()){a.s||m(Error("Caller must call setElement before trying to show the popup"));a.Ra();var c=Jd(a.s);a.th&&If(a.mb,c,"keydown",a.Mh,q);if(a.Ng)if(If(a.mb,c,"mousedown",a.eg,q),M){var d;try{d=c.activeElement}catch(e){}for(;d&&"IFRAME"==d.nodeName;){try{var f=d.contentDocument||d.contentWindow.document}catch(g){break}c=f;d=c.activeElement}If(a.mb,c,"mousedown",a.eg,q);If(a.mb,c,"deactivate",a.dg)}else If(a.mb,c,"blur",a.dg);"toggle_display"== -a.yc?(a.s.style.visibility="visible",fe(a.s,q)):"move_offscreen"==a.yc&&a.Ra();a.ra=q;a.Ud?(Ub(a.Ud,"end",a.hg,s,a),a.Ud.play()):a.hg()}}else fg(a)}w.Ra=ga;function fg(a,b){if(!a.ra||!a.dispatchEvent({type:"beforehide",target:b}))return s;a.mb&&a.mb.Re();a.ra=s;a.Xf=xa();a.Fd?(Ub(a.Fd,"end",wa(a.Ff,b),s,a),a.Fd.play()):a.Ff(b);return q}w.Ff=function(a){"toggle_display"==this.yc?this.Ei?Uf(this.Pf,0,this):this.Pf():"move_offscreen"==this.yc&&(this.s.style.top="-10000px");this.Le(a)}; -w.Pf=function(){this.s.style.visibility="hidden";fe(this.s,s)};w.Ke=function(){return this.dispatchEvent("beforeshow")};w.hg=function(){this.Ee=xa();this.Xf=-1;this.dispatchEvent("show")};w.Le=function(a){this.dispatchEvent({type:"hide",target:a})};w.eg=function(a){a=a.target;!Qd(this.s,a)&&((!this.Af||Qd(this.Af,a))&&!(150>xa()-this.Ee))&&fg(this,a)};w.Mh=function(a){27==a.keyCode&&fg(this,a.target)&&(a.preventDefault(),a.stopPropagation())}; -w.dg=function(a){if(this.bh){var b=Jd(this.s);if(M||ib){if(a=b.activeElement,!a||Qd(this.s,a)||"BODY"==a.tagName)return}else if(a.target!=b)return;150>xa()-this.Ee||fg(this)}};function gg(a,b){this.xe=a instanceof yd?a:new yd(a,b)}G(gg,bg);gg.prototype.Ra=function(a,b,c,d){$f(Vd(a),0,a,b,this.xe,c,r,d)};function hg(a,b){this.oi=4;this.Ld=b||n;dg.call(this,a)}G(hg,dg);hg.prototype.Ra=function(){if(this.Ld){var a=!this.ra&&"move_offscreen"!=this.yc,b=this.m();a&&(b.style.visibility="hidden",fe(b,q));this.Ld.Ra(b,this.oi,this.Yj);a&&fe(b,s)}};function ig(a){this.L=new rc;a&&this.pe(a)}function jg(a){var b=typeof a;return"object"==b&&a||"function"==b?"o"+pa(a):b.substr(0,1)+a}w=ig.prototype;w.Ad=function(){return this.L.Ad()};w.add=function(a){this.L.set(jg(a),a)};w.pe=function(a){a=qc(a);for(var b=a.length,c=0;cthis.Fc)this.Fc=k.x;if(this.Jc===r||g.ythis.Gc)this.Gc=k.y;if(this.Kc===r||g.bthis.Hc)this.Hc=k.b;this.k=[(this.Ic+this.Fc)/2,(this.Jc+this.Gc)/2,(this.Kc+this.Hc)/2];j.f=s}b&&d.f&&(j=this.Gb.get(c),j!=r&&this.a.isBuffer(j.w)&&this.a.deleteBuffer(j.w)); -j=r;!b||d.f?(j=this.a.createBuffer(),d.ob(),this.a.bindBuffer(this.a.ARRAY_BUFFER,j),this.a.bufferData(this.a.ARRAY_BUFFER,d.N,this.a.STATIC_DRAW),j=new Zf(j,d.count,3),d.f=s):j=this.Gb.get(c);rf(this.G,0.3);b&&e.f&&(g=this.Gb.get(c),g!=r&&this.a.isBuffer(g.w)&&this.a.deleteBuffer(g.w));g=r;!b||e.f?(g=this.a.createBuffer(),e.ob(),this.a.bindBuffer(this.a.ARRAY_BUFFER,g),this.a.bufferData(this.a.ARRAY_BUFFER,e.N,this.a.STATIC_DRAW),g=new Zf(g,e.count,3),e.f=s):g=this.ld.get(c);rf(this.G,0.3);b&&(f&& -f.f)&&(e=this.ic.get(c),e!=r&&this.a.isBuffer(e.w)&&this.a.deleteBuffer(e.w));e=r;f&&(!b||f.f?(f.length!=d.length&&m(Error("Mismatch between points and point colors.")),e=this.a.createBuffer(),f.ob(),this.a.bindBuffer(this.a.ARRAY_BUFFER,e),this.a.bufferData(this.a.ARRAY_BUFFER,f.N,this.a.STATIC_DRAW),e=new Zf(e,f.count,3),f.f=s):e=this.ic.get(c));rf(this.G,0.2);b&&(p&&p.f)&&(f=this.oc.get(c),f!=r&&this.a.isBuffer(f.w)&&this.a.deleteBuffer(f.w));f=r;p&&(f=p.zc,!b||p.f?(f.length!=d.length&&m(Error("Mismatch between points and scalars.")), -d=this.a.createBuffer(),this.a.bindBuffer(this.a.ARRAY_BUFFER,d),this.a.bufferData(this.a.ARRAY_BUFFER,f,this.a.STATIC_DRAW),f=new Zf(d,f.length,3),p.f=s):f=this.oc.get(c));rf(this.G,0.1);b||this.Za.add(a);this.Gb.set(c,j);this.ld.set(c,g);this.ic.set(c,e);this.rc.set(c,h);this.oc.set(c,f);this.jd=a.f=s}}else a.f=s}};function zg(a,b){var c=b.i.cd,c=L.d.Qa(b.Yb.ka,c[0],c[1],c[2]),c=L.d.Qa(a.q.p,c.x,c.y,c.b),c=L.g.kb(a.q.wa,c);return Math.round(1E3*c)/1E3} -w.mg=function(a,b){if(this.D.PICKING_ENABLED){this.Lb(q,s);var c=new Uint8Array(4);this.a.readPixels(a,this.B-b,1,1,this.a.RGBA,this.a.UNSIGNED_BYTE,c);return c[0]+255*c[1]+65025*c[2]}return-1}; -w.Lb=function(a,b){yg.r.Lb.call(this,a,b);this.a.viewport(0,0,this.H,this.B);this.a.clear(this.a.COLOR_BUFFER_BIT|this.a.DEPTH_BUFFER_BIT);var c=this.Za.t,d=c.length;if(0!=d){a?this.a.bindFramebuffer(this.a.FRAMEBUFFER,this.uf):this.a.bindFramebuffer(this.a.FRAMEBUFFER,r);var e=this.q.tf,f=this.q.p;this.a.uniformMatrix4fv(this.Oc.get("perspective"),s,e);this.a.uniformMatrix4fv(this.Oc.get("view"),s,f);e=this.k;this.a.uniform3f(this.Oc.get("center"),parseFloat(e[0]),parseFloat(e[1]),parseFloat(e[2])); -f=this.Ma.length;for(e=0;el||l>=v||0>p||p>=c)return r;u[this.yb]=l;u[this.zb]=p;return u}; -w.Lb=function(a,b){Ag.r.Lb.call(this,a,b);if(0!=this.Za.t.length){var c=this.H,d=this.B,e=this.q.p;this.a.save();this.a.clearRect(-c,-d,2*c,2*d);this.a.restore();var f=1*e[12],g=-1*e[13],h=Math.max(e[14],0.6);this.a.setTransform(h,0,0,h,0,0);var j=this.Ma[0],k=r;j.l&&(k=j.l.le);var l=j["index"+this.La],p=this.Xb[parseInt(l,10)],u=p.z.xa,p=p.l,v=r;p&&(v=p.xa);var x=this.od,z=this.nd,C=this.hf,E=this.kf,A=C.getImageData(0,0,x,z),B=E.getImageData(0,0,x,z),H=A.data,I=B.data,N=H.length,J=j.Ha,K=j.S,O= -j.V,aa=j.X/J,ca=j.W/J;if(this.ff!=l||this.S!=K||this.V!=O||this.X!=aa||this.W!=ca||k&&!Cf(k,this.lf,0)){var W=0;do{var da=[0,0,0,0],V=[0,0,0,0],ab=u[W]/255*J,ka=u[W],ka=(ka/255-aa)/(ca-aa),ka=255*ka;ab>=K&&ab<=O&&(da=new S(j.xb[0],j.xb[1],j.xb[2]),da=(new S(j.vb[0],j.vb[1],j.vb[2])).scale(ka).add(da.scale(255-ka)),da=[Math.floor(da.x),Math.floor(da.y),Math.floor(da.b),255],p&&(-255==k[3]?V=[v[W],v[W+1],v[W+2],v[W+3]]:Cf(k,v,W)&&(V=[v[W],v[W+1],v[W+2],v[W+3]])));ka=N-1-W;H[ka-3]=da[0];H[ka-2]=da[1]; -H[ka-1]=da[2];H[ka]=da[3];I[ka-3]=V[0];I[ka-2]=V[1];I[ka-1]=V[2];I[ka]=V[3];W+=4}while(W=e.right))f&=-2;if(132==(f&132)&&(h.y=e.bottom))f&=-5;h.xe.right&&f&16)&&(g.width=Math.max(g.width-(h.x+g.width-e.right),0),d|=4);h.x+g.width>e.right&&f&1&&(h.x=Math.max(e.right-g.width, +e.left),d|=1);f&2&&(d|=(h.xe.right?32:0));h.y=e.top&&(h.y+g.height>e.bottom&&f&32)&&(g.height=Math.max(g.height-(h.y+g.height-e.bottom),0),d|=8);h.y+g.height>e.bottom&&f&4&&(h.y=Math.max(e.bottom-g.height,e.top),d|=2);f&8&&(d|=(h.ye.bottom?128:0));h=d}else h=256;if(h&496)return h}f=a;e=bb&&(Ta||gb)&&pb("1.9");f instanceof +yd?(a=f.x,f=f.y):(a=f,f=n);b.style.left=$d(a,e);b.style.top=$d(f,e);if(!(c==g||(!c||!g?0:c.width==g.width&&c.height==g.height)))a=Qd(Gd(Id(b))),L&&(!a||!pb("8"))?(c=b.style,a?(L?(a=ee(b,"paddingLeft"),e=ee(b,"paddingRight"),f=ee(b,"paddingTop"),d=ee(b,"paddingBottom"),a=new Ad(f,e,d,a)):(a=Sd(b,"paddingLeft"),e=Sd(b,"paddingRight"),f=Sd(b,"paddingTop"),d=Sd(b,"paddingBottom"),a=new Ad(parseFloat(f),parseFloat(e),parseFloat(d),parseFloat(a))),L?(e=ge(b,"borderLeft"),f=ge(b,"borderRight"),d=ge(b,"borderTop"), +b=ge(b,"borderBottom"),b=new Ad(d,f,b,e)):(e=Sd(b,"borderLeftWidth"),f=Sd(b,"borderRightWidth"),d=Sd(b,"borderTopWidth"),b=Sd(b,"borderBottomWidth"),b=new Ad(parseFloat(d),parseFloat(f),parseFloat(b),parseFloat(e))),c.pixelWidth=g.width-b.left-a.left-a.right-b.right,c.pixelHeight=g.height-b.top-a.top-a.bottom-b.bottom):(c.pixelWidth=g.width,c.pixelHeight=g.height)):(b=b.style,bb?b.MozBoxSizing="border-box":db?b.WebkitBoxSizing="border-box":b.boxSizing="border-box",b.width=Math.max(g.width,0)+"px", +b.height=Math.max(g.height,0)+"px");return h};function Zf(){}Zf.prototype.Oa=aa();function $f(a,b,c){this.element=a;this.zf=b;this.fi=c}F($f,Zf);$f.prototype.Oa=function(a,b,c){Xf(this.element,this.zf,a,b,n,c,this.fi)};function ag(a,b){sb.call(this);this.cb=new Df(this);this.Oe(a||r);b&&(this.rc=b)}F(ag,bc);w=ag.prototype;w.r=r;w.Gg=q;w.tf=r;w.oa=s;w.yi=s;w.Be=-1;w.Rf=-1;w.mh=s;w.Vg=q;w.rc="toggle_display";w.l=u("r");w.Oe=function(a){this.oa&&m(Error("Can not change this state of the popup while showing."));this.r=a}; +function bg(a,b){a.Od&&a.Od.stop();a.zd&&a.zd.stop();if(b){if(!a.oa&&a.He()){a.r||m(Error("Caller must call setElement before trying to show the popup"));a.Oa();var c=Id(a.r);a.mh&&Ff(a.cb,c,"keydown",a.Fh,q);if(a.Gg)if(Ff(a.cb,c,"mousedown",a.Zf,q),L){var d;try{d=c.activeElement}catch(e){}for(;d&&"IFRAME"==d.nodeName;){try{var f=d.contentDocument||d.contentWindow.document}catch(g){break}c=f;d=c.activeElement}Ff(a.cb,c,"mousedown",a.Zf,q);Ff(a.cb,c,"deactivate",a.Yf)}else Ff(a.cb,c,"blur",a.Yf);"toggle_display"== +a.rc?(a.r.style.visibility="visible",ce(a.r,q)):"move_offscreen"==a.rc&&a.Oa();a.oa=q;a.Od?(Sb(a.Od,"end",a.bg,s,a),a.Od.play()):a.bg()}}else cg(a)}w.Oa=ea;function cg(a,b){if(!a.oa||!a.dispatchEvent({type:"beforehide",target:b}))return s;a.cb&&a.cb.Ne();a.oa=s;a.Rf=wa();a.zd?(Sb(a.zd,"end",va(a.yf,b),s,a),a.zd.play()):a.yf(b);return q}w.yf=function(a){"toggle_display"==this.rc?this.yi?Rf(this.Jf,0,this):this.Jf():"move_offscreen"==this.rc&&(this.r.style.top="-10000px");this.Ie(a)}; +w.Jf=function(){this.r.style.visibility="hidden";ce(this.r,s)};w.He=function(){return this.dispatchEvent("beforeshow")};w.bg=function(){this.Be=wa();this.Rf=-1;this.dispatchEvent("show")};w.Ie=function(a){this.dispatchEvent({type:"hide",target:a})};w.Zf=function(a){a=a.target;!Pd(this.r,a)&&((!this.tf||Pd(this.tf,a))&&!(150>wa()-this.Be))&&cg(this,a)};w.Fh=function(a){27==a.keyCode&&cg(this,a.target)&&(a.preventDefault(),a.stopPropagation())}; +w.Yf=function(a){if(this.Vg){var b=Id(this.r);if(L||ab){if(a=b.activeElement,!a||Pd(this.r,a)||"BODY"==a.tagName)return}else if(a.target!=b)return;150>wa()-this.Be||cg(this)}};function dg(a,b){this.ue=a instanceof yd?a:new yd(a,b)}F(dg,Zf);dg.prototype.Oa=function(a,b,c,d){Xf(Ud(a),0,a,b,this.ue,c,r,d)};function eg(a,b){this.ii=4;this.Fd=b||n;ag.call(this,a)}F(eg,ag);eg.prototype.Oa=function(){if(this.Fd){var a=!this.oa&&"move_offscreen"!=this.rc,b=this.l();a&&(b.style.visibility="hidden",ce(b,q));this.Fd.Oa(b,this.ii,this.Oj);a&&ce(b,s)}};function fg(a){this.J=new rc;a&&this.me(a)}function gg(a){var b=typeof a;return"object"==b&&a||"function"==b?"o"+oa(a):b.substr(0,1)+a}w=fg.prototype;w.ud=function(){return this.J.ud()};w.add=function(a){this.J.set(gg(a),a)};w.me=function(a){a=qc(a);for(var b=a.length,c=0;cthis.yc)this.yc=j.x;if(this.Cc===r||g.ythis.zc)this.zc=j.y;if(this.Dc===r||g.bthis.Ac)this.Ac=j.b;this.k=[(this.Bc+this.yc)/2,(this.Cc+this.zc)/2,(this.Dc+this.Ac)/2];l.g=s}b&&d.g&&(l=this.Jc.get(c),l!=r&&this.a.isBuffer(l.ha)&&this.a.deleteBuffer(l.ha)); +l=r;!b||d.g?(l=this.a.createBuffer(),d.fb(),this.a.bindBuffer(this.a.ARRAY_BUFFER,l),this.a.bufferData(this.a.ARRAY_BUFFER,d.L,this.a.STATIC_DRAW),l=new Wf(l,d.count,3),d.g=s):l=this.Jc.get(c);pf(this.C,0.3);b&&e.g&&(g=this.Jc.get(c),g!=r&&this.a.isBuffer(g.ha)&&this.a.deleteBuffer(g.ha));g=r;!b||e.g?(g=this.a.createBuffer(),e.fb(),this.a.bindBuffer(this.a.ARRAY_BUFFER,g),this.a.bufferData(this.a.ARRAY_BUFFER,e.L,this.a.STATIC_DRAW),g=new Wf(g,e.count,3),e.g=s):g=this.be.get(c);pf(this.C,0.3);b&& +(f&&f.g)&&(e=this.Wc.get(c),e!=r&&this.a.isBuffer(e.ha)&&this.a.deleteBuffer(e.ha));e=r;f&&(!b||f.g?(f.length!=d.length&&m(Error("Mismatch between points and point colors.")),e=this.a.createBuffer(),f.fb(),this.a.bindBuffer(this.a.ARRAY_BUFFER,e),this.a.bufferData(this.a.ARRAY_BUFFER,f.L,this.a.STATIC_DRAW),e=new Wf(e,f.count,3),f.g=s):e=this.Wc.get(c));pf(this.C,0.2);b&&(p&&p.g)&&(f=this.fd.get(c),f!=r&&this.a.isBuffer(f.ha)&&this.a.deleteBuffer(f.ha));f=r;p&&(f=p.sc,!b||p.g?(f.length!=d.length&& +m(Error("Mismatch between points and scalars.")),d=this.a.createBuffer(),this.a.bindBuffer(this.a.ARRAY_BUFFER,d),this.a.bufferData(this.a.ARRAY_BUFFER,f,this.a.STATIC_DRAW),f=new Wf(d,f.length,3),p.g=s):f=this.fd.get(c));pf(this.C,0.1);b||this.Ya.add(a);this.Jc.set(c,l);this.be.set(c,g);this.Wc.set(c,e);this.gd.set(c,h);this.fd.set(c,f);this.bd=a.g=s}}else a.g=s}}; +function wg(a,b){var c=b.i.Vc,c=H.d.Na(b.Wb.ia,c[0],c[1],c[2]),c=H.d.Na(a.t.p,c.x,c.y,c.b),c=H.f.Ab(a.t.ua,c);return Math.round(1E3*c)/1E3}w.gg=function(a,b){if(this.F.PICKING_ENABLED){this.Eb(q,s);var c=new Uint8Array(4);this.a.readPixels(a,this.G-b,1,1,this.a.RGBA,this.a.UNSIGNED_BYTE,c);return c[0]+255*c[1]+65025*c[2]}return-1}; +w.Eb=function(a,b){vg.s.Eb.call(this,a,b);var c=this.Ya.v,d=c.length;if(0!=d){a?this.a.bindFramebuffer(this.a.FRAMEBUFFER,this.of):this.a.bindFramebuffer(this.a.FRAMEBUFFER,r);this.a.viewport(0,0,this.M,this.G);this.a.clear(this.a.COLOR_BUFFER_BIT|this.a.DEPTH_BUFFER_BIT);var e=this.t.nf,f=this.t.p;this.a.uniformMatrix4fv(this.Gc.get("perspective"),s,e);this.a.uniformMatrix4fv(this.Gc.get("view"),s,f);e=this.k;this.a.uniform3f(this.Gc.get("center"),parseFloat(e[0]),parseFloat(e[1]),parseFloat(e[2])); +f=this.Ra.length;for(e=0;e=N&&ka<=J&&(T=new S(e.sb[0],e.sb[1],e.sb[2]),T=(new S(e.qb[0],e.qb[1],e.qb[2])).scale(M).add(T.scale(255-M)),T=[Math.floor(T.x),Math.floor(T.y),Math.floor(T.b),255],j&&(ia=[p[V],p[V+1],p[V+2],p[V+3]]));M=G-1-V;x[M-3]=T[0];x[M-2]=T[1];x[M-1]=T[2];x[M]=T[3];B[M-3]=ia[0];B[M-2]=ia[1];B[M-1]=ia[2];B[M]=ia[3];V+=4}while(V Date: Thu, 10 Jul 2014 23:10:59 +0200 Subject: [PATCH 34/53] ENH: Further interface improvements to the web app --- scripts/tract_querier | 31 +-- tract_querier/tornado_server/js/wmqlviz.js | 32 +-- tract_querier/tornado_server/js/wmqlviz.js.in | 214 ------------------ 3 files changed, 15 insertions(+), 262 deletions(-) delete mode 100644 tract_querier/tornado_server/js/wmqlviz.js.in diff --git a/scripts/tract_querier b/scripts/tract_querier index 829c807..951d0f7 100755 --- a/scripts/tract_querier +++ b/scripts/tract_querier @@ -80,11 +80,7 @@ def main(): import tract_querier if options.interactive_web: - #kill_server_callback = activate_webserver(options) - kill_server_callback = None options.interactive = True - else: - kill_server_callback = None if options.bounding_box_affine_transform: try: @@ -264,15 +260,11 @@ def main(): 'action': 'add' }) - p = Process( + Process( target=urllib.urlopen, args=(options.interactive_url, params), - #kwargs=params - ) - p.start() + ).start() - #f = urllib.urlopen(options.interactive_url, params) - #f.close() except Exception, e: print "Interactive URL error:", e return filename @@ -283,15 +275,11 @@ def main(): 'name': query_name, 'action': 'remove' }) - p = Process( + Process( target=urllib.urlopen, args=(options.interactive_url, params), - #kwargs=params - ) - p.start() + ).start() - #f = urllib.urlopen(options.interactive_url, params) - #f.close() except Exception, e: print "Interactive URL error:", e @@ -300,7 +288,6 @@ def main(): initial_body=query_script, save_query_callback=query_save, del_query_callback=query_del, - eof_callback=kill_server_callback, include_folders=qry_search_folders ) @@ -308,8 +295,6 @@ def main(): activate_webserver(options, interactive_shell) else: interactive_shell.cmdloop() - #kill_server_callback = activate_webserver(options) - def save_query(query_name, tractography, options, evaluated_queries, extension='.vtk', extra_kwargs={}): @@ -389,7 +374,6 @@ def activate_webserver(options, shell): 'shell': shell } ) - #args=(os.path.abspath(options.atlas_file_name),), args = tuple() kwargs = { 'atlas': os.path.abspath(options.atlas_file_name), @@ -401,13 +385,6 @@ def activate_webserver(options, shell): } tornado_server.xtk_server(*args, **kwargs) - #p.start() - - #def kill_server(): - # p.terminate() - - #return kill_server - def affine_transform_tract(affine_transform, tract): import numpy as np diff --git a/tract_querier/tornado_server/js/wmqlviz.js b/tract_querier/tornado_server/js/wmqlviz.js index 9f88f8b..9d51a14 100644 --- a/tract_querier/tornado_server/js/wmqlviz.js +++ b/tract_querier/tornado_server/js/wmqlviz.js @@ -253,6 +253,16 @@ function init_terminal(host) { }, 5); // wait 5 milisecond for the connection... }; + + function sendCommand(command) { + console.log("Sending command"); + console.log(command); + + _WS_.send(command); + wait = 1; + waitForShell(); + }; + $('#wmql_console').terminal(function(command, term) { _WS_.onmessage = function(evt){ console.log("Received!"); @@ -264,27 +274,7 @@ function init_terminal(host) { wait = 0; }; - console.log("Sending command"); - console.log(command); - - _WS_.send(command); - wait = 1; - waitForShell(); - - - /* - function sendMessage(msg){ - // Wait until the state of the socket is not ready and send the message when it is... - waitForSocketConnection(_WS_, function(){ - console.log("message sent!!!"); - _WS_.send(msg); - }); - } - - // Make the function wait until the connection is made... - sendMessage(command); - */ - + sendCommand(command); }, { greetings: 'White Matter Query Language Console', diff --git a/tract_querier/tornado_server/js/wmqlviz.js.in b/tract_querier/tornado_server/js/wmqlviz.js.in deleted file mode 100644 index f40e05e..0000000 --- a/tract_querier/tornado_server/js/wmqlviz.js.in +++ /dev/null @@ -1,214 +0,0 @@ -$(function() { - - // create the sliders for the 2D sliders - $("#yellow_slider").slider({ - slide: volumeslicingX - }); - $("#yellow_slider .ui-slider-handle").unbind('keydown'); - - $("#red_slider").slider({ - slide: volumeslicingY - }); - $("#red_slider .ui-slider-handle").unbind('keydown'); - - $("#green_slider").slider({ - slide: volumeslicingZ - }); - $("#green_slider .ui-slider-handle").unbind('keydown'); - -}); - -function init_viewer2d() { - - var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; - - // X Slice - if (sliceX) { - sliceX.destroy(); - } - sliceX = new X.renderer2D(); - sliceX.container = 'sliceX'; - sliceX.orientation = 'X'; - sliceX.init(); - sliceX.add(volume); - sliceX.render(); - sliceX.interactor.onMouseMove = function() { - if (_ATLAS_.hover){ - clearTimeout(_ATLAS_.hover); - } - _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceX), 100); - }; - - // Y Slice - if (sliceY) { - sliceY.destroy(); - } - sliceY = new X.renderer2D(); - sliceY.container = 'sliceY'; - sliceY.orientation = 'Y'; - sliceY.init(); - sliceY.add(volume); - sliceY.render(); - sliceY.interactor.onMouseMove = function() { - if (_ATLAS_.hover){ - clearTimeout(_ATLAS_.hover); - } - _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceY), 100); - }; - - // Z Slice - if (sliceZ) { - sliceZ.destroy(); - } - sliceZ = new X.renderer2D(); - sliceZ.container = 'sliceZ'; - sliceZ.orientation = 'Z'; - sliceZ.init(); - sliceZ.add(volume); - sliceZ.render(); - sliceZ.interactor.onMouseMove = function() { - if (_ATLAS_.hover){ - clearTimeout(_ATLAS_.hover); - } - _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceZ), 100); - }; - - // update 2d slice sliders - var dim = volume.dimensions; - $("#yellow_slider").slider("option", "disabled", false); - $("#yellow_slider").slider("option", "min", 0); - $("#yellow_slider").slider("option", "max", dim[0] - 1); - $("#yellow_slider").slider("option", "value", volume.indexX); - $("#red_slider").slider("option", "disabled", false); - $("#red_slider").slider("option", "min", 0); - $("#red_slider").slider("option", "max", dim[1] - 1); - $("#red_slider").slider("option", "value", volume.indexY); - $("#green_slider").slider("option", "disabled", false); - $("#green_slider").slider("option", "min", 0); - $("#green_slider").slider("option", "max", dim[2] - 1); - $("#green_slider").slider("option", "value", volume.indexZ); -}//init_viewer2d() - -// show labels on hover -function on2DHover(renderer) { - - // check that feature is enabled - if (!_ATLAS_.hoverLabelSelect){ - return; - } - - // get cursor position - var mousepos = renderer.interactor.mousePosition; - var ijk = renderer.xy2ijk(mousepos[0], mousepos[1]); - if (!ijk) { - return; - } - - // - var orientedIJK = ijk.slice(); - orientedIJK[0] = ijk[2]; - orientedIJK[1] = ijk[1]; - orientedIJK[2] = ijk[0]; - - var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; - - // get the number associated with the label - var labelvalue = volume.labelmap.image[orientedIJK[0]][orientedIJK[1]][orientedIJK[2]]; - if (!labelvalue || labelvalue == 0) { - return; - } - - //volume.labelmap.opacity = 0.6; - //volume.labelmap.showOnly = labelvalue; - console.info(labelvalue); - _WS_.send(labelvalue) - var labelname = volume.labelmap.colortable.get(labelvalue)[0]; - var _r = parseInt(volume.labelmap.colortable.get(labelvalue)[1] * 255, 10); - var _g = parseInt(volume.labelmap.colortable.get(labelvalue)[2] * 255, 10); - var _b = parseInt(volume.labelmap.colortable.get(labelvalue)[3] * 255, 10); - $('#anatomy_caption').html(labelname); - $('#anatomy_caption').css('color', 'rgb( ' + _r + ',' + _g + ',' + _b + ' )' ); -} - - -sliceX = null; -sliceY = null; -sliceZ = null; - -function init_websocket(localsocket) { - Error("test"); - console.info("websocket start"); - - $(document).ready(function () { - _WS_=new WebSocket(localsocket); - -// _WS_=new WebSocket("ws://localhost:%(port)d/ws"); - console.info("Activating stuff") - _WS_.onopen = function () { - console.info("websocket engage"); - }; - - _WS_.onmessage = function(evt){ - console.info(evt.data) - new_fibers = new X.fibers() - new_fibers.file = evt.data - render3D.add(new_fibers) - //the received content is in evt.data, set it where you want - }; - - _WS_.onclose = function () { - console.info("connection closed"); - }; - - $(".column li").on("mouseup") //the function that sends data - { - pid = $(this).attr("id"); - oldCid = $(this).parent().parent().attr("id"); - newCid = $(this).parent().attr("id"); - message = pid + " " + oldCid + " " + newCid; - _WS_.send(message); - }; - }); - - _WS_.send("test inside"); -}; - -window.onload = function() { - -init_websocket(); - -render3D = new X.renderer3D(); -render3D.init(); - -// create a mesh from a .vtk file -// // create a new X.fibers -volume = new X.volume(); -volume.file = '%(volume)s'; -volume.labelmap.file = '%(volume)s'; -volume.labelmap.colortable.file = '%(colortable)s'; - -_ATLAS_ = {}; -_ATLAS_.currentVolume = volume; -_ATLAS_.volumes = {}; -_ATLAS_.volumes[_ATLAS_.currentVolume] = volume -_ATLAS_.currentMesh = 0; -_ATLAS_.meshOpacity = 0.9; -_ATLAS_.labelOpacity = 0.5; -_ATLAS_.hover = null; -_ATLAS_.hoverLabelSelect = true; - -render3D.add(volume); - -// .. and render it -// -render3D.onShowtime = function() { - init_viewer2d(); -} - - -render3D.render(); - -} - - - From f3920b18f716015af6101c82c4b6af810c792232 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 11 Jul 2014 18:02:55 +0200 Subject: [PATCH 35/53] ENH: Made the shell more pythonic --- tract_querier/shell.py | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/tract_querier/shell.py b/tract_querier/shell.py index 8559a4a..5ce9397 100644 --- a/tract_querier/shell.py +++ b/tract_querier/shell.py @@ -90,7 +90,7 @@ def visit_For(self, node): pass -class TractQuerierCmd(cmd.Cmd): +class TractQuerierCmd(object, cmd.Cmd): def __init__( self, @@ -110,10 +110,6 @@ def __init__( self.querier = EvaluateQueries(tractography_spatial_indexing) self.save_query_callback = save_query_callback - self.save_query_visitor = SaveQueries( - self.save_query_callback, self.querier - ) - self.del_query_callback = del_query_callback self.eof_callback = eof_callback @@ -129,6 +125,18 @@ def __init__( else: self.querier.visit(initial_body) + @property + def save_query_callback(self): + return self._save_query_callback + + @save_query_callback.setter + def save_query_callback(self, value): + self._save_query_callback = value + self.save_query_visitor = SaveQueries( + self._save_query_callback, self.querier + ) + + def _print(self, test): self.stdout.write(test + '\n') self.stdout.flush() From c026f56ca8c793fe8a8bb543a903373d38a62142 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 11 Jul 2014 18:48:41 +0200 Subject: [PATCH 36/53] ENH: Included the WMQL command line on the webpage --- scripts/tract_querier | 96 +- tract_querier/tornado_server/__init__.py | 147 +- .../tornado_server/css/jquery.terminal.css | 145 + tract_querier/tornado_server/css/viewer.css | 4 - tract_querier/tornado_server/index.html | 2 +- tract_querier/tornado_server/js/dterm.js | 63 + .../tornado_server/js/jquery-1.7.1.min.js | 4 + .../js/jquery.mousewheel-min.js | 2 + .../js/jquery.terminal-0.8.7.js | 4328 ++++++++++++++++ .../js/jquery.terminal-0.8.7.min.js | 32 + .../js/jquery.terminal-0.8.8.js | 4339 +++++++++++++++++ .../js/jquery.terminal-0.8.8.min.js | 3 + .../tornado_server/js/jquery.terminal-min.js | 3 + .../tornado_server/js/jquery.terminal-src.js | 4335 ++++++++++++++++ tract_querier/tornado_server/js/wmqlviz.js | 86 +- 15 files changed, 13429 insertions(+), 160 deletions(-) create mode 100644 tract_querier/tornado_server/css/jquery.terminal.css create mode 100644 tract_querier/tornado_server/js/dterm.js create mode 100644 tract_querier/tornado_server/js/jquery-1.7.1.min.js create mode 100644 tract_querier/tornado_server/js/jquery.mousewheel-min.js create mode 100644 tract_querier/tornado_server/js/jquery.terminal-0.8.7.js create mode 100644 tract_querier/tornado_server/js/jquery.terminal-0.8.7.min.js create mode 100644 tract_querier/tornado_server/js/jquery.terminal-0.8.8.js create mode 100644 tract_querier/tornado_server/js/jquery.terminal-0.8.8.min.js create mode 100644 tract_querier/tornado_server/js/jquery.terminal-min.js create mode 100644 tract_querier/tornado_server/js/jquery.terminal-src.js diff --git a/scripts/tract_querier b/scripts/tract_querier index 951d0f7..3d46ea7 100755 --- a/scripts/tract_querier +++ b/scripts/tract_querier @@ -48,13 +48,14 @@ def main(): help='Atlas colortable for the webgl viz' ) parser.add_option( - '--interactive-webdisplay-url', dest='interactive_url', - help='Server port for the interactive display of the results: default: http://localhost:9999', + '--interactive-webdisplay-hostname', dest='interactive_hostname', + help='Server port for the interactive display of the results: default: $(default)s', + default='localhost' ) parser.add_option( '--interactive-webdisplay-port', dest='interactive_port', - help='Server port for the interactive display of the results: default $(default)d', + help='Server port for the interactive display of the results: default $(default)04d', default=9999 ) @@ -236,58 +237,16 @@ def main(): extension=tractography_extension, extra_kwargs=tractography_extra_kwargs ) else: - if options.interactive_url is None and options.interactive_web is None: - def query_save(query_name, query_result): - return save_query( - query_name, tr, options, {query_name: query_result}, - extension=tractography_extension, extra_kwargs=tractography_extra_kwargs - ) - query_del = None - else: - import urllib - from multiprocessing import Process - - def query_save(query_name, query_result): - filename = save_query( - query_name, tr, options, {query_name: query_result}, - extension=tractography_extension, extra_kwargs=tractography_extra_kwargs - ) - if filename is not None: - try: - params = urllib.urlencode({ - 'name': query_name, - 'file': filename, - 'action': 'add' - }) - - Process( - target=urllib.urlopen, - args=(options.interactive_url, params), - ).start() - - except Exception, e: - print "Interactive URL error:", e - return filename - - def query_del(query_name): - try: - params = urllib.urlencode({ - 'name': query_name, - 'action': 'remove' - }) - Process( - target=urllib.urlopen, - args=(options.interactive_url, params), - ).start() - - except Exception, e: - print "Interactive URL error:", e + def query_save(query_name, query_result): + return save_query( + query_name, tr, options, {query_name: query_result}, + extension=tractography_extension, extra_kwargs=tractography_extra_kwargs + ) interactive_shell = tract_querier.TractQuerierCmd( tractography_spatial_indexing, initial_body=query_script, save_query_callback=query_save, - del_query_callback=query_del, include_folders=qry_search_folders ) @@ -350,7 +309,6 @@ def save_tractography_file( def activate_webserver(options, shell): import os - from multiprocessing import Process from tract_querier import tornado_server from uuid import uuid4 suffix = str(uuid4()).replace('-', '') @@ -358,32 +316,20 @@ def activate_webserver(options, shell): options.interactive_port = int(options.interactive_port) - if options.interactive_url is None: - options.interactive_url = 'http://localhost:%04d/tracts' % options.interactive_port - - print "Starting web server, please direct your browser to http://localhost:%04d" % options.interactive_port + print "Starting web server, please direct your browser to http://%s:%04d" % ( + options.interactive_hostname, + options.interactive_port + ) - p = Process( - target=tornado_server.xtk_server, - args=(os.path.abspath(options.atlas_file_name),), - kwargs={ - 'colortable': options.interactive_colortable, - 'port': options.interactive_port, - 'files_path': os.getcwd(), - 'suffix': suffix, - 'shell': shell - } + tornado_server.xtk_server( + atlas=os.path.abspath(options.atlas_file_name), + colortable=options.interactive_colortable, + hostname=options.interactive_hostname, + port=options.interactive_port, + files_path=os.getcwd(), + suffix=suffix, + shell=shell ) - args = tuple() - kwargs = { - 'atlas': os.path.abspath(options.atlas_file_name), - 'colortable': options.interactive_colortable, - 'port': options.interactive_port, - 'files_path': os.getcwd(), - 'suffix': suffix, - 'shell': shell - } - tornado_server.xtk_server(*args, **kwargs) def affine_transform_tract(affine_transform, tract): diff --git a/tract_querier/tornado_server/__init__.py b/tract_querier/tornado_server/__init__.py index f79e0f0..510229c 100644 --- a/tract_querier/tornado_server/__init__.py +++ b/tract_querier/tornado_server/__init__.py @@ -1,7 +1,8 @@ import os -import sys import json from StringIO import StringIO +import urllib +from multiprocessing import Process import tornado.ioloop import tornado.web @@ -19,6 +20,7 @@ def initialize(self, shell=None): self.sio = StringIO() self.shell.stdout = self.sio self.json_encoder = json.JSONEncoder() + self.json_decoder = json.JSONDecoder() def open(self): global websocket_clients @@ -26,18 +28,20 @@ def open(self): def on_message(self, message): # self.write_message(u"You Said: " + message) - global change - change = message - self.sio.seek(0) - self.shell.onecmd(message) - self.sio.seek(0) - result = self.sio.getvalue() - term_output = { - 'receiver': 'terminal', - 'output': result - } - self.write_message(self.json_encoder.encode(term_output)) - self.sio.truncate(0) + action = self.json_decoder.decode(message) + if action['receiver'] == 'terminal': + if action['action'] == 'cmd': + print "Received command" + self.sio.seek(0) + self.shell.onecmd(action['command']) + self.sio.seek(0) + result = self.sio.getvalue() + term_output = { + 'receiver': 'terminal', + 'output': result + } + self.write_message(self.json_encoder.encode(term_output)) + self.sio.truncate(0) #self.write_message(message + "Response") @@ -47,6 +51,61 @@ def on_close(self): websocket_clients.remove(self) +class JSONRPCHandler(tornado.web.RequestHandler): + def initialize(self, shell=None): + self.shell = shell + self.sio = StringIO() + self.shell.stdout = self.sio + self.json_encoder = json.JSONEncoder() + self.json_decoder = json.JSONDecoder() + + def post(self): + print self.request.body + args = self.get_argument('data', 'No data received') + decoded_args = self.json_decoder.decode(self.request.body) + if decoded_args['jsonrpc'] != '2.0': + raise ValueError('Wrong JSON-RPC version, must be 2.0') + try: + if decoded_args['method'].startswith('system.'): + method = getattr(self, decoded_args['method'].replace('system.', '')) + result = method(self, *decoded_args['params']) + else: + wmql_string = '%s %s' % ( + decoded_args['method'], + ''.join((s + ' ' for s in decoded_args['params'])) + ) + self.sio.seek(0) + self.shell.onecmd(wmql_string) + self.sio.seek(0) + result = self.sio.getvalue() + self.sio.truncate(0) + + output = { + 'jsonrpc': "2.0", + 'result': result, + 'error': '', + 'id': decoded_args['id'] + } + self.write(output) + except KeyError: + raise ValueError("JSON-RPC protocol not well implemented " + args) + + + def get(self): + return self.post() + + def describe(self, *args): + return ''' + White Matter Query Language Command Line + ''' + + def completion(self, *args): + print "Complete", args[1] + completions = self.shell.completedefault(args[1]) + print completions + return completions + + class MainHandler(tornado.web.RequestHandler): def initialize( self, @@ -129,7 +188,7 @@ def post(self): print e -def xtk_server(atlas=None, colortable=None, port=9999, files_path=None, suffix='', shell=None): +def xtk_server(atlas=None, colortable=None, hostname='localhost', port=9999, files_path=None, suffix='', shell=None): print "Using atlas", atlas global application @@ -154,9 +213,11 @@ def xtk_server(atlas=None, colortable=None, port=9999, files_path=None, suffix=' else: colortable = os.path.abspath(colortable) + adapt_shell_callbacks(shell, 'http://%s:%04d/tracts' % (hostname, port)) + application = tornado.web.Application([ (r"/", MainHandler, { - 'host': 'localhost', 'port': 9999, + 'host': hostname, 'port': port, 'path': static_folder, 'filename': atlas, 'colortable': colortable, @@ -170,6 +231,9 @@ def xtk_server(atlas=None, colortable=None, port=9999, files_path=None, suffix=' (r'/ws', WSHandler, { 'shell': shell, }), + (r'/jsonrpc', JSONRPCHandler, { + 'shell': shell, + }), (r'/tracts', TractHandler), ( r'/atlas/(.*)', @@ -182,5 +246,58 @@ def xtk_server(atlas=None, colortable=None, port=9999, files_path=None, suffix=' ), (r'/files/(.*)', NoCacheStaticHandler, {"path": files_path}) ]) + application.listen(port) tornado.ioloop.IOLoop.instance().start() + + +def adapt_shell_callbacks(shell, url): + shell_save_query_callback = shell.save_query_callback + shell_del_query_callback = shell.del_query_callback + + def save_query_callback(query_name, query_result): + if shell_save_query_callback is not None: + filename = shell_save_query_callback(query_name, query_result) + else: + filename = None + + if filename is not None: + try: + params = urllib.urlencode({ + 'name': query_name, + 'file': filename, + 'action': 'add' + }) + Process( + target=urllib.urlopen, + args=(url, params), + ).start() + + except Exception, e: + print "interactive URL error:", e + return filename + + def del_query_callback(query_name): + if shell_del_query_callback is not None: + shell_del_query_callback(query_name) + + try: + + params = urllib.urlencode({ + 'name': query_name, + 'action': 'remove' + }) + Process( + target=urllib.urlopen, + args=(url, params), + ).start() + + except Exception, e: + print "interactive URL error:", e + + shell.save_query_callback = save_query_callback + shell.del_query_callback = del_query_callback + + + + diff --git a/tract_querier/tornado_server/css/jquery.terminal.css b/tract_querier/tornado_server/css/jquery.terminal.css new file mode 100644 index 0000000..81bec33 --- /dev/null +++ b/tract_querier/tornado_server/css/jquery.terminal.css @@ -0,0 +1,145 @@ +/* + * This css file is part of jquery terminal + * + * Licensed under GNU LGPL Version 3 license + * Copyright (c) 2011-2013 Jakub Jankiewicz + * + */ +.terminal .terminal-output .format, .cmd .format, +.cmd .prompt, .cmd .prompt div, .terminal .terminal-output div div{ + display: inline-block; +} +.cmd .clipboard { + position: absolute; + bottom: 0; + left: 0; + opacity: 0.01; + filter: alpha(opacity = 0.01); + filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0.01); + width: 2px; +} +.cmd > .clipboard { + position: fixed; +} +.terminal { + padding: 10px; + position: relative; + overflow: hidden; + width: 80%; + border-bottom: thin solid #666; +} +.cmd { + padding: 0; + margin: 0; + height: 1.3em; + /*margin-top: 3px; */ +} +.cmd .cursor.blink { + -webkit-animation: blink 1s infinite steps(1, start); + -moz-animation: blink 1s infinite steps(1, start); + -ms-animation: blink 1s infinite steps(1, start); + animation: blink 1s infinite steps(1, start); +} +@keyframes blink { + 0%, 100% { + background-color: #000; + color: #aaa; + } + 50% { + background-color: #bbb; /* not #aaa because it's seem there is Google Chrome bug */ + color: #000; + } +} +@-webkit-keyframes blink { + 0%, 100% { + background-color: #000; + color: #aaa; + } + 50% { + background-color: #bbb; + color: #000; + } +} +@-ms-keyframes blink { + 0%, 100% { + background-color: #000; + color: #aaa; + } + 50% { + background-color: #bbb; + color: #000; + } +} +@-moz-keyframes blink { + 0%, 100% { + background-color: #000; + color: #aaa; + } + 50% { + background-color: #bbb; + color: #000; + } +} +.terminal .terminal-output div div, .cmd .prompt { + display: block; + line-height: 20px; + height: auto; +} +.cmd .prompt { + float: left; +} +.terminal, .cmd { + font-family: FreeMono, monospace; + color: #aaa; + background-color: #000; + font-size: 18px; + line-height: 20px; +} +.terminal-output > div { + /*padding-top: 3px;*/ + min-height: 20px; +} +.terminal .terminal-output div span { + display: inline-block; +} +.cmd span { + float: left; + /*display: inline-block; */ +} +.terminal .inverted, .cmd .inverted, .cmd .cursor.blink { + background-color: #aaa; + color: #000; +} +.terminal .terminal-output div div::-moz-selection, +.terminal .terminal-output div span::-moz-selection, +.terminal .terminal-output div div a::-moz-selection { + background-color: #aaa; + color: #000; +} +.terminal .terminal-output div div::selection, +.terminal .terminal-output div div a::selection, +.terminal .terminal-output div span::selection, +.cmd > span::selection, +.cmd .prompt span::selection { + background-color: #aaa; + color: #000; +} +.terminal .terminal-output div.error, .terminal .terminal-output div.error div { + color: red; +} +.tilda { + position: fixed; + top: 0; + left: 0; + width: 100%; + z-index: 1100; +} +.clear { + clear: both; +} +.terminal a { + color: #0F60FF; +} +.terminal a:hover { + color: red; +} diff --git a/tract_querier/tornado_server/css/viewer.css b/tract_querier/tornado_server/css/viewer.css index 70b7113..ef83e0d 100644 --- a/tract_querier/tornado_server/css/viewer.css +++ b/tract_querier/tornado_server/css/viewer.css @@ -25,10 +25,6 @@ height: 5%; } -#shell { - bottom: 5%; -} - #sliceX { top: 7%; } diff --git a/tract_querier/tornado_server/index.html b/tract_querier/tornado_server/index.html index 226e40a..ad35c8a 100644 --- a/tract_querier/tornado_server/index.html +++ b/tract_querier/tornado_server/index.html @@ -27,7 +27,7 @@ diff --git a/tract_querier/tornado_server/js/dterm.js b/tract_querier/tornado_server/js/dterm.js new file mode 100644 index 0000000..4dd4dcb --- /dev/null +++ b/tract_querier/tornado_server/js/dterm.js @@ -0,0 +1,63 @@ +/*! + * Example plugin using JQuery Terminal Emulator + * Copyright (C) 2010 Jakub Jankiewicz + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ +(function($) { + $.extend_if_has = function(desc, source, array) { + for (var i=array.length;i--;) { + if (typeof source[array[i]] != 'undefined') { + desc[array[i]] = source[array[i]]; + } + } + return desc; + }; + $.fn.dterm = function(eval, options) { + var op = $.extend_if_has({}, options, + ['greetings', 'prompt', 'onInit', + 'onExit', 'clear', + 'login', 'name', 'exit']); + op.enabled = false; + var terminal = this.terminal(eval, op).css('overflow', 'hidden'); + if (!options.title) { + options.title = 'JQuery Terminal Emulator'; + } + if (options.logoutOnClose) { + options.close = function(e, ui) { + terminal.logout(); + terminal.clear(); + }; + } else { + options.close = function(e, ui) { + terminal.disable(); + }; + } + var self = this; + this.dialog($.extend(options, { + resizeStop: function(e, ui) { + var content = self.find('.ui-dialog-content'); + terminal.resize(content.width(), content.height()); + }, + open: function(e, ui) { + terminal.focus(); + terminal.resize(); + }, + show: 'fade', + closeOnEscape: false + })); + self.terminal = terminal; + return self; + }; +})(jQuery); diff --git a/tract_querier/tornado_server/js/jquery-1.7.1.min.js b/tract_querier/tornado_server/js/jquery-1.7.1.min.js new file mode 100644 index 0000000..198b3ff --- /dev/null +++ b/tract_querier/tornado_server/js/jquery-1.7.1.min.js @@ -0,0 +1,4 @@ +/*! jQuery v1.7.1 jquery.com | jquery.org/license */ +(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
    a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
    "+""+"
    ",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
    t
    ",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
    ",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; +f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

    ";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
    ";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
    ","
    "],thead:[1,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],col:[2,"","
    "],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
    ","
    "]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() +{for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
    ").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); \ No newline at end of file diff --git a/tract_querier/tornado_server/js/jquery.mousewheel-min.js b/tract_querier/tornado_server/js/jquery.mousewheel-min.js new file mode 100644 index 0000000..1ff8c87 --- /dev/null +++ b/tract_querier/tornado_server/js/jquery.mousewheel-min.js @@ -0,0 +1,2 @@ +(function(c){function g(a){var b=a||window.event,i=[].slice.call(arguments,1),e=0,h=0,f=0;a=c.event.fix(b);a.type="mousewheel";if(b.wheelDelta)e=b.wheelDelta/120;if(b.detail)e=-b.detail/3;f=e;if(b.axis!==undefined&&b.axis===b.HORIZONTAL_AXIS){f=0;h=-1*e}if(b.wheelDeltaY!==undefined)f=b.wheelDeltaY/120;if(b.wheelDeltaX!==undefined)h=-1*b.wheelDeltaX/120;i.unshift(a,e,h,f);return(c.event.dispatch||c.event.handle).apply(this,i)}var d=["DOMMouseScroll","mousewheel"];if(c.event.fixHooks)for(var j=d.length;j;)c.event.fixHooks[d[--j]]= +c.event.mouseHooks;c.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=d.length;a;)this.addEventListener(d[--a],g,false);else this.onmousewheel=g},teardown:function(){if(this.removeEventListener)for(var a=d.length;a;)this.removeEventListener(d[--a],g,false);else this.onmousewheel=null}};c.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery); diff --git a/tract_querier/tornado_server/js/jquery.terminal-0.8.7.js b/tract_querier/tornado_server/js/jquery.terminal-0.8.7.js new file mode 100644 index 0000000..091eeb8 --- /dev/null +++ b/tract_querier/tornado_server/js/jquery.terminal-0.8.7.js @@ -0,0 +1,4328 @@ +/**@license + * __ _____ ________ __ + * / // _ /__ __ _____ ___ __ _/__ ___/__ ___ ______ __ __ __ ___ / / + * __ / // // // // // _ // _// // / / // _ // _// // // \/ // _ \/ / + * / / // // // // // ___// / / // / / // ___// / / / / // // /\ // // / /__ + * \___//____ \\___//____//_/ _\_ / /_//____//_/ /_/ /_//_//_/ /_/ \__\_\___/ + * \/ /____/ version 0.8.7 + * http://terminal.jcubic.pl + * + * Licensed under GNU LGPL Version 3 license + * Copyright (c) 2011-2013 Jakub Jankiewicz + * + * Includes: + * + * Storage plugin Distributed under the MIT License + * Copyright (c) 2010 Dave Schindler + * + * jQuery Timers licenced with the WTFPL + * + * + * Cross-Browser Split 1.1.1 + * Copyright 2007-2012 Steven Levithan + * Available under the MIT License + * + * sprintf.js + * Copyright (c) 2007-2013 Alexandru Marasteanu + * licensed under 3 clause BSD license + * + * Date: + * + */ + +(function(ctx) { + var sprintf = function() { + if (!sprintf.cache.hasOwnProperty(arguments[0])) { + sprintf.cache[arguments[0]] = sprintf.parse(arguments[0]); + } + return sprintf.format.call(null, sprintf.cache[arguments[0]], arguments); + }; + + sprintf.format = function(parse_tree, argv) { + var cursor = 1, tree_length = parse_tree.length, node_type = '', arg, output = [], i, k, match, pad, pad_character, pad_length; + for (i = 0; i < tree_length; i++) { + node_type = get_type(parse_tree[i]); + if (node_type === 'string') { + output.push(parse_tree[i]); + } + else if (node_type === 'array') { + match = parse_tree[i]; // convenience purposes only + if (match[2]) { // keyword argument + arg = argv[cursor]; + for (k = 0; k < match[2].length; k++) { + if (!arg.hasOwnProperty(match[2][k])) { + throw(sprintf('[sprintf] property "%s" does not exist', match[2][k])); + } + arg = arg[match[2][k]]; + } + } + else if (match[1]) { // positional argument (explicit) + arg = argv[match[1]]; + } + else { // positional argument (implicit) + arg = argv[cursor++]; + } + + if (/[^s]/.test(match[8]) && (get_type(arg) != 'number')) { + throw(sprintf('[sprintf] expecting number but found %s', get_type(arg))); + } + switch (match[8]) { + case 'b': arg = arg.toString(2); break; + case 'c': arg = String.fromCharCode(arg); break; + case 'd': arg = parseInt(arg, 10); break; + case 'e': arg = match[7] ? arg.toExponential(match[7]) : arg.toExponential(); break; + case 'f': arg = match[7] ? parseFloat(arg).toFixed(match[7]) : parseFloat(arg); break; + case 'o': arg = arg.toString(8); break; + case 's': arg = ((arg = String(arg)) && match[7] ? arg.substring(0, match[7]) : arg); break; + case 'u': arg = arg >>> 0; break; + case 'x': arg = arg.toString(16); break; + case 'X': arg = arg.toString(16).toUpperCase(); break; + } + arg = (/[def]/.test(match[8]) && match[3] && arg >= 0 ? '+'+ arg : arg); + pad_character = match[4] ? match[4] == '0' ? '0' : match[4].charAt(1) : ' '; + pad_length = match[6] - String(arg).length; + pad = match[6] ? str_repeat(pad_character, pad_length) : ''; + output.push(match[5] ? arg + pad : pad + arg); + } + } + return output.join(''); + }; + + sprintf.cache = {}; + + sprintf.parse = function(fmt) { + var _fmt = fmt, match = [], parse_tree = [], arg_names = 0; + while (_fmt) { + if ((match = /^[^\x25]+/.exec(_fmt)) !== null) { + parse_tree.push(match[0]); + } + else if ((match = /^\x25{2}/.exec(_fmt)) !== null) { + parse_tree.push('%'); + } + else if ((match = /^\x25(?:([1-9]\d*)\$|\(([^\)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-fosuxX])/.exec(_fmt)) !== null) { + if (match[2]) { + arg_names |= 1; + var field_list = [], replacement_field = match[2], field_match = []; + if ((field_match = /^([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') { + if ((field_match = /^\.([a-z_][a-z_\d]*)/i.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else if ((field_match = /^\[(\d+)\]/.exec(replacement_field)) !== null) { + field_list.push(field_match[1]); + } + else { + throw('[sprintf] huh?'); + } + } + } + else { + throw('[sprintf] huh?'); + } + match[2] = field_list; + } + else { + arg_names |= 2; + } + if (arg_names === 3) { + throw('[sprintf] mixing positional and named placeholders is not (yet) supported'); + } + parse_tree.push(match); + } + else { + throw('[sprintf] huh?'); + } + _fmt = _fmt.substring(match[0].length); + } + return parse_tree; + }; + + var vsprintf = function(fmt, argv, _argv) { + _argv = argv.slice(0); + _argv.splice(0, 0, fmt); + return sprintf.apply(null, _argv); + }; + + /** + * helpers + */ + function get_type(variable) { + return Object.prototype.toString.call(variable).slice(8, -1).toLowerCase(); + } + + function str_repeat(input, multiplier) { + for (var output = []; multiplier > 0; output[--multiplier] = input) {/* do nothing */} + return output.join(''); + } + + /** + * export to either browser or node.js + */ + ctx.sprintf = sprintf; + ctx.vsprintf = vsprintf; +})(typeof exports != "undefined" ? exports : window); + +(function($, undefined) { + "use strict"; + // ----------------------------------------------------------------------- + // :: map object to object + // ----------------------------------------------------------------------- + $.omap = function(o, fn) { + var result = {}; + $.each(o, function(k, v) { + result[k] = fn.call(o, k, v); + }); + return result; + }; + // ----------------------------------------------------------------------- + // :: Storage plugin + // ----------------------------------------------------------------------- + // Private data + var isLS = typeof window.localStorage !== 'undefined'; + // Private functions + function wls(n, v) { + var c; + if (typeof n === 'string' && typeof v === 'string') { + localStorage[n] = v; + return true; + } else if (typeof n === 'object' && typeof v === 'undefined') { + for (c in n) { + if (n.hasOwnProperty(c)) { + localStorage[c] = n[c]; + } + } + return true; + } + return false; + } + function wc(n, v) { + var dt, e, c; + dt = new Date(); + dt.setTime(dt.getTime() + 31536000000); + e = '; expires=' + dt.toGMTString(); + if (typeof n === 'string' && typeof v === 'string') { + document.cookie = n + '=' + v + e + '; path=/'; + return true; + } else if (typeof n === 'object' && typeof v === 'undefined') { + for (c in n) { + if (n.hasOwnProperty(c)) { + document.cookie = c + '=' + n[c] + e + '; path=/'; + } + } + return true; + } + return false; + } + function rls(n) { + return localStorage[n]; + } + function rc(n) { + var nn, ca, i, c; + nn = n + '='; + ca = document.cookie.split(';'); + for (i = 0; i < ca.length; i++) { + c = ca[i]; + while (c.charAt(0) === ' ') { + c = c.substring(1, c.length); + } + if (c.indexOf(nn) === 0) { + return c.substring(nn.length, c.length); + } + } + return null; + } + function dls(n) { + return delete localStorage[n]; + } + function dc(n) { + return wc(n, '', -1); + } + /** + * Public API + * $.Storage.set("name", "value") + * $.Storage.set({"name1":"value1", "name2":"value2", etc}) + * $.Storage.get("name") + * $.Storage.remove("name") + */ + $.extend({ + Storage: { + set: isLS ? wls : wc, + get: isLS ? rls : rc, + remove: isLS ? dls : dc + } + }); + // ----------------------------------------------------------------------- + // :: jQuery Timers + // ----------------------------------------------------------------------- + jQuery.fn.extend({ + everyTime: function(interval, label, fn, times, belay) { + return this.each(function() { + jQuery.timer.add(this, interval, label, fn, times, belay); + }); + }, + oneTime: function(interval, label, fn) { + return this.each(function() { + jQuery.timer.add(this, interval, label, fn, 1); + }); + }, + stopTime: function(label, fn) { + return this.each(function() { + jQuery.timer.remove(this, label, fn); + }); + } + }); + + jQuery.extend({ + timer: { + guid: 1, + global: {}, + regex: /^([0-9]+)\s*(.*s)?$/, + powers: { + // Yeah this is major overkill... + 'ms': 1, + 'cs': 10, + 'ds': 100, + 's': 1000, + 'das': 10000, + 'hs': 100000, + 'ks': 1000000 + }, + timeParse: function(value) { + if (value === undefined || value === null) { + return null; + } + var result = this.regex.exec(jQuery.trim(value.toString())); + if (result[2]) { + var num = parseInt(result[1], 10); + var mult = this.powers[result[2]] || 1; + return num * mult; + } else { + return value; + } + }, + add: function(element, interval, label, fn, times, belay) { + var counter = 0; + + if (jQuery.isFunction(label)) { + if (!times) { + times = fn; + } + fn = label; + label = interval; + } + + interval = jQuery.timer.timeParse(interval); + + if (typeof interval !== 'number' || + isNaN(interval) || + interval <= 0) { + return; + } + if (times && times.constructor !== Number) { + belay = !!times; + times = 0; + } + + times = times || 0; + belay = belay || false; + + if (!element.$timers) { + element.$timers = {}; + } + if (!element.$timers[label]) { + element.$timers[label] = {}; + } + fn.$timerID = fn.$timerID || this.guid++; + + var handler = function() { + if (belay && handler.inProgress) { + return; + } + handler.inProgress = true; + if ((++counter > times && times !== 0) || + fn.call(element, counter) === false) { + jQuery.timer.remove(element, label, fn); + } + handler.inProgress = false; + }; + + handler.$timerID = fn.$timerID; + + if (!element.$timers[label][fn.$timerID]) { + element.$timers[label][fn.$timerID] = window.setInterval(handler, interval); + } + + if (!this.global[label]) { + this.global[label] = []; + } + this.global[label].push(element); + + }, + remove: function(element, label, fn) { + var timers = element.$timers, ret; + + if (timers) { + + if (!label) { + for (var lab in timers) { + if (timers.hasOwnProperty(lab)) { + this.remove(element, lab, fn); + } + } + } else if (timers[label]) { + if (fn) { + if (fn.$timerID) { + window.clearInterval(timers[label][fn.$timerID]); + delete timers[label][fn.$timerID]; + } + } else { + for (var _fn in timers[label]) { + if (timers[label].hasOwnProperty(_fn)) { + window.clearInterval(timers[label][_fn]); + delete timers[label][_fn]; + } + } + } + + for (ret in timers[label]) { + if (timers[label].hasOwnProperty(ret)) { + break; + } + } + if (!ret) { + ret = null; + delete timers[label]; + } + } + + for (ret in timers) { + if (timers.hasOwnProperty(ret)) { + break; + } + } + if (!ret) { + element.$timers = null; + } + } + } + } + }); + + if (/(msie) ([\w.]+)/.exec(navigator.userAgent.toLowerCase())) { + jQuery(window).one('unload', function() { + var global = jQuery.timer.global; + for (var label in global) { + if (global.hasOwnProperty(label)) { + var els = global[label], i = els.length; + while (--i) { + jQuery.timer.remove(els[i], label); + } + } + } + }); + } + // ----------------------------------------------------------------------- + // :: CROSS BROWSER SPLIT + // ----------------------------------------------------------------------- + + (function(undef) { + + // prevent double include + + if (!String.prototype.split.toString().match(/\[native/)) { + return; + } + + var nativeSplit = String.prototype.split, + compliantExecNpcg = /()??/.exec("")[1] === undef, // NPCG: nonparticipating capturing group + self; + + self = function (str, separator, limit) { + // If `separator` is not a regex, use `nativeSplit` + if (Object.prototype.toString.call(separator) !== "[object RegExp]") { + return nativeSplit.call(str, separator, limit); + } + var output = [], + flags = (separator.ignoreCase ? "i" : "") + + (separator.multiline ? "m" : "") + + (separator.extended ? "x" : "") + // Proposed for ES6 + (separator.sticky ? "y" : ""), // Firefox 3+ + lastLastIndex = 0, + // Make `global` and avoid `lastIndex` issues by working with a copy + separator2, match, lastIndex, lastLength; + separator = new RegExp(separator.source, flags + "g"); + str += ""; // Type-convert + if (!compliantExecNpcg) { + // Doesn't need flags gy, but they don't hurt + separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags); + } + /* Values for `limit`, per the spec: + * If undefined: 4294967295 // Math.pow(2, 32) - 1 + * If 0, Infinity, or NaN: 0 + * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296; + * If negative number: 4294967296 - Math.floor(Math.abs(limit)) + * If other: Type-convert, then use the above rules + */ + // ? Math.pow(2, 32) - 1 : ToUint32(limit) + limit = limit === undef ? -1 >>> 0 : limit >>> 0; + while (match = separator.exec(str)) { + // `separator.lastIndex` is not reliable cross-browser + lastIndex = match.index + match[0].length; + if (lastIndex > lastLastIndex) { + output.push(str.slice(lastLastIndex, match.index)); + // Fix browsers whose `exec` methods don't consistently return `undefined` for + // nonparticipating capturing groups + if (!compliantExecNpcg && match.length > 1) { + match[0].replace(separator2, function () { + for (var i = 1; i < arguments.length - 2; i++) { + if (arguments[i] === undef) { + match[i] = undef; + } + } + }); + } + if (match.length > 1 && match.index < str.length) { + Array.prototype.push.apply(output, match.slice(1)); + } + lastLength = match[0].length; + lastLastIndex = lastIndex; + if (output.length >= limit) { + break; + } + } + if (separator.lastIndex === match.index) { + separator.lastIndex++; // Avoid an infinite loop + } + } + if (lastLastIndex === str.length) { + if (lastLength || !separator.test("")) { + output.push(""); + } + } else { + output.push(str.slice(lastLastIndex)); + } + return output.length > limit ? output.slice(0, limit) : output; + }; + + // For convenience + String.prototype.split = function (separator, limit) { + return self(this, separator, limit); + }; + + return self; + + })(); + // ----------------------------------------------------------------------- + // :: Split string to array of strings with the same length + // ----------------------------------------------------------------------- + function str_parts(str, length) { + var result = []; + var len = str.length; + if (len < length) { + return [str]; + } + for (var i = 0; i < len; i += length) { + result.push(str.substring(i, i + length)); + } + return result; + } + // ----------------------------------------------------------------------- + // :: CYCLE DATA STRUCTURE + // ----------------------------------------------------------------------- + function Cycle(init) { + var data = init ? [init] : []; + var pos = 0; + $.extend(this, { + get: function() { + return data; + }, + rotate: function() { + if (data.length === 1) { + return data[0]; + } else { + if (pos === data.length - 1) { + pos = 0; + } else { + ++pos; + } + return data[pos]; + } + }, + length: function() { + return data.length; + }, + set: function(item) { + for (var i = data.length; i--;) { + if (data[i] === item) { + pos = i; + return; + } + } + this.append(item); + }, + front: function() { + return data[pos]; + }, + append: function(item) { + data.push(item); + } + }); + } + // ----------------------------------------------------------------------- + // :: STACK DATA STRUCTURE + // ----------------------------------------------------------------------- + function Stack(init) { + var data = init ? [init] : []; + $.extend(this, { + map: function(fn) { + return $.map(data, fn); + }, + size: function() { + return data.length; + }, + pop: function() { + if (data.length === 0) { + return null; + } else { + var value = data[data.length - 1]; + data = data.slice(0, data.length - 1); + return value; + } + }, + push: function(value) { + data = data.concat([value]); + return value; + }, + top: function() { + return data.length > 0 ? data[data.length - 1] : null; + } + }); + } + // ----------------------------------------------------------------------- + // :: Serialize object myself (biwascheme or prototype library do something + // :: wicked with JSON serialization for Arrays) + // ----------------------------------------------------------------------- + $.json_stringify = function(object, level) { + var result = '', i; + level = level === undefined ? 1 : level; + var type = typeof object; + switch (type) { + case 'function': + result += object; + break; + case 'boolean': + result += object ? 'true' : 'false'; + break; + case 'object': + if (object === null) { + result += 'null'; + } else if (object instanceof Array) { + result += '['; + var len = object.length; + for (i = 0; i < len - 1; ++i) { + result += $.json_stringify(object[i], level + 1); + } + result += $.json_stringify(object[len - 1], level + 1) + ']'; + } else { + result += '{'; + for (var property in object) { + if (object.hasOwnProperty(property)) { + result += '"' + property + '":' + + $.json_stringify(object[property], level + 1); + } + } + result += '}'; + } + break; + case 'string': + var str = object; + var repl = { + '\\\\': '\\\\', + '"': '\\"', + '/': '\\/', + '\\n': '\\n', + '\\r': '\\r', + '\\t': '\\t'}; + for (i in repl) { + if (repl.hasOwnProperty(i)) { + str = str.replace(new RegExp(i, 'g'), repl[i]); + } + } + result += '"' + str + '"'; + break; + case 'number': + result += String(object); + break; + } + result += (level > 1 ? ',' : ''); + // quick hacks below + if (level === 1) { + // fix last comma + result = result.replace(/,([\]}])/g, '$1'); + } + // fix comma before array or object + return result.replace(/([\[{]),/g, '$1'); + }; + // ----------------------------------------------------------------------- + // :: HISTORY CLASS + // ----------------------------------------------------------------------- + function History(name, size) { + var enabled = true; + var storage_key = ''; + if (typeof name === 'string' && name !== '') { + storage_key = name + '_'; + } + storage_key += 'commands'; + var data = $.Storage.get(storage_key); + data = data ? $.parseJSON(data) : []; + var pos = data.length-1; + $.extend(this, { + append: function(item) { + if (enabled) { + if (data[data.length-1] !== item) { + data.push(item); + if (size && data.length > size) { + data = data.slice(-size); + } + pos = data.length-1; + $.Storage.set(storage_key, $.json_stringify(data)); + } + } + }, + data: function() { + return data; + }, + reset: function() { + pos = data.length-1; + }, + last: function() { + return data[length-1]; + }, + end: function() { + return pos === data.length-1; + }, + position: function() { + return pos; + }, + current: function() { + return data[pos]; + }, + next: function() { + if (pos < data.length-1) { + ++pos; + } + if (pos !== -1) { + return data[pos]; + } + }, + previous: function() { + var old = pos; + if (pos > 0) { + --pos; + } + if (old !== -1) { + return data[pos]; + } + }, + clear: function() { + data = []; + this.purge(); + }, + enabled: function() { + return enabled; + }, + enable: function() { + enabled = true; + }, + purge: function() { + $.Storage.remove(storage_key); + }, + disable: function() { + enabled = false; + } + }); + } + // ----------------------------------------------------------------------- + // :: COMMAND LINE PLUGIN + // ----------------------------------------------------------------------- + $.fn.cmd = function(options) { + var self = this; + var maybe_data = self.data('cmd'); + if (maybe_data) { + return maybe_data; + } + self.addClass('cmd'); + self.append('' + + ' '); + var clip = $('\n\n
    \n\n Automatically save\n values to localStorage on exit.\n\n
    The values saved to localStorage will\n override those passed to dat.GUI's constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
    \n \n
    \n\n
    ", +".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n", +dat.controllers.factory = (function (OptionController, NumberControllerBox, NumberControllerSlider, StringController, FunctionController, BooleanController, common) { + + return function(object, property) { + + var initialValue = object[property]; + + // Providing options? + if (common.isArray(arguments[2]) || common.isObject(arguments[2])) { + return new OptionController(object, property, arguments[2]); + } + + // Providing a map? + + if (common.isNumber(initialValue)) { + + if (common.isNumber(arguments[2]) && common.isNumber(arguments[3])) { + + // Has min and max. + return new NumberControllerSlider(object, property, arguments[2], arguments[3]); + + } else { + + return new NumberControllerBox(object, property, { min: arguments[2], max: arguments[3] }); + + } + + } + + if (common.isString(initialValue)) { + return new StringController(object, property); + } + + if (common.isFunction(initialValue)) { + return new FunctionController(object, property, ''); + } + + if (common.isBoolean(initialValue)) { + return new BooleanController(object, property); + } + + } + + })(dat.controllers.OptionController, +dat.controllers.NumberControllerBox, +dat.controllers.NumberControllerSlider, +dat.controllers.StringController = (function (Controller, dom, common) { + + /** + * @class Provides a text input to alter the string property of an object. + * + * @extends dat.controllers.Controller + * + * @param {Object} object The object to be manipulated + * @param {string} property The name of the property to be manipulated + * + * @member dat.controllers + */ + var StringController = function(object, property) { + + StringController.superclass.call(this, object, property); + + var _this = this; + + this.__input = document.createElement('input'); + this.__input.setAttribute('type', 'text'); + + dom.bind(this.__input, 'keyup', onChange); + dom.bind(this.__input, 'change', onChange); + dom.bind(this.__input, 'blur', onBlur); + dom.bind(this.__input, 'keydown', function(e) { + if (e.keyCode === 13) { + this.blur(); + } + }); + + + function onChange() { + _this.setValue(_this.__input.value); + } + + function onBlur() { + if (_this.__onFinishChange) { + _this.__onFinishChange.call(_this, _this.getValue()); + } + } + + this.updateDisplay(); + + this.domElement.appendChild(this.__input); + + }; + + StringController.superclass = Controller; + + common.extend( + + StringController.prototype, + Controller.prototype, + + { + + updateDisplay: function() { + // Stops the caret from moving on account of: + // keyup -> setValue -> updateDisplay + if (!dom.isActive(this.__input)) { + this.__input.value = this.getValue(); + } + return StringController.superclass.prototype.updateDisplay.call(this); + } + + } + + ); + + return StringController; + +})(dat.controllers.Controller, +dat.dom.dom, +dat.utils.common), +dat.controllers.FunctionController, +dat.controllers.BooleanController, +dat.utils.common), +dat.controllers.Controller, +dat.controllers.BooleanController, +dat.controllers.FunctionController, +dat.controllers.NumberControllerBox, +dat.controllers.NumberControllerSlider, +dat.controllers.OptionController, +dat.controllers.ColorController = (function (Controller, dom, Color, interpret, common) { + + var ColorController = function(object, property) { + + ColorController.superclass.call(this, object, property); + + this.__color = new Color(this.getValue()); + this.__temp = new Color(0); + + var _this = this; + + this.domElement = document.createElement('div'); + + dom.makeSelectable(this.domElement, false); + + this.__selector = document.createElement('div'); + this.__selector.className = 'selector'; + + this.__saturation_field = document.createElement('div'); + this.__saturation_field.className = 'saturation-field'; + + this.__field_knob = document.createElement('div'); + this.__field_knob.className = 'field-knob'; + this.__field_knob_border = '2px solid '; + + this.__hue_knob = document.createElement('div'); + this.__hue_knob.className = 'hue-knob'; + + this.__hue_field = document.createElement('div'); + this.__hue_field.className = 'hue-field'; + + this.__input = document.createElement('input'); + this.__input.type = 'text'; + this.__input_textShadow = '0 1px 1px '; + + dom.bind(this.__input, 'keydown', function(e) { + if (e.keyCode === 13) { // on enter + onBlur.call(this); + } + }); + + dom.bind(this.__input, 'blur', onBlur); + + dom.bind(this.__selector, 'mousedown', function(e) { + + dom + .addClass(this, 'drag') + .bind(window, 'mouseup', function(e) { + dom.removeClass(_this.__selector, 'drag'); + }); + + }); + + var value_field = document.createElement('div'); + + common.extend(this.__selector.style, { + width: '122px', + height: '102px', + padding: '3px', + backgroundColor: '#222', + boxShadow: '0px 1px 3px rgba(0,0,0,0.3)' + }); + + common.extend(this.__field_knob.style, { + position: 'absolute', + width: '12px', + height: '12px', + border: this.__field_knob_border + (this.__color.v < .5 ? '#fff' : '#000'), + boxShadow: '0px 1px 3px rgba(0,0,0,0.5)', + borderRadius: '12px', + zIndex: 1 + }); + + common.extend(this.__hue_knob.style, { + position: 'absolute', + width: '15px', + height: '2px', + borderRight: '4px solid #fff', + zIndex: 1 + }); + + common.extend(this.__saturation_field.style, { + width: '100px', + height: '100px', + border: '1px solid #555', + marginRight: '3px', + display: 'inline-block', + cursor: 'pointer' + }); + + common.extend(value_field.style, { + width: '100%', + height: '100%', + background: 'none' + }); + + linearGradient(value_field, 'top', 'rgba(0,0,0,0)', '#000'); + + common.extend(this.__hue_field.style, { + width: '15px', + height: '100px', + display: 'inline-block', + border: '1px solid #555', + cursor: 'ns-resize' + }); + + hueGradient(this.__hue_field); + + common.extend(this.__input.style, { + outline: 'none', +// width: '120px', + textAlign: 'center', +// padding: '4px', +// marginBottom: '6px', + color: '#fff', + border: 0, + fontWeight: 'bold', + textShadow: this.__input_textShadow + 'rgba(0,0,0,0.7)' + }); + + dom.bind(this.__saturation_field, 'mousedown', fieldDown); + dom.bind(this.__field_knob, 'mousedown', fieldDown); + + dom.bind(this.__hue_field, 'mousedown', function(e) { + setH(e); + dom.bind(window, 'mousemove', setH); + dom.bind(window, 'mouseup', unbindH); + }); + + function fieldDown(e) { + setSV(e); + // document.body.style.cursor = 'none'; + dom.bind(window, 'mousemove', setSV); + dom.bind(window, 'mouseup', unbindSV); + } + + function unbindSV() { + dom.unbind(window, 'mousemove', setSV); + dom.unbind(window, 'mouseup', unbindSV); + // document.body.style.cursor = 'default'; + } + + function onBlur() { + var i = interpret(this.value); + if (i !== false) { + _this.__color.__state = i; + _this.setValue(_this.__color.toOriginal()); + } else { + this.value = _this.__color.toString(); + } + } + + function unbindH() { + dom.unbind(window, 'mousemove', setH); + dom.unbind(window, 'mouseup', unbindH); + } + + this.__saturation_field.appendChild(value_field); + this.__selector.appendChild(this.__field_knob); + this.__selector.appendChild(this.__saturation_field); + this.__selector.appendChild(this.__hue_field); + this.__hue_field.appendChild(this.__hue_knob); + + this.domElement.appendChild(this.__input); + this.domElement.appendChild(this.__selector); + + this.updateDisplay(); + + function setSV(e) { + + e.preventDefault(); + + var w = dom.getWidth(_this.__saturation_field); + var o = dom.getOffset(_this.__saturation_field); + var s = (e.clientX - o.left + document.body.scrollLeft) / w; + var v = 1 - (e.clientY - o.top + document.body.scrollTop) / w; + + if (v > 1) v = 1; + else if (v < 0) v = 0; + + if (s > 1) s = 1; + else if (s < 0) s = 0; + + _this.__color.v = v; + _this.__color.s = s; + + _this.setValue(_this.__color.toOriginal()); + + + return false; + + } + + function setH(e) { + + e.preventDefault(); + + var s = dom.getHeight(_this.__hue_field); + var o = dom.getOffset(_this.__hue_field); + var h = 1 - (e.clientY - o.top + document.body.scrollTop) / s; + + if (h > 1) h = 1; + else if (h < 0) h = 0; + + _this.__color.h = h * 360; + + _this.setValue(_this.__color.toOriginal()); + + return false; + + } + + }; + + ColorController.superclass = Controller; + + common.extend( + + ColorController.prototype, + Controller.prototype, + + { + + updateDisplay: function() { + + var i = interpret(this.getValue()); + + if (i !== false) { + + var mismatch = false; + + // Check for mismatch on the interpreted value. + + common.each(Color.COMPONENTS, function(component) { + if (!common.isUndefined(i[component]) && + !common.isUndefined(this.__color.__state[component]) && + i[component] !== this.__color.__state[component]) { + mismatch = true; + return {}; // break + } + }, this); + + // If nothing diverges, we keep our previous values + // for statefulness, otherwise we recalculate fresh + if (mismatch) { + common.extend(this.__color.__state, i); + } + + } + + common.extend(this.__temp.__state, this.__color.__state); + + this.__temp.a = 1; + + var flip = (this.__color.v < .5 || this.__color.s > .5) ? 255 : 0; + var _flip = 255 - flip; + + common.extend(this.__field_knob.style, { + marginLeft: 100 * this.__color.s - 7 + 'px', + marginTop: 100 * (1 - this.__color.v) - 7 + 'px', + backgroundColor: this.__temp.toString(), + border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip +')' + }); + + this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px' + + this.__temp.s = 1; + this.__temp.v = 1; + + linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toString()); + + common.extend(this.__input.style, { + backgroundColor: this.__input.value = this.__color.toString(), + color: 'rgb(' + flip + ',' + flip + ',' + flip +')', + textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip +',.7)' + }); + + } + + } + + ); + + var vendors = ['-moz-','-o-','-webkit-','-ms-','']; + + function linearGradient(elem, x, a, b) { + elem.style.background = ''; + common.each(vendors, function(vendor) { + elem.style.cssText += 'background: ' + vendor + 'linear-gradient('+x+', '+a+' 0%, ' + b + ' 100%); '; + }); + } + + function hueGradient(elem) { + elem.style.background = ''; + elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);' + elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);' + elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);' + elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);' + elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);' + } + + + return ColorController; + +})(dat.controllers.Controller, +dat.dom.dom, +dat.color.Color = (function (interpret, math, toString, common) { + + var Color = function() { + + this.__state = interpret.apply(this, arguments); + + if (this.__state === false) { + throw 'Failed to interpret color arguments'; + } + + this.__state.a = this.__state.a || 1; + + + }; + + Color.COMPONENTS = ['r','g','b','h','s','v','hex','a']; + + common.extend(Color.prototype, { + + toString: function() { + return toString(this); + }, + + toOriginal: function() { + return this.__state.conversion.write(this); + } + + }); + + defineRGBComponent(Color.prototype, 'r', 2); + defineRGBComponent(Color.prototype, 'g', 1); + defineRGBComponent(Color.prototype, 'b', 0); + + defineHSVComponent(Color.prototype, 'h'); + defineHSVComponent(Color.prototype, 's'); + defineHSVComponent(Color.prototype, 'v'); + + Object.defineProperty(Color.prototype, 'a', { + + get: function() { + return this.__state.a; + }, + + set: function(v) { + this.__state.a = v; + } + + }); + + Object.defineProperty(Color.prototype, 'hex', { + + get: function() { + + if (!this.__state.space !== 'HEX') { + this.__state.hex = math.rgb_to_hex(this.r, this.g, this.b); + } + + return this.__state.hex; + + }, + + set: function(v) { + + this.__state.space = 'HEX'; + this.__state.hex = v; + + } + + }); + + function defineRGBComponent(target, component, componentHexIndex) { + + Object.defineProperty(target, component, { + + get: function() { + + if (this.__state.space === 'RGB') { + return this.__state[component]; + } + + recalculateRGB(this, component, componentHexIndex); + + return this.__state[component]; + + }, + + set: function(v) { + + if (this.__state.space !== 'RGB') { + recalculateRGB(this, component, componentHexIndex); + this.__state.space = 'RGB'; + } + + this.__state[component] = v; + + } + + }); + + } + + function defineHSVComponent(target, component) { + + Object.defineProperty(target, component, { + + get: function() { + + if (this.__state.space === 'HSV') + return this.__state[component]; + + recalculateHSV(this); + + return this.__state[component]; + + }, + + set: function(v) { + + if (this.__state.space !== 'HSV') { + recalculateHSV(this); + this.__state.space = 'HSV'; + } + + this.__state[component] = v; + + } + + }); + + } + + function recalculateRGB(color, component, componentHexIndex) { + + if (color.__state.space === 'HEX') { + + color.__state[component] = math.component_from_hex(color.__state.hex, componentHexIndex); + + } else if (color.__state.space === 'HSV') { + + common.extend(color.__state, math.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v)); + + } else { + + throw 'Corrupted color state'; + + } + + } + + function recalculateHSV(color) { + + var result = math.rgb_to_hsv(color.r, color.g, color.b); + + common.extend(color.__state, + { + s: result.s, + v: result.v + } + ); + + if (!common.isNaN(result.h)) { + color.__state.h = result.h; + } else if (common.isUndefined(color.__state.h)) { + color.__state.h = 0; + } + + } + + return Color; + +})(dat.color.interpret, +dat.color.math = (function () { + + var tmpComponent; + + return { + + hsv_to_rgb: function(h, s, v) { + + var hi = Math.floor(h / 60) % 6; + + var f = h / 60 - Math.floor(h / 60); + var p = v * (1.0 - s); + var q = v * (1.0 - (f * s)); + var t = v * (1.0 - ((1.0 - f) * s)); + var c = [ + [v, t, p], + [q, v, p], + [p, v, t], + [p, q, v], + [t, p, v], + [v, p, q] + ][hi]; + + return { + r: c[0] * 255, + g: c[1] * 255, + b: c[2] * 255 + }; + + }, + + rgb_to_hsv: function(r, g, b) { + + var min = Math.min(r, g, b), + max = Math.max(r, g, b), + delta = max - min, + h, s; + + if (max != 0) { + s = delta / max; + } else { + return { + h: NaN, + s: 0, + v: 0 + }; + } + + if (r == max) { + h = (g - b) / delta; + } else if (g == max) { + h = 2 + (b - r) / delta; + } else { + h = 4 + (r - g) / delta; + } + h /= 6; + if (h < 0) { + h += 1; + } + + return { + h: h * 360, + s: s, + v: max / 255 + }; + }, + + rgb_to_hex: function(r, g, b) { + var hex = this.hex_with_component(0, 2, r); + hex = this.hex_with_component(hex, 1, g); + hex = this.hex_with_component(hex, 0, b); + return hex; + }, + + component_from_hex: function(hex, componentIndex) { + return (hex >> (componentIndex * 8)) & 0xFF; + }, + + hex_with_component: function(hex, componentIndex, value) { + return value << (tmpComponent = componentIndex * 8) | (hex & ~ (0xFF << tmpComponent)); + } + + } + +})(), +dat.color.toString, +dat.utils.common), +dat.color.interpret, +dat.utils.common), +dat.utils.requestAnimationFrame = (function () { + + /** + * requirejs version of Paul Irish's RequestAnimationFrame + * http://paulirish.com/2011/requestanimationframe-for-smart-animating/ + */ + + return window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame || + window.msRequestAnimationFrame || + function(callback, element) { + + window.setTimeout(callback, 1000 / 60); + + }; +})(), +dat.dom.CenteredDiv = (function (dom, common) { + + + var CenteredDiv = function() { + + this.backgroundElement = document.createElement('div'); + common.extend(this.backgroundElement.style, { + backgroundColor: 'rgba(0,0,0,0.8)', + top: 0, + left: 0, + display: 'none', + zIndex: '1000', + opacity: 0, + WebkitTransition: 'opacity 0.2s linear' + }); + + dom.makeFullscreen(this.backgroundElement); + this.backgroundElement.style.position = 'fixed'; + + this.domElement = document.createElement('div'); + common.extend(this.domElement.style, { + position: 'fixed', + display: 'none', + zIndex: '1001', + opacity: 0, + WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear' + }); + + + document.body.appendChild(this.backgroundElement); + document.body.appendChild(this.domElement); + + var _this = this; + dom.bind(this.backgroundElement, 'click', function() { + _this.hide(); + }); + + + }; + + CenteredDiv.prototype.show = function() { + + var _this = this; + + + + this.backgroundElement.style.display = 'block'; + + this.domElement.style.display = 'block'; + this.domElement.style.opacity = 0; +// this.domElement.style.top = '52%'; + this.domElement.style.webkitTransform = 'scale(1.1)'; + + this.layout(); + + common.defer(function() { + _this.backgroundElement.style.opacity = 1; + _this.domElement.style.opacity = 1; + _this.domElement.style.webkitTransform = 'scale(1)'; + }); + + }; + + CenteredDiv.prototype.hide = function() { + + var _this = this; + + var hide = function() { + + _this.domElement.style.display = 'none'; + _this.backgroundElement.style.display = 'none'; + + dom.unbind(_this.domElement, 'webkitTransitionEnd', hide); + dom.unbind(_this.domElement, 'transitionend', hide); + dom.unbind(_this.domElement, 'oTransitionEnd', hide); + + }; + + dom.bind(this.domElement, 'webkitTransitionEnd', hide); + dom.bind(this.domElement, 'transitionend', hide); + dom.bind(this.domElement, 'oTransitionEnd', hide); + + this.backgroundElement.style.opacity = 0; +// this.domElement.style.top = '48%'; + this.domElement.style.opacity = 0; + this.domElement.style.webkitTransform = 'scale(1.1)'; + + }; + + CenteredDiv.prototype.layout = function() { + this.domElement.style.left = window.innerWidth/2 - dom.getWidth(this.domElement) / 2 + 'px'; + this.domElement.style.top = window.innerHeight/2 - dom.getHeight(this.domElement) / 2 + 'px'; + }; + + function lockScroll(e) { + console.log(e); + } + + return CenteredDiv; + +})(dat.dom.dom, +dat.utils.common), +dat.dom.dom, +dat.utils.common); From d609c24bfb0320f41e09103efa64d0a5aeada286 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 11 Jul 2014 22:15:36 +0200 Subject: [PATCH 40/53] ENH: Added command to see which tracts have been calculated on the web interface --- tract_querier/tornado_server/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tract_querier/tornado_server/__init__.py b/tract_querier/tornado_server/__init__.py index a6ead0f..9fa9b84 100644 --- a/tract_querier/tornado_server/__init__.py +++ b/tract_querier/tornado_server/__init__.py @@ -101,6 +101,10 @@ def post(self): for client in self.websocket_clients: client.write_message(action_json) + elif decoded_args['method'] == 'list': + result = '' + for k in self.file_handler.tract_name_file: + result += k + '\n' else: if decoded_args['method'] == 'show': decoded_args['method'] = 'save' From 6d103aae91789e296c90f6e60840840a8a4fb5e1 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Sat, 12 Jul 2014 08:46:06 +0200 Subject: [PATCH 41/53] ENH: Viewer improvements --- .../tornado_server/FreeSurferColorLUT.txt | 1274 ++++++++--------- tract_querier/tornado_server/css/viewer.css | 36 +- tract_querier/tornado_server/index.html | 7 +- tract_querier/tornado_server/js/wmqlviz.js | 32 +- 4 files changed, 680 insertions(+), 669 deletions(-) diff --git a/tract_querier/tornado_server/FreeSurferColorLUT.txt b/tract_querier/tornado_server/FreeSurferColorLUT.txt index d42b3af..e9d880a 100644 --- a/tract_querier/tornado_server/FreeSurferColorLUT.txt +++ b/tract_querier/tornado_server/FreeSurferColorLUT.txt @@ -1,158 +1,158 @@ #$Id: FreeSurferColorLUT.txt,v 1.15.2.4 2006/05/22 17:32:14 greve Exp $ 0 Unknown 0 0 0 0 -1 Left-Cerebral-Exterior 205 62 78 255 -2 Left-Cerebral-White-Matter 245 245 245 255 -3 Left-Cerebral-Cortex 205 62 78 255 -4 Left-Lateral-Ventricle 120 18 134 255 -5 Left-Inf-Lat-Vent 196 58 250 255 -6 Left-Cerebellum-Exterior 0 148 0 255 -7 Left-Cerebellum-White-Matter 220 248 164 255 -8 Left-Cerebellum-Cortex 230 148 34 255 -9 Left-Thalamus 0 118 14 255 -10 Left-Thalamus-Proper 0 118 14 255 -11 Left-Caudate 122 186 220 255 -12 Left-Putamen 236 13 176 255 -13 Left-Pallidum 12 48 255 255 -14 3rd-Ventricle 204 182 142 255 -15 4th-Ventricle 42 204 164 255 -16 Brain-Stem 119 159 176 255 -17 Left-Hippocampus 220 216 20 255 -18 Left-Amygdala 103 255 255 255 -19 Left-Insula 80 196 98 255 -20 Left-Operculum 60 58 210 255 -21 Line-1 60 58 210 255 -22 Line-2 60 58 210 255 -23 Line-3 60 58 210 255 +1 Cerebral_Exterior.left 205 62 78 255 +2 Cerebral_White_Matter.left 245 245 245 255 +3 Cerebral_Cortex.left 205 62 78 255 +4 Lateral_Ventricle.left 120 18 134 255 +5 Inf_Lat_Vent.left 196 58 250 255 +6 Cerebellum_Exterior.left 0 148 0 255 +7 Cerebellum_White_Matter.left 220 248 164 255 +8 Cerebellum_Cortex.left 230 148 34 255 +9 Thalamus.left 0 118 14 255 +10 Thalamus_Proper.left 0 118 14 255 +11 Caudate.left 122 186 220 255 +12 Putamen.left 236 13 176 255 +13 Pallidum.left 12 48 255 255 +14 3rd_Ventricle 204 182 142 255 +15 4th_Ventricle 42 204 164 255 +16 Brain_Stem 119 159 176 255 +17 Hippocampus.left 220 216 20 255 +18 Amygdala.left 103 255 255 255 +19 Insula.left 80 196 98 255 +20 Operculum.left 60 58 210 255 +21 Line_1 60 58 210 255 +22 Line_2 60 58 210 255 +23 Line_3 60 58 210 255 24 CSF 60 60 60 255 -25 Left-Lesion 255 165 0 255 -26 Left-Accumbens-area 255 165 0 255 -27 Left-Substancia-Nigra 0 255 127 255 -28 Left-VentralDC 165 42 42 255 -29 Left-undetermined 135 206 235 255 -30 Left-vessel 160 32 240 255 -31 Left-choroid-plexus 0 200 200 255 -32 Left-F3orb 100 50 100 255 -33 Left-lOg 135 50 74 255 -34 Left-aOg 122 135 50 255 -35 Left-mOg 51 50 135 255 -36 Left-pOg 74 155 60 255 -37 Left-Stellate 120 62 43 255 -38 Left-Porg 74 155 60 255 -39 Left-Aorg 122 135 50 255 -40 Right-Cerebral-Exterior 205 62 78 255 -41 Right-Cerebral-White-Matter 0 225 0 255 -42 Right-Cerebral-Cortex 205 62 78 255 -43 Right-Lateral-Ventricle 120 18 134 255 -44 Right-Inf-Lat-Vent 196 58 250 255 -45 Right-Cerebellum-Exterior 0 148 0 255 -46 Right-Cerebellum-White-Matter 220 248 164 255 -47 Right-Cerebellum-Cortex 230 148 34 255 -48 Right-Thalamus 0 118 14 255 -49 Right-Thalamus-Proper 0 118 14 255 -50 Right-Caudate 122 186 220 255 -51 Right-Putamen 236 13 176 255 -52 Right-Pallidum 13 48 255 255 -53 Right-Hippocampus 220 216 20 255 -54 Right-Amygdala 103 255 255 255 -55 Right-Insula 80 196 98 255 -56 Right-Operculum 60 58 210 255 -57 Right-Lesion 255 165 0 255 -58 Right-Accumbens-area 255 165 0 255 -59 Right-Substancia-Nigra 0 255 127 255 -60 Right-VentralDC 165 42 42 255 -61 Right-undetermined 135 206 235 255 -62 Right-vessel 160 32 240 255 -63 Right-choroid-plexus 0 200 221 255 -64 Right-F3orb 100 50 100 255 -65 Right-lOg 135 50 74 255 -66 Right-aOg 122 135 50 255 -67 Right-mOg 51 50 135 255 -68 Right-pOg 74 155 60 255 -69 Right-Stellate 120 62 43 255 -70 Right-Porg 74 155 60 255 -71 Right-Aorg 122 135 50 255 -72 5th-Ventricle 120 190 150 255 -73 Left-Interior 122 135 50 255 -74 Right-Interior 122 135 50 255 -75 Left-Lateral-Ventricles 120 18 134 255 -76 Right-Lateral-Ventricles 120 18 134 255 -77 WM-hypointensities 200 70 255 255 -78 Left-WM-hypointensities 255 148 10 255 -79 Right-WM-hypointensities 255 148 10 255 -80 non-WM-hypointensities 164 108 226 255 -81 Left-non-WM-hypointensities 164 108 226 255 -82 Right-non-WM-hypointensities 164 108 226 255 -83 Left-F1 255 218 185 255 -84 Right-F1 255 218 185 255 -85 Optic-Chiasm 234 169 30 255 +25 Lesion.left 255 165 0 255 +26 Accumbens_area.left 255 165 0 255 +27 Substancia_Nigra.left 0 255 127 255 +28 VentralDC.left 165 42 42 255 +29 undetermined.left 135 206 235 255 +30 vessel.left 160 32 240 255 +31 choroid_plexus.left 0 200 200 255 +32 F.left3orb 100 50 100 255 +33 lOg.left 135 50 74 255 +34 aOg.left 122 135 50 255 +35 mOg.left 51 50 135 255 +36 pOg.left 74 155 60 255 +37 Stellate.left 120 62 43 255 +38 Porg.left 74 155 60 255 +39 Aorg.left 122 135 50 255 +40 Cerebral_Exterior.right 205 62 78 255 +41 Cerebral_White_Matter.right 0 225 0 255 +42 Cerebral_Cortex.right 205 62 78 255 +43 Lateral_Ventricle.right 120 18 134 255 +44 Inf_Lat_Vent.right 196 58 250 255 +45 Cerebellum_Exterior.right 0 148 0 255 +46 Cerebellum_White_Matter.right 220 248 164 255 +47 Cerebellum_Cortex.right 230 148 34 255 +48 Thalamus.right 0 118 14 255 +49 Thalamus_Proper.right 0 118 14 255 +50 Caudate.right 122 186 220 255 +51 Putamen.right 236 13 176 255 +52 Pallidum.right 13 48 255 255 +53 Hippocampus.right 220 216 20 255 +54 Amygdala.right 103 255 255 255 +55 Insula.right 80 196 98 255 +56 Operculum.right 60 58 210 255 +57 Lesion.right 255 165 0 255 +58 Accumbens_area.right 255 165 0 255 +59 Substancia_Nigra.right 0 255 127 255 +60 VentralDC.right 165 42 42 255 +61 undetermined.right 135 206 235 255 +62 vessel.right 160 32 240 255 +63 choroid_plexus.right 0 200 221 255 +64 F.right3orb 100 50 100 255 +65 lOg.right 135 50 74 255 +66 aOg.right 122 135 50 255 +67 mOg.right 51 50 135 255 +68 pOg.right 74 155 60 255 +69 Stellate.right 120 62 43 255 +70 Porg.right 74 155 60 255 +71 Aorg.right 122 135 50 255 +72 5th_Ventricle 120 190 150 255 +73 Interior.left 122 135 50 255 +74 Interior.right 122 135 50 255 +75 Lateral_Ventricles.left 120 18 134 255 +76 Lateral_Ventricles.right 120 18 134 255 +77 WM_hypointensities 200 70 255 255 +78 WM_hypointensities.left 255 148 10 255 +79 WM_hypointensities.right 255 148 10 255 +80 non_WM_hypointensities 164 108 226 255 +81 non_WM_hypointensities.left 164 108 226 255 +82 non_WM_hypointensities.right 164 108 226 255 +83 F.left1 255 218 185 255 +84 F.right1 255 218 185 255 +85 Optic_Chiasm 234 169 30 255 86 Corpus_Callosum 250 255 50 255 -96 Left-Amygdala-Anterior 205 10 125 255 -97 Right-Amygdala-Anterior 205 10 125 255 +96 Amygdala_Anterior.left 205 10 125 255 +97 Amygdala_Anterior.right 205 10 125 255 98 Dura 160 32 240 255 -100 Left-wm-intensity-abnormality 124 140 178 255 -101 Left-caudate-intensity-abnormality 125 140 178 255 -102 Left-putamen-intensity-abnormality 126 140 178 255 -103 Left-accumbens-intensity-abnormality 127 140 178 255 -104 Left-pallidum-intensity-abnormality 124 141 178 255 -105 Left-amygdala-intensity-abnormality 124 142 178 255 -106 Left-hippocampus-intensity-abnormality 124 143 178 255 -107 Left-thalamus-intensity-abnormality 124 144 178 255 -108 Left-VDC-intensity-abnormality 124 140 179 255 -109 Right-wm-intensity-abnormality 124 140 178 255 -110 Right-caudate-intensity-abnormality 125 140 178 255 -111 Right-putamen-intensity-abnormality 126 140 178 255 -112 Right-accumbens-intensity-abnormality 127 140 178 255 -113 Right-pallidum-intensity-abnormality 124 141 178 255 -114 Right-amygdala-intensity-abnormality 124 142 178 255 -115 Right-hippocampus-intensity-abnormality 124 143 178 255 -116 Right-thalamus-intensity-abnormality 124 144 178 255 -117 Right-VDC-intensity-abnormality 124 140 179 255 +100 wm_intensity_abnormality.left 124 140 178 255 +101 caudate_intensity_abnormality.left 125 140 178 255 +102 putamen_intensity_abnormality.left 126 140 178 255 +103 accumbens_intensity_abnormality.left 127 140 178 255 +104 pallidum_intensity_abnormality.left 124 141 178 255 +105 amygdala_intensity_abnormality.left 124 142 178 255 +106 hippocampus_intensity_abnormality.left 124 143 178 255 +107 thalamus_intensity_abnormality.left 124 144 178 255 +108 VDC_intensity_abnormality.left 124 140 179 255 +109 wm_intensity_abnormality.right 124 140 178 255 +110 caudate_intensity_abnormality.right 125 140 178 255 +111 putamen_intensity_abnormality.right 126 140 178 255 +112 accumbens_intensity_abnormality.right 127 140 178 255 +113 pallidum_intensity_abnormality.right 124 141 178 255 +114 amygdala_intensity_abnormality.right 124 142 178 255 +115 hippocampus_intensity_abnormality.right 124 143 178 255 +116 thalamus_intensity_abnormality.right 124 144 178 255 +117 VDC_intensity_abnormality.right 124 140 179 255 118 Epidermis 255 20 147 255 -119 Conn-Tissue 205 179 139 255 -120 SC-Fat/Muscle 238 238 209 255 +119 Conn_Tissue 205 179 139 255 +120 SC_Fat/Muscle 238 238 209 255 121 Cranium 200 200 200 255 -122 CSF-SA 74 255 74 255 +122 CSF_SA 74 255 74 255 123 Muscle 238 0 0 255 124 Ear 0 0 139 255 125 Adipose 173 255 47 255 -126 Spinal-Cord 133 203 229 255 -127 Soft-Tissue 26 237 57 255 +126 Spinal_Cord 133 203 229 255 +127 Soft_Tissue 26 237 57 255 128 Nerve 34 139 34 255 129 Bone 30 144 255 255 130 Air 147 19 173 255 -131 Orbital-Fat 238 59 59 255 +131 Orbital_Fat 238 59 59 255 132 Tongue 221 39 200 255 -133 Nasal-Structures 238 174 238 255 +133 Nasal_Structures 238 174 238 255 134 Globe 255 0 0 255 135 Teeth 72 61 139 255 -136 Left-Caudate/Putamen 21 39 132 255 -137 Right-Caudate/Putamen 21 39 132 255 -138 Left-Claustrum 65 135 20 255 -139 Right-Claustrum 65 135 20 255 +136 Caudate.left/Putamen 21 39 132 255 +137 Caudate.right/Putamen 21 39 132 255 +138 Claustrum.left 65 135 20 255 +139 Claustrum.right 65 135 20 255 140 Cornea 134 4 160 255 142 Diploe 221 226 68 255 -143 Vitreous-Humor 255 255 254 255 +143 Vitreous_Humor 255 255 254 255 144 Lens 52 209 226 255 -145 Aqueous-Humor 239 160 223 255 -146 Outer-Table 70 130 180 255 -147 Inner-Table 70 130 181 255 +145 Aqueous_Humor 239 160 223 255 +146 Outer_Table 70 130 180 255 +147 Inner_Table 70 130 181 255 148 Periosteum 139 121 94 255 149 Endosteum 224 224 224 255 150 R/C/S 255 0 0 255 151 Iris 205 205 0 255 -152 SC-Adipose/Muscle 238 238 209 255 -153 SC-Tissue 139 121 94 255 -154 Orbital-Adipose 238 59 59 255 +152 SC_Adipose/Muscle 238 238 209 255 +153 SC_Tissue 139 121 94 255 +154 Orbital_Adipose 238 59 59 255 -193 Left-hippocampal_fissure 0 196 255 255 -194 Left-CADG-head 255 164 164 255 -195 Left-subiculum 196 196 0 255 -196 Left-fimbria 0 100 255 255 -197 Right-hippocampal_fissure 128 196 164 255 -198 Right-CADG-head 0 126 75 255 -199 Right-subiculum 128 96 64 255 -200 Right-fimbria 0 50 128 255 +193 hippocampal_fissure.left 0 196 255 255 +194 CADG_head.left 255 164 164 255 +195 subiculum.left 196 196 0 255 +196 fimbria.left 0 100 255 255 +197 hippocampal_fissure.right 128 196 164 255 +198 CADG_head.right 0 126 75 255 +199 subiculum.right 128 96 64 255 +200 fimbria.right 0 50 128 255 201 alveus 255 204 153 255 202 perforant_pathway 255 128 128 255 203 parasubiculum 255 255 0 255 @@ -162,7 +162,7 @@ 207 CA2 128 128 255 255 208 CA3 0 128 0 255 209 CA4 196 160 128 255 -210 GC-DG 32 200 255 255 +210 GC_DG 32 200 255 255 211 HATA 128 255 128 255 212 fimbria 204 153 204 255 213 lateral_ventricle 121 17 136 255 @@ -182,34 +182,34 @@ # lymph node and vascular labels 331 Aorta 255 0 0 255 -332 Left-Common-IliacA 255 80 0 255 -333 Right-Common-IliacA 255 160 0 255 -334 Left-External-IliacA 255 255 0 255 -335 Right-External-IliacA 0 255 0 255 -336 Left-Internal-IliacA 255 0 160 255 -337 Right-Internal-IliacA 255 0 255 255 -338 Left-Lateral-SacralA 255 50 80 255 -339 Right-Lateral-SacralA 80 255 50 255 -340 Left-ObturatorA 160 255 50 255 -341 Right-ObturatorA 160 200 255 255 -342 Left-Internal-PudendalA 0 255 160 255 -343 Right-Internal-PudendalA 0 0 255 255 -344 Left-UmbilicalA 80 50 255 255 -345 Right-UmbilicalA 160 0 255 255 -346 Left-Inf-RectalA 255 210 0 255 -347 Right-Inf-RectalA 0 160 255 255 -348 Left-Common-IliacV 255 200 80 255 -349 Right-Common-IliacV 255 200 160 255 -350 Left-External-IliacV 255 80 200 255 -351 Right-External-IliacV 255 160 200 255 -352 Left-Internal-IliacV 30 255 80 255 -353 Right-Internal-IliacV 80 200 255 255 -354 Left-ObturatorV 80 255 200 255 -355 Right-ObturatorV 195 255 200 255 -356 Left-Internal-PudendalV 120 200 20 255 -357 Right-Internal-PudendalV 170 10 200 255 -358 Pos-Lymph 20 130 180 255 -359 Neg-Lymph 20 180 130 255 +332 Common_IliacA.left 255 80 0 255 +333 Common_IliacA.right 255 160 0 255 +334 External_IliacA.left 255 255 0 255 +335 External_IliacA.right 0 255 0 255 +336 Internal_IliacA.left 255 0 160 255 +337 Internal_IliacA.right 255 0 255 255 +338 Lateral_SacralA.left 255 50 80 255 +339 Lateral_SacralA.right 80 255 50 255 +340 ObturatorA.left 160 255 50 255 +341 ObturatorA.right 160 200 255 255 +342 Internal_PudendalA.left 0 255 160 255 +343 Internal_PudendalA.right 0 0 255 255 +344 UmbilicalA.left 80 50 255 255 +345 UmbilicalA.right 160 0 255 255 +346 Inf_RectalA.left 255 210 0 255 +347 Inf_RectalA.right 0 160 255 255 +348 Common_IliacV.left 255 200 80 255 +349 Common_IliacV.right 255 200 160 255 +350 External_IliacV.left 255 80 200 255 +351 External_IliacV.right 255 160 200 255 +352 Internal_IliacV.left 30 255 80 255 +353 Internal_IliacV.right 80 200 255 255 +354 ObturatorV.left 80 255 200 255 +355 ObturatorV.right 195 255 200 255 +356 Internal_PudendalV.left 120 200 20 255 +357 Internal_PudendalV.right 170 10 200 255 +358 Pos_Lymph 20 130 180 255 +359 Neg_Lymph 20 180 130 255 400 V1 206 62 78 255 401 V2 121 18 134 255 @@ -229,500 +229,500 @@ # do not change from above. The cortical lables are the same as in # colortable_desikan_killiany.txt, except that left hemisphere has # 1000 added to the index and the right has 2000 added. The label -# names are also prepended with ctx-lh or ctx-rh. The white matter +# names are also prepended with ctx_lh or ctx_rh. The white matter # labels are the same as in colortable_desikan_killiany.txt, except # that left hemisphere has 3000 added to the index and the right has -# 4000 added. The label names are also prepended with wm-lh or wm-rh. +# 4000 added. The label names are also prepended with wm_lh or wm_rh. # Centrum semiovale is also labled with 5001 (left) and 5002 (right). # Even further below is the color table for aparc.a2005s. -1000 ctx-lh-unknown 25 5 25 255 -1001 ctx-lh-bankssts 25 100 40 255 -1002 ctx-lh-caudalanteriorcingulate 125 100 160 255 -1003 ctx-lh-caudalmiddlefrontal 100 25 0 255 -1004 ctx-lh-corpuscallosum 120 70 50 255 -1005 ctx-lh-cuneus 220 20 100 255 -1006 ctx-lh-entorhinal 220 20 10 255 -1007 ctx-lh-fusiform 180 220 140 255 -1008 ctx-lh-inferiorparietal 220 60 220 255 -1009 ctx-lh-inferiortemporal 180 40 120 255 -1010 ctx-lh-isthmuscingulate 140 20 140 255 -1011 ctx-lh-lateraloccipital 20 30 140 255 -1012 ctx-lh-lateralorbitofrontal 35 75 50 255 -1013 ctx-lh-lingual 225 140 140 255 -1014 ctx-lh-medialorbitofrontal 200 35 75 255 -1015 ctx-lh-middletemporal 160 100 50 255 -1016 ctx-lh-parahippocampal 20 220 60 255 -1017 ctx-lh-paracentral 60 220 60 255 -1018 ctx-lh-parsopercularis 220 180 140 255 -1019 ctx-lh-parsorbitalis 20 100 50 255 -1020 ctx-lh-parstriangularis 220 60 20 255 -1021 ctx-lh-pericalcarine 120 100 60 255 -1022 ctx-lh-postcentral 220 20 20 255 -1023 ctx-lh-posteriorcingulate 220 180 220 255 -1024 ctx-lh-precentral 60 20 220 255 -1025 ctx-lh-precuneus 160 140 180 255 -1026 ctx-lh-rostralanteriorcingulate 80 20 140 255 -1027 ctx-lh-rostralmiddlefrontal 75 50 125 255 -1028 ctx-lh-superiorfrontal 20 220 160 255 -1029 ctx-lh-superiorparietal 20 180 140 255 -1030 ctx-lh-superiortemporal 140 220 220 255 -1031 ctx-lh-supramarginal 80 160 20 255 -1032 ctx-lh-frontalpole 100 0 100 255 -1033 ctx-lh-temporalpole 70 70 70 255 -1034 ctx-lh-transversetemporal 150 150 200 255 -1035 ctx-lh-Insula 80 196 98 255 +1000 ctx_unknown.left 25 5 25 255 +1001 ctx_bankssts.left 25 100 40 255 +1002 ctx_caudalanteriorcingulate.left 125 100 160 255 +1003 ctx_caudalmiddlefrontal.left 100 25 0 255 +1004 ctx_corpuscallosum.left 120 70 50 255 +1005 ctx_cuneus.left 220 20 100 255 +1006 ctx_entorhinal.left 220 20 10 255 +1007 ctx_fusiform.left 180 220 140 255 +1008 ctx_inferiorparietal.left 220 60 220 255 +1009 ctx_inferiortemporal.left 180 40 120 255 +1010 ctx_isthmuscingulate.left 140 20 140 255 +1011 ctx_lateraloccipital.left 20 30 140 255 +1012 ctx_lateralorbitofrontal.left 35 75 50 255 +1013 ctx_lingual.left 225 140 140 255 +1014 ctx_medialorbitofrontal.left 200 35 75 255 +1015 ctx_middletemporal.left 160 100 50 255 +1016 ctx_parahippocampal.left 20 220 60 255 +1017 ctx_paracentral.left 60 220 60 255 +1018 ctx_parsopercularis.left 220 180 140 255 +1019 ctx_parsorbitalis.left 20 100 50 255 +1020 ctx_parstriangularis.left 220 60 20 255 +1021 ctx_pericalcarine.left 120 100 60 255 +1022 ctx_postcentral.left 220 20 20 255 +1023 ctx_posteriorcingulate.left 220 180 220 255 +1024 ctx_precentral.left 60 20 220 255 +1025 ctx_precuneus.left 160 140 180 255 +1026 ctx_rostralanteriorcingulate.left 80 20 140 255 +1027 ctx_rostralmiddlefrontal.left 75 50 125 255 +1028 ctx_superiorfrontal.left 20 220 160 255 +1029 ctx_superiorparietal.left 20 180 140 255 +1030 ctx_superiortemporal.left 140 220 220 255 +1031 ctx_supramarginal.left 80 160 20 255 +1032 ctx_frontalpole.left 100 0 100 255 +1033 ctx_temporalpole.left 70 70 70 255 +1034 ctx_transversetemporal.left 150 150 200 255 +1035 ctx_Insula.left 80 196 98 255 -2000 ctx-rh-unknown 25 5 25 255 -2001 ctx-rh-bankssts 25 100 40 255 -2002 ctx-rh-caudalanteriorcingulate 125 100 160 255 -2003 ctx-rh-caudalmiddlefrontal 100 25 0 255 -2004 ctx-rh-corpuscallosum 120 70 50 255 -2005 ctx-rh-cuneus 220 20 100 255 -2006 ctx-rh-entorhinal 220 20 10 255 -2007 ctx-rh-fusiform 180 220 140 255 -2008 ctx-rh-inferiorparietal 220 60 220 255 -2009 ctx-rh-inferiortemporal 180 40 120 255 -2010 ctx-rh-isthmuscingulate 140 20 140 255 -2011 ctx-rh-lateraloccipital 20 30 140 255 -2012 ctx-rh-lateralorbitofrontal 35 75 50 255 -2013 ctx-rh-lingual 225 140 140 255 -2014 ctx-rh-medialorbitofrontal 200 35 75 255 -2015 ctx-rh-middletemporal 160 100 50 255 -2016 ctx-rh-parahippocampal 20 220 60 255 -2017 ctx-rh-paracentral 60 220 60 255 -2018 ctx-rh-parsopercularis 220 180 140 255 -2019 ctx-rh-parsorbitalis 20 100 50 255 -2020 ctx-rh-parstriangularis 220 60 20 255 -2021 ctx-rh-pericalcarine 120 100 60 255 -2022 ctx-rh-postcentral 220 20 20 255 -2023 ctx-rh-posteriorcingulate 220 180 220 255 -2024 ctx-rh-precentral 60 20 220 255 -2025 ctx-rh-precuneus 160 140 180 255 -2026 ctx-rh-rostralanteriorcingulate 80 20 140 255 -2027 ctx-rh-rostralmiddlefrontal 75 50 125 255 -2028 ctx-rh-superiorfrontal 20 220 160 255 -2029 ctx-rh-superiorparietal 20 180 140 255 -2030 ctx-rh-superiortemporal 140 220 220 255 -2031 ctx-rh-supramarginal 80 160 20 255 -2032 ctx-rh-frontalpole 100 0 100 255 -2033 ctx-rh-temporalpole 70 70 70 255 -2034 ctx-rh-transversetemporal 150 150 200 255 -2035 ctx-rh-Insula 80 196 98 255 +2000 ctx_unknown.right 25 5 25 255 +2001 ctx_bankssts.right 25 100 40 255 +2002 ctx_caudalanteriorcingulate.right 125 100 160 255 +2003 ctx_caudalmiddlefrontal.right 100 25 0 255 +2004 ctx_corpuscallosum.right 120 70 50 255 +2005 ctx_cuneus.right 220 20 100 255 +2006 ctx_entorhinal.right 220 20 10 255 +2007 ctx_fusiform.right 180 220 140 255 +2008 ctx_inferiorparietal.right 220 60 220 255 +2009 ctx_inferiortemporal.right 180 40 120 255 +2010 ctx_isthmuscingulate.right 140 20 140 255 +2011 ctx_lateraloccipital.right 20 30 140 255 +2012 ctx_lateralorbitofrontal.right 35 75 50 255 +2013 ctx_lingual.right 225 140 140 255 +2014 ctx_medialorbitofrontal.right 200 35 75 255 +2015 ctx_middletemporal.right 160 100 50 255 +2016 ctx_parahippocampal.right 20 220 60 255 +2017 ctx_paracentral.right 60 220 60 255 +2018 ctx_parsopercularis.right 220 180 140 255 +2019 ctx_parsorbitalis.right 20 100 50 255 +2020 ctx_parstriangularis.right 220 60 20 255 +2021 ctx_pericalcarine.right 120 100 60 255 +2022 ctx_postcentral.right 220 20 20 255 +2023 ctx_posteriorcingulate.right 220 180 220 255 +2024 ctx_precentral.right 60 20 220 255 +2025 ctx_precuneus.right 160 140 180 255 +2026 ctx_rostralanteriorcingulate.right 80 20 140 255 +2027 ctx_rostralmiddlefrontal.right 75 50 125 255 +2028 ctx_superiorfrontal.right 20 220 160 255 +2029 ctx_superiorparietal.right 20 180 140 255 +2030 ctx_superiortemporal.right 140 220 220 255 +2031 ctx_supramarginal.right 80 160 20 255 +2032 ctx_frontalpole.right 100 0 100 255 +2033 ctx_temporalpole.right 70 70 70 255 +2034 ctx_transversetemporal.right 150 150 200 255 +2035 ctx_Insula.right 80 196 98 255 -3000 wm-lh-unknown 230 250 230 255 -3001 wm-lh-bankssts 230 155 215 255 -3002 wm-lh-caudalanteriorcingulate 130 155 95 255 -3003 wm-lh-caudalmiddlefrontal 155 230 255 255 -3004 wm-lh-corpuscallosum 135 185 205 255 -3005 wm-lh-cuneus 35 235 155 255 -3006 wm-lh-entorhinal 35 235 245 255 -3007 wm-lh-fusiform 75 35 115 255 -3008 wm-lh-inferiorparietal 35 195 35 255 -3009 wm-lh-inferiortemporal 75 215 135 255 -3010 wm-lh-isthmuscingulate 115 235 115 255 -3011 wm-lh-lateraloccipital 235 225 115 255 -3012 wm-lh-lateralorbitofrontal 220 180 205 255 -3013 wm-lh-lingual 30 115 115 255 -3014 wm-lh-medialorbitofrontal 55 220 180 255 -3015 wm-lh-middletemporal 95 155 205 255 -3016 wm-lh-parahippocampal 235 35 195 255 -3017 wm-lh-paracentral 195 35 195 255 -3018 wm-lh-parsopercularis 35 75 115 255 -3019 wm-lh-parsorbitalis 235 155 205 255 -3020 wm-lh-parstriangularis 35 195 235 255 -3021 wm-lh-pericalcarine 135 155 195 255 -3022 wm-lh-postcentral 35 235 235 255 -3023 wm-lh-posteriorcingulate 35 75 35 255 -3024 wm-lh-precentral 195 235 35 255 -3025 wm-lh-precuneus 95 115 75 255 -3026 wm-lh-rostralanteriorcingulate 175 235 115 255 -3027 wm-lh-rostralmiddlefrontal 180 205 130 255 -3028 wm-lh-superiorfrontal 235 35 95 255 -3029 wm-lh-superiorparietal 235 75 115 255 -3030 wm-lh-superiortemporal 115 35 35 255 -3031 wm-lh-supramarginal 175 95 235 255 -3032 wm-lh-frontalpole 155 255 155 255 -3033 wm-lh-temporalpole 185 185 185 255 -3034 wm-lh-transversetemporal 105 105 55 255 -3035 wm-lh-Insula 80 196 98 255 +3000 wm_unknown.left 230 250 230 255 +3001 wm_bankssts.left 230 155 215 255 +3002 wm_caudalanteriorcingulate.left 130 155 95 255 +3003 wm_caudalmiddlefrontal.left 155 230 255 255 +3004 wm_corpuscallosum.left 135 185 205 255 +3005 wm_cuneus.left 35 235 155 255 +3006 wm_entorhinal.left 35 235 245 255 +3007 wm_fusiform.left 75 35 115 255 +3008 wm_inferiorparietal.left 35 195 35 255 +3009 wm_inferiortemporal.left 75 215 135 255 +3010 wm_isthmuscingulate.left 115 235 115 255 +3011 wm_lateraloccipital.left 235 225 115 255 +3012 wm_lateralorbitofrontal.left 220 180 205 255 +3013 wm_lingual.left 30 115 115 255 +3014 wm_medialorbitofrontal.left 55 220 180 255 +3015 wm_middletemporal.left 95 155 205 255 +3016 wm_parahippocampal.left 235 35 195 255 +3017 wm_paracentral.left 195 35 195 255 +3018 wm_parsopercularis.left 35 75 115 255 +3019 wm_parsorbitalis.left 235 155 205 255 +3020 wm_parstriangularis.left 35 195 235 255 +3021 wm_pericalcarine.left 135 155 195 255 +3022 wm_postcentral.left 35 235 235 255 +3023 wm_posteriorcingulate.left 35 75 35 255 +3024 wm_precentral.left 195 235 35 255 +3025 wm_precuneus.left 95 115 75 255 +3026 wm_rostralanteriorcingulate.left 175 235 115 255 +3027 wm_rostralmiddlefrontal.left 180 205 130 255 +3028 wm_superiorfrontal.left 235 35 95 255 +3029 wm_superiorparietal.left 235 75 115 255 +3030 wm_superiortemporal.left 115 35 35 255 +3031 wm_supramarginal.left 175 95 235 255 +3032 wm_frontalpole.left 155 255 155 255 +3033 wm_temporalpole.left 185 185 185 255 +3034 wm_transversetemporal.left 105 105 55 255 +3035 wm_Insula.left 80 196 98 255 -4000 wm-rh-unknown 230 250 230 255 -4001 wm-rh-bankssts 230 155 215 255 -4002 wm-rh-caudalanteriorcingulate 130 155 95 255 -4003 wm-rh-caudalmiddlefrontal 155 230 255 255 -4004 wm-rh-corpuscallosum 135 185 205 255 -4005 wm-rh-cuneus 35 235 155 255 -4006 wm-rh-entorhinal 35 235 245 255 -4007 wm-rh-fusiform 75 35 115 255 -4008 wm-rh-inferiorparietal 35 195 35 255 -4009 wm-rh-inferiortemporal 75 215 135 255 -4010 wm-rh-isthmuscingulate 115 235 115 255 -4011 wm-rh-lateraloccipital 235 225 115 255 -4012 wm-rh-lateralorbitofrontal 220 180 205 255 -4013 wm-rh-lingual 30 115 115 255 -4014 wm-rh-medialorbitofrontal 55 220 180 255 -4015 wm-rh-middletemporal 95 155 205 255 -4016 wm-rh-parahippocampal 235 35 195 255 -4017 wm-rh-paracentral 195 35 195 255 -4018 wm-rh-parsopercularis 35 75 115 255 -4019 wm-rh-parsorbitalis 235 155 205 255 -4020 wm-rh-parstriangularis 35 195 235 255 -4021 wm-rh-pericalcarine 135 155 195 255 -4022 wm-rh-postcentral 35 235 235 255 -4023 wm-rh-posteriorcingulate 35 75 35 255 -4024 wm-rh-precentral 195 235 35 255 -4025 wm-rh-precuneus 95 115 75 255 -4026 wm-rh-rostralanteriorcingulate 175 235 115 255 -4027 wm-rh-rostralmiddlefrontal 180 205 130 255 -4028 wm-rh-superiorfrontal 235 35 95 255 -4029 wm-rh-superiorparietal 235 75 115 255 -4030 wm-rh-superiortemporal 115 35 35 255 -4031 wm-rh-supramarginal 175 95 235 255 -4032 wm-rh-frontalpole 155 255 155 255 -4033 wm-rh-temporalpole 185 185 185 255 -4034 wm-rh-transversetemporal 105 105 55 255 -4035 wm-rh-Insula 80 196 98 255 +4000 wm_unknown.right 230 250 230 255 +4001 wm_bankssts.right 230 155 215 255 +4002 wm_caudalanteriorcingulate.right 130 155 95 255 +4003 wm_caudalmiddlefrontal.right 155 230 255 255 +4004 wm_corpuscallosum.right 135 185 205 255 +4005 wm_cuneus.right 35 235 155 255 +4006 wm_entorhinal.right 35 235 245 255 +4007 wm_fusiform.right 75 35 115 255 +4008 wm_inferiorparietal.right 35 195 35 255 +4009 wm_inferiortemporal.right 75 215 135 255 +4010 wm_isthmuscingulate.right 115 235 115 255 +4011 wm_lateraloccipital.right 235 225 115 255 +4012 wm_lateralorbitofrontal.right 220 180 205 255 +4013 wm_lingual.right 30 115 115 255 +4014 wm_medialorbitofrontal.right 55 220 180 255 +4015 wm_middletemporal.right 95 155 205 255 +4016 wm_parahippocampal.right 235 35 195 255 +4017 wm_paracentral.right 195 35 195 255 +4018 wm_parsopercularis.right 35 75 115 255 +4019 wm_parsorbitalis.right 235 155 205 255 +4020 wm_parstriangularis.right 35 195 235 255 +4021 wm_pericalcarine.right 135 155 195 255 +4022 wm_postcentral.right 35 235 235 255 +4023 wm_posteriorcingulate.right 35 75 35 255 +4024 wm_precentral.right 195 235 35 255 +4025 wm_precuneus.right 95 115 75 255 +4026 wm_rostralanteriorcingulate.right 175 235 115 255 +4027 wm_rostralmiddlefrontal.right 180 205 130 255 +4028 wm_superiorfrontal.right 235 35 95 255 +4029 wm_superiorparietal.right 235 75 115 255 +4030 wm_superiortemporal.right 115 35 35 255 +4031 wm_supramarginal.right 175 95 235 255 +4032 wm_frontalpole.right 155 255 155 255 +4033 wm_temporalpole.right 185 185 185 255 +4034 wm_transversetemporal.right 105 105 55 255 +4035 wm_Insula.right 80 196 98 255 -5001 wm-lh-centrum-semiovale 20 30 40 255 -5002 wm-rh-centrum-semiovale 20 30 40 255 +5001 wm_centrum_semiovale.left 20 30 40 255 +5002 wm_centrum_semiovale.right 20 30 40 255 # Below is the color table for the cortical labels of the seg volume -# created by mri_aparc2aseg (with --a2005 flag) in which the aseg +# created by mri_aparc2aseg (with _a2005 flag) in which the aseg # cortex label is replaced by the labels in the aparc.a2005. The # cortical lables are the same as in Simple_surface_labels2005.txt, # except that left hemisphere has 1100 added to the index and the # right has 2100 added. The label names are also prepended with -# ctx-lh or ctx-rh. +# ctx_lh or ctx_rh. -1100 ctx-lh-Unknown 0 0 0 255 -1101 ctx-lh-Corpus_callosum 50 50 50 255 -1102 ctx-lh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 255 -1103 ctx-lh-G_cingulate-Isthmus 60 25 25 255 -1104 ctx-lh-G_cingulate-Main_part 25 60 60 255 -1105 ctx-lh-G_cuneus 180 20 20 255 -1106 ctx-lh-G_frontal_inf-Opercular_part 220 20 100 255 -1107 ctx-lh-G_frontal_inf-Orbital_part 140 60 60 255 -1108 ctx-lh-G_frontal_inf-Triangular_part 180 220 140 255 -1109 ctx-lh-G_frontal_middle 140 100 180 255 -1110 ctx-lh-G_frontal_superior 180 20 140 255 -1111 ctx-lh-G_frontomarginal 140 20 140 255 -1112 ctx-lh-G_insular_long 21 10 10 255 -1113 ctx-lh-G_insular_short 225 140 140 255 -1114 ctx-lh-G_and_S_occipital_inferior 23 60 180 255 -1115 ctx-lh-G_occipital_middle 180 60 180 255 -1116 ctx-lh-G_occipital_superior 20 220 60 255 -1117 ctx-lh-G_occipit-temp_lat-Or_fusiform 60 20 140 255 -1118 ctx-lh-G_occipit-temp_med-Lingual_part 220 180 140 255 -1119 ctx-lh-G_occipit-temp_med-Parahippocampal_part 65 100 20 255 -1120 ctx-lh-G_orbital 220 60 20 255 -1121 ctx-lh-G_paracentral 60 100 60 255 -1122 ctx-lh-G_parietal_inferior-Angular_part 20 60 220 255 -1123 ctx-lh-G_parietal_inferior-Supramarginal_part 100 100 60 255 -1124 ctx-lh-G_parietal_superior 220 180 220 255 -1125 ctx-lh-G_postcentral 20 180 140 255 -1126 ctx-lh-G_precentral 60 140 180 255 -1127 ctx-lh-G_precuneus 25 20 140 255 -1128 ctx-lh-G_rectus 20 60 100 255 -1129 ctx-lh-G_subcallosal 60 220 20 255 -1130 ctx-lh-G_subcentral 60 20 220 255 -1131 ctx-lh-G_temporal_inferior 220 220 100 255 -1132 ctx-lh-G_temporal_middle 180 60 60 255 -1133 ctx-lh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 255 -1134 ctx-lh-G_temp_sup-Lateral_aspect 220 60 220 255 -1135 ctx-lh-G_temp_sup-Planum_polare 65 220 60 255 -1136 ctx-lh-G_temp_sup-Planum_tempolare 25 140 20 255 -1137 ctx-lh-G_and_S_transverse_frontopolar 13 0 250 255 -1138 ctx-lh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 255 -1139 ctx-lh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 255 -1140 ctx-lh-Lat_Fissure-post_sgt 61 60 100 255 -1141 ctx-lh-Medial_wall 25 25 25 255 -1142 ctx-lh-Pole_occipital 140 20 60 255 -1143 ctx-lh-Pole_temporal 220 180 20 255 -1144 ctx-lh-S_calcarine 63 180 180 255 -1145 ctx-lh-S_central 221 20 10 255 -1146 ctx-lh-S_central_insula 21 220 20 255 -1147 ctx-lh-S_cingulate-Main_part_and_Intracingulate 183 100 20 255 -1148 ctx-lh-S_cingulate-Marginalis_part 221 20 100 255 -1149 ctx-lh-S_circular_insula_anterior 221 60 140 255 -1150 ctx-lh-S_circular_insula_inferior 221 20 220 255 -1151 ctx-lh-S_circular_insula_superior 61 220 220 255 -1152 ctx-lh-S_collateral_transverse_ant 100 200 200 255 -1153 ctx-lh-S_collateral_transverse_post 10 200 200 255 -1154 ctx-lh-S_frontal_inferior 221 220 20 255 -1155 ctx-lh-S_frontal_middle 141 20 100 255 -1156 ctx-lh-S_frontal_superior 61 220 100 255 -1157 ctx-lh-S_frontomarginal 21 220 60 255 -1158 ctx-lh-S_intermedius_primus-Jensen 141 60 20 255 -1159 ctx-lh-S_intraparietal-and_Parietal_transverse 143 20 220 255 -1160 ctx-lh-S_occipital_anterior 61 20 180 255 -1161 ctx-lh-S_occipital_middle_and_Lunatus 101 60 220 255 -1162 ctx-lh-S_occipital_superior_and_transversalis 21 20 140 255 -1163 ctx-lh-S_occipito-temporal_lateral 221 140 20 255 -1164 ctx-lh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 255 -1165 ctx-lh-S_orbital-H_shapped 101 20 20 255 -1166 ctx-lh-S_orbital_lateral 221 100 20 255 -1167 ctx-lh-S_orbital_medial-Or_olfactory 181 200 20 255 -1168 ctx-lh-S_paracentral 21 180 140 255 -1169 ctx-lh-S_parieto_occipital 101 100 180 255 -1170 ctx-lh-S_pericallosal 181 220 20 255 -1171 ctx-lh-S_postcentral 21 140 200 255 -1172 ctx-lh-S_precentral-Inferior-part 21 20 240 255 -1173 ctx-lh-S_precentral-Superior-part 21 20 200 255 -1174 ctx-lh-S_subcentral_ant 61 180 60 255 -1175 ctx-lh-S_subcentral_post 61 180 250 255 -1176 ctx-lh-S_suborbital 21 20 60 255 -1177 ctx-lh-S_subparietal 101 60 60 255 -1178 ctx-lh-S_supracingulate 21 220 220 255 -1179 ctx-lh-S_temporal_inferior 21 180 180 255 -1180 ctx-lh-S_temporal_superior 223 220 60 255 -1181 ctx-lh-S_temporal_transverse 221 60 60 255 +1100 ctx_Unknown.left 0 0 0 255 +1101 ctx_Corpus_callosum.left 50 50 50 255 +1102 ctx_G_and_S_Insula_ONLY_AVERAGE.left 180 20 30 255 +1103 ctx_G_cingulate_Isthmus.left 60 25 25 255 +1104 ctx_G_cingulate_Main_part.left 25 60 60 255 +1105 ctx_G_cuneus.left 180 20 20 255 +1106 ctx_G_frontal_inf_Opercular_part.left 220 20 100 255 +1107 ctx_G_frontal_inf_Orbital_part.left 140 60 60 255 +1108 ctx_G_frontal_inf_Triangular_part.left 180 220 140 255 +1109 ctx_G_frontal_middle.left 140 100 180 255 +1110 ctx_G_frontal_superior.left 180 20 140 255 +1111 ctx_G_frontomarginal.left 140 20 140 255 +1112 ctx_G_insular_long.left 21 10 10 255 +1113 ctx_G_insular_short.left 225 140 140 255 +1114 ctx_G_and_S_occipital_inferior.left 23 60 180 255 +1115 ctx_G_occipital_middle.left 180 60 180 255 +1116 ctx_G_occipital_superior.left 20 220 60 255 +1117 ctx_G_occipit_temp_lat_Or_fusiform.left 60 20 140 255 +1118 ctx_G_occipit_temp_med_Lingual_part.left 220 180 140 255 +1119 ctx_G_occipit_temp_med_Parahippocampal_part.left 65 100 20 255 +1120 ctx_G_orbital.left 220 60 20 255 +1121 ctx_G_paracentral.left 60 100 60 255 +1122 ctx_G_parietal_inferior_Angular_part.left 20 60 220 255 +1123 ctx_G_parietal_inferior_Supramarginal_part.left 100 100 60 255 +1124 ctx_G_parietal_superior.left 220 180 220 255 +1125 ctx_G_postcentral.left 20 180 140 255 +1126 ctx_G_precentral.left 60 140 180 255 +1127 ctx_G_precuneus.left 25 20 140 255 +1128 ctx_G_rectus.left 20 60 100 255 +1129 ctx_G_subcallosal.left 60 220 20 255 +1130 ctx_G_subcentral.left 60 20 220 255 +1131 ctx_G_temporal_inferior.left 220 220 100 255 +1132 ctx_G_temporal_middle.left 180 60 60 255 +1133 ctx_G_temp_sup_G_temp_transv_and_interm_S.left 60 60 220 255 +1134 ctx_G_temp_sup_Lateral_aspect.left 220 60 220 255 +1135 ctx_G_temp_sup_Planum_polare.left 65 220 60 255 +1136 ctx_G_temp_sup_Planum_tempolare.left 25 140 20 255 +1137 ctx_G_and_S_transverse_frontopolar.left 13 0 250 255 +1138 ctx_Lat_Fissure_ant_sgt_ramus_horizontal.left 61 20 220 255 +1139 ctx_Lat_Fissure_ant_sgt_ramus_vertical.left 61 20 60 255 +1140 ctx_Lat_Fissure_post_sgt.left 61 60 100 255 +1141 ctx_Medial_wall.left 25 25 25 255 +1142 ctx_Pole_occipital.left 140 20 60 255 +1143 ctx_Pole_temporal.left 220 180 20 255 +1144 ctx_S_calcarine.left 63 180 180 255 +1145 ctx_S_central.left 221 20 10 255 +1146 ctx_S_central_insula.left 21 220 20 255 +1147 ctx_S_cingulate_Main_part_and_Intracingulate.left 183 100 20 255 +1148 ctx_S_cingulate_Marginalis_part.left 221 20 100 255 +1149 ctx_S_circular_insula_anterior.left 221 60 140 255 +1150 ctx_S_circular_insula_inferior.left 221 20 220 255 +1151 ctx_S_circular_insula_superior.left 61 220 220 255 +1152 ctx_S_collateral_transverse_ant.left 100 200 200 255 +1153 ctx_S_collateral_transverse_post.left 10 200 200 255 +1154 ctx_S_frontal_inferior.left 221 220 20 255 +1155 ctx_S_frontal_middle.left 141 20 100 255 +1156 ctx_S_frontal_superior.left 61 220 100 255 +1157 ctx_S_frontomarginal.left 21 220 60 255 +1158 ctx_S_intermedius_primus_Jensen.left 141 60 20 255 +1159 ctx_S_intraparietal_and_Parietal_transverse.left 143 20 220 255 +1160 ctx_S_occipital_anterior.left 61 20 180 255 +1161 ctx_S_occipital_middle_and_Lunatus.left 101 60 220 255 +1162 ctx_S_occipital_superior_and_transversalis.left 21 20 140 255 +1163 ctx_S_occipito_temporal_lateral.left 221 140 20 255 +1164 ctx_S_occipito_temporal_medial_and_S_Lingual.left 141 100 220 255 +1165 ctx_S_orbital_H_shapped.left 101 20 20 255 +1166 ctx_S_orbital_lateral.left 221 100 20 255 +1167 ctx_S_orbital_medial_Or_olfactory.left 181 200 20 255 +1168 ctx_S_paracentral.left 21 180 140 255 +1169 ctx_S_parieto_occipital.left 101 100 180 255 +1170 ctx_S_pericallosal.left 181 220 20 255 +1171 ctx_S_postcentral.left 21 140 200 255 +1172 ctx_S_precentral_Inferior_part.left 21 20 240 255 +1173 ctx_S_precentral_Superior_part.left 21 20 200 255 +1174 ctx_S_subcentral_ant.left 61 180 60 255 +1175 ctx_S_subcentral_post.left 61 180 250 255 +1176 ctx_S_suborbital.left 21 20 60 255 +1177 ctx_S_subparietal.left 101 60 60 255 +1178 ctx_S_supracingulate.left 21 220 220 255 +1179 ctx_S_temporal_inferior.left 21 180 180 255 +1180 ctx_S_temporal_superior.left 223 220 60 255 +1181 ctx_S_temporal_transverse.left 221 60 60 255 -2100 ctx-rh-Unknown 0 0 0 255 -2101 ctx-rh-Corpus_callosum 50 50 50 255 -2102 ctx-rh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 255 -2103 ctx-rh-G_cingulate-Isthmus 60 25 25 255 -2104 ctx-rh-G_cingulate-Main_part 25 60 60 255 -2105 ctx-rh-G_cuneus 180 20 20 255 -2106 ctx-rh-G_frontal_inf-Opercular_part 220 20 100 255 -2107 ctx-rh-G_frontal_inf-Orbital_part 140 60 60 255 -2108 ctx-rh-G_frontal_inf-Triangular_part 180 220 140 255 -2109 ctx-rh-G_frontal_middle 140 100 180 255 -2110 ctx-rh-G_frontal_superior 180 20 140 255 -2111 ctx-rh-G_frontomarginal 140 20 140 255 -2112 ctx-rh-G_insular_long 21 10 10 255 -2113 ctx-rh-G_insular_short 225 140 140 255 -2114 ctx-rh-G_and_S_occipital_inferior 23 60 180 255 -2115 ctx-rh-G_occipital_middle 180 60 180 255 -2116 ctx-rh-G_occipital_superior 20 220 60 255 -2117 ctx-rh-G_occipit-temp_lat-Or_fusiform 60 20 140 255 -2118 ctx-rh-G_occipit-temp_med-Lingual_part 220 180 140 255 -2119 ctx-rh-G_occipit-temp_med-Parahippocampal_part 65 100 20 255 -2120 ctx-rh-G_orbital 220 60 20 255 -2121 ctx-rh-G_paracentral 60 100 60 255 -2122 ctx-rh-G_parietal_inferior-Angular_part 20 60 220 255 -2123 ctx-rh-G_parietal_inferior-Supramarginal_part 100 100 60 255 -2124 ctx-rh-G_parietal_superior 220 180 220 255 -2125 ctx-rh-G_postcentral 20 180 140 255 -2126 ctx-rh-G_precentral 60 140 180 255 -2127 ctx-rh-G_precuneus 25 20 140 255 -2128 ctx-rh-G_rectus 20 60 100 255 -2129 ctx-rh-G_subcallosal 60 220 20 255 -2130 ctx-rh-G_subcentral 60 20 220 255 -2131 ctx-rh-G_temporal_inferior 220 220 100 255 -2132 ctx-rh-G_temporal_middle 180 60 60 255 -2133 ctx-rh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 255 -2134 ctx-rh-G_temp_sup-Lateral_aspect 220 60 220 255 -2135 ctx-rh-G_temp_sup-Planum_polare 65 220 60 255 -2136 ctx-rh-G_temp_sup-Planum_tempolare 25 140 20 255 -2137 ctx-rh-G_and_S_transverse_frontopolar 13 0 250 255 -2138 ctx-rh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 255 -2139 ctx-rh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 255 -2140 ctx-rh-Lat_Fissure-post_sgt 61 60 100 255 -2141 ctx-rh-Medial_wall 25 25 25 255 -2142 ctx-rh-Pole_occipital 140 20 60 255 -2143 ctx-rh-Pole_temporal 220 180 20 255 -2144 ctx-rh-S_calcarine 63 180 180 255 -2145 ctx-rh-S_central 221 20 10 255 -2146 ctx-rh-S_central_insula 21 220 20 255 -2147 ctx-rh-S_cingulate-Main_part_and_Intracingulate 183 100 20 255 -2148 ctx-rh-S_cingulate-Marginalis_part 221 20 100 255 -2149 ctx-rh-S_circular_insula_anterior 221 60 140 255 -2150 ctx-rh-S_circular_insula_inferior 221 20 220 255 -2151 ctx-rh-S_circular_insula_superior 61 220 220 255 -2152 ctx-rh-S_collateral_transverse_ant 100 200 200 255 -2153 ctx-rh-S_collateral_transverse_post 10 200 200 255 -2154 ctx-rh-S_frontal_inferior 221 220 20 255 -2155 ctx-rh-S_frontal_middle 141 20 100 255 -2156 ctx-rh-S_frontal_superior 61 220 100 255 -2157 ctx-rh-S_frontomarginal 21 220 60 255 -2158 ctx-rh-S_intermedius_primus-Jensen 141 60 20 255 -2159 ctx-rh-S_intraparietal-and_Parietal_transverse 143 20 220 255 -2160 ctx-rh-S_occipital_anterior 61 20 180 255 -2161 ctx-rh-S_occipital_middle_and_Lunatus 101 60 220 255 -2162 ctx-rh-S_occipital_superior_and_transversalis 21 20 140 255 -2163 ctx-rh-S_occipito-temporal_lateral 221 140 20 255 -2164 ctx-rh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 255 -2165 ctx-rh-S_orbital-H_shapped 101 20 20 255 -2166 ctx-rh-S_orbital_lateral 221 100 20 255 -2167 ctx-rh-S_orbital_medial-Or_olfactory 181 200 20 255 -2168 ctx-rh-S_paracentral 21 180 140 255 -2169 ctx-rh-S_parieto_occipital 101 100 180 255 -2170 ctx-rh-S_pericallosal 181 220 20 255 -2171 ctx-rh-S_postcentral 21 140 200 255 -2172 ctx-rh-S_precentral-Inferior-part 21 20 240 255 -2173 ctx-rh-S_precentral-Superior-part 21 20 200 255 -2174 ctx-rh-S_subcentral_ant 61 180 60 255 -2175 ctx-rh-S_subcentral_post 61 180 250 255 -2176 ctx-rh-S_suborbital 21 20 60 255 -2177 ctx-rh-S_subparietal 101 60 60 255 -2178 ctx-rh-S_supracingulate 21 220 220 255 -2179 ctx-rh-S_temporal_inferior 21 180 180 255 -2180 ctx-rh-S_temporal_superior 223 220 60 255 -2181 ctx-rh-S_temporal_transverse 221 60 60 255 +2100 ctx_Unknown.right 0 0 0 255 +2101 ctx_Corpus_callosum.right 50 50 50 255 +2102 ctx_G_and_S_Insula_ONLY_AVERAGE.right 180 20 30 255 +2103 ctx_G_cingulate_Isthmus.right 60 25 25 255 +2104 ctx_G_cingulate_Main_part.right 25 60 60 255 +2105 ctx_G_cuneus.right 180 20 20 255 +2106 ctx_G_frontal_inf_Opercular_part.right 220 20 100 255 +2107 ctx_G_frontal_inf_Orbital_part.right 140 60 60 255 +2108 ctx_G_frontal_inf_Triangular_part.right 180 220 140 255 +2109 ctx_G_frontal_middle.right 140 100 180 255 +2110 ctx_G_frontal_superior.right 180 20 140 255 +2111 ctx_G_frontomarginal.right 140 20 140 255 +2112 ctx_G_insular_long.right 21 10 10 255 +2113 ctx_G_insular_short.right 225 140 140 255 +2114 ctx_G_and_S_occipital_inferior.right 23 60 180 255 +2115 ctx_G_occipital_middle.right 180 60 180 255 +2116 ctx_G_occipital_superior.right 20 220 60 255 +2117 ctx_G_occipit_temp_lat_Or_fusiform.right 60 20 140 255 +2118 ctx_G_occipit_temp_med_Lingual_part.right 220 180 140 255 +2119 ctx_G_occipit_temp_med_Parahippocampal_part.right 65 100 20 255 +2120 ctx_G_orbital.right 220 60 20 255 +2121 ctx_G_paracentral.right 60 100 60 255 +2122 ctx_G_parietal_inferior_Angular_part.right 20 60 220 255 +2123 ctx_G_parietal_inferior_Supramarginal_part.right 100 100 60 255 +2124 ctx_G_parietal_superior.right 220 180 220 255 +2125 ctx_G_postcentral.right 20 180 140 255 +2126 ctx_G_precentral.right 60 140 180 255 +2127 ctx_G_precuneus.right 25 20 140 255 +2128 ctx_G_rectus.right 20 60 100 255 +2129 ctx_G_subcallosal.right 60 220 20 255 +2130 ctx_G_subcentral.right 60 20 220 255 +2131 ctx_G_temporal_inferior.right 220 220 100 255 +2132 ctx_G_temporal_middle.right 180 60 60 255 +2133 ctx_G_temp_sup_G_temp_transv_and_interm_S.right 60 60 220 255 +2134 ctx_G_temp_sup_Lateral_aspect.right 220 60 220 255 +2135 ctx_G_temp_sup_Planum_polare.right 65 220 60 255 +2136 ctx_G_temp_sup_Planum_tempolare.right 25 140 20 255 +2137 ctx_G_and_S_transverse_frontopolar.right 13 0 250 255 +2138 ctx_Lat_Fissure_ant_sgt_ramus_horizontal.right 61 20 220 255 +2139 ctx_Lat_Fissure_ant_sgt_ramus_vertical.right 61 20 60 255 +2140 ctx_Lat_Fissure_post_sgt.right 61 60 100 255 +2141 ctx_Medial_wall.right 25 25 25 255 +2142 ctx_Pole_occipital.right 140 20 60 255 +2143 ctx_Pole_temporal.right 220 180 20 255 +2144 ctx_S_calcarine.right 63 180 180 255 +2145 ctx_S_central.right 221 20 10 255 +2146 ctx_S_central_insula.right 21 220 20 255 +2147 ctx_S_cingulate_Main_part_and_Intracingulate.right 183 100 20 255 +2148 ctx_S_cingulate_Marginalis_part.right 221 20 100 255 +2149 ctx_S_circular_insula_anterior.right 221 60 140 255 +2150 ctx_S_circular_insula_inferior.right 221 20 220 255 +2151 ctx_S_circular_insula_superior.right 61 220 220 255 +2152 ctx_S_collateral_transverse_ant.right 100 200 200 255 +2153 ctx_S_collateral_transverse_post.right 10 200 200 255 +2154 ctx_S_frontal_inferior.right 221 220 20 255 +2155 ctx_S_frontal_middle.right 141 20 100 255 +2156 ctx_S_frontal_superior.right 61 220 100 255 +2157 ctx_S_frontomarginal.right 21 220 60 255 +2158 ctx_S_intermedius_primus_Jensen.right 141 60 20 255 +2159 ctx_S_intraparietal_and_Parietal_transverse.right 143 20 220 255 +2160 ctx_S_occipital_anterior.right 61 20 180 255 +2161 ctx_S_occipital_middle_and_Lunatus.right 101 60 220 255 +2162 ctx_S_occipital_superior_and_transversalis.right 21 20 140 255 +2163 ctx_S_occipito_temporal_lateral.right 221 140 20 255 +2164 ctx_S_occipito_temporal_medial_and_S_Lingual.right 141 100 220 255 +2165 ctx_S_orbital_H_shapped.right 101 20 20 255 +2166 ctx_S_orbital_lateral.right 221 100 20 255 +2167 ctx_S_orbital_medial_Or_olfactory.right 181 200 20 255 +2168 ctx_S_paracentral.right 21 180 140 255 +2169 ctx_S_parieto_occipital.right 101 100 180 255 +2170 ctx_S_pericallosal.right 181 220 20 255 +2171 ctx_S_postcentral.right 21 140 200 255 +2172 ctx_S_precentral_Inferior_part.right 21 20 240 255 +2173 ctx_S_precentral_Superior_part.right 21 20 200 255 +2174 ctx_S_subcentral_ant.right 61 180 60 255 +2175 ctx_S_subcentral_post.right 61 180 250 255 +2176 ctx_S_suborbital.right 21 20 60 255 +2177 ctx_S_subparietal.right 101 60 60 255 +2178 ctx_S_supracingulate.right 21 220 220 255 +2179 ctx_S_temporal_inferior.right 21 180 180 255 +2180 ctx_S_temporal_superior.right 223 220 60 255 +2181 ctx_S_temporal_transverse.right 221 60 60 255 -3100 wm-lh-Unknown 0 0 0 255 -3101 wm-lh-Corpus_callosum 50 50 50 255 -3102 wm-lh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 255 -3103 wm-lh-G_cingulate-Isthmus 60 25 25 255 -3104 wm-lh-G_cingulate-Main_part 25 60 60 255 -3105 wm-lh-G_cuneus 180 20 20 255 -3106 wm-lh-G_frontal_inf-Opercular_part 220 20 100 255 -3107 wm-lh-G_frontal_inf-Orbital_part 140 60 60 255 -3108 wm-lh-G_frontal_inf-Triangular_part 180 220 140 255 -3109 wm-lh-G_frontal_middle 140 100 180 255 -3110 wm-lh-G_frontal_superior 180 20 140 255 -3111 wm-lh-G_frontomarginal 140 20 140 255 -3112 wm-lh-G_insular_long 21 10 10 255 -3113 wm-lh-G_insular_short 225 140 140 255 -3114 wm-lh-G_and_S_occipital_inferior 23 60 180 255 -3115 wm-lh-G_occipital_middle 180 60 180 255 -3116 wm-lh-G_occipital_superior 20 220 60 255 -3117 wm-lh-G_occipit-temp_lat-Or_fusiform 60 20 140 255 -3118 wm-lh-G_occipit-temp_med-Lingual_part 220 180 140 255 -3119 wm-lh-G_occipit-temp_med-Parahippocampal_part 65 100 20 255 -3120 wm-lh-G_orbital 220 60 20 255 -3121 wm-lh-G_paracentral 60 100 60 255 -3122 wm-lh-G_parietal_inferior-Angular_part 20 60 220 255 -3123 wm-lh-G_parietal_inferior-Supramarginal_part 100 100 60 255 -3124 wm-lh-G_parietal_superior 220 180 220 255 -3125 wm-lh-G_postcentral 20 180 140 255 -3126 wm-lh-G_precentral 60 140 180 255 -3127 wm-lh-G_precuneus 25 20 140 255 -3128 wm-lh-G_rectus 20 60 100 255 -3129 wm-lh-G_subcallosal 60 220 20 255 -3130 wm-lh-G_subcentral 60 20 220 255 -3131 wm-lh-G_temporal_inferior 220 220 100 255 -3132 wm-lh-G_temporal_middle 180 60 60 255 -3133 wm-lh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 255 -3134 wm-lh-G_temp_sup-Lateral_aspect 220 60 220 255 -3135 wm-lh-G_temp_sup-Planum_polare 65 220 60 255 -3136 wm-lh-G_temp_sup-Planum_tempolare 25 140 20 255 -3137 wm-lh-G_and_S_transverse_frontopolar 13 0 250 255 -3138 wm-lh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 255 -3139 wm-lh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 255 -3140 wm-lh-Lat_Fissure-post_sgt 61 60 100 255 -3141 wm-lh-Medial_wall 25 25 25 255 -3142 wm-lh-Pole_occipital 140 20 60 255 -3143 wm-lh-Pole_temporal 220 180 20 255 -3144 wm-lh-S_calcarine 63 180 180 255 -3145 wm-lh-S_central 221 20 10 255 -3146 wm-lh-S_central_insula 21 220 20 255 -3147 wm-lh-S_cingulate-Main_part_and_Intracingulate 183 100 20 255 -3148 wm-lh-S_cingulate-Marginalis_part 221 20 100 255 -3149 wm-lh-S_circular_insula_anterior 221 60 140 255 -3150 wm-lh-S_circular_insula_inferior 221 20 220 255 -3151 wm-lh-S_circular_insula_superior 61 220 220 255 -3152 wm-lh-S_collateral_transverse_ant 100 200 200 255 -3153 wm-lh-S_collateral_transverse_post 10 200 200 255 -3154 wm-lh-S_frontal_inferior 221 220 20 255 -3155 wm-lh-S_frontal_middle 141 20 100 255 -3156 wm-lh-S_frontal_superior 61 220 100 255 -3157 wm-lh-S_frontomarginal 21 220 60 255 -3158 wm-lh-S_intermedius_primus-Jensen 141 60 20 255 -3159 wm-lh-S_intraparietal-and_Parietal_transverse 143 20 220 255 -3160 wm-lh-S_occipital_anterior 61 20 180 255 -3161 wm-lh-S_occipital_middle_and_Lunatus 101 60 220 255 -3162 wm-lh-S_occipital_superior_and_transversalis 21 20 140 255 -3163 wm-lh-S_occipito-temporal_lateral 221 140 20 255 -3164 wm-lh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 255 -3165 wm-lh-S_orbital-H_shapped 101 20 20 255 -3166 wm-lh-S_orbital_lateral 221 100 20 255 -3167 wm-lh-S_orbital_medial-Or_olfactory 181 200 20 255 -3168 wm-lh-S_paracentral 21 180 140 255 -3169 wm-lh-S_parieto_occipital 101 100 180 255 -3170 wm-lh-S_pericallosal 181 220 20 255 -3171 wm-lh-S_postcentral 21 140 200 255 -3172 wm-lh-S_precentral-Inferior-part 21 20 240 255 -3173 wm-lh-S_precentral-Superior-part 21 20 200 255 -3174 wm-lh-S_subcentral_ant 61 180 60 255 -3175 wm-lh-S_subcentral_post 61 180 250 255 -3176 wm-lh-S_suborbital 21 20 60 255 -3177 wm-lh-S_subparietal 101 60 60 255 -3178 wm-lh-S_supracingulate 21 220 220 255 -3179 wm-lh-S_temporal_inferior 21 180 180 255 -3180 wm-lh-S_temporal_superior 223 220 60 255 -3181 wm-lh-S_temporal_transverse 221 60 60 255 +3100 wm_Unknown.left 0 0 0 255 +3101 wm_Corpus_callosum.left 50 50 50 255 +3102 wm_G_and_S_Insula_ONLY_AVERAGE.left 180 20 30 255 +3103 wm_G_cingulate_Isthmus.left 60 25 25 255 +3104 wm_G_cingulate_Main_part.left 25 60 60 255 +3105 wm_G_cuneus.left 180 20 20 255 +3106 wm_G_frontal_inf_Opercular_part.left 220 20 100 255 +3107 wm_G_frontal_inf_Orbital_part.left 140 60 60 255 +3108 wm_G_frontal_inf_Triangular_part.left 180 220 140 255 +3109 wm_G_frontal_middle.left 140 100 180 255 +3110 wm_G_frontal_superior.left 180 20 140 255 +3111 wm_G_frontomarginal.left 140 20 140 255 +3112 wm_G_insular_long.left 21 10 10 255 +3113 wm_G_insular_short.left 225 140 140 255 +3114 wm_G_and_S_occipital_inferior.left 23 60 180 255 +3115 wm_G_occipital_middle.left 180 60 180 255 +3116 wm_G_occipital_superior.left 20 220 60 255 +3117 wm_G_occipit_temp_lat_Or_fusiform.left 60 20 140 255 +3118 wm_G_occipit_temp_med_Lingual_part.left 220 180 140 255 +3119 wm_G_occipit_temp_med_Parahippocampal_part.left 65 100 20 255 +3120 wm_G_orbital.left 220 60 20 255 +3121 wm_G_paracentral.left 60 100 60 255 +3122 wm_G_parietal_inferior_Angular_part.left 20 60 220 255 +3123 wm_G_parietal_inferior_Supramarginal_part.left 100 100 60 255 +3124 wm_G_parietal_superior.left 220 180 220 255 +3125 wm_G_postcentral.left 20 180 140 255 +3126 wm_G_precentral.left 60 140 180 255 +3127 wm_G_precuneus.left 25 20 140 255 +3128 wm_G_rectus.left 20 60 100 255 +3129 wm_G_subcallosal.left 60 220 20 255 +3130 wm_G_subcentral.left 60 20 220 255 +3131 wm_G_temporal_inferior.left 220 220 100 255 +3132 wm_G_temporal_middle.left 180 60 60 255 +3133 wm_G_temp_sup_G_temp_transv_and_interm_S.left 60 60 220 255 +3134 wm_G_temp_sup_Lateral_aspect.left 220 60 220 255 +3135 wm_G_temp_sup_Planum_polare.left 65 220 60 255 +3136 wm_G_temp_sup_Planum_tempolare.left 25 140 20 255 +3137 wm_G_and_S_transverse_frontopolar.left 13 0 250 255 +3138 wm_Lat_Fissure_ant_sgt_ramus_horizontal.left 61 20 220 255 +3139 wm_Lat_Fissure_ant_sgt_ramus_vertical.left 61 20 60 255 +3140 wm_Lat_Fissure_post_sgt.left 61 60 100 255 +3141 wm_Medial_wall.left 25 25 25 255 +3142 wm_Pole_occipital.left 140 20 60 255 +3143 wm_Pole_temporal.left 220 180 20 255 +3144 wm_S_calcarine.left 63 180 180 255 +3145 wm_S_central.left 221 20 10 255 +3146 wm_S_central_insula.left 21 220 20 255 +3147 wm_S_cingulate_Main_part_and_Intracingulate.left 183 100 20 255 +3148 wm_S_cingulate_Marginalis_part.left 221 20 100 255 +3149 wm_S_circular_insula_anterior.left 221 60 140 255 +3150 wm_S_circular_insula_inferior.left 221 20 220 255 +3151 wm_S_circular_insula_superior.left 61 220 220 255 +3152 wm_S_collateral_transverse_ant.left 100 200 200 255 +3153 wm_S_collateral_transverse_post.left 10 200 200 255 +3154 wm_S_frontal_inferior.left 221 220 20 255 +3155 wm_S_frontal_middle.left 141 20 100 255 +3156 wm_S_frontal_superior.left 61 220 100 255 +3157 wm_S_frontomarginal.left 21 220 60 255 +3158 wm_S_intermedius_primus_Jensen.left 141 60 20 255 +3159 wm_S_intraparietal_and_Parietal_transverse.left 143 20 220 255 +3160 wm_S_occipital_anterior.left 61 20 180 255 +3161 wm_S_occipital_middle_and_Lunatus.left 101 60 220 255 +3162 wm_S_occipital_superior_and_transversalis.left 21 20 140 255 +3163 wm_S_occipito_temporal_lateral.left 221 140 20 255 +3164 wm_S_occipito_temporal_medial_and_S_Lingual.left 141 100 220 255 +3165 wm_S_orbital_H_shapped.left 101 20 20 255 +3166 wm_S_orbital_lateral.left 221 100 20 255 +3167 wm_S_orbital_medial_Or_olfactory.left 181 200 20 255 +3168 wm_S_paracentral.left 21 180 140 255 +3169 wm_S_parieto_occipital.left 101 100 180 255 +3170 wm_S_pericallosal.left 181 220 20 255 +3171 wm_S_postcentral.left 21 140 200 255 +3172 wm_S_precentral_Inferior_part.left 21 20 240 255 +3173 wm_S_precentral_Superior_part.left 21 20 200 255 +3174 wm_S_subcentral_ant.left 61 180 60 255 +3175 wm_S_subcentral_post.left 61 180 250 255 +3176 wm_S_suborbital.left 21 20 60 255 +3177 wm_S_subparietal.left 101 60 60 255 +3178 wm_S_supracingulate.left 21 220 220 255 +3179 wm_S_temporal_inferior.left 21 180 180 255 +3180 wm_S_temporal_superior.left 223 220 60 255 +3181 wm_S_temporal_transverse.left 221 60 60 255 -4100 wm-rh-Unknown 0 0 0 255 -4101 wm-rh-Corpus_callosum 50 50 50 255 -4102 wm-rh-G_and_S_Insula_ONLY_AVERAGE 180 20 30 255 -4103 wm-rh-G_cingulate-Isthmus 60 25 25 255 -4104 wm-rh-G_cingulate-Main_part 25 60 60 255 -4105 wm-rh-G_cuneus 180 20 20 255 -4106 wm-rh-G_frontal_inf-Opercular_part 220 20 100 255 -4107 wm-rh-G_frontal_inf-Orbital_part 140 60 60 255 -4108 wm-rh-G_frontal_inf-Triangular_part 180 220 140 255 -4109 wm-rh-G_frontal_middle 140 100 180 255 -4110 wm-rh-G_frontal_superior 180 20 140 255 -4111 wm-rh-G_frontomarginal 140 20 140 255 -4112 wm-rh-G_insular_long 21 10 10 255 -4113 wm-rh-G_insular_short 225 140 140 255 -4114 wm-rh-G_and_S_occipital_inferior 23 60 180 255 -4115 wm-rh-G_occipital_middle 180 60 180 255 -4116 wm-rh-G_occipital_superior 20 220 60 255 -4117 wm-rh-G_occipit-temp_lat-Or_fusiform 60 20 140 255 -4118 wm-rh-G_occipit-temp_med-Lingual_part 220 180 140 255 -4119 wm-rh-G_occipit-temp_med-Parahippocampal_part 65 100 20 255 -4120 wm-rh-G_orbital 220 60 20 255 -4121 wm-rh-G_paracentral 60 100 60 255 -4122 wm-rh-G_parietal_inferior-Angular_part 20 60 220 255 -4123 wm-rh-G_parietal_inferior-Supramarginal_part 100 100 60 255 -4124 wm-rh-G_parietal_superior 220 180 220 255 -4125 wm-rh-G_postcentral 20 180 140 255 -4126 wm-rh-G_precentral 60 140 180 255 -4127 wm-rh-G_precuneus 25 20 140 255 -4128 wm-rh-G_rectus 20 60 100 255 -4129 wm-rh-G_subcallosal 60 220 20 255 -4130 wm-rh-G_subcentral 60 20 220 255 -4131 wm-rh-G_temporal_inferior 220 220 100 255 -4132 wm-rh-G_temporal_middle 180 60 60 255 -4133 wm-rh-G_temp_sup-G_temp_transv_and_interm_S 60 60 220 255 -4134 wm-rh-G_temp_sup-Lateral_aspect 220 60 220 255 -4135 wm-rh-G_temp_sup-Planum_polare 65 220 60 255 -4136 wm-rh-G_temp_sup-Planum_tempolare 25 140 20 255 -4137 wm-rh-G_and_S_transverse_frontopolar 13 0 250 255 -4138 wm-rh-Lat_Fissure-ant_sgt-ramus_horizontal 61 20 220 255 -4139 wm-rh-Lat_Fissure-ant_sgt-ramus_vertical 61 20 60 255 -4140 wm-rh-Lat_Fissure-post_sgt 61 60 100 255 -4141 wm-rh-Medial_wall 25 25 25 255 -4142 wm-rh-Pole_occipital 140 20 60 255 -4143 wm-rh-Pole_temporal 220 180 20 255 -4144 wm-rh-S_calcarine 63 180 180 255 -4145 wm-rh-S_central 221 20 10 255 -4146 wm-rh-S_central_insula 21 220 20 255 -4147 wm-rh-S_cingulate-Main_part_and_Intracingulate 183 100 20 255 -4148 wm-rh-S_cingulate-Marginalis_part 221 20 100 255 -4149 wm-rh-S_circular_insula_anterior 221 60 140 255 -4150 wm-rh-S_circular_insula_inferior 221 20 220 255 -4151 wm-rh-S_circular_insula_superior 61 220 220 255 -4152 wm-rh-S_collateral_transverse_ant 100 200 200 255 -4153 wm-rh-S_collateral_transverse_post 10 200 200 255 -4154 wm-rh-S_frontal_inferior 221 220 20 255 -4155 wm-rh-S_frontal_middle 141 20 100 255 -4156 wm-rh-S_frontal_superior 61 220 100 255 -4157 wm-rh-S_frontomarginal 21 220 60 255 -4158 wm-rh-S_intermedius_primus-Jensen 141 60 20 255 -4159 wm-rh-S_intraparietal-and_Parietal_transverse 143 20 220 255 -4160 wm-rh-S_occipital_anterior 61 20 180 255 -4161 wm-rh-S_occipital_middle_and_Lunatus 101 60 220 255 -4162 wm-rh-S_occipital_superior_and_transversalis 21 20 140 255 -4163 wm-rh-S_occipito-temporal_lateral 221 140 20 255 -4164 wm-rh-S_occipito-temporal_medial_and_S_Lingual 141 100 220 255 -4165 wm-rh-S_orbital-H_shapped 101 20 20 255 -4166 wm-rh-S_orbital_lateral 221 100 20 255 -4167 wm-rh-S_orbital_medial-Or_olfactory 181 200 20 255 -4168 wm-rh-S_paracentral 21 180 140 255 -4169 wm-rh-S_parieto_occipital 101 100 180 255 -4170 wm-rh-S_pericallosal 181 220 20 255 -4171 wm-rh-S_postcentral 21 140 200 255 -4172 wm-rh-S_precentral-Inferior-part 21 20 240 255 -4173 wm-rh-S_precentral-Superior-part 21 20 200 255 -4174 wm-rh-S_subcentral_ant 61 180 60 255 -4175 wm-rh-S_subcentral_post 61 180 250 255 -4176 wm-rh-S_suborbital 21 20 60 255 -4177 wm-rh-S_subparietal 101 60 60 255 -4178 wm-rh-S_supracingulate 21 220 220 255 -4179 wm-rh-S_temporal_inferior 21 180 180 255 -4180 wm-rh-S_temporal_superior 223 220 60 255 -4181 wm-rh-S_temporal_transverse 221 60 60 255 +4100 wm_Unknown.right 0 0 0 255 +4101 wm_Corpus_callosum.right 50 50 50 255 +4102 wm_G_and_S_Insula_ONLY_AVERAGE.right 180 20 30 255 +4103 wm_G_cingulate_Isthmus.right 60 25 25 255 +4104 wm_G_cingulate_Main_part.right 25 60 60 255 +4105 wm_G_cuneus.right 180 20 20 255 +4106 wm_G_frontal_inf_Opercular_part.right 220 20 100 255 +4107 wm_G_frontal_inf_Orbital_part.right 140 60 60 255 +4108 wm_G_frontal_inf_Triangular_part.right 180 220 140 255 +4109 wm_G_frontal_middle.right 140 100 180 255 +4110 wm_G_frontal_superior.right 180 20 140 255 +4111 wm_G_frontomarginal.right 140 20 140 255 +4112 wm_G_insular_long.right 21 10 10 255 +4113 wm_G_insular_short.right 225 140 140 255 +4114 wm_G_and_S_occipital_inferior.right 23 60 180 255 +4115 wm_G_occipital_middle.right 180 60 180 255 +4116 wm_G_occipital_superior.right 20 220 60 255 +4117 wm_G_occipit_temp_lat_Or_fusiform.right 60 20 140 255 +4118 wm_G_occipit_temp_med_Lingual_part.right 220 180 140 255 +4119 wm_G_occipit_temp_med_Parahippocampal_part.right 65 100 20 255 +4120 wm_G_orbital.right 220 60 20 255 +4121 wm_G_paracentral.right 60 100 60 255 +4122 wm_G_parietal_inferior_Angular_part.right 20 60 220 255 +4123 wm_G_parietal_inferior_Supramarginal_part.right 100 100 60 255 +4124 wm_G_parietal_superior.right 220 180 220 255 +4125 wm_G_postcentral.right 20 180 140 255 +4126 wm_G_precentral.right 60 140 180 255 +4127 wm_G_precuneus.right 25 20 140 255 +4128 wm_G_rectus.right 20 60 100 255 +4129 wm_G_subcallosal.right 60 220 20 255 +4130 wm_G_subcentral.right 60 20 220 255 +4131 wm_G_temporal_inferior.right 220 220 100 255 +4132 wm_G_temporal_middle.right 180 60 60 255 +4133 wm_G_temp_sup_G_temp_transv_and_interm_S.right 60 60 220 255 +4134 wm_G_temp_sup_Lateral_aspect.right 220 60 220 255 +4135 wm_G_temp_sup_Planum_polare.right 65 220 60 255 +4136 wm_G_temp_sup_Planum_tempolare.right 25 140 20 255 +4137 wm_G_and_S_transverse_frontopolar.right 13 0 250 255 +4138 wm_Lat_Fissure_ant_sgt_ramus_horizontal.right 61 20 220 255 +4139 wm_Lat_Fissure_ant_sgt_ramus_vertical.right 61 20 60 255 +4140 wm_Lat_Fissure_post_sgt.right 61 60 100 255 +4141 wm_Medial_wall.right 25 25 25 255 +4142 wm_Pole_occipital.right 140 20 60 255 +4143 wm_Pole_temporal.right 220 180 20 255 +4144 wm_S_calcarine.right 63 180 180 255 +4145 wm_S_central.right 221 20 10 255 +4146 wm_S_central_insula.right 21 220 20 255 +4147 wm_S_cingulate_Main_part_and_Intracingulate.right 183 100 20 255 +4148 wm_S_cingulate_Marginalis_part.right 221 20 100 255 +4149 wm_S_circular_insula_anterior.right 221 60 140 255 +4150 wm_S_circular_insula_inferior.right 221 20 220 255 +4151 wm_S_circular_insula_superior.right 61 220 220 255 +4152 wm_S_collateral_transverse_ant.right 100 200 200 255 +4153 wm_S_collateral_transverse_post.right 10 200 200 255 +4154 wm_S_frontal_inferior.right 221 220 20 255 +4155 wm_S_frontal_middle.right 141 20 100 255 +4156 wm_S_frontal_superior.right 61 220 100 255 +4157 wm_S_frontomarginal.right 21 220 60 255 +4158 wm_S_intermedius_primus_Jensen.right 141 60 20 255 +4159 wm_S_intraparietal_and_Parietal_transverse.right 143 20 220 255 +4160 wm_S_occipital_anterior.right 61 20 180 255 +4161 wm_S_occipital_middle_and_Lunatus.right 101 60 220 255 +4162 wm_S_occipital_superior_and_transversalis.right 21 20 140 255 +4163 wm_S_occipito_temporal_lateral.right 221 140 20 255 +4164 wm_S_occipito_temporal_medial_and_S_Lingual.right 141 100 220 255 +4165 wm_S_orbital_H_shapped.right 101 20 20 255 +4166 wm_S_orbital_lateral.right 221 100 20 255 +4167 wm_S_orbital_medial_Or_olfactory.right 181 200 20 255 +4168 wm_S_paracentral.right 21 180 140 255 +4169 wm_S_parieto_occipital.right 101 100 180 255 +4170 wm_S_pericallosal.right 181 220 20 255 +4171 wm_S_postcentral.right 21 140 200 255 +4172 wm_S_precentral_Inferior_part.right 21 20 240 255 +4173 wm_S_precentral_Superior_part.right 21 20 200 255 +4174 wm_S_subcentral_ant.right 61 180 60 255 +4175 wm_S_subcentral_post.right 61 180 250 255 +4176 wm_S_suborbital.right 21 20 60 255 +4177 wm_S_subparietal.right 101 60 60 255 +4178 wm_S_supracingulate.right 21 220 220 255 +4179 wm_S_temporal_inferior.right 21 180 180 255 +4180 wm_S_temporal_superior.right 223 220 60 255 +4181 wm_S_temporal_transverse.right 221 60 60 255 diff --git a/tract_querier/tornado_server/css/viewer.css b/tract_querier/tornado_server/css/viewer.css index ef83e0d..3418552 100644 --- a/tract_querier/tornado_server/css/viewer.css +++ b/tract_querier/tornado_server/css/viewer.css @@ -1,8 +1,9 @@ .threeDRenderer { background-color: #000; position: absolute; - width: 100%; - height: 100%; + top: 171px; + width: 80%; + height: 80%; } .twoDRenderer { @@ -11,8 +12,7 @@ text-color: #FF0; position: absolute; width: 20%; - height: 31%; - /*height: 33.333%;*/ + height: 32%; right: 0%; } @@ -25,16 +25,34 @@ height: 5%; } +#anatomy_caption { + font-family:"Helvetica"; + top: 95%; + height: 5%; + border-top: thin solid #666; + background-color: #000; + text-color: #FF0; + position: absolute; + width: 80%; + left: 0%; + padding-left: 2%; + text-shadow: + -1px -1px 0 #222, + 1px -1px 0 #222, + -1px 1px 0 #222, + 1px 1px 0 #222; +} + #sliceX { - top: 7%; + top: 5%; } #sliceY { - top: 38%; + top: 36%; } #sliceZ { - top: 69%; + top: 68%; } @@ -68,7 +86,3 @@ border: thin dotted #484848; opacity: 0.5; } - -#anatomy_caption { - font-family:"Helvetica"; -} diff --git a/tract_querier/tornado_server/index.html b/tract_querier/tornado_server/index.html index 403894a..4570891 100644 --- a/tract_querier/tornado_server/index.html +++ b/tract_querier/tornado_server/index.html @@ -36,13 +36,12 @@
    -
    +
    +

    No Label Selected +

    -
    -

    No Label Selected

    -
    diff --git a/tract_querier/tornado_server/js/wmqlviz.js b/tract_querier/tornado_server/js/wmqlviz.js index 0b605bc..b4143e8 100644 --- a/tract_querier/tornado_server/js/wmqlviz.js +++ b/tract_querier/tornado_server/js/wmqlviz.js @@ -105,6 +105,7 @@ function on2DHover(renderer) { // get cursor position var mousepos = renderer.interactor.mousePosition; var ijk = renderer.xy2ijk(mousepos[0], mousepos[1]); + $('#anatomy_caption').html(""); console.info(ijk) if (!ijk) { return; @@ -112,9 +113,9 @@ function on2DHover(renderer) { // var orientedIJK = ijk.slice(); - orientedIJK[0] = ijk[1]; + orientedIJK[0] = ijk[0]; orientedIJK[1] = ijk[2]; - orientedIJK[2] = ijk[0]; + orientedIJK[2] = ijk[1]; var volume = _ATLAS_.currentVolume; @@ -129,8 +130,8 @@ function on2DHover(renderer) { var _g = parseInt(volume.labelmap.colortable.get(labelvalue)[2] * 255, 10); var _b = parseInt(volume.labelmap.colortable.get(labelvalue)[3] * 255, 10); $('#anatomy_caption').html(""); - //$('#anatomy_caption').html(labelname); - //$('#anatomy_caption').css('color', 'rgb( ' + _r + ',' + _g + ',' + _b + ' )' ); + $('#anatomy_caption').html(labelname); + $('#anatomy_caption').css('color', 'rgb( ' + _r + ',' + _g + ',' + _b + ' )' ); } @@ -178,7 +179,7 @@ function init_websocket(host, tract_download_host) { if (name in _tracts_) { console.info("Removing tract " + name); _tracts_gui_.remove(_tracts_[name].control); - render3D.remove(_tracts_[name]); + threeDRenderer.remove(_tracts_[name]); }; delete _tracts_[name]; @@ -192,7 +193,7 @@ function init_websocket(host, tract_download_host) { _tracts_[name].modified(); - render3D.add(_tracts_[name]); + threeDRenderer.add(_tracts_[name]); } @@ -200,20 +201,16 @@ function init_websocket(host, tract_download_host) { if (name in _tracts_) { console.info("Removing tract " + name); _tracts_gui_.remove(_tracts_[name].control); - render3D.remove(_tracts_[name]); + threeDRenderer.remove(_tracts_[name]); delete _tracts_[name]; } } if (action == 'download') { - //window.open(tract_download_host + '/' + name); - // javascript var iframe = document.createElement("iframe"); iframe.src = tract_download_host + '/' + name; iframe.onload = function() { - // iframe has finished loading, download has started - //el.innerHTML = "Download"; - console.log("test"); + console.log("Download trigger"); }; iframe.style.display = "none"; document.body.appendChild(iframe); @@ -258,10 +255,11 @@ function init_terminal() { window.onload = function() { - render3D = new X.renderer3D(); - render3D.init(); + threeDRenderer = new X.renderer3D(); + threeDRenderer.container = $( "#3d" )[0] + threeDRenderer.init(); - render3D.onShowtime = function() { + threeDRenderer.onShowtime = function() { init_viewer2d(); }; @@ -275,8 +273,8 @@ window.onload = function() { _tracts_gui_ = gui.addFolder('Tracts'); - render3D.add(_ATLAS_.currentVolume) - render3D.render(); + threeDRenderer.add(_ATLAS_.currentVolume) + threeDRenderer.render(); } From 6836688a29c5e0e2afbf9fc9c2f91062a4fcd11c Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Sat, 12 Jul 2014 08:52:32 +0200 Subject: [PATCH 42/53] ENH: Enhanced the completion algorithm in the webserver --- tract_querier/tornado_server/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tract_querier/tornado_server/__init__.py b/tract_querier/tornado_server/__init__.py index 9fa9b84..b15014b 100644 --- a/tract_querier/tornado_server/__init__.py +++ b/tract_querier/tornado_server/__init__.py @@ -139,7 +139,10 @@ def describe(self, *args): ''' def completion(self, *args): - completions = self.shell.completedefault(args[1]) + string = args[1] + if '(' in string: + string = string[string.rindex('(') + 1:] + completions = self.shell.completedefault(string) return completions From 785a35755b34c4465fcee5053034d9df3a6eafe9 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Sat, 12 Jul 2014 09:15:36 +0200 Subject: [PATCH 43/53] ENH: Minor viz touches --- tract_querier/tornado_server/js/wmqlviz.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tract_querier/tornado_server/js/wmqlviz.js b/tract_querier/tornado_server/js/wmqlviz.js index b4143e8..4111417 100644 --- a/tract_querier/tornado_server/js/wmqlviz.js +++ b/tract_querier/tornado_server/js/wmqlviz.js @@ -232,7 +232,7 @@ function init_terminal() { greetings: 'White Matter Query Language Console', name: 'wmql_console', prompt: '[WMQL] ', - height: 150, + height: '19%', completion: function (terminal, string, callback) { var cmd = 'system.completion' var result = [] From 87c1b81c9ffb33bab65be8fde7b8e1f196028db4 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Mon, 14 Jul 2014 17:28:07 +0200 Subject: [PATCH 44/53] RFR: Cleaned unused files --- .../tornado_server/js/wmqlviz_scratch.js | 302 ------------------ 1 file changed, 302 deletions(-) delete mode 100644 tract_querier/tornado_server/js/wmqlviz_scratch.js diff --git a/tract_querier/tornado_server/js/wmqlviz_scratch.js b/tract_querier/tornado_server/js/wmqlviz_scratch.js deleted file mode 100644 index dbdb1c5..0000000 --- a/tract_querier/tornado_server/js/wmqlviz_scratch.js +++ /dev/null @@ -1,302 +0,0 @@ -$(function() { - - // create the sliders for the 2D sliders - $("#yellow_slider").slider({ - slide: volumeslicingX - }); - $("#yellow_slider .ui-slider-handle").unbind('keydown'); - - $("#red_slider").slider({ - slide: volumeslicingY - }); - $("#red_slider .ui-slider-handle").unbind('keydown'); - - $("#green_slider").slider({ - slide: volumeslicingZ - }); - $("#green_slider .ui-slider-handle").unbind('keydown'); - -}); - -function init_viewer2d() { - - var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; - - // X Slice - if (sliceX) { - sliceX.destroy(); - } - sliceX = new X.renderer2D(); - sliceX.container = 'sliceX'; - sliceX.orientation = 'X'; - sliceX.init(); - sliceX.add(volume); - sliceX.render(); - sliceX.interactor.onMouseMove = function() { - if (_ATLAS_.hover){ - clearTimeout(_ATLAS_.hover); - } - _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceX), 100); - }; - - // Y Slice - if (sliceY) { - sliceY.destroy(); - } - sliceY = new X.renderer2D(); - sliceY.container = 'sliceY'; - sliceY.orientation = 'Y'; - sliceY.init(); - sliceY.add(volume); - sliceY.render(); - sliceY.interactor.onMouseMove = function() { - if (_ATLAS_.hover){ - clearTimeout(_ATLAS_.hover); - } - _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceY), 100); - }; - - // Z Slice - if (sliceZ) { - sliceZ.destroy(); - } - sliceZ = new X.renderer2D(); - sliceZ.container = 'sliceZ'; - sliceZ.orientation = 'Z'; - sliceZ.init(); - sliceZ.add(volume); - sliceZ.render(); - sliceZ.interactor.onMouseMove = function() { - if (_ATLAS_.hover){ - clearTimeout(_ATLAS_.hover); - } - _ATLAS_.hover = setTimeout(on2DHover.bind(this, sliceZ), 100); - }; - - // update 2d slice sliders - var dim = volume.dimensions; - $("#yellow_slider").slider("option", "disabled", false); - $("#yellow_slider").slider("option", "min", 0); - $("#yellow_slider").slider("option", "max", dim[0] - 1); - $("#yellow_slider").slider("option", "value", volume.indexX); - $("#red_slider").slider("option", "disabled", false); - $("#red_slider").slider("option", "min", 0); - $("#red_slider").slider("option", "max", dim[1] - 1); - $("#red_slider").slider("option", "value", volume.indexY); - $("#green_slider").slider("option", "disabled", false); - $("#green_slider").slider("option", "min", 0); - $("#green_slider").slider("option", "max", dim[2] - 1); - $("#green_slider").slider("option", "value", volume.indexZ); -}//init_viewer2d() - -// show labels on hover -function on2DHover(renderer) { - - // check that feature is enabled - if (!_ATLAS_.hoverLabelSelect){ - return; - } - - // get cursor position - var mousepos = renderer.interactor.mousePosition; - var ijk = renderer.xy2ijk(mousepos[0], mousepos[1]); - if (!ijk) { - return; - } - - // - var orientedIJK = ijk.slice(); - orientedIJK[0] = ijk[2]; - orientedIJK[1] = ijk[1]; - orientedIJK[2] = ijk[0]; - - var volume = _ATLAS_.volumes[_ATLAS_.currentVolume]; - - // get the number associated with the label - var labelvalue = volume.labelmap.image[orientedIJK[0]][orientedIJK[1]][orientedIJK[2]]; - if (!labelvalue || labelvalue == 0) { - return; - } - //console.info(labelvalue); - - - //volume.labelmap.opacity = 0.6; - //volume.labelmap.showOnly = labelvalue; - console.info(labelvalue); - _WS_.send(labelvalue) - var labelname = volume.labelmap.colortable.get(labelvalue)[0]; - var _r = parseInt(volume.labelmap.colortable.get(labelvalue)[1] * 255, 10); - var _g = parseInt(volume.labelmap.colortable.get(labelvalue)[2] * 255, 10); - var _b = parseInt(volume.labelmap.colortable.get(labelvalue)[3] * 255, 10); - $('#anatomy_caption').html(labelname); - $('#anatomy_caption').css('color', 'rgb( ' + _r + ',' + _g + ',' + _b + ' )' ); -} - - -sliceX = null; -sliceY = null; -sliceZ = null; - -function init_websocket() { - Error("test"); - console.info("websocket start"); - - $(document).ready(function () { - _WS_=new WebSocket("_WS_://localhost:9999/_WS_"); - console.info("Activating stuff") - _WS_.onopen = function () { - console.info("websocket engage"); - }; - - _WS_.onmessage = function(evt){ - console.info(evt.data) - new_fibers = new X.fibers() - new_fibers.file = evt.data - render3D.add(new_fibers) - //the received content is in evt.data, set it where you want - }; - - _WS_.onclose = function () { - console.info("connection closed"); - }; - - $(".column li").on("mouseup") //the function that sends data - { - pid = $(this).attr("id"); - oldCid = $(this).parent().parent().attr("id"); - newCid = $(this).parent().attr("id"); - message = pid + " " + oldCid + " " + newCid; - _WS_.send(message); - }; - }); - - _WS_.send("test inside"); -}; - -window.onload = function() { -console.info("OnLoad"); -init_websocket(); - -render3D = new X.renderer3D(); -render3D.init(); - -// create a mesh from a .vtk file -// // create a new X.fibers -volume = new X.volume(); -volume.file = 'MNI152_T1_1mm_brain.nii.gz'; -//volume.file = 't1_very_small_2.nii.gz'; -//volume.color = [1, 0, 0]; -//volume.labelmap.file = 'MNI152_wmparc_1mm.nii.gz'; -volume.labelmap.file = 'MNI152_wmparc_1mm_small.nii.gz'; -volume.labelmap.colortable.file = 'FreeSurferColorLUT.txt'; -//volume.visible = false; -//volume.labelmap.visible = true; - -_ATLAS_ = {}; -_ATLAS_.currentVolume = volume; -_ATLAS_.volumes = {}; -_ATLAS_.volumes[_ATLAS_.currentVolume] = volume -_ATLAS_.currentMesh = 0; -_ATLAS_.meshOpacity = 0.9; -_ATLAS_.labelOpacity = 0.5; -_ATLAS_.hover = null; -_ATLAS_.hoverLabelSelect = true; - -// create dictionary "label name" : "label value" -//initializeFreesurferLabels(_ATLAS_); -/*_ATLAS_.labels4 = { - "Accumbens area": 26, - "Amygdala": 18, - "Caudate": 11, - "Cerebellum Cortex": 8, - "Cerebral Cortex": 3, - "Hippocampus": 17, - "Lateral Ventricle": 4, - "Medulla": 175, - "Midbrain": 173, - "Pallidum": 13, - "Pons": 174, - "Putamen": 12, - "Thalamus": 9, - "Ventral DC": 28, - "Vermis": 172, - "3rd Ventricle": 14, - "4th Ventricle": 15 -};*/ - - - - -//var fibers = new X.fibers(); - - -//render3D.camera.position = [120, 80, 160]; - -render3D.add(volume); -//render3D.add(volume.labelmap); -var fibers = new X.fibers(); -fibers.file = -render3D.add(fibers); - -// .. and render it -// -render3D.onShowtime = function() { - init_viewer2d(); -} -/*render3D.onShowtime = function() { - - // - // The GUI panel - // - // (we need to create this during onShowtime(..) since we do not know the - // volume dimensions before the loading was completed) - - // indicate if the mesh was loaded - var gui = new dat.GUI(); - - var labelmapgui = gui.addFolder('Label Map'); - var labelMapVisibleController = labelmapgui.add(volume.labelmap, 'visible'); - - // the following configures the gui for interacting with the X.volume - var volumegui = gui.addFolder('Volume'); - // now we can configure controllers which.. - var visibilityControler = volumegui.add(volume, 'visible') - - // .. switch between slicing and volume rendering - //var vrController = volumegui.add(volume, 'volumeRendering'); - // the min and max color which define the linear gradient mapping - var minColorController = volumegui.addColor(volume, 'minColor'); - var maxColorController = volumegui.addColor(volume, 'maxColor'); - // .. configure the volume rendering opacity - var opacityController = volumegui.add(volume, 'opacity', 0, 1).listen(); - // .. and the threshold in the min..max range - var lowerThresholdController = volumegui.add(volume, 'lowerThreshold', - volume.min, volume.max); - var upperThresholdController = volumegui.add(volume, 'upperThreshold', - volume.min, volume.max); - var lowerWindowController = volumegui.add(volume, 'windowLow', volume.min, - volume.max); - var upperWindowController = volumegui.add(volume, 'windowHigh', volume.min, - volume.max); - // the indexX,Y,Z are the currently displayed slice indices in the range - // 0..dimensions-1 - var sliceXController = volumegui.add(volume, 'indexX', 0, - volume.dimensions[0] - 1); - var sliceYController = volumegui.add(volume, 'indexY', 0, - volume.dimensions[1] - 1); - var sliceZController = volumegui.add(volume, 'indexZ', 0, - volume.dimensions[2] - 1); - - //var fibergui = gui.addFolder('Fiber'); - //trackVisibleController = fibergui.add(fibers, 'visible'); - - //fibergui.open() - volumegui.open(); -};*/ - -render3D.render(); - -} - - - From b7d4f7b6c97aca9fb30113d113099021029fbee6 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Tue, 15 Jul 2014 15:17:09 +0200 Subject: [PATCH 45/53] ENH: Unbind the reset key from the viewer so the terminal works better --- tract_querier/tornado_server/js/wmqlviz.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tract_querier/tornado_server/js/wmqlviz.js b/tract_querier/tornado_server/js/wmqlviz.js index 4111417..1ab298a 100644 --- a/tract_querier/tornado_server/js/wmqlviz.js +++ b/tract_querier/tornado_server/js/wmqlviz.js @@ -220,7 +220,7 @@ function init_websocket(host, tract_download_host) { _WS_.onclose = function () { console.info("connection closed"); }; - + window.location.hash = '#wmql_console'; }); }; @@ -259,6 +259,13 @@ window.onload = function() { threeDRenderer.container = $( "#3d" )[0] threeDRenderer.init(); + // restore the original key bindings and reinitialize the interactor + // so it doesn't catch anymore the 'r' key to reset the view + // + window.onkeydown = function (e) { return true; } + threeDRenderer.interactor.config.KEYBOARD_ENABLED = false; + threeDRenderer.interactor.init(); + threeDRenderer.onShowtime = function() { init_viewer2d(); }; @@ -275,6 +282,5 @@ window.onload = function() { threeDRenderer.add(_ATLAS_.currentVolume) threeDRenderer.render(); - } From bbc7fc72a159517404b2d73f0473f847b1f65929 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Wed, 16 Jul 2014 13:42:43 +0200 Subject: [PATCH 46/53] ENH: Fixed terminal focus issues --- tract_querier/tornado_server/js/wmqlviz.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tract_querier/tornado_server/js/wmqlviz.js b/tract_querier/tornado_server/js/wmqlviz.js index 1ab298a..c36c8c7 100644 --- a/tract_querier/tornado_server/js/wmqlviz.js +++ b/tract_querier/tornado_server/js/wmqlviz.js @@ -31,6 +31,9 @@ function init_viewer2d() { sliceX.container = 'sliceX'; sliceX.orientation = 'X'; sliceX.init(); + window.onkeydown = function (e) { return true; } + sliceX.interactor.config.KEYBOARD_ENABLED = false; + sliceX.interactor.init(); sliceX.add(volume); sliceX.render(); sliceX.interactor.onMouseMove = function() { @@ -48,6 +51,9 @@ function init_viewer2d() { sliceY.container = 'sliceY'; sliceY.orientation = 'Y'; sliceY.init(); + window.onkeydown = function (e) { return true; } + sliceY.interactor.config.KEYBOARD_ENABLED = false; + sliceY.interactor.init(); sliceY.add(volume); sliceY.render(); sliceY.interactor.onMouseMove = function() { @@ -65,6 +71,9 @@ function init_viewer2d() { sliceZ.container = 'sliceZ'; sliceZ.orientation = 'Z'; sliceZ.init(); + window.onkeydown = function (e) { return true; } + sliceZ.interactor.config.KEYBOARD_ENABLED = false; + sliceZ.interactor.init(); sliceZ.add(volume); sliceZ.render(); sliceZ.interactor.onMouseMove = function() { @@ -220,7 +229,6 @@ function init_websocket(host, tract_download_host) { _WS_.onclose = function () { console.info("connection closed"); }; - window.location.hash = '#wmql_console'; }); }; @@ -269,7 +277,6 @@ window.onload = function() { threeDRenderer.onShowtime = function() { init_viewer2d(); }; - // The GUI panel // indicate if the mesh was loaded @@ -282,5 +289,6 @@ window.onload = function() { threeDRenderer.add(_ATLAS_.currentVolume) threeDRenderer.render(); + document.getElementById("wmql_console").focus(); } From a0b8e1155127e3a0285b29f4f1b584afd5d5cc62 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 18 Jul 2014 09:01:36 +0200 Subject: [PATCH 47/53] ENH: Better error reporting on the WMQL web-based terminal --- tract_querier/tornado_server/__init__.py | 54 ++++++++++++------------ 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/tract_querier/tornado_server/__init__.py b/tract_querier/tornado_server/__init__.py index b15014b..a6f5b18 100644 --- a/tract_querier/tornado_server/__init__.py +++ b/tract_querier/tornado_server/__init__.py @@ -17,9 +17,6 @@ class WSHandler(tornado.websocket.WebSocketHandler): def initialize(self, shell=None, websocket_clients=None): - self.shell = shell - self.sio = StringIO() - self.shell.stdout = self.sio self.json_encoder = json.JSONEncoder() self.json_decoder = json.JSONDecoder() self.websocket_clients = websocket_clients @@ -31,19 +28,7 @@ def open(self): self.websocket_clients.append(self) def on_message(self, message): - action = self.json_decoder.decode(message) - if action['receiver'] == 'terminal': - if action['action'] == 'cmd': - self.sio.seek(0) - self.shell.onecmd(action['command']) - self.sio.seek(0) - result = self.sio.getvalue() - term_output = { - 'receiver': 'terminal', - 'output': result - } - self.write_message(self.json_encoder.encode(term_output)) - self.sio.truncate(0) + pass def on_close(self): self.websocket_clients.remove(self) @@ -53,8 +38,9 @@ class JSONRPCHandler(tornado.web.RequestHandler): def initialize(self, shell=None, file_handler=None, websocket_clients=None): self.shell = shell self.file_handler = file_handler - self.sio = StringIO() - self.shell.stdout = self.sio + self.stdout_buffer = StringIO() + self.stderr_buffer = StringIO() + self.shell.stdout = self.stdout_buffer self.json_encoder = json.JSONEncoder() self.json_decoder = json.JSONDecoder() @@ -113,11 +99,22 @@ def post(self): decoded_args['method'], ''.join((s + ' ' for s in decoded_args['params'])) ) - self.sio.seek(0) + self.stdout_buffer.seek(0) + self.stderr_buffer.seek(0) + old_stderr = sys.stderr + sys.stderr = self.stderr_buffer self.shell.onecmd(wmql_string) - self.sio.seek(0) - result = self.sio.getvalue() - self.sio.truncate(0) + if self.stderr_buffer.pos > 0: + error = { + 'code': '-1', + 'message': self.stderr_buffer.getvalue(), + 'data': '' + } + sys.stderr = old_stderr + self.stdout_buffer.seek(0) + self.stderr_buffer.seek(0) + result = self.stdout_buffer.getvalue() + self.stdout_buffer.truncate(0) output = { 'jsonrpc': "2.0", @@ -139,9 +136,12 @@ def describe(self, *args): ''' def completion(self, *args): - string = args[1] + if len(args[1]) == 0: + return [] + + string = args[1].split()[-1].strip() if '(' in string: - string = string[string.rindex('(') + 1:] + string = string[string.rindex('(') + 1:].strip() completions = self.shell.completedefault(string) return completions @@ -264,7 +264,6 @@ def xtk_server(atlas=None, colortable=None, hostname='localhost', port=9999, fil {"path": static_folder} ), (r'/%s' % websocket_suffix, WSHandler, { - 'shell': shell, 'websocket_clients': websocket_clients }), (r'/jsonrpc', JSONRPCHandler, { @@ -310,7 +309,6 @@ def __del__(self): def clean_files(self): for k, v in self.tract_name_file.iteritems(): - print "Removing", k, v os.remove(v) self.tract_name_file = {} @@ -352,7 +350,7 @@ def save_query_callback(self, query_name, query_result): for client in self.websocket_clients: client.write_message(action_json) except Exception, e: - print "Websocket error:", e + sys.stderr.write("Websocket error: %s\n" % str(e)) return filename def del_query_callback(self, query_name): @@ -376,4 +374,4 @@ def del_query_callback(self, query_name): os.remove(self.tract_name_file[query_name]) del self.tract_name_file[query_name] except Exception, e: - print "Websocket error:", e + sys.stderr("Websocket error: %s\n" % str(e)) From 643fef2bcaae51cd99858271e3862584cf5cb17c Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 27 Mar 2015 08:37:16 +0100 Subject: [PATCH 48/53] ENH: Updated to the latest nibabel version --- requirements.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 6de5320..a8b8291 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ numpy>=1.6 nose>=1.2 tornado>=3.1 -#nibabel>=1.3 --e git://github.com/demianw/nibabel.git@fix_trackvis_scalar_save#egg=nibabel +nibabel>=2.0 numpydoc From d73d53f9cc2ee5846c9c09af273843f9798ea4dc Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 27 Mar 2015 09:19:45 +0100 Subject: [PATCH 49/53] BUG: Fixed folder hiding when 'h' was pressed on the terminal --- tract_querier/tornado_server/js/wmqlviz.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tract_querier/tornado_server/js/wmqlviz.js b/tract_querier/tornado_server/js/wmqlviz.js index c36c8c7..290e0e1 100644 --- a/tract_querier/tornado_server/js/wmqlviz.js +++ b/tract_querier/tornado_server/js/wmqlviz.js @@ -280,7 +280,7 @@ window.onload = function() { // The GUI panel // indicate if the mesh was loaded - var gui = new dat.GUI(); + var gui = new dat.GUI({ hideable: false }); var labelmapgui = gui.addFolder('Label Map'); var labelMapVisibleController = labelmapgui.add(_ATLAS_.currentVolume, 'visible'); From 3bbe1185d5686b684a9a7793df7ffe561cabf508 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 27 Mar 2015 09:33:27 +0100 Subject: [PATCH 50/53] ENH: Terminal now works better when window is resized --- tract_querier/tornado_server/js/wmqlviz.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tract_querier/tornado_server/js/wmqlviz.js b/tract_querier/tornado_server/js/wmqlviz.js index 290e0e1..9fd14de 100644 --- a/tract_querier/tornado_server/js/wmqlviz.js +++ b/tract_querier/tornado_server/js/wmqlviz.js @@ -239,8 +239,10 @@ function init_terminal() { { greetings: 'White Matter Query Language Console', name: 'wmql_console', + outputLimit: -1, prompt: '[WMQL] ', - height: '19%', + height: '15%', + width: '80%', completion: function (terminal, string, callback) { var cmd = 'system.completion' var result = [] From 00174940bf03cf8313f7955b95a8909cb365476e Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Fri, 27 Mar 2015 09:57:48 +0100 Subject: [PATCH 51/53] ENH: Resizing of terminal and footer looks better and works --- tract_querier/tornado_server/css/viewer.css | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tract_querier/tornado_server/css/viewer.css b/tract_querier/tornado_server/css/viewer.css index 3418552..2c09224 100644 --- a/tract_querier/tornado_server/css/viewer.css +++ b/tract_querier/tornado_server/css/viewer.css @@ -1,7 +1,9 @@ .threeDRenderer { background-color: #000; + border-top: thin solid #666; + border-bottom: thin solid #666; position: absolute; - top: 171px; + top: 16%; width: 80%; height: 80%; } @@ -22,20 +24,20 @@ position: fixed; bottom: 0; right: 0; - height: 5%; + height: 4%; } #anatomy_caption { font-family:"Helvetica"; - top: 95%; - height: 5%; - border-top: thin solid #666; + top: 96%; + height: 4%; background-color: #000; text-color: #FF0; position: absolute; width: 80%; left: 0%; padding-left: 2%; + padding-top: .25%; text-shadow: -1px -1px 0 #222, 1px -1px 0 #222, From 04c02ae21d05ea33c74fb425b1ae9ba1bad26146 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Wed, 13 May 2015 10:00:34 +0200 Subject: [PATCH 52/53] ENH: Better support for trackvis header --- tract_querier/tract_math/operations.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tract_querier/tract_math/operations.py b/tract_querier/tract_math/operations.py index 8e23a38..e1ba31c 100644 --- a/tract_querier/tract_math/operations.py +++ b/tract_querier/tract_math/operations.py @@ -255,7 +255,8 @@ def tract_resubsample(tractography, points_per_tract, file_output=None): tractography.subsample_tracts(int(points_per_tract), True) return Tractography( - tractography.tracts(), tractography.tracts_data() + tractography.tracts(), tractography.tracts_data(), + **tractography.extra_args ) @@ -758,7 +759,7 @@ def tract_prototype_median(tractography, file_output=None): else: selected_data[key] = item - return Tractography(selected_tracts, selected_data) + return Tractography(selected_tracts, selected_data, **tractography.extra_args) @tract_math_operation(' : compute the protoype tract') @@ -794,7 +795,7 @@ def tract_prototype_mean(tractography, smooth_order, file_output=None): except ImportError: warn("A smooth order larger than 0 needs scipy installed") - return Tractography([mean_tract], {}) + return Tractography([mean_tract], {}, **tractography.extra_args) @tract_math_operation(' ... : calculates the Bhattacharyya coefficient of the first tract with the rest in the space of the reference image') From d6da8ee9a681a0f5a782aaa84c0b72fe8de45151 Mon Sep 17 00:00:00 2001 From: Demian Wassermann Date: Wed, 18 Nov 2015 18:38:57 +0100 Subject: [PATCH 53/53] BUG: Corrected bug when translating from VTK to TRK files --- tract_querier/tractography/__init__.py | 20 ++++++++++++++++---- tract_querier/tractography/trackvis.py | 2 +- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/tract_querier/tractography/__init__.py b/tract_querier/tractography/__init__.py index 3908df4..a508561 100644 --- a/tract_querier/tractography/__init__.py +++ b/tract_querier/tractography/__init__.py @@ -59,19 +59,31 @@ def tractography_from_file(filename): def tractography_to_file(filename, tractography, **kwargs): if filename.endswith('trk'): - if 'affine' not in kwargs: - if hasattr(tractography, 'affine'): + if 'affine' not in kwargs or kwargs['affine'] is None: + if ( + hasattr(tractography, 'affine') and + tractography.affine is not None + ): kwargs['affine'] = tractography.affine else: warn('Setting affine of trk file to the identity') kwargs['affine'] = numpy.eye(4) - if 'image_dimensions' not in kwargs: - if hasattr(tractography, 'image_dims'): + + if ( + 'image_dimensions' not in kwargs or + kwargs['image_dimensions'] is None + ): + if ( + hasattr(tractography, 'image_dims') and + tractography.image_dims is not None + ): kwargs['image_dimensions'] = tractography.image_dims else: warn('Setting image_dimensions of trk file to: 1 1 1') kwargs['image_dimensions'] = numpy.ones(3) + return tractography_to_trackvis_file(filename, tractography, **kwargs) + elif filename.endswith('vtk') or filename.endswith('vtp'): if 'tractography_from_vtk_files' in __all__: return tractography_to_vtk_file(filename, tractography, **kwargs) diff --git a/tract_querier/tractography/trackvis.py b/tract_querier/tractography/trackvis.py index 16e92b1..2a6ba7b 100644 --- a/tract_querier/tractography/trackvis.py +++ b/tract_querier/tractography/trackvis.py @@ -23,7 +23,7 @@ def tractography_to_trackvis_file(filename, tractography, affine=None, image_dim if image_dimensions is not None: trk_header['dim'] = image_dimensions elif hasattr(tractography, 'image_dimensions'): - trk_header['dim'] = image_dimensions + trk_header['dim'] = tractography.image_dimensions else: raise ValueError("Image dimensions needed to save a trackvis file")