<commit_before>import React, { Component } from 'react'
import './index.css'
import axios from 'axios'
import _ from 'lodash'
import {
  CellMeasurer,
  CellMeasurerCache,
  createMasonryCellPositioner,
  Masonry,
  AutoSizer
} from 'react-virtualized';

const blacklistSubcategories = [
  "Monster Battle",
  "Skill Effect",
  "Pet Use",
  "Test Armor",
  "Test Weapon",
  "Shovel",
  "Pickaxe",
  "Totem"
]

const cellMeasurerCache = new CellMeasurerCache({
  defaultHeight: 32,
  defaultWidth: 32,
  fixedWidth: true
})

const itemListPromise = axios.get('https://labs.maplestory.io/api/gms/latest/item/category/equip');

class ItemListing extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [],
      categories: {},
      categoryNames: {},
      selectedCategory: null,
      search: '',
      gutterSize: 6,
      columnWidth: 32,
      categoryNameSelected: '',
      selectedGender: '',
      cashItemsOnly: false,
      similarItems: null
    }

    this._cache = cellMeasurerCache

    itemListPromise.then(response => {
      if(response.status === 200) {
        const categories = _.mapValues(
          _.groupBy(
            response.data
              .filter(item => item.Id < 10000 || item.Id > 50000)
              .concat(
                _.map(
                  _.groupBy(
                    response.data.filter(item => item.Id >= 30000 && item.Id <= 60000),
                    item => Math.floor(item.Id / 10)
                  ), itemGrouping => {
                    const firstItem = itemGrouping[0]
                    firstItem.similar = itemGrouping
                    return firstItem
                  }
                )
              )
              .concat(
                _.map(
                  _.groupBy(
                    response.data.filter(item => item.Id >= 10000 && item.Id < 30000),
                    item => (item.Id % 100) + (item.Id - (item.Id % 1000))
                  ), itemGrouping => {
                    const firstItem = itemGrouping[0]
                    firstItem.similar = itemGrouping
                    return firstItem
                  }
                )
              ),
            item => item.TypeInfo.Category),
          items => _.groupBy(items, item => item.TypeInfo.SubCategory)
        );

        const categoryNames = _.mapValues(categories, _.keys);

        this.setState({
          items: response.data,
          categories,
          categoryNames
        })
      }
    })
  }

  render() {
    const { categoryNames, selectedCategory, items, categoryNameSelected, cashItemsOnly, selectedGender, similarItems } = this.state
    const search = this.state.search.toLowerCase()

    if (search) console.log(`Searching for ${search}`)
    this.showIcons = !search ? (selectedCategory || items) : items.filter((item, i) => {
      return (item.Name || '').toLowerCase().indexOf(search) !== -1 ||
        item.Id.toString().toLowerCase().indexOf(search) !== -1 ||
        (item.desc || '').toLowerCase().indexOf(search) !== -1
    })

    if (cashItemsOnly)
      this.showIcons = this.showIcons.filter(item => item.IsCash)

    if (selectedGender)
      this.showIcons = this.showIcons.filter(c => c.RequiredGender == selectedGender);

    this.showIcons = this.showIcons.filter(item => item && item.Id)

    return (

          <input type="search" value={search} onChange={this.search.bind(this)} placeholder="Search.." className="item-search"/>

            <input type="checkbox" onChange={this.toggleCashItems.bind(this)} checked={this.cashItemsOnly} />
            Cash Only

          <select onChange={this.changeGender.bind(this)} value={this.selectedGender} className="gender-select">
            <option value="">Gender Filter</option>
            <option value="0">Male</option>
            <option value="1">Female</option>
            <option value="2">Universal</option>
          </select>

          {
            _.map(categoryNames, (subCategories, category) => {
              return (

              {category}

                {
                  subCategories.filter(categoryName => blacklistSubcategories.indexOf(categoryName) === -1).map(subCategory =>

                      {subCategory}

)
                }

)
            })
          }

            { similarItems &&

                { similarItems.item.similar.map((item) => this.containedItemIcon(item, true)) }

            }
            { this._renderAutoSizer({ height: 32 }) }

    )
  }

  onSimilarScroll(e) {
    var masonry = document.getElementsByClassName("ReactVirtualized__Masonry")[0]
    masonry.scrollTop += e.deltaY
    this.mouseOutSimilar()
  }

  mouseOutSimilar() {
    this.setState({ similarItems: null })
  }

  toggleCashItems (e) {
    this.setState({ cashItemsOnly: e.target.checked })
  }

  changeGender (e) {
    this.setState({ selectedGender: e.target.value })
  }

  _renderAutoSizer ({ height }) {
    this._height = height || 32

    return (
      <AutoSizer
        onResize={this._onResize.bind(this)}
      >
        {this._renderMasonry.bind(this)}
      </AutoSizer>
    )
  }

  _renderMasonry({ height, width }) {
    this._width = width
    this._height = height

    this._calculateColumnCount()
    this._initCellPositioner()

    return <Masonry
      cellCount={this.showIcons.length - 1}
      cellMeasurerCache={cellMeasurerCache}
      cellPositioner={this._cellPositioner}
      cellRenderer={this.cellRenderer.bind(this)}
      ref={this._setMasonryRef.bind(this)}
      width={width}
      height={this._height}
      />
  }

  _calculateColumnCount () {
    const {
      columnWidth,
      gutterSize
    } = this.state

    this._columnCount = Math.floor(this._width / (columnWidth + gutterSize))
  }

  _initCellPositioner () {
    if (typeof this._cellPositioner === 'undefined') {
      const {
        columnWidth,
        gutterSize
      } = this.state

      this._cellPositioner = createMasonryCellPositioner({
        cellMeasurerCache: this._cache,
        columnCount: this._columnCount,
        columnWidth,
        spacer: gutterSize
      })
    }
  }

  _onResize ({ height, width }) {
    this._width = width

    this._columnHeights = {}
    this._calculateColumnCount()
    this._resetCellPositioner()
    this._masonry.recomputeCellPositions()
  }

  _resetCellPositioner () {
    const {
      columnWidth,
      gutterSize
    } = this.state

    this._cellPositioner.reset({
      columnCount: this._columnCount,
      columnWidth,
      spacer: gutterSize
    })
  }

  _setMasonryRef (ref) {
    this._masonry = ref
  }

  cellRenderer ({ index, key, parent, style }) {
    const item = this.showIcons[index]
    const { showSimilarTo } = this.state

    if (!item) return

    return (
      <CellMeasurer
        cache={cellMeasurerCache}
        index={index}
        key={item.Id}
        parent={parent}
      >

          { this.itemIcon(item, this.state.search) }

      </CellMeasurer>
    )
  }

  containedItemIcon(item, hideSimilar) {
    return (

        { this.itemIcon(item, hideSimilar) }

    )
  }

  itemIcon(item, hideSimilar) {
    return (<img
      src={`https://labs.maplestory.io/api/gms/latest/item/${item.Id}/icon`}
      onClick={this.selectItem.bind(this, item)}
      alt={item.Name}
      title={item.Name}
      id={item.Id}
      key={item.Id}
      onMouseOver={!hideSimilar && item.similar ? this.showSimilar.bind(this, item) : false} />)
  }

  showSimilar(item) {
    const iconImg = document.getElementById(item.Id).parentElement
    const masonryContainer = document.getElementsByClassName("ReactVirtualized__Masonry")[0]
    this.setState({
      similarItems: {
        item,
        x: iconImg.offsetLeft + masonryContainer.offsetLeft,
        y: iconImg.offsetTop + masonryContainer.offsetTop - iconImg.parentElement.parentElement.scrollTop
      }
    })
  }

  search(e) {
    this.setState({
      search: e.target.value
    })
  }

  selectPrimaryCategory(primaryCategory, proxy, e) {
    const selectedCategory = _.flatMap(_.values(this.state.categories[primaryCategory], a => a))
    this.selectCategory(selectedCategory, primaryCategory)
    proxy.preventDefault()
    proxy.stopPropagation()
  }

  selectChildCategory(primaryCategory, childCategory, proxy, e) {
    const selectedCategory = this.state.categories[primaryCategory][childCategory]
    this.selectCategory(selectedCategory, childCategory)
    proxy.preventDefault()
    proxy.stopPropagation()
  }

  selectCategory(selectedCategory, categoryNameSelected) {
    console.log(`Selected category: ${categoryNameSelected}`)
    this.setState({
      selectedCategory,
      categoryNameSelected,
      search: ''
    })
  }

  selectItem(item){
    this.props.onItemSelected(item)
  }
}

export default ItemListing
<commit_msg>Poll was rigged, should've been no<commit_after>import React, { Component } from 'react'
import './index.css'
import axios from 'axios'
import _ from 'lodash'
import {
  CellMeasurer,
  CellMeasurerCache,
  createMasonryCellPositioner,
  Masonry,
  AutoSizer
} from 'react-virtualized';

const blacklistSubcategories = [
  "Monster Battle",
  "Skill Effect",
  "Pet Use",
  "Test Armor",
  "Test Weapon",
  "Shovel",
  "Pickaxe",
  "Totem"
]

const cellMeasurerCache = new CellMeasurerCache({
  defaultHeight: 32,
  defaultWidth: 32,
  fixedWidth: true
})

const itemListPromise = axios.get('https://labs.maplestory.io/api/gms/latest/item/category/equip');

