<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { routerActions } from 'react-router-redux'
import { withRouter } from 'react-router-dom'
import { white, blueA700, grey100, grey300, grey700, grey800 } from 'material-ui/styles/colors'
import EditorPage from '../components/EditorPage'
// import { createResource } from '../state/actions/access'
import { requestTemplates } from '../state/actions/templates'
import { requestSwagger } from '../state/actions/apimodels'
import MenuItem from 'material-ui/MenuItem'
import FlatButton from 'material-ui/FlatButton'
import IconExpand from 'material-ui/svg-icons/navigation/more-vert'
import IconApply from 'material-ui/svg-icons/action/get-app'
import RaisedButton from 'material-ui/RaisedButton'
import Popover from 'material-ui/Popover'
import Menu from 'material-ui/Menu'

import ace from 'brace'
const { Range } = ace.acequire('ace/range')

const mapStateToProps = function(store) {
  return {
    user: store.session.user,
    templatesByGroup: store.templates.templatesByGroup,
    isFetching: store.templates.isFetching,
    swagger: store.apimodels.swagger,
  }
}

const mapDispatchToProps = function(dispatch, ownProps) {
  return {
    cancelEditor: function() {
      dispatch(routerActions.goBack())
    },
    createResource: function(contents) {
      dispatch(ownProps.resourceCreator(contents))
    },
    requestTemplates: function() {
      dispatch(requestTemplates())
    },
    requestSwagger: function() {
      dispatch(requestSwagger())
    },
  }
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps) (
class NewResource extends React.Component {

  static propTypes = {
    resourceCreator: PropTypes.func.isRequired,
    resourceGroup: PropTypes.string.isRequired,
  }

  static defaultProps = {
    resourceCreator: function(){},
  }

  constructor(props) {
    super(props);

    props.requestTemplates()
    props.requestSwagger()

    let templateNames = this.getSortedTemplateNames(props.templatesByGroup[props.resourceGroup])
    let selectedTemplate = templateNames && templateNames[0]

    this.state = {
      templateMenuOpen: false,
      variablesMenuOpen: false,
      templateNames: templateNames || [],
      selectedTemplate,
      variables: [],
      errors: [],
      selectedVariable: '',
    }
    this.contents = ''
  }

  handleTouchTapTemplates = (event) => {
    // This prevents ghost click.
    event.preventDefault()
    this.setState({
      templateMenuOpen: true,
      templatesAnchorEl: event.currentTarget,
    })
  }

  handleTemplatesMenuSelection = (event, value) => {
    this.setState({
      selectedTemplate: value,
      templateMenuOpen: false,
    })
  }

  selectAllInstancesOfVariable = (variable) => {
    this.editor.focus()
    this.editor.selection.clearSelection()
    this.editor.findAll('${' + variable + '}',{
      backwards: false,
      wrap: true,
      caseSensitive: true,
      wholeWord: false,
      regExp: false,
    })
  }

  handleEditorChange = (contents) => {
    this.contents = contents
  }

  handleSelectionChange = (selection, event) => {

    if (!this.ignoreSelectionChange) {
      let s = selection.toOrientedRange()
      if (s.end.column > s.start.column && s.end.row === s.start.row) {
        let rawText = this.editor.session.getTextRange(s)
        if (!rawText.startsWith('${') && !rawText.endsWith('}')) {
          let range = new Range(
            s.start.row,
            s.start.column -2,
            s.end.row,
            s.end.column + 1)
          let text = this.editor.session.getTextRange(range)
          if (text.startsWith('${') && text.endsWith('}')) {
            this.lastRange = s
            let variable = text.slice(2,-1)
            this.ignoreSelectionChange = true
            this.selectAllInstancesOfVariable(variable)
            this.ignoreSelectionChange = false
          }
        }
      }
    }
  }

  handleCursorChange = (cursor) => {

  }

  handleRequestCloseTemplates = () => {
    this.setState({
      templateMenuOpen: false,
    })
  }

  handleEditorLoaded = (editor) => {
    this.editor = editor
    if (this.state.selectedVariable) {
      this.selectAllInstancesOfVariable(this.state.selectedVariable)
      this.setState({
        selectedVariable: null,
      })
    }
  }

  handleEditorBlur = () => {

  }

  handleEditorApply = () => {
    this.props.createResource(this.contents)
  }

  getSortedTemplateNames = (templates) => {
    if (!!templates) {
      let templateNames = []
      for (let key in templates) {
        templateNames.push(key)
      }
      templateNames.sort(String.localeCompare)
      return templateNames
    }
  }

  detectVariables = (contents) => {
    let variables = {}
    let varPattern = /\${([A-Za-z0-9_-]+)}/g;
    let m = varPattern.exec(contents)
    while (m) {
      variables[m[1]] = true
      m = varPattern.exec(contents)
    }
    return Object.keys(variables)
  }

  onApplyTemplate = () => {
    let contents = this.props.templates[this.state.selectedTemplate]
    this.editor && this.editor.setValue(contents)
    let variables = this.detectVariables(contents)
    this.contents = contents
    this.setState({
      variables: variables,
      selectedVariable: variables[0],
    })
  }

  componentWillReceiveProps = (props) => {

    if (!props.templatesByGroup && !props.isFetching) {
      props.requestTemplates()
    } else if (props.templatesByGroup) {
      let templateNames = this.getSortedTemplateNames(props.templatesByGroup[props.resourceGroup])
      let selectedTemplate = this.state.selectedTemplate || (templateNames && templateNames[0])
      this.setState({
        templateNames: (templateNames || []),
        selectedTemplate,
      })
    }
  }

  render() {

    const styles = {
      label: {
        paddingLeft: 4,
        lineHeight: '24px',
        marginRight: 5,
        fontSize: 14,
        // fontWeight: 600,
        display: 'inline-block',
        color: white,
      },
      button: {
        minWidth: 160,
        textAlign: 'left',
        textTransform: 'none',
        display: 'inline-block',
        marginLeft: 8,
        color: grey300,
      },
      applyButton: {
        textTransform: 'none',
        display: 'inline-block',
        marginLeft: 8,
        color: white,
      },
      buttonLabel: {
        textTransform: 'none',
        fontSize: 14,
        fontWeight: 600,
        color: grey300,
      },
      popoverMenu: {
        fontSize: 14,
        overflowX: 'hidden',
        paddingTop: 0,
        paddingBottom: 0,
      },
      popoverItems: {
        // color: grey300,
      }
    }

    let { templateNames, selectedTemplate } = this.state

    let menuItems = []
    for (let key of templateNames) {
      menuItems.push(<MenuItem key={key} value={key} primaryText={key}/>)
    }

    let title = (

        template
        <FlatButton
          fullWidth={false}
          labelStyle={styles.buttonLabel}
          style={styles.button}
          label={selectedTemplate}
          hoverColor={grey700}
          backgroundColor={grey800}
          onTouchTap={this.handleTouchTapTemplates.bind(this)}
          icon={<IconExpand style={{height: 18, width: 18}}/>}
        />
        <Popover
          onRequestClose={this.handleRequestCloseTemplates}
          anchorOrigin={{horizontal: 'left', vertical: 'bottom'}}
          targetOrigin={{horizontal: 'left', vertical: 'top'}}
          open={this.state.templateMenuOpen}
          anchorEl={this.state.templatesAnchorEl}
        >
          <Menu
            multiple={false}
            value={selectedTemplate}
            desktop={true}
            selectedMenuItemStyle={{
              color: blueA700,
              fontWeight: 600,
              backgroundColor: grey100,
            }}
            style={styles.popoverMenu}
            onChange={this.handleTemplatesMenuSelection.bind(this)}
          >
            {menuItems}
          </Menu>
        </Popover>

        <RaisedButton
          label="Replace"
          icon={<IconApply style={{fill: grey300}}/>}
          style={styles.applyButton}
          labelColor={grey300}
          backgroundColor={grey800}
          hoverColor={grey700}
          onTouchTap={this.onApplyTemplate.bind(this)}
        />

    )

    let additionalActions = []

    return (
        <EditorPage
          open={!!this.props.user}
          resourceGroup={this.props.resourceGroup}
          detectVariables={this.detectVariables}
          onChange={this.handleEditorChange}
          onEditorApply={this.handleEditorApply.bind(this)}
          onEditorCancel={this.props.cancelEditor}
          onSelectionChange={this.handleSelectionChange.bind(this)}
          onCursorChange={this.handleCursorChange.bind(this)}
          onBlur={this.handleEditorBlur}
          additionalActions={additionalActions}
          title={title}
          titleStyle={{width: '100%', justifyContent: 'flex-start'}}
          contents={this.contents}
          onEditorLoaded={this.handleEditorLoaded}
          ref={(ref) => {
            if (!!ref) {
              this.editorPage = ref
            }
          }}
        />
    )
  }
}))<commit_msg>fix template 'Replace' button action<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { routerActions } from 'react-router-redux'
import { withRouter } from 'react-router-dom'
import { white, blueA700, grey100, grey300, grey700, grey800 } from 'material-ui/styles/colors'
import EditorPage from '../components/EditorPage'
import { requestTemplates } from '../state/actions/templates'
import { requestSwagger } from '../state/actions/apimodels'
import MenuItem from 'material-ui/MenuItem'
import FlatButton from 'material-ui/FlatButton'
import IconExpand from 'material-ui/svg-icons/navigation/more-vert'
import IconApply from 'material-ui/svg-icons/action/get-app'
import RaisedButton from 'material-ui/RaisedButton'
import Popover from 'material-ui/Popover'
import Menu from 'material-ui/Menu'

import ace from 'brace'
const { Range } = ace.acequire('ace/range')

const mapStateToProps = function(store) {
  return {
    user: store.session.user,
    templatesByGroup: store.templates.templatesByGroup,
    isFetching: store.templates.isFetching,
    swagger: store.apimodels.swagger,
  }
}

const mapDispatchToProps = function(dispatch, ownProps) {
  return {
    cancelEditor: function() {
      dispatch(routerActions.goBack())
    },
    createResource: function(contents) {
      dispatch(ownProps.resourceCreator(contents))
    },
    requestTemplates: function() {
      dispatch(requestTemplates())
    },
    requestSwagger: function() {
      dispatch(requestSwagger())
    },
  }
}

