<commit_before>define(['marionette', 'views/dialog',
    'collections/datacollections',
    'models/datacollection',
    'modules/mc/views/dcdistl',
    'tpl!templates/dc/reprocess.html', 'tpl!templates/dc/reprocess_dc.html'], function(Marionette, DialogView,
        DataCollections, DataCollection, DCDistlView,
        template, dctemplate) {

    var IDDataCollection = DataCollection.extend({
        idAttribute: 'CID',
    })

    var IDDataCollections = DataCollections.extend({
        model: IDDataCollection,
    })

    var DCDistlViewLarge = DCDistlView.extend({
        template: dctemplate,
        intStatus: false,
        className: 'data_collection',

        ui: {
            cells: '.cells',
            a: '.a',
            b: '.bb',
            c: '.c',
            al: '.al',
            be: '.be',
            ga: '.ga',
            cell: 'div.cell',
            st: 'input[name=start]',
            en: 'input[name=end]',
            ind: 'div.ind',
        },

        events: {
            'click .cells': 'sendCell',
            'click a.add': 'clone',
            'click a.rem': 'rem',
            'click a.sg': 'toggleSG',
            'change @ui.st': 'updateSelection',
            'change @ui.en': 'updateSelection',
            'keyup @ui.st': 'updateSelection',
            'keyup @ui.en': 'updateSelection',
            'click a.all': 'selectAll',
        },

        selectAll: function(e) {
            e.preventDefault()

            var si = parseInt(this.model.get('SI'))
            var ni = parseInt(this.model.get('NUMIMG'))

            this.ui.st.val(si)
            this.ui.en.val(si+ni)
            this.updateSelection()
        },

        updateSelection: function() {
            var si = parseInt(this.model.get('SI'))
            var ni = parseInt(this.model.get('NUMIMG'))

            if (this.ui.st.val() > (si+ni)) this.ui.st.val(si+ni)
            if (this.ui.st.val() < si) this.ui.st.val(si)

            if (this.ui.en.val() > (si+ni)) this.ui.en.val(si+ni)
            if (this.ui.en.val() < si) this.ui.en.val(si)

            this.plotview.setSelection(parseInt(this.ui.st.val()), parseInt(this.ui.en.val()))
        },

        initialize: function(options) {
            DCDistlView.prototype.initialize.apply(this, arguments)
            this.updateSelection = _.debounce(this.updateSelection, 500)
        },

        setInd: function(ind) {
            ind ? this.ui.ind.show() : this.ui.ind.hide()
            ind ? this.$el.find('ul').removeClass('half') : this.$el.find('ul').addClass('half')
        },

        onRender: function() {
            // DCDistlView.prototype.onRender.apply(this, arguments)
            this.ui.cell.hide()
            this.ui.ind.hide()
            this.$el.find('ul').addClass('half')
            this.$el.find('li input[type="text"]').css('width', '27%')
        },

        toggleSG: function(e) {
            e.preventDefault()
            this.ui.cell.slideToggle()
        },

        rem: function(e) {
            e.preventDefault()
            this.model.collection.remove(this.model)
        },

        clone: function(e) {
            e.preventDefault()
            this.trigger('clone:dc', this.model)
        },

        setCell: function() {
            if (this.aps.length) {
                var e = this.aps.at(0)
                var c = e.get('CELL')

                this.ui.a.text(c['CELL_A'])
                this.ui.b.text(c['CELL_B'])
                this.ui.c.text(c['CELL_C'])
                this.ui.al.text(c['CELL_AL'])
                this.ui.be.text(c['CELL_BE'])
                this.ui.ga.text(c['CELL_GA'])
            }
        },

        setSelection: function(x1, x2) {
            DCDistlView.prototype.setSelection.apply(this, arguments)
            this.ui.st.val(x1)
            this.ui.en.val(x2)
        },

        setDeselection: function() {
            DCDistlView.prototype.setDeselection.apply(this)
            this.ui.st.val('')
            this.ui.en.val('')
        }
    })

    var DCDistlsView = Marionette.CollectionView.extend({
        childView: DCDistlViewLarge,
    })

    return ReprocessView = DialogView.extend({
        template: template,
        dialog: true,
        title: 'Reprocess Data',
        className: 'rp content',

        regions: {
            dcr: '.dcs',
        },

        ui: {
            cell: 'div.cell',
            opts: 'div.options',
            ind: 'input[name=individual]',
            mul: 'span.multi',
            met: 'select[name=method]',
        },

        buttons: {
            Integrate: 'integrate',
            Close: 'closeDialog',
        },

        events: {
            'click a.sgm': 'toggleCell',
            'click a.opt': 'toggleOpts',
            'click @ui.ind': 'toggleIndividual',
        },

        toggleIndividual: function(e) {
            var st = this.ui.ind.is(':checked')
            st ? this.ui.mul.hide() : this.ui.mul.show()
            this.distlview.children.each(function(v) {
                v.setInd(st)
            })
        },

        toggleCell: function(e) {
            e.preventDefault()
            this.ui.cell.slideToggle()
        },

        toggleOpts: function(e) {
            e.preventDefault()
            this.ui.opts.slideToggle()
        },

        integrate: function(e) {
            e.preventDefault()
            var s = this.collection.where({ selected: true })

            if (!s.length) {
                app.alert({ message: 'Please selected some data sets to integrate' })
                return
            }

            var data = { visit: this.getOption('visit'), multi: 1 }
            var integrate = []
            _.each(s, function(s, i) {
                integrate.push([s.get('ID'), s.get('selection')[0], s.get('selection')[1]])
            })

            data.int = integrate
            data.recipes = this.ui.met.val()

            _.each(['a', 'b', 'c', 'alpha', 'beta', 'gamma', 'res', 'sg'], function(f, i) {
                data[f] = this.$el.find('input[name='+f+']').val().replace(/\s/g, '')
            }, this)

            Backbone.ajax({
                url: app.apiurl+'/mc/integrate',
                data: data,
                type: 'POST',

                success: function() {
                    app.alert({ message: s.length+' job(s) successfully submitted'})
                },

                error: function() {
                    app.alert({ message: 'Something went wrong submitting these jobs, please try again'})
                }
            })
        },

        initialize: function(options) {
            this.collection = new IDDataCollections()
            if (options.model) {
                var nm = new IDDataCollection(options.model.toJSON())
                nm.set('CID', this.collection.length+1)
                this.collection.add(nm)
            }
        },

        onRender: function() {
            this.ui.opts.hide()
            this.ui.cell.hide()

            _.each(['Fast DP', 'Xia2', 'DIALS'], function(t,i) {
                this.ui.met.append('<option value="'+(i+1)+'">'+t+'</option>')
            }, this)

            this.distlview = new DCDistlsView({ collection: this.collection })
            this.dcr.show(this.distlview)
            this.listenTo(this.distlview, 'childview:set:cell', this.setCell, this)
            this.listenTo(this.distlview, 'childview:clone:dc', this.cloneDC, this)
        },

        cloneDC: function(e, model) {
            var nm = model.clone()
            nm.set('CID', this.collection.length+1)
            this.collection.add(nm)
        },

        setCell: function(view, ap) {
            console.log('set cell main view', view, ap)
            _.each({'a': 'a', 'b': 'b', 'c': 'c', 'alpha': 'al', 'beta': 'be', 'gamma': 'ga'}, function(k,f) {
                this.$el.find('input[name='+f+']').val(ap.get('CELL')['CELL_'+k.toUpperCase()])
            }, this)

            this.$el.find('input[name=sg]').val(ap.get('SG'))
        },

    })

})<commit_msg>update pipelines<commit_after>define(['marionette', 'views/dialog',
    'collections/datacollections',
    'models/datacollection',
    'modules/mc/views/dcdistl',
    'tpl!templates/dc/reprocess.html', 'tpl!templates/dc/reprocess_dc.html'], function(Marionette, DialogView,
        DataCollections, DataCollection, DCDistlView,
        template, dctemplate) {

    var IDDataCollection = DataCollection.extend({
        idAttribute: 'CID',
    })

    var IDDataCollections = DataCollections.extend({
        model: IDDataCollection,
    })

    var DCDistlViewLarge = DCDistlView.extend({
        template: dctemplate,
        intStatus: false,
        className: 'data_collection',

        ui: {
            cells: '.cells',
            a: '.a',
            b: '.bb',
            c: '.c',
            al: '.al',
            be: '.be',
            ga: '.ga',
            cell: 'div.cell',
            st: 'input[name=start]',
            en: 'input[name=end]',
            ind: 'div.ind',
        },

        events: {
            'click .cells': 'sendCell',
            'click a.add': 'clone',
            'click a.rem': 'rem',
            'click a.sg': 'toggleSG',
            'change @ui.st': 'updateSelection',
            'change @ui.en': 'updateSelection',
            'keyup @ui.st': 'updateSelection',
            'keyup @ui.en': 'updateSelection',
            'click a.all': 'selectAll',
        },

        selectAll: function(e) {
            e.preventDefault()

            var si = parseInt(this.model.get('SI'))
            var ni = parseInt(this.model.get('NUMIMG'))

            this.ui.st.val(si)
            this.ui.en.val(si+ni)
            this.updateSelection()
        },

        updateSelection: function() {
            var si = parseInt(this.model.get('SI'))
            var ni = parseInt(this.model.get('NUMIMG'))

            if (this.ui.st.val() > (si+ni)) this.ui.st.val(si+ni)
            if (this.ui.st.val() < si) this.ui.st.val(si)

            if (this.ui.en.val() > (si+ni)) this.ui.en.val(si+ni)
            if (this.ui.en.val() < si) this.ui.en.val(si)

            this.plotview.setSelection(parseInt(this.ui.st.val()), parseInt(this.ui.en.val()))
        },

        initialize: function(options) {
            DCDistlView.prototype.initialize.apply(this, arguments)
            this.updateSelection = _.debounce(this.updateSelection, 500)
        },

        setInd: function(ind) {
            ind ? this.ui.ind.show() : this.ui.ind.hide()
            ind ? this.$el.find('ul').removeClass('half') : this.$el.find('ul').addClass('half')
        },

        onRender: function() {
            // DCDistlView.prototype.onRender.apply(this, arguments)
            this.ui.cell.hide()
            this.ui.ind.hide()
            this.$el.find('ul').addClass('half')
            this.$el.find('li input[type="text"]').css('width', '25%')
        },

        toggleSG: function(e) {
            e.preventDefault()
            this.ui.cell.slideToggle()
        },

        rem: function(e) {
            e.preventDefault()
            this.model.collection.remove(this.model)
        },

        clone: function(e) {
            e.preventDefault()
            this.trigger('clone:dc', this.model)
        },

        setCell: function() {
            if (this.aps.length) {
                var e = this.aps.at(0)
                var c = e.get('CELL')

                this.ui.a.text(c['CELL_A'])
                this.ui.b.text(c['CELL_B'])
                this.ui.c.text(c['CELL_C'])
                this.ui.al.text(c['CELL_AL'])
                this.ui.be.text(c['CELL_BE'])
                this.ui.ga.text(c['CELL_GA'])
            }
        },

        setSelection: function(x1, x2) {
            DCDistlView.prototype.setSelection.apply(this, arguments)
            this.ui.st.val(x1)
            this.ui.en.val(x2)
        },

        setDeselection: function() {
            DCDistlView.prototype.setDeselection.apply(this)
            this.ui.st.val('')
            this.ui.en.val('')
        }
    })

    var DCDistlsView = Marionette.CollectionView.extend({
        childView: DCDistlViewLarge,
    })

    return ReprocessView = DialogView.extend({
        template: template,
        dialog: true,
        title: 'Reprocess Data',
        className: 'rp content',

        regions: {
            dcr: '.dcs',
        },

        ui: {
            cell: 'div.cell',
            opts: 'div.options',
            ind: 'input[name=individual]',
            mul: 'span.multi',
            met: 'select[name=method]',
        },

        buttons: {
            Integrate: 'integrate',
            Close: 'closeDialog',
        },

        events: {
            'click a.sgm': 'toggleCell',
            'click a.opt': 'toggleOpts',
            'click @ui.ind': 'toggleIndividual',
        },

        toggleIndividual: function(e) {
            var st = this.ui.ind.is(':checked')
            st ? this.ui.mul.hide() : this.ui.mul.show()
            this.distlview.children.each(function(v) {
                v.setInd(st)
            })
        },

        toggleCell: function(e) {
            e.preventDefault()
            this.ui.cell.slideToggle()
        },

        toggleOpts: function(e) {
            e.preventDefault()
            this.ui.opts.slideToggle()
        },

        integrate: function(e) {
            e.preventDefault()
            var s = this.collection.where({ selected: true })

            if (!s.length) {
                app.alert({ message: 'Please selected some data sets to integrate' })
                return
            }

            var data = { visit: this.getOption('visit'), multi: 1 }
            var integrate = []
            _.each(s, function(s, i) {
                integrate.push([s.get('ID'), s.get('selection')[0], s.get('selection')[1]])
            })

            data.int = integrate
            data.recipes = this.ui.met.val()

            _.each(['a', 'b', 'c', 'alpha', 'beta', 'gamma', 'res', 'sg'], function(f, i) {
                data[f] = this.$el.find('input[name='+f+']').val().replace(/\s/g, '')
            }, this)

            Backbone.ajax({
                url: app.apiurl+'/mc/integrate',
                data: data,
                type: 'POST',

                success: function() {
                    app.alert({ message: s.length+' job(s) successfully submitted'})
                },

                error: function() {
                    app.alert({ message: 'Something went wrong submitting these jobs, please try again'})
                }
            })
        },

        initialize: function(options) {
            this.collection = new IDDataCollections()
            if (options.model) {
                var nm = new IDDataCollection(options.model.toJSON())
                nm.set('CID', this.collection.length+1)
                this.collection.add(nm)
            }
        },

        onRender: function() {
            this.ui.opts.hide()
            this.ui.cell.hide()

            _.each(['xia2 3daii', 'xia2 dials'], function(t,i) {
                this.ui.met.append('<option value="'+(i+1)+'">'+t+'</option>')
            }, this)

            this.distlview = new DCDistlsView({ collection: this.collection })
            this.dcr.show(this.distlview)
            this.listenTo(this.distlview, 'childview:set:cell', this.setCell, this)
            this.listenTo(this.distlview, 'childview:clone:dc', this.cloneDC, this)
        },

        cloneDC: function(e, model) {
            var nm = model.clone()
            nm.set('CID', this.collection.length+1)
            this.collection.add(nm)
        },

        setCell: function(view, ap) {
            console.log('set cell main view', view, ap)
            _.each({'a': 'a', 'b': 'b', 'c': 'c', 'alpha': 'al', 'beta': 'be', 'gamma': 'ga'}, function(k,f) {
                this.$el.find('input[name='+f+']').val(ap.get('CELL')['CELL_'+k.toUpperCase()])
            }, this)

            this.$el.find('input[name=sg]').val(ap.get('SG'))
        },

    })

})<|endoftext|>