class ItemListing extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [],
      categories: {},
      categoryNames: {},
      selectedCategory: null,
      search: '',
      gutterSize: 6,
      columnWidth: 32,
      categoryNameSelected: '',
      selectedGender: '',
      cashItemsOnly: false,
      similarItems: null
    }

    this._cache = cellMeasurerCache

    itemListPromise.then(response => {
      if(response.status === 200) {
        const categories = _.mapValues(
          _.groupBy(
            response.data
              .filter(item => item.Id < 10000 || item.Id > 50000)
              .concat(
                _.map(
                  _.groupBy(
                    response.data.filter(item => item.Id >= 30000 && item.Id <= 60000),
                    item => Math.floor(item.Id / 10)
                  ), itemGrouping => {
                    const firstItem = itemGrouping[0]
                    firstItem.similar = itemGrouping
                    return firstItem
                  }
                )
              )
              .concat(
                _.map(
                  _.groupBy(
                    response.data.filter(item => item.Id >= 10000 && item.Id < 30000),
                    item => (item.Id % 100) + (item.Id - (item.Id % 1000))
                  ), itemGrouping => {
                    const firstItem = itemGrouping[0]
                    firstItem.similar = itemGrouping
                    return firstItem
                  }
                )
              ),
            item => item.TypeInfo.Category),
          items => _.groupBy(items, item => item.TypeInfo.SubCategory)
        );

        const categoryNames = _.mapValues(categories, _.keys);
        const categoryNamesKeys = _.keys(categoryNames).filter((categoryName) => categoryName != 'Character');
        categoryNamesKeys.unshift('Character');

        this.setState({
          items: response.data,
          categories,
          categoryNames,
          categoryNamesKeys
        })
      }
    })
  }

  render() {
    const { categoryNames, categoryNamesKeys, selectedCategory, items, categoryNameSelected, cashItemsOnly, selectedGender, similarItems } = this.state
    const search = this.state.search.toLowerCase()

    if (search) console.log(`Searching for ${search}`)
    this.showIcons = !search ? (selectedCategory || items) : items.filter((item, i) => {
      return (item.Name || '').toLowerCase().indexOf(search) !== -1 ||
        item.Id.toString().toLowerCase().indexOf(search) !== -1 ||
        (item.desc || '').toLowerCase().indexOf(search) !== -1
    })

    if (cashItemsOnly)
      this.showIcons = this.showIcons.filter(item => item.IsCash)

    if (selectedGender)
      this.showIcons = this.showIcons.filter(c => c.RequiredGender == selectedGender);

    this.showIcons = this.showIcons.filter(item => item && item.Id)

    return (

          <input type="search" value={search} onChange={this.search.bind(this)} placeholder="Search.." className="item-search"/>

            <input type="checkbox" onChange={this.toggleCashItems.bind(this)} checked={this.cashItemsOnly} />
            Cash Only

          <select onChange={this.changeGender.bind(this)} value={this.selectedGender} className="gender-select">
            <option value="">Gender Filter</option>
            <option value="0">Male</option>
            <option value="1">Female</option>
            <option value="2">Universal</option>
          </select>

          {
            _.map(categoryNamesKeys, category => {
              const subCategories = categoryNames[category];
              return (

              {category}

                {
                  subCategories.filter(categoryName => blacklistSubcategories.indexOf(categoryName) === -1).map(subCategory =>

                      {subCategory}

)
                }

)
            })
          }

            { similarItems &&

                { similarItems.item.similar.map((item) => this.containedItemIcon(item, true)) }

            }
            { this._renderAutoSizer({ height: 32 }) }

    )
  }

  onSimilarScroll(e) {
    var masonry = document.getElementsByClassName("ReactVirtualized__Masonry")[0]
    masonry.scrollTop += e.deltaY
    this.mouseOutSimilar()
  }

  mouseOutSimilar() {
    this.setState({ similarItems: null })
  }

  toggleCashItems (e) {
    this.setState({ cashItemsOnly: e.target.checked })
  }

  changeGender (e) {
    this.setState({ selectedGender: e.target.value })
  }

  _renderAutoSizer ({ height }) {
    this._height = height || 32

    return (
      <AutoSizer
        onResize={this._onResize.bind(this)}
      >
        {this._renderMasonry.bind(this)}
      </AutoSizer>
    )
  }

  _renderMasonry({ height, width }) {
    this._width = width
    this._height = height

    this._calculateColumnCount()
    this._initCellPositioner()

    return <Masonry
      cellCount={this.showIcons.length - 1}
      cellMeasurerCache={cellMeasurerCache}
      cellPositioner={this._cellPositioner}
      cellRenderer={this.cellRenderer.bind(this)}
      ref={this._setMasonryRef.bind(this)}
      width={width}
      height={this._height}
      />
  }

  _calculateColumnCount () {
    const {
      columnWidth,
      gutterSize
    } = this.state

    this._columnCount = Math.floor(this._width / (columnWidth + gutterSize))
  }

  _initCellPositioner () {
    if (typeof this._cellPositioner === 'undefined') {
      const {
        columnWidth,
        gutterSize
      } = this.state

      this._cellPositioner = createMasonryCellPositioner({
        cellMeasurerCache: this._cache,
        columnCount: this._columnCount,
        columnWidth,
        spacer: gutterSize
      })
    }
  }

  _onResize ({ height, width }) {
    this._width = width

    this._columnHeights = {}
    this._calculateColumnCount()
    this._resetCellPositioner()
    this._masonry.recomputeCellPositions()
  }

  _resetCellPositioner () {
    const {
      columnWidth,
      gutterSize
    } = this.state

    this._cellPositioner.reset({
      columnCount: this._columnCount,
      columnWidth,
      spacer: gutterSize
    })
  }

  _setMasonryRef (ref) {
    this._masonry = ref
  }

  cellRenderer ({ index, key, parent, style }) {
    const item = this.showIcons[index]
    const { showSimilarTo } = this.state

    if (!item) return

    return (
      <CellMeasurer
        cache={cellMeasurerCache}
        index={index}
        key={item.Id}
        parent={parent}
      >

          { this.itemIcon(item, this.state.search) }

      </CellMeasurer>
    )
  }

  containedItemIcon(item, hideSimilar) {
    return (

        { this.itemIcon(item, hideSimilar) }

    )
  }

  itemIcon(item, hideSimilar) {
    return (<img
      src={`https://labs.maplestory.io/api/gms/latest/item/${item.Id}/icon`}
      onClick={this.selectItem.bind(this, item)}
      alt={item.Name}
      title={item.Name}
      id={item.Id}
      key={item.Id}
      onMouseOver={!hideSimilar && item.similar ? this.showSimilar.bind(this, item) : false} />)
  }

  showSimilar(item) {
    const iconImg = document.getElementById(item.Id).parentElement
    const masonryContainer = document.getElementsByClassName("ReactVirtualized__Masonry")[0]
    this.setState({
      similarItems: {
        item,
        x: iconImg.offsetLeft + masonryContainer.offsetLeft,
        y: iconImg.offsetTop + masonryContainer.offsetTop - iconImg.parentElement.parentElement.scrollTop
      }
    })
  }

  search(e) {
    this.setState({
      search: e.target.value
    })
  }

  selectPrimaryCategory(primaryCategory, proxy, e) {
    const selectedCategory = _.flatMap(_.values(this.state.categories[primaryCategory], a => a))
    this.selectCategory(selectedCategory, primaryCategory)
    proxy.preventDefault()
    proxy.stopPropagation()
  }

  selectChildCategory(primaryCategory, childCategory, proxy, e) {
    const selectedCategory = this.state.categories[primaryCategory][childCategory]
    this.selectCategory(selectedCategory, childCategory)
    proxy.preventDefault()
    proxy.stopPropagation()
  }

  selectCategory(selectedCategory, categoryNameSelected) {
    console.log(`Selected category: ${categoryNameSelected}`)
    this.setState({
      selectedCategory,
      categoryNameSelected,
      search: ''
    })
  }

  selectItem(item){
    this.props.onItemSelected(item)
  }
}

export default ItemListing
<|endoftext|>


<commit_before>/* eslint-disable no-unused-expressions */
import React from 'react'
import { expect } from 'chai'
import { shallowWithIntl } from '~root/intl/helpers'

import { ControlButtons } from '~client/components/forms/control-buttons'

describe('client/components/forms/control-buttons', () => {
  let wrapper
  const context = { $formRedux: { floatButton: '', successMessage: 'Foo Bar!' } }
  const props = {
    submitting: false,
    submitted: false,
    dirty: false,
    valid: false
  }

  describe('default', () => {
    beforeAll(() => {
      wrapper = shallowWithIntl(<ControlButtons {...props} />, { context })
    })
    it('should render buttons without form inline style', () => {
      expect(wrapper.find('.control-buttons').props().className).to.have.string('flex')
    })
    it('should render submit button as disabled', () => {
      expect(wrapper.find('input[type="submit"]').props().disabled).to.be.true
    })
    it('should render submit button with its text as "Continuar"', () => {
      expect(wrapper.find('input[type="submit"]').props().value).to.equal('Continuar')
    })
    it('should not render form submit success message', () => {
      expect(wrapper.find('.success-message')).to.have.length(0)
    })
  })

  describe('with cancel button', () => {
    beforeAll(() => {
      wrapper = shallowWithIntl(<ControlButtons {...{ ...props }} />, { context })
    })
    it('should render cancel button when pass onCancel', () => {
      let called
      wrapper.setProps({ onCancel: () => { called = true } })
      expect(wrapper.find('button')).to.have.length(1)

      wrapper.find('button').simulate('click')
      expect(called).to.equal(true)
    })
  })

  describe('with form inline style', () => {
    beforeAll(() => {
      wrapper = shallowWithIntl(<ControlButtons {...{ ...props, formInline: true }} />, { context })
    })
    it('should render buttons with form inline style', () => {
      expect(wrapper.find('.control-buttons').props().className).to.have.string('inline-block')
    })
  })

  describe('with submitting status', () => {
    beforeAll(() => {
      wrapper = shallowWithIntl(<ControlButtons {...{ ...props, submitting: true }} />, { context })
    })
    it('should render submit button with its text as "Salvando..."', () => {
      expect(wrapper.find('input[type="submit"]').props().value).to.equal('Salvando...')
    })
    it('should render submit button as disabled', () => {
      expect(wrapper.find('input[type="submit"]').props().disabled).to.be.true
    })
  })

  describe('with submitted status', () => {
    beforeAll(() => {
      wrapper = shallowWithIntl(<ControlButtons {...{ ...props, submitted: true }} />, { context })
    })
    it('should render form submit success message', () => {
      expect(wrapper.find('.success-message')).to.have.length(1)
    })
    it('should render submit button with its text as "Continuar"', () => {
      expect(wrapper.find('input[type="submit"]').props().value).to.equal('Continuar')
    })
    it('should render submit button as disabled', () => {
      expect(wrapper.find('input[type="submit"]').props().disabled).to.be.true
    })
  })

  describe('with dirty status', () => {
    beforeAll(() => {
      wrapper = shallowWithIntl(<ControlButtons {...{ ...props, dirty: true, valid: true }} />, { context })
    })
    it('should render submit button as enabled', () => {
      expect(wrapper.find('input[type="submit"]').props().disabled).to.be.false
    })
  })
})
<commit_msg>chore(tests): Update text expected from buttons<commit_after>/* eslint-disable no-unused-expressions */
import React from 'react'
import { expect } from 'chai'
import { shallowWithIntl } from '~root/intl/helpers'

import { ControlButtons } from '~client/components/forms/control-buttons'

