<commit_before>/**
 * @file TreeNode component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import CircularLoading from '../CircularLoading';
import TipProvider from '../TipProvider';
import Theme from '../Theme';
import IconButton from '../IconButton';
import Radio from '../Radio';
import Checkbox from '../Checkbox';

import Position from '../_statics/Position';
import SelectMode from '../_statics/SelectMode';

import Util from '../_vendors/Util';
import Calculation from '../_vendors/Calculation';

class TreeNode extends Component {

    static SelectMode = SelectMode;
    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            collapsed: false
        };

    }

    toggleTreeNode = e => {

        e.stopPropagation();

        const {onNodeToggleStart} = this.props;
        onNodeToggleStart && onNodeToggleStart();

        this.setState({
            collapsed: !this.state.collapsed
        }, () => {
            const {onNodeToggleEnd} = this.props;
            onNodeToggleEnd && onNodeToggleEnd();
        });

    };

    checkboxChangeHandler = e => {

        const {data, path, value, onSelect, onDeselect} = this.props;

        if (!Calculation.isItemChecked(data, value, this.props)) {
            onSelect && onSelect(data, path, e);
        } else {
            onDeselect && onDeselect(data, path, e);
        }

    };

    radioChangeHandler = e => {
        const {data, path, onSelect} = this.props;
        onSelect && onSelect(data, path, e);
    };

    clickHandler = e => {

        e.preventDefault();

        const {data, path, disabled, isLoading, readOnly} = this.props;

        if (disabled || isLoading || readOnly || data.disabled || data.isLoading || data.readOnly) {
            return;
        }

        const {onClick} = this.props;
        onClick && onClick(data, path, e);

        const {selectMode} = this.props;

        switch (selectMode) {
            case SelectMode.MULTI_SELECT:
                this.checkboxChangeHandler(e);
                return;
            case SelectMode.SINGLE_SELECT:
                this.radioChangeHandler(e);
                return;
        }

    };

    render() {

        const {

                index, depth, path, theme, selectTheme, selectMode, data, value,
                disabled, isLoading, readOnly, allowCollapse, isSelectRecursive,

                collapsedIconCls, expandedIconCls, radioUncheckedIconCls, radioCheckedIconCls,
                checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,

                renderer, onMouseEnter, onMouseLeave

            } = this.props,
            {collapsed} = this.state,

            checked = Calculation.isItemChecked(data, value, this.props),
            indeterminate = Calculation.isItemIndeterminate(data, value, this.props),

            isNodeLoading = data.isLoading || isLoading,
            isNodeDisabled = data.disabled || disabled || isNodeLoading,

            nodeClassName = classNames('tree-node', {
                [`theme-${theme}`]: theme,
                [data.className]: data.className
            }),
            nodeStyle = {
                ...data.style,
                paddingLeft: (depth + 1) * 20
            },

            childrenClassName = classNames('tree-node-children', {
                collapsed
            }),

            loadingIconPosition = (data.rightIconCls && !data.iconCls) ? 'right' : 'left';

        return (

                <TipProvider className='block'
                             text={data.tip}
                             position={data.tipPosition}>

                            {
                                allowCollapse && data.children && data.children.length > 0 ?
                                    <IconButton className="tree-node-collapse-icon"
                                                iconCls={collapsed ?
                                                    data.collapsedIconCls || collapsedIconCls
                                                    :
                                                    data.expandedIconCls || expandedIconCls}
                                                onClick={this.toggleTreeNode}/>
                                    :
                                    null
                            }

                            {
                                selectMode === SelectMode.SINGLE_SELECT && (radioUncheckedIconCls || radioCheckedIconCls) ?
                                    <Radio className="tree-node-select"
                                           theme={selectTheme}
                                           checked={checked}
                                           disabled={isNodeDisabled}
                                           uncheckedIconCls={data.radioUncheckedIconCls || radioUncheckedIconCls}
                                           checkedIconCls={data.radioCheckedIconCls || radioCheckedIconCls}
                                           disableTouchRipple={true}/>
                                    :
                                    null
                            }

                            {
                                selectMode === SelectMode.MULTI_SELECT ?
                                    <Checkbox className="tree-node-select"
                                              theme={selectTheme}
                                              checked={checked}
                                              indeterminate={isSelectRecursive ? indeterminate : false}
                                              disabled={isNodeDisabled}
                                              uncheckedIconCls={data.checkboxUncheckedIconCls || checkboxUncheckedIconCls}
                                              checkedIconCls={data.checkboxCheckedIconCls || checkboxCheckedIconCls}
                                              indeterminateIconCls={data.checkboxIndeterminateIconCls || checkboxIndeterminateIconCls}
                                              disableTouchRipple={true}/>
                                    :
                                    null
                            }

                            {
                                isNodeLoading && loadingIconPosition === 'left' ?

                                        <CircularLoading className="button-loading-icon"
                                                         size="small"/>

                                    :
                                    (
                                        data.iconCls ?
                                            <i className={`button-icon button-icon-left ${data.iconCls}`}
                                               aria-hidden="true">
                                            :
                                            null
                                    )
                            }

                            {
                                data.itemRenderer && typeof data.itemRenderer === 'function' ?
                                    data.itemRenderer(data, index)
                                    :
                                    (
                                        renderer && typeof renderer === 'function' ?
                                            renderer(data, index)
                                            :
                                            (
                                                data.desc ?

                                                        {data.text}

                                                        {data.desc}

                                                    :
                                                    data.text
                                            )
                                    )
                            }

                            {
                                isNodeLoading && loadingIconPosition === 'right' ?
                                    <CircularLoading className="button-icon button-icon-right button-loading-icon"
                                                     size="small"/>
                                    :
                                    (
                                        data.rightIconCls ?
                                            <i className={`button-icon button-icon-right ${data.rightIconCls}`}
                                               aria-hidden="true">
                                            :
                                            null
                                    )
                            }

                </TipProvider>

                {
                    data.children && data.children.length > 0 ?

                            {
                                data.children.map((item, index) =>
                                    <TreeNode {...this.props}
                                              key={index}
                                              data={item}
                                              index={index}
                                              depth={depth + 1}
                                              path={
                                                  path ?
                                                      [...path, {index, node: item}]
                                                      :
                                                      [{index, node: item}]
                                              }/>
                                )
                            }

                        :
                        null
                }

        );

    }
}

TreeNode.propTypes = {

    index: PropTypes.number,
    depth: PropTypes.number,
    path: PropTypes.array,

    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    data: PropTypes.object,
    value: PropTypes.any,

    idField: PropTypes.string,
    valueField: PropTypes.string,
    displayField: PropTypes.string,
    descriptionField: PropTypes.string,

    disabled: PropTypes.bool,
    isLoading: PropTypes.bool,
    readOnly: PropTypes.bool,
    allowCollapse: PropTypes.bool,
    isNodeToggling: PropTypes.bool,
    isSelectRecursive: PropTypes.bool,

    renderer: PropTypes.func,

    collapsedIconCls: PropTypes.string,
    expandedIconCls: PropTypes.string,
    radioUncheckedIconCls: PropTypes.string,
    radioCheckedIconCls: PropTypes.string,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: PropTypes.string,

    onClick: PropTypes.func,
    onSelect: PropTypes.func,
    onDeselect: PropTypes.func,
    onMouseEnter: PropTypes.func,
    onMouseLeave: PropTypes.func,
    onNodeToggleStart: PropTypes.func,
    onNodeToggleEnd: PropTypes.func

};

TreeNode.defaultProps = {

    index: 0,
    depth: 0,

    theme: Theme.DEFAULT,

    selectTheme: Theme.DEFAULT,
    selectMode: SelectMode.SINGLE_SELECT,

    idField: 'id',
    valueField: 'value',
    displayField: 'text',
    descriptionField: 'desc',

    disabled: false,
    isLoading: false,
    readOnly: false,
    allowCollapse: true,
    isNodeToggling: false,
    isSelectRecursive: false,

    tipPosition: Position.BOTTOM,

    collapsedIconCls: 'fas fa-caret-right',
    expandedIconCls: 'fas fa-caret-down',
    checkboxUncheckedIconCls: 'far fa-square',
    checkboxCheckedIconCls: 'fas fa-check-square',
    checkboxIndeterminateIconCls: 'fas fa-minus-square'

};

export default TreeNode;<commit_msg>update TreeNode<commit_after>/**
 * @file TreeNode component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';

import CircularLoading from '../CircularLoading';
import TipProvider from '../TipProvider';
import Theme from '../Theme';
import IconButton from '../IconButton';
import Radio from '../Radio';
import Checkbox from '../Checkbox';

import Position from '../_statics/Position';
import SelectMode from '../_statics/SelectMode';

import Util from '../_vendors/Util';
import Calculation from '../_vendors/Calculation';

class TreeNode extends Component {

    static SelectMode = SelectMode;
    static Theme = Theme;

    constructor(props, ...restArgs) {

        super(props, ...restArgs);

        this.state = {
            collapsed: false
        };

    }

    toggleTreeNode = e => {

        e.stopPropagation();

        const {onNodeToggleStart} = this.props;
        onNodeToggleStart && onNodeToggleStart();

        this.setState({
            collapsed: !this.state.collapsed
        }, () => {
            const {onNodeToggleEnd} = this.props;
            onNodeToggleEnd && onNodeToggleEnd();
        });

    };

    checkboxChangeHandler = e => {

        const {data, path, value, onSelect, onDeselect} = this.props;

        if (!Calculation.isItemChecked(data, value, this.props)) {
            onSelect && onSelect(data, path, e);
        } else {
            onDeselect && onDeselect(data, path, e);
        }

    };

    radioChangeHandler = e => {
        const {data, path, onSelect} = this.props;
        onSelect && onSelect(data, path, e);
    };

    clickHandler = e => {

        e.preventDefault();

        const {data, path, disabled, isLoading, readOnly} = this.props;

        if (disabled || isLoading || readOnly || data.disabled || data.isLoading || data.readOnly) {
            return;
        }

        const {onClick} = this.props;
        onClick && onClick(data, path, e);

        const {selectMode} = this.props;

        switch (selectMode) {
            case SelectMode.MULTI_SELECT:
                this.checkboxChangeHandler(e);
                return;
            case SelectMode.SINGLE_SELECT:
                this.radioChangeHandler(e);
                return;
        }

    };

    render() {

        const {

                index, depth, path, theme, selectTheme, selectMode, data, value,
                disabled, isLoading, readOnly, allowCollapse, isSelectRecursive,
                valueField, displayField, descriptionField,

                collapsedIconCls, expandedIconCls, radioUncheckedIconCls, radioCheckedIconCls,
                checkboxUncheckedIconCls, checkboxCheckedIconCls, checkboxIndeterminateIconCls,

                renderer, onMouseEnter, onMouseLeave

            } = this.props,
            {collapsed} = this.state,

            checked = Calculation.isItemChecked(data, value, this.props),
            indeterminate = Calculation.isItemIndeterminate(data, value, this.props),

            isNodeLoading = data.isLoading || isLoading,
            isNodeDisabled = data.disabled || disabled || isNodeLoading,

            nodeClassName = classNames('tree-node', {
                [`theme-${theme}`]: theme,
                [data.className]: data.className
            }),
            nodeStyle = {
                ...data.style,
                paddingLeft: (depth + 1) * 20
            },

            childrenClassName = classNames('tree-node-children', {
                collapsed
            }),

            loadingIconPosition = (data.rightIconCls && !data.iconCls) ? 'right' : 'left';

        return (

                <TipProvider className='block'
                             text={data.tip}
                             position={data.tipPosition}>

                            {
                                allowCollapse && data.children && data.children.length > 0 ?
                                    <IconButton className="tree-node-collapse-icon"
                                                iconCls={collapsed ?
                                                    data.collapsedIconCls || collapsedIconCls
                                                    :
                                                    data.expandedIconCls || expandedIconCls}
                                                onClick={this.toggleTreeNode}/>
                                    :
                                    null
                            }

                            {
                                selectMode === SelectMode.SINGLE_SELECT && (radioUncheckedIconCls || radioCheckedIconCls) ?
                                    <Radio className="tree-node-select"
                                           theme={selectTheme}
                                           checked={checked}
                                           disabled={isNodeDisabled}
                                           uncheckedIconCls={data.radioUncheckedIconCls || radioUncheckedIconCls}
                                           checkedIconCls={data.radioCheckedIconCls || radioCheckedIconCls}
                                           disableTouchRipple={true}/>
                                    :
                                    null
                            }

                            {
                                selectMode === SelectMode.MULTI_SELECT ?
                                    <Checkbox className="tree-node-select"
                                              theme={selectTheme}
                                              checked={checked}
                                              indeterminate={isSelectRecursive ? indeterminate : false}
                                              disabled={isNodeDisabled}
                                              uncheckedIconCls={data.checkboxUncheckedIconCls || checkboxUncheckedIconCls}
                                              checkedIconCls={data.checkboxCheckedIconCls || checkboxCheckedIconCls}
                                              indeterminateIconCls={data.checkboxIndeterminateIconCls || checkboxIndeterminateIconCls}
                                              disableTouchRipple={true}/>
                                    :
                                    null
                            }

                            {
                                isNodeLoading && loadingIconPosition === 'left' ?

                                        <CircularLoading className="button-loading-icon"
                                                         size="small"/>

                                    :
                                    (
                                        data.iconCls ?
                                            <i className={`button-icon button-icon-left ${data.iconCls}`}
                                               aria-hidden="true">
                                            :
                                            null
                                    )
                            }

                            {
                                data.itemRenderer && typeof data.itemRenderer === 'function' ?
                                    data.itemRenderer(data, index)
                                    :
                                    (
                                        renderer && typeof renderer === 'function' ?
                                            renderer(data, index)
                                            :
                                            (
                                                data[descriptionField] ?

                                                        {Util.getTextByDisplayField(data, displayField, valueField)}

                                                        {data[descriptionField]}

                                                    :
                                                    Util.getTextByDisplayField(data, displayField, valueField)
                                            )
                                    )
                            }

                            {
                                isNodeLoading && loadingIconPosition === 'right' ?
                                    <CircularLoading className="button-icon button-icon-right button-loading-icon"
                                                     size="small"/>
                                    :
                                    (
                                        data.rightIconCls ?
                                            <i className={`button-icon button-icon-right ${data.rightIconCls}`}
                                               aria-hidden="true">
                                            :
                                            null
                                    )
                            }

                </TipProvider>

                {
                    data.children && data.children.length > 0 ?

                            {
                                data.children.map((item, index) =>
                                    <TreeNode {...this.props}
                                              key={index}
                                              data={item}
                                              index={index}
                                              depth={depth + 1}
                                              path={
                                                  path ?
                                                      [...path, {index, node: item}]
                                                      :
                                                      [{index, node: item}]
                                              }/>
                                )
                            }

                        :
                        null
                }

        );

    }
}

TreeNode.propTypes = {

    index: PropTypes.number,
    depth: PropTypes.number,
    path: PropTypes.array,

    theme: PropTypes.oneOf(Util.enumerateValue(Theme)),

    selectTheme: PropTypes.oneOf(Util.enumerateValue(Theme)),
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    data: PropTypes.object,
    value: PropTypes.any,

    idField: PropTypes.string,
    valueField: PropTypes.string,
    displayField: PropTypes.string,
    descriptionField: PropTypes.string,

    disabled: PropTypes.bool,
    isLoading: PropTypes.bool,
    readOnly: PropTypes.bool,
    allowCollapse: PropTypes.bool,
    isNodeToggling: PropTypes.bool,
    isSelectRecursive: PropTypes.bool,

    renderer: PropTypes.func,

    collapsedIconCls: PropTypes.string,
    expandedIconCls: PropTypes.string,
    radioUncheckedIconCls: PropTypes.string,
    radioCheckedIconCls: PropTypes.string,
    checkboxUncheckedIconCls: PropTypes.string,
    checkboxCheckedIconCls: PropTypes.string,
    checkboxIndeterminateIconCls: PropTypes.string,

    onClick: PropTypes.func,
    onSelect: PropTypes.func,
    onDeselect: PropTypes.func,
    onMouseEnter: PropTypes.func,
    onMouseLeave: PropTypes.func,
    onNodeToggleStart: PropTypes.func,
    onNodeToggleEnd: PropTypes.func

};

TreeNode.defaultProps = {

    index: 0,
    depth: 0,

    theme: Theme.DEFAULT,

    selectTheme: Theme.DEFAULT,
    selectMode: SelectMode.SINGLE_SELECT,

    idField: 'id',
    valueField: 'value',
    displayField: 'text',
    descriptionField: 'desc',

    disabled: false,
    isLoading: false,
    readOnly: false,
    allowCollapse: true,
    isNodeToggling: false,
    isSelectRecursive: false,

    tipPosition: Position.BOTTOM,

    collapsedIconCls: 'fas fa-caret-right',
    expandedIconCls: 'fas fa-caret-down',
    checkboxUncheckedIconCls: 'far fa-square',
    checkboxCheckedIconCls: 'fas fa-check-square',
    checkboxIndeterminateIconCls: 'fas fa-minus-square'

};

export default TreeNode;<|endoftext|>


<commit_before>/**
 * Copyright (c) 2017, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */
/* global chai */
/* global describe */
/* global sinon */
/* global it */
/* global beforeEach */

import React from 'react';
import { mount } from 'enzyme';

import UploadLaunchOverlay from '../../../app/components/uploadlaunchoverlay';
import ModalOverlay from '../../../app/components/modaloverlay';
import { URL_UPLOADER_DOWNLOAD_PAGE } from '../../../app/core/constants';

const expect = chai.expect;

import releases from '../../fixtures/githubreleasefixture';

describe('UploadLaunchOverlay', function () {
  const props = {
    overlayClickHandler: sinon.spy(),
  };

  let wrapper;
  beforeEach(() => {
    wrapper = mount( <UploadLaunchOverlay {...props} /> );
  });

  it('should be a function', function() {
    expect(UploadLaunchOverlay).to.be.a('function');
  });

  describe('render', function() {
    it('should render without problems', function () {
      expect(wrapper.find(UploadLaunchOverlay)).to.have.length(1);
      expect(wrapper.find(ModalOverlay)).to.have.length(1);
    });

    it('should respond to an onClick event', () => {
      var callCount = props.overlayClickHandler.callCount;
      wrapper.find('.ModalOverlay-target').simulate('click');
      expect(props.overlayClickHandler.callCount).to.equal(callCount + 1);
    });

    it('should have disabled download buttons if no URLs have been set', () => {
      wrapper.setState({
        latestWinRelease: null,
        latestMacRelease: null,
      });
      expect(wrapper.find('a.disabled')).to.have.length(2);
    });

    it('should have active buttons if URLs have been set', () => {
      wrapper.setState({
        latestMacRelease: 'test',
        latestWinRelease: 'test',
      });
      expect(wrapper.find('a')).to.have.length(2);
      expect(wrapper.find('a.disabled')).to.have.length(0);
    });

    it('should display download link if error retrieving github releases', () => {
      wrapper.setState({
        error: 'some error',
      });
      expect(wrapper.find({ href: URL_UPLOADER_DOWNLOAD_PAGE }).filter('a')).to.have.length(1);
    });
  });
});
<commit_msg>Fix variable name in unit tests<commit_after>/**
 * Copyright (c) 2017, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 */