<commit_before>import LinkAnet from "components/editor/LinkAnet"
import LinkAnetEntity from "components/editor/LinkAnetEntity"
import "components/editor/RichTextEditor.css"
import Toolbar from "components/editor/Toolbar"
import escapeHtml from "escape-html"
import { debounce } from "lodash"
import _isEmpty from "lodash/isEmpty"
import PropTypes from "prop-types"
import React, { useCallback, useMemo, useState } from "react"
import { createEditor, Text } from "slate"
import { withHistory } from "slate-history"
import { jsx } from "slate-hyperscript"
import {
  Editable,
  Slate,
  useFocused,
  useSelected,
  withReact
} from "slate-react"
import { getUrlFromEntityInfo } from "utils_links"

const RichTextEditor = ({ value, onChange, onHandleBlur, className }) => {
  const withAnetLink = editor => {
    const { isVoid, isInline } = editor

    editor.isVoid = element =>
      element.type === "anet-link" ? true : isVoid(element)

    editor.isInline = element =>
      element.type === "anet-link" ? true : isInline(element)

    return editor
  }
  const editor = useMemo(
    () => withReact(withHistory(withAnetLink(createEditor()))),
    []
  )

  const [slateValue, setSlateValue] = useState(() => {
    const document = new DOMParser().parseFromString(value || "", "text/html")
    return deserialize(document.body)
  })

  const renderElement = useCallback(props => <Element {...props} />, [])
  const renderLeaf = useCallback(props => <Leaf {...props} />, [])

  return (

      <Slate
        editor={editor}
        value={slateValue}
        onChange={newValue => {
          setSlateValue(newValue)
          serializeDebounced(editor, onChange)
        }}
      >

          <Toolbar />
          <Editable
            renderElement={renderElement}
            renderLeaf={renderLeaf}
            onBlur={onHandleBlur}
            className="editable"
          />

      </Slate>

  )
}

RichTextEditor.propTypes = {
  value: PropTypes.string,
  onChange: PropTypes.func,
  onHandleBlur: PropTypes.func,
  className: PropTypes.string
}

const serialize = (node, onChange) => {
  if (Text.isText(node)) {
    let string = escapeHtml(node.text)
    if (node.bold) {
      string = `<strong>${string}</strong>`
    }
    if (node.italic) {
      string = `<em>${string}</em>`
    }
    if (node.code) {
      string = `<code>${string}</code>`
    }
    if (node.underline) {
      string = `<u>${string}</u>`
    }
    if (node.strikethrough) {
      string = `<strike>${string}</strike>`
    }
    return string
  }
  const children = node.children.map(n => serialize(n)).join("")
  switch (node.type) {
    case "paragraph":
      return `<p>${children}</p>`
    case "block-quote":
      return `<blockquote>${children}</blockquote>`
    case "bulleted-list":
      return `<ul>${children}</ul>`
    case "heading-one":
      return `<h1>${children}</h1>`
    case "heading-two":
      return `<h2>${children}</h2>`
    case "heading-three":
      return `<h3>${children}</h3>`
    case "list-item":
      return `<li>${children}</li>`
    case "numbered-list":
      return `<ol>${children}</ol>`
    case "anet-link":
      return `<a href="${getUrlFromEntityInfo(node)}">${node.children.text}</a>`
    default:
      onChange(children)
      return children
  }
}

const serializeDebounced = debounce(serialize, 100)

const deserialize = element => {
  let children = Array.from(element.childNodes).map(deserialize)
  // Body must have at least one children node for user to be able to edit the text in it
  // Every other node must have a non-empty array of children
  if (element.nodeName !== "#text" && _isEmpty(children)) {
    children =
      element.nodeName === "BODY"
        ? jsx("element", { type: "paragraph" }, [{ text: "" }])
        : [{ text: "" }]
  }

  switch (element.nodeName) {
    case "BODY":
      return jsx("fragment", {}, children)
    case "P":
      return jsx("element", { type: "paragraph" }, children)
    case "STRONG":
      return jsx("text", { bold: true }, children)
    case "EM":
      return jsx("text", { italic: true }, children)
    case "U":
      return jsx("text", { underline: true }, children)
    case "STRIKE":
      return jsx("text", { strikethrough: true }, children)
    case "H1":
      return jsx("element", { type: "heading-one" }, children)
    case "H2":
      return jsx("element", { type: "heading-two" }, children)
    case "H3":
      return jsx("element", { type: "heading-three" }, children)
    case "BLOCKQUOTE":
      return jsx("element", { type: "block-quote" }, children)
    case "LI":
      return jsx("element", { type: "list-item" }, children)
    case "UL":
      return jsx("element", { type: "bulleted-list" }, children)
    case "OL":
      return jsx("element", { type: "numbered-list" }, children)
    case "A":
      return jsx(
        "element",
        { type: "anet-link", href: element.getAttribute("href") },
        children
      )
    default:
      // Text cannot be the direct child of BODY. If the value is plain text without any html tags, we should be wrapped in a "

" tag
      return element.parentNode.nodeName === "BODY"
        ? jsx("element", { type: "paragraph" }, element.textContent)
        : element.textContent
  }
}

const Element = ({ attributes, children, element }) => {
  const selected = useSelected()
  const focused = useFocused()
  switch (element.type) {
    case "block-quote":
      return
{children}

    case "bulleted-list":
      return
{children}

    case "heading-one":
      return
{children}

    case "heading-two":
      return
{children}

    case "heading-three":
      return
{children}

    case "list-item":
      return
{children}

    case "numbered-list":
      return
{children}

    case "anet-link":
      return (

          {element.href ? (
            <LinkAnet url={element.href} />
          ) : (
            <LinkAnetEntity
              type={element.entityType}
              uuid={element.entityUuid}
            />
          )}
          {children}

      )
    default:
      return
{children}

  }
}

Element.propTypes = {
  attributes: PropTypes.object.isRequired,
  children: PropTypes.node,
  element: PropTypes.object
}

const Leaf = ({ attributes, children, leaf }) => {
  if (leaf.bold) {
    children = {children}
  }

  if (leaf.code) {
    children = {children}
  }

  if (leaf.italic) {
    children = {children}
  }

  if (leaf.underline) {
    children = {children}
  }

  if (leaf.strikethrough) {
    children = {children}
  }

  if (leaf.highlight) {
    children = {children}
  }

  return {children}
}

Leaf.propTypes = {
  attributes: PropTypes.object.isRequired,
  children: PropTypes.node,
  leaf: PropTypes.object
}