describe('client/components/forms/control-buttons', () => {
  let wrapper
  const context = { $formRedux: { floatButton: '', successMessage: 'Foo Bar!' } }
  const props = {
    submitting: false,
    submitted: false,
    dirty: false,
    valid: false
  }

  describe('default', () => {
    beforeAll(() => {
      wrapper = shallowWithIntl(<ControlButtons {...props} />, { context })
    })
    it('should render buttons without form inline style', () => {
      expect(wrapper.find('.control-buttons').props().className).to.have.string('flex')
    })
    it('should render submit button as disabled', () => {
      expect(wrapper.find('input[type="submit"]').props().disabled).to.be.true
    })
    it('should render submit button with its text as "Próxima parada"', () => {
      expect(wrapper.find('input[type="submit"]').props().value).to.equal('Próxima parada')
    })
    it('should not render form submit success message', () => {
      expect(wrapper.find('.success-message')).to.have.length(0)
    })
  })

  describe('with cancel button', () => {
    beforeAll(() => {
      wrapper = shallowWithIntl(<ControlButtons {...{ ...props }} />, { context })
    })
    it('should render cancel button when pass onCancel', () => {
      let called
      wrapper.setProps({ onCancel: () => { called = true } })
      expect(wrapper.find('button')).to.have.length(1)

      wrapper.find('button').simulate('click')
      expect(called).to.equal(true)
    })
  })

  describe('with form inline style', () => {
    beforeAll(() => {
      wrapper = shallowWithIntl(<ControlButtons {...{ ...props, formInline: true }} />, { context })
    })
    it('should render buttons with form inline style', () => {
      expect(wrapper.find('.control-buttons').props().className).to.have.string('inline-block')
    })
  })

  describe('with submitting status', () => {
    beforeAll(() => {
      wrapper = shallowWithIntl(<ControlButtons {...{ ...props, submitting: true }} />, { context })
    })
    it('should render submit button with its text as "Salvando..."', () => {
      expect(wrapper.find('input[type="submit"]').props().value).to.equal('Salvando...')
    })
    it('should render submit button as disabled', () => {
      expect(wrapper.find('input[type="submit"]').props().disabled).to.be.true
    })
  })

  describe('with submitted status', () => {
    beforeAll(() => {
      wrapper = shallowWithIntl(<ControlButtons {...{ ...props, submitted: true }} />, { context })
    })
    it('should render form submit success message', () => {
      expect(wrapper.find('.success-message')).to.have.length(1)
    })
    it('should render submit button with its text as "Próxima parada"', () => {
      expect(wrapper.find('input[type="submit"]').props().value).to.equal('Próxima parada')
    })
    it('should render submit button as disabled', () => {
      expect(wrapper.find('input[type="submit"]').props().disabled).to.be.true
    })
  })

  describe('with dirty status', () => {
    beforeAll(() => {
      wrapper = shallowWithIntl(<ControlButtons {...{ ...props, dirty: true, valid: true }} />, { context })
    })
    it('should render submit button as enabled', () => {
      expect(wrapper.find('input[type="submit"]').props().disabled).to.be.false
    })
  })
})
<|endoftext|>


<commit_before>import React from 'react'
import _ from 'lodash'
export default React.createClass({
  render: function () {
    let s = _.assign({}, this.props.style, {marginLeft: -8, marginBottom: -16, marginRight: -24})
    return (

 {
        evt.stopPropagation()
      }}>
        <svg xmlns="http://www.w3.org/2000/svg"
             width="32" height="32" viewBox="0 0 32 32" fill="red"
             aria-labelledby="title">
          <title>marker</title>
          <defs>
            <filter id="pressed" x="0" y="0" width="150%" height="150%">
              <feOffset result="offOut" in="SourceAlpha" dx="1" dy="1"/>
              <feGaussianBlur result="blurOut" in="offOut" stdDeviation="1"/>
              <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
            </filter>
            <filter id="unpressed" x="0" y="0" width="150%" height="150%">
              <feOffset result="offOut" in="SourceAlpha" dx="3" dy="3"/>
              <feGaussianBlur result="blurOut" in="offOut" stdDeviation="2"/>
              <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
            </filter>
            <path id="up-pressed" filter="url(#pressed)" d="M 8 0 L 16 16 L 0 16 z"></path>
            <path id="down-pressed" filter="url(#pressed)" d="M 0 0 L 16 0 L 8 16 z"></path>
            <path id="up-unpressed" filter="url(#unpressed)" d="M 8 0 L 16 16 L 0 16 z"></path>
            <path id="down-unpressed" filter="url(#unpressed)" d="M 0 0 L 16 0 L 8 16 z"></path>
          </defs>
          <use xlinkHref={(this.props.down ? '#down-' : '#up-') + (this.props.pressed ? 'pressed' : 'unpressed')}
               onClick={(evt)=> {
                 this.props.onClick(evt, this)
               }} style={{cursor: 'pointer'}}></use>
        </svg>

    )
  }
})
<commit_msg>applied draggable mixin to marker<commit_after>import React from 'react'
import _ from 'lodash'
import Draggable from '../../mixins/draggable'
export default React.createClass({
  mixins: [Draggable(function () {
      return [this]
    }, function (e) {
      return {
        x: 0,
        y: 0
      }
    },
    function (e, x, y) {
      this.props.updateMarkerPosition()
    }, function (e, x, y) {
      this.props.updateMarkerPosition()
    })],

  getInitialState: function () {
    return {draggable: true}
  },
  componentWillMount: function () {
    this.mouseDownHdlrs = []
  },
  onMouseDown: function () {
    this.mouseDownHdlrs.forEach(e=>e.apply(this, arguments))
  },
  render: function () {
    let s = _.assign({}, this.props.style, {marginLeft: -8, marginBottom: -16, marginRight: -24})
    return (

 {
        evt.stopPropagation()
      }}>
        <svg xmlns="http://www.w3.org/2000/svg"
             width="32" height="32" viewBox="0 0 32 32" fill="red"
             aria-labelledby="title">
          <title>marker</title>
          <defs>
            <filter id="pressed" x="0" y="0" width="150%" height="150%">
              <feOffset result="offOut" in="SourceAlpha" dx="1" dy="1"/>
              <feGaussianBlur result="blurOut" in="offOut" stdDeviation="1"/>
              <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
            </filter>
            <filter id="unpressed" x="0" y="0" width="150%" height="150%">
              <feOffset result="offOut" in="SourceAlpha" dx="3" dy="3"/>
              <feGaussianBlur result="blurOut" in="offOut" stdDeviation="2"/>
              <feBlend in="SourceGraphic" in2="blurOut" mode="normal"/>
            </filter>
            <path id="up-pressed" filter="url(#pressed)" d="M 8 0 L 16 16 L 0 16 z"></path>
            <path id="down-pressed" filter="url(#pressed)" d="M 0 0 L 16 0 L 8 16 z"></path>
            <path id="up-unpressed" filter="url(#unpressed)" d="M 8 0 L 16 16 L 0 16 z"></path>
            <path id="down-unpressed" filter="url(#unpressed)" d="M 0 0 L 16 0 L 8 16 z"></path>
          </defs>
          <use xlinkHref={(this.props.down ? '#down-' : '#up-') + (this.props.pressed ? 'pressed' : 'unpressed')}
               onMouseDown={this.onMouseDown}
               onClick={(evt)=> {
                 this.props.onClick(evt, this)
               }} style={{cursor: 'pointer'}}></use>
        </svg>

    )
  }
})
<|endoftext|>


<commit_before>var path = require('path');
var should = require('should');

var IndexFileStream = require('../lib/gulp-index-file-stream');

describe('gulp-index-file-stream', function() {
  var indexStatic = {
    URLS: ['/', '/foo/'],
    generate: function(url, options, cb) {
      options.should.eql({});
      process.nextTick(function() {
        cb('i am ' + url);
      });
    }
  };

  it('should be cool', function(done) {
    var stream = new IndexFileStream(indexStatic);
    var files = [];
    stream.on('data', function(file) {
      files.push({
        path: '/' + path.relative(file.base, file.path)
          .split(path.sep).join('/'),
        contents: file.contents.toString('utf8')
      });
    });
    stream.on('end', function() {
      files.should.eql([{
        path: '/index.html',
        contents: 'i am /'
      }, {
        path: '/foo/index.html',
        contents: 'i am /foo/'
      }]);
      done();
    });
  });
});
<commit_msg>rename test.<commit_after>var path = require('path');
var should = require('should');

var IndexFileStream = require('../lib/gulp-index-file-stream');

describe('gulp-index-file-stream', function() {
  var indexStatic = {
    URLS: ['/', '/foo/'],
    generate: function(url, options, cb) {
      options.should.eql({});
      process.nextTick(function() {
        cb('i am ' + url);
      });
    }
  };

  it('should emit Vinyl file objects', function(done) {
    var stream = new IndexFileStream(indexStatic);
    var files = [];
    stream.on('data', function(file) {
      files.push({
        path: '/' + path.relative(file.base, file.path)
          .split(path.sep).join('/'),
        contents: file.contents.toString('utf8')
      });
    });
    stream.on('end', function() {
      files.should.eql([{
        path: '/index.html',
        contents: 'i am /'
      }, {
        path: '/foo/index.html',
        contents: 'i am /foo/'
      }]);
      done();
    });
  });
});
<|endoftext|>


<commit_before>/**
 * New Relic agent configuration.
 *
 * See lib/config.defaults.js in the agent distribution for a more complete
 * description of configuration variables and their potential values.
 */
exports.config = {
  /**
   * Array of application names.
   */
  app_name : ['cyclon.p2p Signalling server'],
  /**
   * Your New Relic license key.
   */
  license_key : 'set-using-environment-variables',
  logging : {
    /**
     * Level at which to log. 'trace' is most useful to New Relic when diagnosing
     * issues with the agent, 'info' and higher will impose the least overhead on
     * production applications.
     */
    level : 'info'
  }
};
<commit_msg>Get rid of newrelic config<commit_after><|endoftext|>


<commit_before>'use strict';
/* jshint camelcase: false */

var config = require('./config');
var gulp = require('gulp');

/**
 * Dev Task File
 *
 */

var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var sourcemaps = require('gulp-sourcemaps');
var wiredep = require('wiredep').stream;
var inj = require('gulp-inject');

var browserSync = require('browser-sync');
var reload = browserSync.reload;
var watch = require('gulp-watch');
var runSequence = require('run-sequence').use(gulp);

var jshint = require('gulp-jshint');
var jscs = require('gulp-jscs');
var karma = require('gulp-karma');

function swallowError(error)
{
    console.log(error.toString());
    this.emit('end');
}

// main task
gulp.task('default', function ()
{
    runSequence(
        'injectAll',
        'buildStyles',
        'test',
        'browserSync',
        'watch'
    );
});
gulp.task('serve', ['default']);
gulp.task('server', ['default']);

gulp.task('injectAll', function (callback)
{
    runSequence(
        'wiredep',
        'injectScripts',
        'injectStyles',
        callback
    );
});

gulp.task('watch', function ()
{
    watch(config.stylesF, function ()
    {
        gulp.start('buildStyles');
    });
    watch(config.scriptsF, function ()
    {
        gulp.start('injectScripts');
    });
    watch(config.scriptsAllF, function ()
    {
        gulp.start('lint');
    });

    watch(config.allHtmlF, function ()
    {
        gulp.start('html');
    });

    gulp.watch('bower.json', ['wiredep']);
});

gulp.task('buildStyles', function ()
{
    runSequence(
        'injectStyles',
        'sass'
    );
});

gulp.task('injectStyles', function ()
{
    var sources = gulp.src(config.stylesF, {read: false});
    var target = gulp.src(config.mainSassFile);
    var outputFolder = gulp.dest(config.styles);

    target
        .pipe(inj(sources,
            {
                starttag: '// inject:sass',
                endtag: '// endinject',
                ignorePath: [config.base.replace('./', ''), 'styles'],
                relative: true,
                addRootSlash: false,
                transform: function (filepath)
                {
                    if (filepath) {
                        return '@import  \'' + filepath + '\';';
                    }
                }
            }
        ))
        .pipe(outputFolder);
});