/* global chai */
/* global describe */
/* global sinon */
/* global it */
/* global beforeEach */

import React from 'react';
import { mount } from 'enzyme';

import UploadLaunchOverlay from '../../../app/components/uploadlaunchoverlay';
import ModalOverlay from '../../../app/components/modaloverlay';
import { URL_UPLOADER_DOWNLOAD_PAGE } from '../../../app/core/constants';

const expect = chai.expect;

import releases from '../../fixtures/githubreleasefixture';

describe('UploadLaunchOverlay', function () {
  const props = {
    modalDismissHandler: sinon.spy(),
  };

  let wrapper;
  beforeEach(() => {
    wrapper = mount( <UploadLaunchOverlay {...props} /> );
  });

  it('should be a function', function() {
    expect(UploadLaunchOverlay).to.be.a('function');
  });

  describe('render', function() {
    it('should render without problems', function () {
      expect(wrapper.find(UploadLaunchOverlay)).to.have.length(1);
      expect(wrapper.find(ModalOverlay)).to.have.length(1);
    });

    it('should respond to an onClick event', () => {
      var callCount = props.modalDismissHandler.callCount;
      wrapper.find('.ModalOverlay-target').simulate('click');
      expect(props.modalDismissHandler.callCount).to.equal(callCount + 1);
    });

    it('should have disabled download buttons if no URLs have been set', () => {
      wrapper.setState({
        latestWinRelease: null,
        latestMacRelease: null,
      });
      expect(wrapper.find('a.disabled')).to.have.length(2);
    });

    it('should have active buttons if URLs have been set', () => {
      wrapper.setState({
        latestMacRelease: 'test',
        latestWinRelease: 'test',
      });
      expect(wrapper.find('a')).to.have.length(2);
      expect(wrapper.find('a.disabled')).to.have.length(0);
    });

    it('should display download link if error retrieving github releases', () => {
      wrapper.setState({
        error: 'some error',
      });
      expect(wrapper.find({ href: URL_UPLOADER_DOWNLOAD_PAGE }).filter('a')).to.have.length(1);
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

var Plotly = require('./plotly'),
    objectAssign = require('object-assign');

var NESTED_MODULE = '_nestedModules',
    COMPOSED_MODULE = '_composedModules';

// list of underscore attributes to keep in schema as is
var UNDERSCORE_ATTRS = ['_isLinkedToArray', '_isSubplotObj'];

var plotSchema = {
    traces: {},
    layout: {},
    defs: {}
};

// FIXME polar attribute are not part of Plotly yet
var polarAreaAttrs = require('./polar/attributes/area'),
    polarAxisAttrs = require('./polar/attributes/polaraxes');

var PlotSchema = module.exports = {};

PlotSchema.get =  function() {
    Plotly.Plots.allTypes
        .concat('area')  // FIXME polar 'area' attributes
        .forEach(getTraceAttributes);

    getLayoutAttributes();
    getDefs();
    return plotSchema;
};

PlotSchema.crawl = function(attrs, callback) {
    Object.keys(attrs).forEach(function(attrName) {
        var attr = attrs[attrName];

        callback(attr, attrName, attrs);

        if(PlotSchema.isValObject(attr)) return;
        if(Plotly.Lib.isPlainObject(attr)) PlotSchema.crawl(attr, callback);
    });
};

PlotSchema.isValObject = function(obj) {
    return obj && obj.valType !== undefined;
};

function getTraceAttributes(type) {
    var globalAttributes = Plotly.Plots.attributes,
        _module = getModule({type: type}),
        meta = getMeta(type),
        subplotRegistry = getSubplotRegistry(type),
        attributes = {},
        layoutAttributes = {};

    // make 'type' the first attribute in the object
    attributes.type = null;

    // module attributes (+ nested + composed)
    attributes = coupleAttrs(
        _module.attributes, attributes, 'attributes', type
    );

    // subplot attributes
    if(subplotRegistry.attributes !== undefined) {
        attributes = objectAssign(attributes, subplotRegistry.attributes);
    }

    // global attributes (same for all trace types)
    attributes = objectAssign(attributes, globalAttributes);

    // 'type' gets overwritten by globalAttributes; reset it here
    attributes.type = type;

    attributes = removeUnderscoreAttrs(attributes);

    mergeValTypeAndRole(attributes);
    plotSchema.traces[type] = objectAssign(
        meta,
        { attributes: attributes }
    );

    // trace-specific layout attributes
    if(_module.layoutAttributes !== undefined) {
        layoutAttributes = coupleAttrs(
            _module.layoutAttributes, layoutAttributes, 'layoutAttributes', type
        );

        mergeValTypeAndRole(layoutAttributes);
        plotSchema.traces[type].layoutAttributes = layoutAttributes;
    }
}

function getLayoutAttributes() {
    var globalLayoutAttributes = Plotly.Plots.layoutAttributes,
        subplotsRegistry = Plotly.Plots.subplotsRegistry,
        layoutAttributes = {};

    // layout module attributes (+ nested + composed)
    layoutAttributes = coupleAttrs(
        globalLayoutAttributes, layoutAttributes, 'layoutAttributes', '*'
    );

    // FIXME polar layout attributes
    layoutAttributes = assignPolarLayoutAttrs(layoutAttributes);
    layoutAttributes = removeUnderscoreAttrs(layoutAttributes);

    // add IS_SUBPLOT_OBJ key
    Object.keys(layoutAttributes).forEach(function(k) {
        if(subplotsRegistry.gl3d.idRegex.test(k) ||
            subplotsRegistry.geo.idRegex.test(k) ||
            /^xaxis[0-9]*$/.test(k) ||
            /^yaxis[0-9]*$/.test(k)
          ) layoutAttributes[k][IS_SUBPLOT_OBJ] = true;
    });

    mergeValTypeAndRole(layoutAttributes);
    plotSchema.layout = { layoutAttributes: layoutAttributes };
}

function getDefs() {
    plotSchema.defs = { valObjects: Plotly.Lib.valObjects };
}

function coupleAttrs(attrsIn, attrsOut, whichAttrs, type) {
    var nestedModule, nestedAttrs, nestedReference,
        composedModule, composedAttrs;

    Object.keys(attrsIn).forEach(function(k) {

        if(k === NESTED_MODULE) {
            Object.keys(attrsIn[k]).forEach(function(kk) {
                nestedModule = getModule({module: attrsIn[k][kk]});
                if(nestedModule === undefined) return;

                nestedAttrs = nestedModule[whichAttrs];
                nestedReference = coupleAttrs(
                    nestedAttrs, {}, whichAttrs, type
                );

                Plotly.Lib.nestedProperty(attrsOut, kk)
                    .set(nestedReference);
            });
            return;
        }

        if(k === COMPOSED_MODULE) {
            Object.keys(attrsIn[k]).forEach(function(kk) {
                if(kk !== type) return;

                composedModule = getModule({module: attrsIn[k][kk]});
                if(composedModule === undefined) return;

                composedAttrs = composedModule[whichAttrs];
                composedAttrs = coupleAttrs(
                    composedAttrs, {}, whichAttrs, type
                );

                attrsOut = objectAssign(attrsOut, composedAttrs);
            });
            return;
        }

        // underscore attributes are booleans
        attrsOut[k] = (UNDERSCORE_ATTRS.indexOf(k) !== -1) ?
            attrsIn[k] :
            objectAssign({}, attrsIn[k]);
    });

    return attrsOut;
}

function mergeValTypeAndRole(attrs) {

    function callback(attr, attrName, attrs) {
        if(PlotSchema.isValObject(attr)) {
            if(attr.valType === 'data_array') {
                attr.role = 'data';
                attrs[attrName + 'src'] = {
                    valType: 'string',
                    role: 'data',
                    description: [
                        'Sets the source for ', attrName, '.'
                    ].join(' ')
                };
           }
        }
        else if(Plotly.Lib.isPlainObject(attr)) attr.role = 'object';
    }

    PlotSchema.crawl(attrs, callback);
}

// helper methods

function getModule(arg) {
    if('type' in arg) {
        return (arg.type === 'area') ?  // FIXME
            { attributes: polarAreaAttrs } :
            Plotly.Plots.getModule({type: arg.type});
    }
    else if('module' in arg) return Plotly[arg.module];
}

function removeUnderscoreAttrs(attributes) {
    Object.keys(attributes).forEach(function(k){
        if(k.charAt(0) === '_' &&
            UNDERSCORE_ATTRS.indexOf(k) === -1) delete attributes[k];
    });
    return attributes;
}

function getMeta(type) {
    if(type === 'area') return {};  // FIXME
    return Plotly.Plots.modules[type].meta || {};
}

function assignPolarLayoutAttrs(layoutAttributes) {
    layoutAttributes = objectAssign(layoutAttributes, {
        radialaxis: polarAxisAttrs.radialaxis,
        angularaxis: polarAxisAttrs.angularaxis
    });

    layoutAttributes = objectAssign(layoutAttributes, polarAxisAttrs.layout);

    return layoutAttributes;
}

function getSubplotRegistry(traceType) {
    var subplotsRegistry = Plotly.Plots.subplotsRegistry,
        subplotType = Object.keys(subplotsRegistry).filter(function(subplotType) {
            return Plotly.Plots.traceIs({type: traceType}, subplotType);
        })[0];

    if(traceType === 'area') return {};  // FIXME
    if(subplotType === undefined) return {};

    return subplotsRegistry[subplotType];
}
<commit_msg>add a few comments in plotschema.js<commit_after>'use strict';

var Plotly = require('./plotly'),
    objectAssign = require('object-assign');

var NESTED_MODULE = '_nestedModules',
    COMPOSED_MODULE = '_composedModules',
    IS_SUBPLOT_OBJ = '_isSubplotObj';

// list of underscore attributes to keep in schema as is
var UNDERSCORE_ATTRS = ['_isLinkedToArray', '_isSubplotObj'];

var plotSchema = {
    traces: {},
    layout: {},
    defs: {}
};

// FIXME polar attribute are not part of Plotly yet
var polarAreaAttrs = require('./polar/attributes/area'),
    polarAxisAttrs = require('./polar/attributes/polaraxes');

var PlotSchema = module.exports = {};

PlotSchema.get =  function() {
    Plotly.Plots.allTypes
        .concat('area')  // FIXME polar 'area' attributes
        .forEach(getTraceAttributes);

    getLayoutAttributes();
    getDefs();
    return plotSchema;
};

PlotSchema.crawl = function(attrs, callback) {
    Object.keys(attrs).forEach(function(attrName) {
        var attr = attrs[attrName];

        callback(attr, attrName, attrs);

        if(PlotSchema.isValObject(attr)) return;
        if(Plotly.Lib.isPlainObject(attr)) PlotSchema.crawl(attr, callback);
    });
};

PlotSchema.isValObject = function(obj) {
    return obj && obj.valType !== undefined;
};

function getTraceAttributes(type) {
    var globalAttributes = Plotly.Plots.attributes,
        _module = getModule({type: type}),
        meta = getMeta(type),
        subplotRegistry = getSubplotRegistry(type),
        attributes = {},
        layoutAttributes = {};

    // make 'type' the first attribute in the object
    attributes.type = null;

    // module attributes (+ nested + composed)
    attributes = coupleAttrs(
        _module.attributes, attributes, 'attributes', type
    );

    // subplot attributes
    if(subplotRegistry.attributes !== undefined) {
        attributes = objectAssign(attributes, subplotRegistry.attributes);
    }

    // global attributes (same for all trace types)
    attributes = objectAssign(attributes, globalAttributes);

    // 'type' gets overwritten by globalAttributes; reset it here
    attributes.type = type;

    attributes = removeUnderscoreAttrs(attributes);

    mergeValTypeAndRole(attributes);
    plotSchema.traces[type] = objectAssign(
        meta,
        { attributes: attributes }
    );

    // trace-specific layout attributes
    if(_module.layoutAttributes !== undefined) {
        layoutAttributes = coupleAttrs(
            _module.layoutAttributes, layoutAttributes, 'layoutAttributes', type
        );

        mergeValTypeAndRole(layoutAttributes);
        plotSchema.traces[type].layoutAttributes = layoutAttributes;
    }
}

function getLayoutAttributes() {
    var globalLayoutAttributes = Plotly.Plots.layoutAttributes,
        subplotsRegistry = Plotly.Plots.subplotsRegistry,
        layoutAttributes = {};

    // layout module attributes (+ nested + composed)
    layoutAttributes = coupleAttrs(
        globalLayoutAttributes, layoutAttributes, 'layoutAttributes', '*'
    );

    // FIXME polar layout attributes
    layoutAttributes = assignPolarLayoutAttrs(layoutAttributes);

    // add IS_SUBPLOT_OBJ attribute
    Object.keys(layoutAttributes).forEach(function(k) {
        if(subplotsRegistry.gl3d.idRegex.test(k) ||
            subplotsRegistry.geo.idRegex.test(k) ||
            /^xaxis[0-9]*$/.test(k) ||
            /^yaxis[0-9]*$/.test(k)
          ) layoutAttributes[k][IS_SUBPLOT_OBJ] = true;
    });

    layoutAttributes = removeUnderscoreAttrs(layoutAttributes);

    mergeValTypeAndRole(layoutAttributes);
    plotSchema.layout = { layoutAttributes: layoutAttributes };
}

function getDefs() {
    plotSchema.defs = { valObjects: Plotly.Lib.valObjects };
}

function coupleAttrs(attrsIn, attrsOut, whichAttrs, type) {
    var nestedModule, nestedAttrs, nestedReference,
        composedModule, composedAttrs;

    Object.keys(attrsIn).forEach(function(k) {

        if(k === NESTED_MODULE) {
            Object.keys(attrsIn[k]).forEach(function(kk) {
                nestedModule = getModule({module: attrsIn[k][kk]});
                if(nestedModule === undefined) return;

                nestedAttrs = nestedModule[whichAttrs];
                nestedReference = coupleAttrs(
                    nestedAttrs, {}, whichAttrs, type
                );

                Plotly.Lib.nestedProperty(attrsOut, kk)
                    .set(nestedReference);
            });
            return;
        }

        if(k === COMPOSED_MODULE) {
            Object.keys(attrsIn[k]).forEach(function(kk) {
                if(kk !== type) return;

                composedModule = getModule({module: attrsIn[k][kk]});
                if(composedModule === undefined) return;

                composedAttrs = composedModule[whichAttrs];
                composedAttrs = coupleAttrs(
                    composedAttrs, {}, whichAttrs, type
                );

                attrsOut = objectAssign(attrsOut, composedAttrs);
            });
            return;
        }

        // underscore attributes are booleans
        attrsOut[k] = (UNDERSCORE_ATTRS.indexOf(k) !== -1) ?
            attrsIn[k] :
            objectAssign({}, attrsIn[k]);
    });

    return attrsOut;
}

function mergeValTypeAndRole(attrs) {

    function callback(attr, attrName, attrs) {
        if(PlotSchema.isValObject(attr)) {
            if(attr.valType === 'data_array') {
                // all 'data_array' attrs have role 'data'
                attr.role = 'data';
                // all 'data_array' attrs have a corresponding 'src' attr
                attrs[attrName + 'src'] = {
                    valType: 'string',
                    role: 'data',
                    description: [
                        'Sets the source for ', attrName, '.'
                    ].join(' ')
                };
           }
        }
        else if(Plotly.Lib.isPlainObject(attr)) {
            // all attrs container objects get role 'object'
            attr.role = 'object';
        }
    }

    PlotSchema.crawl(attrs, callback);
}

// helper methods

function getModule(arg) {
    if('type' in arg) {
        return (arg.type === 'area') ?  // FIXME
            { attributes: polarAreaAttrs } :
            Plotly.Plots.getModule({type: arg.type});
    }
    else if('module' in arg) return Plotly[arg.module];
}

function removeUnderscoreAttrs(attributes) {
    Object.keys(attributes).forEach(function(k){
        if(k.charAt(0) === '_' &&
            UNDERSCORE_ATTRS.indexOf(k) === -1) delete attributes[k];
    });
    return attributes;
}

function getMeta(type) {
    if(type === 'area') return {};  // FIXME
    return Plotly.Plots.modules[type].meta || {};
}

function assignPolarLayoutAttrs(layoutAttributes) {
    layoutAttributes = objectAssign(layoutAttributes, {
        radialaxis: polarAxisAttrs.radialaxis,
        angularaxis: polarAxisAttrs.angularaxis
    });

    layoutAttributes = objectAssign(layoutAttributes, polarAxisAttrs.layout);

    return layoutAttributes;  // FIXME
}

function getSubplotRegistry(traceType) {
    var subplotsRegistry = Plotly.Plots.subplotsRegistry,
        subplotType = Object.keys(subplotsRegistry).filter(function(subplotType) {
            return Plotly.Plots.traceIs({type: traceType}, subplotType);
        })[0];

    if(traceType === 'area') return {};  // FIXME
    if(subplotType === undefined) return {};

    return subplotsRegistry[subplotType];
}
<|endoftext|>


<commit_before>engine.ImportExtension("qt.core");
engine.ImportExtension("qt.xml");

print("< JS qt.xml example:");

//converted the c++ in http://doc.trolltech.com/4.6/qdomdocument.html
var doc = new QDomDocument("mydocument");

//works when running from Tundra bin: ./Tundra --headless --run jsmodules/apitest/qtxml.js
var file = new QFile("plugins.xml");

//if (!file.open(QIODevice::ReadOnly))
//     return;
/*if (!doc.setContent(&file)) {
     file.close();
     //return;
}*/
doc.setContent(file);
file.close();

print("---");

// print out the element names of all elements that are direct children
 // of the outermost element.
var docElem = doc.documentElement();

var n = docElem.firstChild();
while(!n.isNull()) {
    //print(".");
    var e = n.toElement(); // try to convert the node to an element.
    if(!e.isNull()) {
        print(e.tagName()); // the node really is an element.
     }
     n = n.nextSibling();
 }

/*
 // Here we append a new element to the end of the document
 QDomElement elem = doc.createElement("img");
 elem.setAttribute("src", "myimage.png");
 docElem.appendChild(elem);
*/

/* creating - no worky for some reason?
is from http://developer.qt.nokia.com/forums/viewthread/12949 where they suspect appendChild is broken.

var doc = new QDomDocument();
var root = doc.createElement("root");
doc.appendChild(root);
root.setAttribute("attr1", "value1")

var tag = doc.createElement("tag1");
root.appendChild(tag);

print(doc);
print((doc.toString()));
*/

print(".. /qt xml example end> ");<commit_msg>Append my QtXml-QtScript code snippet done in the past to the existing test/example code.<commit_after>// For conditions of distribution and use, see copyright notice in LICENSE

engine.ImportExtension("qt.core");
engine.ImportExtension("qt.xml");

QtXmlTest();

// Loads the plugin.xml from Tundra/bin twice, first by using both plain QFile, and the second time using QFile and QXmlInputSource.
function QtXmlTest()
{
    var file = new QFile("plugins.xml");
    var errorMsg;
    var errorLine;
    var errorColumn;
    var domDocFromFile = new QDomDocument();

    // The following line should work to my knowledge, but for some (non-apparent) reason it doens't:
    // var fileOk = domDocFromFile["setContent(QIODevice,bool,QString,int,int)"](file, true, errorMsg, errorLine, errorColumn);
    // I'm suspecting it has something to do with the fact that QDomDocument doesn't inherit QObject (I have encountered some mysterious
    // behavior with e.g. QTreeWidgetItem also), and the fact that the actual C++ function implementation uses default argument values:
    // bool setContent(QIODevice *dev, bool namespaceProcessing, QString * errorMsg = 0, int * errorLine = 0, int * errorColumn = 0);
    // My guess is that that passing C-type pointers (or references for that matter) which are used for output is not simply
    // supported/understood by QtScript(Generator).
    // Probably QtScriptGenerator doesn't generate function "signatures" for all cases (the function at hand would yield four different possible signatures).
    // Hence the function call must be done with none of the "optional" arguments provided.
    // So, the following works without problems (let's try "bool setContent(QIODevice * dev)"):
    var fileOk = domDocFromFile.setContent(file);
    if (fileOk)
    {
        // Should work ok!
        // Simply dump the whole file contents to stdout.
        print("File contents:");
        print(domDocFromFile.toString());
        print("");
    }

    file.close(); // Remember to close the file handle.

    // So, the setContent function seems to be working by omitting the default arguments from the signatures
    // (http://developer.qt.nokia.com/doc/qt-4.7/qdomdocument.html) alltogether, and the following signatures/overloads should work:
    // bool setContent(const QByteArray & data, bool namespaceProcessing)
    // bool setContent(const QString & text, bool namespaceProcessing)
    // bool setContent(QIODevice * dev, bool namespaceProcessing)
    // bool setContent(QXmlInputSource * source, bool namespaceProcessing)
    // bool setContent(const QString & text)
    // bool setContent(const QByteArray & buffer)
    // bool setContent(QIODevice * dev) - which we usesd previously
    // bool setContent(QXmlInputSource * source, QXmlReader * reader)

    var file2 = new QFile("plugins.xml");
    var source = new QXmlInputSource(file2);
    var domDocFromInputSource = new QDomDocument();

    // Utilize the Qt XML/DOM API and print the names of the C++ plugins defined int the XML file individually.
    // Let's try "bool setContent(QXmlInputSource * source, bool namespaceProcessing)".
    var sourceOk = domDocFromInputSource.setContent(source, true);
    if (sourceOk)
    {
        // Should work ok!
        var pluginElems = domDocFromInputSource.elementsByTagName("plugin");
        print(pluginElems.length() + " C++ plugins found. The plugins are:");
        for(var i = 0; i < pluginElems.length(); ++i)
            print("* " + pluginElems.item(i).toElement().attribute("path"));
    }

    file2.close();
}

print("< JS qt.xml example:");

//converted the c++ in http://doc.trolltech.com/4.6/qdomdocument.html
var doc = new QDomDocument("mydocument");

//works when running from Tundra bin: ./Tundra --headless --run jsmodules/apitest/qtxml.js
var file = new QFile("plugins.xml");

//if (!file.open(QIODevice::ReadOnly))
//     return;
/*if (!doc.setContent(&file)) {
     file.close();
     //return;
}*/
doc.setContent(file);
file.close();

print("---");

// print out the element names of all elements that are direct children
 // of the outermost element.
var docElem = doc.documentElement();

var n = docElem.firstChild();
while(!n.isNull()) {
    //print(".");
    var e = n.toElement(); // try to convert the node to an element.
    if(!e.isNull()) {
        print(e.tagName()); // the node really is an element.
     }
     n = n.nextSibling();
 }

/*
 // Here we append a new element to the end of the document
 QDomElement elem = doc.createElement("img");
 elem.setAttribute("src", "myimage.png");
 docElem.appendChild(elem);
*/

/* creating - no worky for some reason?
is from http://developer.qt.nokia.com/forums/viewthread/12949 where they suspect appendChild is broken.

var doc = new QDomDocument();
var root = doc.createElement("root");
doc.appendChild(root);
root.setAttribute("attr1", "value1")

var tag = doc.createElement("tag1");
root.appendChild(tag);

print(doc);
print((doc.toString()));
*/

print(".. /qt xml example end> ");<|endoftext|>


<commit_before>var Parser = require('ringo/args').Parser;
var httpclient = require('ringo/httpclient');
var system = require('system');

// TODO add option to print to a separate file.
function main(args) {
	var script = args.shift();
	var parser = new Parser(system.args);
	parser.addOption('o', 'ontologyname', 'ONTOLOGY', 'ontology name (or sf project), defaults to "geneontology"');
	parser.addOption('t', 'trackername', 'TRACKER', 'tracker name, defaults to "ontology-requests"');
	parser.addOption('r', 'range', 'RANGE', 'date range, defaults to one day');
	parser.addOption('h', 'help', null, 'Display help');

	var options = parser.parse(args);
	if (options.help) {
		print(parser.help());
		system.exit('-1');
	}

	var oname = 'geneontology';
	if (options.ontologyname !== undefined) {
		oname = options.ontologyname;
	}

	var trackername = 'ontology-requests';
	if (options.trackername !== undefined) {
		trackername = options.trackername;
	}

	var durationInDays = 1;
	if (options.range !== undefined) {
		durationInDays = parseInt(options.range);
	}

	var today = new Date();
	var yesterday = new Date(new Date().setDate(new Date().getDate()-durationInDays));
	var range = yesterday.toISOString()+"+TO+"+today.toISOString();
	//console.log(range);

	var newTickets = getNewTickets(oname, trackername, range);
	var modTickets = getUpdatedTickets(oname, trackername, range);

	print("
Summary for tickets from "+yesterday.toISOString()+" to "+today.toISOString()+"
");
	printNewTickets(newTickets, oname);
	printUpdatedTickets(modTickets, oname);

}

function printNewTickets(tickets, oname) {
	printTickets(tickets, oname, 'new', 'New');
}

function printUpdatedTickets(tickets, oname) {
	printTickets(tickets, oname, 'updated', 'Updated');
}

function printTickets(tickets, oname, type, typeUpperCase) {
	print("
"+typeUpperCase+" Tickets
");
	if (tickets !== undefined && tickets.length > 0) {

		if (tickets.length === 1) {
			print("There is one "+type+" ticket.");
		}
		else {
			print("There are "+tickets.length+" "+type+" tickets.");
		}
		var body = "
\n";
		for (var k=0; k<tickets.length; k++) {
		    var ticket = tickets[k];

		    // Example: http://sourceforge.net/p/geneontology/ontology-requests/10193/ cilium/flagellum
		    body += '
';
		    body += '' + ticket.ticket_num + '';
		    body += " ";
		    body += makeHtmlSave(ticket.summary);
		    body += '
\n';
		}
		body += "
"
		print(body);
	}else {
		print("
There have been no "+type+" tickets.
");
	}
}

/**
 * Save guard against problematic text.

 * Escape HTML reserved characters and remove non-ASCII symbols.
 */
function makeHtmlSave(s) {
	// rempve all non-ascii symbols with a '?'
	s = s.replace(/[^A-Za-z 0-9 \.,\?""!@#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*/g, '') ;
	// escape html specific characters
	return s.replace(/&/g, '&')
    	.replace(/"/g, '"')
    	.replace(/>/g, '>')
    	.replace(/</g, '<');
}

function getNewTickets(oname, trackername, range) {
	//EXAMPLE = "http://sourceforge.net/rest/p/geneontology/ontology-requests/search?q=created_date_dt:[2013-07-30T00:00:00Z%20TO%202013-07-30T23:59:59Z]";
	return getTickets(oname, trackername, range, 'created_date_dt');
}

function getUpdatedTickets(oname, trackername, range) {
	//EXAMPLE = "http://sourceforge.net/rest/p/geneontology/ontology-requests/search?q=mod_date_dt:[2013-07-30T00:00:00Z%20TO%202013-07-30T23:59:59Z]";
	return getTickets(oname, trackername, range, 'mod_date_dt');
}

/**
 * Get the tickets. Warning: This method uses system.exit(-1) to exit the
 * program in case of an error.
 *
 * TODO: handle pagination, maybe add a retry count
 */
function getTickets(oname, trackername, range, type) {
	var url = 'http://sourceforge.net/rest/p/'+oname+'/'+trackername+'/search?q='+type+':['+range+']';
	//console.log(url);
	var exchange = httpclient.get(url);
	var payload = exchange.content;
	if (exchange.status === 200) {
		//console.log(payload);
		var resultObj = JSON.parse(payload);
		return resultObj.tickets;
	}
	else {
		print('Http error status code: '+exchange.status+' for request url: '+url);
		system.exit('-1');
	}
}

// call the main method; ringo specific
if (require.main == module.id) {
	main(system.args);
}<commit_msg>fix path problem for target URL<commit_after>var Parser = require('ringo/args').Parser;
var httpclient = require('ringo/httpclient');
var system = require('system');

// TODO add option to print to a separate file.
function main(args) {
	var script = args.shift();
	var parser = new Parser(system.args);
	parser.addOption('o', 'ontologyname', 'ONTOLOGY', 'ontology name (or sf project), defaults to "geneontology"');
	parser.addOption('t', 'trackername', 'TRACKER', 'tracker name, defaults to "ontology-requests"');
	parser.addOption('r', 'range', 'RANGE', 'date range, defaults to one day');
	parser.addOption('h', 'help', null, 'Display help');

	var options = parser.parse(args);
	if (options.help) {
		print(parser.help());
		system.exit('-1');
	}

	var oname = 'geneontology';
	if (options.ontologyname !== undefined) {
		oname = options.ontologyname;
	}

	var trackername = 'ontology-requests';
	if (options.trackername !== undefined) {
		trackername = options.trackername;
	}

	var durationInDays = 1;
	if (options.range !== undefined) {
		durationInDays = parseInt(options.range);
	}

	var today = new Date();
	var yesterday = new Date(new Date().setDate(new Date().getDate()-durationInDays));
	var range = yesterday.toISOString()+"+TO+"+today.toISOString();
	//console.log(range);

	var newTickets = getNewTickets(oname, trackername, range);
	var modTickets = getUpdatedTickets(oname, trackername, range);

	print("
Summary for tickets from "+yesterday.toISOString()+" to "+today.toISOString()+"
");
	printNewTickets(newTickets, oname, trackername);
	printUpdatedTickets(modTickets, oname, trackername);

}

function printNewTickets(tickets, oname, trackername) {
	printTickets(tickets, oname, 'new', 'New', trackername);
}

function printUpdatedTickets(tickets, oname, trackername) {
	printTickets(tickets, oname, 'updated', 'Updated', trackername);
}

function printTickets(tickets, oname, type, typeUpperCase, trackername) {
	print("
"+typeUpperCase+" Tickets
");
	if (tickets !== undefined && tickets.length > 0) {

		if (tickets.length === 1) {
			print("There is one "+type+" ticket.");
		}
		else {
			print("There are "+tickets.length+" "+type+" tickets.");
		}
		var body = "
\n";
		for (var k=0; k<tickets.length; k++) {
		    var ticket = tickets[k];

		    // Example: http://sourceforge.net/p/geneontology/ontology-requests/10193/ cilium/flagellum
		    body += '
';
		    body += '' + ticket.ticket_num + '';
		    body += " ";
		    body += makeHtmlSave(ticket.summary);
		    body += '
\n';
		}
		body += "
"
		print(body);
	}else {
		print("
There have been no "+type+" tickets.
");
	}
}

/**
 * Save guard against problematic text.

 * Escape HTML reserved characters and remove non-ASCII symbols.
 */
function makeHtmlSave(s) {
	// rempve all non-ascii symbols with a '?'
	s = s.replace(/[^A-Za-z 0-9 \.,\?""!@#\$%\^&\*\(\)-_=\+;:<>\/\\\|\}\{\[\]`~]*/g, '') ;
	// escape html specific characters
	return s.replace(/&/g, '&')
    	.replace(/"/g, '"')
    	.replace(/>/g, '>')
    	.replace(/</g, '<');
}

function getNewTickets(oname, trackername, range) {
	//EXAMPLE = "http://sourceforge.net/rest/p/geneontology/ontology-requests/search?q=created_date_dt:[2013-07-30T00:00:00Z%20TO%202013-07-30T23:59:59Z]";
	return getTickets(oname, trackername, range, 'created_date_dt');
}

function getUpdatedTickets(oname, trackername, range) {
	//EXAMPLE = "http://sourceforge.net/rest/p/geneontology/ontology-requests/search?q=mod_date_dt:[2013-07-30T00:00:00Z%20TO%202013-07-30T23:59:59Z]";
	return getTickets(oname, trackername, range, 'mod_date_dt');
}

/**
 * Get the tickets. Warning: This method uses system.exit(-1) to exit the
 * program in case of an error.
 *
 * TODO: handle pagination, maybe add a retry count
 */
function getTickets(oname, trackername, range, type) {
	var url = 'http://sourceforge.net/rest/p/'+oname+'/'+trackername+'/search?q='+type+':['+range+']';
	//console.log(url);
	var exchange = httpclient.get(url);
	var payload = exchange.content;
	if (exchange.status === 200) {
		//console.log(payload);
		var resultObj = JSON.parse(payload);
		return resultObj.tickets;
	}
	else {
		print('Http error status code: '+exchange.status+' for request url: '+url);
		system.exit('-1');
	}
}

// call the main method; ringo specific
if (require.main == module.id) {
	main(system.args);
}<|endoftext|>


<commit_before>/**
 * @fileOverview Window manager module for restartless addons
 * @author       YUKI "Piro" Hiroshi
 * @version      5
 *
 * @license
 *   The MIT License, Copyright (c) 2010-2014 YUKI "Piro" Hiroshi.
 *   https://github.com/piroor/restartless/blob/master/license.txt
 * @url http://github.com/piroor/restartless
 */

const EXPORTED_SYMBOLS = ['WindowManager'];

var _WindowWatcher = Cc['@mozilla.org/embedcomp/window-watcher;1']
						.getService(Ci.nsIWindowWatcher);
var _WindowMediator = Cc['@mozilla.org/appshell/window-mediator;1']
						.getService(Ci.nsIWindowMediator);

var _gListener = {
		observe : function(aSubject, aTopic, aData)
		{
			if (
				aTopic == 'domwindowopened' &&
				!aSubject
					.QueryInterface(Ci.nsIInterfaceRequestor)
					.getInterface(Ci.nsIWebNavigation)
					.QueryInterface(Ci.nsIDocShell)
					.QueryInterface(Ci.nsIDocShellTreeNode || Ci.nsIDocShellTreeItem) // nsIDocShellTreeNode is merged to nsIDocShellTreeItem by https://bugzilla.mozilla.org/show_bug.cgi?id=331376
					.QueryInterface(Ci.nsIDocShellTreeItem)
					.parent
				)
				aSubject
					.QueryInterface(Ci.nsIDOMWindow)
					.addEventListener('DOMContentLoaded', this, false);
		},
		handleEvent : function(aEvent)
		{
			aEvent.currentTarget.removeEventListener(aEvent.type, this, false);

			var window = aEvent.target.defaultView;
			this.listeners.forEach(function(aListener) {
				try {
					if (aListener.handleEvent &&
						typeof aListener.handleEvent == 'function')
						aListener.handleEvent(aEvent);
					if (aListener.handleWindow &&
						typeof aListener.handleWindow == 'function')
						aListener.handleWindow(window);
					if (typeof aListener == 'function')
						aListener(window);
				}
				catch(e) {
					dump(e+'\n');
				}
			});
		},
		listeners : []
	};
_WindowWatcher.registerNotification(_gListener);

/**
 * @class
 *   Provides features to get existing chrome windows, etc.
 */
var WindowManager = {
		/**
		 * Registers a handler for newly opened chrome windows. Handlers will
		 * be called when DOMContentLoaded events are fired in newly opened
		 * windows.
		 *
		 * @param {Object} aHandler
		 *   A handler for new windows. If you specify a function, it will be
		 *   called with the DOMWindow object as the first argument. If the
		 *   specified object has a method named "handleWindow", then the
		 *   method will be called with the DOMWindow. If the object has a
		 *   method named "handleEvent", then it will be called with the
		 *   DOMContentLoaded event object (not DOMWindow object.)
		 */
		addHandler : function(aListener)
		{
			if (!_gListener) return;
			if (
				aListener &&
				(
					typeof aListener == 'function' ||
					(aListener.handleWindow && typeof aListener.handleWindow == 'function') ||
					(aListener.handleEvent && typeof aListener.handleEvent == 'function')
				) &&
				_gListener.listeners.indexOf(aListener) < 0
				)
				_gListener.listeners.push(aListener);
		},
		/**
		 * Unregisters a handler.
		 */
		removeHandler : function(aListener)
		{
			if (!_gListener) return;
			let index = _gListener.listeners.indexOf(aListener);
			if (index > -1)
				_gListener.listeners.splice(index, 1);
		},
		/**
		 * Returns the most recent chrome window (DOMWindow).
		 *
		 * @param {string=} aWindowType
		 *   The window type you want to get, ex. "navigator:browser". If you
		 *   specify no type (null, blank string, etc.) then this returns
		 *   the most recent window of any type.
		 *
		 * @returns {nsIDOMWindow}
		 *   A found DOMWindow.
		 */
		getWindow : function(aType)
		{
			return _WindowMediator.getMostRecentWindow(aType || null);
		},
		/**
		 * Returns an array of chrome windows (DOMWindow).
		 *
		 * @param {string=} aWindowType
		 *   The window type you want to filter, ex. "navigator:browser". If
		 *   you  specify no type (null, blank string, etc.) then this returns
		 *   an array of all chrome windows.
		 *
		 * @returns {Array}
		 *   An array of found DOMWindows.
		 */
		getWindows : function(aType)
		{
			var array = [];
			var windows = _WindowMediator.getZOrderDOMWindowEnumerator(aType || null, true);

			// By the bug 156333, we cannot find windows by their Z order on Linux.
			// https://bugzilla.mozilla.org/show_bug.cgi?id=156333
			if (!windows.hasMoreElements())
				windows = _WindowMediator.getEnumerator(aType || null);

			while (windows.hasMoreElements())
			{
				array.push(windows.getNext().QueryInterface(Ci.nsIDOMWindow));
			}
			return array;
		}
	};
for (let i in WindowManager)
{
	exports[i] = (function(aSymbol) {
		return function() {
			return WindowManager[aSymbol].apply(WindowManager, arguments);
		};
	})(i);
}

/** A handler for bootstrap.js */
function shutdown()
{
	_WindowWatcher.unregisterNotification(_gListener);
	_WindowWatcher = void(0);
	_gListener.listeners = [];
}
<commit_msg>Export "EXPORTED_SYMBOLS" correctly (due to bug 1202902)<commit_after>/**
 * @fileOverview Window manager module for restartless addons
 * @author       YUKI "Piro" Hiroshi
 * @version      5
 *
 * @license
 *   The MIT License, Copyright (c) 2010-2014 YUKI "Piro" Hiroshi.
 *   https://github.com/piroor/restartless/blob/master/license.txt
 * @url http://github.com/piroor/restartless
 */

var EXPORTED_SYMBOLS = ['WindowManager'];

var _WindowWatcher = Cc['@mozilla.org/embedcomp/window-watcher;1']
						.getService(Ci.nsIWindowWatcher);
var _WindowMediator = Cc['@mozilla.org/appshell/window-mediator;1']
						.getService(Ci.nsIWindowMediator);

var _gListener = {
		observe : function(aSubject, aTopic, aData)
		{
			if (
				aTopic == 'domwindowopened' &&
				!aSubject
					.QueryInterface(Ci.nsIInterfaceRequestor)
					.getInterface(Ci.nsIWebNavigation)
					.QueryInterface(Ci.nsIDocShell)
					.QueryInterface(Ci.nsIDocShellTreeNode || Ci.nsIDocShellTreeItem) // nsIDocShellTreeNode is merged to nsIDocShellTreeItem by https://bugzilla.mozilla.org/show_bug.cgi?id=331376
					.QueryInterface(Ci.nsIDocShellTreeItem)
					.parent
				)
				aSubject
					.QueryInterface(Ci.nsIDOMWindow)
					.addEventListener('DOMContentLoaded', this, false);
		},
		handleEvent : function(aEvent)
		{
			aEvent.currentTarget.removeEventListener(aEvent.type, this, false);

			var window = aEvent.target.defaultView;
			this.listeners.forEach(function(aListener) {
				try {
					if (aListener.handleEvent &&
						typeof aListener.handleEvent == 'function')
						aListener.handleEvent(aEvent);
					if (aListener.handleWindow &&
						typeof aListener.handleWindow == 'function')
						aListener.handleWindow(window);
					if (typeof aListener == 'function')
						aListener(window);
				}
				catch(e) {
					dump(e+'\n');
				}
			});
		},
		listeners : []
	};
_WindowWatcher.registerNotification(_gListener);

/**
 * @class
 *   Provides features to get existing chrome windows, etc.
 */
var WindowManager = {
		/**
		 * Registers a handler for newly opened chrome windows. Handlers will
		 * be called when DOMContentLoaded events are fired in newly opened
		 * windows.
		 *
		 * @param {Object} aHandler
		 *   A handler for new windows. If you specify a function, it will be
		 *   called with the DOMWindow object as the first argument. If the
		 *   specified object has a method named "handleWindow", then the
		 *   method will be called with the DOMWindow. If the object has a
		 *   method named "handleEvent", then it will be called with the
		 *   DOMContentLoaded event object (not DOMWindow object.)
		 */
		addHandler : function(aListener)
		{
			if (!_gListener) return;
			if (
				aListener &&
				(
					typeof aListener == 'function' ||
					(aListener.handleWindow && typeof aListener.handleWindow == 'function') ||
					(aListener.handleEvent && typeof aListener.handleEvent == 'function')
				) &&
				_gListener.listeners.indexOf(aListener) < 0
				)
				_gListener.listeners.push(aListener);
		},
		/**
		 * Unregisters a handler.
		 */
		removeHandler : function(aListener)
		{
			if (!_gListener) return;
			let index = _gListener.listeners.indexOf(aListener);
			if (index > -1)
				_gListener.listeners.splice(index, 1);
		},
		/**
		 * Returns the most recent chrome window (DOMWindow).
		 *
		 * @param {string=} aWindowType
		 *   The window type you want to get, ex. "navigator:browser". If you
		 *   specify no type (null, blank string, etc.) then this returns
		 *   the most recent window of any type.
		 *
		 * @returns {nsIDOMWindow}
		 *   A found DOMWindow.
		 */
		getWindow : function(aType)
		{
			return _WindowMediator.getMostRecentWindow(aType || null);
		},
		/**
		 * Returns an array of chrome windows (DOMWindow).
		 *
		 * @param {string=} aWindowType
		 *   The window type you want to filter, ex. "navigator:browser". If
		 *   you  specify no type (null, blank string, etc.) then this returns
		 *   an array of all chrome windows.
		 *
		 * @returns {Array}
		 *   An array of found DOMWindows.
		 */
		getWindows : function(aType)
		{
			var array = [];
			var windows = _WindowMediator.getZOrderDOMWindowEnumerator(aType || null, true);

			// By the bug 156333, we cannot find windows by their Z order on Linux.
			// https://bugzilla.mozilla.org/show_bug.cgi?id=156333
			if (!windows.hasMoreElements())
				windows = _WindowMediator.getEnumerator(aType || null);

			while (windows.hasMoreElements())
			{
				array.push(windows.getNext().QueryInterface(Ci.nsIDOMWindow));
			}
			return array;
		}
	};
for (let i in WindowManager)
{
	exports[i] = (function(aSymbol) {
		return function() {
			return WindowManager[aSymbol].apply(WindowManager, arguments);
		};
	})(i);
}

/** A handler for bootstrap.js */
function shutdown()
{
	_WindowWatcher.unregisterNotification(_gListener);
	_WindowWatcher = void(0);
	_gListener.listeners = [];
}
<|endoftext|>


<commit_before>/*
 * Cookie Calculator / scales/length.js
 * copyright (c) 2016 Susisu
 */

"use strict";

import { SIUnit } from "../units.js";

let values = [
    {
        value: 1.616199e-35,
        description:
            `1 Planck Length

            Size of the hypothetical quantum strings`
    },
    {
        value: 2e-23,
        description:
            `Effective cross section radius of
            1 MeV neutrinos`
    },
    {
        value: 1e-21,
        description:
            `Effective cross section radius of
            high energy neutrinos`
    },
    {
        value: 3.10e-19,
        description:
            `De Broglie wavelength of 4 TeV
            protons at the
            LHC`
    },
    {
        value: 1e-18,
        description:
            `Upper limit for the size of quarks and
            electrons

            Sensitivity of the LIGO detector for
            gravitational waves`
    },
    {
        value: 1e-17,
        description:
            `Range of the <a href="https://en.wikipedia.org/wiki/Weak_interaction">weak force</a>`
    },
    {
        value: 1e-15,
        description:
            `Scale of the <a href="https://en.wikipedia.org/wiki/Atomic_nucleus">atomic nuculeus</a>`
    },
    {
        value: 1e-12,
        description:
            `Longest wavelength of <a href="https://en.wikipedia.org/wiki/Gamma_ray">gamma rays</a>`
    },
    {
        value: 5e-12,
        description:
            `Shortest wavelength of <a href="https://en.wikipedia.org/wiki/X-ray">X-rays</a>`
    },
    {
        value: 2.5e-11,
        description:
            `Radius of <a href="https://en.wikipedia.org/wiki/Hydrogen_atom">hydrogen atom</a>`
    },
    {
        value: 5.3e-11,
        description:
            `<a href="https://en.wikipedia.org/wiki/Bohr_radius">Bohr radius</a>`
    },
    {
        value: 1e-10,
        description:
            `1 <a href="https://en.wikipedia.org/wiki/Ångström">Ångström</a>`
    },
    {
        value: 5e-10,
        description:
            `Width of <a href="https://en.wikipedia.org/wiki/Alpha_helix">α helix</a>`
    },
    {
        value: 1e-9,
        description:
            `Diameter of a <a href="https://en.wikipedia.org/wiki/Carbon_nanotube">carbon nanotube</a>`
    },
    {
        value: 4e-8,
        description:
            `Wavelength of extreme ultraviolet`
    },
    {
        value: 4e-7,
        description:
            `Wavelength of violet light`
    },
    {
        value: 7e-7,
        description:
            `Wavelength of red light`
    },
    {
        value: 7e-6,
        description:
            `Diameter of a red blood cell`
    },
    {
        value: 1e-5,
        description:
            `Typical size of fog water droplet`
    },
    {
        value: 1e-4,
        description:
            `Average width of a human hair`
    },
    {
        value: 5e-3,
        description:
            `Ant`
    },
    {
        value: 1.5e-2,
        description:
            `Mosquito`
    },
    {
        value: 2.54e-2,
        description:
            `1 inch`
    },
    {
        value: 1e-1,
        description:
            `Wavelength of the highest UHF radio frequency`
    },
    {
        value: 3.048e-1,
        description:
            `1 foot`
    },
    {
        value: 9.144e-1,
        description:
            `1 yard`
    },
    {
        value: 1.7,
        description:
            `Human`
    },
    {
        value: 3.3e+1,
        description:
            `Blue whale, the largest animal`
    },
    {
        value: 9.347e+1,
        description:
            `Height of the Statue of Liberty`
    },
    {
        value: 1.37e+2,
        description:
            `Height of the Great Pyramid of Giza`
    },
    {
        value: 8.848e+3,
        description:
            `Height of the highest mountain on Earth, Mount Everest`
    },
    {
        value: 1.0911e+4,
        description:
            `Depth of the deepest part of the Ocean, Mariana Trench`
    },
    {
        value: 9.0e+4,
        description:
            `Width of the Bering Strait`
    },
    {
        value: 9.746e+5,
        description:
            `Greatest diameter of the dwarf planet Ceres`
    },
    {
        value: 2.39e+6,
        description:
            `Diameter of Pluto`
    },
    {
        value: 3.48e+6,
        description:
            `Diameter of the Moon`
    },
    {
        value: 6.4e+6,
        description:
            `Length of the Great Wall of China`
    },
    {
        value: 1.2756e+7,
        description:
            `Equatorial diameter of Earth`
    },
    {
        value: 4.0075e+7,
        description:
            `Length of Earth's equator`
    },
    {
        value: 1.42984e+8,
        description:
            `Diameter of Jupiter`
    },
    {
        value: 2.99792458e+8,
        description:
            `1 light-second (distance traveled by light in one second)`
    },
    {
        value: 3.84e+8,
        description:
            `Moon's orbital distance from Earth`
    },
    {
        value: 1.39e+9,
        description:
            `Diameter of the Sun`
    },
    {
        value: 1.8e+10,
        description:
            `1 light-minute`
    },
    {
        value: 1.5e+11,
        description:
            `1 astronomical unit (AU, mean distance between Earth and Sun)`
    },
    {
        value: 1.4e+12,
        description:
            `Orbital distance of Saturn from Sun`
    },
    {
        value: 5.9e+12,
        description:
            `Orbital distance of Pluto from Sun`
    },
    {
        value: 7.5e+12,
        description:
            `Outer boundary of the Kuiper belt, inner boundary of the Oort cloud`
    },
    {
        value: 1e+13,
        description:
            `Diameter of the Solar System`
    }
];

export default values.map(x => ({
    quantity   : SIUnit.METRE.value(x.value),
    description: x.description
}));
<commit_msg>Add length scales<commit_after>/*
 * Cookie Calculator / scales/length.js
 * copyright (c) 2016 Susisu
 */

"use strict";

import { SIUnit } from "../units.js";

let values = [
    {
        value: 1.616199e-35,
        description:
            `1 Planck Length

            Size of the hypothetical quantum strings`
    },
    {
        value: 2e-23,
        description:
            `Effective cross section radius of
            1 MeV neutrinos`
    },
    {
        value: 1e-21,
        description:
            `Effective cross section radius of
            high energy neutrinos`
    },
    {
        value: 3.10e-19,
        description:
            `De Broglie wavelength of 4 TeV
            protons at the
            LHC`
    },
    {
        value: 1e-18,
        description:
            `Upper limit for the size of quarks and
            electrons

            Sensitivity of the LIGO detector for
            gravitational waves`
    },
    {
        value: 1e-17,
        description:
            `Range of the <a href="https://en.wikipedia.org/wiki/Weak_interaction">weak force</a>`
    },
    {
        value: 1e-15,
        description:
            `Scale of the <a href="https://en.wikipedia.org/wiki/Atomic_nucleus">atomic nuculeus</a>`
    },
    {
        value: 1e-12,
        description:
            `Longest wavelength of <a href="https://en.wikipedia.org/wiki/Gamma_ray">gamma rays</a>`
    },
    {
        value: 5e-12,
        description:
            `Shortest wavelength of <a href="https://en.wikipedia.org/wiki/X-ray">X-rays</a>`
    },
    {
        value: 2.5e-11,
        description:
            `Radius of <a href="https://en.wikipedia.org/wiki/Hydrogen_atom">hydrogen atom</a>`
    },
    {
        value: 5.3e-11,
        description:
            `<a href="https://en.wikipedia.org/wiki/Bohr_radius">Bohr radius</a>`
    },
    {
        value: 1e-10,
        description:
            `1 <a href="https://en.wikipedia.org/wiki/Ångström">Ångström</a>`
    },
    {
        value: 5e-10,
        description:
            `Width of <a href="https://en.wikipedia.org/wiki/Alpha_helix">α helix</a>`
    },
    {
        value: 1e-9,
        description:
            `Diameter of a <a href="https://en.wikipedia.org/wiki/Carbon_nanotube">carbon nanotube</a>`
    },
    {
        value: 4e-8,
        description:
            `Wavelength of extreme ultraviolet`
    },
    {
        value: 4e-7,
        description:
            `Wavelength of violet light`
    },
    {
        value: 7e-7,
        description:
            `Wavelength of red light`
    },
    {
        value: 7e-6,
        description:
            `Diameter of a red blood cell`
    },
    {
        value: 1e-5,
        description:
            `Typical size of fog water droplet`
    },
    {
        value: 1e-4,
        description:
            `Average width of a human hair`
    },
    {
        value: 5e-3,
        description:
            `Ant`
    },
    {
        value: 1.5e-2,
        description:
            `Mosquito`
    },
    {
        value: 2.54e-2,
        description:
            `1 inch`
    },
    {
        value: 1e-1,
        description:
            `Wavelength of the highest UHF radio frequency`
    },
    {
        value: 3.048e-1,
        description:
            `1 foot`
    },
    {
        value: 9.144e-1,
        description:
            `1 yard`
    },
    {
        value: 1.7,
        description:
            `Human`
    },
    {
        value: 3.3e+1,
        description:
            `Blue whale, the largest animal`
    },
    {
        value: 9.347e+1,
        description:
            `Height of the Statue of Liberty`
    },
    {
        value: 1.37e+2,
        description:
            `Height of the Great Pyramid of Giza`
    },
    {
        value: 8.848e+3,
        description:
            `Height of the highest mountain on Earth, Mount Everest`
    },
    {
        value: 1.0911e+4,
        description:
            `Depth of the deepest part of the Ocean, Mariana Trench`
    },
    {
        value: 9.0e+4,
        description:
            `Width of the Bering Strait`
    },
    {
        value: 9.746e+5,
        description:
            `Greatest diameter of the dwarf planet Ceres`
    },
    {
        value: 2.39e+6,
        description:
            `Diameter of Pluto`
    },
    {
        value: 3.48e+6,
        description:
            `Diameter of the Moon`
    },
    {
        value: 6.4e+6,
        description:
            `Length of the Great Wall of China`
    },
    {
        value: 1.2756e+7,
        description:
            `Equatorial diameter of Earth`
    },
    {
        value: 4.0075e+7,
        description:
            `Length of Earth's equator`
    },
    {
        value: 1.42984e+8,
        description:
            `Diameter of Jupiter`
    },
    {
        value: 2.99792458e+8,
        description:
            `1 light-second (distance traveled by light in one second)`
    },
    {
        value: 3.84e+8,
        description:
            `Moon's orbital distance from Earth`
    },
    {
        value: 1.39e+9,
        description:
            `Diameter of the Sun`
    },
    {
        value: 1.8e+10,
        description:
            `1 light-minute`
    },
    {
        value: 1.5e+11,
        description:
            `1 astronomical unit (AU, mean distance between Earth and Sun)`
    },
    {
        value: 1.4e+12,
        description:
            `Orbital distance of Saturn from Sun`
    },
    {
        value: 5.9e+12,
        description:
            `Orbital distance of Pluto from Sun`
    },
    {
        value: 7.5e+12,
        description:
            `Outer boundary of the Kuiper belt, inner boundary of the Oort cloud`
    },
    {
        value: 1e+13,
        description:
            `Diameter of the Solar System`
    },
    {
        value: 2e+14,
        description:
            `Total length of DNA molecules in all cells of an adult human`
    },
    {
        value: 7.5e+15,
        description:
            `Outer boundary of the Oort cloud`
    },
    {
        value: 9.46e+15,
        description:
            `1 light-year`
    },
    {
        value: 3.0857e+16,
        description:
            `1 parsec`
    }
];

export default values.map(x => ({
    quantity   : SIUnit.METRE.value(x.value),
    description: x.description
}));
<|endoftext|>


<commit_before>import { loop, isLoop, getEffect, getModel } from './loop';
import { batch, none } from './effects';

function optimizeBatch(effects) {
  switch(effects.length) {
    case 0:
      return none();
    case 1:
      return effects[0];
    default:
      return batch(effects);
  }
}

export function combineReducers(
    reducerMap,
    rootState = {},
    accessor = (child, key) => child[key],
    mutator = (child, key, value) => { child[key] = value; return child; }
) {
    return function finalReducer(state = rootState, action) {
        let hasChanged = false;
        let effects = [];

        const model = Object.keys(reducerMap).reduce((model, key) => {
            const reducer = reducerMap[key];
            const previousStateForKey = accessor(state, key);
            let nextStateForKey = reducer(previousStateForKey, action);

            if (isLoop(nextStateForKey)) {
                effects.push(getEffect(nextStateForKey));
                nextStateForKey = getModel(nextStateForKey);
            }

            hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
            return mutator(model, key, nextStateForKey);
        }, rootState);

        return loop(
            hasChanged ? model : state,
            optimizeBatch(effects)
        );
    };
}
<commit_msg>move default accessor and mutator into variables<commit_after>import { loop, isLoop, getEffect, getModel } from './loop';
import { batch, none } from './effects';

function optimizeBatch(effects) {
  switch(effects.length) {
    case 0:
      return none();
    case 1:
      return effects[0];
    default:
      return batch(effects);
  }
}

const defaultAccessor = (state, key) => {
  return state[key];
};

const defaultMutator = (state, key, value) => {
  state[key] = value;
  return state;
};

export function combineReducers(
    reducerMap,
    rootState = {},
    accessor = defaultAccessor,
    mutator = defaultMutator
) {
    return function finalReducer(state = rootState, action) {
        let hasChanged = false;
        let effects = [];

        const model = Object.keys(reducerMap).reduce((model, key) => {
            const reducer = reducerMap[key];
            const previousStateForKey = accessor(state, key);
            let nextStateForKey = reducer(previousStateForKey, action);

            if (isLoop(nextStateForKey)) {
                effects.push(getEffect(nextStateForKey));
                nextStateForKey = getModel(nextStateForKey);
            }

            hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
            return mutator(model, key, nextStateForKey);
        }, rootState);

        return loop(
            hasChanged ? model : state,
            optimizeBatch(effects)
        );
    };
}
<|endoftext|>