export default withRouter(connect(mapStateToProps, mapDispatchToProps) (
class NewResource extends React.Component {

  static propTypes = {
    resourceCreator: PropTypes.func.isRequired,
    resourceGroup: PropTypes.string.isRequired,
  }

  static defaultProps = {
    resourceCreator: function(){},
  }

  constructor(props) {
    super(props);

    props.requestTemplates()
    props.requestSwagger()

    let templateNames = this.getSortedTemplateNames(props.templatesByGroup[props.resourceGroup])
    let selectedTemplate = templateNames && templateNames[0]

    this.state = {
      templateMenuOpen: false,
      variablesMenuOpen: false,
      templateNames: templateNames || [],
      selectedTemplate,
      variables: [],
      errors: [],
      selectedVariable: '',
    }
    this.contents = ''
  }

  handleTouchTapTemplates = (event) => {
    // This prevents ghost click.
    event.preventDefault()
    this.setState({
      templateMenuOpen: true,
      templatesAnchorEl: event.currentTarget,
    })
  }

  handleTemplatesMenuSelection = (event, value) => {
    this.setState({
      selectedTemplate: value,
      templateMenuOpen: false,
    })
  }

  selectAllInstancesOfVariable = (variable) => {
    this.editor.focus()
    this.editor.selection.clearSelection()
    this.editor.findAll('${' + variable + '}',{
      backwards: false,
      wrap: true,
      caseSensitive: true,
      wholeWord: false,
      regExp: false,
    })
  }

  handleEditorChange = (contents) => {
    this.contents = contents
  }

  handleSelectionChange = (selection, event) => {

    if (!this.ignoreSelectionChange) {
      let s = selection.toOrientedRange()
      if (s.end.column > s.start.column && s.end.row === s.start.row) {
        let rawText = this.editor.session.getTextRange(s)
        if (!rawText.startsWith('${') && !rawText.endsWith('}')) {
          let range = new Range(
            s.start.row,
            s.start.column -2,
            s.end.row,
            s.end.column + 1)
          let text = this.editor.session.getTextRange(range)
          if (text.startsWith('${') && text.endsWith('}')) {
            this.lastRange = s
            let variable = text.slice(2,-1)
            this.ignoreSelectionChange = true
            this.selectAllInstancesOfVariable(variable)
            this.ignoreSelectionChange = false
          }
        }
      }
    }
  }

  handleCursorChange = (cursor) => {

  }

  handleRequestCloseTemplates = () => {
    this.setState({
      templateMenuOpen: false,
    })
  }

  handleEditorLoaded = (editor) => {
    this.editor = editor
    if (this.state.selectedVariable) {
      this.selectAllInstancesOfVariable(this.state.selectedVariable)
      this.setState({
        selectedVariable: null,
      })
    }
  }

  handleEditorBlur = () => {

  }

  handleEditorApply = () => {
    this.props.createResource(this.contents)
  }

  getSortedTemplateNames = (templates) => {
    if (!!templates) {
      let templateNames = []
      for (let key in templates) {
        templateNames.push(key)
      }
      templateNames.sort(String.localeCompare)
      return templateNames
    }
  }

  detectVariables = (contents) => {
    let variables = {}
    let varPattern = /\${([A-Za-z0-9_-]+)}/g;
    let m = varPattern.exec(contents)
    while (m) {
      variables[m[1]] = true
      m = varPattern.exec(contents)
    }
    return Object.keys(variables)
  }

  onApplyTemplate = () => {
    let contents = this.props.templatesByGroup[this.props.resourceGroup][this.state.selectedTemplate]
    this.editor && this.editor.setValue(contents)
    let variables = this.detectVariables(contents)
    this.contents = contents
    this.setState({
      variables: variables,
      selectedVariable: variables[0],
    })
  }

  componentWillReceiveProps = (props) => {

    if (!props.templatesByGroup && !props.isFetching) {
      props.requestTemplates()
    } else if (props.templatesByGroup) {
      let templateNames = this.getSortedTemplateNames(props.templatesByGroup[props.resourceGroup])
      let selectedTemplate = this.state.selectedTemplate || (templateNames && templateNames[0])
      this.setState({
        templateNames: (templateNames || []),
        selectedTemplate,
      })
    }
  }

  render() {

    const styles = {
      label: {
        paddingLeft: 4,
        lineHeight: '24px',
        marginRight: 5,
        fontSize: 14,
        // fontWeight: 600,
        display: 'inline-block',
        color: white,
      },
      button: {
        minWidth: 160,
        textAlign: 'left',
        textTransform: 'none',
        display: 'inline-block',
        marginLeft: 8,
        color: grey300,
      },
      applyButton: {
        textTransform: 'none',
        display: 'inline-block',
        marginLeft: 8,
        color: white,
      },
      buttonLabel: {
        textTransform: 'none',
        fontSize: 14,
        fontWeight: 600,
        color: grey300,
      },
      popoverMenu: {
        fontSize: 14,
        overflowX: 'hidden',
        paddingTop: 0,
        paddingBottom: 0,
      },
      popoverItems: {
        // color: grey300,
      }
    }

    let { templateNames, selectedTemplate } = this.state

    let menuItems = []
    for (let key of templateNames) {
      menuItems.push(<MenuItem key={key} value={key} primaryText={key}/>)
    }

    let title = (

        template
        <FlatButton
          fullWidth={false}
          labelStyle={styles.buttonLabel}
          style={styles.button}
          label={selectedTemplate}
          hoverColor={grey700}
          backgroundColor={grey800}
          onTouchTap={this.handleTouchTapTemplates.bind(this)}
          icon={<IconExpand style={{height: 18, width: 18}}/>}
        />
        <Popover
          onRequestClose={this.handleRequestCloseTemplates}
          anchorOrigin={{horizontal: 'left', vertical: 'bottom'}}
          targetOrigin={{horizontal: 'left', vertical: 'top'}}
          open={this.state.templateMenuOpen}
          anchorEl={this.state.templatesAnchorEl}
        >
          <Menu
            multiple={false}
            value={selectedTemplate}
            desktop={true}
            selectedMenuItemStyle={{
              color: blueA700,
              fontWeight: 600,
              backgroundColor: grey100,
            }}
            style={styles.popoverMenu}
            onChange={this.handleTemplatesMenuSelection.bind(this)}
          >
            {menuItems}
          </Menu>
        </Popover>

        <RaisedButton
          label="Replace"
          icon={<IconApply style={{fill: grey300}}/>}
          style={styles.applyButton}
          labelColor={grey300}
          backgroundColor={grey800}
          hoverColor={grey700}
          onTouchTap={this.onApplyTemplate.bind(this)}
        />

    )

    let additionalActions = []

    return (
        <EditorPage
          open={!!this.props.user}
          resourceGroup={this.props.resourceGroup}
          detectVariables={this.detectVariables}
          onChange={this.handleEditorChange}
          onEditorApply={this.handleEditorApply.bind(this)}
          onEditorCancel={this.props.cancelEditor}
          onSelectionChange={this.handleSelectionChange.bind(this)}
          onCursorChange={this.handleCursorChange.bind(this)}
          onBlur={this.handleEditorBlur}
          additionalActions={additionalActions}
          title={title}
          titleStyle={{width: '100%', justifyContent: 'flex-start'}}
          contents={this.contents}
          onEditorLoaded={this.handleEditorLoaded}
          ref={(ref) => {
            if (!!ref) {
              this.editorPage = ref
            }
          }}
        />
    )
  }
}))<|endoftext|>


<commit_before>// Copyright 2017, University of Colorado Boulder

/**
 * QUnit tests for Property
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var axon = require( 'AXON/axon' );
  var ObjectIO = require( 'ifphetio!PHET_IO/types/ObjectIO' );
  var Property = require( 'AXON/Property' );
  var PropertyIO = require( 'AXON/PropertyIO' );
  var Tandem = require( 'TANDEM/Tandem' );

  QUnit.module( 'Property' );

  QUnit.test( 'Test unlink', function( assert ) {
    var p = new Property( 1 );
    var a = function( a ) {};
    var b = function( b ) {};
    var c = function( c ) {};
    p.link( a );
    p.link( b );
    p.link( c );
    assert.equal( p.changedEmitter.listeners.length, 3, 'should have 3 observers now' );
    p.unlink( b );
    assert.equal( p.changedEmitter.listeners[ 0 ], a, 'should have removed b' );
    assert.equal( p.changedEmitter.listeners[ 1 ], c, 'should have removed b' );
    assert.equal( p.changedEmitter.listeners.length, 2, 'should have removed an item' );
  } );

  QUnit.test( 'Test Property.multilink', function( assert ) {
    var a = new Property( 1 );
    var b = new Property( 2 );
    var callbacks = 0;
    Property.multilink( [ a, b ], function( a, b ) {
      callbacks++;
      assert.equal( a, 1, 'first value should pass through' );
      assert.equal( b, 2, 'second value should pass through' );
    } );
    assert.equal( callbacks, 1, 'should have called back to a multilink' );
  } );

  QUnit.test( 'Test Property.lazyMultilink', function( assert ) {
    var a = new Property( 1 );
    var b = new Property( 2 );
    var callbacks = 0;
    Property.lazyMultilink( [ a, b ], function( a, b ) {
      callbacks++;
      assert.equal( a, 1 );
      assert.equal( b, 2 );
    } );
    assert.equal( callbacks, 0, 'shouldnt call back to a lazy multilink' );
  } );

  /**
   * Make sure linking attributes and unlinking attributes works on Property
   */
  QUnit.test( 'Property.linkAttribute', function( assert ) {
    var property = new axon.Property( 7 );
    var state = { age: 99 };
    var listener = property.linkAttribute( state, 'age' );
    assert.equal( state.age, 7, 'link should synchronize values' );
    property.value = 8;
    assert.equal( state.age, 8, 'link should update values' );
    property.unlinkAttribute( listener );
    property.value = 9;
    assert.equal( state.age, 8, 'state shouldnt have changed after unlink' );
  } );

  QUnit.test( 'Property value validation', function( assert ) {

    var property;
    window.assert && assert.throws( function() {
      new axon.Property( 0, { validValues: [ 1, 2, 3 ] } ); // eslint-disable-line
    }, 'invalid initial value for Property with options.validValues' );
    property = new axon.Property( 1, { validValues: [ 1, 2, 3 ] } );
    property.set( 3 );
    window.assert && assert.throws( function() {
      property.set( 4 );
    }, 'set an invalid value for Property with options.validValues' );

    window.assert && assert.throws( function() {
      new axon.Property( 0, { isValidValue: function( value ) { return ( value > 0 && value < 4 ); } } ); // eslint-disable-line
    }, 'invalid initial value for Property with options.isValidValue' );

    property = new axon.Property( 1, { isValidValue: function( value ) { return ( value > 0 && value < 4 ); } } );
    property.set( 3 );
    window.assert && assert.throws( function() {
      property.set( 4 );
    }, 'set an invalid value for Property with options.isValidValue' );

    assert.ok( true, 'so we have at least 1 test in this set' );
  } );

  // Tests that can only run in phet-io mode
  if ( window.phet.phetio ) {
    QUnit.test( 'Test PropertyIO toStateObject/fromStateObject', function( assert ) {
      var done = assert.async();
      var tandem = Tandem.rootTandem.createTandem( 'testTandemProperty' );
      tandem.addInstance = function( instance, options ) {

        // Run in the next frame after the object finished getting constructed
        setTimeout( function() {
          var stateObject = ObjectIO.toStateObject( instance );
          assert.equal( stateObject.value, 0, 'toStateObject should match' );
          done();
        }, 0 );
      };
      new Property( 0, { // eslint-disable-line
        phetioType: PropertyIO( ObjectIO ),
        tandem: tandem,
        validValues: [ 0, 1, 2, 3 ]
      } );
    } );
  }
} );<commit_msg>add unit tests for Property valueType option, #172<commit_after>// Copyright 2017, University of Colorado Boulder