gulp.task('injectScripts', function ()
{
    var sources = gulp.src(config.scriptsF, {read: false});
    var target = gulp.src(config.mainFile);
    target
        .pipe(inj(sources,
            {
                ignorePath: config.base.replace('./', ''),
                addRootSlash: false
            }
        ))
        .pipe(gulp.dest(config.base));
});

gulp.task('sass', function ()
{
    var sources = gulp.src(config.mainSassFile);
    var outputFolder = gulp.dest(config.styles);

    sources
        .pipe(sourcemaps.init())
        .pipe(sass())
        .pipe(autoprefixer({
            browsers: ['last 2 versions']
        }))
        .pipe(sourcemaps.write())
        .pipe(outputFolder)
        .pipe(reload({stream: true}))
        .on('error', swallowError)
});

gulp.task('browserSync', function ()
{
    browserSync({
        server: {
            baseDir: config.base,
            livereload: true
        }
    });
});

gulp.task('html', function ()
{
    gulp.src(config.allHtmlF)
        .pipe(reload({stream: true}));
});

gulp.task('wiredep', function ()
{
    gulp.src([config.mainFile], {base: './'})
        .pipe(wiredep({
            devDependencies: false
        }))
        .pipe(gulp.dest('./'))
        .pipe(reload({stream: true}));

    gulp.src([config.karmaConf], {base: './'})
        .pipe(wiredep({
            devDependencies: true
        }))
        .pipe(gulp.dest('./'));
});

gulp.task('test', function ()
{
    // Be sure to return the stream
    gulp.src('.nonononoNOTHING')
        .pipe(karma({
            configFile: './karma.conf.js',
            action: 'watch'
        }))
        .on('error', function (err)
        {
            throw err;
        })
        .on('error', swallowError);
});

gulp.task('testSingle', function ()
{
    // Be sure to return the stream
    gulp.src('.nonononoNOTHING')
        .pipe(karma({
            configFile: './karma.conf.js',
            action: 'run'
        }))
        .on('error', function (err)
        {
            throw err;
        });
});

gulp.task('lint', function ()
{
    gulp.src([
        config.scriptsAllF,
        './karma-e2e.conf.js',
        './karma.conf.js',
        './gulpfile.js'
    ])
        .pipe(jshint())
        .pipe(jshint.reporter('jshint-stylish'))
        .pipe(jscs());
});
<commit_msg>fixes #12 wiredep issue with index.html<commit_after>'use strict';
/* jshint camelcase: false */

var config = require('./config');
var gulp = require('gulp');

/**
 * Dev Task File
 *
 */

var sass = require('gulp-sass');
var autoprefixer = require('gulp-autoprefixer');
var sourcemaps = require('gulp-sourcemaps');
var wiredep = require('wiredep').stream;
var inj = require('gulp-inject');

var browserSync = require('browser-sync');
var reload = browserSync.reload;
var watch = require('gulp-watch');
var runSequence = require('run-sequence').use(gulp);

var jshint = require('gulp-jshint');
var jscs = require('gulp-jscs');
var karma = require('gulp-karma');

function swallowError(error)
{
    console.log(error.toString());
    this.emit('end');
}

// main task
gulp.task('default', function ()
{
    runSequence(
        'injectAll',
        'buildStyles',
        'test',
        'browserSync',
        'watch'
    );
});
gulp.task('serve', ['default']);
gulp.task('server', ['default']);

gulp.task('injectAll', function (callback)
{
    runSequence(
        'wiredep',
        'injectScripts',
        'injectStyles',
        callback
    );
});

gulp.task('watch', function ()
{
    watch(config.stylesF, function ()
    {
        gulp.start('buildStyles');
    });
    watch(config.scriptsF, function ()
    {
        gulp.start('injectScripts');
    });
    watch(config.scriptsAllF, function ()
    {
        gulp.start('lint');
    });

    watch(config.allHtmlF, function ()
    {
        gulp.start('html');
    });

    gulp.watch('bower.json', ['wiredep']);
});

gulp.task('buildStyles', function ()
{
    runSequence(
        'injectStyles',
        'sass'
    );
});

gulp.task('injectStyles', function ()
{
    var sources = gulp.src(config.stylesF, {read: false});
    var target = gulp.src(config.mainSassFile);
    var outputFolder = gulp.dest(config.styles);

    target
        .pipe(inj(sources,
            {
                starttag: '// inject:sass',
                endtag: '// endinject',
                ignorePath: [config.base.replace('./', ''), 'styles'],
                relative: true,
                addRootSlash: false,
                transform: function (filepath)
                {
                    if (filepath) {
                        return '@import  \'' + filepath + '\';';
                    }
                }
            }
        ))
        .pipe(outputFolder);
});

gulp.task('injectScripts', function ()
{
    var sources = gulp.src(config.scriptsF, {read: false});
    var target = gulp.src(config.mainFile);
    target
        .pipe(inj(sources,
            {
                ignorePath: config.base.replace('./', ''),
                addRootSlash: false
            }
        ))
        .pipe(gulp.dest(config.base));
});

gulp.task('sass', function ()
{
    var sources = gulp.src(config.mainSassFile);
    var outputFolder = gulp.dest(config.styles);

    sources
        .pipe(sourcemaps.init())
        .pipe(sass())
        .pipe(autoprefixer({
            browsers: ['last 2 versions']
        }))
        .pipe(sourcemaps.write())
        .pipe(outputFolder)
        .pipe(reload({stream: true}))
        .on('error', swallowError)
});

gulp.task('browserSync', function ()
{
    browserSync({
        server: {
            baseDir: config.base,
            livereload: true
        }
    });
});

gulp.task('html', function ()
{
    gulp.src(config.allHtmlF)
        .pipe(reload({stream: true}));
});

gulp.task('wiredep', function ()
{
    gulp.src([config.karmaConf], {base: './'})
        .pipe(wiredep({
            devDependencies: true
        }))
        // required as weird workaround for not messing up the files
        .pipe(gulp.dest(config.tmp))
        .pipe(gulp.dest('./'));

    return gulp.src([config.mainFile], {base: './'})
        .pipe(wiredep({
            devDependencies: false
        }))
        // required as weird workaround for not messing up the files
        .pipe(gulp.dest(config.tmp))
        .pipe(gulp.dest('./'));
});

gulp.task('test', function ()
{
    // Be sure to return the stream
    gulp.src('.nonononoNOTHING')
        .pipe(karma({
            configFile: './karma.conf.js',
            action: 'watch'
        }))
        .on('error', function (err)
        {
            throw err;
        })
        .on('error', swallowError);
});

gulp.task('testSingle', function ()
{
    // Be sure to return the stream
    gulp.src('.nonononoNOTHING')
        .pipe(karma({
            configFile: './karma.conf.js',
            action: 'run'
        }))
        .on('error', function (err)
        {
            throw err;
        });
});

gulp.task('lint', function ()
{
    gulp.src([
        config.scriptsAllF,
        './karma-e2e.conf.js',
        './karma.conf.js',
        './gulpfile.js'
    ])
        .pipe(jshint())
        .pipe(jshint.reporter('jshint-stylish'))
        .pipe(jscs());
});
<|endoftext|>


<commit_before>// var Backbone = require('backbone');
// var _ = require('underscore');
// var AnalysesQuotaFactory = require('../../../../../../../javascripts/cartodb3/editor/layers/layer-content-views/analyses/analyses-quota-factory');
// var QUOTA_FIELDS = ['totalQuota', 'usedQuota', 'blockSize', 'blockPrice', 'hardLimit'];

describe('editor/layers/layer-content-view/analyses/analyses-service', function () {
  // beforeEach(function () {
  //   this.userModel = new Backbone.Model({
  //     isolines_provider: 'heremaps',
  //     geocoder_provider: 'heremaps'
  //   });
  //   this.userModel._organizationModel = new Backbone.Model({
  //     isolines_provider: 'heremaps',
  //     geocoder_provider: 'heremaps'
  //   });

  //   this.userModel.isInsideOrg = function () {
  //     return false;
  //   };
  //   this.userModel.getOrganization = function () {
  //     return this.userModel._organizationModel;
  //   }.bind(this);
  // });

  // describe('analyses without quota', function () {
  //   it('should not return any quota info', function () {
  //     expect(AnalysesQuotaFactory.requiresQuota('carto-analysis', this.userModel)).toBeFalsy();
  //   });
  // });

  // describe('analysis with quota', function () {
  //   describe('trade-area', function () {
  //     it('should return quota', function () {
  //       expect(AnalysesQuotaFactory.requiresQuota('trade-area', this.userModel)).toBeTruthy();
  //       var analysisQuota = AnalysesQuotaFactory.getQuotaInfo('trade-area', this.userModel);
  //       _.each(QUOTA_FIELDS, function (item) {
  //         expect(analysisQuota[item]).toBeDefined();
  //       });
  //     });

  //     it('should not require quota when provider is different than heremaps', function () {
  //       expect(AnalysesQuotaFactory.requiresQuota('trade-area', this.userModel)).toBeTruthy();
  //       this.userModel.set('isolines_provider', null);
  //       expect(AnalysesQuotaFactory.requiresQuota('trade-area', this.userModel)).toBeFalsy();
  //       this.userModel.set('isolines_provider', 'mapzen');
  //       expect(AnalysesQuotaFactory.requiresQuota('trade-area', this.userModel)).toBeFalsy();
  //     });

  //     it('should take organization provider attributes when user belongs to one', function () {
  //       this.userModel.isInsideOrg = function () { return true; };
  //       expect(AnalysesQuotaFactory.requiresQuota('trade-area', this.userModel)).toBeTruthy();
  //       this.userModel.set('isolines_provider', null);
  //       expect(AnalysesQuotaFactory.requiresQuota('trade-area', this.userModel)).toBeTruthy();
  //     });
  //   });

  //   describe('georeference-street-address', function () {
  //     it('should return quota', function () {
  //       expect(AnalysesQuotaFactory.requiresQuota('georeference-street-address', this.userModel)).toBeTruthy();
  //       var analysisQuota = AnalysesQuotaFactory.getQuotaInfo('georeference-street-address', this.userModel);
  //       _.each(QUOTA_FIELDS, function (item) {
  //         expect(analysisQuota[item]).toBeDefined();
  //       });
  //     });

  //     it('should not require quota when provider is not set or is different than heremaps', function () {
  //       expect(AnalysesQuotaFactory.requiresQuota('georeference-street-address', this.userModel)).toBeTruthy();
  //       this.userModel.set('geocoder_provider', null);
  //       expect(AnalysesQuotaFactory.requiresQuota('georeference-street-address', this.userModel)).toBeFalsy();
  //       this.userModel.set('geocoder_provider', 'mapzen');
  //       expect(AnalysesQuotaFactory.requiresQuota('georeference-street-address', this.userModel)).toBeFalsy();
  //       this.userModel.set('geocoder_provider', 'google');
  //       expect(AnalysesQuotaFactory.requiresQuota('georeference-street-address', this.userModel)).toBeFalsy();
  //     });

  //     it('should take organization provider attributes when user belongs to one', function () {
  //       this.userModel.isInsideOrg = function () { return true; };
  //       expect(AnalysesQuotaFactory.requiresQuota('georeference-street-address', this.userModel)).toBeTruthy();
  //       this.userModel.set('geocoder_provider', null);
  //       expect(AnalysesQuotaFactory.requiresQuota('georeference-street-address', this.userModel)).toBeTruthy();
  //     });
  //   });
  // });
});
<commit_msg>fix tests<commit_after>var Backbone = require('backbone');
var CoreView = require('backbone/core-view');
var LayerDefinitionModel = require('../../../../../../../javascripts/cartodb3/data/layer-definition-model');
var LayerDefinitionsCollection = require('../../../../../../../javascripts/cartodb3/data/layer-definitions-collection');
var ConfigModel = require('../../../../../../../javascripts/cartodb3/data/config-model');
var UserModel = require('../../../../../../../javascripts/cartodb3/data/user-model');
var AnalysesService = require('../../../../../../../javascripts/cartodb3/editor/layers/layer-content-views/analyses/analyses-service');
var StackLayoutView = require('../../../../../../../javascripts/cartodb3/components/stack-layout/stack-layout-view');
var ModalsService = require('../../../../../../../javascripts/cartodb3/components/modals/modals-service-model');
var AddAnalysisView = require('../../../../../../../javascripts/cartodb3/components/modals/add-analysis/add-analysis-view');