export default RichTextEditor
<commit_msg>NCI-Agency/anet#3762: Add paste functionality<commit_after>import LinkAnet from "components/editor/LinkAnet"
import LinkAnetEntity from "components/editor/LinkAnetEntity"
import "components/editor/RichTextEditor.css"
import Toolbar from "components/editor/Toolbar"
import escapeHtml from "escape-html"
import { debounce } from "lodash"
import _isEmpty from "lodash/isEmpty"
import _trim from "lodash/trim"
import PropTypes from "prop-types"
import React, { useCallback, useMemo, useState } from "react"
import { createEditor, Text, Transforms } from "slate"
import { withHistory } from "slate-history"
import { jsx } from "slate-hyperscript"
import {
  Editable,
  Slate,
  useFocused,
  useSelected,
  withReact
} from "slate-react"
import { getUrlFromEntityInfo } from "utils_links"

const RichTextEditor = ({ value, onChange, onHandleBlur, className }) => {
  const editor = useMemo(
    () => withHtml(withReact(withHistory(withAnetLink(createEditor())))),
    []
  )

  const [slateValue, setSlateValue] = useState(() => {
    const document = new DOMParser().parseFromString(value || "", "text/html")
    return deserialize(document.body)
  })

  const renderElement = useCallback(props => <Element {...props} />, [])
  const renderLeaf = useCallback(props => <Leaf {...props} />, [])

  return (

      <Slate
        editor={editor}
        value={slateValue}
        onChange={newValue => {
          setSlateValue(newValue)
          serializeDebounced(editor, onChange)
        }}
      >

          <Toolbar />
          <Editable
            renderElement={renderElement}
            renderLeaf={renderLeaf}
            onBlur={onHandleBlur}
            className="editable"
          />

      </Slate>

  )
}

RichTextEditor.propTypes = {
  value: PropTypes.string,
  onChange: PropTypes.func,
  onHandleBlur: PropTypes.func,
  className: PropTypes.string
}

const withHtml = editor => {
  const { insertData } = editor
  editor.insertData = data => {
    const html = data?.getData("text/html")
    if (html) {
      const parsed = new DOMParser().parseFromString(html, "text/html")
      const nodes = deserialize(parsed.body)
      Transforms.insertNodes(editor, nodes)
    } else {
      insertData(data)
    }
  }
  return editor
}

const withAnetLink = editor => {
  const { isVoid, isInline } = editor
  editor.isVoid = element =>
    element.type === "anet-link" ? true : isVoid(element)
  editor.isInline = element =>
    element.type === "anet-link" ? true : isInline(element)
  return editor
}

const serialize = (node, onChange) => {
  if (Text.isText(node)) {
    let string = escapeHtml(node.text)
    if (node.bold) {
      string = `<strong>${string}</strong>`
    }
    if (node.italic) {
      string = `<em>${string}</em>`
    }
    if (node.code) {
      string = `<code>${string}</code>`
    }
    if (node.underline) {
      string = `<u>${string}</u>`
    }
    if (node.strikethrough) {
      string = `<strike>${string}</strike>`
    }
    return string
  }
  const children = node.children.map(n => serialize(n)).join("")
  switch (node.type) {
    case "paragraph":
      return `<p>${children}</p>`
    case "block-quote":
      return `<blockquote>${children}</blockquote>`
    case "bulleted-list":
      return `<ul>${children}</ul>`
    case "heading-one":
      return `<h1>${children}</h1>`
    case "heading-two":
      return `<h2>${children}</h2>`
    case "heading-three":
      return `<h3>${children}</h3>`
    case "list-item":
      return `<li>${children}</li>`
    case "numbered-list":
      return `<ol>${children}</ol>`
    case "anet-link":
      return `<a href="${getUrlFromEntityInfo(node)}">${node.children.text}</a>`
    default:
      onChange(children)
      return children
  }
}

const serializeDebounced = debounce(serialize, 100)

const deserialize = element => {
  if (
    element.nodeName === "#text" &&
    _isEmpty(_trim(element.textContent, "\n"))
  ) {
    // Skip empty elements
    return null
  }
  let children = Array.from(element.childNodes).map(deserialize)
  // Body must have at least one children node for user to be able to edit the text in it
  // Every other node must have a non-empty array of children
  if (element.nodeName !== "#text" && _isEmpty(children)) {
    children =
      element.nodeName === "BODY"
        ? jsx("element", { type: "paragraph" }, [{ text: "" }])
        : [{ text: "" }]
  }

  switch (element.nodeName) {
    case "BODY":
      return jsx("fragment", {}, children)
    case "P":
      return jsx("element", { type: "paragraph" }, children)
    case "STRONG":
    case "B":
      return jsx("text", { bold: true }, children)
    case "EM":
    case "I":
      return jsx("text", { italic: true }, children)
    case "U":
      return jsx("text", { underline: true }, children)
    case "STRIKE":
      return jsx("text", { strikethrough: true }, children)
    case "H1":
      return jsx("element", { type: "heading-one" }, children)
    case "H2":
      return jsx("element", { type: "heading-two" }, children)
    case "H3":
      return jsx("element", { type: "heading-three" }, children)
    case "BLOCKQUOTE":
    case "CITE":
      return jsx("element", { type: "block-quote" }, children)
    case "LI":
      return jsx("element", { type: "list-item" }, children)
    case "UL":
      return jsx("element", { type: "bulleted-list" }, children)
    case "OL":
      return jsx("element", { type: "numbered-list" }, children)
    case "A":
      return jsx(
        "element",
        { type: "anet-link", href: element.getAttribute("href") },
        children
      )
    default:
      // Text cannot be the direct child of BODY. If the value is plain text without any html tags, we should be wrapped in a "

" tag
      return element.parentNode.nodeName === "BODY"
        ? jsx("element", { type: "paragraph" }, element.textContent)
        : element.textContent
  }
}

const Element = ({ attributes, children, element }) => {
  const selected = useSelected()
  const focused = useFocused()
  switch (element.type) {
    case "block-quote":
      return
{children}

    case "bulleted-list":
      return
{children}

    case "heading-one":
      return
{children}

    case "heading-two":
      return
{children}

    case "heading-three":
      return
{children}

    case "list-item":
      return
{children}

    case "numbered-list":
      return
{children}

    case "anet-link":
      return (

          {element.href ? (
            <LinkAnet url={element.href} />
          ) : (
            <LinkAnetEntity
              type={element.entityType}
              uuid={element.entityUuid}
            />
          )}
          {children}

      )
    default:
      return
{children}

  }
}

Element.propTypes = {
  attributes: PropTypes.object.isRequired,
  children: PropTypes.node,
  element: PropTypes.object
}

const Leaf = ({ attributes, children, leaf }) => {
  if (leaf.bold) {
    children = {children}
  }

  if (leaf.code) {
    children = {children}
  }

  if (leaf.italic) {
    children = {children}
  }

  if (leaf.underline) {
    children = {children}
  }

  if (leaf.strikethrough) {
    children = {children}
  }

  if (leaf.highlight) {
    children = {children}
  }

  return {children}
}

Leaf.propTypes = {
  attributes: PropTypes.object.isRequired,
  children: PropTypes.node,
  leaf: PropTypes.object
}

export default RichTextEditor
<|endoftext|>


<commit_before>import { h } from 'hyperapp';

export const TopBar = ({ state, switchSettings }) =>

            <IndicatorBattery batteryLevel={state.batteryLevel} />
            <IndicatorSignal signalLevel={state.signalLevel} />

            {/*  */}
            {/*   */}
            {/*  */}
            {/*   */}
            <ActionFullscreen />

 switchSettings()}>

;

const IndicatorBattery = ({ batteryLevel }) =>
    ;

const IndicatorSignal = ({ signalLevel }) =>
    ;

const batteryLevelIcon = (batteryLevel) => {
    if ((batteryLevel >= 19.5) === (batteryLevel < 21.5)) {
        return require('../../../img/ui/battery-1.svg');
    } else if ((batteryLevel >= 21.5) === (batteryLevel < 23)) {
        return require('../../../img/ui/battery-2.svg');
    } else if ((batteryLevel >= 23) === (batteryLevel < 24)) {
        return require('../../../img/ui/battery-3.svg');
    } else if (batteryLevel >= 24) {
        return require('../../../img/ui/battery-4.svg');
    } else {
        return require('../../../img/ui/battery-0.svg');
    }
};

const signalLevelIcon = (signalLevel) => {
    if ((signalLevel >= 80) === (signalLevel < 85)) {
        return require('../../../img/ui/signal-1.svg');
    } else if ((signalLevel >= 85) === (signalLevel < 90)) {
        return require('../../../img/ui/signal-2.svg');
    } else if ((signalLevel >= 90) === (signalLevel < 95)) {
        return require('../../../img/ui/signal-3.svg');
    } else if (signalLevel >= 95) {
        return require('../../../img/ui/signal-4.svg');
    } else {
        return require('../../../img/ui/signal-0.svg');
    }
};

const ActionFullscreen = () =>
     toggleFullscreen(el.target)}
    />;

const toggleFullscreen = () => {
    const main = document.documentElement;
    if (!document.fullscreenElement) {
        if (main.mozRequestFullScreen) {
            main.mozRequestFullScreen();
        } else {
            main.webkitRequestFullScreen();
        }
    } else {
        document.exitFullscreen();
        if (document.mozCancelFullScreen) {
            document.mozCancelFullScreen();
        } else if (document.webkitExitFullscreen) {
            document.webkitExitFullscreen();
        }
    }
};
<commit_msg>fix toggle fullscreen<commit_after>import { h } from 'hyperapp';

export const TopBar = ({ state, switchSettings }) =>

            <IndicatorBattery batteryLevel={state.batteryLevel} />
            <IndicatorSignal signalLevel={state.signalLevel} />

            {/*  */}
            {/*   */}
            {/*  */}
            {/*   */}
            <ActionFullscreen />

 switchSettings()}>

;

const IndicatorBattery = ({ batteryLevel }) =>
    ;

const IndicatorSignal = ({ signalLevel }) =>
    ;

const batteryLevelIcon = (batteryLevel) => {
    if ((batteryLevel >= 19.5) === (batteryLevel < 21.5)) {
        return require('../../../img/ui/battery-1.svg');
    } else if ((batteryLevel >= 21.5) === (batteryLevel < 23)) {
        return require('../../../img/ui/battery-2.svg');
    } else if ((batteryLevel >= 23) === (batteryLevel < 24)) {
        return require('../../../img/ui/battery-3.svg');
    } else if (batteryLevel >= 24) {
        return require('../../../img/ui/battery-4.svg');
    } else {
        return require('../../../img/ui/battery-0.svg');
    }
};

const signalLevelIcon = (signalLevel) => {
    if ((signalLevel >= 80) === (signalLevel < 85)) {
        return require('../../../img/ui/signal-1.svg');
    } else if ((signalLevel >= 85) === (signalLevel < 90)) {
        return require('../../../img/ui/signal-2.svg');
    } else if ((signalLevel >= 90) === (signalLevel < 95)) {
        return require('../../../img/ui/signal-3.svg');
    } else if (signalLevel >= 95) {
        return require('../../../img/ui/signal-4.svg');
    } else {
        return require('../../../img/ui/signal-0.svg');
    }
};

const ActionFullscreen = () =>
     toggleFullscreen(event)}
    />;