/**
 * QUnit tests for Property
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var axon = require( 'AXON/axon' );
  var ObjectIO = require( 'ifphetio!PHET_IO/types/ObjectIO' );
  var Property = require( 'AXON/Property' );
  var PropertyIO = require( 'AXON/PropertyIO' );
  var Tandem = require( 'TANDEM/Tandem' );

  QUnit.module( 'Property' );

  QUnit.test( 'Test unlink', function( assert ) {
    var p = new Property( 1 );
    var a = function( a ) {};
    var b = function( b ) {};
    var c = function( c ) {};
    p.link( a );
    p.link( b );
    p.link( c );
    assert.equal( p.changedEmitter.listeners.length, 3, 'should have 3 observers now' );
    p.unlink( b );
    assert.equal( p.changedEmitter.listeners[ 0 ], a, 'should have removed b' );
    assert.equal( p.changedEmitter.listeners[ 1 ], c, 'should have removed b' );
    assert.equal( p.changedEmitter.listeners.length, 2, 'should have removed an item' );
  } );

  QUnit.test( 'Test Property.multilink', function( assert ) {
    var a = new Property( 1 );
    var b = new Property( 2 );
    var callbacks = 0;
    Property.multilink( [ a, b ], function( a, b ) {
      callbacks++;
      assert.equal( a, 1, 'first value should pass through' );
      assert.equal( b, 2, 'second value should pass through' );
    } );
    assert.equal( callbacks, 1, 'should have called back to a multilink' );
  } );

  QUnit.test( 'Test Property.lazyMultilink', function( assert ) {
    var a = new Property( 1 );
    var b = new Property( 2 );
    var callbacks = 0;
    Property.lazyMultilink( [ a, b ], function( a, b ) {
      callbacks++;
      assert.equal( a, 1 );
      assert.equal( b, 2 );
    } );
    assert.equal( callbacks, 0, 'shouldnt call back to a lazy multilink' );
  } );

  /**
   * Make sure linking attributes and unlinking attributes works on Property
   */
  QUnit.test( 'Property.linkAttribute', function( assert ) {
    var property = new axon.Property( 7 );
    var state = { age: 99 };
    var listener = property.linkAttribute( state, 'age' );
    assert.equal( state.age, 7, 'link should synchronize values' );
    property.value = 8;
    assert.equal( state.age, 8, 'link should update values' );
    property.unlinkAttribute( listener );
    property.value = 9;
    assert.equal( state.age, 8, 'state shouldnt have changed after unlink' );
  } );

  QUnit.test( 'Property value validation', function( assert ) {

    // Type that is specific to valueType tests
    function TestType( index ) { this.index = index; }

    var property;
    window.assert && assert.throws( function() {
      new axon.Property( 0, { validValues: [ 1, 2, 3 ] } ); // eslint-disable-line
    }, 'invalid initial value for Property with options.validValues' );
    property = new axon.Property( 1, { validValues: [ 1, 2, 3 ] } );
    property.set( 3 );
    window.assert && assert.throws( function() {
      property.set( 4 );
    }, 'set an invalid value for Property with options.validValues' );

    window.assert && assert.throws( function() {
      new axon.Property( 0, { isValidValue: function( value ) { return ( value > 0 && value < 4 ); } } ); // eslint-disable-line
    }, 'invalid initial value for Property with options.isValidValue' );

    property = new axon.Property( 1, { isValidValue: function( value ) { return ( value > 0 && value < 4 ); } } );
    property.set( 3 );
    window.assert && assert.throws( function() {
      property.set( 4 );
    }, 'set an invalid value for Property with options.isValidValue' );

    // valueType by itself
    var options = {
      valueType: TestType
    };
    window.assert && assert.throws( function() {
      new axon.Property( 0, options ); // eslint-disable-line
    }, 'invalid value fails valueType validation for Property with options.valueType' );
    property = new axon.Property( new TestType( 0 ), options );
    property.set( new TestType( 0 ) );
    window.assert && assert.throws( function() {
      property.set( 0 );
    }, 'set value fails valueType validation for Property with options.valueType' );

    // valueType and isValidValue combined
    options = {
      valueType: TestType,
      isValidValue: function( value ) {
        return value.index >= 0;
      }
    };
    window.assert && assert.throws( function() {
      new axon.Property( 0, options ); // eslint-disable-line
    }, 'initial value fails valueType validation for Property with options.valueType and options.isValidValue' );
    window.assert && assert.throws( function() {
      new axon.Property( new TestType( -1 ), options ); // eslint-disable-line
    }, 'initial value fails isValidValue validation for Property with options.valueType and options.isValidValue' );
    property = new axon.Property( new TestType( 0 ), options );
    property.set( new TestType( 0 ) );
    window.assert && assert.throws( function() {
      property.set( 0 );
    }, 'set value fails valueType validation for Property with options.valueType and options.isValidValue' );
    window.assert && assert.throws( function() {
      property.set( new TestType( -1 ) );
    }, 'set value fails isValidValue validation for Property with options.valueType and options.isValidValue' );

    assert.ok( true, 'so we have at least 1 test in this set' );
  } );

  // Tests that can only run in phet-io mode
  if ( window.phet.phetio ) {
    QUnit.test( 'Test PropertyIO toStateObject/fromStateObject', function( assert ) {
      var done = assert.async();
      var tandem = Tandem.rootTandem.createTandem( 'testTandemProperty' );
      tandem.addInstance = function( instance, options ) {

        // Run in the next frame after the object finished getting constructed
        setTimeout( function() {
          var stateObject = ObjectIO.toStateObject( instance );
          assert.equal( stateObject.value, 0, 'toStateObject should match' );
          done();
        }, 0 );
      };
      new Property( 0, { // eslint-disable-line
        phetioType: PropertyIO( ObjectIO ),
        tandem: tandem,
        validValues: [ 0, 1, 2, 3 ]
      } );
    } );
  }
} );<|endoftext|>


<commit_before>'use strict';

const mongoose = requireLocal('controller/mongo.js');
const fs = require('fs');
const path = require('path');
const renderer = requireLocal('services/renderer');
const fileSystem = requireLocal('services/file-system');
const multer = require('multer');
const adminAuth = requireLocal('controller/admin-auth');
const api = requireLocal('controller/api-proxy');

const express = require('express');
const reader = requireLocal('services/template-reader.js');
const router = express.Router();

const models = {
  view: mongoose.model('view', requireLocal('schemas/view.js')),
  page: mongoose.model('page', requireLocal('schemas/page.js')),
  menu: mongoose.model('menu', requireLocal('schemas/menu.js'))
};

// Creates regex string for filtering valid models
const allowedModels = '(' + Object.keys(models).reduce((p, k) => p + '|' + k, '').substr(1) + ')';

const storage = multer.diskStorage({
  destination: (req, file, callback) => {
    callback(null, './public/img/uploads');
  },

  filename: (req, file, callback) => {
    const fn = file.originalname;
    callback(null, fn + '-' + Date.now() + path.extname(fn));
  }
});
const upload = multer({ storage: storage }).single('image');

router.use((req, res, next) => {
  res.set({
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE',
    'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept'
  });
  if ('OPTIONS' == req.method) {
    res.sendStatus(200);
  }
  else {
    next();
  }
});

router.post('/auth/login', function(req, res) {
  console.log(req.body);
  api.authenticate(req.body.email, req.body.password)
    .then(() => {
      res.send({ token: adminAuth.createJWT(req.body.email) });
    })
    .catch(() => {
      return res.status(401).send({ message: 'Invalid email and/or password' });
    });
});

router.use(adminAuth.ensureAuthenticated);

/**
 * Reads a file path originating from / and sends it to the response
 * @param fpath Path to the file
 * @param res The HTTP response object
 * @param next
 */
function serveFile(fpath, res, next) {
  fs.access(fpath, fs.R_OK, err => err ? next(err) : res.sendFile(fpath));
}

router.post('/image', upload, (req, res) =>
  res.json({
    filePath: '/img/uploads/' + req.file.filename
  })
);

router.delete('/image/:filename', (req, res, next) =>
  fs.unlink('./public/img/uploads/' + req.params.filename, (err) => {
    if (err) return next(err);

    res.json({
      result: 'ok'
    });
  })
);

router.get('/getList', (req, res) =>
  res.json(reader.getAll())
);

router.get('/css', (req, res, next) =>
  serveFile(path.join(global.ROOT, 'public/css/styles.min.css'), res, next)
);

router.get('/html/:name', (req, res, next) =>
  req.params.name === 'master' ?
    serveFile(fileSystem.buildMasterTemplatePath(), res, next) :
    serveFile(fileSystem.buildTemplatePath(req.params.name), res, next)
);

router.get('/:model' + allowedModels, (req, res, next) =>
  models[req.params.model].find({}).exec((err, docs) =>
    err ? next(err) : res.json(docs)
  )
);

router.get('/:model' + allowedModels + '/:id', (req, res, next) =>
  models[req.params.model].findOne({ _id: req.params.id }).exec((err, docs) =>
    err ? next(err) : res.json(docs)
  )
);

router.get('/render/:pageid', (req, res) => {
  renderer.renderAndSavePageByID(req.params.pageid);
  res.json({
    status: 'ok'
  });
});

// Specific override for POST /api/view
router.post('/view', (req, res, next) => {
  if (!req.body || !req.body.name) {
    return res.sendStatus(400);
  }

  const template = reader.getByName(req.body.name);
  if (!template) {
    return res.sendStatus(404);
  }

  const rawView = {
    templateName: template.name,
    variables: []
  };

  //FILL WITH DEFAULT VALUES
  for (let variable of template.variables) {
    variable.values = [
      { language: 'de', value: 'defaultValue' },
      { language: 'en', value: 'defaultValue' }
    ];
    rawView.variables.push(variable);
  }

  models.view.create(rawView, (err, docs) => {
    console.log(docs);
    if (err) {
      next(err);
    } else {
      res.json(docs);
    }
  });
});

router.post('/:model' + allowedModels, (req, res, next) => {
  if (!req.body) {
    res.sendStatus(400);
    return;
  }

  models[req.params.model].create(req.body, (err, docs) => {
    if (err) {
      next(err);
    } else {
      res.json(docs);
    }
  });

});

router.post('/:model' + allowedModels + '/:id', (req, res, next) => {
  if (!req.body) {
    res.sendStatus(400);
    return;
  }

  models[req.params.model]
    .findOneAndUpdate({ _id: req.params.id }, req.body, { new: true }, (err, doc) => {
      if (err) {
        next(err);
      } else {
        res.json(doc);
      }
    });
});

router.delete('/:model' + allowedModels + '/:id', (req, res, next) => {
  models[req.params.model].findOneAndRemove({ _id: req.params.id }, (err, doc) => {
    if (err) {
      next(err);
    } else {
      res.json(doc);
    }
  });
});

module.exports = router;
<commit_msg>Remove logging<commit_after>'use strict';