describe('editor/layers/layer-content-view/analyses/analyses-service', function () {
  beforeEach(function () {
    this.configModel = new ConfigModel({
      base_url: '/u/pepe'
    });

    this.userModel = new UserModel({}, {
      configModel: this.configModel
    });

    this.layerDefinitionModel = new LayerDefinitionModel({
      id: 'l-1',
      options: {
        type: 'CartoDB',
        table_name: 'foo'
      }
    }, {
      parse: true,
      configModel: this.configModel
    });

    var onboardings = new Backbone.Model();
    onboardings.create = function () {};
    onboardings.destroy = function () {};

    this.layerDefinitionsCollection = new LayerDefinitionsCollection(null, {
      configModel: this.configModel,
      userModel: this.userModel,
      analysisDefinitionNodesCollection: new Backbone.Collection(),
      mapId: 'map-123',
      stateDefinitionModel: {}
    });

    this.layerDefinitionsCollection.add(this.layerDefinitionModel);

    var modals = new ModalsService();

    AnalysesService.init({
      onboardings: onboardings,
      layerDefinitionsCollection: this.layerDefinitionsCollection,
      modals: modals,
      userModel: this.userModel,
      configModel: this.configModel
    });

    var model1 = new Backbone.Model({
      createStackView: function (stackLayoutModel) {
        return new CoreView();
      }
    });
    var model2 = new Backbone.Model({
      createStackView: function (stackLayoutModel) {
        return new CoreView();
      }
    });
    var collection = new Backbone.Collection([model1, model2]);
    this._stackLayoutView = new StackLayoutView({
      collection: collection
    });
  });

  describe('.setLayerId', function () {
    it('should set LayerId', function () {
      AnalysesService.setLayerId(this.layerDefinitionModel.get('id'));
      expect(AnalysesService._layerId).toBe('l-1');
    });
  });

  describe('.setStackLayoutView', function () {
    it('should set StackLayoutView', function () {
      AnalysesService.setStackLayoutView(this._stackLayoutView);
      expect(AnalysesService._stackLayoutView).toBe(this._stackLayoutView);
    });
  });

  describe('.addAnalysis', function () {
    beforeEach(function () {
      var mockView = new CoreView();
      spyOn(AddAnalysisView.prototype, 'initialize');
      spyOn(AddAnalysisView.prototype, 'render').and.returnValue(mockView);

      spyOn(AnalysesService._modals, 'create').and.callThrough();
      spyOn(AnalysesService._modals, 'onDestroyOnce').and.callThrough();

      AnalysesService.setLayerId(this.layerDefinitionModel.get('id'));
      AnalysesService.setStackLayoutView(this._stackLayoutView);
      AnalysesService.addAnalysis();
    });

    afterEach(function () {
      AnalysesService._modals.destroy();
    });

    it('should open a modal add-analysis-view', function () {
      expect(AnalysesService._modals.create).toHaveBeenCalled();
    });

    describe('when modal is closed', function () {
      var modalView;

      beforeEach(function () {
        modalView = AnalysesService._modals._modalView;
        AnalysesService.setStackLayoutView(this._stackLayoutView);
        spyOn(AnalysesService._stackLayoutView.model, 'goToStep');

        this.analysisFormAttrs = {id: 'a1', type: 'buffer'};
        var destroyOnceArgs = AnalysesService._modals.onDestroyOnce.calls.argsFor(0);
        destroyOnceArgs[0].call(destroyOnceArgs[1], this.analysisFormAttrs);
      });

      it('should redirect stack to layer-content', function () {
        expect(AnalysesService._stackLayoutView.model.goToStep).toHaveBeenCalledWith(1, this.layerDefinitionModel, 'layer-content', this.analysisFormAttrs);
      });

      afterEach(function () {
        modalView.clean();
      })
    });
  });
});
<|endoftext|>


<commit_before>"use strict";

var assert = require("assert");
var inspector = require("schema-inspector");

function RPCValidation(endpoint, inout, obj, parseDates){
    assert(parseDates === true || parseDates === false);
    let schema;
    let datePaths;

    if (inout === "input") {
        schema = endpoint.requestSchema;
        if (!endpoint.inDatePaths) {
            endpoint.inDatePaths = extractDatepaths(schema);
        }
        datePaths = endpoint.inDatePaths;

    } else if (inout === "output") {
        schema = endpoint.replySchema;
        if (!endpoint.outDatePaths) {
            endpoint.outDatePaths = extractDatepaths(schema);
        }
        datePaths = endpoint.outDatePaths;
    } else {
        throw new Error("doValidation called with wrong argument");
    }

    if (parseDates && datePaths.length) {
        for(let path of datePaths) {
            applyDatepath(path, obj);
        }
    }

    if (!schema){
        console.error("There's no schema for RPC Call " + endpoint.name + ". Fix this!");
    } else {
        var validation = inspector.validate(schema, obj);
        if (!validation.valid){
            throw new Error("Validation failed! " + validation.format());
        }
    }
}

function SourceSinkValidation(endpoint, obj, parseDates){
    assert(parseDates === true || parseDates === false);

    var schema = endpoint.messageSchema;

    if(schema.skip){
        return
    }

    if (schema && !endpoint.datePaths) {
        endpoint.datePaths = extractDatepaths(schema);
    }

    if (!schema){
        console.error("There's no schema for Source/Sink " + endpoint.name + ". Fix this!");
    }

    if (parseDates && endpoint.datePaths && endpoint.datePaths.length) {
        for(let path of endpoint.datePaths) {
            applyDatepath(path, obj);
        }
    }

    var validation = inspector.validate(schema, obj);

    if (!validation.valid){
        throw new Error("Validation failed! " + validation.format());
    }
}

function SharedObjectValidation(endpoint, obj, hint){

    if (!endpoint.objectSchema){
        console.error("There's no schema for SharedObject " + endpoint.name + ". Fix this!");
    }

    if (!hint) {
        hint = [];
    }

    // Check if we need to run validation
    if(endpoint.objectSchema.skip){
        return
    }

    var subs = _getSubsForHint(endpoint.objectSchema, obj, hint);

    var schema = subs.schema;
    obj = subs.obj;

    var validation = inspector.validate(schema, obj);

    if (!validation.valid) {
        throw new Error("Validation failed! " + validation.format());
    }
}

function parseDiffDates(endpoint, diff) {
    var schema = endpoint.objectSchema;

    if (schema.skip) {
        return;
    }

    if (schema && !schema.skip && !endpoint.datePaths) {
        endpoint.datePaths = extractDatepaths(schema);

    }

    if (!endpoint.datePaths || endpoint.datePaths.length === 0) {
        return;
    }

    if (!endpoint.slicedPaths) {
        endpoint.slicedPaths = {};
    }

    if ((diff.path.length || diff.path.length === 0) && !endpoint.slicedPaths[diff.path.length]) {
        endpoint.slicedPaths[diff.path.length] = endpoint.datePaths.map(x => x.slice(diff.path.length-1)).filter(x => x.length)
    }

    if (diff.rhs) {
        for (let datePath of endpoint.slicedPaths[diff.path.length]) {
            if (datePath[0] === diff.path[diff.path.length-1] || datePath[0] === "*") {
                // Kinda yuk
                let memo = datePath[0];

                datePath[0] = "rhs";
                applyDatepath(datePath, diff);
                datePath[0] = "lhs";
                applyDatepath(datePath, diff);

                datePath[0] = memo;
            }
        }
    }

    if (diff.kind === "A" && diff.item) {
        for (let datePath of endpoint.slicedPaths[diff.path.length]) {
            if (datePath[0] === diff.path[diff.path.length - 1] || datePath[0] === "*") {
                // Kinda yuk

                let slicedPath = datePath.slice(1);
                slicedPath[0] = "rhs";
                applyDatepath(slicedPath, diff.item);
            }
        }
    }

}

function parseFullDates(endpoint, obj) {
    assert(endpoint.objectSchema);

    var schema = endpoint.objectSchema;

    if(schema.skip){
        return
    }

    if (schema && !endpoint.datePaths) {
        endpoint.datePaths = extractDatepaths(schema);
    }

    if (endpoint.datePaths && endpoint.datePaths.length) {
        for(let path of endpoint.datePaths) {
            applyDatepath(path, obj);
        }
    }

    var validation = inspector.validate(schema, obj);

    if (!validation.valid){
        throw new Error("Validation failed! " + validation.format());
    }
}

function _getSubsForHint(schema, obj, hint){
    var i = 0;
    while(i < hint.length){
        if (!(hint[i] in obj)) {
            break; // On delete, validate entire parent. Otherwise possible missing items may not be caught.
        }

        obj = obj[hint[i]];

        if (schema.type === 'object') {
            if (hint[i] in schema.properties) {
                schema = schema.properties[hint[i]];
            } else if ('*' in schema.properties) {
                schema = schema.properties['*'];
            } else{
                throw new Error("Unknown property, and no catch all!")
            }
        } else if (schema.type === 'array') {
            schema = schema.items;
        } else {
            // Hinting on anything else is not currently supported, crash on possible weirdness.
            throw new Error("Please only do hinting on objects/arrays.");
        }

        i++;
    }

    return {schema, obj};
}

module.exports = {
    RPCValidation,
    SharedObjectValidation,
    parseDiffDates,
    parseFullDates,
    SourceValidation: SourceSinkValidation,
    SinkValidation: SourceSinkValidation
};

function extractDatepaths(schema) {
    let out = [];
    if (schema && schema.type === "object" && schema.properties) {
        for (let prop in schema.properties) {
            if (schema.properties[prop].type === "object") {
                let recurse = extractDatepaths(schema.properties[prop]);
                out = [...out, ...recurse.map(x => [prop, ...x])];
            } else if (schema.properties[prop].type === "array") {
                let recurse = extractDatepaths(schema.properties[prop].items);
                out = [...out, ...recurse.map(x=>[prop,"*",...x])];
            } else if (schema.properties[prop].type === "date") {
                out.push([prop]);
            }
        }
    }

    return out;
}

