gitbook-plugin-webpd
Version:
A webpd plugin for gitbooks
1,591 lines (1,384 loc) • 445 kB
JavaScript
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
exports.parse = require('pd-fileutils.parser').parse
exports.renderSvg = require('./lib/svg-rendering').render
exports.renderPd = require('./lib/pd-rendering').render
exports.Patch = require('./lib/Patch')
if (typeof window !== 'undefined') window.pdfu = exports
},{"./lib/Patch":2,"./lib/pd-rendering":3,"./lib/svg-rendering":4,"pd-fileutils.parser":10}],2:[function(require,module,exports){
/*
* Copyright (c) 2012-2015 Sébastien Piquemal <sebpiq@gmail.com>
*
* BSD Simplified License.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
*
* See https://github.com/sebpiq/pd-fileutils for documentation
*
*/
var _ = require('underscore')
var Patch = module.exports = function(obj) { _.extend(this, obj) }
_.extend(Patch.prototype, {
getNode: function(id) {
return _.find(this.nodes, function(node) { return node.id === id }) || null
},
guessPortlets: function() {
var self = this
_.each(this.nodes, function(node) {
node.outlets = _.reduce(self.connections, function(memo, conn) {
if (conn.source.id === node.id) {
return Math.max(memo, conn.source.port)
} else return memo
}, -1) + 1
node.inlets = _.reduce(self.connections, function(memo, conn) {
if (conn.sink.id === node.id) {
return Math.max(memo, conn.sink.port)
} else return memo
}, -1) + 1
})
},
getSinks: function(node) {
var conns = _.filter(this.connections, function(conn) { return conn.source.id === node.id })
, sinkIds = _.uniq(_.map(conns, function(conn) { return conn.sink.id }))
, self = this
return _.map(sinkIds, function(sinkId) { return self.getNode(sinkId) })
},
getSources: function(node) {
var conns = _.filter(this.connections, function(conn) { return conn.sink.id === node.id })
, sourceIds = _.uniq(_.map(conns, function(conn) { return conn.source.id }))
, self = this
return _.map(sourceIds, function(sourceId) { return self.getNode(sourceId) })
},
addNode: function(node) {
if (node.id === undefined) node.id = this.nextId()
else if (this.getNode(node.id) !== null) return
this.nodes.push(node)
},
nextId: function() {
if (this.nodes.length) {
return Math.max.apply(Math, _.pluck(this.nodes, 'id')) + 1
} else return 0
}
})
},{"underscore":11}],3:[function(require,module,exports){
/*
* Copyright (c) 2012-2015 Sébastien Piquemal <sebpiq@gmail.com>
*
* BSD Simplified License.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
*
* See https://github.com/sebpiq/pd-fileutils for documentation
*
*/
var mustache = require('mustache')
, _ = require('underscore')
exports.render = function(patch) {
// Render the graph canvas
var rendered = ''
, layout = _.clone(patch.layout || {})
_.defaults(layout, {x: 0, y: 0, width: 500, height: 500})
rendered += mustache.render(canvasTpl, {args: patch.args, layout: layout}) + ';\n'
// Render all nodes
_.forEach(patch.nodes.sort(function(n1, n2){return n1.id - n2.id}), function(node) {
var layout = _.clone(node.layout || {})
_.defaults(layout, {x: 0, y: 0})
rendered += mustache.render(objTpl, {args: node.args, layout: layout, proto: node.proto}) + ';\n'
})
// Render all connections
_.forEach(patch.connections, function(conn) {
rendered += mustache.render(connectTpl, conn) + ';\n'
})
return rendered
}
var canvasTpl = '#N canvas {{{layout.x}}} {{{layout.y}}} {{{layout.width}}} {{{layout.height}}} {{{args.0}}}{{#layout.openOnLoad}} {{{.}}}{{/layout.openOnLoad}}'
, connectTpl = '#X connect {{{source.id}}} {{{source.port}}} {{{sink.id}}} {{{sink.port}}}'
var floatAtomTpl = '#X floatatom {{{layout.x}}} {{{layout.y}}} {{{layout.width}}} {{{args.0}}} {{{args.1}}} {{{layout.labelPos}}} {{{layout.label}}} {{{args.2}}} {{{args.3}}}'
, symbolAtomTpl = '#X symbolatom {{{layout.x}}} {{{layout.y}}} {{{layout.width}}} {{{args.0}}} {{{args.1}}} {{{layout.labelPos}}} {{{layout.label}}} {{{args.2}}} {{{args.3}}}'
, bngTpl = '#X obj {{{layout.x}}} {{{layout.y}}} bng {{{layout.size}}} {{{layout.hold}}} {{{layout.interrupt}}} {{{args.0}}} {{{args.1}}} {{{args.2}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.fgColor}}} {{{layout.labelColor}}}'
, nbxTpl = '#X obj {{{layout.x}}} {{{layout.y}}} nbx {{{layout.size}}} {{{layout.height}}} {{{args.0}}} {{{args.1}}} {{{layout.log}}} {{{args.2}}} {{{args.3}}} {{{args.4}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.fgColor}}} {{{layout.labelColor}}} {{{layout.logHeight}}}'
, vslTpl = '#X obj {{{layout.x}}} {{{layout.y}}} vsl {{{layout.width}}} {{{layout.height}}} {{{args.0}}} {{{args.1}}} {{{layout.log}}} {{{args.2}}} {{{args.3}}} {{{args.4}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.fgColor}}} {{{layout.labelColor}}} {{{args.5}}} {{{layout.steadyOnClick}}}'
, hslTpl = '#X obj {{{layout.x}}} {{{layout.y}}} hsl {{{layout.width}}} {{{layout.height}}} {{{args.0}}} {{{args.1}}} {{{layout.log}}} {{{args.2}}} {{{args.3}}} {{{args.4}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.fgColor}}} {{{layout.labelColor}}} {{{args.5}}} {{{layout.steadyOnClick}}}'
, vradioTpl = '#X obj {{{layout.x}}} {{{layout.y}}} vradio {{{layout.size}}} {{{args.0}}} {{{args.1}}} {{{args.2}}} {{{args.3}}} {{{args.4}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.fgColor}}} {{{layout.labelColor}}} {{{args.5}}}'
, hradioTpl = '#X obj {{{layout.x}}} {{{layout.y}}} hradio {{{layout.size}}} {{{args.0}}} {{{args.1}}} {{{args.2}}} {{{args.3}}} {{{args.4}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.fgColor}}} {{{layout.labelColor}}} {{{args.5}}}'
, vuTpl = '#X obj {{{layout.x}}} {{{layout.y}}} vu {{{layout.width}}} {{{layout.height}}} {{{args.0}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.labelColor}}} {{{layout.log}}} {{{args.1}}}'
, cnvTpl = '#X obj {{{layout.x}}} {{{layout.y}}} cnv {{{layout.size}}} {{{layout.width}}} {{{layout.height}}} {{{args.0}}} {{{args.1}}} {{{layout.label}}} {{{layout.labelX}}} {{{layout.labelY}}} {{{layout.labelFont}}} {{{layout.labelFontSize}}} {{{layout.bgColor}}} {{{layout.labelColor}}} {{{args.2}}}'
, objTpl = '#X obj {{{layout.x}}} {{{layout.y}}} {{{proto}}}{{#args}} {{.}}{{/args}}'
},{"mustache":9,"underscore":11}],4:[function(require,module,exports){
(function (__dirname){
/*
* Copyright (c) 2012-2015 Sébastien Piquemal <sebpiq@gmail.com>
*
* BSD Simplified License.
* For information on usage and redistribution, and for a DISCLAIMER OF ALL
* WARRANTIES, see the file, "LICENSE.txt," in this distribution.
*
* See https://github.com/sebpiq/pd-fileutils for documentation
*
*/
var _ = require('underscore')
, d3 = require('d3')
, Patch = require('./Patch')
, isBrowser = (typeof window !== 'undefined')
if (!isBrowser) {
var fs = require('fs')
, path = require('path')
, defaultStyle = fs.readFileSync(path.join(__dirname, 'svg-default-style.css')).toString()
}
var defaults = {
portletWidth: 5,
portletHeight: 3.5,
objMinWidth: 25,
objMinHeight: 20,
ratio: 1.2,
padding: 10,
glyphWidth: 8,
glyphHeight: 9,
textPadding: 6,
svgFile: true,
style: isBrowser ? null : defaultStyle
}
exports.render = function(patch, opts) {
opts = opts || {}
_.defaults(opts, defaults)
d3.select('svg').remove()
var svgContainer = d3.select('body').append('div')
, svg = svgContainer.append('svg')
.attr('xmlns', 'http://www.w3.org/2000/svg')
.attr('version', '1.1')
, root = svg.append('g')
, connections, nodes
if (opts.style) {
svg.append('style').text(opts.style)
}
// Creating all renderers
patch = new Patch(patch)
patch.guessPortlets()
patch.nodes = _.map(patch.nodes, function(node) {
var proto = node.proto
if (proto === 'msg') return new MsgRenderer(node, opts)
else if (proto === 'text') return new TextRenderer(node, opts)
else if (proto === 'floatatom') return new FloatAtomRenderer(node, opts)
else if (proto === 'symbolatom') return new SymbolAtomRenderer(node, opts)
else if (proto === 'bng') return new BngRenderer(node, opts)
else if (proto === 'tgl') return new TglRenderer(node, opts)
else if (proto === 'nbx') return new NbxRenderer(node, opts)
else if (proto === 'hsl') return new HslRenderer(node, opts)
else if (proto === 'vsl') return new VslRenderer(node, opts)
else if (proto === 'hradio') return new HRadioRenderer(node, opts)
else if (proto === 'vradio') return new VRadioRenderer(node, opts)
else if (proto === 'vu') return new VuRenderer(node, opts)
else return new ObjectRenderer(node, opts)
})
// Render the nodes
nodes = root.selectAll('g.node')
.data(patch.nodes)
.enter()
.append('g')
.attr('transform', function(renderer) {
return 'translate(' + renderer.getX() + ' ' + renderer.getY() + ')'
})
.attr('class', 'node')
.attr('id', function(node) { return node.id })
.each(function(renderer, i) { renderer.render(d3.select(this)) })
// Render the connections
connections = root.selectAll('line.connection')
.data(patch.connections)
.enter()
.append('line')
.attr('class', 'connection')
.attr('style', 'stroke:black;stroke-width:2px;')
.each(function(conn) {
var sourceRenderer = patch.getNode(conn.source.id)
, sinkRenderer = patch.getNode(conn.sink.id)
d3.select(this)
.attr('x1', function(conn) {
return sourceRenderer.getOutletX(conn.source.port) + opts.portletWidth/2
})
.attr('y1', function(conn) {
return sourceRenderer.getOutletY(conn.source.port) + opts.portletHeight
})
.attr('x2', function(conn) {
return sinkRenderer.getInletX(conn.sink.port) + opts.portletWidth/2
})
.attr('y2', function(conn) {
return sinkRenderer.getInletY(conn.sink.port)
})
})
// Calculate width / height of the SVG
var allX1 = [], allY1 = [], allX2 = [], allY2 = []
, topLeft = {}, bottomRight = {}
_.forEach(patch.nodes, function(n) {
allX1.push(n.getX())
allY1.push(n.getY())
allX2.push(n.getX() + n.getW())
allY2.push(n.getY() + n.getH())
})
topLeft.x = _.min(allX1)
topLeft.y = _.min(allY1)
bottomRight.x = _.max(allX2)
bottomRight.y = _.max(allY2)
svg.attr('width', bottomRight.x - topLeft.x + opts.padding * 2)
svg.attr('height', bottomRight.y - topLeft.y + opts.padding * 2)
root.attr('transform', 'translate('
+ (-topLeft.x + opts.padding) + ' '
+ (-topLeft.y + opts.padding) + ')'
)
// Finally rendering to a string
var rendered = svgContainer[0][0].innerHTML
if (opts.svgFile) {
rendered = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" '
+ '"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">' + rendered
} else {
svgContainer.remove()
}
return rendered
}
//==================== Node renderers ====================//
// Simple helper to memoize some method calls
var memoized = function(obj, methodName) {
var originalMethod = obj[methodName]
, cache = undefined
if (originalMethod.length > 0)
throw new Error('This memoization is valid only for methods with 0 arguments')
obj[methodName] = function() {
cache = originalMethod.apply(obj, arguments)
obj[methodName] = function() { return cache }
return cache
}
}
var NodeRenderer = function(node, opts) {
this.opts = opts
this.node = node
this.id = node.id
memoized(this, 'getX')
memoized(this, 'getY')
}
_.extend(NodeRenderer.prototype, {
// Returns node X in the canvas
getX: function() { return this.node.layout.x * this.opts.ratio },
// Returns node Y in the canvas
getY: function() { return this.node.layout.y * this.opts.ratio },
// Returns outlet's absolute X in the canvas
getOutletX: function(outlet) {
return this.getOutletRelX(outlet) + this.getX()
},
// Returns intlet's absolute X in the canvas
getInletX: function(inlet) {
return this.getInletRelX(inlet) + this.getX()
},
// Returns outlet's Y in the canvas
getOutletY: function(outlet) {
return this.getOutletRelY(outlet) + this.getY()
},
// Returns inlet's Y in the canvas
getInletY: function(inlet) {
return this.getInletRelY(inlet) + this.getY()
},
// ---- Methods to implement ---- //
// Do the actual rendering in svg group `g`.
render: function(g) { throw new Error('Implement me') },
// Returns the width of the bounding box of the node
getW: function() { throw new Error('Implement me') },
// Returns the height of the bounding box of the node
getH: function() { throw new Error('Implement me') },
// Returns outlet X relatively to the node
getOutletRelX: function(outlet) { throw new Error('Implement me') },
// Returns inlet X relatively to the node
getInletRelX: function(inlet) { throw new Error('Implement me') },
// Returns outlet Y relatively to the node
getOutletRelY: function(outlet) { throw new Error('Implement me') },
// Returns inlet Y relatively to the node
getInletRelY: function(inlet) { throw new Error('Implement me') },
})
var ObjectRenderer = function() {
NodeRenderer.prototype.constructor.apply(this, arguments)
memoized(this, 'getW')
memoized(this, 'getH')
}
_.extend(ObjectRenderer.prototype, NodeRenderer.prototype, {
render: function(g) {
this.renderBox(g)
this.renderText(g)
this.renderOutlets(g)
this.renderInlets(g)
},
renderBox: function(g) {
g.append('rect')
.attr('class', 'box')
.attr('width', this.getW())
.attr('height', this.getH())
.attr('style', 'stroke:black;fill:white;')
},
renderText: function(g) {
g.append('text')
.attr('class', 'proto')
.text(this.getText())
.attr('dy', this.getTextY())
.attr('dx', this.opts.textPadding)
},
renderInlets: function(g) { this._genericRenderPortlets('inlet', g) },
renderOutlets: function(g) { this._genericRenderPortlets('outlet', g) },
_genericRenderPortlets: function(portletType, g) {
var portletTypeCap = portletType.substr(0, 1).toUpperCase() + portletType.substr(1)
, self = this
g.selectAll('rect.' + portletType)
.data(_.range(this.node[portletType+'s']))
.enter()
.append('rect')
.classed(portletType, true)
.classed('portlet', true)
.attr('width', this.opts.portletWidth)
.attr('height', this.opts.portletHeight)
.attr('x', function(i) { return self['get' + portletTypeCap + 'RelX'](i) })
.attr('y', function(i) { return self['get' + portletTypeCap + 'RelY'](i) })
},
// Returns object height
getH: function() { return this.opts.objMinHeight },
// Returns object width
getW: function() {
var maxPortlet = Math.max(this.node.inlets, this.node.outlets)
, textLength = this.getText().length * this.opts.glyphWidth + this.opts.textPadding * 2
return Math.max((maxPortlet-1) * this.opts.objMinWidth, this.opts.objMinWidth, textLength)
},
// Returns text to display on the object
getText: function() { return this.node.proto + ' ' + this.node.args.join(' ') },
// Returns text Y relatively to the object
getTextY: function() { return this.getH()/2 + this.opts.glyphHeight/2 },
// ---- Implement virtual methods ---- //
getOutletRelX: function(outlet) {
return this._genericPortletRelX('outlets', outlet)
},
getInletRelX: function(inlet) {
return this._genericPortletRelX('inlets', inlet)
},
getOutletRelY: function(outlet) {
return this.getH() - this.opts.portletHeight
},
getInletRelY: function(inlet) { return 0 },
_genericPortletRelX: function(inOrOutlets, portlet) {
var width = this.getW()
, n = this.node[inOrOutlets]
if (portlet === 0) return 0;
else if (portlet === n-1) return width - this.opts.portletWidth
else {
// Space between portlets
var a = (width - n*this.opts.portletWidth) / (n-1)
return portlet * (this.opts.portletWidth + a)
}
}
})
var MsgRenderer = function() {
ObjectRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(MsgRenderer.prototype, ObjectRenderer.prototype, {
renderBox: function(g) {
var r = this.getH() * 0.75
, teta = Math.asin(this.getH() / (2 * r))
, arcPath = d3.svg.arc()({
innerRadius: r,
outerRadius: r,
startAngle: -Math.PI / 2 - teta,
endAngle: -Math.PI / 2 + teta
})
, linePath = d3.svg.line()([
[this.getW(), 0], [0, 0],
[0, this.getH()], [this.getW(), this.getH()]
])
g.append('svg:path')
.attr('d', linePath)
.attr('style', 'stroke:black;fill:white;')
g.append('svg:path')
.attr('d', arcPath)
.attr('transform', 'translate(' + (this.getW() + r * Math.cos(teta)) + ' ' + this.getH()/2 + ')')
.attr('style', 'stroke:black;fill:white;')
},
getText: function() { return this.node.args.join(' ') }
})
var AtomBoxRenderer = function() {
ObjectRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(AtomBoxRenderer.prototype, ObjectRenderer.prototype, {
renderBox: function(g) {
var r = this.getH() * 0.4
, arcPath = d3.svg.arc()({
innerRadius: r,
outerRadius: r,
startAngle: 0,
endAngle: Math.PI / 2
})
, linePath = d3.svg.line()([
[this.getW() - r, 0], [0, 0], [0, this.getH()],
[this.getW(), this.getH()], [this.getW(), r]
])
g.append('svg:path')
.attr('d', linePath)
.attr('style', 'stroke:black;fill:white;')
g.append('svg:path')
.attr('d', arcPath)
.attr('transform', 'translate(' + (this.getW() - r) + ' ' + r + ')')
.attr('style', 'stroke:black;fill:white;')
}
})
var FloatAtomRenderer = function() {
AtomBoxRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(FloatAtomRenderer.prototype, AtomBoxRenderer.prototype, {
getText: function() { return '0' }
})
var SymbolAtomRenderer = function() {
AtomBoxRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(SymbolAtomRenderer.prototype, AtomBoxRenderer.prototype, {
getText: function() { return 'symbol' }
})
var BngRenderer = function() {
ObjectRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(BngRenderer.prototype, ObjectRenderer.prototype, {
render: function(g) {
g.append('rect')
.attr('class', 'box')
.attr('width', this.getW())
.attr('height', this.getH())
.attr('style', 'stroke:black;fill:white;')
g.append('circle')
.attr('cx', this.getW()/2)
.attr('cy', this.getH()/2)
.attr('r', this.getW()/3)
.attr('style', 'stroke:black;fill:white;')
this.renderOutlets(g)
this.renderInlets(g)
},
getW: function() { return 20 },
getH: function() { return 20 }
})
var TglRenderer = function() {
ObjectRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(TglRenderer.prototype, ObjectRenderer.prototype, {
render: function(g) {
var crossPath = d3.svg.symbol()
.size(this.getW() * this.getH() / 3.5)
.type('cross')([1])
g.append('rect')
.attr('class', 'box')
.attr('width', this.getW())
.attr('height', this.getH())
.attr('style', 'stroke:black;fill:white;')
g.append('svg:path')
.attr('d', crossPath)
.attr('transform', 'rotate(' + 45 + ' ' + this.getW()/2 + ' ' + this.getH()/2
+ ') translate(' + this.getW()/2 + ' ' + this.getH()/2 + ')')
.attr('style', 'stroke:black;fill:white;')
this.renderOutlets(g)
this.renderInlets(g)
},
getW: function() { return 20 },
getH: function() { return 20 }
})
var NbxRenderer = function() {
AtomBoxRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(NbxRenderer.prototype, AtomBoxRenderer.prototype, {
renderBox: function(g) {
AtomBoxRenderer.prototype.renderBox.apply(this, arguments)
var trianglePath = d3.svg.line()([ [0, 0], [this.getW()/6, this.getH()/2], [0, this.getH()] ])
g.append('svg:path')
.attr('d', trianglePath)
.attr('style', 'stroke:black;fill:white;')
},
getText: function() { return '0' }
})
var HslRenderer = function() {
ObjectRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(HslRenderer.prototype, ObjectRenderer.prototype, {
renderBox: function(g) {
ObjectRenderer.prototype.renderBox.apply(this, arguments)
var cursorPath = d3.svg.line()([ [5, 0], [10, 0],
[10, this.getH()], [5, this.getH()], [5, 0] ])
g.append('svg:path')
.attr('d', cursorPath)
.attr('style', 'stroke:black;fill:black;')
},
getText: function() { return '' },
getW: function() { return 200 },
getH: function() { return 20 }
})
var VslRenderer = function() {
ObjectRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(VslRenderer.prototype, ObjectRenderer.prototype, {
renderBox: function(g) {
ObjectRenderer.prototype.renderBox.apply(this, arguments)
var cursorPath = d3.svg.line()([ [0, 5], [0, 10],
[this.getW(), 10], [this.getW(), 5], [0, 5] ])
g.append('svg:path')
.attr('d', cursorPath)
.attr('style', 'stroke:black;fill:black;')
},
getText: function() { return '' },
getW: function() { return 20 },
getH: function() { return 200 }
})
var HRadioRenderer = function() {
ObjectRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(HRadioRenderer.prototype, ObjectRenderer.prototype, {
renderBox: function(g) {
var nBoxes = this.getNBoxes(), i
, enabledSize = this.getBoxSize() / 1.5
for (i = 0; i < nBoxes; i++) {
g.append('rect')
.attr('width', this.getBoxSize())
.attr('height', this.getBoxSize())
.attr('transform', 'translate(' + i * this.getBoxSize() + ' ' + 0 + ')')
.attr('style', 'stroke:black;fill:white;')
}
g.append('rect')
.attr('width', enabledSize)
.attr('height', enabledSize)
.attr('transform', 'translate(' + (this.getBoxSize() - enabledSize) / 2
+ ' ' + (this.getBoxSize() - enabledSize) / 2 + ')')
.attr('style', 'stroke:black;fill:black;')
},
getW: function() { return this.getBoxSize() * this.getNBoxes() },
getH: function() { return this.getBoxSize() },
getBoxSize: function() { return 20 },
getNBoxes: function() { return this.node.args[2] },
getText: function() { return '' }
})
var VRadioRenderer = function() {
ObjectRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(VRadioRenderer.prototype, ObjectRenderer.prototype, {
renderBox: function(g) {
var nBoxes = this.getNBoxes(), i
, enabledSize = this.getBoxSize() / 1.5
for (i = 0; i < nBoxes; i++) {
g.append('rect')
.attr('width', this.getBoxSize())
.attr('height', this.getBoxSize())
.attr('transform', 'translate(' + 0 + ' ' + i * this.getBoxSize() + ')')
.attr('style', 'stroke:black;fill:white;')
}
g.append('rect')
.attr('width', enabledSize)
.attr('height', enabledSize)
.attr('transform', 'translate(' + (this.getBoxSize() - enabledSize) / 2
+ ' ' + (this.getBoxSize() - enabledSize) / 2 + ')')
.attr('style', 'stroke:black;fill:black;')
},
getW: function() { return this.getBoxSize() },
getH: function() { return this.getBoxSize() * this.getNBoxes() },
getBoxSize: function() { return 20 },
getNBoxes: function() { return this.node.args[2] },
getText: function() { return '' }
})
var VuRenderer = function() {
ObjectRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(VuRenderer.prototype, ObjectRenderer.prototype, {
renderBox: function(g) {
g.append('rect')
.attr('class', 'box')
.attr('width', this.getW())
.attr('height', this.getH())
.attr('style', 'stroke:black;fill:grey;')
},
getText: function() { return '' },
getW: function() { return 20 },
getH: function() { return 200 }
})
var TextRenderer = function() {
NodeRenderer.prototype.constructor.apply(this, arguments)
}
_.extend(TextRenderer.prototype, NodeRenderer.prototype, {
render: function(g) {
g.append('text')
.attr('class', 'comment')
.text(this.node.args[0])
.attr('dy', this.getH()/2 + this.opts.glyphHeight/2)
},
getW: function() { return this.node.args[0].length * this.opts.glyphWidth + this.opts.textPadding * 2 },
getH: function() { return this.opts.objMinHeight }
})
}).call(this,"/lib")
},{"./Patch":2,"d3":8,"fs":5,"path":6,"underscore":11}],5:[function(require,module,exports){
},{}],6:[function(require,module,exports){
(function (process){
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
// resolves . and .. elements in a path array with directory names there
// must be no slashes, empty elements, or device names (c:\) in the array
// (so also no leading and trailing slashes - it does not distinguish
// relative and absolute paths)
function normalizeArray(parts, allowAboveRoot) {
// if the path tries to go above the root, `up` ends up > 0
var up = 0;
for (var i = parts.length - 1; i >= 0; i--) {
var last = parts[i];
if (last === '.') {
parts.splice(i, 1);
} else if (last === '..') {
parts.splice(i, 1);
up++;
} else if (up) {
parts.splice(i, 1);
up--;
}
}
// if the path is allowed to go above the root, restore leading ..s
if (allowAboveRoot) {
for (; up--; up) {
parts.unshift('..');
}
}
return parts;
}
// Split a filename into [root, dir, basename, ext], unix version
// 'root' is just a slash, or nothing.
var splitPathRe =
/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
var splitPath = function(filename) {
return splitPathRe.exec(filename).slice(1);
};
// path.resolve([from ...], to)
// posix version
exports.resolve = function() {
var resolvedPath = '',
resolvedAbsolute = false;
for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
var path = (i >= 0) ? arguments[i] : process.cwd();
// Skip empty and invalid entries
if (typeof path !== 'string') {
throw new TypeError('Arguments to path.resolve must be strings');
} else if (!path) {
continue;
}
resolvedPath = path + '/' + resolvedPath;
resolvedAbsolute = path.charAt(0) === '/';
}
// At this point the path should be resolved to a full absolute path, but
// handle relative paths to be safe (might happen when process.cwd() fails)
// Normalize the path
resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
return !!p;
}), !resolvedAbsolute).join('/');
return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
};
// path.normalize(path)
// posix version
exports.normalize = function(path) {
var isAbsolute = exports.isAbsolute(path),
trailingSlash = substr(path, -1) === '/';
// Normalize the path
path = normalizeArray(filter(path.split('/'), function(p) {
return !!p;
}), !isAbsolute).join('/');
if (!path && !isAbsolute) {
path = '.';
}
if (path && trailingSlash) {
path += '/';
}
return (isAbsolute ? '/' : '') + path;
};
// posix version
exports.isAbsolute = function(path) {
return path.charAt(0) === '/';
};
// posix version
exports.join = function() {
var paths = Array.prototype.slice.call(arguments, 0);
return exports.normalize(filter(paths, function(p, index) {
if (typeof p !== 'string') {
throw new TypeError('Arguments to path.join must be strings');
}
return p;
}).join('/'));
};
// path.relative(from, to)
// posix version
exports.relative = function(from, to) {
from = exports.resolve(from).substr(1);
to = exports.resolve(to).substr(1);
function trim(arr) {
var start = 0;
for (; start < arr.length; start++) {
if (arr[start] !== '') break;
}
var end = arr.length - 1;
for (; end >= 0; end--) {
if (arr[end] !== '') break;
}
if (start > end) return [];
return arr.slice(start, end - start + 1);
}
var fromParts = trim(from.split('/'));
var toParts = trim(to.split('/'));
var length = Math.min(fromParts.length, toParts.length);
var samePartsLength = length;
for (var i = 0; i < length; i++) {
if (fromParts[i] !== toParts[i]) {
samePartsLength = i;
break;
}
}
var outputParts = [];
for (var i = samePartsLength; i < fromParts.length; i++) {
outputParts.push('..');
}
outputParts = outputParts.concat(toParts.slice(samePartsLength));
return outputParts.join('/');
};
exports.sep = '/';
exports.delimiter = ':';
exports.dirname = function(path) {
var result = splitPath(path),
root = result[0],
dir = result[1];
if (!root && !dir) {
// No dirname whatsoever
return '.';
}
if (dir) {
// It has a dirname, strip trailing slash
dir = dir.substr(0, dir.length - 1);
}
return root + dir;
};
exports.basename = function(path, ext) {
var f = splitPath(path)[2];
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
}
return f;
};
exports.extname = function(path) {
return splitPath(path)[3];
};
function filter (xs, f) {
if (xs.filter) return xs.filter(f);
var res = [];
for (var i = 0; i < xs.length; i++) {
if (f(xs[i], i, xs)) res.push(xs[i]);
}
return res;
}
// String.prototype.substr - negative index don't work in IE8
var substr = 'ab'.substr(-1) === 'b'
? function (str, start, len) { return str.substr(start, len) }
: function (str, start, len) {
if (start < 0) start = str.length + start;
return str.substr(start, len);
}
;
}).call(this,require('_process'))
},{"_process":7}],7:[function(require,module,exports){
// shim for using process in browser
var process = module.exports = {};
var queue = [];
var draining = false;
function drainQueue() {
if (draining) {
return;
}
draining = true;
var currentQueue;
var len = queue.length;
while(len) {
currentQueue = queue;
queue = [];
var i = -1;
while (++i < len) {
currentQueue[i]();
}
len = queue.length;
}
draining = false;
}
process.nextTick = function (fun) {
queue.push(fun);
if (!draining) {
setTimeout(drainQueue, 0);
}
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};
function noop() {}
process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.binding = function (name) {
throw new Error('process.binding is not supported');
};
// TODO(shtylman)
process.cwd = function () { return '/' };
process.chdir = function (dir) {
throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };
},{}],8:[function(require,module,exports){
!function() {
var d3 = {
version: "3.5.3"
};
if (!Date.now) Date.now = function() {
return +new Date();
};
var d3_arraySlice = [].slice, d3_array = function(list) {
return d3_arraySlice.call(list);
};
var d3_document = document, d3_documentElement = d3_document.documentElement, d3_window = window;
try {
d3_array(d3_documentElement.childNodes)[0].nodeType;
} catch (e) {
d3_array = function(list) {
var i = list.length, array = new Array(i);
while (i--) array[i] = list[i];
return array;
};
}
try {
d3_document.createElement("div").style.setProperty("opacity", 0, "");
} catch (error) {
var d3_element_prototype = d3_window.Element.prototype, d3_element_setAttribute = d3_element_prototype.setAttribute, d3_element_setAttributeNS = d3_element_prototype.setAttributeNS, d3_style_prototype = d3_window.CSSStyleDeclaration.prototype, d3_style_setProperty = d3_style_prototype.setProperty;
d3_element_prototype.setAttribute = function(name, value) {
d3_element_setAttribute.call(this, name, value + "");
};
d3_element_prototype.setAttributeNS = function(space, local, value) {
d3_element_setAttributeNS.call(this, space, local, value + "");
};
d3_style_prototype.setProperty = function(name, value, priority) {
d3_style_setProperty.call(this, name, value + "", priority);
};
}
d3.ascending = d3_ascending;
function d3_ascending(a, b) {
return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
d3.descending = function(a, b) {
return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
};
d3.min = function(array, f) {
var i = -1, n = array.length, a, b;
if (arguments.length === 1) {
while (++i < n) if ((b = array[i]) != null && b >= b) {
a = b;
break;
}
while (++i < n) if ((b = array[i]) != null && a > b) a = b;
} else {
while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {
a = b;
break;
}
while (++i < n) if ((b = f.call(array, array[i], i)) != null && a > b) a = b;
}
return a;
};
d3.max = function(array, f) {
var i = -1, n = array.length, a, b;
if (arguments.length === 1) {
while (++i < n) if ((b = array[i]) != null && b >= b) {
a = b;
break;
}
while (++i < n) if ((b = array[i]) != null && b > a) a = b;
} else {
while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {
a = b;
break;
}
while (++i < n) if ((b = f.call(array, array[i], i)) != null && b > a) a = b;
}
return a;
};
d3.extent = function(array, f) {
var i = -1, n = array.length, a, b, c;
if (arguments.length === 1) {
while (++i < n) if ((b = array[i]) != null && b >= b) {
a = c = b;
break;
}
while (++i < n) if ((b = array[i]) != null) {
if (a > b) a = b;
if (c < b) c = b;
}
} else {
while (++i < n) if ((b = f.call(array, array[i], i)) != null && b >= b) {
a = c = b;
break;
}
while (++i < n) if ((b = f.call(array, array[i], i)) != null) {
if (a > b) a = b;
if (c < b) c = b;
}
}
return [ a, c ];
};
function d3_number(x) {
return x === null ? NaN : +x;
}
function d3_numeric(x) {
return !isNaN(x);
}
d3.sum = function(array, f) {
var s = 0, n = array.length, a, i = -1;
if (arguments.length === 1) {
while (++i < n) if (d3_numeric(a = +array[i])) s += a;
} else {
while (++i < n) if (d3_numeric(a = +f.call(array, array[i], i))) s += a;
}
return s;
};
d3.mean = function(array, f) {
var s = 0, n = array.length, a, i = -1, j = n;
if (arguments.length === 1) {
while (++i < n) if (d3_numeric(a = d3_number(array[i]))) s += a; else --j;
} else {
while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) s += a; else --j;
}
if (j) return s / j;
};
d3.quantile = function(values, p) {
var H = (values.length - 1) * p + 1, h = Math.floor(H), v = +values[h - 1], e = H - h;
return e ? v + e * (values[h] - v) : v;
};
d3.median = function(array, f) {
var numbers = [], n = array.length, a, i = -1;
if (arguments.length === 1) {
while (++i < n) if (d3_numeric(a = d3_number(array[i]))) numbers.push(a);
} else {
while (++i < n) if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) numbers.push(a);
}
if (numbers.length) return d3.quantile(numbers.sort(d3_ascending), .5);
};
d3.variance = function(array, f) {
var n = array.length, m = 0, a, d, s = 0, i = -1, j = 0;
if (arguments.length === 1) {
while (++i < n) {
if (d3_numeric(a = d3_number(array[i]))) {
d = a - m;
m += d / ++j;
s += d * (a - m);
}
}
} else {
while (++i < n) {
if (d3_numeric(a = d3_number(f.call(array, array[i], i)))) {
d = a - m;
m += d / ++j;
s += d * (a - m);
}
}
}
if (j > 1) return s / (j - 1);
};
d3.deviation = function() {
var v = d3.variance.apply(this, arguments);
return v ? Math.sqrt(v) : v;
};
function d3_bisector(compare) {
return {
left: function(a, x, lo, hi) {
if (arguments.length < 3) lo = 0;
if (arguments.length < 4) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (compare(a[mid], x) < 0) lo = mid + 1; else hi = mid;
}
return lo;
},
right: function(a, x, lo, hi) {
if (arguments.length < 3) lo = 0;
if (arguments.length < 4) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (compare(a[mid], x) > 0) hi = mid; else lo = mid + 1;
}
return lo;
}
};
}
var d3_bisect = d3_bisector(d3_ascending);
d3.bisectLeft = d3_bisect.left;
d3.bisect = d3.bisectRight = d3_bisect.right;
d3.bisector = function(f) {
return d3_bisector(f.length === 1 ? function(d, x) {
return d3_ascending(f(d), x);
} : f);
};
d3.shuffle = function(array, i0, i1) {
if ((m = arguments.length) < 3) {
i1 = array.length;
if (m < 2) i0 = 0;
}
var m = i1 - i0, t, i;
while (m) {
i = Math.random() * m-- | 0;
t = array[m + i0], array[m + i0] = array[i + i0], array[i + i0] = t;
}
return array;
};
d3.permute = function(array, indexes) {
var i = indexes.length, permutes = new Array(i);
while (i--) permutes[i] = array[indexes[i]];
return permutes;
};
d3.pairs = function(array) {
var i = 0, n = array.length - 1, p0, p1 = array[0], pairs = new Array(n < 0 ? 0 : n);
while (i < n) pairs[i] = [ p0 = p1, p1 = array[++i] ];
return pairs;
};
d3.zip = function() {
if (!(n = arguments.length)) return [];
for (var i = -1, m = d3.min(arguments, d3_zipLength), zips = new Array(m); ++i < m; ) {
for (var j = -1, n, zip = zips[i] = new Array(n); ++j < n; ) {
zip[j] = arguments[j][i];
}
}
return zips;
};
function d3_zipLength(d) {
return d.length;
}
d3.transpose = function(matrix) {
return d3.zip.apply(d3, matrix);
};
d3.keys = function(map) {
var keys = [];
for (var key in map) keys.push(key);
return keys;
};
d3.values = function(map) {
var values = [];
for (var key in map) values.push(map[key]);
return values;
};
d3.entries = function(map) {
var entries = [];
for (var key in map) entries.push({
key: key,
value: map[key]
});
return entries;
};
d3.merge = function(arrays) {
var n = arrays.length, m, i = -1, j = 0, merged, array;
while (++i < n) j += arrays[i].length;
merged = new Array(j);
while (--n >= 0) {
array = arrays[n];
m = array.length;
while (--m >= 0) {
merged[--j] = array[m];
}
}
return merged;
};
var abs = Math.abs;
d3.range = function(start, stop, step) {
if (arguments.length < 3) {
step = 1;
if (arguments.length < 2) {
stop = start;
start = 0;
}
}
if ((stop - start) / step === Infinity) throw new Error("infinite range");
var range = [], k = d3_range_integerScale(abs(step)), i = -1, j;
start *= k, stop *= k, step *= k;
if (step < 0) while ((j = start + step * ++i) > stop) range.push(j / k); else while ((j = start + step * ++i) < stop) range.push(j / k);
return range;
};
function d3_range_integerScale(x) {
var k = 1;
while (x * k % 1) k *= 10;
return k;
}
function d3_class(ctor, properties) {
for (var key in properties) {
Object.defineProperty(ctor.prototype, key, {
value: properties[key],
enumerable: false
});
}
}
d3.map = function(object, f) {
var map = new d3_Map();
if (object instanceof d3_Map) {
object.forEach(function(key, value) {
map.set(key, value);
});
} else if (Array.isArray(object)) {
var i = -1, n = object.length, o;
if (arguments.length === 1) while (++i < n) map.set(i, object[i]); else while (++i < n) map.set(f.call(object, o = object[i], i), o);
} else {
for (var key in object) map.set(key, object[key]);
}
return map;
};
function d3_Map() {
this._ = Object.create(null);
}
var d3_map_proto = "__proto__", d3_map_zero = "\x00";
d3_class(d3_Map, {
has: d3_map_has,
get: function(key) {
return this._[d3_map_escape(key)];
},
set: function(key, value) {
return this._[d3_map_escape(key)] = value;
},
remove: d3_map_remove,
keys: d3_map_keys,
values: function() {
var values = [];
for (var key in this._) values.push(this._[key]);
return values;
},
entries: function() {
var entries = [];
for (var key in this._) entries.push({
key: d3_map_unescape(key),
value: this._[key]
});
return entries;
},
size: d3_map_size,
empty: d3_map_empty,
forEach: function(f) {
for (var key in this._) f.call(this, d3_map_unescape(key), this._[key]);
}
});
function d3_map_escape(key) {
return (key += "") === d3_map_proto || key[0] === d3_map_zero ? d3_map_zero + key : key;
}
function d3_map_unescape(key) {
return (key += "")[0] === d3_map_zero ? key.slice(1) : key;
}
function d3_map_has(key) {
return d3_map_escape(key) in this._;
}
function d3_map_remove(key) {
return (key = d3_map_escape(key)) in this._ && delete this._[key];
}
function d3_map_keys() {
var keys = [];
for (var key in this._) keys.push(d3_map_unescape(key));
return keys;
}
function d3_map_size() {
var size = 0;
for (var key in this._) ++size;
return size;
}
function d3_map_empty() {
for (var key in this._) return false;
return true;
}
d3.nest = function() {
var nest = {}, keys = [], sortKeys = [], sortValues, rollup;
function map(mapType, array, depth) {
if (depth >= keys.length) return rollup ? rollup.call(nest, array) : sortValues ? array.sort(sortValues) : array;
var i = -1, n = array.length, key = keys[depth++], keyValue, object, setter, valuesByKey = new d3_Map(), values;
while (++i < n) {
if (values = valuesByKey.get(keyValue = key(object = array[i]))) {
values.push(object);
} else {
valuesByKey.set(keyValue, [ object ]);
}
}
if (mapType) {
object = mapType();
setter = function(keyValue, values) {
object.set(keyValue, map(mapType, values, depth));
};
} else {
object = {};
setter = function(keyValue, values) {
object[keyValue] = map(mapType, values, depth);
};
}
valuesByKey.forEach(setter);
return object;
}
function entries(map, depth) {
if (depth >= keys.length) return map;
var array = [], sortKey = sortKeys[depth++];
map.forEach(function(key, keyMap) {
array.push({
key: key,
values: entries(keyMap, depth)
});
});
return sortKey ? array.sort(function(a, b) {
return sortKey(a.key, b.key);
}) : array;
}
nest.map = function(array, mapType) {
return map(mapType, array, 0);
};
nest.entries = function(array) {
return entries(map(d3.map, array, 0), 0);
};
nest.key = function(d) {
keys.push(d);
return nest;
};
nest.sortKeys = function(order) {
sortKeys[keys.length - 1] = order;
return nest;
};
nest.sortValues = function(order) {
sortValues = order;
return nest;
};
nest.rollup = function(f) {
rollup = f;
return nest;
};
return nest;
};
d3.set = function(array) {
var set = new d3_Set();
if (array) for (var i = 0, n = array.length; i < n; ++i) set.add(array[i]);
return set;
};
function d3_Set() {
this._ = Object.create(null);
}
d3_class(d3_Set, {
has: d3_map_has,
add: function(key) {
this._[d3_map_escape(key += "")] = true;
return key;
},
remove: d3_map_remove,
values: d3_map_keys,
size: d3_map_size,
empty: d3_map_empty,
forEach: function(f) {
for (var key in this._) f.call(this, d3_map_unescape(key));
}
});
d3.behavior = {};
d3.rebind = function(target, source) {
var i = 1, n = arguments.length, method;
while (++i < n) target[method = arguments[i]] = d3_rebind(target, source, source[method]);
return target;
};
function d3_rebind(target, source, method) {
return function() {
var value = method.apply(source, arguments);
return value === source ? target : value;
};
}
function d3_vendorSymbol(object, name) {
if (name in object) return name;
name = name.charAt(0).toUpperCase() + name.slice(1);
for (var i = 0, n = d3_vendorPrefixes.length; i < n; ++i) {
var prefixName = d3_vendorPrefixes[i] + name;
if (prefixName in object) return prefixName;
}
}
var d3_vendorPrefixes = [ "webkit", "ms", "moz", "Moz", "o", "O" ];
function d3_noop() {}
d3.dispatch = function() {
var dispatch = new d3_dispatch(), i = -1, n = arguments.length;
while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
return dispatch;
};
function d3_dispatch() {}
d3_dispatch.prototype.on = function(type, listener) {
var i = type.indexOf("."), name = "";
if (i >= 0) {
name = type.slice(i + 1);
type = type.slice(0, i);
}
if (type) return arguments.length < 2 ? this[type].on(name) : this[type].on(name, listener);
if (arguments.length === 2) {
if (listener == null) for (type in this) {
if (this.hasOwnProperty(type)) this[type].on(name, null);
}
return this;
}
};
function d3_dispatch_event(dispatch) {
var listeners = [], listenerByName = new d3_Map();
function event() {
var z = listeners, i = -1, n = z.length, l;
while (++i < n) if (l = z[i].on) l.apply(this, arguments);
return dispatch;
}
event.on = function(name, listener) {
var l = listenerByName.get(name), i;
if (arguments.length < 2) return l && l.on;
if (l) {
l.on = null;
listeners = listeners.slice(0, i = listeners.indexOf(l)).concat(listeners.slice(i + 1));
listenerByName.remove(name);
}
if (listener) listeners.push(listenerByName.set(name, {
on: listener
}));
return dispatch;
};
return event;
}
d3.event = null;
function d3_eventPreventDefault() {
d3.event.preventDefault();
}
function d3_eventSource() {
var e = d3.event, s;
while (s = e.sourceEvent) e = s;
return e;
}
function d3_eventDispatch(target) {
var dispatch = new d3_dispatch(), i = 0, n = arguments.length;
while (++i < n) dispatch[arguments[i]] = d3_dispatch_event(dispatch);
dispatch.of = function(thiz, argumentz) {
return function(e1) {
try {
var e0 = e1.sourceEvent = d3.event;
e1.target = target;
d3.event = e1;
dispatch[e1.type].apply(thiz, argumentz);
} finally {
d3.event = e0;
}
};
};
return dispatch;
}
d3.requote = func