// https://gist.github.com/demonixis/5188326
const toggleFullscreen = (event) => {
    console.log(event);

    let element = document.body;
    if (event instanceof window.HTMLElement) {
        element = event;
    }

    const isFullscreen = document.webkitIsFullScreen || document.mozFullScreen || false;

    element.requestFullScreen = element.requestFullScreen || element.webkitRequestFullScreen || element.mozRequestFullScreen || function () { return false; };
    document.cancelFullScreen = document.cancelFullScreen || document.webkitCancelFullScreen || document.mozCancelFullScreen || function () { return false; };

    isFullscreen ? document.cancelFullScreen() : element.requestFullScreen();
};
<|endoftext|>


<commit_before>Template.groupsInput.onRendered(function() {
  this.subscribe('groups', () => {
    Tracker.afterFlush(() => {
      this.$('.ui.dropdown').dropdown();
    });
  });
});

Template.groupsInput.helpers({
  groups: () => Groups.find()
});<commit_msg>publishing groups for groupsinput lazily<commit_after>Template.groupsInput.onCreated(function() {
  this.search = new ReactiveVar();

  this.autorun(() => {
    this.subscribe('groups', this.search.get());
  });
});

Template.groupsInput.onRendered(function() {
  this.autorun(() => {
    Template.currentData();

    this.$('.ui.dropdown').dropdown({
      allowAdditions: true,
      fullTextSearch: true
    });
  });
});

Template.groupsInput.helpers({
  groups: () => Groups.find()
});

Template.groupsInput.events({
  'keyup input.search': function(event, template) {
    template.search.set(event.target.value);
  }
});<|endoftext|>


<commit_before>import File from './file';

export default class Package extends File {
  async templateRepo(context) {
    const content = await this.originalContent(context, {
      ignoreMissing: true
    });
    const pkg = JSON.parse(content);
    if (pkg.template !== undefined && pkg.template.repository !== undefined) {
      const m = pkg.template.repository.url.match(/github.com\/(.*)\.git$/);
      return m[1];
    }

    return undefined;
  }

  async mergeContent(context, original, templateContent) {
    const originalLastChar = original[original.length - 1];

    let target =
      original === undefined || original === '' ? {} : JSON.parse(original);
    const template = JSON.parse(templateContent);
    const messages = [];
    const properties = context.properties;

    if (target.name === undefined || target.name === '') {
      const m = context.targetRepo.name.match(/^([^\/]+)\/(.*)/);
      target.name = m ? m[2] : context.targetRepo.name;
    }

    if (target.module !== undefined && !target.module.match(/\{\{module\}\}/)) {
      properties.module = target.module;
    }

    properties.main =
      target.main && !target.main.match(/\{\{main\}\}/)
        ? target.main
        : 'dist/index.js';

    const githubURL = `git+https://github.com/${properties.user}/${target.name}.git`;
    const githubURLAlternative = `git+https://github.com/${properties.user}/node-${target.name}.git`;

    let repoName = target.name;

    if (
      target.repository === undefined ||
      (target.repository.url !== githubURL &&
        target.repository.url !== githubURLAlternative)
    ) {
      target.repository = {
        type: 'git',
        url: githubURL
      };
      messages.push(`chore(package): correct github url`);
    }

    if (
      target.repository !== undefined &&
      githubURLAlternative === target.repository.url
    ) {
      repoName = `node-${target.name}`;
    }

    const bugsURL = `https://github.com/${properties.user}/${repoName}/issues`;

    if (target.bugs === undefined || target.bugs.url !== bugsURL) {
      target.bugs = {
        url: bugsURL
      };
      messages.push(`chore(package): correct bugs url`);
    }

    const homepageURL = `https://github.com/${properties.user}/${repoName}#readme`;

    if (target.homepage === undefined || target.homepage !== homepageURL) {
      target.homepage = homepageURL;
      messages.push(`chore(package): correct hompage url`);
    }

    let buildOutput;
    const extraBuilds = {};

    if (target.scripts !== undefined) {
      Object.keys(target.scripts).forEach(key => {
        const script = target.scripts[key];
        const ma = script.match(/--output=([^\s]+)/);
        if (ma) {
          buildOutput = ma[1];
        }

        if (template.scripts !== undefined) {
          const templateScript = template.scripts[key];
          if (templateScript !== undefined) {
            const mb = script.match(/&&\s*(.+)$/);
            if (mb && !templateScript.includes(mb[1])) {
              extraBuilds[key] = mb[1];
            }
          }
        }
      });
    }

    const deepPropeties = {
      scripts: {},
      devDependencies: {},
      engines: {}
    };

    Object.keys(deepPropeties).forEach(p => {
      if (target[p] === undefined) {
        target[p] = {};
      }

      if (template[p] !== undefined) {
        Object.keys(template[p]).forEach(d => {
          if (template[p][d] === '-') {
            if (target[p][d] !== undefined) {
              messages.push(`chore(${p}): remove ${d}@${target[p][d]}`);
              delete target[p][d];
            }
          } else {
            const tp = context.expand(template[p][d]);
            if (tp !== target[p][d]) {
              messages.push(
                target[p][d] === undefined
                  ? `chore(${p}): add ${d}@${tp} from template`
                  : `chore(${p}): update ${d}@${tp} from template`
              );
              target[p][d] = tp;
            }
          }
        });
      }
    });

    Object.keys(template).forEach(p => {
      if (p !== 'template') {
        if (target[p] === undefined) {
          target[p] = template[p];
        }
      }
    });

    if (target.scripts.prepare) {
      if (buildOutput !== undefined) {
        target.scripts.prepare = target.scripts.prepare.replace(
          /--output=([^\s]+)/,
          `--output=${buildOutput}`
        );
      }
    }

    Object.keys(extraBuilds).forEach(key => {
      target.scripts[key] += ` && ${extraBuilds[key]}`;
    });

    if (target.module === '{{module}}') {
      delete target.module;
    }

    if (
      target.contributors !== undefined &&
      target.author !== undefined &&
      target.author.name !== undefined
    ) {
      const m = target.author.name.match(/(^[^<]+)<([^>]+)>/);
      if (m !== undefined) {
        const name = String(m[1]).replace(/^\s+|\s+$/g, '');
        const email = m[2];

        if (
          target.contributors.find(c => c.name === name && c.email === email)
        ) {
          delete target.author;
        }
      }
    }

    if (
      target.template === undefined ||
      target.template.repository === undefined ||
      target.template.repository.url !==
        `https://github.com/${context.templateRepo.name}.git`
    ) {
      messages.push('chore(package): set template repo');

      target.template = {
        repository: {
          url: `https://github.com/${context.templateRepo.name}.git`
        }
      };
    }

    // TODO loop over all rollup files
    const usedModules = (await Promise.all(
      ['rollup.config.js', 'tests/rollup.config.js'].map(async file => {
        const rcj = await context.files.get(file);
        if (rcj) {
          const m = await rcj.merge(context);
          return rcj.usedDevModules(m.content);
        }
        return new Set();
      })
    )).reduce((sum, current) => new Set([...sum, ...current]), new Set());

    Object.keys(target.devDependencies)
      .filter(m => {
        if (m.match(/rollup-plugin/) || m.match(/babel-preset/)) {
          return usedModules.has(m) ? false : true;
        }

        return false;
      })
      .forEach(toBeRemoved => {
        delete target.devDependencies[toBeRemoved];
      });

    target = deleter(target, template, messages, []);

    if (target.keywords !== undefined) {
      delete target.keywords['npm-package-template'];
    }

    if (
      template.template !== undefined &&
      template.template.keywords !== undefined
    ) {
      Object.keys(template.template.keywords).forEach(r =>
        addKeyword(
          target,
          new RegExp(r),
          template.template.keywords[r],
          messages
        )
      );
    }

    removeKeyword(target, ['null', null, undefined], messages);

    if (messages.length === 0) {
      messages.push('chore: update package.json from template');
    }

    let newContent = JSON.stringify(context.expand(target), undefined, 2);
    const lastChar = newContent[newContent.length - 1];

    // keep trailing newline
    if (originalLastChar === '\n' && lastChar === '}') {
      newContent += '\n';
    }

    return {
      content: newContent,
      messages,
      path: this.path,
      changed: original !== newContent
    };
  }
}

function deleter(object, reference, messages, path) {
  if (
    typeof object === 'string' ||
    object instanceof String ||
    object === true ||
    object === false ||
    object === undefined ||
    object === null ||
    typeof object === 'number' ||
    object instanceof Number
  ) {
    return object;
  }

  Object.keys(reference).forEach(key => {
    path.push(key);

    if (reference[key] === '--delete--' && object[key] !== undefined) {
      if (object[key] !== '--delete--') {
        messages.push(`chore(npm): delete ${path.join('.')}`);
      }
      delete object[key];
    } else {
      object[key] = deleter(object[key], reference[key], messages, path);
    }
    path.pop();
  });

  return object;
}

function removeKeyword(pkg, keywords, messages) {
  if (pkg.keywords !== undefined) {
    keywords.forEach(keyword => {
      if (pkg.keywords.find(k => k === keyword)) {
        messages.push(`docs(package): remove keyword ${keyword}`);
        pkg.keywords = pkg.keywords.filter(k => k !== keyword);
      }
    });

    if (pkg.keywords[0] === null || pkg.keywords[0] === undefined) {
      messages.push(`docs(package): remove keyword null`);
      pkg.keywords = [];
    }
  }
}

function addKeyword(pkg, regex, keyword, messages) {
  if (keyword === undefined || keyword === null || keyword === 'null') {
    return;
  }

  if (pkg.name.match(regex)) {
    if (pkg.keywords === undefined) {
      pkg.keywords = [];
    }
    if (!pkg.keywords.find(k => k === keyword)) {
      messages.push(`docs(package): add keyword ${keyword}`);
      pkg.keywords.push(keyword);
    }
  }
}
<commit_msg>refactor: better var names<commit_after>import File from './file';

export default class Package extends File {
  async templateRepo(context) {
    const content = await this.originalContent(context, {
      ignoreMissing: true
    });
    const pkg = JSON.parse(content);
    if (pkg.template !== undefined && pkg.template.repository !== undefined) {
      const m = pkg.template.repository.url.match(/github.com\/(.*)\.git$/);
      return m[1];
    }

    return undefined;
  }