function applyDatepath(path, obj) {
    if (!obj[path[0]] && !(path[0] === "*" && typeof obj === "object")) {
        return;
    }

    if (path.length === 1) {
        if (path[0] !== "*") {
            obj[path[0]] = new Date(obj[path[0]])
        } else {
            for(let key in obj) {
                obj[key] = new Date(obj[key]);
            }
        }
    } else {
        let nextPath = path.slice(1);
        if (path[0] !== "*") {
            applyDatepath(nextPath, obj[path[0]]);
        } else {
            for(let key in obj) {
                applyDatepath(nextPath, obj[key]);
            }
        }
    }
}<commit_msg>Better subpath handling<commit_after>"use strict";

var assert = require("assert");
var inspector = require("schema-inspector");

function RPCValidation(endpoint, inout, obj, parseDates){
    assert(parseDates === true || parseDates === false);
    let schema;
    let datePaths;

    if (inout === "input") {
        schema = endpoint.requestSchema;
        if (!endpoint.inDatePaths) {
            endpoint.inDatePaths = extractDatepaths(schema);
        }
        datePaths = endpoint.inDatePaths;

    } else if (inout === "output") {
        schema = endpoint.replySchema;
        if (!endpoint.outDatePaths) {
            endpoint.outDatePaths = extractDatepaths(schema);
        }
        datePaths = endpoint.outDatePaths;
    } else {
        throw new Error("doValidation called with wrong argument");
    }

    if (parseDates && datePaths.length) {
        for(let path of datePaths) {
            applyDatepath(path, obj);
        }
    }

    if (!schema){
        console.error("There's no schema for RPC Call " + endpoint.name + ". Fix this!");
    } else {
        var validation = inspector.validate(schema, obj);
        if (!validation.valid){
            throw new Error("Validation failed! " + validation.format());
        }
    }
}

function SourceSinkValidation(endpoint, obj, parseDates){
    assert(parseDates === true || parseDates === false);

    var schema = endpoint.messageSchema;

    if(schema.skip){
        return
    }

    if (schema && !endpoint.datePaths) {
        endpoint.datePaths = extractDatepaths(schema);
    }

    if (!schema){
        console.error("There's no schema for Source/Sink " + endpoint.name + ". Fix this!");
    }

    if (parseDates && endpoint.datePaths && endpoint.datePaths.length) {
        for(let path of endpoint.datePaths) {
            applyDatepath(path, obj);
        }
    }

    var validation = inspector.validate(schema, obj);

    if (!validation.valid){
        throw new Error("Validation failed! " + validation.format());
    }
}

function SharedObjectValidation(endpoint, obj, hint){

    if (!endpoint.objectSchema){
        console.error("There's no schema for SharedObject " + endpoint.name + ". Fix this!");
    }

    if (!hint) {
        hint = [];
    }

    // Check if we need to run validation
    if(endpoint.objectSchema.skip){
        return
    }

    var subs = _getSubsForHint(endpoint.objectSchema, obj, hint);

    var schema = subs.schema;
    obj = subs.obj;

    var validation = inspector.validate(schema, obj);

    if (!validation.valid) {
        throw new Error("Validation failed! " + validation.format());
    }
}

function parseDiffDates(endpoint, diff) {
    var schema = endpoint.objectSchema;

    if (schema.skip) {
        return;
    }

    if (schema && !schema.skip && !endpoint.datePaths) {
        endpoint.datePaths = extractDatepaths(schema);
    }

    if (!endpoint.datePaths || endpoint.datePaths.length === 0) {
        return;
    }

    let slicedPaths = endpoint.datePaths.filter((path) => {
        for(let i = 0; i < diff.path.length; i++) {
            if (!(path[i] === "*" || path[i] === diff.path[i])) {
                return false;
            }
        }
        return true;
    }).map(x => x.slice(diff.path.length-1)).filter(x => x.length);

    if (diff.rhs) {
        for (let datePath of slicedPaths) {
            if (datePath[0] === diff.path[diff.path.length-1] || datePath[0] === "*") {
                // Kinda yuk
                let memo = datePath[0];

                datePath[0] = "rhs";
                applyDatepath(datePath, diff);
                datePath[0] = "lhs";
                applyDatepath(datePath, diff);

                datePath[0] = memo;
            }
        }
    }

    if (diff.kind === "A" && diff.item) {
        for (let datePath of slicedPaths) {
            if (datePath[0] === diff.path[diff.path.length - 1] || datePath[0] === "*") {
                // Kinda yuk

                let slicedPath = datePath.slice(1);
                slicedPath[0] = "rhs";
                applyDatepath(slicedPath, diff.item);
            }
        }
    }

}

function parseFullDates(endpoint, obj) {
    assert(endpoint.objectSchema);

    var schema = endpoint.objectSchema;

    if(schema.skip){
        return
    }

    if (schema && !endpoint.datePaths) {
        endpoint.datePaths = extractDatepaths(schema);
    }

    if (endpoint.datePaths && endpoint.datePaths.length) {
        for(let path of endpoint.datePaths) {
            applyDatepath(path, obj);
        }
    }

    var validation = inspector.validate(schema, obj);

    if (!validation.valid){
        throw new Error("Validation failed! " + validation.format());
    }
}

function _getSubsForHint(schema, obj, hint){
    var i = 0;
    while(i < hint.length){
        if (!(hint[i] in obj)) {
            break; // On delete, validate entire parent. Otherwise possible missing items may not be caught.
        }

        obj = obj[hint[i]];

        if (schema.type === 'object') {
            if (hint[i] in schema.properties) {
                schema = schema.properties[hint[i]];
            } else if ('*' in schema.properties) {
                schema = schema.properties['*'];
            } else{
                throw new Error("Unknown property, and no catch all!")
            }
        } else if (schema.type === 'array') {
            schema = schema.items;
        } else {
            // Hinting on anything else is not currently supported, crash on possible weirdness.
            throw new Error("Please only do hinting on objects/arrays.");
        }

        i++;
    }

    return {schema, obj};
}

module.exports = {
    RPCValidation,
    SharedObjectValidation,
    parseDiffDates,
    parseFullDates,
    SourceValidation: SourceSinkValidation,
    SinkValidation: SourceSinkValidation
};

function extractDatepaths(schema) {
    let out = [];
    if (schema && schema.type === "object" && schema.properties) {
        for (let prop in schema.properties) {
            if (schema.properties[prop].type === "object") {
                let recurse = extractDatepaths(schema.properties[prop]);
                out = [...out, ...recurse.map(x => [prop, ...x])];
            } else if (schema.properties[prop].type === "array") {
                let recurse = extractDatepaths(schema.properties[prop].items);
                out = [...out, ...recurse.map(x=>[prop,"*",...x])];
            } else if (schema.properties[prop].type === "date") {
                out.push([prop]);
            }
        }
    }

    return out;
}

function applyDatepath(path, obj) {
    if (!obj[path[0]] && !(path[0] === "*" && typeof obj === "object")) {
        return;
    }

    if (path.length === 1) {
        if (path[0] !== "*") {
            obj[path[0]] = new Date(obj[path[0]])
        } else {
            for(let key in obj) {
                obj[key] = new Date(obj[key]);
            }
        }
    } else {
        let nextPath = path.slice(1);
        if (path[0] !== "*") {
            applyDatepath(nextPath, obj[path[0]]);
        } else {
            for(let key in obj) {
                applyDatepath(nextPath, obj[key]);
            }
        }
    }
}<|endoftext|>