const mongoose = requireLocal('controller/mongo.js');
const fs = require('fs');
const path = require('path');
const renderer = requireLocal('services/renderer');
const fileSystem = requireLocal('services/file-system');
const multer = require('multer');
const adminAuth = requireLocal('controller/admin-auth');
const api = requireLocal('controller/api-proxy');

const express = require('express');
const reader = requireLocal('services/template-reader.js');
const router = express.Router();

const models = {
  view: mongoose.model('view', requireLocal('schemas/view.js')),
  page: mongoose.model('page', requireLocal('schemas/page.js')),
  menu: mongoose.model('menu', requireLocal('schemas/menu.js'))
};

// Creates regex string for filtering valid models
const allowedModels = '(' + Object.keys(models).reduce((p, k) => p + '|' + k, '').substr(1) + ')';

const storage = multer.diskStorage({
  destination: (req, file, callback) => {
    callback(null, './public/img/uploads');
  },

  filename: (req, file, callback) => {
    const fn = file.originalname;
    callback(null, fn + '-' + Date.now() + path.extname(fn));
  }
});
const upload = multer({ storage: storage }).single('image');

router.use((req, res, next) => {
  res.set({
    'Access-Control-Allow-Origin': '*',
    'Access-Control-Allow-Methods': 'GET,PUT,POST,DELETE',
    'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept'
  });
  if ('OPTIONS' == req.method) {
    res.sendStatus(200);
  }
  else {
    next();
  }
});

router.post('/auth/login', function(req, res) {
  api.authenticate(req.body.email, req.body.password)
    .then(() => {
      res.send({ token: adminAuth.createJWT(req.body.email) });
    })
    .catch(() => {
      return res.status(401).send({ message: 'Invalid email and/or password' });
    });
});

router.use(adminAuth.ensureAuthenticated);

/**
 * Reads a file path originating from / and sends it to the response
 * @param fpath Path to the file
 * @param res The HTTP response object
 * @param next
 */
function serveFile(fpath, res, next) {
  fs.access(fpath, fs.R_OK, err => err ? next(err) : res.sendFile(fpath));
}

router.post('/image', upload, (req, res) =>
  res.json({
    filePath: '/img/uploads/' + req.file.filename
  })
);

router.delete('/image/:filename', (req, res, next) =>
  fs.unlink('./public/img/uploads/' + req.params.filename, (err) => {
    if (err) return next(err);

    res.json({
      result: 'ok'
    });
  })
);

router.get('/getList', (req, res) =>
  res.json(reader.getAll())
);

router.get('/css', (req, res, next) =>
  serveFile(path.join(global.ROOT, 'public/css/styles.min.css'), res, next)
);

router.get('/html/:name', (req, res, next) =>
  req.params.name === 'master' ?
    serveFile(fileSystem.buildMasterTemplatePath(), res, next) :
    serveFile(fileSystem.buildTemplatePath(req.params.name), res, next)
);

router.get('/:model' + allowedModels, (req, res, next) =>
  models[req.params.model].find({}).exec((err, docs) =>
    err ? next(err) : res.json(docs)
  )
);

router.get('/:model' + allowedModels + '/:id', (req, res, next) =>
  models[req.params.model].findOne({ _id: req.params.id }).exec((err, docs) =>
    err ? next(err) : res.json(docs)
  )
);

router.get('/render/:pageid', (req, res) => {
  renderer.renderAndSavePageByID(req.params.pageid);
  res.json({
    status: 'ok'
  });
});

// Specific override for POST /api/view
router.post('/view', (req, res, next) => {
  if (!req.body || !req.body.name) {
    return res.sendStatus(400);
  }

  const template = reader.getByName(req.body.name);
  if (!template) {
    return res.sendStatus(404);
  }

  const rawView = {
    templateName: template.name,
    variables: []
  };

  //FILL WITH DEFAULT VALUES
  for (let variable of template.variables) {
    variable.values = [
      { language: 'de', value: 'defaultValue' },
      { language: 'en', value: 'defaultValue' }
    ];
    rawView.variables.push(variable);
  }

  models.view.create(rawView, (err, docs) => {
    console.log(docs);
    if (err) {
      next(err);
    } else {
      res.json(docs);
    }
  });
});

router.post('/:model' + allowedModels, (req, res, next) => {
  if (!req.body) {
    res.sendStatus(400);
    return;
  }

  models[req.params.model].create(req.body, (err, docs) => {
    if (err) {
      next(err);
    } else {
      res.json(docs);
    }
  });

});

router.post('/:model' + allowedModels + '/:id', (req, res, next) => {
  if (!req.body) {
    res.sendStatus(400);
    return;
  }

  models[req.params.model]
    .findOneAndUpdate({ _id: req.params.id }, req.body, { new: true }, (err, doc) => {
      if (err) {
        next(err);
      } else {
        res.json(doc);
      }
    });
});

router.delete('/:model' + allowedModels + '/:id', (req, res, next) => {
  models[req.params.model].findOneAndRemove({ _id: req.params.id }, (err, doc) => {
    if (err) {
      next(err);
    } else {
      res.json(doc);
    }
  });
});

module.exports = router;
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

module.exports = function (crypto, error, isA, serverPublicKey, bridge) {

  const HEX_STRING = /^(?:[a-fA-F0-9]{2})+$/

  var routes = [
    {
      method: 'GET',
      path: '/.well-known/browserid',
      config: {
        handler: function wellKnown(request) {
          request.reply(
            {
              'public-key': serverPublicKey,
              'authentication': '/sign_in.html',
              'provisioning': '/provision.html'
            }
          )
        }
      }
    },
    {
      method: 'GET',
      path: '/sign_in.html',
      config: {
        handler: {
          file: './sign_in.html'
        }
      }
    },
    {
      method: 'GET',
      path: '/provision.html',
      config: {
        handler: {
          file: './provision.html'
        }
      }
    },
    {
      method: 'POST',
      path: '/get_random_bytes',
      config: {
        handler: function getRandomBytes(request) {
          crypto.randomBytes(
            32,
            function(err, buf) {
              request.reply(err || { data: buf.toString('hex') })
            }
          )
        }
      }
    },
    {
      method: 'GET',
      path: '/verify_email',
      config: {
        handler: {
          proxy: {
            mapUri: function (request, next) {
              return next(null, bridge.url + request.raw.req.url)
            },
            passThrough: true,
            xforward: true
          }
        },
        validate: {
          query: {
            code: isA.String().regex(HEX_STRING).required(),
            uid: isA.String().max(64).required()
          }
        }
      }
    }
  ]

  return routes
}
<commit_msg>redirect instead of using a proxy<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

module.exports = function (crypto, error, isA, serverPublicKey, bridge) {

  const HEX_STRING = /^(?:[a-fA-F0-9]{2})+$/

  var routes = [
    {
      method: 'GET',
      path: '/.well-known/browserid',
      config: {
        handler: function wellKnown(request) {
          request.reply(
            {
              'public-key': serverPublicKey,
              'authentication': '/sign_in.html',
              'provisioning': '/provision.html'
            }
          )
        }
      }
    },
    {
      method: 'GET',
      path: '/sign_in.html',
      config: {
        handler: {
          file: './sign_in.html'
        }
      }
    },
    {
      method: 'GET',
      path: '/provision.html',
      config: {
        handler: {
          file: './provision.html'
        }
      }
    },
    {
      method: 'POST',
      path: '/get_random_bytes',
      config: {
        handler: function getRandomBytes(request) {
          crypto.randomBytes(
            32,
            function(err, buf) {
              request.reply(err || { data: buf.toString('hex') })
            }
          )
        }
      }
    },
    {
      method: 'GET',
      path: '/verify_email',
      config: {
        handler: function (request, next) {
          return request.reply.redirect(bridge.url + request.raw.req.url)
        },
        validate: {
          query: {
            code: isA.String().regex(HEX_STRING).required(),
            uid: isA.String().max(64).required()
          }
        }
      }
    }
  ]

  return routes
}
<|endoftext|>


<commit_before>const axios = require('axios');

module.exports = async function() {

  const galleries = await axios.get('https://galleries.ticklethepanda.co.uk/', {
    headers: {
      "Cache-Control": "no-store"
    }
  });

  console.log(JSON.stringify(galleries.data, null, 2));

  return galleries.data;
}
<commit_msg>Improve galleries info output<commit_after>const axios = require('axios');

module.exports = async function() {

  const galleries = await axios.get('https://galleries.ticklethepanda.co.uk/', {
    headers: {
      "Cache-Control": "no-store"
    }
  });

  printGalleryInfo(galleries.data);

  return galleries.data;
}

function printGalleryInfo(galleries) {
  console.log("Galleries fetched:")
  for (let gallery of galleries.galleries) {
    console.log(` - ${gallery.name} (${gallery.ref}) | ${gallery.images.map(i => i.name).join(', ')}`);
  }
}<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Broad Institute
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

import BamReaderNonIndexed from "./bamReaderNonIndexed.js";
import ShardedBamReader from "./shardedBamReader.js";
import BamReader from "./bamReader.js";
import BamWebserviceReader from "./bamWebserviceReader.js";
import HtsgetReader from "./htsgetReader.js";
import CramReader from "../cram/cramReader.js";
import Ga4ghAlignmentReader from "../ga4gh/ga4ghAlignmentReader.js";
import  {pairAlignments, unpairAlignments, packAlignmentRows} from "./alignmentUtils.js";
import {StringUtils} from "../../node_modules/igv-utils/src/index.js";

const isString = StringUtils.isString;

const BamSource = function (config, browser) {

    const genome = browser.genome;

    this.config = config;
    this.genome = genome;
    this.alignmentContainer = undefined;

    if (isString(config.url) && config.url.startsWith("data:")) {
        if ("cram" === config.format) {
            throw "CRAM data uris are not supported"
        }
        this.config.indexed = false;
    }

    if ("ga4gh" === config.sourceType) {
        this.bamReader = new Ga4ghAlignmentReader(config, genome);
    } else if ("pysam" === config.sourceType) {
        this.bamReader = new BamWebserviceReader(config, genome)
    } else if ("htsget" === config.sourceType) {
        this.bamReader = new HtsgetReader(config, genome);
    } else if ("shardedBam" === config.sourceType) {
        this.bamReader = new ShardedBamReader(config, genome);
    } else if ("cram" === config.format) {
        this.bamReader = new CramReader(config, genome, browser);
    } else {
        if (this.config.indexed === false) {
            this.bamReader = new BamReaderNonIndexed(config, genome);
        } else {
            this.bamReader = new BamReader(config, genome);
        }
    }

    this.viewAsPairs = config.viewAsPairs;
    this.showSoftClips = config.showSoftClips;
};

BamSource.prototype.setViewAsPairs = function (bool) {
    var self = this;

    if (this.viewAsPairs !== bool) {
        this.viewAsPairs = bool;
       // if (this.alignmentContainer) {
       //     this.alignmentContainer.setViewAsPairs(bool);
       // }
    }
}