  async mergeContent(context, original, templateContent) {
    const originalLastChar = original[original.length - 1];

    let target =
      original === undefined || original === '' ? {} : JSON.parse(original);
    const template = JSON.parse(templateContent);
    const messages = [];
    const properties = context.properties;

    if (target.name === undefined || target.name === '') {
      const m = context.targetRepo.name.match(/^([^\/]+)\/(.*)/);
      target.name = m ? m[2] : context.targetRepo.name;
    }

    if (target.module !== undefined && !target.module.match(/\{\{module\}\}/)) {
      properties.module = target.module;
    }

    properties.main =
      target.main && !target.main.match(/\{\{main\}\}/)
        ? target.main
        : 'dist/index.js';

    const githubURL = `git+https://github.com/${properties.user}/${target.name}.git`;
    const githubURLAlternative = `git+https://github.com/${properties.user}/node-${target.name}.git`;

    let repoName = target.name;

    if (
      target.repository === undefined ||
      (target.repository.url !== githubURL &&
        target.repository.url !== githubURLAlternative)
    ) {
      target.repository = {
        type: 'git',
        url: githubURL
      };
      messages.push(`chore(package): correct github url`);
    }

    if (
      target.repository !== undefined &&
      githubURLAlternative === target.repository.url
    ) {
      repoName = `node-${target.name}`;
    }

    const bugsURL = `https://github.com/${properties.user}/${repoName}/issues`;

    if (target.bugs === undefined || target.bugs.url !== bugsURL) {
      target.bugs = {
        url: bugsURL
      };
      messages.push(`chore(package): correct bugs url`);
    }

    const homepageURL = `https://github.com/${properties.user}/${repoName}#readme`;

    if (target.homepage === undefined || target.homepage !== homepageURL) {
      target.homepage = homepageURL;
      messages.push(`chore(package): correct hompage url`);
    }

    let buildOutput;
    const extraBuilds = {};

    if (target.scripts !== undefined) {
      Object.keys(target.scripts).forEach(key => {
        const script = target.scripts[key];
        const ma = script.match(/--output=([^\s]+)/);
        if (ma) {
          buildOutput = ma[1];
        }

        if (template.scripts !== undefined) {
          const templateScript = template.scripts[key];
          if (templateScript !== undefined) {
            const mb = script.match(/&&\s*(.+)$/);
            if (mb && !templateScript.includes(mb[1])) {
              extraBuilds[key] = mb[1];
            }
          }
        }
      });
    }

    // TODO loop over all files
    const usedModules = (await Promise.all(
      ['rollup.config.js', 'tests/rollup.config.js'].map(async file => {
        const rcj = await context.files.get(file);
        if (rcj) {
          const m = await rcj.merge(context);
          return rcj.usedDevModules(m.content);
        }
        return new Set();
      })
    )).reduce((sum, current) => new Set([...sum, ...current]), new Set());

    const deepPropeties = {
      scripts: {},
      devDependencies: {},
      engines: {}
    };

    Object.keys(deepPropeties).forEach(category => {
      if (target[category] === undefined) {
        target[category] = {};
      }

      if (template[category] !== undefined) {
        Object.keys(template[category]).forEach(d => {
          if (template[category][d] === '-') {
            if (target[category][d] !== undefined) {
              messages.push(
                `chore(${category}): remove ${d}@${target[category][d]}`
              );
              delete target[category][d];
            }
          } else {
            const tp = context.expand(template[category][d]);
            if (tp !== target[category][d]) {
              messages.push(
                target[category][d] === undefined
                  ? `chore(${category}): add ${d}@${tp} from template`
                  : `chore(${category}): update ${d}@${tp} from template`
              );
              target[category][d] = tp;
            }
          }
        });
      }
    });

    Object.keys(template).forEach(p => {
      if (p !== 'template') {
        if (target[p] === undefined) {
          target[p] = template[p];
        }
      }
    });

    if (target.scripts.prepare) {
      if (buildOutput !== undefined) {
        target.scripts.prepare = target.scripts.prepare.replace(
          /--output=([^\s]+)/,
          `--output=${buildOutput}`
        );
      }
    }

    Object.keys(extraBuilds).forEach(key => {
      target.scripts[key] += ` && ${extraBuilds[key]}`;
    });

    if (target.module === '{{module}}') {
      delete target.module;
    }

    if (
      target.contributors !== undefined &&
      target.author !== undefined &&
      target.author.name !== undefined
    ) {
      const m = target.author.name.match(/(^[^<]+)<([^>]+)>/);
      if (m !== undefined) {
        const name = String(m[1]).replace(/^\s+|\s+$/g, '');
        const email = m[2];

        if (
          target.contributors.find(c => c.name === name && c.email === email)
        ) {
          delete target.author;
        }
      }
    }

    if (
      target.template === undefined ||
      target.template.repository === undefined ||
      target.template.repository.url !==
        `https://github.com/${context.templateRepo.name}.git`
    ) {
      messages.push('chore(package): set template repo');

      target.template = {
        repository: {
          url: `https://github.com/${context.templateRepo.name}.git`
        }
      };
    }

    const devModulesToBeRemoved = Object.keys(
      target.devDependencies
    ).filter(m => {
      if (m.match(/rollup-plugin/) || m.match(/babel-preset/)) {
        return usedModules.has(m) ? false : true;
      }

      return false;
    });

    devModulesToBeRemoved.forEach(
      toBeRemoved => delete target.devDependencies[toBeRemoved]
    );

    target = deleter(target, template, messages, []);

    if (target.keywords !== undefined) {
      delete target.keywords['npm-package-template'];
    }

    if (
      template.template !== undefined &&
      template.template.keywords !== undefined
    ) {
      Object.keys(template.template.keywords).forEach(r =>
        addKeyword(
          target,
          new RegExp(r),
          template.template.keywords[r],
          messages
        )
      );
    }

    removeKeyword(target, ['null', null, undefined], messages);

    if (messages.length === 0) {
      messages.push('chore: update package.json from template');
    }

    let newContent = JSON.stringify(context.expand(target), undefined, 2);
    const lastChar = newContent[newContent.length - 1];

    // keep trailing newline
    if (originalLastChar === '\n' && lastChar === '}') {
      newContent += '\n';
    }

    return {
      content: newContent,
      messages,
      path: this.path,
      changed: original !== newContent
    };
  }
}

function deleter(object, reference, messages, path) {
  if (
    typeof object === 'string' ||
    object instanceof String ||
    object === true ||
    object === false ||
    object === undefined ||
    object === null ||
    typeof object === 'number' ||
    object instanceof Number
  ) {
    return object;
  }

  Object.keys(reference).forEach(key => {
    path.push(key);

    if (reference[key] === '--delete--' && object[key] !== undefined) {
      if (object[key] !== '--delete--') {
        messages.push(`chore(npm): delete ${path.join('.')}`);
      }
      delete object[key];
    } else {
      object[key] = deleter(object[key], reference[key], messages, path);
    }
    path.pop();
  });

  return object;
}

function removeKeyword(pkg, keywords, messages) {
  if (pkg.keywords !== undefined) {
    keywords.forEach(keyword => {
      if (pkg.keywords.find(k => k === keyword)) {
        messages.push(`docs(package): remove keyword ${keyword}`);
        pkg.keywords = pkg.keywords.filter(k => k !== keyword);
      }
    });

    if (pkg.keywords[0] === null || pkg.keywords[0] === undefined) {
      messages.push(`docs(package): remove keyword null`);
      pkg.keywords = [];
    }
  }
}

function addKeyword(pkg, regex, keyword, messages) {
  if (keyword === undefined || keyword === null || keyword === 'null') {
    return;
  }

  if (pkg.name.match(regex)) {
    if (pkg.keywords === undefined) {
      pkg.keywords = [];
    }
    if (!pkg.keywords.find(k => k === keyword)) {
      messages.push(`docs(package): add keyword ${keyword}`);
      pkg.keywords.push(keyword);
    }
  }
}
<|endoftext|>


<commit_before>import {
  Vector2,
  Vector3,
  Euler,
  Spherical,
  Quaternion,
  Fog,
  Color,
  Shape,
} from 'three';

/**
 * Returns a parsed quaternion object.
 */
export function parseQuaternion(str) {
  return str.isQuaternion ? str : new Quaternion(...str.trim().split(/\s+/).map((elm) => parseFloat(elm)));
}

/**
 * Returns a parsed vector3 object.
 */
export function parseVector3(str) {
  return str.isVector3 ? str : new Vector3(...str.trim().split(/\s+/).map((elm) => parseFloat(elm)));
}

/**
 * Returns a parsed vector2 object.
 */
export function parseVector2(str) {
  if (str.isVector2) return str;
  if (Array.isArray(str) && str.length === 2) {
    return new Vector2(...(str.map((e) => parseFloat(e))));
  }
  return new Vector2(...str.trim().split(/\s+/).map((elm) => parseFloat(elm)));
}

/**
 * Returns a parsed euler object.
 */
export function parseEuler(str) {
  return str.isEuler ? str : new Euler(...str.trim().split(/\s+/).map((elm, i) => (i === 3 ? elm : parseFloat(elm))));
}

/**
 * Returns a parsed spherical object.
 */
export function parseSpherical(str) {
  return str.isSpherical ? str : new Spherical(...str.trim().split(/\s+/).map((elm) => parseFloat(elm))).makeSafe();
}

/**
 * Returns a parsed array.
 */
export function parseArray(str) {
  return Array.isArray(str) ? str : str.split(',');
}

/**
 * Returns a parsed array of vector2.
 */
export function parseVector2Array(str) {
  return parseArray(str).map((elm) => parseVector2(elm));
}

/**
 * Returns a parsed fog object
 */
export function parseFog(str) {
  return str.isFog ? str : new Fog(...str.trim().split(/\s+/).map((elm, i) => (i === 0 ? elm : parseFloat(elm))));
}

/**
 * Returns a parsed Color object
 */
export function parseColor(str) {
  return str.isColor ? str : new Color(str);
}

/**
 * Return a parsed Shape
 */
export function parseShape(str) {
  if (!str) return new Shape();
  return (str.type && str.type === 'Shape') ? str : new Shape(parseVector2Array(str));
}
<commit_msg>Remove unnecessary check during Vector2 parsing<commit_after>import {
  Vector2,
  Vector3,
  Euler,
  Spherical,
  Quaternion,
  Fog,
  Color,
  Shape,
} from 'three';

/**
 * Returns a parsed quaternion object.
 */
export function parseQuaternion(str) {
  return str.isQuaternion ? str : new Quaternion(...str.trim().split(/\s+/).map((elm) => parseFloat(elm)));
}

/**
 * Returns a parsed vector3 object.
 */
export function parseVector3(str) {
  return str.isVector3 ? str : new Vector3(...str.trim().split(/\s+/).map((elm) => parseFloat(elm)));
}

/**
 * Returns a parsed vector2 object.
 */
export function parseVector2(str) {
  if (str.isVector2) return str;
  if (Array.isArray(str)) {
    return new Vector2(...(str.map((e) => parseFloat(e))));
  }
  return new Vector2(...str.trim().split(/\s+/).map((elm) => parseFloat(elm)));
}

/**
 * Returns a parsed euler object.
 */
export function parseEuler(str) {
  return str.isEuler ? str : new Euler(...str.trim().split(/\s+/).map((elm, i) => (i === 3 ? elm : parseFloat(elm))));
}

/**
 * Returns a parsed spherical object.
 */
export function parseSpherical(str) {
  return str.isSpherical ? str : new Spherical(...str.trim().split(/\s+/).map((elm) => parseFloat(elm))).makeSafe();
}

/**
 * Returns a parsed array.
 */