<commit_before>/*
    It's a simple jQuery plugin that searchs for SVG images on your website and creates PNG versions on the run.
    Meaning that you don't have to create different versions of the images yourself.
    Copyright (C) 2013 - Dirk Groenen [Bitlabs Development]

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
(function( $ ){
    $.fn.svgmagic = function(givenoptions) {
        var defaultoptions = {
            preloader: false,
            testmode: false,
            secure: false,
            callback: false,
            backgroundimage: false
        }
        var options = $.extend(defaultoptions,givenoptions);

        var ieversion = false, preloaderTimer = [];
        if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)){
            ieversion=new Number(RegExp.$1);
        }

        if((ieversion < 9 && ieversion != false) || true == options.testmode){
            if(ieversion < 8){
                if(typeof JSON!=="object"){JSON={}}(function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){escapable.lastIndex=0;return escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t==="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];if(a&&typeof a==="object"&&typeof a.toJSON==="function"){a=a.toJSON(e)}if(typeof rep==="function"){a=rep.call(t,e,a)}switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a){return"null"}gap+=indent;u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n<s;n+=1){u[n]=str(n,a)||"null"}i=u.length===0?"[]":gap?"[\n"+gap+u.join(",\n"+gap)+"\n"+o+"]":"["+u.join(",")+"]";gap=o;return i}if(rep&&typeof rep==="object"){s=rep.length;for(n=0;n<s;n+=1){if(typeof rep[n]==="string"){r=rep[n];i=str(r,a);if(i){u.push(quote(r)+(gap?": ":":")+i)}}}}else{for(r in a){if(Object.prototype.hasOwnProperty.call(a,r)){i=str(r,a);if(i){u.push(quote(r)+(gap?": ":":")+i)}}}}i=u.length===0?"{}":gap?"{\n"+gap+u.join(",\n"+gap)+"\n"+o+"}":"{"+u.join(",")+"}";gap=o;return i}}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","	":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;if(typeof JSON.stringify!=="function"){JSON.stringify=function(e,t,n){var r;gap="";indent="";if(typeof n==="number"){for(r=0;r<n;r+=1){indent+=" "}}else if(typeof n==="string"){indent=n}rep=t;if(t&&typeof t!=="function"&&(typeof t!=="object"||typeof t.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":e})}}if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){function walk(e,t){var n,r,i=e[t];if(i&&typeof i==="object"){for(n in i){if(Object.prototype.hasOwnProperty.call(i,n)){r=walk(i,n);if(r!==undefined){i[n]=r}else{delete i[n]}}}}return reviver.call(e,t,i)}var j;text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(e){return"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}})()
            }
            var obj = this, images = [], domimages = [], cssimages = [];

            obj.each(function(){
                if($(this).attr('src') != undefined){
                    if($(this).attr('src').split('.').pop() == 'svg'){
                        $obj = $(this);
                        var image = new Image();
                        image.src = $(this).attr('src');
                        images.push(image.src);
                        domimages.push($obj);

                        if(options.preloader != false){
                            preloaderTimer.push(setTimeout(function(){
                                $obj.attr('src', options.preloader);
                            },500));
                        }
                    }
                }
            });

            // If backgroundimage option is enabled it will search for background images in the div
            if(options.backgroundimage){
                if(obj.css('background-image') != undefined){
                    var bgsrc = obj.css('background-image').replace(/^url\(["']?/, '').replace(/["']?\)$/, '');
                    if(bgsrc.split('.').pop() == 'svg'){
                        var image = new Image();
                        image.src = bgsrc;
                        images.push(image.src);
                        cssimages.push(obj);
                    }
                }
            }

            var data = {
                svgsources: images,
                secure: options.secure
            };

            if(images.length > 0){
                var i = 0;
                $.ajax({
                    dataType: "jsonp",
                    url: "http://svgmagic.bitlabs.nl/converter.php",
                    data: data,
                    success: function(response){
                        var i;
                        for(i = 0;i < domimages.length; i++){
                            clearTimeout(preloaderTimer[i]);
                            domimages[i].attr('src', response.results[i].url);
                        }

                        if(options.backgroundimage){
                            for(i;i < (domimages.length+cssimages.length); i++){
                                var fakeindex = (i - domimages.length);
                                cssimages[fakeindex].css('background-image', 'url("'+response.results[i].url+'")');
                            }
                        }

                        if(options.callback){
                            options.callback();
                        }
                    }
                });

            }
        }
    };
}(jQuery));<commit_msg>replace undefined check with "none"<commit_after>/*
    It's a simple jQuery plugin that searchs for SVG images on your website and creates PNG versions on the run.
    Meaning that you don't have to create different versions of the images yourself.
    Copyright (C) 2013 - Dirk Groenen [Bitlabs Development]

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
(function( $ ){
    $.fn.svgmagic = function(givenoptions) {
        var defaultoptions = {
            preloader: false,
            testmode: false,
            secure: false,
            callback: false,
            backgroundimage: false
        }
        var options = $.extend(defaultoptions,givenoptions);

        var ieversion = false, preloaderTimer = [];
        if (/MSIE (\d+\.\d+);/.test(navigator.userAgent)){
            ieversion=new Number(RegExp.$1);
        }

        if((ieversion < 9 && ieversion != false) || true == options.testmode){
            if(ieversion < 8){
                if(typeof JSON!=="object"){JSON={}}(function(){"use strict";function f(e){return e<10?"0"+e:e}function quote(e){escapable.lastIndex=0;return escapable.test(e)?'"'+e.replace(escapable,function(e){var t=meta[e];return typeof t==="string"?t:"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+e+'"'}function str(e,t){var n,r,i,s,o=gap,u,a=t[e];if(a&&typeof a==="object"&&typeof a.toJSON==="function"){a=a.toJSON(e)}if(typeof rep==="function"){a=rep.call(t,e,a)}switch(typeof a){case"string":return quote(a);case"number":return isFinite(a)?String(a):"null";case"boolean":case"null":return String(a);case"object":if(!a){return"null"}gap+=indent;u=[];if(Object.prototype.toString.apply(a)==="[object Array]"){s=a.length;for(n=0;n<s;n+=1){u[n]=str(n,a)||"null"}i=u.length===0?"[]":gap?"[\n"+gap+u.join(",\n"+gap)+"\n"+o+"]":"["+u.join(",")+"]";gap=o;return i}if(rep&&typeof rep==="object"){s=rep.length;for(n=0;n<s;n+=1){if(typeof rep[n]==="string"){r=rep[n];i=str(r,a);if(i){u.push(quote(r)+(gap?": ":":")+i)}}}}else{for(r in a){if(Object.prototype.hasOwnProperty.call(a,r)){i=str(r,a);if(i){u.push(quote(r)+(gap?": ":":")+i)}}}}i=u.length===0?"{}":gap?"{\n"+gap+u.join(",\n"+gap)+"\n"+o+"}":"{"+u.join(",")+"}";gap=o;return i}}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(){return this.valueOf()}}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","	":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;if(typeof JSON.stringify!=="function"){JSON.stringify=function(e,t,n){var r;gap="";indent="";if(typeof n==="number"){for(r=0;r<n;r+=1){indent+=" "}}else if(typeof n==="string"){indent=n}rep=t;if(t&&typeof t!=="function"&&(typeof t!=="object"||typeof t.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":e})}}if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){function walk(e,t){var n,r,i=e[t];if(i&&typeof i==="object"){for(n in i){if(Object.prototype.hasOwnProperty.call(i,n)){r=walk(i,n);if(r!==undefined){i[n]=r}else{delete i[n]}}}}return reviver.call(e,t,i)}var j;text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(e){return"\\u"+("0000"+e.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}})()
            }
            var obj = this, images = [], domimages = [], cssimages = [];

            obj.each(function(){
                if($(this).attr('src') != undefined){
                    if($(this).attr('src').split('.').pop() == 'svg'){
                        $obj = $(this);
                        var image = new Image();
                        image.src = $(this).attr('src');
                        images.push(image.src);
                        domimages.push($obj);

                        if(options.preloader != false){
                            preloaderTimer.push(setTimeout(function(){
                                $obj.attr('src', options.preloader);
                            },500));
                        }
                    }
                }
            });

            // If backgroundimage option is enabled it will search for background images in the div
            if(options.backgroundimage){
                if(obj.css('background-image') != "none" && obj.css('background-image') != undefined){
                    var bgsrc = obj.css('background-image').replace(/^url\(["']?/, '').replace(/["']?\)$/, '');
                    if(bgsrc.split('.').pop() == 'svg'){
                        var image = new Image();
                        image.src = bgsrc;
                        images.push(image.src);
                        cssimages.push(obj);
                    }
                }
            }

            var data = {
                svgsources: images,
                secure: options.secure
            };

            if(images.length > 0){
                var i = 0;
                $.ajax({
                    dataType: "jsonp",
                    url: "http://svgmagic.bitlabs.nl/converter.php",
                    data: data,
                    success: function(response){
                        var i;
                        for(i = 0;i < domimages.length; i++){
                            clearTimeout(preloaderTimer[i]);
                            domimages[i].attr('src', response.results[i].url);
                        }

                        if(options.backgroundimage){
                            for(i;i < (domimages.length+cssimages.length); i++){
                                var fakeindex = (i - domimages.length);
                                cssimages[fakeindex].css('background-image', 'url("'+response.results[i].url+'")');
                            }
                        }

                        if(options.callback){
                            options.callback();
                        }
                    }
                });

            }
        }
    };
}(jQuery));<|endoftext|>


<commit_before>'use babel'

/* @flow */

import FS from 'fs'
import Temp from 'tmp'
import promisify from 'sb-promisify'
import consistentEnv from 'consistent-env'
import type { TextEditor } from 'atom'
import type { TempDirectory, ExecResult, ExecOptions } from './types'

let BufferedProcess
let BufferedNodeProcess
try {
  const Atom = require('atom')
  BufferedProcess = Atom.BufferedProcess
  BufferedNodeProcess = Atom.BufferedNodeProcess
} catch (_) {
  BufferedNodeProcess = BufferedProcess = function () {
    throw new Error('Process execution is not available')
  }
}

const COMMAND_NOT_RECOGNIZED_MESSAGE = 'is not recognized as an internal or external command'
export const writeFile = promisify(FS.writeFile)
export const unlinkFile = promisify(FS.unlink)
export const assign = Object.assign || function (target, source) {
  for (const key in source) {
    if (source.hasOwnProperty(key)) {
      target[key] = source[key]
    }
  }
  return target
}

export function getTempDirectory(prefix: string): Promise<TempDirectory> {
  return new Promise(function (resolve, reject) {
    Temp.dir({ prefix }, function (error, directory, cleanup) {
      if (error) {
        reject(error)
      } else resolve({ path: directory, cleanup })
    })
  })
}

export function fileExists(filePath: string): Promise<boolean> {
  return new Promise(function (resolve) {
    FS.access(filePath, FS.R_OK, function (error) {
      resolve(error === null)
    })
  })
}

export function validateExec(command: string, args: Array<string>, options: Object) {
  if (typeof command !== 'string') {
    throw new Error('Invalid or no `command` provided')
  } else if (!(args instanceof Array)) {
    throw new Error('Invalid or no `args` provided')
  } else if (typeof options !== 'object') {
    throw new Error('Invalid or no `options` provided')
  }
}

export function validateEditor(editor: TextEditor) {
  let isEditor
  if (typeof atom.workspace.isTextEditor === 'function') {
    // Added in Atom v1.4.0
    isEditor = atom.workspace.isTextEditor(editor)
  } else {
    isEditor = typeof editor.getText === 'function'
  }
  if (!isEditor) {
    throw new Error('Invalid TextEditor provided')
  }
}

export function validateFind(directory: string, name: string | Array<string>) {
  if (typeof directory !== 'string') {
    throw new Error('Invalid or no `directory` provided')
  } else if (typeof name !== 'string' && !(name instanceof Array)) {
    throw new Error('Invalid or no `name` provided')
  }
}

export function exec(
  command: string,
  args: Array<string>,
  opts: ExecOptions,
  isNode: boolean
): Promise<ExecResult> {
  const options: ExecOptions = assign({
    env: {},
    stream: 'stdout',
    throwOnStdErr: true
  }, opts)

  options.env = assign(consistentEnv(), options.env)
  if (isNode && options.env) {
    delete options.env.OS
  }

  return new Promise(function (resolve, reject) {
    const data = { stdout: [], stderr: [] }
    const handleError = function (error) {
      if (error && error.code === 'EACCES' ||
        (error && error.message && error.message.indexOf(COMMAND_NOT_RECOGNIZED_MESSAGE) !== -1)
      ) {
        const newError = new Error(`Failed to spawn command '${command}'.` +
          ` Make sure it's a file, not a directory, and it's executable.`)
        newError.name = 'BufferedProcessError'
        reject(newError)
      }
      reject(error)
    }
    const parameters = {
      command,
      args,
      options,
      stdout(chunk) {
        data.stdout.push(chunk)
      },
      stderr(chunk) {
        data.stderr.push(chunk)
      },
      exit() {
        if (options.stream === 'stdout') {
          if (data.stderr.length && options.throwOnStdErr) {
            handleError(new Error(data.stderr.join('').trim()))
          } else {
            resolve(data.stdout.join('').trim())
          }
        } else if (options.stream === 'stderr') {
          resolve(data.stderr.join('').trim())
        } else {
          resolve({ stdout: data.stdout.join('').trim(), stderr: data.stderr.join('').trim() })
        }
      }
    }
    const spawnedProcess = isNode ?
      new BufferedNodeProcess(parameters) :
      new BufferedProcess(parameters)

    spawnedProcess.onWillThrowError(function ({ error }) {
      handleError(error)
    })

    if (options.stdin) {
      try {
        spawnedProcess.process.stdin.write(options.stdin.toString())
        spawnedProcess.process.stdin.end()
      } catch (_) {
        // Do nothing
      }
    }
  })
}
<commit_msg>:bug: Improve a check<commit_after>'use babel'

/* @flow */

import FS from 'fs'
import Temp from 'tmp'
import promisify from 'sb-promisify'
import consistentEnv from 'consistent-env'
import type { TextEditor } from 'atom'
import type { TempDirectory, ExecResult, ExecOptions } from './types'