BamSource.prototype.setShowSoftClips = function (bool) {
    if (this.showSoftClips !== bool) {
        this.showSoftClips = bool;
    }
}

BamSource.prototype.getAlignments = async function (chr, bpStart, bpEnd) {

    try {
        const genome = this.genome;
        const showSoftClips = this.showSoftClips;

        if (this.alignmentContainer && this.alignmentContainer.contains(chr, bpStart, bpEnd)) {
            return this.alignmentContainer;

        } else {
            const alignmentContainer = await this.bamReader.readAlignments(chr, bpStart, bpEnd)
            let alignments = alignmentContainer.alignments;
            if (!this.viewAsPairs) {
                alignments = unpairAlignments([{alignments: alignments}]);
            }
            const hasAlignments = alignments.length > 0;
            alignmentContainer.packedAlignmentRows = packAlignmentRows(alignments, alignmentContainer.start, alignmentContainer.end, showSoftClips);
            alignmentContainer.alignments = undefined;  // Don't need to hold onto these anymore

            this.alignmentContainer = alignmentContainer;

            if (!hasAlignments) {
                return alignmentContainer;
            } else {

                const sequence = await genome.sequence.getSequence(chr, alignmentContainer.start, alignmentContainer.end)
                if (sequence) {
                    alignmentContainer.coverageMap.refSeq = sequence;    // TODO -- fix this
                    alignmentContainer.sequence = sequence;           // TODO -- fix this
                    return alignmentContainer;
                } else {
                    console.error("No sequence for: " + chr + ":" + alignmentContainer.start + "-" + alignmentContainer.end)
                }
            }
        }
    } catch (e) {
        console.error(e);
        throw e;
    }
}

export default BamSource;
<commit_msg>minor cleanup<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Broad Institute
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

import BamReaderNonIndexed from "./bamReaderNonIndexed.js";
import ShardedBamReader from "./shardedBamReader.js";
import BamReader from "./bamReader.js";
import BamWebserviceReader from "./bamWebserviceReader.js";
import HtsgetReader from "./htsgetReader.js";
import CramReader from "../cram/cramReader.js";
import Ga4ghAlignmentReader from "../ga4gh/ga4ghAlignmentReader.js";
import {packAlignmentRows, unpairAlignments} from "./alignmentUtils.js";
import {StringUtils} from "../../node_modules/igv-utils/src/index.js";

const isString = StringUtils.isString;

const BamSource = function (config, browser) {

    const genome = browser.genome;

    this.config = config;
    this.genome = genome;
    this.alignmentContainer = undefined;

    if (isString(config.url) && config.url.startsWith("data:")) {
        if ("cram" === config.format) {
            throw "CRAM data uris are not supported"
        }
        this.config.indexed = false;
    }

    if ("ga4gh" === config.sourceType) {
        this.bamReader = new Ga4ghAlignmentReader(config, genome);
    } else if ("pysam" === config.sourceType) {
        this.bamReader = new BamWebserviceReader(config, genome)
    } else if ("htsget" === config.sourceType) {
        this.bamReader = new HtsgetReader(config, genome);
    } else if ("shardedBam" === config.sourceType) {
        this.bamReader = new ShardedBamReader(config, genome);
    } else if ("cram" === config.format) {
        this.bamReader = new CramReader(config, genome, browser);
    } else {
        if (this.config.indexed === false) {
            this.bamReader = new BamReaderNonIndexed(config, genome);
        } else {
            this.bamReader = new BamReader(config, genome);
        }
    }

    this.viewAsPairs = config.viewAsPairs;
    this.showSoftClips = config.showSoftClips;
};

BamSource.prototype.setViewAsPairs = function (bool) {
    var self = this;

    if (this.viewAsPairs !== bool) {
        this.viewAsPairs = bool;
        // if (this.alignmentContainer) {
        //     this.alignmentContainer.setViewAsPairs(bool);
        // }
    }
}

BamSource.prototype.setShowSoftClips = function (bool) {
    if (this.showSoftClips !== bool) {
        this.showSoftClips = bool;
    }
}

BamSource.prototype.getAlignments = async function (chr, bpStart, bpEnd) {

    const genome = this.genome;
    const showSoftClips = this.showSoftClips;

    if (this.alignmentContainer && this.alignmentContainer.contains(chr, bpStart, bpEnd)) {
        return this.alignmentContainer;

    } else {
        const alignmentContainer = await this.bamReader.readAlignments(chr, bpStart, bpEnd)
        let alignments = alignmentContainer.alignments;
        if (!this.viewAsPairs) {
            alignments = unpairAlignments([{alignments: alignments}]);
        }
        const hasAlignments = alignments.length > 0;
        alignmentContainer.packedAlignmentRows = packAlignmentRows(alignments, alignmentContainer.start, alignmentContainer.end, showSoftClips);
        alignmentContainer.alignments = undefined;  // Don't need to hold onto these anymore

        this.alignmentContainer = alignmentContainer;

        if (hasAlignments) {
            const sequence = await genome.sequence.getSequence(chr, alignmentContainer.start, alignmentContainer.end)
            if (sequence) {
                alignmentContainer.coverageMap.refSeq = sequence;    // TODO -- fix this
                alignmentContainer.sequence = sequence;           // TODO -- fix this
                return alignmentContainer;
            } else {
                console.error("No sequence for: " + chr + ":" + alignmentContainer.start + "-" + alignmentContainer.end)
            }
        }
        return alignmentContainer
    }
}

export default BamSource;
<|endoftext|>


<commit_before>/// <reference path="../../../../ext/ext-core-debug.js"/>
/// <reference path="../../../../Simplate.js"/>
/// <reference path="../../../../sdata/SDataSingleResourceRequest.js"/>
/// <reference path="../../../../sdata/SDataService.js"/>
/// <reference path="../../../../platform/View.js"/>
/// <reference path="../../../../platform/Detail.js"/>
/// <reference path="../../Format.js"/>
/// <reference path="../../Template.js"/>

Ext.namespace("Mobile.SalesLogix.Contract");