export function parseArray(str) {
  return Array.isArray(str) ? str : str.split(',');
}

/**
 * Returns a parsed array of vector2.
 */
export function parseVector2Array(str) {
  return parseArray(str).map((elm) => parseVector2(elm));
}

/**
 * Returns a parsed fog object
 */
export function parseFog(str) {
  return str.isFog ? str : new Fog(...str.trim().split(/\s+/).map((elm, i) => (i === 0 ? elm : parseFloat(elm))));
}

/**
 * Returns a parsed Color object
 */
export function parseColor(str) {
  return str.isColor ? str : new Color(str);
}

/**
 * Return a parsed Shape
 */
export function parseShape(str) {
  if (!str) return new Shape();
  return (str.type && str.type === 'Shape') ? str : new Shape(parseVector2Array(str));
}
<|endoftext|>


<commit_before>import {
  UpdateMessage,
  UpdateInlineQuery,
  getEntityFirst
} from './telegram-driver'
import { find, curryN, prop } from 'ramda'

import t from 'tcomb'

let matchPluginPath = (plugins, str) => find(
  ({path}) => str.match(path),
  plugins
)

let matchPluginArgs = (str, plugin) => str.match(plugin.path)

let makeResolverWith = curryN(3, (plugins, queryWith, u) => {
  let query = queryWith(u)
  let plugin = matchPluginPath(plugins, query)
  let props = matchPluginArgs(query, plugin)

  return { plugin, props }
})

export let matchPlugin = function (plugins) {
  let resolve = makeResolverWith(plugins)
  let type = (u) => t.match(u,
    UpdateMessage, resolve(
      u => u.message.text.substr(getEntityFirst('bot_command', u).offset)
    ),
    UpdateInlineQuery, resolve(
      u => u.inline_query.query
    )
  )

  return this.map(u => {
    let match = type(u)
    let component = {}
    if (match.plugin.type.is(u)) {
      component = match.plugin.component({props: match.props}, u) || {}
    }
    return component
  }).filter(prop('bot'))
}
<commit_msg>fix(plugins): correct behaviour for `UpdateMessage`<commit_after>import {
  UpdateMessage,
  UpdateInlineQuery,
  getEntityFirst
} from './telegram-driver'
import { find, curryN, prop, compose, isNil, not, merge } from 'ramda'

import isolate from '@cycle/isolate'
import t from 'tcomb'

const UpdateMessageCommand = t.refinement(UpdateMessage,
  compose(not, isNil, getEntityFirst('bot_command')),
  'UpdateMessageCommand')

let matchPluginPath = (plugins, str) => find(
  ({path}) => str.match(path),
  plugins
)

let matchPluginArgs = (str, plugin) => str.match(plugin.path)

let makeResolverWith = curryN(3, (plugins, queryWith, u) => {
  let query = queryWith(u)
  let plugin = matchPluginPath(plugins, query)
  let props = matchPluginArgs(query, plugin)

  return { plugin, props }
})

export let matchPlugin = function (plugins, sources) {
  let resolve = makeResolverWith(plugins)
  let type = (u) => t.match(u,
    UpdateMessageCommand, resolve(
      u => u.message.text.substr(getEntityFirst('bot_command', u).offset)
    ),
    UpdateInlineQuery, resolve(
      u => u.inline_query.query
    ),
    UpdateMessage, resolve(u => u.message.text)
  )

  return this.map(u => {
    let match = type(u)
    let component = {}
    let args = merge({props: match.props}, sources)
    if (match.plugin.type.is(u)) {
      component = isolate(match.plugin.component)(args, u) || {}
    }
    return component
  }).filter(prop('bot'))
}
<|endoftext|>


<commit_before>import { Actions } from 'thundercats';
import assign from 'object.assign';
import debugFactory from 'debug';
import Fetchr from 'fetchr';

const debug = debugFactory('freecc:hikes:actions');
const service = new Fetchr({
  xhrPath: '/services'
});

function getCurrentHike(hikes =[{}], dashedName, currentHike) {
  if (!dashedName) {
    return hikes[0];
  }
  const filterRegex = new RegExp(dashedName, 'i');

  return hikes
    .filter(({ dashedName }) => {
      return filterRegex.test(dashedName);
    })
    .reduce((throwAway, hike) => {
      return hike;
    }, currentHike || {});
}

export default Actions({
  // start fetching hikes
  fetchHikes: null,
  // set hikes on store
  setHikes: null
})
  .refs({ displayName: 'HikesActions' })
  .init(({ instance }) => {
    // set up hikes fetching
    instance.fetchHikes.subscribe(
      ({ isPrimed, dashedName }) => {
        if (isPrimed) {
          return instance.setHikes({
            transform: (oldState) => {
              const { hikes, currentContext } = oldState;
              const currentHike = getCurrentHike(
                hikes,
                dashedName,
                currentContext
              );
              return assign({}, oldState, { currentHike });
            }
          });
        }
        service.read('hikes', null, null, (err, hikes) => {
          if (err) {
            debug('an error occurred fetching hikes', err);
          }
          instance.setHikes({
            set: {
              hikes: hikes,
              currentHike: getCurrentHike(hikes, dashedName)
            }
          });
        });
      }
    );
  });
<commit_msg>return currentHike on load<commit_after>import { Actions } from 'thundercats';
import assign from 'object.assign';
import debugFactory from 'debug';
import Fetchr from 'fetchr';

const debug = debugFactory('freecc:hikes:actions');
const service = new Fetchr({
  xhrPath: '/services'
});

function getCurrentHike(hikes =[{}], dashedName, currentHike) {
  if (!dashedName) {
    debug('no dashedName');
    return hikes[0];
  }

  const filterRegex = new RegExp(dashedName, 'i');
  if (currentHike && filterRegex.test(currentHike.dashedName)) {
    return currentHike;
  }

  return hikes
    .filter(({ dashedName }) => {
      return filterRegex.test(dashedName);
    })
    .reduce((throwAway, hike) => {
      return hike;
    }, currentHike || {});
}

export default Actions({
  // start fetching hikes
  fetchHikes: null,
  // set hikes on store
  setHikes: null
})
  .refs({ displayName: 'HikesActions' })
  .init(({ instance }) => {
    // set up hikes fetching
    instance.fetchHikes.subscribe(
      ({ isPrimed, dashedName }) => {
        if (isPrimed) {
          return instance.setHikes({
            transform: (oldState) => {
              const { hikes } = oldState;
              const currentHike = getCurrentHike(
                hikes,
                dashedName,
                oldState.currentHike
              );
              return assign({}, oldState, { currentHike });
            }
          });
        }
        service.read('hikes', null, null, (err, hikes) => {
          if (err) {
            debug('an error occurred fetching hikes', err);
          }
          instance.setHikes({
            set: {
              hikes: hikes,
              currentHike: getCurrentHike(hikes, dashedName)
            }
          });
        });
      }
    );
  });
<|endoftext|>


<commit_before>//= require "qucsator"

/* FILE breadboard.js */

