From 2bc7b954ab788f267d44c9a15e8e16f2b86d3593 Mon Sep 17 00:00:00 2001 From: Sarina Canelake <sarina@edx.org> Date: Mon, 7 Dec 2015 01:45:00 -0500 Subject: [PATCH] Remove the graphical slider tool --- .../contentstore/views/tests/test_item.py | 9 - cms/envs/common.py | 7 +- common/lib/xmodule/setup.py | 1 - .../lib/xmodule/xmodule/css/gst/display.scss | 44 - common/lib/xmodule/xmodule/gst_module.py | 241 --- .../js/src/graphical_slider_tool/.gitignore | 1 - .../js/src/graphical_slider_tool/el_output.js | 141 -- .../g_label_el_output.js | 115 -- .../graphical_slider_tool/general_methods.js | 23 - .../js/src/graphical_slider_tool/graph.js | 1512 ----------------- .../js/src/graphical_slider_tool/gst.js | 22 - .../js/src/graphical_slider_tool/gst_main.js | 86 - .../js/src/graphical_slider_tool/inputs.js | 88 - .../graphical_slider_tool/jstat-1.0.0.min.js | 236 --- .../js/src/graphical_slider_tool/sliders.js | 89 - .../js/src/graphical_slider_tool/state.js | 395 ----- .../lib/xmodule/xmodule/tests/test_export.py | 1 - .../lib/xmodule/xmodule/tests/test_import.py | 16 - .../xmodule/tests/test_xblock_wrappers.py | 5 +- .../test/data/graphic_slider_tool/README.md | 2 - .../test/data/graphic_slider_tool/course.xml | 1 - .../graphic_slider_tool/course/2012_Fall.xml | 5 - .../graphical_slider_tool/sample_gst.xml | 30 - .../policies/2012_Fall.json | 14 - .../graphic_slider_tool/roots/2012_Fall.xml | 1 - .../courseware/features/gst.feature | 10 - lms/djangoapps/courseware/features/gst.py | 76 - lms/templates/graphical_slider_tool.html | 9 - lms/templates/staff_problem_info.html | 2 +- 29 files changed, 7 insertions(+), 3175 deletions(-) delete mode 100644 common/lib/xmodule/xmodule/css/gst/display.scss delete mode 100644 common/lib/xmodule/xmodule/gst_module.py delete mode 100644 common/lib/xmodule/xmodule/js/src/graphical_slider_tool/.gitignore delete mode 100644 common/lib/xmodule/xmodule/js/src/graphical_slider_tool/el_output.js delete mode 100644 common/lib/xmodule/xmodule/js/src/graphical_slider_tool/g_label_el_output.js delete mode 100644 common/lib/xmodule/xmodule/js/src/graphical_slider_tool/general_methods.js delete mode 100644 common/lib/xmodule/xmodule/js/src/graphical_slider_tool/graph.js delete mode 100644 common/lib/xmodule/xmodule/js/src/graphical_slider_tool/gst.js delete mode 100644 common/lib/xmodule/xmodule/js/src/graphical_slider_tool/gst_main.js delete mode 100644 common/lib/xmodule/xmodule/js/src/graphical_slider_tool/inputs.js delete mode 100644 common/lib/xmodule/xmodule/js/src/graphical_slider_tool/jstat-1.0.0.min.js delete mode 100644 common/lib/xmodule/xmodule/js/src/graphical_slider_tool/sliders.js delete mode 100644 common/lib/xmodule/xmodule/js/src/graphical_slider_tool/state.js delete mode 100644 common/test/data/graphic_slider_tool/README.md delete mode 120000 common/test/data/graphic_slider_tool/course.xml delete mode 100644 common/test/data/graphic_slider_tool/course/2012_Fall.xml delete mode 100644 common/test/data/graphic_slider_tool/graphical_slider_tool/sample_gst.xml delete mode 100644 common/test/data/graphic_slider_tool/policies/2012_Fall.json delete mode 100644 common/test/data/graphic_slider_tool/roots/2012_Fall.xml delete mode 100644 lms/djangoapps/courseware/features/gst.feature delete mode 100644 lms/djangoapps/courseware/features/gst.py delete mode 100644 lms/templates/graphical_slider_tool.html diff --git a/cms/djangoapps/contentstore/views/tests/test_item.py b/cms/djangoapps/contentstore/views/tests/test_item.py index 6ecc9f97eb1..c17917f326e 100644 --- a/cms/djangoapps/contentstore/views/tests/test_item.py +++ b/cms/djangoapps/contentstore/views/tests/test_item.py @@ -1374,15 +1374,6 @@ class TestComponentTemplates(CourseTestCase): self.assertNotEqual(only_template.get('category'), 'video') self.assertNotEqual(only_template.get('category'), 'openassessment') - def test_advanced_components_without_display_name(self): - """ - Test that advanced components without display names display their category instead. - """ - self.course.advanced_modules.append('graphical_slider_tool') - self.templates = get_component_templates(self.course) - template = self.get_templates_of_type('advanced')[0] - self.assertEqual(template.get('display_name'), 'graphical_slider_tool') - def test_advanced_problems(self): """ Test the handling of advanced problem templates. diff --git a/cms/envs/common.py b/cms/envs/common.py index af89b610c3a..ce1d565bba2 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -997,7 +997,6 @@ ADVANCED_COMPONENT_TYPES = [ 'videoannotation', # module for annotating video (with annotation table) 'imageannotation', # module for annotating image (with annotation table) 'word_cloud', - 'graphical_slider_tool', 'lti', 'lti_consumer', 'library_content', @@ -1115,7 +1114,11 @@ CREDIT_PROVIDER_TIMESTAMP_EXPIRATION = 15 * 60 ################################ Deprecated Blocks Info ################################ -DEPRECATED_BLOCK_TYPES = ['peergrading', 'combinedopenended'] +DEPRECATED_BLOCK_TYPES = [ + 'peergrading', + 'combinedopenended', + 'graphical_slider_tool', +] #### PROCTORING CONFIGURATION DEFAULTS diff --git a/common/lib/xmodule/setup.py b/common/lib/xmodule/setup.py index 1bf6ce53244..d697067efe8 100644 --- a/common/lib/xmodule/setup.py +++ b/common/lib/xmodule/setup.py @@ -28,7 +28,6 @@ XMODULES = [ "static_tab = xmodule.html_module:StaticTabDescriptor", "custom_tag_template = xmodule.raw_module:RawDescriptor", "about = xmodule.html_module:AboutDescriptor", - "graphical_slider_tool = xmodule.gst_module:GraphicalSliderToolDescriptor", "annotatable = xmodule.annotatable_module:AnnotatableDescriptor", "textannotation = xmodule.textannotation_module:TextAnnotationDescriptor", "videoannotation = xmodule.videoannotation_module:VideoAnnotationDescriptor", diff --git a/common/lib/xmodule/xmodule/css/gst/display.scss b/common/lib/xmodule/xmodule/css/gst/display.scss deleted file mode 100644 index 83ca4650f0c..00000000000 --- a/common/lib/xmodule/xmodule/css/gst/display.scss +++ /dev/null @@ -1,44 +0,0 @@ -// In the LMS sliders use built-in styles from jquery-ui-1.8.22.custom.css. -// CMS uses its own sliders styles. -// These styles we use only to sure, that slider in GST module -// will be render correctly (just like a duplication some from jquery-ui-1.8.22.custom.css). -// Cause, for example, CMS overwrites many jquery-ui-1.8.22.custom.css styles, -// and we must overwrite them again. - -.ui-widget-content { - border: 1px solid #dddddd; - color: #333333; -} - -.ui-widget { - font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; - font-size: 1.1em; -} - -.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; -} \ No newline at end of file diff --git a/common/lib/xmodule/xmodule/gst_module.py b/common/lib/xmodule/xmodule/gst_module.py deleted file mode 100644 index 27ba362db51..00000000000 --- a/common/lib/xmodule/xmodule/gst_module.py +++ /dev/null @@ -1,241 +0,0 @@ -""" -Graphical slider tool module is ungraded xmodule used by students to -understand functional dependencies. -""" - -import json -import logging -from lxml import etree -from lxml import html -import xmltodict - -from xmodule.editing_module import XMLEditingDescriptor -from xmodule.xml_module import XmlDescriptor -from xmodule.x_module import XModule -from xmodule.stringify import stringify_children -from pkg_resources import resource_string -from xblock.fields import String, Scope - -log = logging.getLogger(__name__) - -DEFAULT_RENDER = """ - <h2>Graphic slider tool: Dynamic range and implicit functions.</h2> - - <p>You can make the range of the x axis (but not ticks of x axis) of - functions depend on a parameter value. This can be useful when the - function domain needs to be variable.</p> - <p>Implicit functions like a circle can be plotted as 2 separate - functions of the same color.</p> - <div style="height:50px;"> - <slider var='r' style="width:400px;float:left;"/> - <textbox var='r' style="float:left;width:60px;margin-left:15px;"/> - </div> - <plot style="margin-top:15px;margin-bottom:15px;"/> -""" - -DEFAULT_CONFIGURATION = """ - <parameters> - <param var="r" min="5" max="25" step="0.5" initial="12.5" /> - </parameters> - <functions> - <function color="red">Math.sqrt(r * r - x * x)</function> - <function color="red">-Math.sqrt(r * r - x * x)</function> - <function color="red">Math.sqrt(r * r / 20 - Math.pow(x-r/2.5, 2)) + r/8</function> - <function color="red">-Math.sqrt(r * r / 20 - Math.pow(x-r/2.5, 2)) + r/5.5</function> - <function color="red">Math.sqrt(r * r / 20 - Math.pow(x+r/2.5, 2)) + r/8</function> - <function color="red">-Math.sqrt(r * r / 20 - Math.pow(x+r/2.5, 2)) + r/5.5</function> - <function color="red">-Math.sqrt(r * r / 5 - x * x) - r/5.5</function> - </functions> - <plot> - <xrange> - <!-- dynamic range --> - <min>-r</min> - <max>r</max> - </xrange> - <num_points>1000</num_points> - <xticks>-30, 6, 30</xticks> - <yticks>-30, 6, 30</yticks> - </plot> -""" - - -class GraphicalSliderToolFields(object): - data = String( - help="Html contents to display for this module", - default='<render>{}</render><configuration>{}</configuration>'.format( - DEFAULT_RENDER, DEFAULT_CONFIGURATION), - scope=Scope.content - ) - - -class GraphicalSliderToolModule(GraphicalSliderToolFields, XModule): - ''' Graphical-Slider-Tool Module - ''' - - js = { - 'coffee': [resource_string(__name__, 'js/src/javascript_loader.coffee')], - 'js': [ - # 3rd party libraries used by graphic slider tool. - # TODO - where to store them - outside xmodule? - resource_string(__name__, 'js/src/graphical_slider_tool/gst_main.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/state.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/general_methods.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/sliders.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/inputs.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/graph.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/el_output.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/g_label_el_output.js'), - resource_string(__name__, 'js/src/graphical_slider_tool/gst.js') - ] - } - css = {'scss': [resource_string(__name__, 'css/gst/display.scss')]} - js_module_name = "GraphicalSliderTool" - - @property - def configuration(self): - return stringify_children( - html.fromstring(self.data).xpath('configuration')[0] - ) - - @property - def render(self): - return stringify_children( - html.fromstring(self.data).xpath('render')[0] - ) - - def get_html(self): - """ Renders parameters to template. """ - - # these 3 will be used in class methods - self.html_id = self.location.html_id() - self.html_class = self.location.category - - self.configuration_json = self.build_configuration_json() - params = { - 'gst_html': self.substitute_controls(self.render), - 'element_id': self.html_id, - 'element_class': self.html_class, - 'configuration_json': self.configuration_json - } - content = self.system.render_template( - 'graphical_slider_tool.html', params - ) - return content - - def substitute_controls(self, html_string): - """ Substitutes control elements (slider, textbox and plot) in - html_string with their divs. Html_string is content of <render> tag - inside <graphical_slider_tool> tag. Documentation on how information in - <render> tag is organized and processed is located in: - edx-platform/docs/build/html/graphical_slider_tool.html. - - Args: - html_string: content of <render> tag, with controls as xml tags, - e.g. <slider var="a"/>. - - Returns: - html_string with control tags replaced by proper divs - (<slider var="a"/> -> <div class="....slider" > </div>) - """ - - xml = html.fromstring(html_string) - - # substitute plot, if presented - plot_div = '<div class="{element_class}_plot" id="{element_id}_plot" \ - style="{style}"></div>' - plot_el = xml.xpath('//plot') - if plot_el: - plot_el = plot_el[0] - plot_el.getparent().replace(plot_el, html.fromstring( - plot_div.format( - element_class=self.html_class, - element_id=self.html_id, - style=plot_el.get('style', "")))) - - # substitute sliders - slider_div = '<div class="{element_class}_slider" \ - id="{element_id}_slider_{var}" \ - data-var="{var}" \ - style="{style}">\ - </div>' - slider_els = xml.xpath('//slider') - for slider_el in slider_els: - slider_el.getparent().replace(slider_el, html.fromstring( - slider_div.format( - element_class=self.html_class, - element_id=self.html_id, - var=slider_el.get('var', ""), - style=slider_el.get('style', "")))) - - # substitute inputs aka textboxes - input_div = '<input class="{element_class}_input" \ - id="{element_id}_input_{var}_{input_index}" \ - data-var="{var}" style="{style}"/>' - input_els = xml.xpath('//textbox') - for input_index, input_el in enumerate(input_els): - input_el.getparent().replace(input_el, html.fromstring( - input_div.format( - element_class=self.html_class, - element_id=self.html_id, - var=input_el.get('var', ""), - style=input_el.get('style', ""), - input_index=input_index))) - - return html.tostring(xml) - - def build_configuration_json(self): - """Creates json element from xml element (with aim to transfer later - directly to javascript via hidden field in template). Steps: - - 1. Convert xml tree to python dict. - - 2. Dump dict to json. - - """ - # <root> added for interface compatibility with xmltodict.parse - # class added for javascript's part purposes - root = '<root class="{}">{}</root>'.format( - self.html_class, - self.configuration) - return json.dumps(xmltodict.parse(root)) - - -class GraphicalSliderToolDescriptor(GraphicalSliderToolFields, XMLEditingDescriptor, XmlDescriptor): - module_class = GraphicalSliderToolModule - - @classmethod - def definition_from_xml(cls, xml_object, system): - """ - Pull out the data into dictionary. - - Args: - xml_object: xml from file. - - Returns: - dict - """ - # check for presense of required tags in xml - expected_children_level_0 = ['render', 'configuration'] - for child in expected_children_level_0: - if len(xml_object.xpath(child)) != 1: - raise ValueError(u"Graphical Slider Tool definition must include \ - exactly one '{0}' tag".format(child)) - - expected_children_level_1 = ['functions'] - for child in expected_children_level_1: - if len(xml_object.xpath('configuration')[0].xpath(child)) != 1: - raise ValueError(u"Graphical Slider Tool definition must include \ - exactly one '{0}' tag".format(child)) - # finished - - return { - 'data': stringify_children(xml_object) - }, [] - - def definition_to_xml(self, resource_fs): - '''Return an xml element representing this definition.''' - data = u'<{tag}>{body}</{tag}>'.format( - tag='graphical_slider_tool', - body=self.data) - xml_object = etree.fromstring(data) - return xml_object diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/.gitignore b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/.gitignore deleted file mode 100644 index d4aa116a26c..00000000000 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/.gitignore +++ /dev/null @@ -1 +0,0 @@ -!*.js diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/el_output.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/el_output.js deleted file mode 100644 index f81cdc000be..00000000000 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/el_output.js +++ /dev/null @@ -1,141 +0,0 @@ -// Wrapper for RequireJS. It will make the standard requirejs(), require(), and -// define() functions from Require JS available inside the anonymous function. -(function (requirejs, require, define) { - -define('ElOutput', [], function () { - - return ElOutput; - - function ElOutput(config, state) { - - if ($.isPlainObject(config.functions["function"])) { - processFuncObj(config.functions["function"]); - } else if ($.isArray(config.functions["function"])) { - (function (c1) { - while (c1 < config.functions["function"].length) { - if ($.isPlainObject(config.functions["function"][c1])) { - processFuncObj(config.functions["function"][c1]); - } - - c1 += 1; - } - }(0)); - } - - return; - - function processFuncObj(obj) { - var paramNames, funcString, func, el, disableAutoReturn, updateOnEvent; - - // We are only interested in functions that are meant for output to an - // element. - if ( - (typeof obj['@output'] !== 'string') || - ((obj['@output'].toLowerCase() !== 'element') && (obj['@output'].toLowerCase() !== 'none')) - ) { - return; - } - - if (typeof obj['@el_id'] !== 'string') { - console.log('ERROR: You specified "output" as "element", but did not spify "el_id".'); - - return; - } - - if (typeof obj['#text'] !== 'string') { - console.log('ERROR: Function body is not defined.'); - - return; - } - - updateOnEvent = 'slide'; - if ( - (obj.hasOwnProperty('@update_on') === true) && - (typeof obj['@update_on'] === 'string') && - ((obj['@update_on'].toLowerCase() === 'slide') || (obj['@update_on'].toLowerCase() === 'change')) - ) { - updateOnEvent = obj['@update_on'].toLowerCase(); - } - - disableAutoReturn = obj['@disable_auto_return']; - - funcString = obj['#text']; - - if ( - (disableAutoReturn === undefined) || - ( - (typeof disableAutoReturn === 'string') && - (disableAutoReturn.toLowerCase() !== 'true') - ) - ) { - if (funcString.search(/return/i) === -1) { - funcString = 'return ' + funcString; - } - } else { - if (funcString.search(/return/i) === -1) { - console.log( - 'ERROR: You have specified a JavaScript ' + - 'function without a "return" statemnt. Your ' + - 'function will return "undefined" by default.' - ); - } - } - - // Make sure that all HTML entities are converted to their proper - // ASCII text equivalents. - funcString = $('<div>').html(funcString).text(); - - paramNames = state.getAllParameterNames(); - paramNames.push(funcString); - - try { - func = Function.apply(null, paramNames); - } catch (err) { - console.log( - 'ERROR: The function body "' + - funcString + - '" was not converted by the Function constructor.' - ); - console.log('Error message: "' + err.message + '".'); - - if (state.showDebugInfo) { - $('#' + gstId).html('<div style="color: red;">' + 'ERROR IN XML: Could not create a function from string "' + funcString + '".' + '</div>'); - $('#' + gstId).append('<div style="color: red;">' + 'Error message: "' + err.message + '".' + '</div>'); - } - - paramNames.pop(); - - return; - } - - paramNames.pop(); - - if (obj['@output'].toLowerCase() !== 'none') { - el = $('#' + obj['@el_id']); - - if (el.length !== 1) { - console.log( - 'ERROR: DOM element with ID "' + obj['@el_id'] + '" ' + - 'not found. Dynamic element not created.' - ); - - return; - } - - el.html(func.apply(window, state.getAllParameterValues())); - } else { - el = null; - func.apply(window, state.getAllParameterValues()); - } - - state.addDynamicEl(el, func, obj['@el_id'], updateOnEvent); - } - - } -}); - -// End of wrapper for RequireJS. As you can see, we are passing -// namespaced Require JS variables to an anonymous function. Within -// it, you can use the standard requirejs(), require(), and define() -// functions as if they were in the global namespace. -}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define) diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/g_label_el_output.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/g_label_el_output.js deleted file mode 100644 index 3ad264d9eb0..00000000000 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/g_label_el_output.js +++ /dev/null @@ -1,115 +0,0 @@ -// Wrapper for RequireJS. It will make the standard requirejs(), require(), and -// define() functions from Require JS available inside the anonymous function. -(function (requirejs, require, define) { - -define('GLabelElOutput', [], function () { - return GLabelElOutput; - - function GLabelElOutput(config, state) { - if ($.isPlainObject(config.functions["function"])) { - processFuncObj(config.functions["function"]); - } else if ($.isArray(config.functions["function"])) { - (function (c1) { - while (c1 < config.functions["function"].length) { - if ($.isPlainObject(config.functions["function"][c1])) { - processFuncObj(config.functions["function"][c1]); - } - - c1 += 1; - } - }(0)); - } - - return; - - function processFuncObj(obj) { - var paramNames, funcString, func, disableAutoReturn; - - // We are only interested in functions that are meant for output to an - // element. - if ( - (typeof obj['@output'] !== 'string') || - (obj['@output'].toLowerCase() !== 'plot_label') - ) { - return; - } - - if (typeof obj['@el_id'] !== 'string') { - console.log('ERROR: You specified "output" as "plot_label", but did not spify "el_id".'); - - return; - } - - if (typeof obj['#text'] !== 'string') { - console.log('ERROR: Function body is not defined.'); - - return; - } - - disableAutoReturn = obj['@disable_auto_return']; - - funcString = obj['#text']; - - if ( - (disableAutoReturn === undefined) || - ( - (typeof disableAutoReturn === 'string') && - (disableAutoReturn.toLowerCase() !== 'true') - ) - ) { - if (funcString.search(/return/i) === -1) { - funcString = 'return ' + funcString; - } - } else { - if (funcString.search(/return/i) === -1) { - console.log( - 'ERROR: You have specified a JavaScript ' + - 'function without a "return" statemnt. Your ' + - 'function will return "undefined" by default.' - ); - } - } - - // Make sure that all HTML entities are converted to their proper - // ASCII text equivalents. - funcString = $('<div>').html(funcString).text(); - - paramNames = state.getAllParameterNames(); - paramNames.push(funcString); - - try { - func = Function.apply(null, paramNames); - } catch (err) { - console.log( - 'ERROR: The function body "' + - funcString + - '" was not converted by the Function constructor.' - ); - console.log('Error message: "' + err.message + '".'); - - if (state.showDebugInfo) { - $('#' + gstId).html('<div style="color: red;">' + 'ERROR IN XML: Could not create a function from string "' + funcString + '".' + '</div>'); - $('#' + gstId).append('<div style="color: red;">' + 'Error message: "' + err.message + '".' + '</div>'); - } - - paramNames.pop(); - - return; - } - - paramNames.pop(); - - state.plde.push({ - 'elId': obj['@el_id'], - 'func': func - }); - } - - } -}); - -// End of wrapper for RequireJS. As you can see, we are passing -// namespaced Require JS variables to an anonymous function. Within -// it, you can use the standard requirejs(), require(), and define() -// functions as if they were in the global namespace. -}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define) diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/general_methods.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/general_methods.js deleted file mode 100644 index 9cdd4fff0f2..00000000000 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/general_methods.js +++ /dev/null @@ -1,23 +0,0 @@ -// Wrapper for RequireJS. It will make the standard requirejs(), require(), and -// define() functions from Require JS available inside the anonymous function. -(function (requirejs, require, define) { - -define('GeneralMethods', [], function () { - if (!String.prototype.trim) { - // http://blog.stevenlevithan.com/archives/faster-trim-javascript - String.prototype.trim = function trim(str) { - return str.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); - }; - } - - return { - 'module_name': 'GeneralMethods', - 'module_status': 'OK' - }; -}); - -// End of wrapper for RequireJS. As you can see, we are passing -// namespaced Require JS variables to an anonymous function. Within -// it, you can use the standard requirejs(), require(), and define() -// functions as if they were in the global namespace. -}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define) diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/graph.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/graph.js deleted file mode 100644 index cc221490eb3..00000000000 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/graph.js +++ /dev/null @@ -1,1512 +0,0 @@ -// Wrapper for RequireJS. It will make the standard requirejs(), require(), and -// define() functions from Require JS available inside the anonymous function. -(function (requirejs, require, define) { - -define('Graph', [], function () { - - return Graph; - - function Graph(gstId, config, state) { - var plotDiv, dataSeries, functions, xaxis, yaxis, numPoints, xrange, - asymptotes, movingLabels, xTicksNames, yTicksNames, graphBarWidth, graphBarAlign; - - // We need plot configuration settings. Without them we can't continue. - if ($.isPlainObject(config.plot) === false) { - return; - } - - // We must have a graph container DIV element available in order to - // proceed. - plotDiv = $('#' + gstId + '_plot'); - if (plotDiv.length === 0) { - console.log('ERROR: Could not find the plot DIV with ID "' + gstId + '_plot".'); - - return; - } - - if (plotDiv.width() === 0) { - plotDiv.width(300); - } - - // Sometimes, when height is not explicitly set via CSS (or by some - // other means), it is 0 pixels by default. When Flot will try to plot - // a graph in this DIV with 0 height, then it will raise an error. To - // prevent this, we will set it to be equal to the width. - if (plotDiv.height() === 0) { - plotDiv.height(plotDiv.width()); - } - - plotDiv.css('position', 'relative'); - - // Configure some settings for the graph. - if (setGraphXRange() === false) { - console.log('ERROR: Could not configure the xrange. Will not continue.'); - - return; - } - - if (setGraphAxes() === false) { - console.log('ERROR: Could not process configuration for the axes.'); - - return; - } - - graphBarWidth = 1; - graphBarAlign = null; - - getBarWidth(); - getBarAlign(); - - // Get the user defined functions. If there aren't any, don't do - // anything else. - createFunctions(); - - if (functions.length === 0) { - console.log('ERROR: No functions were specified, or something went wrong.'); - - return; - } - - if (createMarkingsFunctions() === false) { - return; - } - if (createMovingLabelFunctions() === false) { - return; - } - - // Create the initial graph and plot it for the user to see. - if (generateData() === true) { - updatePlot(); - } - - // Bind an event. Whenever some constant changes, the graph will be - // redrawn - state.bindUpdatePlotEvent(plotDiv, onUpdatePlot); - - return; - - function getBarWidth() { - if (config.plot.hasOwnProperty('bar_width') === false) { - return; - } - - if (typeof config.plot.bar_width !== 'string') { - console.log('ERROR: The parameter config.plot.bar_width must be a string.'); - - return; - } - - if (isFinite(graphBarWidth = parseFloat(config.plot.bar_width)) === false) { - console.log('ERROR: The parameter config.plot.bar_width is not a valid floating number.'); - graphBarWidth = 1; - - return; - } - - return; - } - - function getBarAlign() { - if (config.plot.hasOwnProperty('bar_align') === false) { - return; - } - - if (typeof config.plot.bar_align !== 'string') { - console.log('ERROR: The parameter config.plot.bar_align must be a string.'); - - return; - } - - if ( - (config.plot.bar_align.toLowerCase() !== 'left') && - (config.plot.bar_align.toLowerCase() !== 'center') - ) { - console.log('ERROR: Property config.plot.bar_align can be one of "left", or "center".'); - - return; - } - - graphBarAlign = config.plot.bar_align.toLowerCase(); - - return; - } - - function createMovingLabelFunctions() { - var c1, returnStatus; - - returnStatus = true; - movingLabels = []; - - if (config.plot.hasOwnProperty('moving_label') !== true) { - returnStatus = true; - } else if ($.isPlainObject(config.plot.moving_label) === true) { - if (processMovingLabel(config.plot.moving_label) === false) { - returnStatus = false; - } - } else if ($.isArray(config.plot.moving_label) === true) { - for (c1 = 0; c1 < config.plot.moving_label.length; c1++) { - if (processMovingLabel(config.plot.moving_label[c1]) === false) { - returnStatus = false; - } - } - } - - return returnStatus; - } - - function processMovingLabel(obj) { - var labelText, funcString, disableAutoReturn, paramNames, func, - fontWeight, fontColor; - - if (obj.hasOwnProperty('@text') === false) { - console.log('ERROR: You did not define a "text" attribute for the moving_label.'); - - return false; - } - if (typeof obj['@text'] !== 'string') { - console.log('ERROR: "text" attribute is not a string.'); - - return false; - } - labelText = obj['@text']; - - if (obj.hasOwnProperty('#text') === false) { - console.log('ERROR: moving_label is missing function declaration.'); - - return false; - } - if (typeof obj['#text'] !== 'string') { - console.log('ERROR: Function declaration is not a string.'); - - return false; - } - funcString = obj['#text']; - - fontColor = 'black'; - if ( - (obj.hasOwnProperty('@color') === true) && - (typeof obj['@color'] === 'string') - ) { - fontColor = obj['@color']; - } - - fontWeight = 'normal'; - if ( - (obj.hasOwnProperty('@weight') === true) && - (typeof obj['@weight'] === 'string') - ) { - if ( - (obj['@weight'].toLowerCase() === 'normal') || - (obj['@weight'].toLowerCase() === 'bold') - ) { - fontWeight = obj['@weight']; - } else { - console.log('ERROR: Moving label can have a weight property of "normal" or "bold".'); - } - } - - disableAutoReturn = obj['@disable_auto_return']; - - funcString = $('<div>').html(funcString).text(); - - if ( - (disableAutoReturn === undefined) || - ( - (typeof disableAutoReturn === 'string') && - (disableAutoReturn.toLowerCase() !== 'true') - ) - ) { - if (funcString.search(/return/i) === -1) { - funcString = 'return ' + funcString; - } - } else { - if (funcString.search(/return/i) === -1) { - console.log( - 'ERROR: You have specified a JavaScript ' + - 'function without a "return" statemnt. Your ' + - 'function will return "undefined" by default.' - ); - } - } - - paramNames = state.getAllParameterNames(); - paramNames.push(funcString); - - try { - func = Function.apply(null, paramNames); - } catch (err) { - console.log( - 'ERROR: The function body "' + - funcString + - '" was not converted by the Function constructor.' - ); - console.log('Error message: "' + err.message + '"'); - - if (state.showDebugInfo) { - $('#' + gstId).html('<div style="color: red;">' + 'ERROR IN XML: Could not create a function from the string "' + funcString + '".' + '</div>'); - $('#' + gstId).append('<div style="color: red;">' + 'Error message: "' + err.message + '".' + '</div>'); - } - - paramNames.pop(); - - return false; - } - - paramNames.pop(); - - movingLabels.push({ - 'labelText': labelText, - 'func': func, - 'el': null, - 'fontColor': fontColor, - 'fontWeight': fontWeight - }); - - return true; - } - - function createMarkingsFunctions() { - var c1, paramNames, returnStatus; - - returnStatus = true; - - asymptotes = []; - paramNames = state.getAllParameterNames(); - - if ($.isPlainObject(config.plot.asymptote)) { - if (processAsymptote(config.plot.asymptote) === false) { - returnStatus = false; - } - } else if ($.isArray(config.plot.asymptote)) { - for (c1 = 0; c1 < config.plot.asymptote.length; c1 += 1) { - if (processAsymptote(config.plot.asymptote[c1]) === false) { - returnStatus = false; - } - } - } - - return returnStatus; - - // Read configuration options for asymptotes, and store them as - // an array of objects. Each object will have 3 properties: - // - // - color: the color of the asymptote line - // - type: 'x' (vertical), or 'y' (horizontal) - // - func: the function that will generate the value at which - // the asymptote will be plotted; i.e. x = func(), or - // y = func(); for now only horizontal and vertical - // asymptotes are supported - // - // Since each asymptote can have a variable function - function - // that relies on some parameter specified in the config - we will - // generate each asymptote just before we draw the graph. See: - // - // function updatePlot() - // function generateMarkings() - // - // Asymptotes are really thin rectangles implemented via the Flot's - // markings option. - function processAsymptote(asyObj) { - var newAsyObj, funcString, func; - - newAsyObj = {}; - - if (typeof asyObj['@type'] === 'string') { - if (asyObj['@type'].toLowerCase() === 'x') { - newAsyObj.type = 'x'; - } else if (asyObj['@type'].toLowerCase() === 'y') { - newAsyObj.type = 'y'; - } else { - console.log('ERROR: Attribute "type" for asymptote can be "x" or "y".'); - - return false; - } - } else { - console.log('ERROR: Attribute "type" for asymptote is not specified.'); - - return false; - } - - if (typeof asyObj['#text'] === 'string') { - funcString = asyObj['#text']; - } else { - console.log('ERROR: Function body for asymptote is not specified.'); - - return false; - } - - newAsyObj.color = '#000'; - if (typeof asyObj['@color'] === 'string') { - newAsyObj.color = asyObj['@color']; - } - - newAsyObj.label = false; - if ( - (asyObj.hasOwnProperty('@label') === true) && - (typeof asyObj['@label'] === 'string') - ) { - newAsyObj.label = asyObj['@label']; - } - - funcString = $('<div>').html(funcString).text(); - - disableAutoReturn = asyObj['@disable_auto_return']; - if ( - (disableAutoReturn === undefined) || - ( - (typeof disableAutoReturn === 'string') && - (disableAutoReturn.toLowerCase() !== 'true') - ) - ) { - if (funcString.search(/return/i) === -1) { - funcString = 'return ' + funcString; - } - } else { - if (funcString.search(/return/i) === -1) { - console.log( - 'ERROR: You have specified a JavaScript ' + - 'function without a "return" statemnt. Your ' + - 'function will return "undefined" by default.' - ); - } - } - - paramNames.push(funcString); - - try { - func = Function.apply(null, paramNames); - } catch (err) { - console.log('ERROR: Asymptote function body could not be converted to function object.'); - console.log('Error message: "".' + err.message); - - return false; - } - - paramNames.pop(); - - newAsyObj.func = func; - asymptotes.push(newAsyObj); - - return true; - } - } - - function setGraphAxes() { - xaxis = { - 'tickFormatter': null - }; - - if (typeof config.plot['xticks'] === 'string') { - if (processTicks(config.plot['xticks'], xaxis, 'xunits') === false) { - console.log('ERROR: Could not process the ticks for x-axis.'); - - return false; - } - } else { - // console.log('MESSAGE: "xticks" were not specified. Using defaults.'); - - return false; - } - - yaxis = { - 'tickFormatter': null - }; - if (typeof config.plot['yticks'] === 'string') { - if (processTicks(config.plot['yticks'], yaxis, 'yunits') === false) { - console.log('ERROR: Could not process the ticks for y-axis.'); - - return false; - } - } else { - // console.log('MESSAGE: "yticks" were not specified. Using defaults.'); - - return false; - } - - xTicksNames = null; - yTicksNames = null; - - if (checkForTicksNames('x') === false) { - return false; - } - - if (checkForTicksNames('y') === false) { - return false; - } - - return true; - - // - // function checkForTicksNames(axisName) - // - // The parameter "axisName" can be either "x" or "y" (string). Depending on it, the function - // will set "xTicksNames" or "yTicksNames" private variable. - // - // This function does not return anything. It sets the private variable "xTicksNames" ("yTicksNames") - // to the object converted by JSON.parse from the XML parameter "plot.xticks_names" ("plot.yticks_names"). - // If the "plot.xticks_names" ("plot.yticks_names") is missing or it is not a valid JSON string, then - // "xTicksNames" ("yTicksNames") will be set to "null". - // - // Depending on the "xTicksNames" ("yTicksNames") being "null" or an object, the plot will either draw - // number ticks, or use the names specified by the opbject. - // - function checkForTicksNames(axisName) { - var tmpObj; - - if ((axisName !== 'x') && (axisName !== 'y')) { - // This is not an error. This funcion should simply stop executing. - - return true; - } - - if ( - (config.plot.hasOwnProperty(axisName + 'ticks_names') === true) || - (typeof config.plot[axisName + 'ticks_names'] === 'string') - ) { - try { - tmpObj = JSON.parse(config.plot[axisName + 'ticks_names']); - } catch (err) { - console.log( - 'ERROR: plot.' + axisName + 'ticks_names is not a valid JSON string.', - 'Error message: "' + err.message + '".' - ); - - return false; - } - - if (axisName === 'x') { - xTicksNames = tmpObj; - xaxis.tickFormatter = xAxisTickFormatter; - } - // At this point, we are certain that axisName = 'y'. - else { - yTicksNames = tmpObj; - yaxis.tickFormatter = yAxisTickFormatter; - } - } - } - - function processTicks(ticksStr, ticksObj, unitsType) { - var ticksBlobs, tempFloat, tempTicks, c1, c2; - - // The 'ticks' setting is a string containing 3 floating-point - // numbers. - ticksBlobs = ticksStr.split(','); - - if (ticksBlobs.length !== 3) { - console.log('ERROR: Did not get 3 blobs from ticksStr = "' + ticksStr + '".'); - - return false; - } - - tempFloat = parseFloat(ticksBlobs[0]); - if (isNaN(tempFloat) === false) { - ticksObj.min = tempFloat; - } else { - console.log('ERROR: Invalid "min". ticksBlobs[0] = ', ticksBlobs[0]); - - return false; - } - - tempFloat = parseFloat(ticksBlobs[1]); - if (isNaN(tempFloat) === false) { - ticksObj.tickSize = tempFloat; - } else { - console.log('ERROR: Invalid "tickSize". ticksBlobs[1] = ', ticksBlobs[1]); - - return false; - } - - tempFloat = parseFloat(ticksBlobs[2]); - if (isNaN(tempFloat) === false) { - ticksObj.max = tempFloat; - } else { - console.log('ERROR: Invalid "max". ticksBlobs[2] = ', ticksBlobs[2]); - - return false; - } - - // Is the starting tick to the left of the ending tick (on the - // x-axis)? If not, set default starting and ending tick. - if (ticksObj.min >= ticksObj.max) { - console.log('ERROR: Ticks min >= max.'); - - return false; - } - - // Make sure the range makes sense - i.e. that there are at - // least 3 ticks. If not, set a tickSize which will produce - // 11 ticks. tickSize is the spacing between the ticks. - if (ticksObj.tickSize > ticksObj.max - ticksObj.min) { - console.log('ERROR: tickSize > max - min.'); - - return false; - } - - // units: change last tick to units - if (typeof config.plot[unitsType] === 'string') { - tempTicks = []; - - for (c1 = ticksObj.min; c1 <= ticksObj.max; c1 += ticksObj.tickSize) { - c2 = roundToPrec(c1, ticksObj.tickSize); - tempTicks.push([c2, c2]); - } - - tempTicks.pop(); - tempTicks.push([ - roundToPrec(ticksObj.max, ticksObj.tickSize), - config.plot[unitsType] - ]); - - ticksObj.tickSize = null; - ticksObj.ticks = tempTicks; - } - - return true; - - function roundToPrec(num, prec) { - var c1, tn1, tn2, digitsBefore, digitsAfter; - - tn1 = Math.abs(num); - tn2 = Math.abs(prec); - - // Find out number of digits BEFORE the decimal point. - c1 = 0; - tn1 = Math.abs(num); - while (tn1 >= 1) { - c1 += 1; - - tn1 /= 10; - } - digitsBefore = c1; - - // Find out number of digits AFTER the decimal point. - c1 = 0; - tn1 = Math.abs(num); - while (Math.round(tn1) !== tn1) { - c1 += 1; - - tn1 *= 10; - } - digitsAfter = c1; - - // For precision, find out number of digits AFTER the - // decimal point. - c1 = 0; - while (Math.round(tn2) !== tn2) { - c1 += 1; - - tn2 *= 10; - } - - // If precision is more than 1 (no digits after decimal - // points). - if (c1 === 0) { - return num; - } - - // If the precision contains digits after the decimal - // point, we apply special rules. - else { - tn1 = Math.abs(num); - - // if (digitsAfter > c1) { - tn1 = tn1.toFixed(c1); - // } else { - // tn1 = tn1.toPrecision(digitsBefore + digitsAfter); - // } - } - - if (num < 0) { - return -tn1; - } - - return tn1; - } - } - } - - function setGraphXRange() { - var xRangeStr, xRangeBlobs, tempNum, allParamNames, funcString, - disableAutoReturn; - - xrange = {}; - - if ($.isPlainObject(config.plot.xrange) === false) { - console.log( - 'ERROR: Expected config.plot.xrange to be an object. ' + - 'It is not.' - ); - console.log('config.plot.xrange = ', config.plot.xrange); - - return false; - } - - if (config.plot.xrange.hasOwnProperty('min') === false) { - console.log( - 'ERROR: Expected config.plot.xrange.min to be ' + - 'present. It is not.' - ); - - return false; - } - - disableAutoReturn = false; - if (typeof config.plot.xrange.min === 'string') { - funcString = config.plot.xrange.min; - } else if ( - ($.isPlainObject(config.plot.xrange.min) === true) && - (config.plot.xrange.min.hasOwnProperty('#text') === true) && - (typeof config.plot.xrange.min['#text'] === 'string') - ) { - funcString = config.plot.xrange.min['#text']; - - disableAutoReturn = - config.plot.xrange.min['@disable_auto_return']; - if ( - (disableAutoReturn === undefined) || - ( - (typeof disableAutoReturn === 'string') && - (disableAutoReturn.toLowerCase() !== 'true') - ) - ) { - disableAutoReturn = false; - } else { - disableAutoReturn = true; - } - } else { - console.log( - 'ERROR: Could not get a function definition for ' + - 'xrange.min property.' - ); - - return false; - } - - funcString = $('<div>').html(funcString).text(); - - if (disableAutoReturn === false) { - if (funcString.search(/return/i) === -1) { - funcString = 'return ' + funcString; - } - } else { - if (funcString.search(/return/i) === -1) { - console.log( - 'ERROR: You have specified a JavaScript ' + - 'function without a "return" statemnt. Your ' + - 'function will return "undefined" by default.' - ); - } - } - - allParamNames = state.getAllParameterNames(); - - allParamNames.push(funcString); - try { - xrange.min = Function.apply(null, allParamNames); - } catch (err) { - console.log( - 'ERROR: could not create a function from the string "' + - funcString + '" for xrange.min.' - ); - console.log('Error message: "' + err.message + '"'); - - if (state.showDebugInfo) { - $('#' + gstId).html( - '<div style="color: red;">' + 'ERROR IN ' + - 'XML: Could not create a function from the string "' + - funcString + '" for xrange.min.' + '</div>' - ); - $('#' + gstId).append( - '<div style="color: red;">' + 'Error ' + - 'message: "' + err.message + '".' + '</div>' - ); - } - - return false; - } - allParamNames.pop(); - - if (config.plot.xrange.hasOwnProperty('max') === false) { - console.log( - 'ERROR: Expected config.plot.xrange.max to be ' + - 'present. It is not.' - ); - - return false; - } - - disableAutoReturn = false; - if (typeof config.plot.xrange.max === 'string') { - funcString = config.plot.xrange.max; - } else if ( - ($.isPlainObject(config.plot.xrange.max) === true) && - (config.plot.xrange.max.hasOwnProperty('#text') === true) && - (typeof config.plot.xrange.max['#text'] === 'string') - ) { - funcString = config.plot.xrange.max['#text']; - - disableAutoReturn = - config.plot.xrange.max['@disable_auto_return']; - if ( - (disableAutoReturn === undefined) || - ( - (typeof disableAutoReturn === 'string') && - (disableAutoReturn.toLowerCase() !== 'true') - ) - ) { - disableAutoReturn = false; - } else { - disableAutoReturn = true; - } - } else { - console.log( - 'ERROR: Could not get a function definition for ' + - 'xrange.max property.' - ); - - return false; - } - - funcString = $('<div>').html(funcString).text(); - - if (disableAutoReturn === false) { - if (funcString.search(/return/i) === -1) { - funcString = 'return ' + funcString; - } - } else { - if (funcString.search(/return/i) === -1) { - console.log( - 'ERROR: You have specified a JavaScript ' + - 'function without a "return" statemnt. Your ' + - 'function will return "undefined" by default.' - ); - } - } - - allParamNames.push(funcString); - try { - xrange.max = Function.apply(null, allParamNames); - } catch (err) { - console.log( - 'ERROR: could not create a function from the string "' + - funcString + '" for xrange.max.' - ); - console.log('Error message: "' + err.message + '"'); - - if (state.showDebugInfo) { - $('#' + gstId).html( - '<div style="color: red;">' + 'ERROR IN ' + - 'XML: Could not create a function from the string "' + - funcString + '" for xrange.max.' + '</div>' - ); - $('#' + gstId).append( - '<div style="color: red;">' + 'Error message: "' + - err.message + '".' + '</div>' - ); - } - - return false; - } - allParamNames.pop(); - - tempNum = parseInt(config.plot.num_points, 10); - if (isFinite(tempNum) === false) { - tempNum = plotDiv.width() / 5.0; - } - - if ( - (tempNum < 2) && - (tempNum > 1000) - ) { - console.log( - 'ERROR: Number of points is outside the allowed range ' + - '[2, 1000]' - ); - console.log('config.plot.num_points = ' + tempNum); - - return false; - } - - numPoints = tempNum; - - return true; - } - - function createFunctions() { - var c1; - - functions = []; - - if (typeof config.functions === 'undefined') { - console.log('ERROR: config.functions is undefined.'); - - return; - } - - if (typeof config.functions["function"] === 'string') { - - // If just one function string is present. - addFunction(config.functions["function"]); - - } else if ($.isPlainObject(config.functions["function"]) === true) { - - // If a function is present, but it also has properties - // defined. - callAddFunction(config.functions["function"]); - - } else if ($.isArray(config.functions["function"])) { - - // If more than one function is defined. - for (c1 = 0; c1 < config.functions["function"].length; c1 += 1) { - - // For each definition, we must check if it is a simple - // string definition, or a complex one with properties. - if (typeof config.functions["function"][c1] === 'string') { - - // Simple string. - addFunction(config.functions["function"][c1]); - - } else if ($.isPlainObject(config.functions["function"][c1])) { - - // Properties are present. - callAddFunction(config.functions["function"][c1]); - - } - } - } else { - console.log('ERROR: config.functions.function is of an unsupported type.'); - - return; - } - - return; - - // This function will reduce code duplication. We have to call - // the function addFunction() several times passing object - // properties as parameters. Rather than writing them out every - // time, we will have a single place where it is done. - function callAddFunction(obj) { - if ( - (obj.hasOwnProperty('@output')) && - (typeof obj['@output'] === 'string') - ) { - - // If this function is meant to be calculated for an - // element then skip it. - if ((obj['@output'].toLowerCase() === 'element') || - (obj['@output'].toLowerCase() === 'none')) { - return; - } - - // If this function is meant to be calculated for a - // dynamic element in a label then skip it. - else if (obj['@output'].toLowerCase() === 'plot_label') { - return; - } - - // It is an error if '@output' is not 'element', - // 'plot_label', or 'graph'. However, if the '@output' - // attribute is omitted, we will not have reached this. - else if (obj['@output'].toLowerCase() !== 'graph') { - console.log( - 'ERROR: Function "output" attribute can be ' + - 'either "element", "plot_label", "none" or "graph".' - ); - - return; - } - - } - - // The user did not specify an "output" attribute, or it is - // "graph". - addFunction( - obj['#text'], - obj['@color'], - obj['@line'], - obj['@dot'], - obj['@label'], - obj['@point_size'], - obj['@fill_area'], - obj['@bar'], - obj['@disable_auto_return'] - ); - } - - function addFunction(funcString, color, line, dot, label, - pointSize, fillArea, bar, disableAutoReturn) { - - var newFunctionObject, func, paramNames, c1, rgxp; - - // The main requirement is function string. Without it we can't - // create a function, and the series cannot be calculated. - if (typeof funcString !== 'string') { - return; - } - - // Make sure that any HTML entities that were escaped will be - // unescaped. This is done because if a string with escaped - // HTML entities is passed to the Function() constructor, it - // will break. - funcString = $('<div>').html(funcString).text(); - - // If the user did not specifically turn off this feature, - // check if the function string contains a 'return', and - // prepend a 'return ' to the string if one, or more, is not - // found. - if ( - (disableAutoReturn === undefined) || - ( - (typeof disableAutoReturn === 'string') && - (disableAutoReturn.toLowerCase() !== 'true') - ) - ) { - if (funcString.search(/return/i) === -1) { - funcString = 'return ' + funcString; - } - } else { - if (funcString.search(/return/i) === -1) { - console.log( - 'ERROR: You have specified a JavaScript ' + - 'function without a "return" statemnt. Your ' + - 'function will return "undefined" by default.' - ); - } - } - - // Some defaults. If no options are set for the graph, we will - // make sure that at least a line is drawn for a function. - newFunctionObject = { - 'line': true, - 'dot': false, - 'bars': false - }; - - // Get all of the parameter names defined by the user in the - // XML. - paramNames = state.getAllParameterNames(); - - // The 'x' is always one of the function parameters. - paramNames.push('x'); - - // Must make sure that the function body also gets passed to - // the Function constructor. - paramNames.push(funcString); - - // Create the function from the function string, and all of the - // available parameters AND the 'x' variable as it's parameters. - // For this we will use the built-in Function object - // constructor. - // - // If something goes wrong during this step, most - // likely the user supplied an invalid JavaScript function body - // string. In this case we will not proceed. - try { - func = Function.apply(null, paramNames); - } catch (err) { - console.log( - 'ERROR: The function body "' + - funcString + - '" was not converted by the Function constructor.' - ); - console.log('Error message: "' + err.message + '"'); - - if (state.showDebugInfo) { - $('#' + gstId).html('<div style="color: red;">' + 'ERROR IN XML: Could not create a function from the string "' + funcString + '".' + '</div>'); - $('#' + gstId).append('<div style="color: red;">' + 'Error message: "' + err.message + '".' + '</div>'); - } - - paramNames.pop(); - paramNames.pop(); - - return; - } - - // Return the array back to original state. Remember that it is - // a pointer to original array which is stored in state object. - paramNames.pop(); - paramNames.pop(); - - newFunctionObject['func'] = func; - - if (typeof color === 'string') { - newFunctionObject['color'] = color; - } - - if (typeof line === 'string') { - if (line.toLowerCase() === 'true') { - newFunctionObject['line'] = true; - } else if (line.toLowerCase() === 'false') { - newFunctionObject['line'] = false; - } - } - - if (typeof dot === 'string') { - if (dot.toLowerCase() === 'true') { - newFunctionObject['dot'] = true; - } else if (dot.toLowerCase() === 'false') { - newFunctionObject['dot'] = false; - } - } - - if (typeof pointSize === 'string') { - newFunctionObject['pointSize'] = pointSize; - } - - if (typeof bar === 'string') { - if (bar.toLowerCase() === 'true') { - newFunctionObject['bars'] = true; - } else if (bar.toLowerCase() === 'false') { - newFunctionObject['bars'] = false; - } - } - - if (newFunctionObject['bars'] === true) { - newFunctionObject['line'] = false; - newFunctionObject['dot'] = false; - // To do: See if need to do anything here. - } else if ( - (newFunctionObject['dot'] === false) && - (newFunctionObject['line'] === false) - ) { - newFunctionObject['line'] = true; - } - - if (newFunctionObject['line'] === true) { - if (typeof fillArea === 'string') { - if (fillArea.toLowerCase() === 'true') { - newFunctionObject['fillArea'] = true; - } else if (fillArea.toLowerCase() === 'false') { - newFunctionObject['fillArea'] = false; - } else { - console.log('ERROR: The attribute fill_area should be either "true" or "false".'); - console.log('fill_area = "' + fillArea + '".'); - - return; - } - } - } - - if (typeof label === 'string') { - - newFunctionObject.specialLabel = false; - newFunctionObject.pldeHash = []; - - // Let's check the label against all of the plde objects. - // plde is an abbreviation for Plot Label Dynamic Elements. - for (c1 = 0; c1 < state.plde.length; c1 += 1) { - rgxp = new RegExp(state.plde[c1].elId, 'g'); - - // If we find a dynamic element in the label, we will - // hash the current plde object, and indicate that this - // is a special label. - if (rgxp.test(label) === true) { - newFunctionObject.specialLabel = true; - newFunctionObject.pldeHash.push(state.plde[c1]); - } - } - - newFunctionObject.label = label; - } else { - newFunctionObject.label = false; - } - - functions.push(newFunctionObject); - } - } - - // The callback that will be called whenever a constant changes (gets - // updated via a slider or a text input). - function onUpdatePlot(event) { - if (generateData() === true) { - updatePlot(); - } - } - - function generateData() { - var c0, c1, c3, functionObj, seriesObj, dataPoints, paramValues, x, y, - start, end, step, numNotUndefined; - - paramValues = state.getAllParameterValues(); - - dataSeries = []; - - for (c0 = 0; c0 < functions.length; c0 += 1) { - functionObj = functions[c0]; - - try { - start = xrange.min.apply(window, paramValues); - } catch (err) { - console.log('ERROR: Could not determine xrange start.'); - console.log('Error message: "' + err.message + '".'); - - if (state.showDebugInfo) { - $('#' + gstId).html('<div style="color: red;">' + 'ERROR IN XML: Could not determine xrange start from defined function.' + '</div>'); - $('#' + gstId).append('<div style="color: red;">' + 'Error message: "' + err.message + '".' + '</div>'); - } - - return false; - } - try { - end = xrange.max.apply(window, paramValues); - } catch (err) { - console.log('ERROR: Could not determine xrange end.'); - console.log('Error message: "' + err.message + '".'); - - if (state.showDebugInfo) { - $('#' + gstId).html('<div style="color: red;">' + 'ERROR IN XML: Could not determine xrange end from defined function.' + '</div>'); - $('#' + gstId).append('<div style="color: red;">' + 'Error message: "' + err.message + '".' + '</div>'); - } - - return false; - } - - seriesObj = {}; - dataPoints = []; - - // For counting number of points added. In the end we will - // compare this number to 'numPoints' specified in the config - // JSON. - c1 = 0; - - step = (end - start) / (numPoints - 1); - - // Generate the data points. - for (x = start; x <= end; x += step) { - - // Push the 'x' variable to the end of the parameter array. - paramValues.push(x); - - // We call the user defined function, passing all of the - // available parameter values. Inside this function they - // will be accessible by their names. - try { - y = functionObj.func.apply(window, paramValues); - } catch (err) { - console.log('ERROR: Could not generate data.'); - console.log('Error message: "' + err.message + '".'); - - if (state.showDebugInfo) { - $('#' + gstId).html('<div style="color: red;">' + 'ERROR IN XML: Could not generate data from defined function.' + '</div>'); - $('#' + gstId).append('<div style="color: red;">' + 'Error message: "' + err.message + '".' + '</div>'); - } - - return false; - } - - // Return the paramValues array to how it was before we - // added 'x' variable to the end of it. - paramValues.pop(); - - // Add the generated point to the data points set. - dataPoints.push([x, y]); - - c1 += 1; - - } - - // If the last point did not get included because of rounding - // of floating-point number addition, then we will include it - // manually. - if (c1 != numPoints) { - x = end; - paramValues.push(x); - try { - y = functionObj.func.apply(window, paramValues); - } catch (err) { - console.log('ERROR: Could not generate data.'); - console.log('Error message: "' + err.message + '".'); - - if (state.showDebugInfo) { - $('#' + gstId).html('<div style="color: red;">' + 'ERROR IN XML: Could not generate data from function.' + '</div>'); - $('#' + gstId).append('<div style="color: red;">' + 'Error message: "' + err.message + '".' + '</div>'); - } - - return false; - } - paramValues.pop(); - dataPoints.push([x, y]); - } - - // Put the entire data points set into the series object. - seriesObj.data = dataPoints; - - // See if user defined a specific color for this function. - if (functionObj.hasOwnProperty('color') === true) { - seriesObj.color = functionObj.color; - } - - // See if a user defined a label for this function. - if (functionObj.label !== false) { - if (functionObj.specialLabel === true) { - (function (c1) { - var tempLabel; - - tempLabel = functionObj.label; - - while (c1 < functionObj.pldeHash.length) { - tempLabel = tempLabel.replace( - functionObj.pldeHash[c1].elId, - functionObj.pldeHash[c1].func.apply( - window, - state.getAllParameterValues() - ) - ); - - c1 += 1; - } - - seriesObj.label = tempLabel; - }(0)); - } else { - seriesObj.label = functionObj.label; - } - } - - // Should the data points be connected by a line? - seriesObj.lines = { - 'show': functionObj.line - }; - - if (functionObj.hasOwnProperty('fillArea') === true) { - seriesObj.lines.fill = functionObj.fillArea; - } - - // Should each data point be represented by a point on the - // graph? - seriesObj.points = { - 'show': functionObj.dot - }; - - seriesObj.bars = { - 'show': functionObj.bars, - 'barWidth': graphBarWidth - }; - - if (graphBarAlign !== null) { - seriesObj.bars.align = graphBarAlign; - } - - if (functionObj.hasOwnProperty('pointSize')) { - seriesObj.points.radius = functionObj.pointSize; - } - - // Add the newly created series object to the series set which - // will be plotted by Flot. - dataSeries.push(seriesObj); - } - - if (graphBarAlign === null) { - for (c0 = 0; c0 < numPoints; c0 += 1) { - // Number of points that have a value other than 'undefined' (undefined). - numNotUndefined = 0; - - for (c1 = 0; c1 < dataSeries.length; c1 += 1) { - if (dataSeries[c1].bars.show === false) { - continue; - } - - if (isFinite(parseInt(dataSeries[c1].data[c0][1])) === true) { - numNotUndefined += 1; - } - } - - c3 = 0; - for (c1 = 0; c1 < dataSeries.length; c1 += 1) { - if (dataSeries[c1].bars.show === false) { - continue; - } - - dataSeries[c1].data[c0][0] -= graphBarWidth * (0.5 * numNotUndefined - c3); - - if (isFinite(parseInt(dataSeries[c1].data[c0][1])) === true) { - c3 += 1; - } - } - } - } - - for (c0 = 0; c0 < asymptotes.length; c0 += 1) { - - // If the user defined a label for this asympote, then the - // property 'label' will be a string (in the other case it is - // a boolean value 'false'). We will create an empty data set, - // and add to it a label. This solution is a bit _wrong_ , but - // it will have to do for now. Flot JS does not provide a way - // to add labels to markings, and we use markings to generate - // asymptotes. - if (asymptotes[c0].label !== false) { - dataSeries.push({ - 'data': [], - 'label': asymptotes[c0].label, - 'color': asymptotes[c0].color - }); - } - - } - - return true; - } // End-of: function generateData - - function updatePlot() { - var paramValues, plotObj; - - paramValues = state.getAllParameterValues(); - - if (xaxis.tickFormatter !== null) { - xaxis.ticks = null; - } - - if (yaxis.tickFormatter !== null) { - yaxis.ticks = null; - } - - // Tell Flot to draw the graph to our specification. - plotObj = $.plot( - plotDiv, - dataSeries, - { - 'xaxis': xaxis, - 'yaxis': yaxis, - 'legend': { - - // To show the legend or not. Note, even if 'show' is - // 'true', the legend will only show if labels are - // provided for at least one of the series that are - // going to be plotted. - 'show': true, - - // A floating point number in the range [0, 1]. The - // smaller the number, the more transparent will the - // legend background become. - 'backgroundOpacity': 0 - - }, - 'grid': { - 'markings': generateMarkings() - } - } - ); - - updateMovingLabels(); - - // The first time that the graph gets added to the page, the legend - // is created from scratch. When it appears, MathJax works some - // magic, and all of the specially marked TeX gets rendered nicely. - // The next time when we update the graph, no such thing happens. - // We must ask MathJax to typeset the legend again (well, we will - // ask it to look at our entire graph DIV), the next time it's - // worker queue is available. - MathJax.Hub.Queue([ - 'Typeset', - MathJax.Hub, - plotDiv.attr('id') - ]); - - return; - - function updateMovingLabels() { - var c1, labelCoord, pointOffset; - - for (c1 = 0; c1 < movingLabels.length; c1 += 1) { - if (movingLabels[c1].el === null) { - movingLabels[c1].el = $( - '<div>' + - movingLabels[c1].labelText + - '</div>' - ); - movingLabels[c1].el.css('position', 'absolute'); - movingLabels[c1].el.css('color', movingLabels[c1].fontColor); - movingLabels[c1].el.css('font-weight', movingLabels[c1].fontWeight); - movingLabels[c1].el.appendTo(plotDiv); - - movingLabels[c1].elWidth = movingLabels[c1].el.width(); - movingLabels[c1].elHeight = movingLabels[c1].el.height(); - } else { - movingLabels[c1].el.detach(); - movingLabels[c1].el.appendTo(plotDiv); - } - - labelCoord = movingLabels[c1].func.apply(window, paramValues); - - pointOffset = plotObj.pointOffset({'x': labelCoord.x, 'y': labelCoord.y}); - - movingLabels[c1].el.css('left', pointOffset.left - 0.5 * movingLabels[c1].elWidth); - movingLabels[c1].el.css('top', pointOffset.top - 0.5 * movingLabels[c1].elHeight); - } - } - - // Generate markings to represent asymptotes defined by the user. - // See the following function for more details: - // - // function processAsymptote() - // - function generateMarkings() { - var c1, asymptote, markings, val; - - markings = []; - - for (c1 = 0; c1 < asymptotes.length; c1 += 1) { - asymptote = asymptotes[c1]; - - try { - val = asymptote.func.apply(window, paramValues); - } catch (err) { - console.log('ERROR: Could not generate value from asymptote function.'); - console.log('Error message: ', err.message); - - continue; - } - - if (asymptote.type === 'x') { - markings.push({ - 'color': asymptote.color, - 'lineWidth': 2, - 'xaxis': { - 'from': val, - 'to': val - } - }); - } else { - markings.push({ - 'color': asymptote.color, - 'lineWidth': 2, - 'yaxis': { - 'from': val, - 'to': val - } - }); - - } - } - - return markings; - } - } - - function xAxisTickFormatter(val, axis) { - if (xTicksNames.hasOwnProperty(val.toFixed(axis.tickDecimals)) === true) { - return xTicksNames[val.toFixed(axis.tickDecimals)]; - } - - return ''; - } - - function yAxisTickFormatter(val, axis) { - if (yTicksNames.hasOwnProperty(val.toFixed(axis.tickDecimals)) === true) { - return yTicksNames[val.toFixed(axis.tickDecimals)]; - } - - return ''; - } - } - - -}); - -// End of wrapper for RequireJS. As you can see, we are passing -// namespaced Require JS variables to an anonymous function. Within -// it, you can use the standard requirejs(), require(), and define() -// functions as if they were in the global namespace. -}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define) diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/gst.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/gst.js deleted file mode 100644 index 73252455d0b..00000000000 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/gst.js +++ /dev/null @@ -1,22 +0,0 @@ -/* - * We will add a function that will be called for all GraphicalSliderTool - * xmodule module instances. It must be available globally by design of - * xmodule. - */ -window.GraphicalSliderTool = function (el) { - // All the work will be performed by the GstMain module. We will get access - // to it, and all it's dependencies, via Require JS. Currently Require JS - // is namespaced and is available via a global object RequireJS. - RequireJS.require(['GstMain'], function (GstMain) { - // The GstMain module expects the DOM ID of a Graphical Slider Tool - // element. Since we are given a <section> element which might in - // theory contain multiple graphical_slider_tool <div> elements (each - // with a unique DOM ID), we will iterate over all children, and for - // each match, we will call GstMain module. - $(el).children('.graphical_slider_tool').each(function (index, value) { - JavascriptLoader.executeModuleScripts($(value), function(){ - GstMain($(value).attr('id')); - }); - }); - }); -}; diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/gst_main.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/gst_main.js deleted file mode 100644 index 733e5703336..00000000000 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/gst_main.js +++ /dev/null @@ -1,86 +0,0 @@ -// Wrapper for RequireJS. It will make the standard requirejs(), require(), and -// define() functions from Require JS available inside the anonymous function. -(function (requirejs, require, define) { - -define( - 'GstMain', - - // Even though it is not explicitly in this module, we have to specify - // 'GeneralMethods' as a dependency. It expands some of the core JS objects - // with additional useful methods that are used in other modules. - ['State', 'GeneralMethods', 'Sliders', 'Inputs', 'Graph', 'ElOutput', 'GLabelElOutput'], - function (State, GeneralMethods, Sliders, Inputs, Graph, ElOutput, GLabelElOutput) { - - return GstMain; - - function GstMain(gstId) { - var config, gstClass, state; - - if ($('#' + gstId).attr('data-processed') !== 'processed') { - $('#' + gstId).attr('data-processed', 'processed'); - } else { - // console.log('MESSAGE: Already processed GST with ID ' + gstId + '. Skipping.'); - - return; - } - - // Get the JSON configuration, parse it, and store as an object. - try { - config = JSON.parse($('#' + gstId + '_json').html()).root; - } catch (err) { - console.log('ERROR: could not parse config JSON.'); - console.log('$("#" + gstId + "_json").html() = ', $('#' + gstId + '_json').html()); - console.log('JSON.parse(...) = ', JSON.parse($('#' + gstId + '_json').html())); - console.log('config = ', config); - - return; - } - - // Get the class name of the GST. All elements are assigned a class - // name that is based on the class name of the GST. For example, inputs - // are assigned a class name '{GST class name}_input'. - if (typeof config['@class'] !== 'string') { - console.log('ERROR: Could not get the class name of GST.'); - console.log('config["@class"] = ', config['@class']); - - return; - } - gstClass = config['@class']; - - // Parse the configuration settings for parameters, and store them in a - // state object. - state = State(gstId, config); - - state.showDebugInfo = false; - - // It is possible that something goes wrong while extracting parameters - // from the JSON config object. In this case, we will not continue. - if (state === undefined) { - console.log('ERROR: The state object was not initialized properly.'); - - return; - } - - // Create the sliders and the text inputs, attaching them to - // appropriate parameters. - Sliders(gstId, state); - Inputs(gstId, gstClass, state); - - // Configure functions that output to an element instead of the graph. - ElOutput(config, state); - - // Configure functions that output to an element instead of the graph - // label. - GLabelElOutput(config, state); - - // Configure and display the graph. Attach event for the graph to be - // updated on any change of a slider or a text input. - Graph(gstId, config, state); - } -}); - -// End of wrapper for RequireJS. As you can see, we are passing -// namespaced Require JS variables to an anonymous function. Within -// it, you can use the standard requirejs(), require(), and define() -// functions as if they were in the global namespace. -}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define) diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/inputs.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/inputs.js deleted file mode 100644 index 531a939aec6..00000000000 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/inputs.js +++ /dev/null @@ -1,88 +0,0 @@ -// Wrapper for RequireJS. It will make the standard requirejs(), require(), and -// define() functions from Require JS available inside the anonymous function. -(function (requirejs, require, define) { - -define('Inputs', [], function () { - return Inputs; - - function Inputs(gstId, gstClass, state) { - var c1, paramName, allParamNames; - - allParamNames = state.getAllParameterNames(); - - for (c1 = 0; c1 < allParamNames.length; c1 += 1) { - $('#' + gstId).find('.' + gstClass + '_input').each(function (index, value) { - var inputDiv, paramName; - - paramName = allParamNames[c1]; - inputDiv = $(value); - - if (paramName === inputDiv.data('var')) { - createInput(inputDiv, paramName); - } - }); - } - - return; - - function createInput(inputDiv, paramName) { - var paramObj; - - paramObj = state.getParamObj(paramName); - - // Check that the retrieval went OK. - if (paramObj === undefined) { - console.log('ERROR: Could not get a paramObj for parameter "' + paramName + '".'); - - return; - } - - // Bind a function to the 'change' event. Whenever the user changes - // the value of this text input, and presses 'enter' (or clicks - // somewhere else on the page), this event will be triggered, and - // our callback will be called. - inputDiv.bind('change', inputOnChange); - - inputDiv.val(paramObj.value); - - // Lets style the input element nicely. We will use the button() - // widget for this since there is no native widget for the text - // input. - inputDiv.button().css({ - 'font': 'inherit', - 'color': 'inherit', - 'text-align': 'left', - 'outline': 'none', - 'cursor': 'text', - 'height': '15px' - }); - - // Tell the parameter object from state that we are attaching a - // text input to it. Next time the parameter will be updated with - // a new value, tis input will also be updated. - paramObj.inputDivs.push(inputDiv); - - return; - - // Update the 'state' - i.e. set the value of the parameter this - // input is attached to to a new value. - // - // This will cause the plot to be redrawn each time after the user - // changes the value in the input. Note that he has to either press - // 'Enter', or click somewhere else on the page in order for the - // 'change' event to be tiggered. - function inputOnChange(event) { - var inputDiv; - - inputDiv = $(this); - state.setParameterValue(paramName, inputDiv.val(), inputDiv); - } - } - } -}); - -// End of wrapper for RequireJS. As you can see, we are passing -// namespaced Require JS variables to an anonymous function. Within -// it, you can use the standard requirejs(), require(), and define() -// functions as if they were in the global namespace. -}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define) diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/jstat-1.0.0.min.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/jstat-1.0.0.min.js deleted file mode 100644 index 7f9cd4a1248..00000000000 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/jstat-1.0.0.min.js +++ /dev/null @@ -1,236 +0,0 @@ -function jstat(){} -j=jstat;(function(){var initializing=false,fnTest=/xyz/.test(function(){xyz;})?/\b_super\b/:/.*/;this.Class=function(){};Class.extend=function(prop){var _super=this.prototype;initializing=true;var prototype=new this();initializing=false;for(var name in prop){prototype[name]=typeof prop[name]=="function"&&typeof _super[name]=="function"&&fnTest.test(prop[name])?(function(name,fn){return function(){var tmp=this._super;this._super=_super[name];var ret=fn.apply(this,arguments);this._super=tmp;return ret;};})(name,prop[name]):prop[name];} -function Class(){if(!initializing&&this.init) -this.init.apply(this,arguments);} -Class.prototype=prototype;Class.constructor=Class;Class.extend=arguments.callee;return Class;};})();jstat.ONE_SQRT_2PI=0.3989422804014327;jstat.LN_SQRT_2PI=0.9189385332046727417803297;jstat.LN_SQRT_PId2=0.225791352644727432363097614947;jstat.DBL_MIN=2.22507e-308;jstat.DBL_EPSILON=2.220446049250313e-16;jstat.SQRT_32=5.656854249492380195206754896838;jstat.TWO_PI=6.283185307179586;jstat.DBL_MIN_EXP=-999;jstat.SQRT_2dPI=0.79788456080287;jstat.LN_SQRT_PI=0.5723649429247;jstat.seq=function(min,max,length){var r=new Range(min,max,length);return r.getPoints();} -jstat.dnorm=function(x,mean,sd,log){if(mean==null)mean=0;if(sd==null)sd=1;if(log==null)log=false;var n=new NormalDistribution(mean,sd);if(!isNaN(x)){return n._pdf(x,log);}else if(x.length){var res=[];for(var i=0;i<x.length;i++){res.push(n._pdf(x[i],log));} -return res;}else{throw"Illegal argument: x";}} -jstat.pnorm=function(q,mean,sd,lower_tail,log){if(mean==null)mean=0;if(sd==null)sd=1;if(lower_tail==null)lower_tail=true;if(log==null)log=false;var n=new NormalDistribution(mean,sd);if(!isNaN(q)){return n._cdf(q,lower_tail,log);}else if(q.length){var res=[];for(var i=0;i<q.length;i++){res.push(n._cdf(q[i],lower_tail,log));} -return res;}else{throw"Illegal argument: x";}} -jstat.dlnorm=function(x,meanlog,sdlog,log){if(meanlog==null)meanlog=0;if(sdlog==null)sdlog=1;if(log==null)log=false;var n=new LogNormalDistribution(meanlog,sdlog);if(!isNaN(x)){return n._pdf(x,log);}else if(x.length){var res=[];for(var i=0;i<x.length;i++){res.push(n._pdf(x[i],log));} -return res;}else{throw"Illegal argument: x";}} -jstat.plnorm=function(q,meanlog,sdlog,lower_tail,log){if(meanlog==null)meanlog=0;if(sdlog==null)sdlog=1;if(lower_tail==null)lower_tail=true;if(log==null)log=false;var n=new LogNormalDistribution(meanlog,sdlog);if(!isNaN(q)){return n._cdf(q,lower_tail,log);} -else if(q.length){var res=[];for(var i=0;i<q.length;i++){res.push(n._cdf(q[i],lower_tail,log));} -return res;}else{throw"Illegal argument: x";}} -jstat.dbeta=function(x,alpha,beta,ncp,log){if(ncp==null)ncp=0;if(log==null)log=false;var b=new BetaDistribution(alpha,beta);if(!isNaN(x)){return b._pdf(x,log);} -else if(x.length){var res=[];for(var i=0;i<x.length;i++){res.push(b._pdf(x[i],log));} -return res;}else{throw"Illegal argument: x";}} -jstat.pbeta=function(q,alpha,beta,ncp,lower_tail,log){if(ncp==null)ncp=0;if(log==null)log=false;if(lower_tail==null)lower_tail=true;var b=new BetaDistribution(alpha,beta);if(!isNaN(q)){return b._cdf(q,lower_tail,log);}else if(q.length){var res=[];for(var i=0;i<q.length;i++){res.push(b._cdf(q[i],lower_tail,log));} -return res;} -else{throw"Illegal argument: x";}} -jstat.dgamma=function(x,shape,rate,scale,log){if(rate==null)rate=1;if(scale==null)scale=1/rate;if(log==null)log=false;var g=new GammaDistribution(shape,scale);if(!isNaN(x)){return g._pdf(x,log);}else if(x.length){var res=[];for(var i=0;i<x.length;i++){res.push(g._pdf(x[i],log));} -return res;}else{throw"Illegal argument: x";}} -jstat.pgamma=function(q,shape,rate,scale,lower_tail,log){if(rate==null)rate=1;if(scale==null)scale=1/rate;if(lower_tail==null)lower_tail=true;if(log==null)log=false;var g=new GammaDistribution(shape,scale);if(!isNaN(q)){return g._cdf(q,lower_tail,log);}else if(q.length){var res=[];for(var i=0;i<q.length;i++){res.push(g._cdf(q[i],lower_tail,log));} -return res;}else{throw"Illegal argument: x";}} -jstat.dt=function(x,df,ncp,log){if(log==null)log=false;var t=new StudentTDistribution(df,ncp);if(!isNaN(x)){return t._pdf(x,log);}else if(x.length){var res=[];for(var i=0;i<x.length;i++){res.push(t._pdf(x[i],log));} -return res;}else{throw"Illegal argument: x";}} -jstat.pt=function(q,df,ncp,lower_tail,log){if(lower_tail==null)lower_tail=true;if(log==null)log=false;var t=new StudentTDistribution(df,ncp);if(!isNaN(q)){return t._cdf(q,lower_tail,log);}else if(q.length){var res=[];for(var i=0;i<q.length;i++){res.push(t._cdf(q[i],lower_tail,log));} -return res;}else{throw"Illegal argument: x";}} -jstat.plot=function(x,y,options){if(x==null){throw"x is undefined in jstat.plot";} -if(y==null){throw"y is undefined in jstat.plot";} -if(x.length!=y.length){throw"x and y lengths differ in jstat.plot";} -var flotOpt={series:{lines:{},points:{}}};var series=[];if(x.length==undefined){series.push([x,y]);flotOpt.series.points.show=true;}else{for(var i=0;i<x.length;i++){series.push([x[i],y[i]]);}} -var title='jstat graph';if(options!=null){if(options.type!=null){if(options.type=='l'){flotOpt.series.lines.show=true;}else if(options.type=='p'){flotOpt.series.lines.show=false;flotOpt.series.points.show=true;}} -if(options.hover!=null){flotOpt.grid={hoverable:options.hover}} -if(options.main!=null){title=options.main;}} -var now=new Date();var hash=now.getMilliseconds()*now.getMinutes()+now.getSeconds();$('body').append('<div title="'+title+'" style="display: none;" id="'+hash+'"><div id="graph-'+hash+'" style="width:95%; height: 95%"></div></div>');$('#'+hash).dialog({modal:false,width:475,height:475,resizable:true,resize:function(){$.plot($('#graph-'+hash),[series],flotOpt);},open:function(event,ui){var id='#graph-'+hash;$.plot($('#graph-'+hash),[series],flotOpt);}})} -jstat.log10=function(arg){return Math.log(arg)/Math.LN10;} -jstat.toSigFig=function(num,n){if(num==0){return 0;} -var d=Math.ceil(jstat.log10(num<0?-num:num));var power=n-parseInt(d);var magnitude=Math.pow(10,power);var shifted=Math.round(num*magnitude);return shifted/magnitude;} -jstat.trunc=function(x){return(x>0)?Math.floor(x):Math.ceil(x);} -jstat.isFinite=function(x){return(!isNaN(x)&&(x!=Number.POSITIVE_INFINITY)&&(x!=Number.NEGATIVE_INFINITY));} -jstat.dopois_raw=function(x,lambda,give_log){if(lambda==0){if(x==0){return(give_log)?0.0:1.0;} -return(give_log)?Number.NEGATIVE_INFINITY:0.0;} -if(!jstat.isFinite(lambda))return(give_log)?Number.NEGATIVE_INFINITY:0.0;if(x<0)return(give_log)?Number.NEGATIVE_INFINITY:0.0;if(x<=lambda*jstat.DBL_MIN){return(give_log)?-lambda:Math.exp(-lambda);} -if(lambda<x*jstat.DBL_MIN){var param=-lambda+x*Math.log(lambda)-jstat.lgamma(x+1);return(give_log)?param:Math.exp(param);} -var param1=jstat.TWO_PI*x;var param2=-jstat.stirlerr(x)-jstat.bd0(x,lambda);return(give_log)?-0.5*Math.log(param1)+param2:Math.exp(param2)/Math.sqrt(param1);} -jstat.bd0=function(x,np){var ej,s,s1,v,j;if(!jstat.isFinite(x)||!jstat.isFinite(np)||np==0.0)throw"illegal parameter in jstat.bd0";if(Math.abs(x-np)>0.1*(x+np)){v=(x-np)/(x+np);s=(x-np)*v;ej=2*x*v;v=v*v;for(j=1;;j++){ej*=v;s1=s+ej/((j<<1)+1);if(s1==s) -return(s1);s=s1;}} -return(x*Math.log(x/np)+np-x);} -jstat.stirlerr=function(n){var S0=0.083333333333333333333;var S1=0.00277777777777777777778;var S2=0.00079365079365079365079365;var S3=0.000595238095238095238095238;var S4=0.0008417508417508417508417508;var sferr_halves=[0.0,0.1534264097200273452913848,0.0810614667953272582196702,0.0548141210519176538961390,0.0413406959554092940938221,0.03316287351993628748511048,0.02767792568499833914878929,0.02374616365629749597132920,0.02079067210376509311152277,0.01848845053267318523077934,0.01664469118982119216319487,0.01513497322191737887351255,0.01387612882307074799874573,0.01281046524292022692424986,0.01189670994589177009505572,0.01110455975820691732662991,0.010411265261972096497478567,0.009799416126158803298389475,0.009255462182712732917728637,0.008768700134139385462952823,0.008330563433362871256469318,0.007934114564314020547248100,0.007573675487951840794972024,0.007244554301320383179543912,0.006942840107209529865664152,0.006665247032707682442354394,0.006408994188004207068439631,0.006171712263039457647532867,0.005951370112758847735624416,0.005746216513010115682023589,0.005554733551962801371038690];var nn;if(n<=15.0){nn=n+n;if(nn==parseInt(nn))return(sferr_halves[parseInt(nn)]);return(jstat.lgamma(n+1.0)-(n+0.5)*Math.log(n)+n-jstat.LN_SQRT_2PI);} -nn=n*n;if(n>500)return((S0-S1/nn)/n);if(n>80)return((S0-(S1-S2/nn)/nn)/n);if(n>35)return((S0-(S1-(S2-S3/nn)/nn)/nn)/n);return((S0-(S1-(S2-(S3-S4/nn)/nn)/nn)/nn)/n);} -jstat.lgamma=function(x){function lgammafn_sign(x,sgn){var ans,y,sinpiy;var xmax=2.5327372760800758e+305;var dxrel=1.490116119384765696e-8;if(sgn!=null)sgn=1;if(isNaN(x))return x;if(x<0&&(Math.floor(-x)%2.0)==0) -if(sgn!=null)sgn=-1;if(x<=0&&x==jstat.trunc(x)){console.warn("Negative integer argument in lgammafn_sign");return Number.POSITIVE_INFINITY;} -y=Math.abs(x);if(y<=10)return Math.log(Math.abs(jstat.gamma(x)));if(y>xmax){console.warn("Illegal arguement passed to lgammafn_sign");return Number.POSITIVE_INFINITY;} -if(x>0){if(x>1e17){return(x*(Math.log(x)-1.0));}else if(x>4934720.0){return(jstat.LN_SQRT_2PI+(x-0.5)*Math.log(x)-x);}else{return jstat.LN_SQRT_2PI+(x-0.5)*Math.log(x)-x+jstat.lgammacor(x);}} -sinpiy=Math.abs(Math.sin(Math.PI*y));if(sinpiy==0){throw"Should never happen!!";} -ans=jstat.LN_SQRT_PId2+(x-0.5)*Math.log(y)-x-Math.log(sinpiy)-jstat.lgammacor(y);if(Math.abs((x-jstat.trunc(x-0.5))*ans/x)<dxrel){throw"The answer is less than half the precision argument too close to a negative integer";} -return ans;} -return lgammafn_sign(x,null);} -jstat.gamma=function(x){var xbig=171.624;var p=[-1.71618513886549492533811,24.7656508055759199108314,-379.804256470945635097577,629.331155312818442661052,866.966202790413211295064,-31451.2729688483675254357,-36144.4134186911729807069,66456.1438202405440627855];var q=[-30.8402300119738975254353,315.350626979604161529144,-1015.15636749021914166146,-3107.77167157231109440444,22538.1184209801510330112,4755.84627752788110767815,-134659.959864969306392456,-115132.259675553483497211];var c=[-.001910444077728,8.4171387781295e-4,-5.952379913043012e-4,7.93650793500350248e-4,-.002777777777777681622553,.08333333333333333331554247,.0057083835261];var i,n,parity,fact,xden,xnum,y,z,yi,res,sum,ysq;parity=(0);fact=1.0;n=0;y=x;if(y<=0.0){y=-x;yi=jstat.trunc(y);res=y-yi;if(res!=0.0){if(yi!=jstat.trunc(yi*0.5)*2.0) -parity=(1);fact=-Math.PI/Math.sin(Math.PI*res);y+=1.0;}else{return(Number.POSITIVE_INFINITY);}} -if(y<jstat.DBL_EPSILON){if(y>=jstat.DBL_MIN){res=1.0/y;}else{return(Number.POSITIVE_INFINITY);}}else if(y<12.0){yi=y;if(y<1.0){z=y;y+=1.0;}else{n=parseInt(y)-1;y-=parseFloat(n);z=y-1.0;} -xnum=0.0;xden=1.0;for(i=0;i<8;++i){xnum=(xnum+p[i])*z;xden=xden*z+q[i];} -res=xnum/xden+1.0;if(yi<y){res/=yi;}else if(yi>y){for(i=0;i<n;++i){res*=y;y+=1.0;}}}else{if(y<=xbig){ysq=y*y;sum=c[6];for(i=0;i<6;++i){sum=sum/ysq+c[i];} -sum=sum/y-y+jstat.LN_SQRT_2PI;sum+=(y-0.5)*Math.log(y);res=Math.exp(sum);}else{return(Number.POSITIVE_INFINITY);}} -if(parity) -res=-res;if(fact!=1.0) -res=fact/res;return res;} -jstat.lgammacor=function(x){var algmcs=[+.1666389480451863247205729650822e+0,-.1384948176067563840732986059135e-4,+.9810825646924729426157171547487e-8,-.1809129475572494194263306266719e-10,+.6221098041892605227126015543416e-13,-.3399615005417721944303330599666e-15,+.2683181998482698748957538846666e-17,-.2868042435334643284144622399999e-19,+.3962837061046434803679306666666e-21,-.6831888753985766870111999999999e-23,+.1429227355942498147573333333333e-24,-.3547598158101070547199999999999e-26,+.1025680058010470912000000000000e-27,-.3401102254316748799999999999999e-29,+.1276642195630062933333333333333e-30];var tmp;var nalgm=5;var xbig=94906265.62425156;var xmax=3.745194030963158e306;if(x<10){return Number.NaN;}else if(x>=xmax){throw"Underflow error in lgammacor";}else if(x<xbig){tmp=10/x;return jstat.chebyshev(tmp*tmp*2-1,algmcs,nalgm)/x;} -return 1/(x*12);} -jstat.incompleteBeta=function(a,b,x){function betacf(a,b,x){var MAXIT=100;var EPS=3.0e-12;var FPMIN=1.0e-30;var m,m2,aa,c,d,del,h,qab,qam,qap;qab=a+b;qap=a+1.0;qam=a-1.0;c=1.0;d=1.0-qab*x/qap;if(Math.abs(d)<FPMIN){d=FPMIN;} -d=1.0/d;h=d;for(m=1;m<=MAXIT;m++){m2=2*m;aa=m*(b-m)*x/((qam+m2)*(a+m2));d=1.0+aa*d;if(Math.abs(d)<FPMIN){d=FPMIN;} -c=1.0+aa/c;if(Math.abs(c)<FPMIN){c=FPMIN;} -d=1.0/d;h*=d*c;aa=-(a+m)*(qab+m)*x/((a+m2)*(qap+m2));d=1.0+aa*d;if(Math.abs(d)<FPMIN){d=FPMIN;} -c=1.0+aa/c;if(Math.abs(c)<FPMIN){c=FPMIN;} -d=1.0/d;del=d*c;h*=del;if(Math.abs(del-1.0)<EPS){break;}} -if(m>MAXIT){console.warn("a or b too big, or MAXIT too small in betacf: "+a+", "+b+", "+x+", "+h);return h;} -if(isNaN(h)){console.warn(a+", "+b+", "+x);} -return h;} -var bt;if(x<0.0||x>1.0){throw"bad x in routine incompleteBeta";} -if(x==0.0||x==1.0){bt=0.0;}else{bt=Math.exp(jstat.lgamma(a+b)-jstat.lgamma(a)-jstat.lgamma(b)+a*Math.log(x)+b*Math.log(1.0-x));} -if(x<(a+1.0)/(a+b+2.0)){return bt*betacf(a,b,x)/a;}else{return 1.0-bt*betacf(b,a,1.0-x)/b;}} -jstat.chebyshev=function(x,a,n){var b0,b1,b2,twox;var i;if(n<1||n>1000)return Number.NaN;if(x<-1.1||x>1.1)return Number.NaN;twox=x*2;b2=b1=0;b0=0;for(i=1;i<=n;i++){b2=b1;b1=b0;b0=twox*b1-b2+a[n-i];} -return(b0-b2)*0.5;} -jstat.fmin2=function(x,y){return(x<y)?x:y;} -jstat.log1p=function(x){var ret=0,n=50;if(x<=-1){return Number.NEGATIVE_INFINITY;} -if(x<0||x>1){return Math.log(1+x);} -for(var i=1;i<n;i++){if((i%2)===0){ret-=Math.pow(x,i)/i;}else{ret+=Math.pow(x,i)/i;}} -return ret;} -jstat.expm1=function(x){var y,a=Math.abs(x);if(a<jstat.DBL_EPSILON)return x;if(a>0.697)return Math.exp(x)-1;if(a>1e-8){y=Math.exp(x)-1;}else{y=(x/2+1)*x;} -y-=(1+y)*(jstat.log1p(y)-x);return y;} -jstat.logBeta=function(a,b){var corr,p,q;p=q=a;if(b<p)p=b;if(b>q)q=b;if(p<0){console.warn('Both arguements must be >= 0');return Number.NaN;} -else if(p==0){return Number.POSITIVE_INFINITY;} -else if(!jstat.isFinite(q)){return Number.NEGATIVE_INFINITY;} -if(p>=10){corr=jstat.lgammacor(p)+jstat.lgammacor(q)-jstat.lgammacor(p+q);return Math.log(q)*-0.5+jstat.LN_SQRT_2PI+corr -+(p-0.5)*Math.log(p/(p+q))+q*jstat.log1p(-p/(p+q));} -else if(q>=10){corr=jstat.lgammacor(q)-jstat.lgammacor(p+q);return jstat.lgamma(p)+corr+p-p*Math.log(p+q) -+(q-0.5)*jstat.log1p(-p/(p+q));} -else -return Math.log(jstat.gamma(p)*(jstat.gamma(q)/jstat.gamma(p+q)));} -jstat.dbinom_raw=function(x,n,p,q,give_log){if(give_log==null)give_log=false;var lf,lc;if(p==0){if(x==0){return(give_log)?0.0:1.0;}else{return(give_log)?Number.NEGATIVE_INFINITY:0.0;}} -if(q==0){if(x==n){return(give_log)?0.0:1.0;}else{return(give_log)?Number.NEGATIVE_INFINITY:0.0;}} -if(x==0){if(n==0)return(give_log)?0.0:1.0;lc=(p<0.1)?-jstat.bd0(n,n*q)-n*p:n*Math.log(q);return(give_log)?lc:Math.exp(lc);} -if(x==n){lc=(q<0.1)?-jstat.bd0(n,n*p)-n*q:n*Math.log(p);return(give_log)?lc:Math.exp(lc);} -if(x<0||x>n)return(give_log)?Number.NEGATIVE_INFINITY:0.0;lc=jstat.stirlerr(n)-jstat.stirlerr(x)-jstat.stirlerr(n-x)-jstat.bd0(x,n*p)-jstat.bd0(n-x,n*q);lf=Math.log(jstat.TWO_PI)+Math.log(x)+jstat.log1p(-x/n);return(give_log)?lc-0.5*lf:Math.exp(lc-0.5*lf);} -jstat.max=function(values){var max=Number.NEGATIVE_INFINITY;for(var i=0;i<values.length;i++){if(values[i]>max){max=values[i];}} -return max;} -var Range=Class.extend({init:function(min,max,numPoints){this._minimum=parseFloat(min);this._maximum=parseFloat(max);this._numPoints=parseFloat(numPoints);},getMinimum:function(){return this._minimum;},getMaximum:function(){return this._maximum;},getNumPoints:function(){return this._numPoints;},getPoints:function(){var results=[];var x=this._minimum;var step=(this._maximum-this._minimum)/(this._numPoints-1);for(var i=0;i<this._numPoints;i++){results[i]=parseFloat(x.toFixed(6));x+=step;} -return results;}});Range.validate=function(range){if(!range instanceof Range){return false;} -if(isNaN(range.getMinimum())||isNaN(range.getMaximum())||isNaN(range.getNumPoints())||range.getMaximum()<range.getMinimum()||range.getNumPoints()<=0){return false;} -return true;} -var ContinuousDistribution=Class.extend({init:function(name){this._name=name;},toString:function(){return this._string;},getName:function(){return this._name;},getClassName:function(){return this._name+'Distribution';},density:function(valueOrRange){if(!isNaN(valueOrRange)){return parseFloat(this._pdf(valueOrRange).toFixed(15));}else if(Range.validate(valueOrRange)){var points=valueOrRange.getPoints();var result=[];for(var i=0;i<points.length;i++){result[i]=parseFloat(this._pdf(points[i]));} -return result;}else{throw"Invalid parameter supplied to "+this.getClassName()+".density()";}},cumulativeDensity:function(valueOrRange){if(!isNaN(valueOrRange)){return parseFloat(this._cdf(valueOrRange).toFixed(15));}else if(Range.validate(valueOrRange)){var points=valueOrRange.getPoints();var result=[];for(var i=0;i<points.length;i++){result[i]=parseFloat(this._cdf(points[i]));} -return result;}else{throw"Invalid parameter supplied to "+this.getClassName()+".cumulativeDensity()";}},getRange:function(standardDeviations,numPoints){if(standardDeviations==null){standardDeviations=5;} -if(numPoints==null){numPoints=100;} -var min=this.getMean()-standardDeviations*Math.sqrt(this.getVariance());var max=this.getMean()+standardDeviations*Math.sqrt(this.getVariance());if(this.getClassName()=='GammaDistribution'||this.getClassName()=='LogNormalDistribution'){min=0.0;max=this.getMean()+standardDeviations*Math.sqrt(this.getVariance());}else if(this.getClassName()=='BetaDistribution'){min=0.0;max=1.0;} -var range=new Range(min,max,numPoints);return range;},getVariance:function(){},getMean:function(){},getQuantile:function(p){var self=this;function findClosestMatch(range,p){var ERR=1.0e-5;var xs=range.getPoints();var closestIndex=0;var closestDistance=999;for(var i=0;i<xs.length;i++){var pp=self.cumulativeDensity(xs[i]);var distance=Math.abs(pp-p);if(distance<closestDistance){closestIndex=i;closestDistance=distance;}} -if(closestDistance<=ERR){return xs[closestIndex];}else{var newRange=new Range(xs[closestIndex-1],xs[closestIndex+1],20);return findClosestMatch(newRange,p);}} -var range=this.getRange(5,20);return findClosestMatch(range,p);}});var NormalDistribution=ContinuousDistribution.extend({init:function(mean,sigma){this._super('Normal');this._mean=parseFloat(mean);this._sigma=parseFloat(sigma);this._string="Normal ("+this._mean.toFixed(2)+", "+this._sigma.toFixed(2)+")";},_pdf:function(x,give_log){if(give_log==null){give_log=false;} -var sigma=this._sigma;var mu=this._mean;if(!jstat.isFinite(sigma)){return(give_log)?Number.NEGATIVE_INFINITY:0.0} -if(!jstat.isFinite(x)&&mu==x){return Number.NaN;} -if(sigma<=0){if(sigma<0){throw"invalid sigma in _pdf";} -return(x==mu)?Number.POSITIVE_INFINITY:(give_log)?Number.NEGATIVE_INFINITY:0.0;} -x=(x-mu)/sigma;if(!jstat.isFinite(x)){return(give_log)?Number.NEGATIVE_INFINITY:0.0;} -return(give_log?-(jstat.LN_SQRT_2PI+0.5*x*x+Math.log(sigma)):jstat.ONE_SQRT_2PI*Math.exp(-0.5*x*x)/sigma);},_cdf:function(x,lower_tail,log_p){if(lower_tail==null)lower_tail=true;if(log_p==null)log_p=false;function pnorm_both(x,cum,ccum,i_tail,log_p){var a=[2.2352520354606839287,161.02823106855587881,1067.6894854603709582,18154.981253343561249,0.065682337918207449113];var b=[47.20258190468824187,976.09855173777669322,10260.932208618978205,45507.789335026729956];var c=[0.39894151208813466764,8.8831497943883759412,93.506656132177855979,597.27027639480026226,2494.5375852903726711,6848.1904505362823326,11602.651437647350124,9842.7148383839780218,1.0765576773720192317e-8];var d=[22.266688044328115691,235.38790178262499861,1519.377599407554805,6485.558298266760755,18615.571640885098091,34900.952721145977266,38912.003286093271411,19685.429676859990727];var p=[0.21589853405795699,0.1274011611602473639,0.022235277870649807,0.001421619193227893466,2.9112874951168792e-5,0.02307344176494017303];var q=[1.28426009614491121,0.468238212480865118,0.0659881378689285515,0.00378239633202758244,7.29751555083966205e-5];var xden,xnum,temp,del,eps,xsq,y,i,lower,upper;eps=jstat.DBL_EPSILON*0.5;lower=i_tail!=1;upper=i_tail!=0;y=Math.abs(x);if(y<=0.67448975){if(y>eps){xsq=x*x;xnum=a[4]*xsq;xden=xsq;for(i=0;i<3;++i){xnum=(xnum+a[i])*xsq;xden=(xden+b[i])*xsq;}}else{xnum=xden=0.0;} -temp=x*(xnum+a[3])/(xden+b[3]);if(lower)cum=0.5+temp;if(upper)ccum=0.5-temp;if(log_p){if(lower)cum=Math.log(cum);if(upper)ccum=Math.log(ccum);}}else if(y<=jstat.SQRT_32){xnum=c[8]*y;xden=y;for(i=0;i<7;++i){xnum=(xnum+c[i])*y;xden=(xden+d[i])*y;} -temp=(xnum+c[7])/(xden+d[7]);xsq=jstat.trunc(x*16)/16;del=(x-xsq)*(x+xsq);if(log_p){cum=(-xsq*xsq*0.5)+(-del*0.5)+Math.log(temp);if((lower&&x>0.)||(upper&&x<=0.)) -ccum=jstat.log1p(-Math.exp(-xsq*xsq*0.5)*Math.exp(-del*0.5)*temp);} -else{cum=Math.exp(-xsq*xsq*0.5)*Math.exp(-del*0.5)*temp;ccum=1.0-cum;} -if(x>0.0){temp=cum;if(lower){cum=ccum;} -ccum=temp;}} -else if((log_p&&y<1e170)||(lower&&-37.5193<x&&x<8.2924)||(upper&&-8.2924<x&&x<37.5193)){xsq=1.0/(x*x);xnum=p[5]*xsq;xden=xsq;for(i=0;i<4;++i){xnum=(xnum+p[i])*xsq;xden=(xden+q[i])*xsq;} -temp=xsq*(xnum+p[4])/(xden+q[4]);temp=(jstat.ONE_SQRT_2PI-temp)/y;xsq=jstat.trunc(x*16)/16;del=(x-xsq)*(x+xsq);if(log_p){cum=(-xsq*xsq*0.5)+(-del*0.5)+Math.log(temp);if((lower&&x>0.)||(upper&&x<=0.)) -ccum=jstat.log1p(-Math.exp(-xsq*xsq*0.5)*Math.exp(-del*0.5)*temp);} -else{cum=Math.exp(-xsq*xsq*0.5)*Math.exp(-del*0.5)*temp;ccum=1.0-cum;} -if(x>0.0){temp=cum;if(lower){cum=ccum;} -ccum=temp;}}else{if(x>0){cum=(log_p)?0.0:1.0;ccum=(log_p)?Number.NEGATIVE_INFINITY:0.0;}else{cum=(log_p)?Number.NEGATIVE_INFINITY:0.0;ccum=(log_p)?0.0:1.0;}} -return[cum,ccum];} -var p,cp;var mu=this._mean;var sigma=this._sigma;var R_DT_0,R_DT_1;if(lower_tail){if(log_p){R_DT_0=Number.NEGATIVE_INFINITY;R_DT_1=0.0;}else{R_DT_0=0.0;R_DT_1=1.0;}}else{if(log_p){R_DT_0=0.0;R_DT_1=Number.NEGATIVE_INFINITY;}else{R_DT_0=1.0;R_DT_1=0.0;}} -if(!jstat.isFinite(x)&&mu==x)return Number.NaN;if(sigma<=0){if(sigma<0){console.warn("Sigma is less than 0");return Number.NaN;} -return(x<mu)?R_DT_0:R_DT_1;} -p=(x-mu)/sigma;if(!jstat.isFinite(p)){return(x<mu)?R_DT_0:R_DT_1;} -x=p;var result=pnorm_both(x,p,cp,(lower_tail?false:true),log_p);return(lower_tail?result[0]:result[1]);},getMean:function(){return this._mean;},getSigma:function(){return this._sigma;},getVariance:function(){return this._sigma*this._sigma;}});var LogNormalDistribution=ContinuousDistribution.extend({init:function(location,scale){this._super('LogNormal') -this._location=parseFloat(location);this._scale=parseFloat(scale);this._string="LogNormal ("+this._location.toFixed(2)+", "+this._scale.toFixed(2)+")";},_pdf:function(x,give_log){var y;var sdlog=this._scale;var meanlog=this._location;if(give_log==null){give_log=false;} -if(sdlog<=0)throw"Illegal parameter in _pdf";if(x<=0){return(give_log)?Number.NEGATIVE_INFINITY:0.0;} -y=(Math.log(x)-meanlog)/sdlog;return(give_log?-(jstat.LN_SQRT_2PI+0.5*y*y+Math.log(x*sdlog)):jstat.ONE_SQRT_2PI*Math.exp(-0.5*y*y)/(x*sdlog));},_cdf:function(x,lower_tail,log_p){var sdlog=this._scale;var meanlog=this._location;if(lower_tail==null){lower_tail=true;} -if(log_p==null){log_p=false;} -if(sdlog<=0){throw"illegal std in _cdf";} -if(x>0){var nd=new NormalDistribution(meanlog,sdlog);return nd._cdf(Math.log(x),lower_tail,log_p);} -if(lower_tail){return(log_p)?Number.NEGATIVE_INFINITY:0.0;}else{return(log_p)?0.0:1.0;}},getLocation:function(){return this._location;},getScale:function(){return this._scale;},getMean:function(){return Math.exp((this._location+this._scale)/2);},getVariance:function(){var ans=(Math.exp(this._scale)-1)*Math.exp(2*this._location+this._scale);return ans;}});var GammaDistribution=ContinuousDistribution.extend({init:function(shape,scale){this._super('Gamma');this._shape=parseFloat(shape);this._scale=parseFloat(scale);this._string="Gamma ("+this._shape.toFixed(2)+", "+this._scale.toFixed(2)+")";},_pdf:function(x,give_log){var pr;var shape=this._shape;var scale=this._scale;if(give_log==null){give_log=false;} -if(shape<0||scale<=0){throw"Illegal argument in _pdf";} -if(x<0){return(give_log)?Number.NEGATIVE_INFINITY:0.0;} -if(shape==0){return(x==0)?Number.POSITIVE_INFINITY:(give_log)?Number.NEGATIVE_INFINITY:0.0;} -if(x==0){if(shape<1)return Number.POSITIVE_INFINITY;if(shape>1)return(give_log)?Number.NEGATIVE_INFINITY:0.0;return(give_log)?-Math.log(scale):1/scale;} -if(shape<1){pr=jstat.dopois_raw(shape,x/scale,give_log);return give_log?pr+Math.log(shape/x):pr*shape/x;} -pr=jstat.dopois_raw(shape-1,x/scale,give_log);return give_log?pr-Math.log(scale):pr/scale;},_cdf:function(x,lower_tail,log_p){function USE_PNORM(){pn1=Math.sqrt(alph)*3.0*(Math.pow(x/alph,1.0/3.0)+1.0/(9.0*alph)-1.0);var norm_dist=new NormalDistribution(0.0,1.0);return norm_dist._cdf(pn1,lower_tail,log_p);} -if(lower_tail==null)lower_tail=true;if(log_p==null)log_p=false;var alph=this._shape;var scale=this._scale;var xbig=1.0e+8;var xlarge=1.0e+37;var alphlimit=1e5;var pn1,pn2,pn3,pn4,pn5,pn6,arg,a,b,c,an,osum,sum,n,pearson;if(alph<=0.||scale<=0.){console.warn('Invalid gamma params in _cdf');return Number.NaN;} -x/=scale;if(isNaN(x))return x;if(x<=0.0){if(lower_tail){return(log_p)?Number.NEGATIVE_INFINITY:0.0;}else{return(log_p)?0.0:1.0;}} -if(alph>alphlimit){return USE_PNORM();} -if(x>xbig*alph){if(x>jstat.DBL_MAX*alph){if(lower_tail){return(log_p)?0.0:1.0;}else{return(log_p)?Number.NEGATIVE_INFINITY:0.0;}}else{return USE_PNORM();}} -if(x<=1.0||x<alph){pearson=1;arg=alph*Math.log(x)-x-jstat.lgamma(alph+1.0);c=1.0;sum=1.0;a=alph;do{a+=1.0;c*=x/a;sum+=c;}while(c>jstat.DBL_EPSILON*sum);}else{pearson=0;arg=alph*Math.log(x)-x-jstat.lgamma(alph);a=1.-alph;b=a+x+1.;pn1=1.;pn2=x;pn3=x+1.;pn4=x*b;sum=pn3/pn4;for(n=1;;n++){a+=1.;b+=2.;an=a*n;pn5=b*pn3-an*pn1;pn6=b*pn4-an*pn2;if(Math.abs(pn6)>0.){osum=sum;sum=pn5/pn6;if(Math.abs(osum-sum)<=jstat.DBL_EPSILON*jstat.fmin2(1.0,sum)) -break;} -pn1=pn3;pn2=pn4;pn3=pn5;pn4=pn6;if(Math.abs(pn5)>=xlarge){pn1/=xlarge;pn2/=xlarge;pn3/=xlarge;pn4/=xlarge;}}} -arg+=Math.log(sum);lower_tail=(lower_tail==pearson);if(log_p&&lower_tail) -return(arg);if(lower_tail){return Math.exp(arg);}else{if(log_p){return(arg>-Math.LN2)?Math.log(-jstat.expm1(arg)):jstat.log1p(-Math.exp(arg));}else{return-jstat.expm1(arg);}}},getShape:function(){return this._shape;},getScale:function(){return this._scale;},getMean:function(){return this._shape*this._scale;},getVariance:function(){return this._shape*Math.pow(this._scale,2);}});var BetaDistribution=ContinuousDistribution.extend({init:function(alpha,beta){this._super('Beta');this._alpha=parseFloat(alpha);this._beta=parseFloat(beta);this._string="Beta ("+this._alpha.toFixed(2)+", "+this._beta.toFixed(2)+")";},_pdf:function(x,give_log){if(give_log==null)give_log=false;var a=this._alpha;var b=this._beta;var lval;if(a<=0||b<=0){console.warn('Illegal arguments in _pdf');return Number.NaN;} -if(x<0||x>1){return(give_log)?Number.NEGATIVE_INFINITY:0.0;} -if(x==0){if(a>1){return(give_log)?Number.NEGATIVE_INFINITY:0.0;} -if(a<1){return Number.POSITIVE_INFINITY;} -return(give_log)?Math.log(b):b;} -if(x==1){if(b>1){return(give_log)?Number.NEGATIVE_INFINITY:0.0;} -if(b<1){return Number.POSITIVE_INFINITY;} -return(give_log)?Math.log(a):a;} -if(a<=2||b<=2){lval=(a-1)*Math.log(x)+(b-1)*jstat.log1p(-x)-jstat.logBeta(a,b);}else{lval=Math.log(a+b-1)+jstat.dbinom_raw(a-1,a+b-2,x,1-x,true);} -return(give_log)?lval:Math.exp(lval);},_cdf:function(x,lower_tail,log_p){if(lower_tail==null)lower_tail=true;if(log_p==null)log_p=false;var pin=this._alpha;var qin=this._beta;if(pin<=0||qin<=0){console.warn('Invalid argument in _cdf');return Number.NaN;} -if(x<=0){if(lower_tail){return(log_p)?Number.NEGATIVE_INFINITY:0.0;}else{return(log_p)?0.1:1.0;}} -if(x>=1){if(lower_tail){return(log_p)?0.1:1.0;}else{return(log_p)?Number.NEGATIVE_INFINITY:0.0;}} -return jstat.incompleteBeta(pin,qin,x);},getAlpha:function(){return this._alpha;},getBeta:function(){return this._beta;},getMean:function(){return this._alpha/(this._alpha+this._beta);},getVariance:function(){var ans=(this._alpha*this._beta)/(Math.pow(this._alpha+this._beta,2)*(this._alpha+this._beta+1));return ans;}});var StudentTDistribution=ContinuousDistribution.extend({init:function(degreesOfFreedom,mu){this._super('StudentT');this._dof=parseFloat(degreesOfFreedom);if(mu!=null){this._mu=parseFloat(mu);this._string="StudentT ("+this._dof.toFixed(2)+", "+this._mu.toFixed(2)+")";}else{this._mu=0.0;this._string="StudentT ("+this._dof.toFixed(2)+")";}},_pdf:function(x,give_log){if(give_log==null)give_log=false;if(this._mu==null){return this._dt(x,give_log);}else{var y=this._dnt(x,give_log);if(y>1){console.warn('x:'+x+', y: '+y);} -return y;}},_cdf:function(x,lower_tail,give_log){if(lower_tail==null)lower_tail=true;if(give_log==null)give_log=false;if(this._mu==null){return this._pt(x,lower_tail,give_log);}else{return this._pnt(x,lower_tail,give_log);}},_dt:function(x,give_log){var t,u;var n=this._dof;if(n<=0){console.warn('Invalid parameters in _dt');return Number.NaN;} -if(!jstat.isFinite(x)){return(give_log)?Number.NEGATIVE_INFINITY:0.0;} -if(!jstat.isFinite(n)){var norm=new NormalDistribution(0.0,1.0);return norm.density(x,give_log);} -t=-jstat.bd0(n/2.0,(n+1)/2.0)+jstat.stirlerr((n+1)/2.0)-jstat.stirlerr(n/2.0);if(x*x>0.2*n) -u=Math.log(1+x*x/n)*n/2;else -u=-jstat.bd0(n/2.0,(n+x*x)/2.0)+x*x/2.0;var p1=jstat.TWO_PI*(1+x*x/n);var p2=t-u;return(give_log)?-0.5*Math.log(p1)+p2:Math.exp(p2)/Math.sqrt(p1);},_dnt:function(x,give_log){if(give_log==null)give_log=false;var df=this._dof;var ncp=this._mu;var u;if(df<=0.0){console.warn("Illegal arguments _dnf");return Number.NaN;} -if(ncp==0.0){return this._dt(x,give_log);} -if(!jstat.isFinite(x)){if(give_log){return Number.NEGATIVE_INFINITY;}else{return 0.0;}} -if(!isFinite(df)||df>1e8){var dist=new NormalDistribution(ncp,1.);return dist.density(x,give_log);} -if(Math.abs(x)>Math.sqrt(df*jstat.DBL_EPSILON)){var newT=new StudentTDistribution(df+2,ncp);u=Math.log(df)-Math.log(Math.abs(x))+ -Math.log(Math.abs(newT._pnt(x*Math.sqrt((df+2)/df),true,false)- -this._pnt(x,true,false)));} -else{u=jstat.lgamma((df+1)/2)-jstat.lgamma(df/2) --.5*(Math.log(Math.PI)+Math.log(df)+ncp*ncp);} -return(give_log?u:Math.exp(u));},_pt:function(x,lower_tail,log_p){if(lower_tail==null)lower_tail=true;if(log_p==null)log_p=false;var val,nx;var n=this._dof;var DT_0,DT_1;if(lower_tail){if(log_p){DT_0=Number.NEGATIVE_INFINITY;DT_1=1.;}else{DT_0=0.;DT_1=1.;}}else{if(log_p){DT_0=0.;DT_1=Number.NEGATIVE_INFINITY;}else{DT_0=1.;DT_1=0.;}} -if(n<=0.0){console.warn("Invalid T distribution _pt");return Number.NaN;} -var norm=new NormalDistribution(0,1);if(!jstat.isFinite(x)){return(x<0)?DT_0:DT_1;} -if(!jstat.isFinite(n)){return norm._cdf(x,lower_tail,log_p);} -if(n>4e5){val=1./(4.*n);return norm._cdf(x*(1.-val)/sqrt(1.+x*x*2.*val),lower_tail,log_p);} -nx=1+(x/n)*x;if(nx>1e100){var lval;lval=-0.5*n*(2*Math.log(Math.abs(x))-Math.log(n)) --jstat.logBeta(0.5*n,0.5)-Math.log(0.5*n);val=log_p?lval:Math.exp(lval);}else{if(n>x*x){var beta=new BetaDistribution(0.5,n/2.);return beta._cdf(x*x/(n+x*x),false,log_p);}else{beta=new BetaDistribution(n/2.,0.5);return beta._cdf(1./nx,true,log_p);}} -if(x<=0.) -lower_tail=!lower_tail;if(log_p){if(lower_tail)return jstat.log1p(-0.5*Math.exp(val));else return val-M_LN2;} -else{val/=2.;if(lower_tail){return(0.5-val+0.5);}else{return val;}}},_pnt:function(t,lower_tail,log_p){var dof=this._dof;var ncp=this._mu;var DT_0,DT_1;if(lower_tail){if(log_p){DT_0=Number.NEGATIVE_INFINITY;DT_1=1.;}else{DT_0=0.;DT_1=1.;}}else{if(log_p){DT_0=0.;DT_1=Number.NEGATIVE_INFINITY;}else{DT_0=1.;DT_1=0.;}} -var albeta,a,b,del,errbd,lambda,rxb,tt,x;var geven,godd,p,q,s,tnc,xeven,xodd;var it,negdel;var ITRMAX=1000;var ERRMAX=1.e-7;if(dof<=0.0){return Number.NaN;}else if(dof==0.0){return this._pt(t);} -if(!jstat.isFinite(t)){return(t<0)?DT_0:DT_1;} -if(t>=0.){negdel=false;tt=t;del=ncp;}else{if(ncp>=40&&(!log_p||!lower_tail)){return DT_0;} -negdel=true;tt=-t;del=-ncp;} -if(dof>4e5||del*del>2*Math.LN2*(-(jstat.DBL_MIN_EXP))){s=1./(4.*dof);var norm=new NormalDistribution(del,Math.sqrt(1.+tt*tt*2.*s));var result=norm._cdf(tt*(1.-s),lower_tail!=negdel,log_p);return result;} -x=t*t;rxb=dof/(x+dof);x=x/(x+dof);if(x>0.){lambda=del*del;p=.5*Math.exp(-.5*lambda);if(p==0.){console.warn("underflow in _pnt");return DT_0;} -q=jstat.SQRT_2dPI*p*del;s=.5-p;if(s<1e-7){s=-0.5*jstat.expm1(-0.5*lambda);} -a=.5;b=.5*dof;rxb=Math.pow(rxb,b);albeta=jstat.LN_SQRT_PI+jstat.lgamma(b)-jstat.lgamma(.5+b);xodd=jstat.incompleteBeta(a,b,x);godd=2.*rxb*Math.exp(a*Math.log(x)-albeta);tnc=b*x;xeven=(tnc<jstat.DBL_EPSILON)?tnc:1.-rxb;geven=tnc*rxb;tnc=p*xodd+q*xeven;for(it=1;it<=ITRMAX;it++){a+=1.;xodd-=godd;xeven-=geven;godd*=x*(a+b-1.)/a;geven*=x*(a+b-.5)/(a+.5);p*=lambda/(2*it);q*=lambda/(2*it+1);tnc+=p*xodd+q*xeven;s-=p;if(s<-1.e-10){console.write("precision error _pnt");break;} -if(s<=0&&it>1)break;errbd=2.*s*(xodd-godd);if(Math.abs(errbd)<ERRMAX)break;} -if(it==ITRMAX){throw"Non-convergence _pnt";}}else{tnc=0.;} -norm=new NormalDistribution(0,1);tnc+=norm._cdf(-del,true,false);lower_tail=lower_tail!=negdel;if(tnc>1-1e-10&&lower_tail){console.warn("precision error _pnt");} -var res=jstat.fmin2(tnc,1.);if(lower_tail){if(log_p){return Math.log(res);}else{return res;}}else{if(log_p){return jstat.log1p(-(res));}else{return(0.5-(res)+0.5);}}},getDegreesOfFreedom:function(){return this._dof;},getNonCentralityParameter:function(){return this._mu;},getMean:function(){if(this._dof>1){var ans=(1/2)*Math.log(this._dof/2)+jstat.lgamma((this._dof-1)/2)-jstat.lgamma(this._dof/2) -return Math.exp(ans)*this._mu;}else{return Number.NaN;}},getVariance:function(){if(this._dof>2){var ans=this._dof*(1+this._mu*this._mu)/(this._dof-2)-(((this._mu*this._mu*this._dof)/2)*Math.pow(Math.exp(jstat.lgamma((this._dof-1)/2)-jstat.lgamma(this._dof/2)),2));return ans;}else{return Number.NaN;}}});var Plot=Class.extend({init:function(id,options){this._container='#'+String(id);this._plots=[];this._flotObj=null;this._locked=false;if(options!=null){this._options=options;}else{this._options={};}},getContainer:function(){return this._container;},getGraph:function(){return this._flotObj;},setData:function(data){this._plots=data;},clear:function(){this._plots=[];},showLegend:function(){this._options.legend={show:true} -this.render();},hideLegend:function(){this._options.legend={show:false} -this.render();},render:function(){this._flotObj=null;this._flotObj=$.plot($(this._container),this._plots,this._options);}});var DistributionPlot=Plot.extend({init:function(id,distribution,range,options){this._super(id,options);this._showPDF=true;this._showCDF=false;this._pdfValues=[];this._cdfValues=[];this._maxY=1;this._plotType='line';this._fill=false;this._distribution=distribution;if(range!=null&&Range.validate(range)){this._range=range;}else{this._range=this._distribution.getRange();} -if(this._distribution!=null){this._maxY=this._generateValues();}else{this._options.xaxis={min:range.getMinimum(),max:range.getMaximum()} -this._options.yaxis={max:1}} -this.render();},setHover:function(bool){if(bool){if(this._options.grid==null){this._options.grid={hoverable:true,mouseActiveRadius:25}}else{this._options.grid.hoverable=true,this._options.grid.mouseActiveRadius=25} -function showTooltip(x,y,contents,color){$('<div id="jstat_tooltip">'+contents+'</div>').css({position:'absolute',display:'none',top:y+15,'font-size':'small',left:x+5,border:'1px solid '+color[1],color:color[2],padding:'5px','background-color':color[0],opacity:0.80}).appendTo("body").show();} -var previousPoint=null;$(this._container).bind("plothover",function(event,pos,item){$("#x").text(pos.x.toFixed(2));$("#y").text(pos.y.toFixed(2));if(item){if(previousPoint!=item.datapoint){previousPoint=item.datapoint;$("#jstat_tooltip").remove();var x=jstat.toSigFig(item.datapoint[0],2),y=jstat.toSigFig(item.datapoint[1],2);var text=null;var color=item.series.color;if(item.series.label=='PDF'){text="P("+x+") = "+y;color=["#fee","#fdd","#C05F5F"];}else{text="F("+x+") = "+y;color=["#eef","#ddf","#4A4AC0"];} -showTooltip(item.pageX,item.pageY,text,color);}} -else{$("#jstat_tooltip").remove();previousPoint=null;}});$(this._container).bind("mouseleave",function(){if($('#jstat_tooltip').is(':visible')){$('#jstat_tooltip').remove();previousPoint=null;}});}else{if(this._options.grid==null){this._options.grid={hoverable:false}}else{this._options.grid.hoverable=false} -$(this._container).unbind("plothover");} -this.render();},setType:function(type){this._plotType=type;var lines={};var points={};if(this._plotType=='line'){lines.show=true;points.show=false;}else if(this._plotType=='points'){lines.show=false;points.show=true;}else if(this._plotType=='both'){lines.show=true;points.show=true;} -if(this._options.series==null){this._options.series={lines:lines,points:points}}else{if(this._options.series.lines==null){this._options.series.lines=lines;}else{this._options.series.lines.show=lines.show;} -if(this._options.series.points==null){this._options.series.points=points;}else{this._options.series.points.show=points.show;}} -this.render();},setFill:function(bool){this._fill=bool;if(this._options.series==null){this._options.series={lines:{fill:bool}}}else{if(this._options.series.lines==null){this._options.series.lines={fill:bool}}else{this._options.series.lines.fill=bool;}} -this.render();},clear:function(){this._super();this._distribution=null;this._pdfValues=[];this._cdfValues=[];this.render();},_generateValues:function(){this._cdfValues=[];this._pdfValues=[];var xs=this._range.getPoints();this._options.xaxis={min:xs[0],max:xs[xs.length-1]} -var pdfs=this._distribution.density(this._range);var cdfs=this._distribution.cumulativeDensity(this._range);for(var i=0;i<xs.length;i++){if(pdfs[i]==Number.POSITIVE_INFINITY||pdfs[i]==Number.NEGATIVE_INFINITY){pdfs[i]=null;} -if(cdfs[i]==Number.POSITIVE_INFINITY||cdfs[i]==Number.NEGATIVE_INFINITY){cdfs[i]=null;} -this._pdfValues.push([xs[i],pdfs[i]]);this._cdfValues.push([xs[i],cdfs[i]]);} -return jstat.max(pdfs);},showPDF:function(){this._showPDF=true;this.render();},hidePDF:function(){this._showPDF=false;this.render();},showCDF:function(){this._showCDF=true;this.render();},hideCDF:function(){this._showCDF=false;this.render();},setDistribution:function(distribution,range){this._distribution=distribution;if(range!=null){this._range=range;}else{this._range=distribution.getRange();} -this._maxY=this._generateValues();this._options.yaxis={max:this._maxY*1.1} -this.render();},getDistribution:function(){return this._distribution;},getRange:function(){return this._range;},setRange:function(range){this._range=range;this._generateValues();this.render();},render:function(){if(this._distribution!=null){if(this._showPDF&&this._showCDF){this.setData([{yaxis:1,data:this._pdfValues,color:'rgb(237,194,64)',clickable:false,hoverable:true,label:"PDF"},{yaxis:2,data:this._cdfValues,clickable:false,color:'rgb(175,216,248)',hoverable:true,label:"CDF"}]);this._options.yaxis={max:this._maxY*1.1}}else if(this._showPDF){this.setData([{data:this._pdfValues,hoverable:true,color:'rgb(237,194,64)',clickable:false,label:"PDF"}]);this._options.yaxis={max:this._maxY*1.1}}else if(this._showCDF){this.setData([{data:this._cdfValues,hoverable:true,color:'rgb(175,216,248)',clickable:false,label:"CDF"}]);this._options.yaxis={max:1.1}}}else{this.setData([]);} -this._super();}});var DistributionFactory={};DistributionFactory.build=function(json){if(json.NormalDistribution){if(json.NormalDistribution.mean!=null&&json.NormalDistribution.standardDeviation!=null){return new NormalDistribution(json.NormalDistribution.mean[0],json.NormalDistribution.standardDeviation[0]);}else{throw"Malformed JSON provided to DistributionBuilder "+json;}}else if(json.LogNormalDistribution){if(json.LogNormalDistribution.location!=null&&json.LogNormalDistribution.scale!=null){return new LogNormalDistribution(json.LogNormalDistribution.location[0],json.LogNormalDistribution.scale[0]);}else{throw"Malformed JSON provided to DistributionBuilder "+json;}}else if(json.BetaDistribution){if(json.BetaDistribution.alpha!=null&&json.BetaDistribution.beta!=null){return new BetaDistribution(json.BetaDistribution.alpha[0],json.BetaDistribution.beta[0]);}else{throw"Malformed JSON provided to DistributionBuilder "+json;}}else if(json.GammaDistribution){if(json.GammaDistribution.shape!=null&&json.GammaDistribution.scale!=null){return new GammaDistribution(json.GammaDistribution.shape[0],json.GammaDistribution.scale[0]);}else{throw"Malformed JSON provided to DistributionBuilder "+json;}}else if(json.StudentTDistribution){if(json.StudentTDistribution.degreesOfFreedom!=null&&json.StudentTDistribution.nonCentralityParameter!=null){return new StudentTDistribution(json.StudentTDistribution.degreesOfFreedom[0],json.StudentTDistribution.nonCentralityParameter[0]);}else if(json.StudentTDistribution.degreesOfFreedom!=null){return new StudentTDistribution(json.StudentTDistribution.degreesOfFreedom[0]);}else{throw"Malformed JSON provided to DistributionBuilder "+json;}}else{throw"Malformed JSON provided to DistributionBuilder "+json;}} \ No newline at end of file diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/sliders.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/sliders.js deleted file mode 100644 index 12b444cc94d..00000000000 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/sliders.js +++ /dev/null @@ -1,89 +0,0 @@ -// Wrapper for RequireJS. It will make the standard requirejs(), require(), and -// define() functions from Require JS available inside the anonymous function. -(function (requirejs, require, define) { - -define('Sliders', [], function () { - return Sliders; - - function Sliders(gstId, state) { - var c1, paramName, allParamNames, sliderDiv; - - allParamNames = state.getAllParameterNames(); - - for (c1 = 0; c1 < allParamNames.length; c1 += 1) { - paramName = allParamNames[c1]; - - sliderDiv = $('#' + gstId + '_slider_' + paramName); - - if (sliderDiv.length === 1) { - createSlider(sliderDiv, paramName); - } else if (sliderDiv.length > 1) { - console.log('ERROR: Found more than one slider for the parameter "' + paramName + '".'); - console.log('sliderDiv.length = ', sliderDiv.length); - } // else { - // console.log('MESSAGE: Did not find a slider for the parameter "' + paramName + '".'); - // } - } - - function createSlider(sliderDiv, paramName) { - var paramObj; - - paramObj = state.getParamObj(paramName); - - // Check that the retrieval went OK. - if (paramObj === undefined) { - console.log('ERROR: Could not get a paramObj for parameter "' + paramName + '".'); - - return; - } - - // Create a jQuery UI slider from the slider DIV. We will set - // starting parameters, and will also attach a handler to update - // the 'state' on the 'slide' event. - sliderDiv.slider({ - 'min': paramObj.min, - 'max': paramObj.max, - 'value': paramObj.value, - 'step': paramObj.step - }); - - // Tell the parameter object stored in state that we have a slider - // that is attached to it. Next time when the parameter changes, it - // will also update the value of this slider. - paramObj.sliderDiv = sliderDiv; - - // Atach callbacks to update the slider's parameter. - paramObj.sliderDiv.on('slide', sliderOnSlide); - paramObj.sliderDiv.on('slidechange', sliderOnChange); - - return; - - // Update the 'state' - i.e. set the value of the parameter this - // slider is attached to to a new value. - // - // This will cause the plot to be redrawn each time after the user - // drags the slider handle and releases it. - function sliderOnSlide(event, ui) { - // Last parameter passed to setParameterValue() will be 'true' - // so that the function knows we are a slider, and it can - // change the our value back in the case when the new value is - // invalid for some reason. - if (state.setParameterValue(paramName, ui.value, sliderDiv, true, 'slide') === undefined) { - console.log('ERROR: Could not update the parameter named "' + paramName + '" with the value "' + ui.value + '".'); - } - } - - function sliderOnChange(event, ui) { - if (state.setParameterValue(paramName, ui.value, sliderDiv, true, 'change') === undefined) { - console.log('ERROR: Could not update the parameter named "' + paramName + '" with the value "' + ui.value + '".'); - } - } - } - } -}); - -// End of wrapper for RequireJS. As you can see, we are passing -// namespaced Require JS variables to an anonymous function. Within -// it, you can use the standard requirejs(), require(), and define() -// functions as if they were in the global namespace. -}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define) diff --git a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/state.js b/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/state.js deleted file mode 100644 index 2a4536a8f9b..00000000000 --- a/common/lib/xmodule/xmodule/js/src/graphical_slider_tool/state.js +++ /dev/null @@ -1,395 +0,0 @@ -// Wrapper for RequireJS. It will make the standard requirejs(), require(), and -// define() functions from Require JS available inside the anonymous function. -(function (requirejs, require, define) { - -define('State', [], function () { - var stateInst; - - // Since there will be (can be) multiple GST on a page, and each will have - // a separate state, we will create a factory constructor function. The - // constructor will expect the ID of the DIV with the GST contents, and the - // configuration object (parsed from a JSON string). It will return an - // object containing methods to set and get the private state properties. - - stateInst = 0; - - // This module defines and returns a factory constructor. - return State; - - function State(gstId, config) { - var parameters, allParameterNames, allParameterValues, - plotDiv, dynamicEl, dynamicElByElId; - - dynamicEl = []; - dynamicElByElId = {}; - - stateInst += 1; - // console.log('MESSAGE: Creating state instance # ' + stateInst + '.'); - - // Initially, there are no parameters to track. So, we will instantiate - // an empty object. - // - // As we parse the JSON config object, we will add parameters as - // named properties. For example - // - // parameters.a = {...}; - // - // will be created for the parameter 'a'. - parameters = {}; - - // Check that the required parameters config object is available. - if ($.isPlainObject(config.parameters) === false) { - console.log('ERROR: Expected config.parameters to be an object. It is not.'); - console.log('config.parameters = ', config.parameters); - - return; - } - - // If config.parameters.param is an array, pass it to the processor - // element by element. - if ($.isArray(config.parameters.param) === true) { - (function (c1) { - while (c1 < config.parameters.param.length) { - processParameter(config.parameters.param[c1]); - c1 += 1; - } - }(0)); - } - - // If config.parameters.param is an object, pass this object to the - // processor directly. - else if ($.isPlainObject(config.parameters.param) === true) { - processParameter(config.parameters.param); - } - - // If config.parameters.param is some other type, report an error and - // do not continue. - else { - console.log('ERROR: config.parameters.param is of an unsupported type.'); - console.log('config.parameters.param = ', config.parameters.param); - - return; - } - - // Instead of building these arrays every time when some component - // requests them, we will create them in the beginning, and then update - // each element individually when some parameter's value changes. - // - // Then we can just return the required array, instead of iterating - // over all of the properties of the 'parameters' object, and - // extracting their names/values one by one. - allParameterNames = []; - allParameterValues = []; - - // Populate 'allParameterNames', and 'allParameterValues' with data. - generateHelperArrays(); - - // The constructor will return an object with methods to operate on - // it's private properties. - return { - 'getParameterValue': getParameterValue, - 'setParameterValue': setParameterValue, - - 'getParamObj': getParamObj, - - 'getAllParameterNames': getAllParameterNames, - 'getAllParameterValues': getAllParameterValues, - - 'bindUpdatePlotEvent': bindUpdatePlotEvent, - 'addDynamicEl': addDynamicEl, - - // plde is an abbreviation for Plot Label Dynamic Elements. - plde: [] - }; - - function getAllParameterNames() { - return allParameterNames; - } - - function getAllParameterValues() { - return allParameterValues; - } - - function getParamObj(paramName) { - if (parameters.hasOwnProperty(paramName) === false) { - console.log('ERROR: Object parameters does not have a property named "' + paramName + '".'); - - return; - } - - return parameters[paramName]; - } - - function bindUpdatePlotEvent(newPlotDiv, callback) { - plotDiv = newPlotDiv; - - plotDiv.bind('update_plot', callback); - } - - function addDynamicEl(el, func, elId, updateOnEvent) { - var newLength; - - newLength = dynamicEl.push({ - 'el': el, - 'func': func, - 'elId': elId, - 'updateOnEvent': updateOnEvent - }); - - if (typeof dynamicElByElId[elId] !== 'undefined') { - console.log( - 'ERROR: Duplicate dynamic element ID "' + elId + '" found.' - ); - } else { - dynamicElByElId[elId] = dynamicEl[newLength - 1]; - } - } - - function getParameterValue(paramName) { - - // If the name of the constant is not tracked by state, return an - // 'undefined' value. - if (parameters.hasOwnProperty(paramName) === false) { - console.log('ERROR: Object parameters does not have a property named "' + paramName + '".'); - - return; - } - - return parameters[paramname].value; - } - - // #################################################################### - // - // Function: setParameterValue(paramName, paramValue, element) - // -------------------------------------------------- - // - // - // This function can be called from a callback, registered by a slider - // or a text input, when specific events ('slide' or 'change') are - // triggered. - // - // The 'paramName' is the name of the parameter in 'parameters' object - // whose value must be updated to the new value of 'paramValue'. - // - // Before we update the value, we must check that: - // - // 1.) the parameter named as 'paramName' actually exists in the - // 'parameters' object; - // 2.) the value 'paramValue' is a valid floating-point number, and - // it lies within the range specified by the 'min' and 'max' - // properties of the stored parameter object. - // - // If 'paramName' and 'paramValue' turn out to be valid, we will update - // the stored value in the parameter with the new value, and also - // update all of the text inputs and the slider that correspond to this - // parameter (if any), so that they reflect the new parameter's value. - // Finally, the helper array 'allParameterValues' will also be updated - // to reflect the change. - // - // If something went wrong (for example the new value is outside the - // allowed range), then we will reset the 'element' to display the - // original value. - // - // #################################################################### - function setParameterValue(paramName, paramValue, element, slider, updateOnEvent) { - var paramValueNum, c1; - - // If a parameter with the name specified by the 'paramName' - // parameter is not tracked by state, do not do anything. - if (parameters.hasOwnProperty(paramName) === false) { - console.log('ERROR: Object parameters does not have a property named "' + paramName + '".'); - - return; - } - - // Try to convert the passed value to a valid floating-point - // number. - paramValueNum = parseFloat(paramValue); - - // We are interested only in valid float values. NaN, -INF, - // +INF we will disregard. - if (isFinite(paramValueNum) === false) { - console.log('ERROR: New parameter value is not a floating-point number.'); - console.log('paramValue = ', paramValue); - - return; - } - - if (paramValueNum < parameters[paramName].min) { - paramValueNum = parameters[paramName].min; - } else if (paramValueNum > parameters[paramName].max) { - paramValueNum = parameters[paramName].max; - } - - parameters[paramName].value = paramValueNum; - - // Update all text inputs with the new parameter's value. - for (c1 = 0; c1 < parameters[paramName].inputDivs.length; c1 += 1) { - parameters[paramName].inputDivs[c1].val(paramValueNum); - } - - // Update the single slider with the new parameter's value. - if ((slider === false) && (parameters[paramName].sliderDiv !== null)) { - parameters[paramName].sliderDiv.slider('value', paramValueNum); - } - - // Update the helper array with the new parameter's value. - allParameterValues[parameters[paramName].helperArrayIndex] = paramValueNum; - - for (c1 = 0; c1 < dynamicEl.length; c1++) { - if ( - ((updateOnEvent !== undefined) && (dynamicEl[c1].updateOnEvent === updateOnEvent)) || - (updateOnEvent === undefined) - ) { - // If we have a DOM element, call the function "paste" the answer into the DIV. - if (dynamicEl[c1].el !== null) { - dynamicEl[c1].el.html(dynamicEl[c1].func.apply(window, allParameterValues)); - } - // If we DO NOT have an element, simply call the function. The function can then - // manipulate all the DOM elements it wants, without the fear of them being overwritten - // by us afterwards. - else { - dynamicEl[c1].func.apply(window, allParameterValues); - } - } - } - - // If we have a plot DIV to work with, tell to update. - if (plotDiv !== undefined) { - plotDiv.trigger('update_plot'); - } - - return true; - } // End-of: function setParameterValue - - // #################################################################### - // - // Function: processParameter(obj) - // ------------------------------- - // - // - // This function will be run once for each instance of a GST when - // parsing the JSON config object. - // - // 'newParamObj' must be empty from the start for each invocation of - // this function, that's why we will declare it locally. - // - // We will parse the passed object 'obj' and populate the 'newParamObj' - // object with required properties. - // - // Since there will be many properties that are of type floating-point - // number, we will have a separate function for parsing them. - // - // processParameter() will fail right away if 'obj' does not have a - // '@var' property which represents the name of the parameter we want - // to process. - // - // If, after all of the properties have been processed, we reached the - // end of the function successfully, the 'newParamObj' will be added to - // the 'parameters' object (that is defined in the scope of State() - // function) as a property named as the name of the parameter. - // - // If at least one of the properties from 'obj' does not get correctly - // parsed, then the parameter represented by 'obj' will be disregarded. - // It will not be available to user-defined plotting functions, and - // things will most likely break. We will notify the user about this. - // - // #################################################################### - function processParameter(obj) { - var paramName, newParamObj; - - if (typeof obj['@var'] !== 'string') { - console.log('ERROR: Expected obj["@var"] to be a string. It is not.'); - console.log('obj["@var"] = ', obj['@var']); - - return; - } - - paramName = obj['@var']; - newParamObj = {}; - - if ( - (processFloat('@min', 'min') === false) || - (processFloat('@max', 'max') === false) || - (processFloat('@step', 'step') === false) || - (processFloat('@initial', 'value') === false) - ) { - console.log('ERROR: A required property is missing. Not creating parameter "' + paramName + '"'); - - return; - } - - // Pointers to text input and slider DIV elements that this - // parameter will be attached to. Initially there are none. When we - // will create text inputs and sliders, we will update these - // properties. - newParamObj.inputDivs = []; - newParamObj.sliderDiv = null; - - // Everything went well, so save the new parameter object. - parameters[paramName] = newParamObj; - - return; - - function processFloat(attrName, newAttrName) { - var attrValue; - - if (typeof obj[attrName] !== 'string') { - console.log('ERROR: Expected obj["' + attrName + '"] to be a string. It is not.'); - console.log('obj["' + attrName + '"] = ', obj[attrName]); - - return false; - } else { - attrValue = parseFloat(obj[attrName]); - - if (isFinite(attrValue) === false) { - console.log('ERROR: Expected obj["' + attrName + '"] to be a valid floating-point number. It is not.'); - console.log('obj["' + attrName + '"] = ', obj[attrName]); - - return false; - } - } - - newParamObj[newAttrName] = attrValue; - - return true; - } // End-of: function processFloat - } // End-of: function processParameter - - // #################################################################### - // - // Function: generateHelperArrays() - // ------------------------------- - // - // - // Populate 'allParameterNames' and 'allParameterValues' with data. - // Link each parameter object with the corresponding helper array via - // an index 'helperArrayIndex'. It will be the same for both of the - // arrays. - // - // NOTE: It is important to remember to update these helper arrays - // whenever a new parameter is added (or one is removed), or when a - // parameter's value changes. - // - // #################################################################### - function generateHelperArrays() { - var paramName, c1; - - c1 = 0; - for (paramName in parameters) { - allParameterNames.push(paramName); - allParameterValues.push(parameters[paramName].value); - - parameters[paramName].helperArrayIndex = c1; - - c1 += 1; - } - } - } // End-of: function State -}); - -// End of wrapper for RequireJS. As you can see, we are passing -// namespaced Require JS variables to an anonymous function. Within -// it, you can use the standard requirejs(), require(), and define() -// functions as if they were in the global namespace. -}(RequireJS.requirejs, RequireJS.require, RequireJS.define)); // End-of: (function (requirejs, require, define) diff --git a/common/lib/xmodule/xmodule/tests/test_export.py b/common/lib/xmodule/xmodule/tests/test_export.py index b9f361d4b0e..b4da1df061b 100644 --- a/common/lib/xmodule/xmodule/tests/test_export.py +++ b/common/lib/xmodule/xmodule/tests/test_export.py @@ -82,7 +82,6 @@ class RoundTripTestCase(unittest.TestCase): "conditional_and_poll", "conditional", "self_assessment", - "graphic_slider_tool", "test_exam_registration", "word_cloud", "pure_xblock", diff --git a/common/lib/xmodule/xmodule/tests/test_import.py b/common/lib/xmodule/xmodule/tests/test_import.py index a061780477c..54a7a662c1d 100644 --- a/common/lib/xmodule/xmodule/tests/test_import.py +++ b/common/lib/xmodule/xmodule/tests/test_import.py @@ -614,22 +614,6 @@ class ImportTestCase(BaseCourseTestCase): self.assertRaises(etree.XMLSyntaxError, system.process_xml, bad_xml) - def test_graphicslidertool_import(self): - ''' - Check to see if definition_from_xml in gst_module.py - works properly. Pulls data from the graphic_slider_tool directory - in the test data directory. - ''' - modulestore = XMLModuleStore(DATA_DIR, source_dirs=['graphic_slider_tool']) - - sa_id = SlashSeparatedCourseKey("edX", "gst_test", "2012_Fall") - location = sa_id.make_usage_key("graphical_slider_tool", "sample_gst") - gst_sample = modulestore.get_item(location) - render_string_from_sample_gst_xml = """ - <slider var="a" style="width:400px;float:left;"/>\ -<plot style="margin-top:15px;margin-bottom:15px;"/>""".strip() - self.assertIn(render_string_from_sample_gst_xml, gst_sample.data) - def test_word_cloud_import(self): modulestore = XMLModuleStore(DATA_DIR, source_dirs=['word_cloud']) diff --git a/common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py b/common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py index 214ce621db4..e66b6ae5a29 100644 --- a/common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py +++ b/common/lib/xmodule/xmodule/tests/test_xblock_wrappers.py @@ -32,7 +32,6 @@ from xmodule.annotatable_module import AnnotatableDescriptor from xmodule.capa_module import CapaDescriptor from xmodule.course_module import CourseDescriptor from xmodule.discussion_module import DiscussionDescriptor -from xmodule.gst_module import GraphicalSliderToolDescriptor from xmodule.html_module import HtmlDescriptor from xmodule.poll_module import PollDescriptor from xmodule.word_cloud_module import WordCloudDescriptor @@ -53,7 +52,6 @@ LEAF_XMODULES = { AnnotatableDescriptor: [{}], CapaDescriptor: [{}], DiscussionDescriptor: [{}], - GraphicalSliderToolDescriptor: [{}], HtmlDescriptor: [{}], PollDescriptor: [{'display_name': 'Poll Display Name'}], WordCloudDescriptor: [{}], @@ -75,10 +73,9 @@ CONTAINER_XMODULES = { WrapperBlock: [{}], } -# These modules are editable in studio yet +# These modules are not editable in studio yet NOT_STUDIO_EDITABLE = ( CrowdsourceHinterDescriptor, - GraphicalSliderToolDescriptor, PollDescriptor ) diff --git a/common/test/data/graphic_slider_tool/README.md b/common/test/data/graphic_slider_tool/README.md deleted file mode 100644 index ec4f121ad85..00000000000 --- a/common/test/data/graphic_slider_tool/README.md +++ /dev/null @@ -1,2 +0,0 @@ -This is a very very simple course, useful for debugging graphical slider tool -code. diff --git a/common/test/data/graphic_slider_tool/course.xml b/common/test/data/graphic_slider_tool/course.xml deleted file mode 120000 index 49041310f66..00000000000 --- a/common/test/data/graphic_slider_tool/course.xml +++ /dev/null @@ -1 +0,0 @@ -roots/2012_Fall.xml \ No newline at end of file diff --git a/common/test/data/graphic_slider_tool/course/2012_Fall.xml b/common/test/data/graphic_slider_tool/course/2012_Fall.xml deleted file mode 100644 index 2983c85dd52..00000000000 --- a/common/test/data/graphic_slider_tool/course/2012_Fall.xml +++ /dev/null @@ -1,5 +0,0 @@ -<course> - <chapter url_name="Overview"> - <graphical_slider_tool url_name="sample_gst"/> - </chapter> -</course> diff --git a/common/test/data/graphic_slider_tool/graphical_slider_tool/sample_gst.xml b/common/test/data/graphic_slider_tool/graphical_slider_tool/sample_gst.xml deleted file mode 100644 index bd0360fde82..00000000000 --- a/common/test/data/graphic_slider_tool/graphical_slider_tool/sample_gst.xml +++ /dev/null @@ -1,30 +0,0 @@ - - <graphical_slider_tool> - <render> -<slider var='a' style="width:400px;float:left;"/><plot style="margin-top:15px;margin-bottom:15px;"/> - </render> - <configuration> - <parameters> - <param var="a" min="5" max="25" step="0.5" initial="12.5" /> - </parameters> - <functions> - <function color="red">return Math.sqrt(a * a - x * x);</function> - <function color="red">return -Math.sqrt(a * a - x * x);</function> - </functions> - <plot> - <xrange> - <!-- dynamic range --> - <min> - return -a; - </min> - <max> - return a; - </max> - </xrange> - <num_points>1000</num_points> - <xticks>-30, 6, 30</xticks> - <yticks>-30, 6, 30</yticks> - </plot> - </configuration> - </graphical_slider_tool> - diff --git a/common/test/data/graphic_slider_tool/policies/2012_Fall.json b/common/test/data/graphic_slider_tool/policies/2012_Fall.json deleted file mode 100644 index 9058481dc88..00000000000 --- a/common/test/data/graphic_slider_tool/policies/2012_Fall.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "course/2012_Fall": { - "graceperiod": "2 days 5 hours 59 minutes 59 seconds", - "start": "2015-07-17T12:00", - "display_name": "GST Test", - "graded": "false" - }, - "chapter/Overview": { - "display_name": "Overview" - }, - "graphical_slider_tool/sample_gst": { - "display_name": "Sample GST" - } -} diff --git a/common/test/data/graphic_slider_tool/roots/2012_Fall.xml b/common/test/data/graphic_slider_tool/roots/2012_Fall.xml deleted file mode 100644 index 1dc86c4afcf..00000000000 --- a/common/test/data/graphic_slider_tool/roots/2012_Fall.xml +++ /dev/null @@ -1 +0,0 @@ -<course org="edX" course="gst_test" url_name="2012_Fall"/> diff --git a/lms/djangoapps/courseware/features/gst.feature b/lms/djangoapps/courseware/features/gst.feature deleted file mode 100644 index f397c54bbc0..00000000000 --- a/lms/djangoapps/courseware/features/gst.feature +++ /dev/null @@ -1,10 +0,0 @@ -@shard_2 -Feature: LMS.Graphical Slider Tool Module - As a student, I want to view a Graphical Slider Tool Component - - Scenario: The slider changes values on the page - Given that I have a course with a Graphical Slider Tool - When I view the Graphical Slider Tool - Then the displayed value should be 0 - And I move the slider to the right - Then the displayed value should be 10 \ No newline at end of file diff --git a/lms/djangoapps/courseware/features/gst.py b/lms/djangoapps/courseware/features/gst.py deleted file mode 100644 index f232f9dfadb..00000000000 --- a/lms/djangoapps/courseware/features/gst.py +++ /dev/null @@ -1,76 +0,0 @@ - -from lettuce import world, steps -from nose.tools import assert_equals - -from common import i_am_registered_for_the_course, visit_scenario_item - - -DEFAULT_DATA = """\ -<render> - <p>Test of the graphical slider tool</p> - <div class='gst-value'> - <span id="value-display" style="width:50px; float:left; margin-left:10px;"/> - </div> - <div class='gst-input'> - <slider var="a" style="width:400px;float:left;margin-left:10px;"/> - </div> -</render> -<configuration> - <parameters> - <param var="a" min="0" max="10" step="1" initial="0"/> - </parameters> - <functions> - <function output="element" el_id="value-display">a</function> - </functions> -</configuration> -""" - - -@steps -class GraphicalSliderToolSteps(object): - COURSE_NUM = 'test_course' - - def setup_gst(self, step): - r'that I have a course with a Graphical Slider Tool$' - - i_am_registered_for_the_course(step, self.COURSE_NUM) - - world.scenario_dict['GST'] = world.ItemFactory( - parent_location=world.scenario_dict['SECTION'].location, - category='graphical_slider_tool', - display_name="Test GST", - data=DEFAULT_DATA - ) - - def view_gst(self, step): - r'I view the Graphical Slider Tool$' - visit_scenario_item('GST') - world.wait_for_js_variable_truthy('$(".xblock-student_view[data-type=GraphicalSliderTool]").data("initialized")') - world.wait_for_ajax_complete() - - def check_value(self, step, value): - r'the displayed value should be (?P<value>\d+)$' - - assert_equals(world.css_text('.gst-value'), value) - - def move_slider(self, step): - r'I move the slider to the right$' - - handle_selector = '.gst-input .ui-slider-handle' - world.wait_for_visible(handle_selector) - world.wait_for_visible('.gst-value #value-display') - - def try_move(): - handle = world.css_find(handle_selector).first - slider = world.css_find('.gst-input .ui-slider').first - (handle.action_chains - .click_and_hold(handle._element) - .move_by_offset( - int(handle._element.location['x'] + 400), - 0 - ).release().perform()) - - world.retry_on_exception(try_move) - - -GraphicalSliderToolSteps() diff --git a/lms/templates/graphical_slider_tool.html b/lms/templates/graphical_slider_tool.html deleted file mode 100644 index 93a67617843..00000000000 --- a/lms/templates/graphical_slider_tool.html +++ /dev/null @@ -1,9 +0,0 @@ -<div align="center" id="${element_id}" class="${element_class}"> - <!-- hidden field to read configuration json from --> - <div class="${element_class}" id="${element_id}_json" style="display: none;"> - ${configuration_json} - </div> - - <!-- main xml with marked places for sliders, numbers, and plot --> - ${gst_html} -</div> diff --git a/lms/templates/staff_problem_info.html b/lms/templates/staff_problem_info.html index c422c9839ca..9a7252584e6 100644 --- a/lms/templates/staff_problem_info.html +++ b/lms/templates/staff_problem_info.html @@ -6,7 +6,7 @@ from django.template.defaultfilters import escapejs ## The JS for this is defined in xqa_interface.html ${block_content} -%if location.category in ['problem','video','html','combinedopenended','graphical_slider_tool', 'library_content']: +%if location.category in ['problem','video','html','combinedopenended','library_content']: % if edit_link: <div> <a href="${edit_link}">Edit</a> -- GitLab