Mobile.SalesLogix.Contract.Detail = Ext.extend(Sage.Platform.Mobile.Detail, {
    constructor: function(o) {
        Mobile.SalesLogix.Contract.Detail.superclass.constructor.call(this);

        Ext.apply(this, o, {
            id: 'contract_detail',
            title: 'Contract',
	    editor: 'contract_edit',//Added by Rajkumar. G to enable edit functionality
            resourceKind: 'contracts'
        });

        this.layout = [
            {name: 'ReferenceNumber', label: 'ref num'},
            {name: 'Account.AccountName', label: 'account', view: 'account_detail', key: 'Account.$key', property: true},
            {name: 'Contact.FullName', label: 'contact'},
            {name: 'ServiceCode', label: 'svc type'},
            {name: 'TypeCode', label: 'contract type'},
            {name: 'Period', label: 'quantity'},
            {name: 'Remaining', label: 'remaining'},
            {name: 'StartDate', label: 'start', renderer: Mobile.SalesLogix.Format.date},
            {name: 'EndingDate', label: 'end' , renderer: Mobile.SalesLogix.Format.date},
	        {name: 'IsActive', label: 'active'},
	        {name: 'CreateUser', label: 'create user'},
            {name: 'CreateDate', label: 'create date', renderer: Mobile.SalesLogix.Format.date},
            {options: {title: 'Related Items', list: true}, as: [
                {
                    view: 'ticket_related',
                    where: this.formatAccountRelatedQuery.createDelegate(this, ['Account.id eq "{0}"'], true),
                    label: 'tickets',
                    icon: 'content/images/ticket_16x16.gif'
                }
            ]}
        ];
    },
    formatAccountRelatedQuery: function(entry, fmt) {
        return String.format(fmt, entry['Account']['$key']);
    },
    init: function() {
        Mobile.SalesLogix.Contract.Detail.superclass.init.call(this);
    },
    createRequest: function() {
        var request = Mobile.SalesLogix.Contract.Detail.superclass.createRequest.call(this);

        request
            .setQueryArgs({
                'include': 'Account,Address,AccountManager,AccountManager/UserInfo',
                'select': [
                      'ReferenceNumber',
	                  'Account/AccountName',
            		  'Contact/FullName',
            		  'ServiceCode',
            		  'TypeCode',
            		  'Period',
            		  'Remaining',
            		  'StartDate',
            		  'EndingDate',
            		  'IsActive',
            		  'CreateUser',
            		  'CreateDate'
                ].join(',')
            });

        return request;
    }
});
<commit_msg>[#4179326] Switched from Contact/Fullname to Contact/NameLF<commit_after>/// <reference path="../../../../ext/ext-core-debug.js"/>
/// <reference path="../../../../Simplate.js"/>
/// <reference path="../../../../sdata/SDataSingleResourceRequest.js"/>
/// <reference path="../../../../sdata/SDataService.js"/>
/// <reference path="../../../../platform/View.js"/>
/// <reference path="../../../../platform/Detail.js"/>
/// <reference path="../../Format.js"/>
/// <reference path="../../Template.js"/>

Ext.namespace("Mobile.SalesLogix.Contract");

Mobile.SalesLogix.Contract.Detail = Ext.extend(Sage.Platform.Mobile.Detail, {
    constructor: function(o) {
        Mobile.SalesLogix.Contract.Detail.superclass.constructor.call(this);

        Ext.apply(this, o, {
            id: 'contract_detail',
            title: 'Contract',
	    editor: 'contract_edit',//Added by Rajkumar. G to enable edit functionality
            resourceKind: 'contracts'
        });

        this.layout = [
            {name: 'ReferenceNumber', label: 'ref num'},
            {name: 'Account.AccountName', label: 'account', view: 'account_detail', key: 'Account.$key', property: true},
            {name: 'Contact.NameLF', label: 'contact'},
            {name: 'ServiceCode', label: 'svc type'},
            {name: 'TypeCode', label: 'contract type'},
            {name: 'Period', label: 'quantity'},
            {name: 'Remaining', label: 'remaining'},
            {name: 'StartDate', label: 'start', renderer: Mobile.SalesLogix.Format.date},
            {name: 'EndingDate', label: 'end' , renderer: Mobile.SalesLogix.Format.date},
	        {name: 'IsActive', label: 'active'},
	        {name: 'CreateUser', label: 'create user'},
            {name: 'CreateDate', label: 'create date', renderer: Mobile.SalesLogix.Format.date},
            {options: {title: 'Related Items', list: true}, as: [
                {
                    view: 'ticket_related',
                    where: this.formatAccountRelatedQuery.createDelegate(this, ['Account.id eq "{0}"'], true),
                    label: 'tickets',
                    icon: 'content/images/ticket_16x16.gif'
                }
            ]}
        ];
    },
    formatAccountRelatedQuery: function(entry, fmt) {
        return String.format(fmt, entry['Account']['$key']);
    },
    init: function() {
        Mobile.SalesLogix.Contract.Detail.superclass.init.call(this);
    },
    createRequest: function() {
        var request = Mobile.SalesLogix.Contract.Detail.superclass.createRequest.call(this);

        request
            .setQueryArgs({
                'include': 'Account,Address,AccountManager,AccountManager/UserInfo',
                'select': [
                      'ReferenceNumber',
	                  'Account/AccountName',
            		  'Contact/NameLF',
            		  'ServiceCode',
            		  'TypeCode',
            		  'Period',
            		  'Remaining',
            		  'StartDate',
            		  'EndingDate',
            		  'IsActive',
            		  'CreateUser',
            		  'CreateDate'
                ].join(',')
            });

        return request;
    }
});
<|endoftext|>


<commit_before>var _ = require('underscore'),
	uuid = require('node-uuid'),
	DynDB = require('dyndb'),
	Backbone = require('./backbone-dynamodb-shared');

var dyndb = new DynDB();
Backbone.DynamoDB.setup = dyndb.setup;

var encodeAttribute = exports.encodeAttribute = function(v) {
	if (_.isArray(v)) {
		var type = 'N', set = _.map(v, function(i) {
			var j = encodeAttribute(i);
			if (j.S) type = 'S';
			return j.N || j.S;
		});
		return type === 'N' ? {NS: set} : {SS: set};
	} else if (_.isNumber(v)) return {N: '' + v};
	else if (_.isBoolean(v)) return {S: v.toString()};
	else if (_.isDate(v)) return {S: v.toISOString()};
	else if (_.isString(v)) return {S: v};
	else return {S: JSON.stringify(v)};
};

var decodeAttribute = exports.decodeAttribute = function(attr) {
	if (attr.NS || attr.SS) {
		var type = attr.NS ? 'N' : 'S';
		return _.map(attr[type + 'S'], function(v) {
			var _attr = {};
			_attr[type] = v;
			return decodeAttribute(_attr);
		});
	}
	if (attr.N) return /\./.test(attr.N) ? parseFloat(attr.N) : parseInt(attr.N);

	var v = attr.S;
	if (/^true|false$/.test(v)) return v === 'true';
	else if (/^\d{4}(-\d{2}){2}T\d{2}(:\d{2}){2}\.\d{3}Z$/.test(v)) return new Date(v);
	else if (v.charAt(0) !== '{' && v.charAt(v.length - 1) !== '}' && v !== 'null') return v;
	else return JSON.parse(v);
};

function putItem(model, options) {
	options || (options = {});
	var body = {
		TableName: model._tableName(),
		Item: {}
	};
	var changed = {};
	if (!model.id) {
		changed[_.result(model, 'idAttribute')] = uuid();
		model.set(changed);
	}
	_.each(model.toJSON().model, function(v, key) {
		body.Item[key] = encodeAttribute(v);
	});

	_.extend(body, options.dynamodb);
	dyndb.request('PutItem', body, function(e, jsonResponse, httpResponse) {
		if (e && _.isFunction(options.error)) options.error(model, {code: 'DBError', dbError: e});
		else if (!e && _.isFunction(options.success)) options.success({model: changed});

		if (_.isFunction(options.complete)) options.complete(model);
	});
}

function getItem(model, options) {
	options || (options = {});
	var body = {
		TableName: model._tableName(),
		Key: {
			HashKeyElement: encodeAttribute(model.id)
		}
	};
	if (model.rangeAttribute) body.Key.RangeKeyElement = encodeAttribute(model.get(model.rangeAttribute));

	_.extend(body, options.dynamodb);
	dyndb.request('GetItem', body, function(e, jsonResponse, httpResponse) {
		if (e && _.isFunction(options.error)) options.error(model, {code: 'DBError', dbError: e});
		else if (!e) {
			if (!jsonResponse.Item || _.isEmpty(jsonResponse.Item)) options.error(model, {code: 'NotFound'});
			else {
				var json = {};
				_.each(jsonResponse.Item, function(attr, key) {
					json[key] = decodeAttribute(attr);
				});
				if (_.isFunction(options.success)) options.success({model: json});
				else model.set(json, {silent: true});
			}
		}

		if (_.isFunction(options.complete)) options.complete(model);
	});
}

function deleteItem(model, options) {
	options || (options = {});
	var body = {
		TableName: model._tableName(),
		Key: {
			HashKeyElement: encodeAttribute(model.id)
		}
	};
	if (model.rangeAttribute) body.Key.RangeKeyElement = encodeAttribute(model.get(model.rangeAttribute));

	_.extend(body, options.dynamodb);
	dyndb.request('DeleteItem', body, function(e, jsonResponse, httpResponse) {
		if (e && _.isFunction(options.error)) options.error(model, {code: 'DBError', dbError: e});
		else if (!e && _.isFunction(options.success)) options.success(jsonResponse);

		if (_.isFunction(options.complete)) options.complete(model);
	});
}

function fetchCollection(collection, options) {
	var body = _.extend({TableName: collection._tableName()}, options.query || options.scan, options.dynamodb);

	dyndb.request(options.query ? 'Query' : 'Scan', body, function(e, jsonResponse, httpResponse) {
		if (e && _.isFunction(options.error)) options.error(collection, {code: 'DBError', dbError: e});
		else if (!e) {
			var collection = _.map(jsonResponse.Items, function(it) {
				var model = {};
				_.each(it, function(attr, key) {
					model[key] = decodeAttribute(attr);
				});
				return {model: model};
			});

			if (_.isFunction(options.success)) options.success({collection: collection});
			else collection.set(collection, {silent: true});
		}

		if (_.isFunction(options.complete)) options.complete(collection);
	});

}

Backbone.sync = function(method, instance, options) {
	if (method === 'create' || method === 'update') {
		putItem(instance, options);
	} else if (method === 'read') {
		if (instance instanceof Backbone.DynamoDB.Collection) fetchCollection(instance, options);
		else getItem(instance, options);
	} else {
		deleteItem(instance, options);
	}
};

var sharedMethods = {
	_tableName: function() {
		if (this.tableName) return _.result(this, 'tableName');

		var table = _.result(this, this instanceof Backbone.DynamoDB.Model ? 'urlRoot' : 'url');
		if (table.charAt(0) === '/') table = table.substr(1);
		return table.charAt(0).toUpperCase() + table.substr(1);
	}
};

Backbone.DynamoDB.Model = Backbone.DynamoDB.Model.extend(sharedMethods);
Backbone.DynamoDB.Collection = Backbone.DynamoDB.Collection.extend(sharedMethods);

module.exports = Backbone;<commit_msg>Initial project version<commit_after>/*
 *  backbone-dynamodb 0.0.1
 *  (c) 2012 Sergio Alcantara
 */

var _ = require('underscore'),
	uuid = require('node-uuid'),
	DynDB = require('dyndb'),
	Backbone = require('./backbone-dynamodb-shared');

var dyndb = new DynDB();
Backbone.DynamoDB.setup = dyndb.setup;

var encodeAttribute = exports.encodeAttribute = function(v) {
	if (_.isArray(v)) {
		var type = 'N', set = _.map(v, function(i) {
			var j = encodeAttribute(i);
			if (j.S) type = 'S';
			return j.N || j.S;
		});
		return type === 'N' ? {NS: set} : {SS: set};
	} else if (_.isNumber(v)) return {N: '' + v};
	else if (_.isBoolean(v)) return {S: v.toString()};
	else if (_.isDate(v)) return {S: v.toISOString()};
	else if (_.isString(v)) return {S: v};
	else return {S: JSON.stringify(v)};
};

var decodeAttribute = exports.decodeAttribute = function(attr) {
	if (attr.NS || attr.SS) {
		var type = attr.NS ? 'N' : 'S';
		return _.map(attr[type + 'S'], function(v) {
			var _attr = {};
			_attr[type] = v;
			return decodeAttribute(_attr);
		});
	}
	if (attr.N) return /\./.test(attr.N) ? parseFloat(attr.N) : parseInt(attr.N);

	var v = attr.S;
	if (/^true|false$/.test(v)) return v === 'true';
	else if (/^\d{4}(-\d{2}){2}T\d{2}(:\d{2}){2}\.\d{3}Z$/.test(v)) return new Date(v);
	else if (v.charAt(0) !== '{' && v.charAt(v.length - 1) !== '}' && v !== 'null') return v;
	else return JSON.parse(v);
};

function putItem(model, options) {
	options || (options = {});
	var body = {
		TableName: model._tableName(),
		Item: {}
	};
	var changed = {};
	if (!model.id) {
		changed[_.result(model, 'idAttribute')] = uuid();
		model.set(changed);
	}
	_.each(model.toJSON().model, function(v, key) {
		body.Item[key] = encodeAttribute(v);
	});

	_.extend(body, options.dynamodb);
	dyndb.request('PutItem', body, function(e, jsonResponse, httpResponse) {
		if (e && _.isFunction(options.error)) options.error(model, {code: 'DBError', dbError: e});
		else if (!e && _.isFunction(options.success)) options.success({model: changed});

		if (_.isFunction(options.complete)) options.complete(model);
	});
}

function getItem(model, options) {
	options || (options = {});
	var body = {
		TableName: model._tableName(),
		Key: {
			HashKeyElement: encodeAttribute(model.id)
		}
	};
	if (model.rangeAttribute) body.Key.RangeKeyElement = encodeAttribute(model.get(model.rangeAttribute));

	_.extend(body, options.dynamodb);
	dyndb.request('GetItem', body, function(e, jsonResponse, httpResponse) {
		if (e && _.isFunction(options.error)) options.error(model, {code: 'DBError', dbError: e});
		else if (!e) {
			if (!jsonResponse.Item || _.isEmpty(jsonResponse.Item)) options.error(model, {code: 'NotFound'});
			else {
				var json = {};
				_.each(jsonResponse.Item, function(attr, key) {
					json[key] = decodeAttribute(attr);
				});
				if (_.isFunction(options.success)) options.success({model: json});
				else model.set(json, {silent: true});
			}
		}

		if (_.isFunction(options.complete)) options.complete(model);
	});
}

function deleteItem(model, options) {
	options || (options = {});
	var body = {
		TableName: model._tableName(),
		Key: {
			HashKeyElement: encodeAttribute(model.id)
		}
	};
	if (model.rangeAttribute) body.Key.RangeKeyElement = encodeAttribute(model.get(model.rangeAttribute));

	_.extend(body, options.dynamodb);
	dyndb.request('DeleteItem', body, function(e, jsonResponse, httpResponse) {
		if (e && _.isFunction(options.error)) options.error(model, {code: 'DBError', dbError: e});
		else if (!e && _.isFunction(options.success)) options.success(jsonResponse);

		if (_.isFunction(options.complete)) options.complete(model);
	});
}

function fetchCollection(collection, options) {
	var body = _.extend({TableName: collection._tableName()}, options.query || options.scan, options.dynamodb);

	dyndb.request(options.query ? 'Query' : 'Scan', body, function(e, jsonResponse, httpResponse) {
		if (e && _.isFunction(options.error)) options.error(collection, {code: 'DBError', dbError: e});
		else if (!e) {
			var collection = _.map(jsonResponse.Items, function(it) {
				var model = {};
				_.each(it, function(attr, key) {
					model[key] = decodeAttribute(attr);
				});
				return {model: model};
			});

			if (_.isFunction(options.success)) options.success({collection: collection});
			else collection.set(collection, {silent: true});
		}

		if (_.isFunction(options.complete)) options.complete(collection);
	});

}

Backbone.sync = function(method, instance, options) {
	if (method === 'create' || method === 'update') {
		putItem(instance, options);
	} else if (method === 'read') {
		if (instance instanceof Backbone.DynamoDB.Collection) fetchCollection(instance, options);
		else getItem(instance, options);
	} else {
		deleteItem(instance, options);
	}
};

var sharedMethods = {
	_tableName: function() {
		if (this.tableName) return _.result(this, 'tableName');

		var table = _.result(this, this instanceof Backbone.DynamoDB.Model ? 'urlRoot' : 'url');
		if (table.charAt(0) === '/') table = table.substr(1);
		return table.charAt(0).toUpperCase() + table.substr(1);
	}
};

Backbone.DynamoDB.Model = Backbone.DynamoDB.Model.extend(sharedMethods);
Backbone.DynamoDB.Collection = Backbone.DynamoDB.Collection.extend(sharedMethods);

module.exports = Backbone;<|endoftext|>


<commit_before>/**
 * backbone.mediator.js
 *
 * (c) 2012 Aaron Hall
 * This code may be freely distributed under the MIT license.
 */
(function() {
  "use strict";
  /*global Backbone: true */

  var
    root = this,
    _ = root._;

  if (!_ && (typeof require !== 'undefined')) _ = require('underscore', 'backbone');

  // todo: should extend Backbone.Events
  Backbone.Mediator = (function() {
    var director;
    return {
      register: function(d) {
        director = d;
      },

      propagate: function(handler, context, e) {
        if(!director) throw "Backbone.Mediator: no Director registered";

        var
          args = [],
          mediator;

        if(_.isString(handler)) {
          args = e ? [e] : e;
        } else if(_.isArray(handler) && _.isFunction(handler[1])) {
          args = handler[1].call(context, e);
          handler = handler[0];
        } else {
          throw 'Invalid handler structure (must be string or [string, function])';
        }

        mediator = director.handlers[handler];

        if(!director.handlers[handler]) throw 'No handler in Director for "'+handler+'"';

        if(_.isArray(args)) {
          mediator.apply(director, args);
        } else {
          mediator.call(director, args);
        }
      },

      // todo: not tested
      propagateDirect: function(name, handler, context) {
        var formatted = _.isFunction(handler) ? [name, handler] : name;
        this.propagate(formatted, context);
      }
    };
  })();

  /**
   * Director
   */
  Backbone.Director = function() {
    this.initialize.apply(this, arguments);
  };
  _.extend(Backbone.Director.prototype, Backbone.Events, {
    handlers: {},
    initialize: function() {}
  });

  Backbone.Director.extend = Backbone.Mediator.extend = Backbone.View.extend;

  /**
   * MediatedView
   */
  Backbone.MediatedView = Backbone.View.extend({
    delegateEvents: function(events) {
      var
        _super = Backbone.View.prototype.delegateEvents,
        _undelegateEvents = Backbone.View.prototype.undelegateEvents;

      // delegate normal backbone events
      _super.call(this, events);

      if(!this.mediated) return;

      // Hack to be able to reuse super::delegateEvent to bind mediated. The parent method calls
      // undelegateEvents, so in order to reuse it without unsetting the normal events, temporarily
      // make it an empty function.
      Backbone.View.prototype.undelegateEvents = function() {};
      _super.call(this, this.wrapMediated());
      Backbone.View.prototype.undelegateEvents = _undelegateEvents;
    },

    wrapMediated: function() {
      if(!this.mediated) return;

      var
        key,
        eventSplitter = /^(\S+)\s*(.*)$/,
        wrapped = {};

      for(key in this.mediated) {
        wrapped[key] = (function(handler) {
          return function(e) {
            Backbone.Mediator.propagate(handler, this, e);
          };
        })(this.mediated[key]);
      }

      return wrapped;
    },

    mediate: function(name, handler) {
      Backbone.Mediator.propagateDirect(name, handler, this);
    }
  });

  /**
   * MediatedRouter
   */
  Backbone.MediatedRouter = Backbone.Router.extend({
    _bindRoutes: function() {
      // call super
      Backbone.Router.prototype._bindRoutes.call(this);

      Backbone.history || (Backbone.history = new Backbone.History());

      _.each(this.mediated, function(name, route) {
        if (!_.isRegExp(route)) route = this._routeToRegExp(route);

        Backbone.history.route(route, _.bind(function(fragment) {
          var args = this._extractParameters(route, fragment);

          Backbone.Mediator.propagateDirect(name, function() {
            return args;
          });

          Backbone.history.trigger('route', this, name, args);
        }, this));
      }, this);
    }
  });

}).call(this);
<commit_msg>more refactoring<commit_after>/**
 * backbone.mediator.js
 *
 * (c) 2012 Aaron Hall
 * This code may be freely distributed under the MIT license.
 */
(function() {
  "use strict";
  /*global Backbone: true */

  var
    root = this,
    _ = root._;

  if (!_ && (typeof require !== 'undefined')) _ = require('underscore');

  // todo: should extend Backbone.Events
  Backbone.Mediator = (function() {
    var director;
    return {
      register: function(d) {
        director = d;
      },

      signal: function(handler_def, context, e) {
        if(!director) throw new Error("No director registered");
        if(!context) throw new Error("No context provided registered");

        var
          do_mediate = true,
          handler_name,
          args = [],
          mediator;

        if(_.isString(handler_def)) {
          handler_name = handler_def;
          args = e ? [e] : [];
        } else if(_.isArray(handler_def) && _.isFunction(handler_def[1])) {
          handler_name = handler_def[0];
          args = handler_def[1].call(context, e);
        } else if(_.isObject(handler_def) && handler_def.name && handler_def.args) {
          handler_name = handler_def.name;
          if(_.isFunction(handler_def.args)) {
            args = handler_def.args.call(context, e);
          } else {
            args = handler_def.args;
          }
        } else if(_.isFunction(handler_def)) {
          do_mediate = false;
        } else {
          throw 'Invalid handler definition (must be string or [string, function] or hashmap or function)';
        }

        if(do_mediate) {
          mediator = director.getHandler(handler_name);
          if(!mediator) throw 'No handler in Director for "'+handler_def+'"';

          if(_.isArray(args)) {
            mediator.apply(director, args);
          } else {
            mediator.call(director, args);
          }
        } else {
          handler_def.call(context, e);
        }
      }
    };
  })();

  /**
   * Director
   */
  Backbone.Director = function() {
    this.initialize.apply(this, arguments);
  };
  _.extend(Backbone.Director.prototype, Backbone.Events, {
    handlers: {},
    initialize: function() {},

    getHandler: function(name) {
      return this.handlers[name];
    },

    addHandlers: function(handlers) {
      this.handlers = _.extend(this.handlers, handlers);
    }
  });
  Backbone.Director.extend = Backbone.Mediator.extend = Backbone.View.extend;

  /**
   * MediatedView
   */
  Backbone.MediatedView = Backbone.View.extend({
    constructor: function(options) {
      Backbone.View.call(this, options); // todo: make this isn't already called
      this.delegateMediated();
    },

    delegateMediated: function(events) {
      var
        eventSplitter = /^(\S+)\s*(.*)$/;

      if (!(events || (events = this._transformMediated()))) return;
      this.undelegateMediated();
      for (var key in events) {
        var method = events[key];
        var match = key.match(eventSplitter);
        var eventName = match[1], selector = match[2];
        method = _.bind(method, this);
        eventName += '.delegateMediated' + this.cid;
        if (selector === '') {
          this.$el.bind(eventName, method);
        } else {
          this.$el.delegate(selector, eventName, method);
        }
      }
    },

    undelegateMediated: function() {
      this.$el.unbind('.delegateMediated' + this.cid);
    },

    /**
     * Transform each handler definition in this.mediated into a `signal` call to Backbone.Mediator.
     *
     * @return Hash of event names to functions that can be passed directly into Backbone.View.delegateEvents
     */
    _transformMediated: function() {
      var
        key,
        eventSplitter = /^(\S+)\s*(.*)$/,
        wrapped = {};

      for(key in this.mediated) {
        wrapped[key] = (function(handler_def) {
          return function(e) {
            // `this` is this MediatedView instance
            Backbone.Mediator.signal(handler_def, this, e);
          };
        })(this.mediated[key]);
      }

      return wrapped;
    },

    mediate: function(name, handler) {
      Backbone.Mediator.propagateDirect(name, handler, this);
    }
  });

  /**
   * MediatedRouter
   */
  Backbone.MediatedRouter = Backbone.Router.extend({
    _bindRoutes: function() {
      // call super
      Backbone.Router.prototype._bindRoutes.call(this);

      Backbone.history || (Backbone.history = new Backbone.History());

      _.each(this.mediated, function(name, route) {
        if (!_.isRegExp(route)) route = this._routeToRegExp(route);

        Backbone.history.route(route, _.bind(function(fragment) {
          var args = this._extractParameters(route, fragment);

          Backbone.Mediator.signal({
            'name': name,
            'args': args
          }, this);

          Backbone.history.trigger('route', this, name, args);
        }, this));
      }, this);
    }
  });

}).call(this);
<|endoftext|>


<commit_before>// Copyright (C) 2012 Model N, Inc.
// Released under the MIT License
//
// Backbone.SubRoute extends the functionality of Backbone.Router such that each of an application's modules
// can define its own module-specific routes.  This eliminates the need for one monolithic Router configuration,
// The base router can instead act as a simple delegator that forwards module-specific routes to the
// appropriate module-specific SubRoute.
//
// For example, given this URL:
//   http://example.org/myModule/foo/bar
//
// ...the base router would be responsible for invoking and delegating to the proper module based on "myModule".
// The module would then have its own SubRoute which would have its own mappings for the foo/bar part.
//
// This project is based on a Gist by Tim Branyan: https://gist.github.com/1235317

if (!Backbone) {
    throw new Error('Backbone.Subroute: Backbone dependency was not found');
}

Backbone.SubRoute = Backbone.Router.extend( {
    constructor:function ( prefix ) {
        var routes = {};

        // Prefix is optional, set to empty string if not passed
        this.prefix = prefix = prefix || "";

        // Allow for optionally omitting trailing /.  Since base routes do not
        // trigger with a trailing / this is actually kind of important =)
        if ( prefix.substr( -1 ) != "/" ) {
            prefix = prefix + '/';
        }

        // Every route needs to be prefixed
        _.each( this.routes, function ( callback, path ) {
            if ( path ) {
                routes[prefix + path] = callback;
            } else {
                // If the path is "" just set to prefix, this is to comply
                // with how Backbone expects base paths to look gallery vs gallery/
                routes[prefix.substr( 0, prefix.length - 1 )] = callback;
            }
        } );

        // Must override with prefixed routes
        this.routes = routes;

        // Required to have Backbone set up routes
        Backbone.Router.prototype.constructor.call( this );

        // grab the full URL
        var hash = Backbone.history.getHash();

        // check if there is already a part of the URL that this subview cares about...
        var hashPart = hash.substr( prefix.length, hash.length );

        // ...if so, trigger the subroute immediately.  this supports the case where
        // a user directly navigates to a URL with a subroute on the first page load.
        if ( hashPart && hashPart != "" ) {
            Backbone.history.loadUrl( prefix + hashPart );
        }
    },
    navigate:function ( route, options ) {
        if ( route.substr( 0, 1 ) != '/' && route.indexOf( this.prefix.substr( 0,
                this.prefix.length - 1 ) ) != 0 ) {
            route = this.prefix + route;
        }
        Backbone.Router.prototype.navigate.call( this, route, options );
    }
} );

<commit_msg>Added options pass-thru argument<commit_after>// Copyright (C) 2012 Model N, Inc.
// Released under the MIT License
//
// Backbone.SubRoute extends the functionality of Backbone.Router such that each of an application's modules
// can define its own module-specific routes.  This eliminates the need for one monolithic Router configuration,
// The base router can instead act as a simple delegator that forwards module-specific routes to the
// appropriate module-specific SubRoute.
//
// For example, given this URL:
//   http://example.org/myModule/foo/bar
//
// ...the base router would be responsible for invoking and delegating to the proper module based on "myModule".
// The module would then have its own SubRoute which would have its own mappings for the foo/bar part.
//
// This project is based on a Gist by Tim Branyan: https://gist.github.com/1235317

if (!Backbone) {
    throw new Error('Backbone.Subroute: Backbone dependency was not found');
}

Backbone.SubRoute = Backbone.Router.extend( {
    constructor:function ( prefix, options ) {
        var routes = {};

        // Prefix is optional, set to empty string if not passed
        this.prefix = prefix = prefix || "";

        // Allow for optionally omitting trailing /.  Since base routes do not
        // trigger with a trailing / this is actually kind of important =)
        if ( prefix.substr( -1 ) != "/" ) {
            prefix = prefix + '/';
        }

        // Every route needs to be prefixed
        _.each( this.routes, function ( callback, path ) {
            if ( path ) {
                routes[prefix + path] = callback;
            } else {
                // If the path is "" just set to prefix, this is to comply
                // with how Backbone expects base paths to look gallery vs gallery/
                routes[prefix.substr( 0, prefix.length - 1 )] = callback;
            }
        } );

        // Must override with prefixed routes
        this.routes = routes;

        // Required to have Backbone set up routes
        Backbone.Router.prototype.constructor.call( this, options );

        // grab the full URL
        var hash = Backbone.history.getHash();

        // check if there is already a part of the URL that this subview cares about...
        var hashPart = hash.substr( prefix.length, hash.length );

        // ...if so, trigger the subroute immediately.  this supports the case where
        // a user directly navigates to a URL with a subroute on the first page load.
        if ( hashPart && hashPart != "" ) {
            Backbone.history.loadUrl( prefix + hashPart );
        }
    },
    navigate:function ( route, options ) {
        if ( route.substr( 0, 1 ) != '/' && route.indexOf( this.prefix.substr( 0,
                this.prefix.length - 1 ) ) != 0 ) {
            route = this.prefix + route;
        }
        Backbone.Router.prototype.navigate.call( this, route, options );
    }
} );

<|endoftext|>


<commit_before>/*
    Date:
*/
/*
$(document).ready(function() {

    //EDIT THESE LINES
    //Title of the blog
    var TITLE = "Jesse Monroy";
    //RSS url
    var RSS = "http://feedproxy.google.com/RaymondCamdensColdfusionBlog";
    //Stores entries
    var entries = [];
    var selectedEntry = "";

    //listen for detail links
    $(".contentLink").on("click", function() {
        selectedEntry = $(this).data("entryid");
    });

    //Listen for main page
    $("#mainPage").on("pageinit", function() {

        //Set the title
        $("h1", this).text(TITLE);

        $.get(RSS, {}, function(res, code) {
            var xml = $(res);
            var items = xml.find("item");
            $.each(items, function(i, v) {
                entry = {
                    title:$(v).find("title").text(),
                    link:$(v).find("link").text(),
                    description:$.trim($(v).find("description").text())
                };
                entries.push(entry);
            });

            //now draw the list
            var s = '';
            $.each(entries, function(i, v) {
                s += '
' + v.title + '
';
            });
            $("#linksList").append(s);
            $("#linksList").listview("refresh");
        });

    });

    //Listen for the content page to load
    $("#contentPage").on("pageshow", function(prepage) {
        //Set the title
        $("h1", this).text(entries[selectedEntry].title);
        var contentHTML = "";
        contentHTML += entries[selectedEntry].description;
        contentHTML += '
Read Entry on Site';
        $("#entryText",this).html(contentHTML);
    });

});
*/

//EDIT THESE LINES
var AppInfo = {
    // App Title
    TITLE : "Jesse Monroy",
    //RSS url
    RSS : "http://codesnippets.altervista.org/css/default.css"
    //RSS : "https://cordova.apache.org/feed.xml" // "http://feeds.feedburner.com/raymondcamdensblog"
};

var readerApp = {
    self : {},
    init : function () {
        $('#appTitle').html(AppInfo.TITLE);
    },
    get : function() {
        $.get(AppInfo.RSS, function(data, errorCode) {
            console.log("got data");
            alert("got data:" + errorCode);
            xmlDoc = $.parseXML( data ),
            $xml = $( xmlDoc ),
            $title = $xml.find( "title" );
            alert( $title.text() );
        });
    }

}<commit_msg>update<commit_after>/*
    Date:
*/
/*
$(document).ready(function() {

    //EDIT THESE LINES
    //Title of the blog
    var TITLE = "Jesse Monroy";
    //RSS url
    var RSS = "http://feedproxy.google.com/RaymondCamdensColdfusionBlog";
    //Stores entries
    var entries = [];
    var selectedEntry = "";

    //listen for detail links
    $(".contentLink").on("click", function() {
        selectedEntry = $(this).data("entryid");
    });

    //Listen for main page
    $("#mainPage").on("pageinit", function() {

        //Set the title
        $("h1", this).text(TITLE);

        $.get(RSS, {}, function(res, code) {
            var xml = $(res);
            var items = xml.find("item");
            $.each(items, function(i, v) {
                entry = {
                    title:$(v).find("title").text(),
                    link:$(v).find("link").text(),
                    description:$.trim($(v).find("description").text())
                };
                entries.push(entry);
            });

            //now draw the list
            var s = '';
            $.each(entries, function(i, v) {
                s += '
' + v.title + '
';
            });
            $("#linksList").append(s);
            $("#linksList").listview("refresh");
        });

    });

    //Listen for the content page to load
    $("#contentPage").on("pageshow", function(prepage) {
        //Set the title
        $("h1", this).text(entries[selectedEntry].title);
        var contentHTML = "";
        contentHTML += entries[selectedEntry].description;
        contentHTML += '
Read Entry on Site';
        $("#entryText",this).html(contentHTML);
    });

});
*/

//EDIT THESE LINES
var AppInfo = {
    // App Title
    TITLE : "Jesse Monroy",
    //RSS url
    RSS : "http://codesnippets.altervista.org/css/default.css"
    //RSS : "https://cordova.apache.org/feed.xml" // "http://feeds.feedburner.com/raymondcamdensblog"
};

var readerApp = {
    self : {},
    init : function () {
        $('#appTitle').html(AppInfo.TITLE);
    },
    get : function() {
        $.get(AppInfo.RSS, function(data, errorCode) {
            console.log("got data");
            alert("got data:" + data);
        });
    }

}<|endoftext|>


<commit_before>// ==UserScript==
// @id             iitc-plugin-fix-bad-version-code@jonatkins
// @name           IITC plugin: Fix bad version codes
// @category       Tweaks
// @version        0.1.0.@@DATETIMEVERSION@@
// @namespace      https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL      @@UPDATEURL@@
// @downloadURL    @@DOWNLOADURL@@
// @description    [@@BUILDNAME@@-@@BUILDDATE@@] Sometimes Niantic deployments break, causing an old version of the gen_dashboard.js to be served. This has an out-of-date version code. This plugin overrides known bad codes with the one that should be current.
// @include        https://www.ingress.com/intel*
// @include        http://www.ingress.com/intel*
// @match          https://www.ingress.com/intel*
// @match          http://www.ingress.com/intel*
// @grant          none
// ==/UserScript==

// NOTE: non-standard plugin - designed to work with both IITC *and* the standard intel site

// do NOT use as a template for other IITC plugins

var fixUrl = (window.location.protocol!=='https:'?'http://iitc.jonatkins.com':'https://secure.jonatkins.com/iitc')+'/bad-version-code-fix.js';
var script = document.createElement('script');
script.setAttribute('src', fixUrl);
(document.body || document.head || document.documentElement).appendChild(script);
<commit_msg>temporary change to the bad-version plugin, using internal list of fixes rather than externally loaded one let's see if this works better for users...<commit_after>// ==UserScript==
// @id             iitc-plugin-fix-bad-version-code@jonatkins
// @name           IITC plugin: Fix bad version codes
// @category       Tweaks
// @version        0.2.0.@@DATETIMEVERSION@@
// @namespace      https://github.com/jonatkins/ingress-intel-total-conversion
// @updateURL      @@UPDATEURL@@
// @downloadURL    @@DOWNLOADURL@@
// @description    [@@BUILDNAME@@-@@BUILDDATE@@] Sometimes Niantic deployments break, causing an old version of the gen_dashboard.js to be served. This has an out-of-date version code. This plugin overrides known bad codes with the one that should be current.
// @include        https://www.ingress.com/intel*
// @include        http://www.ingress.com/intel*
// @match          https://www.ingress.com/intel*
// @match          http://www.ingress.com/intel*
// @grant          none
// ==/UserScript==

@@PLUGINSTART@@

// PLUGIN START ////////////////////////////////////////////////////////

// use own namespace for plugin
window.plugin.badVersionCodeFix = function() {};

window.plugin.badVersionCodeFix.setup  = function() {

  var fixes = {
    // 2014-08-02 - broken for 24h+
    '81ad679ab5bc219ef3bcf7ca9b760e917cf0c558': 'afdb91368730a906bae38b2837cc411f880350fa',

  };

  var fixed = fixes[nemesis.dashboard.config.CURRENT_VERSION];

  if (fixed) {
    console.warn('IITC VersionCodeFixer: bad nemesis.dashboard.config.CURRENT_VERSION: is '+nemesis.dashboard.config.CURRENT_VERSION+', should be '+fixed);
    nemesis.dashboard.config.CURRENT_VERSION = fixed;
  } else {
    console.log('IITC VersionCodeFixer: no known fixes needed');
  }

};

var setup =  window.plugin.badVersionCodeFix.setup;

// PLUGIN END //////////////////////////////////////////////////////////

@@PLUGINEND@@
<|endoftext|>