(function () {

    ////////////////////////////////////////////////////////////////////////////////
    //// GLOBAL DEFAULTS ///////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

      var defs = {
        rows            : 31,
        powerRailHoles  : 25,
        debug           : true
      };

    ////////////////////////////////////////////////////////////////////////////////
    //// HELPER FUNCTIONS //////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

      // Array Remove from John Resig http://ejohn.org
      var remove = function(array, from, to) {
        var rest = array.slice((to || from) + 1 || array.length);
        array.length = from < 0 ? array.length + from : from;
        return array.push.apply(array, rest);
      };

      var HTMLLog = undefined, HTMLbody = undefined;
      this.debug = function(){
        if(defs.debug){
          if(typeof console!=='undefined'){
            console.log(arguments[0]);
          }else{
            if(!HTMLLog){
              HTMLLog = document.createElement('div');
              HTMLLog.setAttribute("id", "HTMLLog");
              HTMLBody = document.getElementsByTagName('body')[0];
              HTMLBody.appendChild(HTMLLog);
              HTMLLog.innerHTML += 'HTML-DEBUG-LOG:
';
            }
            HTMLLog.innerHTML += arguments[0] + '
';
          }
        }
      };

    ////////////////////////////////////////////////////////////////////////////////
    //// R E S I S T O R ///////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

      this.Resistor = {
        colorMap : { '-1': 'gold', '-2': 'silver',
            0 : 'black', 1 : 'brown', 2 : 'red', 3 : 'orange',
            4 : 'yellow', 5 : 'green', 6 : 'blue', 7 : 'violet', 8 : 'grey',
            9 : 'white' },
        toleranceColorMap : { 0.01 : 'brown', 0.02 : 'red', 5e-3 : 'green',
            2.5e-3 : 'blue', 1e-3 : 'violet', 5e-4 : 'gray', 5e-2 : 'gold',
            0.1 : 'silver', 0.2 : 'none' },
        getColors4Band: function (ohms, tolerance) {
            var s = ohms.toString();
            var decIx = s.indexOf('.');
            var decLoc = decIx > -1 ? decIx : s.length;
            s = s.replace('.', '');
            var len = s.length;
            for (var i = 0; i < 2 - len; ++i){ s += '0'; }
            var mult = decLoc > 1 ? decLoc - 2 : 10;
            return [ this.colorMap[s.charAt(0)],
                     this.colorMap[s.charAt(1)],
                     this.colorMap[decLoc - 2],
                     this.toleranceColorMap[tolerance]
                   ];
        },
        getColors5Band: function (ohms, tolerance) {
            var s = ohms.toString();
            var decIx = s.indexOf('.');
            var decLoc = decIx > -1 ? decIx : s.length;
            s = s.replace('.', '');
            var len = s.length;
            for (var i = 0; i < 3 - len; ++i) { s += '0'; }
            return [ this.colorMap[s.charAt(0)],
                     this.colorMap[s.charAt(1)],
                     this.colorMap[s.charAt(2)],
                     this.colorMap[decLoc - 3],
                     this.toleranceColorMap[tolerance]
                   ];
        },
        colorToNumber : function(color) {
          for (n in Resistor.colorMap) {
            if (Resistor.colorMap[n] == color) { return parseInt(n); }
          }
        },
        getResistance: function(colors){
          var resistance = Resistor.colorToNumber(colors[0]);
          for ( var i = 1; i < colors.length - 2; i++) {
            resistance = resistance * 10;
            resistance += Resistor.colorToNumber(colors[i]);
          }
          return resistance * Math.pow(10, Resistor.colorToNumber(colors[i]));
        }
      };

    ////////////////////////////////////////////////////////////////////////////////
    //// B R E A D - B O A R D - M O D E L /////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

      //// BREADBOARD Prototype Model //////////////////////////////////////////////
      this.breadBoard = {};

      var Hole = function Hole( strip, name ){
        this.type ='hole';
        this.strip = strip;
        this.name = name;
        this.connections = [];
        return this;
      };

      Hole.prototype.nodeName = function() {
        return this.strip && this.strip.name;
      }

      var GhostHole = function GhostHole(name) {
        this.name = 'node' + calls;
        return this;
      }

      GhostHole.prototype.nodeName = function() {
        return this.name;
      }

      var Strip = function Strip( holes, name ){
        this.type ='strip';
        this.holes={};
        this.name = name;
        if( holes ){
          for(var i=0, l=holes; i < l; i++){
            this.holes[''+i] = new Hole();
            this.holes[''+i].strip = this;
          }
        }
        return this;
      };

      var Breadboard = function Breadboard(){
        this.type ='Breadboard';

        // Create power-rails
        this.powerRail = { // I was told these were called power-rails
          left:{
            positive: new Strip( null, "powerPosL"),
            negative: new Strip( null, "powerNegL")
          },
          right:{
            positive: new Strip( null, "powerPosR" ),
            negative: new Strip( null, "powerNegR" )
          }
        };

        for(var i=0, l=defs.powerRailHoles; i < l; i++){
          for(side in this.powerRail) {
            for(end in this.powerRail[side]) {
              var h = side + '_' + end + '_' + i
              this.powerRail[side][end][h] = this.holes[h] = new Hole(this.powerRail[side][end], h);
            }
          }
        }

        // Create board
        for(var i=0, l=defs.rows; i < l; i++ ){
          newStripL = this.makeStrip("L" + i);
          newStripR = this.makeStrip("R" + i);
          for(var a=0, ll=5; a < ll; a++ ){
            var mapCode = String.fromCharCode(a+97)+i;
            newStripL.holes[mapCode] = this.holes[ mapCode ] = new Hole( newStripL, mapCode );
            var mapCode = String.fromCharCode(a+102)+i;
            newStripR.holes[mapCode] = this.holes[ mapCode ] = new Hole( newStripR, mapCode );
          }
        }
        return this;
      };

      Breadboard.prototype.strips=[];
      Breadboard.prototype.components={};
      Breadboard.prototype.holes={};

      Breadboard.prototype.makeStrip = function(name){
        var stripLen = this.strips.length;
        this.strips[ stripLen ] = new Strip(null, name);
        return this.strips[ stripLen ];
      };

      Breadboard.prototype.component = function component(props){
        if(typeof props=='string'){
          return this.components[props];
        }else {
          return new Component(props);
        }
      };

      Breadboard.prototype.clear = function clear(){
        var destroyed = 0;
        for( k in this.components ){
          destroyed += !!this.component(k).destroy();
        }
        return !!destroyed;
      };

      //// COMPONENT MODEL /////////////////////////////////////////////////////////
      var Component = function Component(props){
        console.log('ENTER Component');
        for(var i in props){
          this[i]=props[i];
        }
        this.breadBoard = breadBoard;
        this.breadBoard.components[props.UID] = this;

        this.connections=[];
        for(var i in props.connections){
          console.log('i=' + i);
          if (props.connections[i].nodeName) {
            this.connections[i] = props.connections[i];
          } else {
            this.connections[i] = this.breadBoard.holes[props.connections[i]];
            this.breadBoard.holes[props.connections[i]].connections[this.breadBoard.holes[props.connections[i]].connections.length] = this;
          }
        }
        return this;
      };

      Component.prototype.move = function move(connections){
        for(var i in this.connections){
          for( var j in this.connections[i].connections ){
            if( this.connections[i].connections[j] === this ){
              this.connections[i].connections = [];
            }
          }
          this.connections[i] = [];
        }
        this.connections = [];
        for(var i in connections){
          this.connections[i] = this.breadBoard.holes[connections[i]];
          this.breadBoard.holes[connections[i]].connections[this.breadBoard.holes[connections[i]].connections.length] = this;
        }
        return this;
      };

      Component.prototype.destroy = function destroy(){
        for(var i in this.connections){
          for( var j in this.connections[i].connections ){
            if( this.connections[i].connections[j] === this ){
              this.connections[i].connections = [];
            }
          }
          this.connections[i] = [];
        }
        this.connections = [];
        return delete this.breadBoard.components[this.name];
      };

      //// BreadBoard Instance & Interface /////////////////////////////////////////
      var breadBoard = new Breadboard();

      var interfaces = {
        insert: function(){
          var props = {
            UID         : arguments[0]+calls,
            kind        : arguments[0],
            connections : arguments[1].split(",")
          };

          switch(props.kind) {
            case "resistor":
              if (typeof(arguments[2])==="string") {
                props.resistance = Resistor.getResistance( arguments[2].split(",") );
              }
              else if (typeof(arguments[2])=="number") {
                props.resistance = arguments[2];
              }
              $('#rated_values').text($('#rated_values').text() + ' ' + props.resistance);
              break;
          }
          var newComponent;
          newComponent = breadBoard.component(props);
          return newComponent.UID;
        },
        destroy: function(){
          breadBoard.component(arguments[0]).destroy();
        },
        clear: function() {
          breadBoard.clear();
        },
        move: function(){
          breadBoard.component(arguments[0]).move(arguments[1].split(','));
        },
        query: function(){
          // Current dummy function will pass query to model
          // Model will then compile SPICE net list and send to server
          // Server will respond with voltage at queried points
          // Power and MultiMeter settings will be assumed

          //debug( breadBoard.query( arguments[1].split(',') ) );

          if (arguments[0] === 'resistance') {
            var connections = arguments[1].split(',');
            var ghost = new GhostHole();
            breadBoard.component({
              UID: 'meterBat',
              kind: 'battery',
              voltage: 1,
              connections: [connections[0], ghost]});
            breadBoard.component({
              UID: 'meter',
              kind: 'iprobe',
              connections: [ghost, connections[1]]});
          } else {
            breadBoard.component({
              UID: 'meter',
              kind: {'current' : 'iprobe', 'voltage' : 'vprobe'}[arguments[0]],
              connections: arguments[1].split(',')});
          }

          breadBoard.component({
            UID: 'bat1',
            kind: 'battery',
            voltage: 9,
            connections: ["left_positive_1", "left_negative_1"]});

          breadBoard.component({
            UID: 'bat2',
            kind: 'battery',
            voltage: 9,
            connections:  ["right_positive_1", "right_negative_1"]});

          var result;

          sparks.circuit.qucsate(sparks.circuit.qucsate.makeNetlist(breadBoard),
                  function(r){ result = r.meter; } );

          console.log('result=' + result);

          breadBoard.component('meter').destroy();
          breadBoard.component('bat1').destroy();
          breadBoard.component('bat2').destroy();

          if (arguments[0] === 'resistance') {
            result = (1 / result)
          }
          result = -1 * result;
          document.getElementById('dmm-output').innerHTML = "Meter Reading: " + result;
          return  result;
        }
      };

      //Stored the number of calls made to the Model: used to create UID
      var calls=0;

      // The inward interface between Flash's ExternalInterface and JavaScript's BreadBoard prototype model instance
      this.breadModel = function () {
        debug(arguments);

        calls++;
        var newArgs = [];
        for(var i=1,l=arguments.length;i< l;i++){
          newArgs[newArgs.length] = arguments[i];
        }
        var func = arguments[0];

        if (func === 'query') {
            var conns = arguments[2].split(',');
            if (conns[0] === 'null' || conns[1] === 'null') {
                return 0;
            }
            $('#popup').text('Calculating...');
            $('#popup').dialog();

            var r = interfaces.query.apply(window, ['resistance', arguments[2], arguments[3]]);
            $('#resistance').text(r);
            var c = interfaces.query.apply(window, ['current', arguments[2], arguments[3]]);
            $('#current').text(c);
            var v = interfaces.query.apply(window, ['voltage', arguments[2], arguments[3]]);
            $('#voltage').text(v);

            $('#popup').dialog('close');
            return v;
        }
        else {
          return interfaces[func].apply(window, newArgs);
        }
      };

      // The outward interface between JS & Flash
      /*
      this.toFlash = function toFlash(){
        console.log(arguments[0]);
        document.getElementById('swf').fromBreadModel(arguments[0]);
      };
      document.addEventListener('click', function(){ flash("testing!","test2") }, false);
      */

})();
<commit_msg>Reflecting namespace change for qucsator<commit_after>//= require "qucsator"

/* FILE breadboard.js */