let BufferedProcess
let BufferedNodeProcess
try {
  const Atom = require('atom')
  BufferedProcess = Atom.BufferedProcess
  BufferedNodeProcess = Atom.BufferedNodeProcess
} catch (_) {
  BufferedNodeProcess = BufferedProcess = function () {
    throw new Error('Process execution is not available')
  }
}

const COMMAND_NOT_RECOGNIZED_MESSAGE = 'is not recognized as an internal or external command'
export const writeFile = promisify(FS.writeFile)
export const unlinkFile = promisify(FS.unlink)
export const assign = Object.assign || function (target, source) {
  for (const key in source) {
    if (source.hasOwnProperty(key)) {
      target[key] = source[key]
    }
  }
  return target
}

export function getTempDirectory(prefix: string): Promise<TempDirectory> {
  return new Promise(function (resolve, reject) {
    Temp.dir({ prefix }, function (error, directory, cleanup) {
      if (error) {
        reject(error)
      } else resolve({ path: directory, cleanup })
    })
  })
}

export function fileExists(filePath: string): Promise<boolean> {
  return new Promise(function (resolve) {
    FS.access(filePath, FS.R_OK, function (error) {
      resolve(error === null)
    })
  })
}

export function validateExec(command: string, args: Array<string>, options: Object) {
  if (typeof command !== 'string') {
    throw new Error('Invalid or no `command` provided')
  } else if (!(args instanceof Array)) {
    throw new Error('Invalid or no `args` provided')
  } else if (typeof options !== 'object') {
    throw new Error('Invalid or no `options` provided')
  }
}

export function validateEditor(editor: TextEditor) {
  let isEditor
  if (typeof atom.workspace.isTextEditor === 'function') {
    // Added in Atom v1.4.0
    isEditor = atom.workspace.isTextEditor(editor)
  } else {
    isEditor = typeof editor.getText === 'function'
  }
  if (!isEditor) {
    throw new Error('Invalid TextEditor provided')
  }
}

export function validateFind(directory: string, name: string | Array<string>) {
  if (typeof directory !== 'string') {
    throw new Error('Invalid or no `directory` provided')
  } else if (typeof name !== 'string' && !(name instanceof Array)) {
    throw new Error('Invalid or no `name` provided')
  }
}

export function exec(
  command: string,
  args: Array<string>,
  opts: ExecOptions,
  isNode: boolean
): Promise<ExecResult> {
  const options: ExecOptions = assign({
    env: {},
    stream: 'stdout',
    throwOnStdErr: true
  }, opts)

  options.env = assign(consistentEnv(), options.env)
  if (isNode && options.env.OS) {
    delete options.env.OS
  }

  return new Promise(function (resolve, reject) {
    const data = { stdout: [], stderr: [] }
    const handleError = function (error) {
      if (error && error.code === 'EACCES' ||
        (error && error.message && error.message.indexOf(COMMAND_NOT_RECOGNIZED_MESSAGE) !== -1)
      ) {
        const newError = new Error(`Failed to spawn command '${command}'.` +
          ` Make sure it's a file, not a directory, and it's executable.`)
        newError.name = 'BufferedProcessError'
        reject(newError)
      }
      reject(error)
    }
    const parameters = {
      command,
      args,
      options,
      stdout(chunk) {
        data.stdout.push(chunk)
      },
      stderr(chunk) {
        data.stderr.push(chunk)
      },
      exit() {
        if (options.stream === 'stdout') {
          if (data.stderr.length && options.throwOnStdErr) {
            handleError(new Error(data.stderr.join('').trim()))
          } else {
            resolve(data.stdout.join('').trim())
          }
        } else if (options.stream === 'stderr') {
          resolve(data.stderr.join('').trim())
        } else {
          resolve({ stdout: data.stdout.join('').trim(), stderr: data.stderr.join('').trim() })
        }
      }
    }
    const spawnedProcess = isNode ?
      new BufferedNodeProcess(parameters) :
      new BufferedProcess(parameters)

    spawnedProcess.onWillThrowError(function ({ error }) {
      handleError(error)
    })

    if (options.stdin) {
      try {
        spawnedProcess.process.stdin.write(options.stdin.toString())
        spawnedProcess.process.stdin.end()
      } catch (_) {
        // Do nothing
      }
    }
  })
}
<|endoftext|>


<commit_before>// This App is supposed to find Test Sets and then list the Test Cases within them
//
//A new comment is added
//
// Verify connector function
// Prepare to add pull requests
//
// Another Change
// Change, Change, Change.....
//
//06 Feb Change-ling
//
// A change for the better
// Added by JC
Ext.define('CustomApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',
    items:{ html:'App SDK 2.0rc3 Docs'},
    launch: function() {
    		var deStore;

    		var panel1 = Ext.create( 'Ext.panel.Panel', {
    			layout : {
    				type : 'hbox', // Arrange child items vertically
    				align : 'middle', // Each takes up full width
    			},
    			width : '100%',
    			bodyPadding : 10,
    			bodyStyle : {
    				background : '#9A9494',
    			},
    			items : [
    					{
    						xtype : 'container',
    						itemId : 'iterationFilter'
    					}, {
    						xtype : 'rallybutton',
    						text : 'Print Summary',
    						handler : function () {
    							this._printSummary();
    						},
    						style : {
    							marginRight : '10px',
    							marginLeft : '10px'
    						},
    						// flex:'1',
    						scope : this
    					}
    			/*
    			 * { xtype:'rallybutton', text: 'Print Defects', handler: function() { this._printDefects(); }, style: { marginLeft: '10px' },
    			 *
    			 * flex:'1', scope:this }
    			 */
    			]
    		} );
    		this.add( panel1 );
    		var panel2 = Ext.create( 'Ext.panel.Panel', {
    			layout : 'vbox',
    			width : '100%',
    			bodyPadding : 10,
    			bodyStyle : {
    				background : '#9A9494',
    			},
    			items : [

    				{
    					xtype : 'container',
    					layout : 'accordion',
    					itemId : 'testStatus',
    					width : '100%',
    					height : 500
    				}
    			]
    		} );

    		this.add( panel2 );
    		this._testSummary = [];
    		this._testResultList = [];
    		this._testSetTestList = [];
    		var TestSetStore;
    		var TestResultStore;
    		scope: this;

    		this.down( '#iterationFilter' ).add( {
    			xtype : 'rallyiterationcombobox',
    			itemId : 'iterationComboBox',
    			listeners : {
    				change : this._queryForTestSets,
    				ready : this._queryForTestSets,
    				scope : this
    			}
    		} );
    		;
    	},
    	_queryForTestSets : function () {

    		// if loading new iteration, destroy existing grids
    		if ( this._summaryGrid !== undefined ) {
    			this._summaryGrid.destroy();
    			this._Grid.destroy();
    			this._Grid2.destroy();
    		}

    		TestSetStore = Ext.create( 'Rally.data.WsapiDataStore', {
    			model : 'TestSet',
    			autoLoad : true,
    			storeId : 'TestSetStorer',
    			context : {
    				projectScopeUp : false,
    				projectScopeDown : true
    			},
    			filters : [
    					{
    						property : 'Project',
    						operator : '=',
    						value : this.getContext().getDataContext().project
    					}, {
    						property : 'Iteration.Name',
    						operator : '=',
    						value : this.down( '#iterationComboBox' ).getRecord().data.Name
    					}
    			],
    			fetch : [
    					'FormattedID', 'Name', 'TestCases', 'ObjectID', 'Project'
    			],
    			limit : 10000,
    			listeners : {
    				load : function ( store, data, success ) {
    					this._queryForTestResults( store, data )
    				},
    				scope : this
    			}
    		} );
    	},
});
<commit_msg>TA125: Testing 1 2 3 <commit_after>// This App is supposed to find Test Sets and then list the Test Cases within them
//
//A new comment is added
//
// Verify connector function
// Prepare to add pull requests
//
// A Comment that needs to be made
// Another Change
// Change, Change, Change.....
//
// A change for the better
// Added by JC
Ext.define('CustomApp', {
    extend: 'Rally.app.App',
    componentCls: 'app',
    items:{ html:'App SDK 2.0rc3 Docs'},
    launch: function() {
    		var deStore;

    		var panel1 = Ext.create( 'Ext.panel.Panel', {
    			layout : {
    				type : 'hbox', // Arrange child items vertically
    				align : 'middle', // Each takes up full width
    			},
    			width : '100%',
    			bodyPadding : 10,
    			bodyStyle : {
    				background : '#9A9494',
    			},
    			items : [
    					{
    						xtype : 'container',
    						itemId : 'iterationFilter'
    					}, {
    						xtype : 'rallybutton',
    						text : 'Print Summary',
    						handler : function () {
    							this._printSummary();
    						},
    						style : {
    							marginRight : '10px',
    							marginLeft : '10px'
    						},
    						// flex:'1',
    						scope : this
    					}
    			/*
    			 * { xtype:'rallybutton', text: 'Print Defects', handler: function() { this._printDefects(); }, style: { marginLeft: '10px' },
    			 *
    			 * flex:'1', scope:this }
    			 */
    			]
    		} );
    		this.add( panel1 );
    		var panel2 = Ext.create( 'Ext.panel.Panel', {
    			layout : 'vbox',
    			width : '100%',
    			bodyPadding : 10,
    			bodyStyle : {
    				background : '#9A9494',
    			},
    			items : [

    				{
    					xtype : 'container',
    					layout : 'accordion',
    					itemId : 'testStatus',
    					width : '100%',
    					height : 500
    				}
    			]
    		} );

    		this.add( panel2 );
    		this._testSummary = [];
    		this._testResultList = [];
    		this._testSetTestList = [];
    		var TestSetStore;
    		var TestResultStore;
    		scope: this;

    		this.down( '#iterationFilter' ).add( {
    			xtype : 'rallyiterationcombobox',
    			itemId : 'iterationComboBox',
    			listeners : {
    				change : this._queryForTestSets,
    				ready : this._queryForTestSets,
    				scope : this
    			}
    		} );
    		;
    	},
    	_queryForTestSets : function () {

    		// if loading new iteration, destroy existing grids
    		if ( this._summaryGrid !== undefined ) {
    			this._summaryGrid.destroy();
    			this._Grid.destroy();
    			this._Grid2.destroy();
    		}

    		TestSetStore = Ext.create( 'Rally.data.WsapiDataStore', {
    			model : 'TestSet',
    			autoLoad : true,
    			storeId : 'TestSetStorer',
    			context : {
    				projectScopeUp : false,
    				projectScopeDown : true
    			},
    			filters : [
    					{
    						property : 'Project',
    						operator : '=',
    						value : this.getContext().getDataContext().project
    					}, {
    						property : 'Iteration.Name',
    						operator : '=',
    						value : this.down( '#iterationComboBox' ).getRecord().data.Name
    					}
    			],
    			fetch : [
    					'FormattedID', 'Name', 'TestCases', 'ObjectID', 'Project'
    			],
    			limit : 10000,
    			listeners : {
    				load : function ( store, data, success ) {
    					this._queryForTestResults( store, data )
    				},
    				scope : this
    			}
    		} );
    	},
});
<|endoftext|>