(function () {

    var q = sparks.circuit.qucsator;

    ////////////////////////////////////////////////////////////////////////////////
    //// GLOBAL DEFAULTS ///////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

      var defs = {
        rows            : 31,
        powerRailHoles  : 25,
        debug           : true
      };

    ////////////////////////////////////////////////////////////////////////////////
    //// HELPER FUNCTIONS //////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

      // Array Remove from John Resig http://ejohn.org
      var remove = function(array, from, to) {
        var rest = array.slice((to || from) + 1 || array.length);
        array.length = from < 0 ? array.length + from : from;
        return array.push.apply(array, rest);
      };

      var HTMLLog = undefined, HTMLbody = undefined;
      this.debug = function(){
        if(defs.debug){
          if(typeof console!=='undefined'){
            console.log(arguments[0]);
          }else{
            if(!HTMLLog){
              HTMLLog = document.createElement('div');
              HTMLLog.setAttribute("id", "HTMLLog");
              HTMLBody = document.getElementsByTagName('body')[0];
              HTMLBody.appendChild(HTMLLog);
              HTMLLog.innerHTML += 'HTML-DEBUG-LOG:
';
            }
            HTMLLog.innerHTML += arguments[0] + '
';
          }
        }
      };

    ////////////////////////////////////////////////////////////////////////////////
    //// R E S I S T O R ///////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

      this.Resistor = {
        colorMap : { '-1': 'gold', '-2': 'silver',
            0 : 'black', 1 : 'brown', 2 : 'red', 3 : 'orange',
            4 : 'yellow', 5 : 'green', 6 : 'blue', 7 : 'violet', 8 : 'grey',
            9 : 'white' },
        toleranceColorMap : { 0.01 : 'brown', 0.02 : 'red', 5e-3 : 'green',
            2.5e-3 : 'blue', 1e-3 : 'violet', 5e-4 : 'gray', 5e-2 : 'gold',
            0.1 : 'silver', 0.2 : 'none' },
        getColors4Band: function (ohms, tolerance) {
            var s = ohms.toString();
            var decIx = s.indexOf('.');
            var decLoc = decIx > -1 ? decIx : s.length;
            s = s.replace('.', '');
            var len = s.length;
            for (var i = 0; i < 2 - len; ++i){ s += '0'; }
            var mult = decLoc > 1 ? decLoc - 2 : 10;
            return [ this.colorMap[s.charAt(0)],
                     this.colorMap[s.charAt(1)],
                     this.colorMap[decLoc - 2],
                     this.toleranceColorMap[tolerance]
                   ];
        },
        getColors5Band: function (ohms, tolerance) {
            var s = ohms.toString();
            var decIx = s.indexOf('.');
            var decLoc = decIx > -1 ? decIx : s.length;
            s = s.replace('.', '');
            var len = s.length;
            for (var i = 0; i < 3 - len; ++i) { s += '0'; }
            return [ this.colorMap[s.charAt(0)],
                     this.colorMap[s.charAt(1)],
                     this.colorMap[s.charAt(2)],
                     this.colorMap[decLoc - 3],
                     this.toleranceColorMap[tolerance]
                   ];
        },
        colorToNumber: function (color) {
          for (n in Resistor.colorMap) {
            if (Resistor.colorMap[n] == color) { return parseInt(n); }
          }
          return null;
        },
        getResistance: function(colors){
          var resistance = Resistor.colorToNumber(colors[0]);
          for (var i = 1; i < colors.length - 2; i++) {
            resistance = resistance * 10;
            resistance += Resistor.colorToNumber(colors[i]);
          }
          return resistance * Math.pow(10, Resistor.colorToNumber(colors[i]));
        }
      };

    ////////////////////////////////////////////////////////////////////////////////
    //// B R E A D - B O A R D - M O D E L /////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////

      //// BREADBOARD Prototype Model //////////////////////////////////////////////
      this.breadBoard = {};

      var Hole = function Hole( strip, name ){
        this.type ='hole';
        this.strip = strip;
        this.name = name;
        this.connections = [];
        return this;
      };

      Hole.prototype.nodeName = function() {
        return this.strip && this.strip.name;
      };

      var GhostHole = function GhostHole(name) {
        this.name = 'node' + calls;
        return this;
      };

      GhostHole.prototype.nodeName = function() {
        return this.name;
      };

      var Strip = function Strip( holes, name ){
        this.type ='strip';
        this.holes={};
        this.name = name;
        if (holes) {
          for (var i=0, l=holes; i < l; i++) {
            this.holes[''+i] = new Hole();
            this.holes[''+i].strip = this;
          }
        }
        return this;
      };

      var Breadboard = function Breadboard(){
        var i;
        this.type ='Breadboard';

        // Create power-rails
        this.powerRail = { // I was told these were called power-rails
          left:{
            positive: new Strip( null, "powerPosL"),
            negative: new Strip( null, "powerNegL")
          },
          right:{
            positive: new Strip( null, "powerPosR" ),
            negative: new Strip( null, "powerNegR" )
          }
        };

        for (i=0, l=defs.powerRailHoles; i < l; i++) {
          for (side in this.powerRail) {
            for (end in this.powerRail[side]) {
              var h = side + '_' + end + '_' + i;
              this.powerRail[side][end][h] = this.holes[h] = new Hole(this.powerRail[side][end], h);
            }
          }
        }

        // Create board
        for (i=0, l=defs.rows; i < l; i++) {
          newStripL = this.makeStrip("L" + i);
          newStripR = this.makeStrip("R" + i);
          for (var a=0, ll=5; a < ll; a++ ) {
            var mapCode = String.fromCharCode(a+97)+i;
            newStripL.holes[mapCode] = this.holes[ mapCode ] = new Hole( newStripL, mapCode );
            mapCode = String.fromCharCode(a+102)+i;
            newStripR.holes[mapCode] = this.holes[ mapCode ] = new Hole( newStripR, mapCode );
          }
        }
        return this;
      };

      Breadboard.prototype.strips=[];
      Breadboard.prototype.components={};
      Breadboard.prototype.holes={};

      Breadboard.prototype.makeStrip = function (name) {
        var stripLen = this.strips.length;
        this.strips[ stripLen ] = new Strip(null, name);
        return this.strips[ stripLen ];
      };

      Breadboard.prototype.component = function (props) {
        if(typeof props=='string'){
          return this.components[props];
        }else {
          return new Component(props);
        }
      };

      Breadboard.prototype.clear = function () {
        var destroyed = 0;
        for( k in this.components ){
          destroyed += !!this.component(k).destroy();
        }
        return !!destroyed;
      };

      //// COMPONENT MODEL /////////////////////////////////////////////////////////
      var Component = function (props) {
        var i;
        //console.log('ENTER Component');
        for (i in props) {
          this[i]=props[i];
        }
        this.breadBoard = breadBoard;
        this.breadBoard.components[props.UID] = this;

        this.connections=[];
        for (i in props.connections) {
          if (props.connections[i].nodeName) {
            this.connections[i] = props.connections[i];
          } else {
            this.connections[i] = this.breadBoard.holes[props.connections[i]];
            this.breadBoard.holes[props.connections[i]].connections[this.breadBoard.holes[props.connections[i]].connections.length] = this;
          }
        }
        return this;
      };

      Component.prototype.move = function (connections) {
        var i;
        for (i in this.connections) {
          for (var j in this.connections[i].connections) {
            if (this.connections[i].connections[j] === this) {
              this.connections[i].connections = [];
            }
          }
          this.connections[i] = [];
        }
        this.connections = [];
        for (i in connections){
          this.connections[i] = this.breadBoard.holes[connections[i]];
          this.breadBoard.holes[connections[i]].connections[this.breadBoard.holes[connections[i]].connections.length] = this;
        }
        return this;
      };

      Component.prototype.destroy = function destroy(){
        for(var i in this.connections){
          for( var j in this.connections[i].connections ){
            if( this.connections[i].connections[j] === this ){
              this.connections[i].connections = [];
            }
          }
          this.connections[i] = [];
        }
        this.connections = [];
        return delete this.breadBoard.components[this.name];
      };

      //// BreadBoard Instance & Interface /////////////////////////////////////////
      var breadBoard = new Breadboard();

      var interfaces = {
        insert: function(){
          var props = {
            UID         : arguments[0]+calls,
            kind        : arguments[0],
            connections : arguments[1].split(",")
          };

          switch(props.kind) {
            case "resistor":
              if (typeof(arguments[2])==="string") {
                props.resistance = Resistor.getResistance( arguments[2].split(",") );
              }
              else if (typeof(arguments[2])=="number") {
                props.resistance = arguments[2];
              }
              props.resistance = 3;
              $('#rated_values').text($('#rated_values').text() + ' ' + props.resistance);
              break;
          }
          var newComponent;
          newComponent = breadBoard.component(props);
          return newComponent.UID;
        },
        destroy: function(){
          breadBoard.component(arguments[0]).destroy();
        },
        clear: function() {
          breadBoard.clear();
        },
        move: function(){
          breadBoard.component(arguments[0]).move(arguments[1].split(','));
        },
        query: function(){
          // Current dummy function will pass query to model
          // Model will then compile SPICE net list and send to server
          // Server will respond with voltage at queried points
          // Power and MultiMeter settings will be assumed

          //debug( breadBoard.query( arguments[1].split(',') ) );

          if (arguments[0] === 'resistance') {
            var connections = arguments[1].split(',');
            var ghost = new GhostHole();
            breadBoard.component({
              UID: 'meterBat',
              kind: 'battery',
              voltage: 1,
              connections: [connections[0], ghost]});
            breadBoard.component({
              UID: 'meter',
              kind: 'iprobe',
              connections: [ghost, connections[1]]});
          } else {
            breadBoard.component({
              UID: 'meter',
              kind: {'current' : 'iprobe', 'voltage' : 'vprobe'}[arguments[0]],
              connections: arguments[1].split(',')});
          }

          breadBoard.component({
            UID: 'bat1',
            kind: 'battery',
            voltage: 9,
            connections: ["left_positive_1", "left_negative_1"]});

          breadBoard.component({
            UID: 'bat2',
            kind: 'battery',
            voltage: 9,
            connections:  ["right_positive_1", "right_negative_1"]});

          var result;

          q.qucsate(q.makeNetlist(breadBoard),
                  function (r) { result = r.meter; } );

          console.log('result=' + result);

          breadBoard.component('meter').destroy();
          breadBoard.component('bat1').destroy();
          breadBoard.component('bat2').destroy();

          if (arguments[0] === 'resistance') {
            result = (1 / result);
          }
          result = -1 * result;
          document.getElementById('dmm-output').innerHTML = "Meter Reading: " + result;
          return  result;
        }
      };

      //Stored the number of calls made to the Model: used to create UID
      var calls=0;

      // The inward interface between Flash's ExternalInterface and JavaScript's BreadBoard prototype model instance
      this.breadModel = function () {
        debug(arguments);

        calls++;
        var newArgs = [];
        for(var i=1,l=arguments.length;i< l;i++){
          newArgs[newArgs.length] = arguments[i];
        }
        var func = arguments[0];

        if (func === 'query') {
            var conns = arguments[2].split(',');
            if (conns[0] === 'null' || conns[1] === 'null') {
                return 0;
            }
            $('#popup').text('Calculating...');
            $('#popup').dialog();

            console.log('RESISTANCE:');
            var r = interfaces.query.apply(window, ['resistance', arguments[2], arguments[3]]);
            $('#resistance').text(r);

            console.log('CURRENT:');
            var c = interfaces.query.apply(window, ['current', arguments[2], arguments[3]]);
            $('#current').text(c);

            console.log('VOLTAGE:');
            var v = interfaces.query.apply(window, ['voltage', arguments[2], arguments[3]]);
            $('#voltage').text(v);

            $('#popup').dialog('close');
            return v;
        }
        else {
          return interfaces[func].apply(window, newArgs);
        }
      };

      // The outward interface between JS & Flash
      /*
      this.toFlash = function toFlash(){
        console.log(arguments[0]);
        document.getElementById('swf').fromBreadModel(arguments[0]);
      };
      document.addEventListener('click', function(){ flash("testing!","test2") }, false);
      */

})();
<|endoftext|>


<commit_before>import {fromJS} from 'immutable'

let facials = [500, 200, 100, 50, 20, 10, 5,
  2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01]
let items  = []
facials.forEach(facial => {
  items.push({
    facial,
    count: 0
  })
})

const INITIAL_STATE = fromJS({items})

export default function reducer(state = INITIAL_STATE, action) {
  switch (action.type) {
  case 'SET_ITEM_COUNT':
    const facial = action.facial
    const count = action.count

    const ind = state.get('items').findIndex(it => {
      return it.get('facial') === facial
    })

    return state.setIn(['items', ind, 'count'], count)

  default:
    return state
  }
}
<commit_msg>State: add type: 'BILL'|'COIN'<commit_after>import {fromJS} from 'immutable'

const billFacials = [500, 200, 100, 50, 20, 10, 5]
const coinFacials = [2, 1, 0.5, 0.2, 0.1, 0.05, 0.02, 0.01]
let items  = []
billFacials.forEach(facial => {
  items.push({
    facial,
    count: 0,
    type: 'BILL'
  })
})
coinFacials.forEach(facial => {
  items.push({
    facial,
    count: 0,
    type: 'COIN'
  })
})

const INITIAL_STATE = fromJS({items})

export default function reducer(state = INITIAL_STATE, action) {
  switch (action.type) {
  case 'SET_ITEM_COUNT':
    const facial = action.facial
    const count = action.count

    const ind = state.get('items').findIndex(it => {
      return it.get('facial') === facial
    })

    return state.setIn(['items', ind, 'count'], count)

  default:
    return state
  }
}
<|endoftext|>