diff --git a/lib/ButtonLink.js b/lib/ButtonLink.js index dd757e2..f5c5333 100644 --- a/lib/ButtonLink.js +++ b/lib/ButtonLink.js @@ -16,19 +16,16 @@ var ButtonLink = React.createClass({displayName: 'ButtonLink', getInitialState: function() { return { - href: '#', - isActive: false + href: '#' } }, componentDidMount: function() { var params = this.getCleanedParams(); var href = this.makeHref(this.props.to, params, this.props.query || null); - var isActive = this.isActive(this.props.to); this.setState({ - href: href, - isActive: isActive + href: href }); }, diff --git a/lib/NavItemLink.js b/lib/NavItemLink.js index f3104a3..98e8da3 100644 --- a/lib/NavItemLink.js +++ b/lib/NavItemLink.js @@ -16,7 +16,8 @@ ADDITIONAL_RESERVED_PROPS = [ 'navItem', 'onSelect', 'ref', - 'children' + 'children', + 'query' ]; var NavItemLink = React.createClass({displayName: 'NavItemLink', @@ -26,27 +27,27 @@ var NavItemLink = React.createClass({displayName: 'NavItemLink', getInitialState: function() { return { - href: '#', - isActive: false + params: false } }, componentDidMount: function() { - var params = this.getCleanedParams(); - var href = this.makeHref(this.props.to, params, this.props.query || null); - var isActive = this.isActive(this.props.to, params, this.props.query || null); - this.setState({ - href: href, - isActive: isActive + params: this.getCleanedParams(this.props) }); }, - getCleanedParams: function() { + getCleanedParams: function(props) { var reserved = Object.keys(this.refs.navItem.constructor.propTypes) .concat(this.additionalReservedProps); - return helpers.withoutProperties(this.props, reserved || []); + return helpers.withoutProperties(props, reserved || []); + }, + + componentWillReceiveProps: function(nextProps) { + this.setState({ + params: this.getCleanedParams(nextProps) + }); }, handleRouteTo: function (e) { @@ -54,16 +55,23 @@ var NavItemLink = React.createClass({displayName: 'NavItemLink', return; } e.preventDefault(); - var params = this.getCleanedParams(); - return this.transitionTo(this.props.to, params, this.props.query || null); + return this.transitionTo(this.props.to, this.state.params, this.props.query || null); }, render: function() { + if (this.state.params !== false) { + var href = this.makeHref(this.props.to, this.state.params, this.props.query || null); + var active = this.isActive(this.props.to, this.state.params, this.props.query || null); + } else { + var href = "#"; + var active = false; + } + return ( React.createElement(NavItem, React.__spread({}, this.props, - {href: this.state.href, - active: this.state.isActive, + {href: href, + active: active, onClick: this.handleRouteTo, ref: "navItem"}), this.props.children diff --git a/src/ButtonLink.js b/src/ButtonLink.js index c974250..c50b365 100644 --- a/src/ButtonLink.js +++ b/src/ButtonLink.js @@ -16,19 +16,16 @@ var ButtonLink = React.createClass({ getInitialState: function() { return { - href: '#', - isActive: false + href: '#' } }, componentDidMount: function() { var params = this.getCleanedParams(); var href = this.makeHref(this.props.to, params, this.props.query || null); - var isActive = this.isActive(this.props.to); this.setState({ - href: href, - isActive: isActive + href: href }); }, diff --git a/src/NavItemLink.js b/src/NavItemLink.js index 84fb0f5..4abff0b 100644 --- a/src/NavItemLink.js +++ b/src/NavItemLink.js @@ -16,7 +16,8 @@ ADDITIONAL_RESERVED_PROPS = [ 'navItem', 'onSelect', 'ref', - 'children' + 'children', + 'query' ]; var NavItemLink = React.createClass({ @@ -26,27 +27,27 @@ var NavItemLink = React.createClass({ getInitialState: function() { return { - href: '#', - isActive: false + params: false } }, componentDidMount: function() { - var params = this.getCleanedParams(); - var href = this.makeHref(this.props.to, params, this.props.query || null); - var isActive = this.isActive(this.props.to, params, this.props.query || null); - this.setState({ - href: href, - isActive: isActive + params: this.getCleanedParams(this.props) }); }, - getCleanedParams: function() { + getCleanedParams: function(props) { var reserved = Object.keys(this.refs.navItem.constructor.propTypes) .concat(this.additionalReservedProps); - return helpers.withoutProperties(this.props, reserved || []); + return helpers.withoutProperties(props, reserved || []); + }, + + componentWillReceiveProps: function(nextProps) { + this.setState({ + params: this.getCleanedParams(nextProps) + }); }, handleRouteTo: function (e) { @@ -54,16 +55,23 @@ var NavItemLink = React.createClass({ return; } e.preventDefault(); - var params = this.getCleanedParams(); - return this.transitionTo(this.props.to, params, this.props.query || null); + return this.transitionTo(this.props.to, this.state.params, this.props.query || null); }, render: function() { + if (this.state.params !== false) { + var href = this.makeHref(this.props.to, this.state.params, this.props.query || null); + var active = this.isActive(this.props.to, this.state.params, this.props.query || null); + } else { + var href = "#"; + var active = false; + } + return ( {this.props.children} diff --git a/tests/0.12/bundle.js b/tests/0.12/bundle.js index c38792c..f6e88d8 100644 --- a/tests/0.12/bundle.js +++ b/tests/0.12/bundle.js @@ -1,1861 +1,1908 @@ (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 + * @license MIT + */ -var Router = require('react-router') - , RouteHandler = Router.RouteHandler - , Route = Router.Route; +var base64 = require('base64-js') +var ieee754 = require('ieee754') +var isArray = require('is-array') -var ReactBootstrap = require('react-bootstrap') - , Nav = ReactBootstrap.Nav; +exports.Buffer = Buffer +exports.SlowBuffer = Buffer +exports.INSPECT_MAX_BYTES = 50 +Buffer.poolSize = 8192 // not used by this implementation -var ReactRouterBootstrap = require('react-router-bootstrap') - , NavItemLink = ReactRouterBootstrap.NavItemLink - , ButtonLink = ReactRouterBootstrap.ButtonLink; +var kMaxLength = 0x3fffffff -var App = React.createClass({displayName: 'App', - render: function() { - return ( - React.createElement("div", null, - React.createElement("b", null, 'Linky'), React.createElement("br", null), - React.createElement(Nav, null, - React.createElement(NavItemLink, { - to: "destination", - firstParam: "hello", - secondParam: "navlinky"}, - "Test linky without query params" - ) - ), React.createElement("br", null), - React.createElement("b", null, 'Linky'), React.createElement("br", null), - React.createElement(Nav, null, - React.createElement(NavItemLink, { - to: "destination", - firstParam: "hello", - secondParam: "navlinky-with-query-params", - query: {firstQuery: 'hello', secondQuery: 'navlinky'}}, - "Test linky with query params" - ) - ), React.createElement("br", null), - React.createElement("b", null, 'Linky'), React.createElement("br", null), - React.createElement(ButtonLink, { - to: "destination", - firstParam: "hello", - secondParam: "buttonlinky"}, - "Button linky without query params" - ), React.createElement("br", null), - React.createElement("b", null, '>Linky'), React.createElement("br", null), - React.createElement(ButtonLink, { - to: "destination", - firstParam: "hello", - secondParam: "buttonlinky-with-query-params", - query: {firstQuery: 'hello', secondQuery: 'buttonlinky'}}, - "Button linky with query params" - ), React.createElement("br", null), - React.createElement(RouteHandler, null) - ) - ); +/** + * If `Buffer.TYPED_ARRAY_SUPPORT`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (most compatible, even IE6) + * + * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, + * Opera 11.6+, iOS 4.2+. + * + * Note: + * + * - Implementation must support adding new properties to `Uint8Array` instances. + * Firefox 4-29 lacked support, fixed in Firefox 30+. + * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. + * + * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. + * + * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of + * incorrect length in some situations. + * + * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will + * get the Object implementation, which is slower but will work correctly. + */ +Buffer.TYPED_ARRAY_SUPPORT = (function () { + try { + var buf = new ArrayBuffer(0) + var arr = new Uint8Array(buf) + arr.foo = function () { return 42 } + return 42 === arr.foo() && // typed array instances can be augmented + typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` + new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` + } catch (e) { + return false } -}); +})() -var Destination = React.createClass({displayName: 'Destination', - mixins: [State], +/** + * Class: Buffer + * ============= + * + * The Buffer constructor returns instances of `Uint8Array` that are augmented + * with function properties for all the node `Buffer` API functions. We use + * `Uint8Array` so that square bracket notation works as expected -- it returns + * a single octet. + * + * By augmenting the instances, we can avoid modifying the `Uint8Array` + * prototype. + */ +function Buffer (subject, encoding, noZero) { + if (!(this instanceof Buffer)) + return new Buffer(subject, encoding, noZero) - render: function() { - return ( - React.createElement("div", null, - React.createElement("h1", null, "Button seems to work! =)"), - React.createElement("b", null, "getParams"), React.createElement("br", null), - JSON.stringify(this.getParams()), React.createElement("br", null), - React.createElement("b", null, "getQuery"), React.createElement("br", null), - JSON.stringify(this.getQuery()) - ) - ); - } -}); + var type = typeof subject -var routes = ( - React.createElement(Route, {handler: App, path: "/"}, - React.createElement(Route, {name: "destination", path: "destination/:firstParam/:secondParam", handler: Destination}) - ) -); + // Find the length + var length + if (type === 'number') + length = subject > 0 ? subject >>> 0 : 0 + else if (type === 'string') { + if (encoding === 'base64') + subject = base64clean(subject) + length = Buffer.byteLength(subject, encoding) + } else if (type === 'object' && subject !== null) { // assume object is array-like + if (subject.type === 'Buffer' && isArray(subject.data)) + subject = subject.data + length = +subject.length > 0 ? Math.floor(+subject.length) : 0 + } else + throw new TypeError('must start with number, buffer, array or string') -Router.run(routes, function (Handler) { - React.render(React.createElement(Handler, null), document.body); -}); + if (this.length > kMaxLength) + throw new RangeError('Attempt to allocate Buffer larger than maximum ' + + 'size: 0x' + kMaxLength.toString(16) + ' bytes') -},{"react":253,"react-bootstrap":51,"react-router":75,"react-router-bootstrap":65}],2:[function(require,module,exports){ -var React = require('react'); -var PanelGroup = require('./PanelGroup'); + var buf + if (Buffer.TYPED_ARRAY_SUPPORT) { + // Preferred: Return an augmented `Uint8Array` instance for best performance + buf = Buffer._augment(new Uint8Array(length)) + } else { + // Fallback: Return THIS instance of Buffer (created by `new`) + buf = this + buf.length = length + buf._isBuffer = true + } -var Accordion = React.createClass({displayName: 'Accordion', - render: function () { - return ( - React.createElement(PanelGroup, React.__spread({}, this.props, {accordion: true}), - this.props.children - ) - ); + var i + if (Buffer.TYPED_ARRAY_SUPPORT && typeof subject.byteLength === 'number') { + // Speed optimization -- use set if we're copying from a typed array + buf._set(subject) + } else if (isArrayish(subject)) { + // Treat array-ish objects as a byte array + if (Buffer.isBuffer(subject)) { + for (i = 0; i < length; i++) + buf[i] = subject.readUInt8(i) + } else { + for (i = 0; i < length; i++) + buf[i] = ((subject[i] % 256) + 256) % 256 + } + } else if (type === 'string') { + buf.write(subject, 0, encoding) + } else if (type === 'number' && !Buffer.TYPED_ARRAY_SUPPORT && !noZero) { + for (i = 0; i < length; i++) { + buf[i] = 0 + } } -}); -module.exports = Accordion; -},{"./PanelGroup":39,"react":253}],3:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var AffixMixin = require('./AffixMixin'); -var domUtils = require('./utils/domUtils'); + return buf +} -var Affix = React.createClass({displayName: 'Affix', - statics: { - domUtils: domUtils - }, +Buffer.isBuffer = function (b) { + return !!(b != null && b._isBuffer) +} - mixins: [AffixMixin], +Buffer.compare = function (a, b) { + if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) + throw new TypeError('Arguments must be Buffers') - render: function () { - var holderStyle = {top: this.state.affixPositionTop}; - return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, this.state.affixClass), style: holderStyle}), - this.props.children - ) - ); + var x = a.length + var y = b.length + for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {} + if (i !== len) { + x = a[i] + y = b[i] } -}); + if (x < y) return -1 + if (y < x) return 1 + return 0 +} -module.exports = Affix; -},{"./AffixMixin":4,"./utils/domUtils":60,"./utils/joinClasses":61,"react":253}],4:[function(require,module,exports){ -/* global window, document */ +Buffer.isEncoding = function (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'binary': + case 'base64': + case 'raw': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} -var React = require('react'); -var domUtils = require('./utils/domUtils'); -var EventListener = require('./utils/EventListener'); +Buffer.concat = function (list, totalLength) { + if (!isArray(list)) throw new TypeError('Usage: Buffer.concat(list[, length])') -var AffixMixin = { - propTypes: { - offset: React.PropTypes.number, - offsetTop: React.PropTypes.number, - offsetBottom: React.PropTypes.number - }, - - getInitialState: function () { - return { - affixClass: 'affix-top' - }; - }, + if (list.length === 0) { + return new Buffer(0) + } else if (list.length === 1) { + return list[0] + } - getPinnedOffset: function (DOMNode) { - if (this.pinnedOffset) { - return this.pinnedOffset; + var i + if (totalLength === undefined) { + totalLength = 0 + for (i = 0; i < list.length; i++) { + totalLength += list[i].length } + } - DOMNode.className = DOMNode.className.replace(/affix-top|affix-bottom|affix/, ''); - DOMNode.className += DOMNode.className.length ? ' affix' : 'affix'; - - this.pinnedOffset = domUtils.getOffset(DOMNode).top - window.pageYOffset; - - return this.pinnedOffset; - }, + var buf = new Buffer(totalLength) + var pos = 0 + for (i = 0; i < list.length; i++) { + var item = list[i] + item.copy(buf, pos) + pos += item.length + } + return buf +} - checkPosition: function () { - var DOMNode, scrollHeight, scrollTop, position, offsetTop, offsetBottom, - affix, affixType, affixPositionTop; +Buffer.byteLength = function (str, encoding) { + var ret + str = str + '' + switch (encoding || 'utf8') { + case 'ascii': + case 'binary': + case 'raw': + ret = str.length + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = str.length * 2 + break + case 'hex': + ret = str.length >>> 1 + break + case 'utf8': + case 'utf-8': + ret = utf8ToBytes(str).length + break + case 'base64': + ret = base64ToBytes(str).length + break + default: + ret = str.length + } + return ret +} - // TODO: or not visible - if (!this.isMounted()) { - return; - } +// pre-set for values that may exist in the future +Buffer.prototype.length = undefined +Buffer.prototype.parent = undefined - DOMNode = this.getDOMNode(); - scrollHeight = document.documentElement.offsetHeight; - scrollTop = window.pageYOffset; - position = domUtils.getOffset(DOMNode); - offsetTop; - offsetBottom; +// toString(encoding, start=0, end=buffer.length) +Buffer.prototype.toString = function (encoding, start, end) { + var loweredCase = false - if (this.affixed === 'top') { - position.top += scrollTop; - } + start = start >>> 0 + end = end === undefined || end === Infinity ? this.length : end >>> 0 - offsetTop = this.props.offsetTop != null ? - this.props.offsetTop : this.props.offset; - offsetBottom = this.props.offsetBottom != null ? - this.props.offsetBottom : this.props.offset; + if (!encoding) encoding = 'utf8' + if (start < 0) start = 0 + if (end > this.length) end = this.length + if (end <= start) return '' - if (offsetTop == null && offsetBottom == null) { - return; - } - if (offsetTop == null) { - offsetTop = 0; - } - if (offsetBottom == null) { - offsetBottom = 0; - } + while (true) { + switch (encoding) { + case 'hex': + return hexSlice(this, start, end) - if (this.unpin != null && (scrollTop + this.unpin <= position.top)) { - affix = false; - } else if (offsetBottom != null && (position.top + DOMNode.offsetHeight >= scrollHeight - offsetBottom)) { - affix = 'bottom'; - } else if (offsetTop != null && (scrollTop <= offsetTop)) { - affix = 'top'; - } else { - affix = false; - } + case 'utf8': + case 'utf-8': + return utf8Slice(this, start, end) - if (this.affixed === affix) { - return; - } + case 'ascii': + return asciiSlice(this, start, end) - if (this.unpin != null) { - DOMNode.style.top = ''; - } + case 'binary': + return binarySlice(this, start, end) - affixType = 'affix' + (affix ? '-' + affix : ''); + case 'base64': + return base64Slice(this, start, end) - this.affixed = affix; - this.unpin = affix === 'bottom' ? - this.getPinnedOffset(DOMNode) : null; + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return utf16leSlice(this, start, end) - if (affix === 'bottom') { - DOMNode.className = DOMNode.className.replace(/affix-top|affix-bottom|affix/, 'affix-bottom'); - affixPositionTop = scrollHeight - offsetBottom - DOMNode.offsetHeight - domUtils.getOffset(DOMNode).top; + default: + if (loweredCase) + throw new TypeError('Unknown encoding: ' + encoding) + encoding = (encoding + '').toLowerCase() + loweredCase = true } + } +} - this.setState({ - affixClass: affixType, - affixPositionTop: affixPositionTop - }); - }, +Buffer.prototype.equals = function (b) { + if(!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + return Buffer.compare(this, b) === 0 +} - checkPositionWithEventLoop: function () { - setTimeout(this.checkPosition, 0); - }, +Buffer.prototype.inspect = function () { + var str = '' + var max = exports.INSPECT_MAX_BYTES + if (this.length > 0) { + str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') + if (this.length > max) + str += ' ... ' + } + return '' +} - componentDidMount: function () { - this._onWindowScrollListener = - EventListener.listen(window, 'scroll', this.checkPosition); - this._onDocumentClickListener = - EventListener.listen(document, 'click', this.checkPositionWithEventLoop); - }, +Buffer.prototype.compare = function (b) { + if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') + return Buffer.compare(this, b) +} - componentWillUnmount: function () { - if (this._onWindowScrollListener) { - this._onWindowScrollListener.remove(); - } +// `get` will be removed in Node 0.13+ +Buffer.prototype.get = function (offset) { + console.log('.get() is deprecated. Access using array indexes instead.') + return this.readUInt8(offset) +} - if (this._onDocumentClickListener) { - this._onDocumentClickListener.remove(); - } - }, +// `set` will be removed in Node 0.13+ +Buffer.prototype.set = function (v, offset) { + console.log('.set() is deprecated. Access using array indexes instead.') + return this.writeUInt8(v, offset) +} - componentDidUpdate: function (prevProps, prevState) { - if (prevState.affixClass === this.state.affixClass) { - this.checkPositionWithEventLoop(); +function hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining } } -}; -module.exports = AffixMixin; -},{"./utils/EventListener":53,"./utils/domUtils":60,"react":253}],5:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var BootstrapMixin = require('./BootstrapMixin'); + // must be an even number of digits + var strLen = string.length + if (strLen % 2 !== 0) throw new Error('Invalid hex string') + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16) + if (isNaN(byte)) throw new Error('Invalid hex string') + buf[offset + i] = byte + } + return i +} -var Alert = React.createClass({displayName: 'Alert', - mixins: [BootstrapMixin], +function utf8Write (buf, string, offset, length) { + var charsWritten = blitBuffer(utf8ToBytes(string), buf, offset, length) + return charsWritten +} - propTypes: { - onDismiss: React.PropTypes.func, - dismissAfter: React.PropTypes.number - }, +function asciiWrite (buf, string, offset, length) { + var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length) + return charsWritten +} - getDefaultProps: function () { - return { - bsClass: 'alert', - bsStyle: 'info' - }; - }, - - renderDismissButton: function () { - return ( - React.createElement("button", { - type: "button", - className: "close", - onClick: this.props.onDismiss, - 'aria-hidden': "true"}, - "×" - ) - ); - }, - - render: function () { - var classes = this.getBsClassSet(); - var isDismissable = !!this.props.onDismiss; +function binaryWrite (buf, string, offset, length) { + return asciiWrite(buf, string, offset, length) +} - classes['alert-dismissable'] = isDismissable; +function base64Write (buf, string, offset, length) { + var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length) + return charsWritten +} - return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), - isDismissable ? this.renderDismissButton() : null, - this.props.children - ) - ); - }, +function utf16leWrite (buf, string, offset, length) { + var charsWritten = blitBuffer(utf16leToBytes(string), buf, offset, length, 2) + return charsWritten +} - componentDidMount: function() { - if (this.props.dismissAfter && this.props.onDismiss) { - this.dismissTimer = setTimeout(this.props.onDismiss, this.props.dismissAfter); +Buffer.prototype.write = function (string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length + length = undefined } - }, + } else { // legacy + var swap = encoding + encoding = offset + offset = length + length = swap + } - componentWillUnmount: function() { - clearTimeout(this.dismissTimer); + offset = Number(offset) || 0 + var remaining = this.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } } -}); + encoding = String(encoding || 'utf8').toLowerCase() -module.exports = Alert; -},{"./BootstrapMixin":7,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],6:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var ValidComponentChildren = require('./utils/ValidComponentChildren'); -var classSet = require('./utils/classSet'); + var ret + switch (encoding) { + case 'hex': + ret = hexWrite(this, string, offset, length) + break + case 'utf8': + case 'utf-8': + ret = utf8Write(this, string, offset, length) + break + case 'ascii': + ret = asciiWrite(this, string, offset, length) + break + case 'binary': + ret = binaryWrite(this, string, offset, length) + break + case 'base64': + ret = base64Write(this, string, offset, length) + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = utf16leWrite(this, string, offset, length) + break + default: + throw new TypeError('Unknown encoding: ' + encoding) + } + return ret +} -var Badge = React.createClass({displayName: 'Badge', - propTypes: { - pullRight: React.PropTypes.bool - }, +Buffer.prototype.toJSON = function () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} - render: function () { - var classes = { - 'pull-right': this.props.pullRight, - 'badge': (ValidComponentChildren.hasValidComponent(this.props.children) - || (typeof this.props.children === 'string')) - }; - return ( - React.createElement("span", React.__spread({}, - this.props, - {className: joinClasses(this.props.className, classSet(classes))}), - this.props.children - ) - ); +function base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) } -}); +} -module.exports = Badge; +function utf8Slice (buf, start, end) { + var res = '' + var tmp = '' + end = Math.min(buf.length, end) -},{"./utils/ValidComponentChildren":56,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],7:[function(require,module,exports){ -var React = require('react'); -var constants = require('./constants'); + for (var i = start; i < end; i++) { + if (buf[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) + tmp = '' + } else { + tmp += '%' + buf[i].toString(16) + } + } -var BootstrapMixin = { - propTypes: { - bsClass: React.PropTypes.oneOf(Object.keys(constants.CLASSES)), - bsStyle: React.PropTypes.oneOf(Object.keys(constants.STYLES)), - bsSize: React.PropTypes.oneOf(Object.keys(constants.SIZES)) - }, + return res + decodeUtf8Char(tmp) +} - getBsClassSet: function () { - var classes = {}; +function asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) - var bsClass = this.props.bsClass && constants.CLASSES[this.props.bsClass]; - if (bsClass) { - classes[bsClass] = true; + for (var i = start; i < end; i++) { + ret += String.fromCharCode(buf[i]) + } + return ret +} - var prefix = bsClass + '-'; +function binarySlice (buf, start, end) { + return asciiSlice(buf, start, end) +} - var bsSize = this.props.bsSize && constants.SIZES[this.props.bsSize]; - if (bsSize) { - classes[prefix + bsSize] = true; - } +function hexSlice (buf, start, end) { + var len = buf.length - var bsStyle = this.props.bsStyle && constants.STYLES[this.props.bsStyle]; - if (this.props.bsStyle) { - classes[prefix + bsStyle] = true; - } - } + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len - return classes; + var out = '' + for (var i = start; i < end; i++) { + out += toHex(buf[i]) } -}; - -module.exports = BootstrapMixin; -},{"./constants":50,"react":253}],8:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var BootstrapMixin = require('./BootstrapMixin'); + return out +} -var Button = React.createClass({displayName: 'Button', - mixins: [BootstrapMixin], +function utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) + } + return res +} - propTypes: { - active: React.PropTypes.bool, - disabled: React.PropTypes.bool, - block: React.PropTypes.bool, - navItem: React.PropTypes.bool, - navDropdown: React.PropTypes.bool, - componentClass: React.PropTypes.node - }, +Buffer.prototype.slice = function (start, end) { + var len = this.length + start = ~~start + end = end === undefined ? len : ~~end - getDefaultProps: function () { - return { - bsClass: 'button', - bsStyle: 'default', - type: 'button' - }; - }, + if (start < 0) { + start += len; + if (start < 0) + start = 0 + } else if (start > len) { + start = len + } - render: function () { - var classes = this.props.navDropdown ? {} : this.getBsClassSet(); - var renderFuncName; + if (end < 0) { + end += len + if (end < 0) + end = 0 + } else if (end > len) { + end = len + } - classes['active'] = this.props.active; - classes['btn-block'] = this.props.block; + if (end < start) + end = start - if (this.props.navItem) { - return this.renderNavItem(classes); + if (Buffer.TYPED_ARRAY_SUPPORT) { + return Buffer._augment(this.subarray(start, end)) + } else { + var sliceLen = end - start + var newBuf = new Buffer(sliceLen, undefined, true) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] } + return newBuf + } +} - renderFuncName = this.props.href || this.props.navDropdown ? - 'renderAnchor' : 'renderButton'; - - return this[renderFuncName](classes); - }, - - renderAnchor: function (classes) { +/* + * Need to make sure that buffer isn't trying to write out of bounds. + */ +function checkOffset (offset, ext, length) { + if ((offset % 1) !== 0 || offset < 0) + throw new RangeError('offset is not uint') + if (offset + ext > length) + throw new RangeError('Trying to access beyond buffer length') +} - var Component = this.props.componentClass || 'a'; - var href = this.props.href || '#'; - classes['disabled'] = this.props.disabled; +Buffer.prototype.readUInt8 = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 1, this.length) + return this[offset] +} - return ( - React.createElement(Component, React.__spread({}, - this.props, - {href: href, - className: joinClasses(this.props.className, classSet(classes)), - role: "button"}), - this.props.children - ) - ); - }, +Buffer.prototype.readUInt16LE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 2, this.length) + return this[offset] | (this[offset + 1] << 8) +} - renderButton: function (classes) { - var Component = this.props.componentClass || 'button'; +Buffer.prototype.readUInt16BE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 2, this.length) + return (this[offset] << 8) | this[offset + 1] +} - return ( - React.createElement(Component, React.__spread({}, - this.props, - {className: joinClasses(this.props.className, classSet(classes))}), - this.props.children - ) - ); - }, +Buffer.prototype.readUInt32LE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 4, this.length) - renderNavItem: function (classes) { - var liClasses = { - active: this.props.active - }; + return ((this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16)) + + (this[offset + 3] * 0x1000000) +} - return ( - React.createElement("li", {className: classSet(liClasses)}, - this.renderAnchor(classes) - ) - ); - } -}); +Buffer.prototype.readUInt32BE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 4, this.length) -module.exports = Button; + return (this[offset] * 0x1000000) + + ((this[offset + 1] << 16) | + (this[offset + 2] << 8) | + this[offset + 3]) +} -},{"./BootstrapMixin":7,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],9:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var BootstrapMixin = require('./BootstrapMixin'); -var Button = require('./Button'); +Buffer.prototype.readInt8 = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 1, this.length) + if (!(this[offset] & 0x80)) + return (this[offset]) + return ((0xff - this[offset] + 1) * -1) +} -var ButtonGroup = React.createClass({displayName: 'ButtonGroup', - mixins: [BootstrapMixin], +Buffer.prototype.readInt16LE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 2, this.length) + var val = this[offset] | (this[offset + 1] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} - propTypes: { - vertical: React.PropTypes.bool, - justified: React.PropTypes.bool - }, +Buffer.prototype.readInt16BE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 2, this.length) + var val = this[offset + 1] | (this[offset] << 8) + return (val & 0x8000) ? val | 0xFFFF0000 : val +} - getDefaultProps: function () { - return { - bsClass: 'button-group' - }; - }, +Buffer.prototype.readInt32LE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 4, this.length) - render: function () { - var classes = this.getBsClassSet(); - classes['btn-group'] = !this.props.vertical; - classes['btn-group-vertical'] = this.props.vertical; - classes['btn-group-justified'] = this.props.justified; + return (this[offset]) | + (this[offset + 1] << 8) | + (this[offset + 2] << 16) | + (this[offset + 3] << 24) +} - return ( - React.createElement("div", React.__spread({}, - this.props, - {className: joinClasses(this.props.className, classSet(classes))}), - this.props.children - ) - ); - } -}); +Buffer.prototype.readInt32BE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 4, this.length) -module.exports = ButtonGroup; -},{"./BootstrapMixin":7,"./Button":8,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],10:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var BootstrapMixin = require('./BootstrapMixin'); -var Button = require('./Button'); + return (this[offset] << 24) | + (this[offset + 1] << 16) | + (this[offset + 2] << 8) | + (this[offset + 3]) +} -var ButtonToolbar = React.createClass({displayName: 'ButtonToolbar', - mixins: [BootstrapMixin], +Buffer.prototype.readFloatLE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, true, 23, 4) +} - getDefaultProps: function () { - return { - bsClass: 'button-toolbar' - }; - }, +Buffer.prototype.readFloatBE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 4, this.length) + return ieee754.read(this, offset, false, 23, 4) +} - render: function () { - var classes = this.getBsClassSet(); +Buffer.prototype.readDoubleLE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, true, 52, 8) +} - return ( - React.createElement("div", React.__spread({}, - this.props, - {role: "toolbar", - className: joinClasses(this.props.className, classSet(classes))}), - this.props.children - ) - ); - } -}); +Buffer.prototype.readDoubleBE = function (offset, noAssert) { + if (!noAssert) + checkOffset(offset, 8, this.length) + return ieee754.read(this, offset, false, 52, 8) +} -module.exports = ButtonToolbar; -},{"./BootstrapMixin":7,"./Button":8,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],11:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var cloneWithProps = require('./utils/cloneWithProps'); -var BootstrapMixin = require('./BootstrapMixin'); -var ValidComponentChildren = require('./utils/ValidComponentChildren'); +function checkInt (buf, value, offset, ext, max, min) { + if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') + if (value > max || value < min) throw new TypeError('value is out of bounds') + if (offset + ext > buf.length) throw new TypeError('index out of range') +} -var Carousel = React.createClass({displayName: 'Carousel', - mixins: [BootstrapMixin], +Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 1, 0xff, 0) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + this[offset] = value + return offset + 1 +} - propTypes: { - slide: React.PropTypes.bool, - indicators: React.PropTypes.bool, - controls: React.PropTypes.bool, - pauseOnHover: React.PropTypes.bool, - wrap: React.PropTypes.bool, - onSelect: React.PropTypes.func, - onSlideEnd: React.PropTypes.func, - activeIndex: React.PropTypes.number, - defaultActiveIndex: React.PropTypes.number, - direction: React.PropTypes.oneOf(['prev', 'next']) - }, +function objectWriteUInt16 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { + buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} - getDefaultProps: function () { - return { - slide: true, - interval: 5000, - pauseOnHover: true, - wrap: true, - indicators: true, - controls: true - }; - }, +Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + } else objectWriteUInt16(this, value, offset, true) + return offset + 2 +} - getInitialState: function () { - return { - activeIndex: this.props.defaultActiveIndex == null ? - 0 : this.props.defaultActiveIndex, - previousActiveIndex: null, - direction: null - }; - }, +Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 2, 0xffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = value + } else objectWriteUInt16(this, value, offset, false) + return offset + 2 +} - getDirection: function (prevIndex, index) { - if (prevIndex === index) { - return null; - } +function objectWriteUInt32 (buf, value, offset, littleEndian) { + if (value < 0) value = 0xffffffff + value + 1 + for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { + buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} - return prevIndex > index ? - 'prev' : 'next'; - }, +Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset + 3] = (value >>> 24) + this[offset + 2] = (value >>> 16) + this[offset + 1] = (value >>> 8) + this[offset] = value + } else objectWriteUInt32(this, value, offset, true) + return offset + 4 +} - componentWillReceiveProps: function (nextProps) { - var activeIndex = this.getActiveIndex(); +Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 4, 0xffffffff, 0) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = value + } else objectWriteUInt32(this, value, offset, false) + return offset + 4 +} - if (nextProps.activeIndex != null && nextProps.activeIndex !== activeIndex) { - clearTimeout(this.timeout); - this.setState({ - previousActiveIndex: activeIndex, - direction: nextProps.direction != null ? - nextProps.direction : this.getDirection(activeIndex, nextProps.activeIndex) - }); - } - }, +Buffer.prototype.writeInt8 = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 1, 0x7f, -0x80) + if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) + if (value < 0) value = 0xff + value + 1 + this[offset] = value + return offset + 1 +} - componentDidMount: function () { - this.waitForNext(); - }, +Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + } else objectWriteUInt16(this, value, offset, true) + return offset + 2 +} - componentWillUnmount: function() { - clearTimeout(this.timeout); - }, +Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 2, 0x7fff, -0x8000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 8) + this[offset + 1] = value + } else objectWriteUInt16(this, value, offset, false) + return offset + 2 +} - next: function (e) { - if (e) { - e.preventDefault(); - } +Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = value + this[offset + 1] = (value >>> 8) + this[offset + 2] = (value >>> 16) + this[offset + 3] = (value >>> 24) + } else objectWriteUInt32(this, value, offset, true) + return offset + 4 +} - var index = this.getActiveIndex() + 1; - var count = ValidComponentChildren.numberOf(this.props.children); +Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { + value = +value + offset = offset >>> 0 + if (!noAssert) + checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) + if (value < 0) value = 0xffffffff + value + 1 + if (Buffer.TYPED_ARRAY_SUPPORT) { + this[offset] = (value >>> 24) + this[offset + 1] = (value >>> 16) + this[offset + 2] = (value >>> 8) + this[offset + 3] = value + } else objectWriteUInt32(this, value, offset, false) + return offset + 4 +} - if (index > count - 1) { - if (!this.props.wrap) { - return; - } - index = 0; - } +function checkIEEE754 (buf, value, offset, ext, max, min) { + if (value > max || value < min) throw new TypeError('value is out of bounds') + if (offset + ext > buf.length) throw new TypeError('index out of range') +} - this.handleSelect(index, 'next'); - }, +function writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) + checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) + ieee754.write(buf, value, offset, littleEndian, 23, 4) + return offset + 4 +} - prev: function (e) { - if (e) { - e.preventDefault(); - } +Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { + return writeFloat(this, value, offset, true, noAssert) +} - var index = this.getActiveIndex() - 1; +Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { + return writeFloat(this, value, offset, false, noAssert) +} - if (index < 0) { - if (!this.props.wrap) { - return; - } - index = ValidComponentChildren.numberOf(this.props.children) - 1; - } +function writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) + checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) + ieee754.write(buf, value, offset, littleEndian, 52, 8) + return offset + 8 +} - this.handleSelect(index, 'prev'); - }, +Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { + return writeDouble(this, value, offset, true, noAssert) +} - pause: function () { - this.isPaused = true; - clearTimeout(this.timeout); - }, +Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { + return writeDouble(this, value, offset, false, noAssert) +} - play: function () { - this.isPaused = false; - this.waitForNext(); - }, +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function (target, target_start, start, end) { + var source = this - waitForNext: function () { - if (!this.isPaused && this.props.slide && this.props.interval && - this.props.activeIndex == null) { - this.timeout = setTimeout(this.next, this.props.interval); - } - }, + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (!target_start) target_start = 0 - handleMouseOver: function () { - if (this.props.pauseOnHover) { - this.pause(); - } - }, + // Copy 0 bytes; we're done + if (end === start) return + if (target.length === 0 || source.length === 0) return - handleMouseOut: function () { - if (this.isPaused) { - this.play(); - } - }, + // Fatal error conditions + if (end < start) throw new TypeError('sourceEnd < sourceStart') + if (target_start < 0 || target_start >= target.length) + throw new TypeError('targetStart out of bounds') + if (start < 0 || start >= source.length) throw new TypeError('sourceStart out of bounds') + if (end < 0 || end > source.length) throw new TypeError('sourceEnd out of bounds') - render: function () { - var classes = { - carousel: true, - slide: this.props.slide - }; + // Are we oob? + if (end > this.length) + end = this.length + if (target.length - target_start < end - start) + end = target.length - target_start + start - return ( - React.createElement("div", React.__spread({}, - this.props, - {className: joinClasses(this.props.className, classSet(classes)), - onMouseOver: this.handleMouseOver, - onMouseOut: this.handleMouseOut}), - this.props.indicators ? this.renderIndicators() : null, - React.createElement("div", {className: "carousel-inner", ref: "inner"}, - ValidComponentChildren.map(this.props.children, this.renderItem) - ), - this.props.controls ? this.renderControls() : null - ) - ); - }, + var len = end - start - renderPrev: function () { - return ( - React.createElement("a", {className: "left carousel-control", href: "#prev", key: 0, onClick: this.prev}, - React.createElement("span", {className: "glyphicon glyphicon-chevron-left"}) - ) - ); - }, + if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { + for (var i = 0; i < len; i++) { + target[i + target_start] = this[i + start] + } + } else { + target._set(this.subarray(start, start + len), target_start) + } +} - renderNext: function () { - return ( - React.createElement("a", {className: "right carousel-control", href: "#next", key: 1, onClick: this.next}, - React.createElement("span", {className: "glyphicon glyphicon-chevron-right"}) - ) - ); - }, +// fill(value, start=0, end=buffer.length) +Buffer.prototype.fill = function (value, start, end) { + if (!value) value = 0 + if (!start) start = 0 + if (!end) end = this.length - renderControls: function () { - if (this.props.wrap) { - var activeIndex = this.getActiveIndex(); - var count = ValidComponentChildren.numberOf(this.props.children); + if (end < start) throw new TypeError('end < start') - return [ - (activeIndex !== 0) ? this.renderPrev() : null, - (activeIndex !== count - 1) ? this.renderNext() : null - ]; + // Fill 0 bytes; we're done + if (end === start) return + if (this.length === 0) return + + if (start < 0 || start >= this.length) throw new TypeError('start out of bounds') + if (end < 0 || end > this.length) throw new TypeError('end out of bounds') + + var i + if (typeof value === 'number') { + for (i = start; i < end; i++) { + this[i] = value + } + } else { + var bytes = utf8ToBytes(value.toString()) + var len = bytes.length + for (i = start; i < end; i++) { + this[i] = bytes[i % len] } + } - return [ - this.renderPrev(), - this.renderNext() - ]; - }, + return this +} - renderIndicator: function (child, index) { - var className = (index === this.getActiveIndex()) ? - 'active' : null; +/** + * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. + * Added in Node 0.12. Only available in browsers that support ArrayBuffer. + */ +Buffer.prototype.toArrayBuffer = function () { + if (typeof Uint8Array !== 'undefined') { + if (Buffer.TYPED_ARRAY_SUPPORT) { + return (new Buffer(this)).buffer + } else { + var buf = new Uint8Array(this.length) + for (var i = 0, len = buf.length; i < len; i += 1) { + buf[i] = this[i] + } + return buf.buffer + } + } else { + throw new TypeError('Buffer.toArrayBuffer not supported in this browser') + } +} - return ( - React.createElement("li", { - key: index, - className: className, - onClick: this.handleSelect.bind(this, index, null)}) - ); - }, +// HELPER FUNCTIONS +// ================ - renderIndicators: function () { - var indicators = []; - ValidComponentChildren - .forEach(this.props.children, function(child, index) { - indicators.push( - this.renderIndicator(child, index), +var BP = Buffer.prototype - // Force whitespace between indicator elements, bootstrap - // requires this for correct spacing of elements. - ' ' - ); - }, this); +/** + * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods + */ +Buffer._augment = function (arr) { + arr.constructor = Buffer + arr._isBuffer = true - return ( - React.createElement("ol", {className: "carousel-indicators"}, - indicators - ) - ); - }, + // save reference to original Uint8Array get/set methods before overwriting + arr._get = arr.get + arr._set = arr.set - getActiveIndex: function () { - return this.props.activeIndex != null ? this.props.activeIndex : this.state.activeIndex; - }, + // deprecated, will be removed in node 0.13+ + arr.get = BP.get + arr.set = BP.set - handleItemAnimateOutEnd: function () { - this.setState({ - previousActiveIndex: null, - direction: null - }, function() { - this.waitForNext(); + arr.write = BP.write + arr.toString = BP.toString + arr.toLocaleString = BP.toString + arr.toJSON = BP.toJSON + arr.equals = BP.equals + arr.compare = BP.compare + arr.copy = BP.copy + arr.slice = BP.slice + arr.readUInt8 = BP.readUInt8 + arr.readUInt16LE = BP.readUInt16LE + arr.readUInt16BE = BP.readUInt16BE + arr.readUInt32LE = BP.readUInt32LE + arr.readUInt32BE = BP.readUInt32BE + arr.readInt8 = BP.readInt8 + arr.readInt16LE = BP.readInt16LE + arr.readInt16BE = BP.readInt16BE + arr.readInt32LE = BP.readInt32LE + arr.readInt32BE = BP.readInt32BE + arr.readFloatLE = BP.readFloatLE + arr.readFloatBE = BP.readFloatBE + arr.readDoubleLE = BP.readDoubleLE + arr.readDoubleBE = BP.readDoubleBE + arr.writeUInt8 = BP.writeUInt8 + arr.writeUInt16LE = BP.writeUInt16LE + arr.writeUInt16BE = BP.writeUInt16BE + arr.writeUInt32LE = BP.writeUInt32LE + arr.writeUInt32BE = BP.writeUInt32BE + arr.writeInt8 = BP.writeInt8 + arr.writeInt16LE = BP.writeInt16LE + arr.writeInt16BE = BP.writeInt16BE + arr.writeInt32LE = BP.writeInt32LE + arr.writeInt32BE = BP.writeInt32BE + arr.writeFloatLE = BP.writeFloatLE + arr.writeFloatBE = BP.writeFloatBE + arr.writeDoubleLE = BP.writeDoubleLE + arr.writeDoubleBE = BP.writeDoubleBE + arr.fill = BP.fill + arr.inspect = BP.inspect + arr.toArrayBuffer = BP.toArrayBuffer - if (this.props.onSlideEnd) { - this.props.onSlideEnd(); - } - }); - }, + return arr +} - renderItem: function (child, index) { - var activeIndex = this.getActiveIndex(); - var isActive = (index === activeIndex); - var isPreviousActive = this.state.previousActiveIndex != null && - this.state.previousActiveIndex === index && this.props.slide; +var INVALID_BASE64_RE = /[^+\/0-9A-z]/g - return cloneWithProps( - child, - { - active: isActive, - ref: child.ref, - key: child.key ? child.key : index, - index: index, - animateOut: isPreviousActive, - animateIn: isActive && this.state.previousActiveIndex != null && this.props.slide, - direction: this.state.direction, - onAnimateOutEnd: isPreviousActive ? this.handleItemAnimateOutEnd: null - } - ); - }, +function base64clean (str) { + // Node strips out invalid characters like \n and \t from the string, base64-js does not + str = stringtrim(str).replace(INVALID_BASE64_RE, '') + // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not + while (str.length % 4 !== 0) { + str = str + '=' + } + return str +} - handleSelect: function (index, direction) { - clearTimeout(this.timeout); +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} - var previousActiveIndex = this.getActiveIndex(); - direction = direction || this.getDirection(previousActiveIndex, index); +function isArrayish (subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number' +} - if (this.props.onSelect) { - this.props.onSelect(index, direction); - } +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} - if (this.props.activeIndex == null && index !== previousActiveIndex) { - if (this.state.previousActiveIndex != null) { - // If currently animating don't activate the new index. - // TODO: look into queuing this canceled call and - // animating after the current animation has ended. - return; +function utf8ToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + var b = str.charCodeAt(i) + if (b <= 0x7F) { + byteArray.push(b) + } else { + var start = i + if (b >= 0xD800 && b <= 0xDFFF) i++ + var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%') + for (var j = 0; j < h.length; j++) { + byteArray.push(parseInt(h[j], 16)) } - - this.setState({ - activeIndex: index, - previousActiveIndex: previousActiveIndex, - direction: direction - }); } } -}); - -module.exports = Carousel; -},{"./BootstrapMixin":7,"./utils/ValidComponentChildren":56,"./utils/classSet":57,"./utils/cloneWithProps":58,"./utils/joinClasses":61,"react":253}],12:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var TransitionEvents = require('./utils/TransitionEvents'); + return byteArray +} -var CarouselItem = React.createClass({displayName: 'CarouselItem', - propTypes: { - direction: React.PropTypes.oneOf(['prev', 'next']), - onAnimateOutEnd: React.PropTypes.func, - active: React.PropTypes.bool, - caption: React.PropTypes.node - }, +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} - getInitialState: function () { - return { - direction: null - }; - }, +function utf16leToBytes (str) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } - getDefaultProps: function () { - return { - animation: true - }; - }, + return byteArray +} - handleAnimateOutEnd: function () { - if (this.props.onAnimateOutEnd && this.isMounted()) { - this.props.onAnimateOutEnd(this.props.index); - } - }, +function base64ToBytes (str) { + return base64.toByteArray(str) +} - componentWillReceiveProps: function (nextProps) { - if (this.props.active !== nextProps.active) { - this.setState({ - direction: null - }); - } - }, +function blitBuffer (src, dst, offset, length, unitSize) { + if (unitSize) length -= length % unitSize; + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) + break + dst[i + offset] = src[i] + } + return i +} - componentDidUpdate: function (prevProps) { - if (!this.props.active && prevProps.active) { - TransitionEvents.addEndEventListener( - this.getDOMNode(), - this.handleAnimateOutEnd - ); - } +function decodeUtf8Char (str) { + try { + return decodeURIComponent(str) + } catch (err) { + return String.fromCharCode(0xFFFD) // UTF 8 invalid char + } +} - if (this.props.active !== prevProps.active) { - setTimeout(this.startAnimation, 20); - } - }, +},{"base64-js":2,"ieee754":3,"is-array":4}],2:[function(require,module,exports){ +var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; - startAnimation: function () { - if (!this.isMounted()) { - return; - } +;(function (exports) { + 'use strict'; - this.setState({ - direction: this.props.direction === 'prev' ? - 'right' : 'left' - }); - }, + var Arr = (typeof Uint8Array !== 'undefined') + ? Uint8Array + : Array - render: function () { - var classes = { - item: true, - active: (this.props.active && !this.props.animateIn) || this.props.animateOut, - next: this.props.active && this.props.animateIn && this.props.direction === 'next', - prev: this.props.active && this.props.animateIn && this.props.direction === 'prev' - }; + var PLUS = '+'.charCodeAt(0) + var SLASH = '/'.charCodeAt(0) + var NUMBER = '0'.charCodeAt(0) + var LOWER = 'a'.charCodeAt(0) + var UPPER = 'A'.charCodeAt(0) - if (this.state.direction && (this.props.animateIn || this.props.animateOut)) { - classes[this.state.direction] = true; - } + function decode (elt) { + var code = elt.charCodeAt(0) + if (code === PLUS) + return 62 // '+' + if (code === SLASH) + return 63 // '/' + if (code < NUMBER) + return -1 //no match + if (code < NUMBER + 10) + return code - NUMBER + 26 + 26 + if (code < UPPER + 26) + return code - UPPER + if (code < LOWER + 26) + return code - LOWER + 26 + } - return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), - this.props.children, - this.props.caption ? this.renderCaption() : null - ) - ); - }, + function b64ToByteArray (b64) { + var i, j, l, tmp, placeHolders, arr - renderCaption: function () { - return ( - React.createElement("div", {className: "carousel-caption"}, - this.props.caption - ) - ); - } -}); + if (b64.length % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } -module.exports = CarouselItem; -},{"./utils/TransitionEvents":55,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],13:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var constants = require('./constants'); + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + var len = b64.length + placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(b64.length * 3 / 4 - placeHolders) -var Col = React.createClass({displayName: 'Col', - propTypes: { - xs: React.PropTypes.number, - sm: React.PropTypes.number, - md: React.PropTypes.number, - lg: React.PropTypes.number, - xsOffset: React.PropTypes.number, - smOffset: React.PropTypes.number, - mdOffset: React.PropTypes.number, - lgOffset: React.PropTypes.number, - xsPush: React.PropTypes.number, - smPush: React.PropTypes.number, - mdPush: React.PropTypes.number, - lgPush: React.PropTypes.number, - xsPull: React.PropTypes.number, - smPull: React.PropTypes.number, - mdPull: React.PropTypes.number, - lgPull: React.PropTypes.number, - componentClass: React.PropTypes.node.isRequired - }, + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length - getDefaultProps: function () { - return { - componentClass: 'div' - }; - }, + var L = 0 - render: function () { - var ComponentClass = this.props.componentClass; - var classes = {}; + function push (v) { + arr[L++] = v + } - Object.keys(constants.SIZES).forEach(function (key) { - var size = constants.SIZES[key]; - var prop = size; - var classPart = size + '-'; + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) + push((tmp & 0xFF0000) >> 16) + push((tmp & 0xFF00) >> 8) + push(tmp & 0xFF) + } - if (this.props[prop]) { - classes['col-' + classPart + this.props[prop]] = true; - } + if (placeHolders === 2) { + tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) + push(tmp & 0xFF) + } else if (placeHolders === 1) { + tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) + push((tmp >> 8) & 0xFF) + push(tmp & 0xFF) + } - prop = size + 'Offset'; - classPart = size + '-offset-'; - if (this.props[prop]) { - classes['col-' + classPart + this.props[prop]] = true; - } + return arr + } - prop = size + 'Push'; - classPart = size + '-push-'; - if (this.props[prop]) { - classes['col-' + classPart + this.props[prop]] = true; - } + function uint8ToBase64 (uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length - prop = size + 'Pull'; - classPart = size + '-pull-'; - if (this.props[prop]) { - classes['col-' + classPart + this.props[prop]] = true; - } - }, this); + function encode (num) { + return lookup.charAt(num) + } - return ( - React.createElement(ComponentClass, React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), - this.props.children - ) - ); - } -}); + function tripletToBase64 (num) { + return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) + } -module.exports = Col; -},{"./constants":50,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],14:[function(require,module,exports){ -var React = require('react'); -var TransitionEvents = require('./utils/TransitionEvents'); + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output += tripletToBase64(temp) + } -var CollapsableMixin = { - - propTypes: { - collapsable: React.PropTypes.bool, - defaultExpanded: React.PropTypes.bool, - expanded: React.PropTypes.bool - }, - - getInitialState: function () { - return { - expanded: this.props.defaultExpanded != null ? this.props.defaultExpanded : null, - collapsing: false - }; - }, - - handleTransitionEnd: function () { - this._collapseEnd = true; - this.setState({ - collapsing: false - }); - }, + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1] + output += encode(temp >> 2) + output += encode((temp << 4) & 0x3F) + output += '==' + break + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) + output += encode(temp >> 10) + output += encode((temp >> 4) & 0x3F) + output += encode((temp << 2) & 0x3F) + output += '=' + break + } - componentWillReceiveProps: function (newProps) { - if (this.props.collapsable && newProps.expanded !== this.props.expanded) { - this._collapseEnd = false; - this.setState({ - collapsing: true - }); - } - }, + return output + } - _addEndTransitionListener: function () { - var node = this.getCollapsableDOMNode(); + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 +}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) - if (node) { - TransitionEvents.addEndEventListener( - node, - this.handleTransitionEnd - ); - } - }, +},{}],3:[function(require,module,exports){ +exports.read = function(buffer, offset, isLE, mLen, nBytes) { + var e, m, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = isLE ? (nBytes - 1) : 0, + d = isLE ? -1 : 1, + s = buffer[offset + i]; - _removeEndTransitionListener: function () { - var node = this.getCollapsableDOMNode(); + i += d; - if (node) { - TransitionEvents.removeEndEventListener( - node, - this.handleTransitionEnd - ); - } - }, + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); - componentDidMount: function () { - this._afterRender(); - }, + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); - componentWillUnmount: function () { - this._removeEndTransitionListener(); - }, + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity); + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); +}; - componentWillUpdate: function (nextProps) { - var dimension = (typeof this.getCollapsableDimension === 'function') ? - this.getCollapsableDimension() : 'height'; - var node = this.getCollapsableDOMNode(); +exports.write = function(buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), + i = isLE ? 0 : (nBytes - 1), + d = isLE ? 1 : -1, + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; - this._removeEndTransitionListener(); - }, + value = Math.abs(value); - componentDidUpdate: function (prevProps, prevState) { - this._afterRender(); - }, + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } - _afterRender: function () { - if (!this.props.collapsable) { - return; + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; } + } - this._addEndTransitionListener(); - setTimeout(this._updateDimensionAfterRender, 0); - }, + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); - _updateDimensionAfterRender: function () { - var node = this.getCollapsableDOMNode(); - if (node) { - var dimension = (typeof this.getCollapsableDimension === 'function') ? - this.getCollapsableDimension() : 'height'; - node.style[dimension] = this.isExpanded() ? - this.getCollapsableDimensionValue() + 'px' : '0px'; - } - }, + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); - isExpanded: function () { - return (this.props.expanded != null) ? - this.props.expanded : this.state.expanded; - }, + buffer[offset + i - d] |= s * 128; +}; - getCollapsableClassSet: function (className) { - var classes = {}; +},{}],4:[function(require,module,exports){ - if (typeof className === 'string') { - className.split(' ').forEach(function (className) { - if (className) { - classes[className] = true; - } - }); - } +/** + * isArray + */ - classes.collapsing = this.state.collapsing; - classes.collapse = !this.state.collapsing; - classes['in'] = this.isExpanded() && !this.state.collapsing; +var isArray = Array.isArray; - return classes; - } -}; +/** + * toString + */ -module.exports = CollapsableMixin; +var str = Object.prototype.toString; -},{"./utils/TransitionEvents":55,"react":253}],15:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var cloneWithProps = require('./utils/cloneWithProps'); +/** + * Whether or not the given `val` + * is an array. + * + * example: + * + * isArray([]); + * // > true + * isArray(arguments); + * // > false + * isArray(''); + * // > false + * + * @param {mixed} val + * @return {bool} + */ -var createChainedFunction = require('./utils/createChainedFunction'); -var BootstrapMixin = require('./BootstrapMixin'); -var DropdownStateMixin = require('./DropdownStateMixin'); -var Button = require('./Button'); -var ButtonGroup = require('./ButtonGroup'); -var DropdownMenu = require('./DropdownMenu'); -var ValidComponentChildren = require('./utils/ValidComponentChildren'); +module.exports = isArray || function (val) { + return !! val && '[object Array]' == str.call(val); +}; +},{}],5:[function(require,module,exports){ +// shim for using process in browser -var DropdownButton = React.createClass({displayName: 'DropdownButton', - mixins: [BootstrapMixin, DropdownStateMixin], +var process = module.exports = {}; - propTypes: { - pullRight: React.PropTypes.bool, - dropup: React.PropTypes.bool, - title: React.PropTypes.node, - href: React.PropTypes.string, - onClick: React.PropTypes.func, - onSelect: React.PropTypes.func, - navItem: React.PropTypes.bool - }, +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canMutationObserver = typeof window !== 'undefined' + && window.MutationObserver; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; - render: function () { - var className = 'dropdown-toggle'; + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } - var renderMethod = this.props.navItem ? - 'renderNavItem' : 'renderButtonGroup'; + var queue = []; - return this[renderMethod]([ - React.createElement(Button, React.__spread({}, - this.props, - {ref: "dropdownButton", - className: joinClasses(this.props.className, className), - onClick: this.handleDropdownClick, - key: 0, - navDropdown: this.props.navItem, - navItem: null, - title: null, - pullRight: null, - dropup: null}), - this.props.title, ' ', - React.createElement("span", {className: "caret"}) - ), - React.createElement(DropdownMenu, { - ref: "menu", - 'aria-labelledby': this.props.id, - pullRight: this.props.pullRight, - key: 1}, - ValidComponentChildren.map(this.props.children, this.renderMenuItem) - ) - ]); - }, + if (canMutationObserver) { + var hiddenDiv = document.createElement("div"); + var observer = new MutationObserver(function () { + var queueList = queue.slice(); + queue.length = 0; + queueList.forEach(function (fn) { + fn(); + }); + }); - renderButtonGroup: function (children) { - var groupClasses = { - 'open': this.state.open, - 'dropup': this.props.dropup - }; + observer.observe(hiddenDiv, { attributes: true }); + + return function nextTick(fn) { + if (!queue.length) { + hiddenDiv.setAttribute('yes', 'no'); + } + queue.push(fn); + }; + } + + if (canPost) { + window.addEventListener('message', function (ev) { + var source = ev.source; + if ((source === window || source === null) && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +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'); +}; + +},{}],6:[function(require,module,exports){ +var React = window.React = require('react'); + +var ReactRouter = require('react-router') + , State = ReactRouter.State; + +var Router = require('react-router') + , RouteHandler = Router.RouteHandler + , Route = Router.Route; +var ReactBootstrap = require('react-bootstrap') + , Nav = ReactBootstrap.Nav; + +var ReactRouterBootstrap = require('react-router-bootstrap') + , NavItemLink = ReactRouterBootstrap.NavItemLink + , ButtonLink = ReactRouterBootstrap.ButtonLink; + +var App = React.createClass({displayName: 'App', + render: function() { return ( - React.createElement(ButtonGroup, { - bsSize: this.props.bsSize, - className: classSet(groupClasses)}, - children + React.createElement("div", null, + React.createElement("b", null, 'Linky'), React.createElement("br", null), + React.createElement(Nav, null, + React.createElement(NavItemLink, { + to: "destination", + firstParam: "hello", + secondParam: "navlinky"}, + "Test linky without query params" + ), + React.createElement("br", null), + React.createElement("b", null, 'Linky'), React.createElement("br", null), + React.createElement(NavItemLink, { + to: "destination", + firstParam: "hello", + secondParam: "navlinky-with-query-params", + query: {firstQuery: 'hello', secondQuery: 'navlinky'}}, + "Test linky with query params" + ) + ), React.createElement("br", null), + React.createElement("b", null, 'Linky'), React.createElement("br", null), + React.createElement(ButtonLink, { + to: "destination", + firstParam: "hello", + secondParam: "buttonlinky"}, + "Button linky without query params" + ), React.createElement("br", null), + React.createElement("b", null, '>Linky'), React.createElement("br", null), + React.createElement(ButtonLink, { + to: "destination", + firstParam: "hello", + secondParam: "buttonlinky-with-query-params", + query: {firstQuery: 'hello', secondQuery: 'buttonlinky'}}, + "Button linky with query params" + ), React.createElement("br", null), + React.createElement(RouteHandler, null) ) ); - }, + } +}); - renderNavItem: function (children) { - var classes = { - 'dropdown': true, - 'open': this.state.open, - 'dropup': this.props.dropup - }; +var Destination = React.createClass({displayName: 'Destination', + mixins: [State], + render: function() { return ( - React.createElement("li", {className: classSet(classes)}, - children + React.createElement("div", null, + React.createElement("h1", null, "Button seems to work! =)"), + React.createElement("b", null, "getParams"), React.createElement("br", null), + JSON.stringify(this.getParams()), React.createElement("br", null), + React.createElement("b", null, "getQuery"), React.createElement("br", null), + JSON.stringify(this.getQuery()) ) ); - }, + } +}); - renderMenuItem: function (child, index) { - // Only handle the option selection if an onSelect prop has been set on the - // component or it's child, this allows a user not to pass an onSelect - // handler and have the browser preform the default action. - var handleOptionSelect = this.props.onSelect || child.props.onSelect ? - this.handleOptionSelect : null; +var routes = ( + React.createElement(Route, {handler: App, path: "/"}, + React.createElement(Route, {name: "destination", path: "destination/:firstParam/:secondParam", handler: Destination}) + ) +); - return cloneWithProps( - child, - { - // Capture onSelect events - onSelect: createChainedFunction(child.props.onSelect, handleOptionSelect), +Router.run(routes, function (Handler) { + React.render(React.createElement(Handler, null), document.body); +}); - // Force special props to be transferred - key: child.key ? child.key : index, - ref: child.ref - } +},{"react":258,"react-bootstrap":56,"react-router":80,"react-router-bootstrap":70}],7:[function(require,module,exports){ +var React = require('react'); +var PanelGroup = require('./PanelGroup'); + +var Accordion = React.createClass({displayName: 'Accordion', + render: function () { + return ( + React.createElement(PanelGroup, React.__spread({}, this.props, {accordion: true}), + this.props.children + ) ); - }, + } +}); - handleDropdownClick: function (e) { - e.preventDefault(); +module.exports = Accordion; +},{"./PanelGroup":44,"react":258}],8:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var AffixMixin = require('./AffixMixin'); +var domUtils = require('./utils/domUtils'); - this.setDropdownState(!this.state.open); +var Affix = React.createClass({displayName: 'Affix', + statics: { + domUtils: domUtils }, - handleOptionSelect: function (key) { - if (this.props.onSelect) { - this.props.onSelect(key); - } + mixins: [AffixMixin], - this.setDropdownState(false); + render: function () { + var holderStyle = {top: this.state.affixPositionTop}; + return ( + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, this.state.affixClass), style: holderStyle}), + this.props.children + ) + ); } }); -module.exports = DropdownButton; -},{"./BootstrapMixin":7,"./Button":8,"./ButtonGroup":9,"./DropdownMenu":16,"./DropdownStateMixin":17,"./utils/ValidComponentChildren":56,"./utils/classSet":57,"./utils/cloneWithProps":58,"./utils/createChainedFunction":59,"./utils/joinClasses":61,"react":253}],16:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var cloneWithProps = require('./utils/cloneWithProps'); +module.exports = Affix; +},{"./AffixMixin":9,"./utils/domUtils":65,"./utils/joinClasses":66,"react":258}],9:[function(require,module,exports){ +/* global window, document */ -var createChainedFunction = require('./utils/createChainedFunction'); -var ValidComponentChildren = require('./utils/ValidComponentChildren'); +var React = require('react'); +var domUtils = require('./utils/domUtils'); +var EventListener = require('./utils/EventListener'); -var DropdownMenu = React.createClass({displayName: 'DropdownMenu', +var AffixMixin = { propTypes: { - pullRight: React.PropTypes.bool, - onSelect: React.PropTypes.func + offset: React.PropTypes.number, + offsetTop: React.PropTypes.number, + offsetBottom: React.PropTypes.number }, - render: function () { - var classes = { - 'dropdown-menu': true, - 'dropdown-menu-right': this.props.pullRight - }; - - return ( - React.createElement("ul", React.__spread({}, - this.props, - {className: joinClasses(this.props.className, classSet(classes)), - role: "menu"}), - ValidComponentChildren.map(this.props.children, this.renderMenuItem) - ) - ); - }, - - renderMenuItem: function (child, index) { - return cloneWithProps( - child, - { - // Capture onSelect events - onSelect: createChainedFunction(child.props.onSelect, this.props.onSelect), - - // Force special props to be transferred - key: child.key ? child.key : index, - ref: child.ref - } - ); - } -}); - -module.exports = DropdownMenu; -},{"./utils/ValidComponentChildren":56,"./utils/classSet":57,"./utils/cloneWithProps":58,"./utils/createChainedFunction":59,"./utils/joinClasses":61,"react":253}],17:[function(require,module,exports){ -var React = require('react'); -var EventListener = require('./utils/EventListener'); - -/** - * Checks whether a node is within - * a root nodes tree - * - * @param {DOMElement} node - * @param {DOMElement} root - * @returns {boolean} - */ -function isNodeInRoot(node, root) { - while (node) { - if (node === root) { - return true; - } - node = node.parentNode; - } - - return false; -} - -var DropdownStateMixin = { getInitialState: function () { return { - open: false + affixClass: 'affix-top' }; }, - setDropdownState: function (newState, onStateChangeComplete) { - if (newState) { - this.bindRootCloseHandlers(); - } else { - this.unbindRootCloseHandlers(); - } - - this.setState({ - open: newState - }, onStateChangeComplete); - }, - - handleDocumentKeyUp: function (e) { - if (e.keyCode === 27) { - this.setDropdownState(false); + getPinnedOffset: function (DOMNode) { + if (this.pinnedOffset) { + return this.pinnedOffset; } - }, - handleDocumentClick: function (e) { - // If the click originated from within this component - // don't do anything. - if (isNodeInRoot(e.target, this.getDOMNode())) { - return; - } + DOMNode.className = DOMNode.className.replace(/affix-top|affix-bottom|affix/, ''); + DOMNode.className += DOMNode.className.length ? ' affix' : 'affix'; - this.setDropdownState(false); - }, + this.pinnedOffset = domUtils.getOffset(DOMNode).top - window.pageYOffset; - bindRootCloseHandlers: function () { - this._onDocumentClickListener = - EventListener.listen(document, 'click', this.handleDocumentClick); - this._onDocumentKeyupListener = - EventListener.listen(document, 'keyup', this.handleDocumentKeyUp); + return this.pinnedOffset; }, - unbindRootCloseHandlers: function () { - if (this._onDocumentClickListener) { - this._onDocumentClickListener.remove(); - } + checkPosition: function () { + var DOMNode, scrollHeight, scrollTop, position, offsetTop, offsetBottom, + affix, affixType, affixPositionTop; - if (this._onDocumentKeyupListener) { - this._onDocumentKeyupListener.remove(); + // TODO: or not visible + if (!this.isMounted()) { + return; } - }, - componentWillUnmount: function () { - this.unbindRootCloseHandlers(); - } -}; + DOMNode = this.getDOMNode(); + scrollHeight = document.documentElement.offsetHeight; + scrollTop = window.pageYOffset; + position = domUtils.getOffset(DOMNode); + offsetTop; + offsetBottom; -module.exports = DropdownStateMixin; -},{"./utils/EventListener":53,"react":253}],18:[function(require,module,exports){ -/*global document */ -// TODO: listen for onTransitionEnd to remove el -function getElementsAndSelf (root, classes){ - var els = root.querySelectorAll('.' + classes.join('.')); + if (this.affixed === 'top') { + position.top += scrollTop; + } - els = [].map.call(els, function(e){ return e; }); + offsetTop = this.props.offsetTop != null ? + this.props.offsetTop : this.props.offset; + offsetBottom = this.props.offsetBottom != null ? + this.props.offsetBottom : this.props.offset; - for(var i = 0; i < classes.length; i++){ - if( !root.className.match(new RegExp('\\b' + classes[i] + '\\b'))){ - return els; + if (offsetTop == null && offsetBottom == null) { + return; + } + if (offsetTop == null) { + offsetTop = 0; + } + if (offsetBottom == null) { + offsetBottom = 0; } - } - els.unshift(root); - return els; -} -module.exports = { - _fadeIn: function () { - var els; + if (this.unpin != null && (scrollTop + this.unpin <= position.top)) { + affix = false; + } else if (offsetBottom != null && (position.top + DOMNode.offsetHeight >= scrollHeight - offsetBottom)) { + affix = 'bottom'; + } else if (offsetTop != null && (scrollTop <= offsetTop)) { + affix = 'top'; + } else { + affix = false; + } - if (this.isMounted()) { - els = getElementsAndSelf(this.getDOMNode(), ['fade']); + if (this.affixed === affix) { + return; + } - if (els.length) { - els.forEach(function (el) { - el.className += ' in'; - }); - } + if (this.unpin != null) { + DOMNode.style.top = ''; } - }, - _fadeOut: function () { - var els = getElementsAndSelf(this._fadeOutEl, ['fade', 'in']); + affixType = 'affix' + (affix ? '-' + affix : ''); - if (els.length) { - els.forEach(function (el) { - el.className = el.className.replace(/\bin\b/, ''); - }); + this.affixed = affix; + this.unpin = affix === 'bottom' ? + this.getPinnedOffset(DOMNode) : null; + + if (affix === 'bottom') { + DOMNode.className = DOMNode.className.replace(/affix-top|affix-bottom|affix/, 'affix-bottom'); + affixPositionTop = scrollHeight - offsetBottom - DOMNode.offsetHeight - domUtils.getOffset(DOMNode).top; } - setTimeout(this._handleFadeOutEnd, 300); + this.setState({ + affixClass: affixType, + affixPositionTop: affixPositionTop + }); }, - _handleFadeOutEnd: function () { - if (this._fadeOutEl && this._fadeOutEl.parentNode) { - this._fadeOutEl.parentNode.removeChild(this._fadeOutEl); - } + checkPositionWithEventLoop: function () { + setTimeout(this.checkPosition, 0); }, componentDidMount: function () { - if (document.querySelectorAll) { - // Firefox needs delay for transition to be triggered - setTimeout(this._fadeIn, 20); - } + this._onWindowScrollListener = + EventListener.listen(window, 'scroll', this.checkPosition); + this._onDocumentClickListener = + EventListener.listen(document, 'click', this.checkPositionWithEventLoop); }, componentWillUnmount: function () { - var els = getElementsAndSelf(this.getDOMNode(), ['fade']), - container = (this.props.container && this.props.container.getDOMNode()) || document.body; + if (this._onWindowScrollListener) { + this._onWindowScrollListener.remove(); + } - if (els.length) { - this._fadeOutEl = document.createElement('div'); - container.appendChild(this._fadeOutEl); - this._fadeOutEl.appendChild(this.getDOMNode().cloneNode(true)); - // Firefox needs delay for transition to be triggered - setTimeout(this._fadeOut, 20); + if (this._onDocumentClickListener) { + this._onDocumentClickListener.remove(); + } + }, + + componentDidUpdate: function (prevProps, prevState) { + if (prevState.affixClass === this.state.affixClass) { + this.checkPositionWithEventLoop(); } } }; -},{}],19:[function(require,module,exports){ +module.exports = AffixMixin; +},{"./utils/EventListener":58,"./utils/domUtils":65,"react":258}],10:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); var classSet = require('./utils/classSet'); var BootstrapMixin = require('./BootstrapMixin'); -var constants = require('./constants'); -var Glyphicon = React.createClass({displayName: 'Glyphicon', + +var Alert = React.createClass({displayName: 'Alert', mixins: [BootstrapMixin], propTypes: { - glyph: React.PropTypes.oneOf(constants.GLYPHS).isRequired + onDismiss: React.PropTypes.func, + dismissAfter: React.PropTypes.number }, getDefaultProps: function () { return { - bsClass: 'glyphicon' + bsClass: 'alert', + bsStyle: 'info' }; }, + renderDismissButton: function () { + return ( + React.createElement("button", { + type: "button", + className: "close", + onClick: this.props.onDismiss, + 'aria-hidden': "true"}, + "×" + ) + ); + }, + render: function () { var classes = this.getBsClassSet(); + var isDismissable = !!this.props.onDismiss; - classes['glyphicon-' + this.props.glyph] = true; + classes['alert-dismissable'] = isDismissable; return ( - React.createElement("span", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + isDismissable ? this.renderDismissButton() : null, this.props.children ) ); + }, + + componentDidMount: function() { + if (this.props.dismissAfter && this.props.onDismiss) { + this.dismissTimer = setTimeout(this.props.onDismiss, this.props.dismissAfter); + } + }, + + componentWillUnmount: function() { + clearTimeout(this.dismissTimer); } }); -module.exports = Glyphicon; -},{"./BootstrapMixin":7,"./constants":50,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],20:[function(require,module,exports){ +module.exports = Alert; +},{"./BootstrapMixin":12,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],11:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); +var ValidComponentChildren = require('./utils/ValidComponentChildren'); +var classSet = require('./utils/classSet'); -var Grid = React.createClass({displayName: 'Grid', +var Badge = React.createClass({displayName: 'Badge', propTypes: { - fluid: React.PropTypes.bool, - componentClass: React.PropTypes.node.isRequired - }, - - getDefaultProps: function () { - return { - componentClass: 'div' - }; + pullRight: React.PropTypes.bool }, render: function () { - var ComponentClass = this.props.componentClass; - var className = this.props.fluid ? 'container-fluid' : 'container'; - + var classes = { + 'pull-right': this.props.pullRight, + 'badge': (ValidComponentChildren.hasValidComponent(this.props.children) + || (typeof this.props.children === 'string')) + }; return ( - React.createElement(ComponentClass, React.__spread({}, + React.createElement("span", React.__spread({}, this.props, - {className: joinClasses(this.props.className, className)}), + {className: joinClasses(this.props.className, classSet(classes))}), this.props.children ) ); } }); -module.exports = Grid; -},{"./utils/joinClasses":61,"react":253}],21:[function(require,module,exports){ +module.exports = Badge; + +},{"./utils/ValidComponentChildren":61,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],12:[function(require,module,exports){ var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var Button = require('./Button'); +var constants = require('./constants'); -var Input = React.createClass({displayName: 'Input', +var BootstrapMixin = { propTypes: { - type: React.PropTypes.string, - label: React.PropTypes.node, - help: React.PropTypes.node, - addonBefore: React.PropTypes.node, - addonAfter: React.PropTypes.node, - buttonBefore: React.PropTypes.node, - buttonAfter: React.PropTypes.node, - bsStyle: function(props) { - if (props.type === 'submit') { - // Return early if `type=submit` as the `Button` component - // it transfers these props to has its own propType checks. - return; - } - - return React.PropTypes.oneOf(['success', 'warning', 'error']).apply(null, arguments); - }, - hasFeedback: React.PropTypes.bool, - groupClassName: React.PropTypes.string, - wrapperClassName: React.PropTypes.string, - labelClassName: React.PropTypes.string, - disabled: React.PropTypes.bool + bsClass: React.PropTypes.oneOf(Object.keys(constants.CLASSES)), + bsStyle: React.PropTypes.oneOf(Object.keys(constants.STYLES)), + bsSize: React.PropTypes.oneOf(Object.keys(constants.SIZES)) }, - getInputDOMNode: function () { - return this.refs.input.getDOMNode(); - }, + getBsClassSet: function () { + var classes = {}; - getValue: function () { - if (this.props.type === 'static') { - return this.props.value; - } - else if (this.props.type) { - return this.getInputDOMNode().value; - } - else { - throw Error('Cannot use getValue without specifying input type.'); - } - }, + var bsClass = this.props.bsClass && constants.CLASSES[this.props.bsClass]; + if (bsClass) { + classes[bsClass] = true; - getChecked: function () { - return this.getInputDOMNode().checked; - }, + var prefix = bsClass + '-'; - isCheckboxOrRadio: function () { - return this.props.type === 'radio' || this.props.type === 'checkbox'; - }, + var bsSize = this.props.bsSize && constants.SIZES[this.props.bsSize]; + if (bsSize) { + classes[prefix + bsSize] = true; + } - isFile: function () { - return this.props.type === 'file'; - }, + var bsStyle = this.props.bsStyle && constants.STYLES[this.props.bsStyle]; + if (this.props.bsStyle) { + classes[prefix + bsStyle] = true; + } + } - renderInput: function () { - var input = null; + return classes; + } +}; - if (!this.props.type) { - return this.props.children - } +module.exports = BootstrapMixin; +},{"./constants":55,"react":258}],13:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var BootstrapMixin = require('./BootstrapMixin'); - switch (this.props.type) { - case 'select': - input = ( - React.createElement("select", React.__spread({}, this.props, {className: joinClasses(this.props.className, 'form-control'), ref: "input", key: "input"}), - this.props.children - ) - ); - break; - case 'textarea': - input = React.createElement("textarea", React.__spread({}, this.props, {className: joinClasses(this.props.className, 'form-control'), ref: "input", key: "input"})); - break; - case 'static': - input = ( - React.createElement("p", React.__spread({}, this.props, {className: joinClasses(this.props.className, 'form-control-static'), ref: "input", key: "input"}), - this.props.value - ) - ); - break; - case 'submit': - input = ( - React.createElement(Button, React.__spread({}, this.props, {componentClass: "input", ref: "input", key: "input"})) - ); - break; - default: - var className = this.isCheckboxOrRadio() || this.isFile() ? '' : 'form-control'; - input = React.createElement("input", React.__spread({}, this.props, {className: joinClasses(this.props.className, className), ref: "input", key: "input"})); - } +var Button = React.createClass({displayName: 'Button', + mixins: [BootstrapMixin], - return input; + propTypes: { + active: React.PropTypes.bool, + disabled: React.PropTypes.bool, + block: React.PropTypes.bool, + navItem: React.PropTypes.bool, + navDropdown: React.PropTypes.bool, + componentClass: React.PropTypes.node }, - renderInputGroup: function (children) { - var addonBefore = this.props.addonBefore ? ( - React.createElement("span", {className: "input-group-addon", key: "addonBefore"}, - this.props.addonBefore - ) - ) : null; - - var addonAfter = this.props.addonAfter ? ( - React.createElement("span", {className: "input-group-addon", key: "addonAfter"}, - this.props.addonAfter - ) - ) : null; + getDefaultProps: function () { + return { + bsClass: 'button', + bsStyle: 'default', + type: 'button' + }; + }, - var buttonBefore = this.props.buttonBefore ? ( - React.createElement("span", {className: "input-group-btn"}, - this.props.buttonBefore - ) - ) : null; + render: function () { + var classes = this.props.navDropdown ? {} : this.getBsClassSet(); + var renderFuncName; - var buttonAfter = this.props.buttonAfter ? ( - React.createElement("span", {className: "input-group-btn"}, - this.props.buttonAfter - ) - ) : null; + classes['active'] = this.props.active; + classes['btn-block'] = this.props.block; - return addonBefore || addonAfter || buttonBefore || buttonAfter ? ( - React.createElement("div", {className: "input-group", key: "input-group"}, - addonBefore, - buttonBefore, - children, - addonAfter, - buttonAfter - ) - ) : children; - }, + if (this.props.navItem) { + return this.renderNavItem(classes); + } - renderIcon: function () { - var classes = { - 'glyphicon': true, - 'form-control-feedback': true, - 'glyphicon-ok': this.props.bsStyle === 'success', - 'glyphicon-warning-sign': this.props.bsStyle === 'warning', - 'glyphicon-remove': this.props.bsStyle === 'error' - }; + renderFuncName = this.props.href || this.props.navDropdown ? + 'renderAnchor' : 'renderButton'; - return this.props.hasFeedback ? ( - React.createElement("span", {className: classSet(classes), key: "icon"}) - ) : null; + return this[renderFuncName](classes); }, - renderHelp: function () { - return this.props.help ? ( - React.createElement("span", {className: "help-block", key: "help"}, - this.props.help - ) - ) : null; - }, + renderAnchor: function (classes) { - renderCheckboxandRadioWrapper: function (children) { - var classes = { - 'checkbox': this.props.type === 'checkbox', - 'radio': this.props.type === 'radio' - }; + var Component = this.props.componentClass || 'a'; + var href = this.props.href || '#'; + classes['disabled'] = this.props.disabled; return ( - React.createElement("div", {className: classSet(classes), key: "checkboxRadioWrapper"}, - children + React.createElement(Component, React.__spread({}, + this.props, + {href: href, + className: joinClasses(this.props.className, classSet(classes)), + role: "button"}), + this.props.children ) ); }, - renderWrapper: function (children) { - return this.props.wrapperClassName ? ( - React.createElement("div", {className: this.props.wrapperClassName, key: "wrapper"}, - children + renderButton: function (classes) { + var Component = this.props.componentClass || 'button'; + + return ( + React.createElement(Component, React.__spread({}, + this.props, + {className: joinClasses(this.props.className, classSet(classes))}), + this.props.children ) - ) : children; + ); }, - renderLabel: function (children) { - var classes = { - 'control-label': !this.isCheckboxOrRadio() + renderNavItem: function (classes) { + var liClasses = { + active: this.props.active }; - classes[this.props.labelClassName] = this.props.labelClassName; - return this.props.label ? ( - React.createElement("label", {htmlFor: this.props.id, className: classSet(classes), key: "label"}, - children, - this.props.label - ) - ) : children; - }, - - renderFormGroup: function (children) { - var classes = { - 'form-group': true, - 'has-feedback': this.props.hasFeedback, - 'has-success': this.props.bsStyle === 'success', - 'has-warning': this.props.bsStyle === 'warning', - 'has-error': this.props.bsStyle === 'error' - }; - classes[this.props.groupClassName] = this.props.groupClassName; - - return ( - React.createElement("div", {className: classSet(classes)}, - children + return ( + React.createElement("li", {className: classSet(liClasses)}, + this.renderAnchor(classes) ) ); - }, - - render: function () { - if (this.isCheckboxOrRadio()) { - return this.renderFormGroup( - this.renderWrapper([ - this.renderCheckboxandRadioWrapper( - this.renderLabel( - this.renderInput() - ) - ), - this.renderHelp() - ]) - ); - } - else { - return this.renderFormGroup([ - this.renderLabel(), - this.renderWrapper([ - this.renderInputGroup( - this.renderInput() - ), - this.renderIcon(), - this.renderHelp() - ]) - ]); - } } }); -module.exports = Input; - -},{"./Button":8,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],22:[function(require,module,exports){ -// https://www.npmjs.org/package/react-interpolate-component -'use strict'; +module.exports = Button; +},{"./BootstrapMixin":12,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],14:[function(require,module,exports){ var React = require('react'); -var ValidComponentChildren = require('./utils/ValidComponentChildren'); -var assign = require('./utils/Object.assign'); - -var REGEXP = /\%\((.+?)\)s/; +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var BootstrapMixin = require('./BootstrapMixin'); +var Button = require('./Button'); -var Interpolate = React.createClass({ - displayName: 'Interpolate', +var ButtonGroup = React.createClass({displayName: 'ButtonGroup', + mixins: [BootstrapMixin], propTypes: { - format: React.PropTypes.string + vertical: React.PropTypes.bool, + justified: React.PropTypes.bool }, - getDefaultProps: function() { - return { component: 'span' }; + getDefaultProps: function () { + return { + bsClass: 'button-group' + }; }, - render: function() { - var format = (ValidComponentChildren.hasValidComponent(this.props.children) || - (typeof this.props.children === 'string')) ? - this.props.children : this.props.format; - var parent = this.props.component; - var unsafe = this.props.unsafe === true; - var props = assign({}, this.props); - - delete props.children; - delete props.format; - delete props.component; - delete props.unsafe; - - if (unsafe) { - var content = format.split(REGEXP).reduce(function(memo, match, index) { - var html; - - if (index % 2 === 0) { - html = match; - } else { - html = props[match]; - delete props[match]; - } - - if (React.isValidElement(html)) { - throw new Error('cannot interpolate a React component into unsafe text'); - } - - memo += html; - - return memo; - }, ''); - - props.dangerouslySetInnerHTML = { __html: content }; - - return React.createElement(parent, props); - } else { - var kids = format.split(REGEXP).reduce(function(memo, match, index) { - var child; - - if (index % 2 === 0) { - if (match.length === 0) { - return memo; - } - - child = match; - } else { - child = props[match]; - delete props[match]; - } - - memo.push(child); - - return memo; - }, []); - - return React.createElement(parent, props, kids); - } - } -}); - -module.exports = Interpolate; - -},{"./utils/Object.assign":54,"./utils/ValidComponentChildren":56,"react":253}],23:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); - -var Jumbotron = React.createClass({displayName: 'Jumbotron', - render: function () { + var classes = this.getBsClassSet(); + classes['btn-group'] = !this.props.vertical; + classes['btn-group-vertical'] = this.props.vertical; + classes['btn-group-justified'] = this.props.justified; + return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, 'jumbotron')}), + React.createElement("div", React.__spread({}, + this.props, + {className: joinClasses(this.props.className, classSet(classes))}), this.props.children ) ); } }); -module.exports = Jumbotron; -},{"./utils/joinClasses":61,"react":253}],24:[function(require,module,exports){ +module.exports = ButtonGroup; +},{"./BootstrapMixin":12,"./Button":13,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],15:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); var classSet = require('./utils/classSet'); var BootstrapMixin = require('./BootstrapMixin'); +var Button = require('./Button'); -var Label = React.createClass({displayName: 'Label', +var ButtonToolbar = React.createClass({displayName: 'ButtonToolbar', mixins: [BootstrapMixin], getDefaultProps: function () { return { - bsClass: 'label', - bsStyle: 'default' + bsClass: 'button-toolbar' }; }, @@ -1863,10743 +1910,8357 @@ var Label = React.createClass({displayName: 'Label', var classes = this.getBsClassSet(); return ( - React.createElement("span", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + React.createElement("div", React.__spread({}, + this.props, + {role: "toolbar", + className: joinClasses(this.props.className, classSet(classes))}), this.props.children ) ); } }); -module.exports = Label; -},{"./BootstrapMixin":7,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],25:[function(require,module,exports){ -var React = require('react'); -var classSet = require('./utils/classSet'); -var cloneWithProps = require('./utils/cloneWithProps'); - -var ValidComponentChildren = require('./utils/ValidComponentChildren'); -var createChainedFunction = require('./utils/createChainedFunction'); - -var ListGroup = React.createClass({displayName: 'ListGroup', - propTypes: { - onClick: React.PropTypes.func - }, - - render: function () { - return ( - React.createElement("div", {className: "list-group"}, - ValidComponentChildren.map(this.props.children, this.renderListItem) - ) - ); - }, - - renderListItem: function (child, index) { - return cloneWithProps(child, { - onClick: createChainedFunction(child.props.onClick, this.props.onClick), - ref: child.ref, - key: child.key ? child.key : index - }); - } -}); - -module.exports = ListGroup; - -},{"./utils/ValidComponentChildren":56,"./utils/classSet":57,"./utils/cloneWithProps":58,"./utils/createChainedFunction":59,"react":253}],26:[function(require,module,exports){ +module.exports = ButtonToolbar; +},{"./BootstrapMixin":12,"./Button":13,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],16:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); -var BootstrapMixin = require('./BootstrapMixin'); var classSet = require('./utils/classSet'); var cloneWithProps = require('./utils/cloneWithProps'); - +var BootstrapMixin = require('./BootstrapMixin'); var ValidComponentChildren = require('./utils/ValidComponentChildren'); -var ListGroupItem = React.createClass({displayName: 'ListGroupItem', +var Carousel = React.createClass({displayName: 'Carousel', mixins: [BootstrapMixin], propTypes: { - bsStyle: React.PropTypes.oneOf(['danger','info','success','warning']), - active: React.PropTypes.any, - disabled: React.PropTypes.any, - header: React.PropTypes.node, - onClick: React.PropTypes.func, - eventKey: React.PropTypes.any + slide: React.PropTypes.bool, + indicators: React.PropTypes.bool, + controls: React.PropTypes.bool, + pauseOnHover: React.PropTypes.bool, + wrap: React.PropTypes.bool, + onSelect: React.PropTypes.func, + onSlideEnd: React.PropTypes.func, + activeIndex: React.PropTypes.number, + defaultActiveIndex: React.PropTypes.number, + direction: React.PropTypes.oneOf(['prev', 'next']) }, getDefaultProps: function () { return { - bsClass: 'list-group-item' + slide: true, + interval: 5000, + pauseOnHover: true, + wrap: true, + indicators: true, + controls: true }; }, - render: function () { - var classes = this.getBsClassSet(); - - classes['active'] = this.props.active; - classes['disabled'] = this.props.disabled; + getInitialState: function () { + return { + activeIndex: this.props.defaultActiveIndex == null ? + 0 : this.props.defaultActiveIndex, + previousActiveIndex: null, + direction: null + }; + }, - if (this.props.href || this.props.onClick) { - return this.renderAnchor(classes); - } else { - return this.renderSpan(classes); + getDirection: function (prevIndex, index) { + if (prevIndex === index) { + return null; } - }, - renderSpan: function (classes) { - return ( - React.createElement("span", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), - this.props.header ? this.renderStructuredContent() : this.props.children - ) - ); + return prevIndex > index ? + 'prev' : 'next'; }, - renderAnchor: function (classes) { - return ( - React.createElement("a", React.__spread({}, - this.props, - {className: joinClasses(this.props.className, classSet(classes)), - onClick: this.handleClick}), - this.props.header ? this.renderStructuredContent() : this.props.children - ) - ); - }, + componentWillReceiveProps: function (nextProps) { + var activeIndex = this.getActiveIndex(); - renderStructuredContent: function () { - var header; - if (React.isValidElement(this.props.header)) { - header = cloneWithProps(this.props.header, { - className: 'list-group-item-heading' + if (nextProps.activeIndex != null && nextProps.activeIndex !== activeIndex) { + clearTimeout(this.timeout); + this.setState({ + previousActiveIndex: activeIndex, + direction: nextProps.direction != null ? + nextProps.direction : this.getDirection(activeIndex, nextProps.activeIndex) }); - } else { - header = ( - React.createElement("h4", {className: "list-group-item-heading"}, - this.props.header - ) - ); } + }, - var content = ( - React.createElement("p", {className: "list-group-item-text"}, - this.props.children - ) - ); + componentDidMount: function () { + this.waitForNext(); + }, - return { - header: header, - content: content - }; + componentWillUnmount: function() { + clearTimeout(this.timeout); }, - handleClick: function (e) { - if (this.props.onClick) { + next: function (e) { + if (e) { e.preventDefault(); - this.props.onClick(this.props.eventKey, this.props.href); } - } -}); - -module.exports = ListGroupItem; -},{"./BootstrapMixin":7,"./utils/ValidComponentChildren":56,"./utils/classSet":57,"./utils/cloneWithProps":58,"./utils/joinClasses":61,"react":253}],27:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); + var index = this.getActiveIndex() + 1; + var count = ValidComponentChildren.numberOf(this.props.children); -var MenuItem = React.createClass({displayName: 'MenuItem', - propTypes: { - header: React.PropTypes.bool, - divider: React.PropTypes.bool, - href: React.PropTypes.string, - title: React.PropTypes.string, - onSelect: React.PropTypes.func, - eventKey: React.PropTypes.any - }, + if (index > count - 1) { + if (!this.props.wrap) { + return; + } + index = 0; + } - getDefaultProps: function () { - return { - href: '#' - }; + this.handleSelect(index, 'next'); }, - handleClick: function (e) { - if (this.props.onSelect) { + prev: function (e) { + if (e) { e.preventDefault(); - this.props.onSelect(this.props.eventKey); } - }, - - renderAnchor: function () { - return ( - React.createElement("a", {onClick: this.handleClick, href: this.props.href, title: this.props.title, tabIndex: "-1"}, - this.props.children - ) - ); - }, - render: function () { - var classes = { - 'dropdown-header': this.props.header, - 'divider': this.props.divider - }; + var index = this.getActiveIndex() - 1; - var children = null; - if (this.props.header) { - children = this.props.children; - } else if (!this.props.divider) { - children = this.renderAnchor(); + if (index < 0) { + if (!this.props.wrap) { + return; + } + index = ValidComponentChildren.numberOf(this.props.children) - 1; } - return ( - React.createElement("li", React.__spread({}, this.props, {role: "presentation", title: null, href: null, - className: joinClasses(this.props.className, classSet(classes))}), - children - ) - ); - } -}); - -module.exports = MenuItem; -},{"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],28:[function(require,module,exports){ -/* global document:false */ - -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var BootstrapMixin = require('./BootstrapMixin'); -var FadeMixin = require('./FadeMixin'); -var EventListener = require('./utils/EventListener'); + this.handleSelect(index, 'prev'); + }, + pause: function () { + this.isPaused = true; + clearTimeout(this.timeout); + }, -// TODO: -// - aria-labelledby -// - Add `modal-body` div if only one child passed in that doesn't already have it -// - Tests + play: function () { + this.isPaused = false; + this.waitForNext(); + }, -var Modal = React.createClass({displayName: 'Modal', - mixins: [BootstrapMixin, FadeMixin], + waitForNext: function () { + if (!this.isPaused && this.props.slide && this.props.interval && + this.props.activeIndex == null) { + this.timeout = setTimeout(this.next, this.props.interval); + } + }, - propTypes: { - title: React.PropTypes.node, - backdrop: React.PropTypes.oneOf(['static', true, false]), - keyboard: React.PropTypes.bool, - closeButton: React.PropTypes.bool, - animation: React.PropTypes.bool, - onRequestHide: React.PropTypes.func.isRequired + handleMouseOver: function () { + if (this.props.pauseOnHover) { + this.pause(); + } }, - getDefaultProps: function () { - return { - bsClass: 'modal', - backdrop: true, - keyboard: true, - animation: true, - closeButton: true - }; + handleMouseOut: function () { + if (this.isPaused) { + this.play(); + } }, render: function () { - var modalStyle = {display: 'block'}; - var dialogClasses = this.getBsClassSet(); - delete dialogClasses.modal; - dialogClasses['modal-dialog'] = true; - var classes = { - modal: true, - fade: this.props.animation, - 'in': !this.props.animation || !document.querySelectorAll + carousel: true, + slide: this.props.slide }; - var modal = ( + return ( React.createElement("div", React.__spread({}, this.props, - {title: null, - tabIndex: "-1", - role: "dialog", - style: modalStyle, - className: joinClasses(this.props.className, classSet(classes)), - onClick: this.props.backdrop === true ? this.handleBackdropClick : null, - ref: "modal"}), - React.createElement("div", {className: classSet(dialogClasses)}, - React.createElement("div", {className: "modal-content"}, - this.props.title ? this.renderHeader() : null, - this.props.children - ) - ) + {className: joinClasses(this.props.className, classSet(classes)), + onMouseOver: this.handleMouseOver, + onMouseOut: this.handleMouseOut}), + this.props.indicators ? this.renderIndicators() : null, + React.createElement("div", {className: "carousel-inner", ref: "inner"}, + ValidComponentChildren.map(this.props.children, this.renderItem) + ), + this.props.controls ? this.renderControls() : null ) ); - - return this.props.backdrop ? - this.renderBackdrop(modal) : modal; }, - renderBackdrop: function (modal) { - var classes = { - 'modal-backdrop': true, - 'fade': this.props.animation - }; - - classes['in'] = !this.props.animation || !document.querySelectorAll; - - var onClick = this.props.backdrop === true ? - this.handleBackdropClick : null; - + renderPrev: function () { return ( - React.createElement("div", null, - React.createElement("div", {className: classSet(classes), ref: "backdrop", onClick: onClick}), - modal + React.createElement("a", {className: "left carousel-control", href: "#prev", key: 0, onClick: this.prev}, + React.createElement("span", {className: "glyphicon glyphicon-chevron-left"}) ) ); }, - renderHeader: function () { - var closeButton; - if (this.props.closeButton) { - closeButton = ( - React.createElement("button", {type: "button", className: "close", 'aria-hidden': "true", onClick: this.props.onRequestHide}, "×") - ); - } - + renderNext: function () { return ( - React.createElement("div", {className: "modal-header"}, - closeButton, - this.renderTitle() + React.createElement("a", {className: "right carousel-control", href: "#next", key: 1, onClick: this.next}, + React.createElement("span", {className: "glyphicon glyphicon-chevron-right"}) ) ); }, - renderTitle: function () { - return ( - React.isValidElement(this.props.title) ? - this.props.title : React.createElement("h4", {className: "modal-title"}, this.props.title) - ); - }, + renderControls: function () { + if (this.props.wrap) { + var activeIndex = this.getActiveIndex(); + var count = ValidComponentChildren.numberOf(this.props.children); - iosClickHack: function () { - // IOS only allows click events to be delegated to the document on elements - // it considers 'clickable' - anchors, buttons, etc. We fake a click handler on the - // DOM nodes themselves. Remove if handled by React: https://github.com/facebook/react/issues/1169 - this.refs.modal.getDOMNode().onclick = function () {}; - this.refs.backdrop.getDOMNode().onclick = function () {}; - }, + return [ + (activeIndex !== 0) ? this.renderPrev() : null, + (activeIndex !== count - 1) ? this.renderNext() : null + ]; + } - componentDidMount: function () { - this._onDocumentKeyupListener = - EventListener.listen(document, 'keyup', this.handleDocumentKeyUp); - - if (this.props.backdrop) { - this.iosClickHack(); - } - }, - - componentDidUpdate: function (prevProps) { - if (this.props.backdrop && this.props.backdrop !== prevProps.backdrop) { - this.iosClickHack(); - } - }, - - componentWillUnmount: function () { - this._onDocumentKeyupListener.remove(); + return [ + this.renderPrev(), + this.renderNext() + ]; }, - handleBackdropClick: function (e) { - if (e.target !== e.currentTarget) { - return; - } + renderIndicator: function (child, index) { + var className = (index === this.getActiveIndex()) ? + 'active' : null; - this.props.onRequestHide(); + return ( + React.createElement("li", { + key: index, + className: className, + onClick: this.handleSelect.bind(this, index, null)}) + ); }, - handleDocumentKeyUp: function (e) { - if (this.props.keyboard && e.keyCode === 27) { - this.props.onRequestHide(); - } - } -}); - -module.exports = Modal; - -},{"./BootstrapMixin":7,"./FadeMixin":18,"./utils/EventListener":53,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],29:[function(require,module,exports){ -var React = require('react'); -var OverlayMixin = require('./OverlayMixin'); -var cloneWithProps = require('./utils/cloneWithProps'); - -var createChainedFunction = require('./utils/createChainedFunction'); + renderIndicators: function () { + var indicators = []; + ValidComponentChildren + .forEach(this.props.children, function(child, index) { + indicators.push( + this.renderIndicator(child, index), -var ModalTrigger = React.createClass({displayName: 'ModalTrigger', - mixins: [OverlayMixin], + // Force whitespace between indicator elements, bootstrap + // requires this for correct spacing of elements. + ' ' + ); + }, this); - propTypes: { - modal: React.PropTypes.node.isRequired + return ( + React.createElement("ol", {className: "carousel-indicators"}, + indicators + ) + ); }, - getInitialState: function () { - return { - isOverlayShown: false - }; + getActiveIndex: function () { + return this.props.activeIndex != null ? this.props.activeIndex : this.state.activeIndex; }, - show: function () { + handleItemAnimateOutEnd: function () { this.setState({ - isOverlayShown: true - }); - }, + previousActiveIndex: null, + direction: null + }, function() { + this.waitForNext(); - hide: function () { - this.setState({ - isOverlayShown: false + if (this.props.onSlideEnd) { + this.props.onSlideEnd(); + } }); }, - toggle: function () { - this.setState({ - isOverlayShown: !this.state.isOverlayShown - }); + renderItem: function (child, index) { + var activeIndex = this.getActiveIndex(); + var isActive = (index === activeIndex); + var isPreviousActive = this.state.previousActiveIndex != null && + this.state.previousActiveIndex === index && this.props.slide; + + return cloneWithProps( + child, + { + active: isActive, + ref: child.ref, + key: child.key ? child.key : index, + index: index, + animateOut: isPreviousActive, + animateIn: isActive && this.state.previousActiveIndex != null && this.props.slide, + direction: this.state.direction, + onAnimateOutEnd: isPreviousActive ? this.handleItemAnimateOutEnd: null + } + ); }, - renderOverlay: function () { - if (!this.state.isOverlayShown) { - return React.createElement("span", null); + handleSelect: function (index, direction) { + clearTimeout(this.timeout); + + var previousActiveIndex = this.getActiveIndex(); + direction = direction || this.getDirection(previousActiveIndex, index); + + if (this.props.onSelect) { + this.props.onSelect(index, direction); } - return cloneWithProps( - this.props.modal, - { - onRequestHide: this.hide + if (this.props.activeIndex == null && index !== previousActiveIndex) { + if (this.state.previousActiveIndex != null) { + // If currently animating don't activate the new index. + // TODO: look into queuing this canceled call and + // animating after the current animation has ended. + return; } - ); - }, - render: function () { - var child = React.Children.only(this.props.children); - return cloneWithProps( - child, - { - onClick: createChainedFunction(child.props.onClick, this.toggle) - } - ); + this.setState({ + activeIndex: index, + previousActiveIndex: previousActiveIndex, + direction: direction + }); + } } }); -module.exports = ModalTrigger; -},{"./OverlayMixin":33,"./utils/cloneWithProps":58,"./utils/createChainedFunction":59,"react":253}],30:[function(require,module,exports){ +module.exports = Carousel; +},{"./BootstrapMixin":12,"./utils/ValidComponentChildren":61,"./utils/classSet":62,"./utils/cloneWithProps":63,"./utils/joinClasses":66,"react":258}],17:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); -var BootstrapMixin = require('./BootstrapMixin'); -var CollapsableMixin = require('./CollapsableMixin'); var classSet = require('./utils/classSet'); -var domUtils = require('./utils/domUtils'); -var cloneWithProps = require('./utils/cloneWithProps'); - -var ValidComponentChildren = require('./utils/ValidComponentChildren'); -var createChainedFunction = require('./utils/createChainedFunction'); - - -var Nav = React.createClass({displayName: 'Nav', - mixins: [BootstrapMixin, CollapsableMixin], +var TransitionEvents = require('./utils/TransitionEvents'); +var CarouselItem = React.createClass({displayName: 'CarouselItem', propTypes: { - bsStyle: React.PropTypes.oneOf(['tabs','pills']), - stacked: React.PropTypes.bool, - justified: React.PropTypes.bool, - onSelect: React.PropTypes.func, - collapsable: React.PropTypes.bool, - expanded: React.PropTypes.bool, - navbar: React.PropTypes.bool, - eventKey: React.PropTypes.any, - right: React.PropTypes.bool + direction: React.PropTypes.oneOf(['prev', 'next']), + onAnimateOutEnd: React.PropTypes.func, + active: React.PropTypes.bool, + caption: React.PropTypes.node }, - getDefaultProps: function () { + getInitialState: function () { return { - bsClass: 'nav' + direction: null }; }, - getCollapsableDOMNode: function () { - return this.getDOMNode(); + getDefaultProps: function () { + return { + animation: true + }; }, - getCollapsableDimensionValue: function () { - var node = this.refs.ul.getDOMNode(), - height = node.offsetHeight, - computedStyles = domUtils.getComputedStyles(node); + handleAnimateOutEnd: function () { + if (this.props.onAnimateOutEnd && this.isMounted()) { + this.props.onAnimateOutEnd(this.props.index); + } + }, - return height + parseInt(computedStyles.marginTop, 10) + parseInt(computedStyles.marginBottom, 10); + componentWillReceiveProps: function (nextProps) { + if (this.props.active !== nextProps.active) { + this.setState({ + direction: null + }); + } }, - render: function () { - var classes = this.props.collapsable ? this.getCollapsableClassSet() : {}; + componentDidUpdate: function (prevProps) { + if (!this.props.active && prevProps.active) { + TransitionEvents.addEndEventListener( + this.getDOMNode(), + this.handleAnimateOutEnd + ); + } - classes['navbar-collapse'] = this.props.collapsable; + if (this.props.active !== prevProps.active) { + setTimeout(this.startAnimation, 20); + } + }, - if (this.props.navbar && !this.props.collapsable) { - return (this.renderUl()); + startAnimation: function () { + if (!this.isMounted()) { + return; } - return ( - React.createElement("nav", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), - this.renderUl() - ) - ); + this.setState({ + direction: this.props.direction === 'prev' ? + 'right' : 'left' + }); }, - renderUl: function () { - var classes = this.getBsClassSet(); + render: function () { + var classes = { + item: true, + active: (this.props.active && !this.props.animateIn) || this.props.animateOut, + next: this.props.active && this.props.animateIn && this.props.direction === 'next', + prev: this.props.active && this.props.animateIn && this.props.direction === 'prev' + }; - classes['nav-stacked'] = this.props.stacked; - classes['nav-justified'] = this.props.justified; - classes['navbar-nav'] = this.props.navbar; - classes['pull-right'] = this.props.pullRight; - classes['navbar-right'] = this.props.right; + if (this.state.direction && (this.props.animateIn || this.props.animateOut)) { + classes[this.state.direction] = true; + } return ( - React.createElement("ul", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes)), ref: "ul"}), - ValidComponentChildren.map(this.props.children, this.renderNavItem) + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + this.props.children, + this.props.caption ? this.renderCaption() : null ) ); }, - getChildActiveProp: function (child) { - if (child.props.active) { - return true; - } - if (this.props.activeKey != null) { - if (child.props.eventKey == this.props.activeKey) { - return true; - } - } - if (this.props.activeHref != null) { - if (child.props.href === this.props.activeHref) { - return true; - } - } - - return child.props.active; - }, - - renderNavItem: function (child, index) { - return cloneWithProps( - child, - { - active: this.getChildActiveProp(child), - activeKey: this.props.activeKey, - activeHref: this.props.activeHref, - onSelect: createChainedFunction(child.props.onSelect, this.props.onSelect), - ref: child.ref, - key: child.key ? child.key : index, - navItem: true - } + renderCaption: function () { + return ( + React.createElement("div", {className: "carousel-caption"}, + this.props.caption + ) ); } }); -module.exports = Nav; - -},{"./BootstrapMixin":7,"./CollapsableMixin":14,"./utils/ValidComponentChildren":56,"./utils/classSet":57,"./utils/cloneWithProps":58,"./utils/createChainedFunction":59,"./utils/domUtils":60,"./utils/joinClasses":61,"react":253}],31:[function(require,module,exports){ +module.exports = CarouselItem; +},{"./utils/TransitionEvents":60,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],18:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); var classSet = require('./utils/classSet'); -var BootstrapMixin = require('./BootstrapMixin'); +var constants = require('./constants'); -var NavItem = React.createClass({displayName: 'NavItem', - mixins: [BootstrapMixin], +var Col = React.createClass({displayName: 'Col', propTypes: { - onSelect: React.PropTypes.func, - active: React.PropTypes.bool, - disabled: React.PropTypes.bool, - href: React.PropTypes.string, - title: React.PropTypes.string, - eventKey: React.PropTypes.any + xs: React.PropTypes.number, + sm: React.PropTypes.number, + md: React.PropTypes.number, + lg: React.PropTypes.number, + xsOffset: React.PropTypes.number, + smOffset: React.PropTypes.number, + mdOffset: React.PropTypes.number, + lgOffset: React.PropTypes.number, + xsPush: React.PropTypes.number, + smPush: React.PropTypes.number, + mdPush: React.PropTypes.number, + lgPush: React.PropTypes.number, + xsPull: React.PropTypes.number, + smPull: React.PropTypes.number, + mdPull: React.PropTypes.number, + lgPull: React.PropTypes.number, + componentClass: React.PropTypes.node.isRequired }, getDefaultProps: function () { return { - href: '#' + componentClass: 'div' }; }, render: function () { - var $__0= - - - - - - this.props,disabled=$__0.disabled,active=$__0.active,href=$__0.href,title=$__0.title,children=$__0.children,props=(function(source, exclusion) {var rest = {};var hasOwn = Object.prototype.hasOwnProperty;if (source == null) {throw new TypeError();}for (var key in source) {if (hasOwn.call(source, key) && !hasOwn.call(exclusion, key)) {rest[key] = source[key];}}return rest;})($__0,{disabled:1,active:1,href:1,title:1,children:1}), - classes = { - 'active': active, - 'disabled': disabled - }; + var ComponentClass = this.props.componentClass; + var classes = {}; - return ( - React.createElement("li", React.__spread({}, props, {className: joinClasses(props.className, classSet(classes))}), - React.createElement("a", { - href: href, - title: title, - onClick: this.handleClick, - ref: "anchor"}, - children - ) - ) - ); - }, + Object.keys(constants.SIZES).forEach(function (key) { + var size = constants.SIZES[key]; + var prop = size; + var classPart = size + '-'; - handleClick: function (e) { - if (this.props.onSelect) { - e.preventDefault(); + if (this.props[prop]) { + classes['col-' + classPart + this.props[prop]] = true; + } - if (!this.props.disabled) { - this.props.onSelect(this.props.eventKey, this.props.href); + prop = size + 'Offset'; + classPart = size + '-offset-'; + if (this.props[prop]) { + classes['col-' + classPart + this.props[prop]] = true; } - } + + prop = size + 'Push'; + classPart = size + '-push-'; + if (this.props[prop]) { + classes['col-' + classPart + this.props[prop]] = true; + } + + prop = size + 'Pull'; + classPart = size + '-pull-'; + if (this.props[prop]) { + classes['col-' + classPart + this.props[prop]] = true; + } + }, this); + + return ( + React.createElement(ComponentClass, React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + this.props.children + ) + ); } }); -module.exports = NavItem; -},{"./BootstrapMixin":7,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],32:[function(require,module,exports){ +module.exports = Col; +},{"./constants":55,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],19:[function(require,module,exports){ var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var BootstrapMixin = require('./BootstrapMixin'); -var classSet = require('./utils/classSet'); -var cloneWithProps = require('./utils/cloneWithProps'); - -var ValidComponentChildren = require('./utils/ValidComponentChildren'); -var createChainedFunction = require('./utils/createChainedFunction'); -var Nav = require('./Nav'); - +var TransitionEvents = require('./utils/TransitionEvents'); -var Navbar = React.createClass({displayName: 'Navbar', - mixins: [BootstrapMixin], +var CollapsableMixin = { propTypes: { - fixedTop: React.PropTypes.bool, - fixedBottom: React.PropTypes.bool, - staticTop: React.PropTypes.bool, - inverse: React.PropTypes.bool, - fluid: React.PropTypes.bool, - role: React.PropTypes.string, - componentClass: React.PropTypes.node.isRequired, - brand: React.PropTypes.node, - toggleButton: React.PropTypes.node, - onToggle: React.PropTypes.func, - navExpanded: React.PropTypes.bool, - defaultNavExpanded: React.PropTypes.bool + collapsable: React.PropTypes.bool, + defaultExpanded: React.PropTypes.bool, + expanded: React.PropTypes.bool }, - getDefaultProps: function () { + getInitialState: function () { return { - bsClass: 'navbar', - bsStyle: 'default', - role: 'navigation', - componentClass: 'Nav' + expanded: this.props.defaultExpanded != null ? this.props.defaultExpanded : null, + collapsing: false }; }, - getInitialState: function () { - return { - navExpanded: this.props.defaultNavExpanded - }; + handleTransitionEnd: function () { + this._collapseEnd = true; + this.setState({ + collapsing: false + }); }, - shouldComponentUpdate: function() { - // Defer any updates to this component during the `onSelect` handler. - return !this._isChanging; + componentWillReceiveProps: function (newProps) { + if (this.props.collapsable && newProps.expanded !== this.props.expanded) { + this._collapseEnd = false; + this.setState({ + collapsing: true + }); + } }, - handleToggle: function () { - if (this.props.onToggle) { - this._isChanging = true; - this.props.onToggle(); - this._isChanging = false; + _addEndTransitionListener: function () { + var node = this.getCollapsableDOMNode(); + + if (node) { + TransitionEvents.addEndEventListener( + node, + this.handleTransitionEnd + ); } + }, - this.setState({ - navExpanded: !this.state.navExpanded - }); + _removeEndTransitionListener: function () { + var node = this.getCollapsableDOMNode(); + + if (node) { + TransitionEvents.removeEndEventListener( + node, + this.handleTransitionEnd + ); + } }, - isNavExpanded: function () { - return this.props.navExpanded != null ? this.props.navExpanded : this.state.navExpanded; + componentDidMount: function () { + this._afterRender(); }, - render: function () { - var classes = this.getBsClassSet(); - var ComponentClass = this.props.componentClass; + componentWillUnmount: function () { + this._removeEndTransitionListener(); + }, - classes['navbar-fixed-top'] = this.props.fixedTop; - classes['navbar-fixed-bottom'] = this.props.fixedBottom; - classes['navbar-static-top'] = this.props.staticTop; - classes['navbar-inverse'] = this.props.inverse; + componentWillUpdate: function (nextProps) { + var dimension = (typeof this.getCollapsableDimension === 'function') ? + this.getCollapsableDimension() : 'height'; + var node = this.getCollapsableDOMNode(); - return ( - React.createElement(ComponentClass, React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), - React.createElement("div", {className: this.props.fluid ? 'container-fluid' : 'container'}, - (this.props.brand || this.props.toggleButton || this.props.toggleNavKey) ? this.renderHeader() : null, - ValidComponentChildren.map(this.props.children, this.renderChild) - ) - ) - ); + this._removeEndTransitionListener(); }, - renderChild: function (child, index) { - return cloneWithProps(child, { - navbar: true, - collapsable: this.props.toggleNavKey != null && this.props.toggleNavKey === child.props.eventKey, - expanded: this.props.toggleNavKey != null && this.props.toggleNavKey === child.props.eventKey && this.isNavExpanded(), - key: child.key ? child.key : index, - ref: child.ref - }); + componentDidUpdate: function (prevProps, prevState) { + this._afterRender(); }, - renderHeader: function () { - var brand; - - if (this.props.brand) { - brand = React.isValidElement(this.props.brand) ? - cloneWithProps(this.props.brand, { - className: 'navbar-brand' - }) : React.createElement("span", {className: "navbar-brand"}, this.props.brand); + _afterRender: function () { + if (!this.props.collapsable) { + return; } - return ( - React.createElement("div", {className: "navbar-header"}, - brand, - (this.props.toggleButton || this.props.toggleNavKey != null) ? this.renderToggleButton() : null - ) - ); + this._addEndTransitionListener(); + setTimeout(this._updateDimensionAfterRender, 0); }, - renderToggleButton: function () { - var children; + _updateDimensionAfterRender: function () { + var node = this.getCollapsableDOMNode(); + if (node) { + var dimension = (typeof this.getCollapsableDimension === 'function') ? + this.getCollapsableDimension() : 'height'; + node.style[dimension] = this.isExpanded() ? + this.getCollapsableDimensionValue() + 'px' : '0px'; + } + }, - if (React.isValidElement(this.props.toggleButton)) { - return cloneWithProps(this.props.toggleButton, { - className: 'navbar-toggle', - onClick: createChainedFunction(this.handleToggle, this.props.toggleButton.props.onClick) + isExpanded: function () { + return (this.props.expanded != null) ? + this.props.expanded : this.state.expanded; + }, + + getCollapsableClassSet: function (className) { + var classes = {}; + + if (typeof className === 'string') { + className.split(' ').forEach(function (className) { + if (className) { + classes[className] = true; + } }); } - children = (this.props.toggleButton != null) ? - this.props.toggleButton : [ - React.createElement("span", {className: "sr-only", key: 0}, "Toggle navigation"), - React.createElement("span", {className: "icon-bar", key: 1}), - React.createElement("span", {className: "icon-bar", key: 2}), - React.createElement("span", {className: "icon-bar", key: 3}) - ]; + classes.collapsing = this.state.collapsing; + classes.collapse = !this.state.collapsing; + classes['in'] = this.isExpanded() && !this.state.collapsing; - return ( - React.createElement("button", {className: "navbar-toggle", type: "button", onClick: this.handleToggle}, - children - ) - ); + return classes; } -}); +}; -module.exports = Navbar; +module.exports = CollapsableMixin; -},{"./BootstrapMixin":7,"./Nav":30,"./utils/ValidComponentChildren":56,"./utils/classSet":57,"./utils/cloneWithProps":58,"./utils/createChainedFunction":59,"./utils/joinClasses":61,"react":253}],33:[function(require,module,exports){ +},{"./utils/TransitionEvents":60,"react":258}],20:[function(require,module,exports){ var React = require('react'); -var CustomPropTypes = require('./utils/CustomPropTypes'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var cloneWithProps = require('./utils/cloneWithProps'); + +var createChainedFunction = require('./utils/createChainedFunction'); +var BootstrapMixin = require('./BootstrapMixin'); +var DropdownStateMixin = require('./DropdownStateMixin'); +var Button = require('./Button'); +var ButtonGroup = require('./ButtonGroup'); +var DropdownMenu = require('./DropdownMenu'); +var ValidComponentChildren = require('./utils/ValidComponentChildren'); + + +var DropdownButton = React.createClass({displayName: 'DropdownButton', + mixins: [BootstrapMixin, DropdownStateMixin], -module.exports = { propTypes: { - container: CustomPropTypes.mountable + pullRight: React.PropTypes.bool, + dropup: React.PropTypes.bool, + title: React.PropTypes.node, + href: React.PropTypes.string, + onClick: React.PropTypes.func, + onSelect: React.PropTypes.func, + navItem: React.PropTypes.bool }, - getDefaultProps: function () { - return { - container: { - // Provide `getDOMNode` fn mocking a React component API. The `document.body` - // reference needs to be contained within this function so that it is not accessed - // in environments where it would not be defined, e.g. nodejs. Equally this is needed - // before the body is defined where `document.body === null`, this ensures - // `document.body` is only accessed after componentDidMount. - getDOMNode: function getDOMNode() { - return document.body; - } - } - }; - }, + render: function () { + var className = 'dropdown-toggle'; - componentWillUnmount: function () { - this._unrenderOverlay(); - if (this._overlayTarget) { - this.getContainerDOMNode() - .removeChild(this._overlayTarget); - this._overlayTarget = null; - } - }, + var renderMethod = this.props.navItem ? + 'renderNavItem' : 'renderButtonGroup'; - componentDidUpdate: function () { - this._renderOverlay(); + return this[renderMethod]([ + React.createElement(Button, React.__spread({}, + this.props, + {ref: "dropdownButton", + className: joinClasses(this.props.className, className), + onClick: this.handleDropdownClick, + key: 0, + navDropdown: this.props.navItem, + navItem: null, + title: null, + pullRight: null, + dropup: null}), + this.props.title, ' ', + React.createElement("span", {className: "caret"}) + ), + React.createElement(DropdownMenu, { + ref: "menu", + 'aria-labelledby': this.props.id, + pullRight: this.props.pullRight, + key: 1}, + ValidComponentChildren.map(this.props.children, this.renderMenuItem) + ) + ]); }, - componentDidMount: function () { - this._renderOverlay(); - }, + renderButtonGroup: function (children) { + var groupClasses = { + 'open': this.state.open, + 'dropup': this.props.dropup + }; - _mountOverlayTarget: function () { - this._overlayTarget = document.createElement('div'); - this.getContainerDOMNode() - .appendChild(this._overlayTarget); + return ( + React.createElement(ButtonGroup, { + bsSize: this.props.bsSize, + className: classSet(groupClasses)}, + children + ) + ); }, - _renderOverlay: function () { - if (!this._overlayTarget) { - this._mountOverlayTarget(); - } + renderNavItem: function (children) { + var classes = { + 'dropdown': true, + 'open': this.state.open, + 'dropup': this.props.dropup + }; - // Save reference to help testing - this._overlayInstance = React.render(this.renderOverlay(), this._overlayTarget); + return ( + React.createElement("li", {className: classSet(classes)}, + children + ) + ); }, - _unrenderOverlay: function () { - React.unmountComponentAtNode(this._overlayTarget); - this._overlayInstance = null; + renderMenuItem: function (child, index) { + // Only handle the option selection if an onSelect prop has been set on the + // component or it's child, this allows a user not to pass an onSelect + // handler and have the browser preform the default action. + var handleOptionSelect = this.props.onSelect || child.props.onSelect ? + this.handleOptionSelect : null; + + return cloneWithProps( + child, + { + // Capture onSelect events + onSelect: createChainedFunction(child.props.onSelect, handleOptionSelect), + + // Force special props to be transferred + key: child.key ? child.key : index, + ref: child.ref + } + ); }, - getOverlayDOMNode: function () { - if (!this.isMounted()) { - throw new Error('getOverlayDOMNode(): A component must be mounted to have a DOM node.'); - } + handleDropdownClick: function (e) { + e.preventDefault(); - return this._overlayInstance.getDOMNode(); + this.setDropdownState(!this.state.open); }, - getContainerDOMNode: function () { - return this.props.container.getDOMNode ? - this.props.container.getDOMNode() : this.props.container; + handleOptionSelect: function (key) { + if (this.props.onSelect) { + this.props.onSelect(key); + } + + this.setDropdownState(false); } -}; +}); -},{"./utils/CustomPropTypes":52,"react":253}],34:[function(require,module,exports){ +module.exports = DropdownButton; +},{"./BootstrapMixin":12,"./Button":13,"./ButtonGroup":14,"./DropdownMenu":21,"./DropdownStateMixin":22,"./utils/ValidComponentChildren":61,"./utils/classSet":62,"./utils/cloneWithProps":63,"./utils/createChainedFunction":64,"./utils/joinClasses":66,"react":258}],21:[function(require,module,exports){ var React = require('react'); -var OverlayMixin = require('./OverlayMixin'); -var domUtils = require('./utils/domUtils'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); var cloneWithProps = require('./utils/cloneWithProps'); var createChainedFunction = require('./utils/createChainedFunction'); -var assign = require('./utils/Object.assign'); - -/** - * Check if value one is inside or equal to the of value - * - * @param {string} one - * @param {string|array} of - * @returns {boolean} - */ -function isOneOf(one, of) { - if (Array.isArray(of)) { - return of.indexOf(one) >= 0; - } - return one === of; -} - -var OverlayTrigger = React.createClass({displayName: 'OverlayTrigger', - mixins: [OverlayMixin], +var ValidComponentChildren = require('./utils/ValidComponentChildren'); +var DropdownMenu = React.createClass({displayName: 'DropdownMenu', propTypes: { - trigger: React.PropTypes.oneOfType([ - React.PropTypes.oneOf(['manual', 'click', 'hover', 'focus']), - React.PropTypes.arrayOf(React.PropTypes.oneOf(['click', 'hover', 'focus'])) - ]), - placement: React.PropTypes.oneOf(['top','right', 'bottom', 'left']), - delay: React.PropTypes.number, - delayShow: React.PropTypes.number, - delayHide: React.PropTypes.number, - defaultOverlayShown: React.PropTypes.bool, - overlay: React.PropTypes.node.isRequired + pullRight: React.PropTypes.bool, + onSelect: React.PropTypes.func }, - getDefaultProps: function () { - return { - placement: 'right', - trigger: ['hover', 'focus'] - }; - }, + render: function () { + var classes = { + 'dropdown-menu': true, + 'dropdown-menu-right': this.props.pullRight + }; + return ( + React.createElement("ul", React.__spread({}, + this.props, + {className: joinClasses(this.props.className, classSet(classes)), + role: "menu"}), + ValidComponentChildren.map(this.props.children, this.renderMenuItem) + ) + ); + }, + + renderMenuItem: function (child, index) { + return cloneWithProps( + child, + { + // Capture onSelect events + onSelect: createChainedFunction(child.props.onSelect, this.props.onSelect), + + // Force special props to be transferred + key: child.key ? child.key : index, + ref: child.ref + } + ); + } +}); + +module.exports = DropdownMenu; +},{"./utils/ValidComponentChildren":61,"./utils/classSet":62,"./utils/cloneWithProps":63,"./utils/createChainedFunction":64,"./utils/joinClasses":66,"react":258}],22:[function(require,module,exports){ +var React = require('react'); +var EventListener = require('./utils/EventListener'); + +/** + * Checks whether a node is within + * a root nodes tree + * + * @param {DOMElement} node + * @param {DOMElement} root + * @returns {boolean} + */ +function isNodeInRoot(node, root) { + while (node) { + if (node === root) { + return true; + } + node = node.parentNode; + } + + return false; +} + +var DropdownStateMixin = { getInitialState: function () { return { - isOverlayShown: this.props.defaultOverlayShown == null ? - false : this.props.defaultOverlayShown, - overlayLeft: null, - overlayTop: null + open: false }; }, - show: function () { - this.setState({ - isOverlayShown: true - }, function() { - this.updateOverlayPosition(); - }); - }, + setDropdownState: function (newState, onStateChangeComplete) { + if (newState) { + this.bindRootCloseHandlers(); + } else { + this.unbindRootCloseHandlers(); + } - hide: function () { this.setState({ - isOverlayShown: false - }); + open: newState + }, onStateChangeComplete); }, - toggle: function () { - this.state.isOverlayShown ? - this.hide() : this.show(); + handleDocumentKeyUp: function (e) { + if (e.keyCode === 27) { + this.setDropdownState(false); + } }, - renderOverlay: function () { - if (!this.state.isOverlayShown) { - return React.createElement("span", null); + handleDocumentClick: function (e) { + // If the click originated from within this component + // don't do anything. + if (isNodeInRoot(e.target, this.getDOMNode())) { + return; } - return cloneWithProps( - this.props.overlay, - { - onRequestHide: this.hide, - placement: this.props.placement, - positionLeft: this.state.overlayLeft, - positionTop: this.state.overlayTop - } - ); + this.setDropdownState(false); }, - render: function () { - if (this.props.trigger === 'manual') { - return React.Children.only(this.props.children); - } - - var props = {}; + bindRootCloseHandlers: function () { + this._onDocumentClickListener = + EventListener.listen(document, 'click', this.handleDocumentClick); + this._onDocumentKeyupListener = + EventListener.listen(document, 'keyup', this.handleDocumentKeyUp); + }, - if (isOneOf('click', this.props.trigger)) { - props.onClick = createChainedFunction(this.toggle, this.props.onClick); + unbindRootCloseHandlers: function () { + if (this._onDocumentClickListener) { + this._onDocumentClickListener.remove(); } - if (isOneOf('hover', this.props.trigger)) { - props.onMouseOver = createChainedFunction(this.handleDelayedShow, this.props.onMouseOver); - props.onMouseOut = createChainedFunction(this.handleDelayedHide, this.props.onMouseOut); + if (this._onDocumentKeyupListener) { + this._onDocumentKeyupListener.remove(); } + }, - if (isOneOf('focus', this.props.trigger)) { - props.onFocus = createChainedFunction(this.handleDelayedShow, this.props.onFocus); - props.onBlur = createChainedFunction(this.handleDelayedHide, this.props.onBlur); - } + componentWillUnmount: function () { + this.unbindRootCloseHandlers(); + } +}; - return cloneWithProps( - React.Children.only(this.props.children), - props - ); - }, +module.exports = DropdownStateMixin; +},{"./utils/EventListener":58,"react":258}],23:[function(require,module,exports){ +/*global document */ +// TODO: listen for onTransitionEnd to remove el +function getElementsAndSelf (root, classes){ + var els = root.querySelectorAll('.' + classes.join('.')); - componentWillUnmount: function() { - clearTimeout(this._hoverDelay); - }, + els = [].map.call(els, function(e){ return e; }); - handleDelayedShow: function () { - if (this._hoverDelay != null) { - clearTimeout(this._hoverDelay); - this._hoverDelay = null; - return; + for(var i = 0; i < classes.length; i++){ + if( !root.className.match(new RegExp('\\b' + classes[i] + '\\b'))){ + return els; } + } + els.unshift(root); + return els; +} - var delay = this.props.delayShow != null ? - this.props.delayShow : this.props.delay; +module.exports = { + _fadeIn: function () { + var els; - if (!delay) { - this.show(); - return; - } + if (this.isMounted()) { + els = getElementsAndSelf(this.getDOMNode(), ['fade']); - this._hoverDelay = setTimeout(function() { - this._hoverDelay = null; - this.show(); - }.bind(this), delay); + if (els.length) { + els.forEach(function (el) { + el.className += ' in'; + }); + } + } }, - handleDelayedHide: function () { - if (this._hoverDelay != null) { - clearTimeout(this._hoverDelay); - this._hoverDelay = null; - return; + _fadeOut: function () { + var els = getElementsAndSelf(this._fadeOutEl, ['fade', 'in']); + + if (els.length) { + els.forEach(function (el) { + el.className = el.className.replace(/\bin\b/, ''); + }); } - var delay = this.props.delayHide != null ? - this.props.delayHide : this.props.delay; + setTimeout(this._handleFadeOutEnd, 300); + }, - if (!delay) { - this.hide(); - return; + _handleFadeOutEnd: function () { + if (this._fadeOutEl && this._fadeOutEl.parentNode) { + this._fadeOutEl.parentNode.removeChild(this._fadeOutEl); } + }, - this._hoverDelay = setTimeout(function() { - this._hoverDelay = null; - this.hide(); - }.bind(this), delay); + componentDidMount: function () { + if (document.querySelectorAll) { + // Firefox needs delay for transition to be triggered + setTimeout(this._fadeIn, 20); + } }, - updateOverlayPosition: function () { - if (!this.isMounted()) { - return; + componentWillUnmount: function () { + var els = getElementsAndSelf(this.getDOMNode(), ['fade']), + container = (this.props.container && this.props.container.getDOMNode()) || document.body; + + if (els.length) { + this._fadeOutEl = document.createElement('div'); + container.appendChild(this._fadeOutEl); + this._fadeOutEl.appendChild(this.getDOMNode().cloneNode(true)); + // Firefox needs delay for transition to be triggered + setTimeout(this._fadeOut, 20); } + } +}; - var pos = this.calcOverlayPosition(); +},{}],24:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var BootstrapMixin = require('./BootstrapMixin'); +var constants = require('./constants'); - this.setState({ - overlayLeft: pos.left, - overlayTop: pos.top - }); +var Glyphicon = React.createClass({displayName: 'Glyphicon', + mixins: [BootstrapMixin], + + propTypes: { + glyph: React.PropTypes.oneOf(constants.GLYPHS).isRequired }, - calcOverlayPosition: function () { - var childOffset = this.getPosition(); + getDefaultProps: function () { + return { + bsClass: 'glyphicon' + }; + }, - var overlayNode = this.getOverlayDOMNode(); - var overlayHeight = overlayNode.offsetHeight; - var overlayWidth = overlayNode.offsetWidth; + render: function () { + var classes = this.getBsClassSet(); - switch (this.props.placement) { - case 'right': - return { - top: childOffset.top + childOffset.height / 2 - overlayHeight / 2, - left: childOffset.left + childOffset.width - }; - case 'left': - return { - top: childOffset.top + childOffset.height / 2 - overlayHeight / 2, - left: childOffset.left - overlayWidth - }; - case 'top': - return { - top: childOffset.top - overlayHeight, - left: childOffset.left + childOffset.width / 2 - overlayWidth / 2 - }; - case 'bottom': - return { - top: childOffset.top + childOffset.height, - left: childOffset.left + childOffset.width / 2 - overlayWidth / 2 - }; - default: - throw new Error('calcOverlayPosition(): No such placement of "' + this.props.placement + '" found.'); - } - }, - - getPosition: function () { - var node = this.getDOMNode(); - var container = this.getContainerDOMNode(); - - var offset = container.tagName == 'BODY' ? - domUtils.getOffset(node) : domUtils.getPosition(node, container); - - return assign({}, offset, { - height: node.offsetHeight, - width: node.offsetWidth - }); - } -}); - -module.exports = OverlayTrigger; -},{"./OverlayMixin":33,"./utils/Object.assign":54,"./utils/cloneWithProps":58,"./utils/createChainedFunction":59,"./utils/domUtils":60,"react":253}],35:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); - -var PageHeader = React.createClass({displayName: 'PageHeader', + classes['glyphicon-' + this.props.glyph] = true; - render: function () { return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, 'page-header')}), - React.createElement("h1", null, this.props.children) + React.createElement("span", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + this.props.children ) ); } }); -module.exports = PageHeader; -},{"./utils/joinClasses":61,"react":253}],36:[function(require,module,exports){ +module.exports = Glyphicon; +},{"./BootstrapMixin":12,"./constants":55,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],25:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); - -var PageItem = React.createClass({displayName: 'PageItem', +var Grid = React.createClass({displayName: 'Grid', propTypes: { - disabled: React.PropTypes.bool, - previous: React.PropTypes.bool, - next: React.PropTypes.bool, - onSelect: React.PropTypes.func, - eventKey: React.PropTypes.any + fluid: React.PropTypes.bool, + componentClass: React.PropTypes.node.isRequired }, getDefaultProps: function () { return { - href: '#' + componentClass: 'div' }; }, render: function () { - var classes = { - 'disabled': this.props.disabled, - 'previous': this.props.previous, - 'next': this.props.next - }; + var ComponentClass = this.props.componentClass; + var className = this.props.fluid ? 'container-fluid' : 'container'; return ( - React.createElement("li", React.__spread({}, + React.createElement(ComponentClass, React.__spread({}, this.props, - {className: joinClasses(this.props.className, classSet(classes))}), - React.createElement("a", { - href: this.props.href, - title: this.props.title, - onClick: this.handleSelect, - ref: "anchor"}, - this.props.children - ) + {className: joinClasses(this.props.className, className)}), + this.props.children ) ); - }, - - handleSelect: function (e) { - if (this.props.onSelect) { - e.preventDefault(); - - if (!this.props.disabled) { - this.props.onSelect(this.props.eventKey, this.props.href); - } - } } }); -module.exports = PageItem; -},{"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],37:[function(require,module,exports){ +module.exports = Grid; +},{"./utils/joinClasses":66,"react":258}],26:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); -var cloneWithProps = require('./utils/cloneWithProps'); - -var ValidComponentChildren = require('./utils/ValidComponentChildren'); -var createChainedFunction = require('./utils/createChainedFunction'); - -var Pager = React.createClass({displayName: 'Pager', +var classSet = require('./utils/classSet'); +var Button = require('./Button'); +var Input = React.createClass({displayName: 'Input', propTypes: { - onSelect: React.PropTypes.func - }, - - render: function () { - return ( - React.createElement("ul", React.__spread({}, - this.props, - {className: joinClasses(this.props.className, 'pager')}), - ValidComponentChildren.map(this.props.children, this.renderPageItem) - ) - ); - }, - - renderPageItem: function (child, index) { - return cloneWithProps( - child, - { - onSelect: createChainedFunction(child.props.onSelect, this.props.onSelect), - ref: child.ref, - key: child.key ? child.key : index + type: React.PropTypes.string, + label: React.PropTypes.node, + help: React.PropTypes.node, + addonBefore: React.PropTypes.node, + addonAfter: React.PropTypes.node, + buttonBefore: React.PropTypes.node, + buttonAfter: React.PropTypes.node, + bsStyle: function(props) { + if (props.type === 'submit') { + // Return early if `type=submit` as the `Button` component + // it transfers these props to has its own propType checks. + return; } - ); - } -}); - -module.exports = Pager; -},{"./utils/ValidComponentChildren":56,"./utils/cloneWithProps":58,"./utils/createChainedFunction":59,"./utils/joinClasses":61,"react":253}],38:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var cloneWithProps = require('./utils/cloneWithProps'); - -var BootstrapMixin = require('./BootstrapMixin'); -var CollapsableMixin = require('./CollapsableMixin'); - -var Panel = React.createClass({displayName: 'Panel', - mixins: [BootstrapMixin, CollapsableMixin], - propTypes: { - onSelect: React.PropTypes.func, - header: React.PropTypes.node, - footer: React.PropTypes.node, - eventKey: React.PropTypes.any + return React.PropTypes.oneOf(['success', 'warning', 'error']).apply(null, arguments); + }, + hasFeedback: React.PropTypes.bool, + groupClassName: React.PropTypes.string, + wrapperClassName: React.PropTypes.string, + labelClassName: React.PropTypes.string, + disabled: React.PropTypes.bool }, - getDefaultProps: function () { - return { - bsClass: 'panel', - bsStyle: 'default' - }; + getInputDOMNode: function () { + return this.refs.input.getDOMNode(); }, - handleSelect: function (e) { - if (this.props.onSelect) { - this._isChanging = true; - this.props.onSelect(this.props.eventKey); - this._isChanging = false; + getValue: function () { + if (this.props.type === 'static') { + return this.props.value; } + else if (this.props.type) { + return this.getInputDOMNode().value; + } + else { + throw Error('Cannot use getValue without specifying input type.'); + } + }, - e.preventDefault(); - - this.setState({ - expanded: !this.state.expanded - }); + getChecked: function () { + return this.getInputDOMNode().checked; }, - shouldComponentUpdate: function () { - return !this._isChanging; + isCheckboxOrRadio: function () { + return this.props.type === 'radio' || this.props.type === 'checkbox'; }, - getCollapsableDimensionValue: function () { - return this.refs.body.getDOMNode().offsetHeight; + isFile: function () { + return this.props.type === 'file'; }, - getCollapsableDOMNode: function () { - if (!this.isMounted() || !this.refs || !this.refs.panel) { - return null; - } + renderInput: function () { + var input = null; - return this.refs.panel.getDOMNode(); - }, + if (!this.props.type) { + return this.props.children + } - render: function () { - var classes = this.getBsClassSet(); - classes['panel'] = true; + switch (this.props.type) { + case 'select': + input = ( + React.createElement("select", React.__spread({}, this.props, {className: joinClasses(this.props.className, 'form-control'), ref: "input", key: "input"}), + this.props.children + ) + ); + break; + case 'textarea': + input = React.createElement("textarea", React.__spread({}, this.props, {className: joinClasses(this.props.className, 'form-control'), ref: "input", key: "input"})); + break; + case 'static': + input = ( + React.createElement("p", React.__spread({}, this.props, {className: joinClasses(this.props.className, 'form-control-static'), ref: "input", key: "input"}), + this.props.value + ) + ); + break; + case 'submit': + input = ( + React.createElement(Button, React.__spread({}, this.props, {componentClass: "input", ref: "input", key: "input"})) + ); + break; + default: + var className = this.isCheckboxOrRadio() || this.isFile() ? '' : 'form-control'; + input = React.createElement("input", React.__spread({}, this.props, {className: joinClasses(this.props.className, className), ref: "input", key: "input"})); + } - return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes)), - id: this.props.collapsable ? null : this.props.id, onSelect: null}), - this.renderHeading(), - this.props.collapsable ? this.renderCollapsableBody() : this.renderBody(), - this.renderFooter() - ) - ); + return input; }, - renderCollapsableBody: function () { - return ( - React.createElement("div", {className: classSet(this.getCollapsableClassSet('panel-collapse')), id: this.props.id, ref: "panel"}, - this.renderBody() + renderInputGroup: function (children) { + var addonBefore = this.props.addonBefore ? ( + React.createElement("span", {className: "input-group-addon", key: "addonBefore"}, + this.props.addonBefore ) - ); - }, + ) : null; - renderBody: function () { - return ( - React.createElement("div", {className: "panel-body", ref: "body"}, - this.props.children + var addonAfter = this.props.addonAfter ? ( + React.createElement("span", {className: "input-group-addon", key: "addonAfter"}, + this.props.addonAfter ) - ); - }, - - renderHeading: function () { - var header = this.props.header; + ) : null; - if (!header) { - return null; - } + var buttonBefore = this.props.buttonBefore ? ( + React.createElement("span", {className: "input-group-btn"}, + this.props.buttonBefore + ) + ) : null; - if (!React.isValidElement(header) || Array.isArray(header)) { - header = this.props.collapsable ? - this.renderCollapsableTitle(header) : header; - } else if (this.props.collapsable) { - header = cloneWithProps(header, { - className: 'panel-title', - children: this.renderAnchor(header.props.children) - }); - } else { - header = cloneWithProps(header, { - className: 'panel-title' - }); - } + var buttonAfter = this.props.buttonAfter ? ( + React.createElement("span", {className: "input-group-btn"}, + this.props.buttonAfter + ) + ) : null; - return ( - React.createElement("div", {className: "panel-heading"}, - header + return addonBefore || addonAfter || buttonBefore || buttonAfter ? ( + React.createElement("div", {className: "input-group", key: "input-group"}, + addonBefore, + buttonBefore, + children, + addonAfter, + buttonAfter ) - ); + ) : children; }, - renderAnchor: function (header) { - return ( - React.createElement("a", { - href: '#' + (this.props.id || ''), - className: this.isExpanded() ? null : 'collapsed', - onClick: this.handleSelect}, - header - ) - ); + renderIcon: function () { + var classes = { + 'glyphicon': true, + 'form-control-feedback': true, + 'glyphicon-ok': this.props.bsStyle === 'success', + 'glyphicon-warning-sign': this.props.bsStyle === 'warning', + 'glyphicon-remove': this.props.bsStyle === 'error' + }; + + return this.props.hasFeedback ? ( + React.createElement("span", {className: classSet(classes), key: "icon"}) + ) : null; }, - renderCollapsableTitle: function (header) { - return ( - React.createElement("h4", {className: "panel-title"}, - this.renderAnchor(header) + renderHelp: function () { + return this.props.help ? ( + React.createElement("span", {className: "help-block", key: "help"}, + this.props.help ) - ); + ) : null; }, - renderFooter: function () { - if (!this.props.footer) { - return null; - } + renderCheckboxandRadioWrapper: function (children) { + var classes = { + 'checkbox': this.props.type === 'checkbox', + 'radio': this.props.type === 'radio' + }; return ( - React.createElement("div", {className: "panel-footer"}, - this.props.footer + React.createElement("div", {className: classSet(classes), key: "checkboxRadioWrapper"}, + children ) ); - } -}); - -module.exports = Panel; -},{"./BootstrapMixin":7,"./CollapsableMixin":14,"./utils/classSet":57,"./utils/cloneWithProps":58,"./utils/joinClasses":61,"react":253}],39:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var cloneWithProps = require('./utils/cloneWithProps'); - -var BootstrapMixin = require('./BootstrapMixin'); -var ValidComponentChildren = require('./utils/ValidComponentChildren'); - -var PanelGroup = React.createClass({displayName: 'PanelGroup', - mixins: [BootstrapMixin], - - propTypes: { - collapsable: React.PropTypes.bool, - activeKey: React.PropTypes.any, - defaultActiveKey: React.PropTypes.any, - onSelect: React.PropTypes.func }, - getDefaultProps: function () { - return { - bsClass: 'panel-group' - }; + renderWrapper: function (children) { + return this.props.wrapperClassName ? ( + React.createElement("div", {className: this.props.wrapperClassName, key: "wrapper"}, + children + ) + ) : children; }, - getInitialState: function () { - var defaultActiveKey = this.props.defaultActiveKey; - - return { - activeKey: defaultActiveKey + renderLabel: function (children) { + var classes = { + 'control-label': !this.isCheckboxOrRadio() }; - }, + classes[this.props.labelClassName] = this.props.labelClassName; - render: function () { - var classes = this.getBsClassSet(); - return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes)), onSelect: null}), - ValidComponentChildren.map(this.props.children, this.renderPanel) + return this.props.label ? ( + React.createElement("label", {htmlFor: this.props.id, className: classSet(classes), key: "label"}, + children, + this.props.label ) - ); + ) : children; }, - renderPanel: function (child, index) { - var activeKey = - this.props.activeKey != null ? this.props.activeKey : this.state.activeKey; - - var props = { - bsStyle: child.props.bsStyle || this.props.bsStyle, - key: child.key ? child.key : index, - ref: child.ref + renderFormGroup: function (children) { + var classes = { + 'form-group': true, + 'has-feedback': this.props.hasFeedback, + 'has-success': this.props.bsStyle === 'success', + 'has-warning': this.props.bsStyle === 'warning', + 'has-error': this.props.bsStyle === 'error' }; + classes[this.props.groupClassName] = this.props.groupClassName; - if (this.props.accordion) { - props.collapsable = true; - props.expanded = (child.props.eventKey === activeKey); - props.onSelect = this.handleSelect; - } - - return cloneWithProps( - child, - props + return ( + React.createElement("div", {className: classSet(classes)}, + children + ) ); }, - shouldComponentUpdate: function() { - // Defer any updates to this component during the `onSelect` handler. - return !this._isChanging; - }, - - handleSelect: function (key) { - if (this.props.onSelect) { - this._isChanging = true; - this.props.onSelect(key); - this._isChanging = false; + render: function () { + if (this.isCheckboxOrRadio()) { + return this.renderFormGroup( + this.renderWrapper([ + this.renderCheckboxandRadioWrapper( + this.renderLabel( + this.renderInput() + ) + ), + this.renderHelp() + ]) + ); } - - if (this.state.activeKey === key) { - key = null; + else { + return this.renderFormGroup([ + this.renderLabel(), + this.renderWrapper([ + this.renderInputGroup( + this.renderInput() + ), + this.renderIcon(), + this.renderHelp() + ]) + ]); } - - this.setState({ - activeKey: key - }); } }); -module.exports = PanelGroup; -},{"./BootstrapMixin":7,"./utils/ValidComponentChildren":56,"./utils/classSet":57,"./utils/cloneWithProps":58,"./utils/joinClasses":61,"react":253}],40:[function(require,module,exports){ +module.exports = Input; + +},{"./Button":13,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],27:[function(require,module,exports){ +// https://www.npmjs.org/package/react-interpolate-component +'use strict'; + var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var BootstrapMixin = require('./BootstrapMixin'); +var ValidComponentChildren = require('./utils/ValidComponentChildren'); +var assign = require('./utils/Object.assign'); +var REGEXP = /\%\((.+?)\)s/; -var Popover = React.createClass({displayName: 'Popover', - mixins: [BootstrapMixin], +var Interpolate = React.createClass({ + displayName: 'Interpolate', propTypes: { - placement: React.PropTypes.oneOf(['top','right', 'bottom', 'left']), - positionLeft: React.PropTypes.number, - positionTop: React.PropTypes.number, - arrowOffsetLeft: React.PropTypes.number, - arrowOffsetTop: React.PropTypes.number, - title: React.PropTypes.node + format: React.PropTypes.string }, - getDefaultProps: function () { - return { - placement: 'right' - }; + getDefaultProps: function() { + return { component: 'span' }; }, - render: function () { - var classes = {}; - classes['popover'] = true; - classes[this.props.placement] = true; - classes['in'] = this.props.positionLeft != null || this.props.positionTop != null; - - var style = {}; - style['left'] = this.props.positionLeft; - style['top'] = this.props.positionTop; - style['display'] = 'block'; - - var arrowStyle = {}; - arrowStyle['left'] = this.props.arrowOffsetLeft; - arrowStyle['top'] = this.props.arrowOffsetTop; - - return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes)), style: style, title: null}), - React.createElement("div", {className: "arrow", style: arrowStyle}), - this.props.title ? this.renderTitle() : null, - React.createElement("div", {className: "popover-content"}, - this.props.children - ) - ) - ); - }, - - renderTitle: function() { - return ( - React.createElement("h3", {className: "popover-title"}, this.props.title) - ); - } -}); - -module.exports = Popover; -},{"./BootstrapMixin":7,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],41:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var Interpolate = require('./Interpolate'); -var BootstrapMixin = require('./BootstrapMixin'); -var classSet = require('./utils/classSet'); -var cloneWithProps = require('./utils/cloneWithProps'); - -var ValidComponentChildren = require('./utils/ValidComponentChildren'); + render: function() { + var format = (ValidComponentChildren.hasValidComponent(this.props.children) || + (typeof this.props.children === 'string')) ? + this.props.children : this.props.format; + var parent = this.props.component; + var unsafe = this.props.unsafe === true; + var props = assign({}, this.props); + delete props.children; + delete props.format; + delete props.component; + delete props.unsafe; -var ProgressBar = React.createClass({displayName: 'ProgressBar', - propTypes: { - min: React.PropTypes.number, - now: React.PropTypes.number, - max: React.PropTypes.number, - label: React.PropTypes.node, - srOnly: React.PropTypes.bool, - striped: React.PropTypes.bool, - active: React.PropTypes.bool - }, + if (unsafe) { + var content = format.split(REGEXP).reduce(function(memo, match, index) { + var html; - mixins: [BootstrapMixin], + if (index % 2 === 0) { + html = match; + } else { + html = props[match]; + delete props[match]; + } - getDefaultProps: function () { - return { - bsClass: 'progress-bar', - min: 0, - max: 100 - }; - }, + if (React.isValidElement(html)) { + throw new Error('cannot interpolate a React component into unsafe text'); + } - getPercentage: function (now, min, max) { - return Math.ceil((now - min) / (max - min) * 100); - }, + memo += html; - render: function () { - var classes = { - progress: true - }; + return memo; + }, ''); - if (this.props.active) { - classes['progress-striped'] = true; - classes['active'] = true; - } else if (this.props.striped) { - classes['progress-striped'] = true; - } + props.dangerouslySetInnerHTML = { __html: content }; - if (!ValidComponentChildren.hasValidComponent(this.props.children)) { - if (!this.props.isChild) { - return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), - this.renderProgressBar() - ) - ); - } else { - return ( - this.renderProgressBar() - ); - } + return React.createElement(parent, props); } else { - return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), - ValidComponentChildren.map(this.props.children, this.renderChildBar) - ) - ); - } - }, + var kids = format.split(REGEXP).reduce(function(memo, match, index) { + var child; - renderChildBar: function (child, index) { - return cloneWithProps(child, { - isChild: true, - key: child.key ? child.key : index, - ref: child.ref - }); - }, + if (index % 2 === 0) { + if (match.length === 0) { + return memo; + } - renderProgressBar: function () { - var percentage = this.getPercentage( - this.props.now, - this.props.min, - this.props.max - ); + child = match; + } else { + child = props[match]; + delete props[match]; + } - var label; + memo.push(child); - if (typeof this.props.label === "string") { - label = this.renderLabel(percentage); - } else if (this.props.label) { - label = this.props.label; - } + return memo; + }, []); - if (this.props.srOnly) { - label = this.renderScreenReaderOnlyLabel(label); + return React.createElement(parent, props, kids); } + } +}); - var classes = this.getBsClassSet(); - - return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes)), role: "progressbar", - style: {width: percentage + '%'}, - 'aria-valuenow': this.props.now, - 'aria-valuemin': this.props.min, - 'aria-valuemax': this.props.max}), - label - ) - ); - }, +module.exports = Interpolate; - renderLabel: function (percentage) { - var InterpolateClass = this.props.interpolateClass || Interpolate; +},{"./utils/Object.assign":59,"./utils/ValidComponentChildren":61,"react":258}],28:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); - return ( - React.createElement(InterpolateClass, { - now: this.props.now, - min: this.props.min, - max: this.props.max, - percent: percentage, - bsStyle: this.props.bsStyle}, - this.props.label - ) - ); - }, +var Jumbotron = React.createClass({displayName: 'Jumbotron', - renderScreenReaderOnlyLabel: function (label) { + render: function () { return ( - React.createElement("span", {className: "sr-only"}, - label + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, 'jumbotron')}), + this.props.children ) ); } }); -module.exports = ProgressBar; - -},{"./BootstrapMixin":7,"./Interpolate":22,"./utils/ValidComponentChildren":56,"./utils/classSet":57,"./utils/cloneWithProps":58,"./utils/joinClasses":61,"react":253}],42:[function(require,module,exports){ +module.exports = Jumbotron; +},{"./utils/joinClasses":66,"react":258}],29:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var BootstrapMixin = require('./BootstrapMixin'); -var Row = React.createClass({displayName: 'Row', - propTypes: { - componentClass: React.PropTypes.node.isRequired - }, +var Label = React.createClass({displayName: 'Label', + mixins: [BootstrapMixin], getDefaultProps: function () { return { - componentClass: 'div' + bsClass: 'label', + bsStyle: 'default' }; }, render: function () { - var ComponentClass = this.props.componentClass; + var classes = this.getBsClassSet(); return ( - React.createElement(ComponentClass, React.__spread({}, this.props, {className: joinClasses(this.props.className, 'row')}), + React.createElement("span", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), this.props.children ) ); } }); -module.exports = Row; -},{"./utils/joinClasses":61,"react":253}],43:[function(require,module,exports){ +module.exports = Label; +},{"./BootstrapMixin":12,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],30:[function(require,module,exports){ var React = require('react'); -var joinClasses = require('./utils/joinClasses'); var classSet = require('./utils/classSet'); -var BootstrapMixin = require('./BootstrapMixin'); -var DropdownStateMixin = require('./DropdownStateMixin'); -var Button = require('./Button'); -var ButtonGroup = require('./ButtonGroup'); -var DropdownMenu = require('./DropdownMenu'); +var cloneWithProps = require('./utils/cloneWithProps'); -var SplitButton = React.createClass({displayName: 'SplitButton', - mixins: [BootstrapMixin, DropdownStateMixin], +var ValidComponentChildren = require('./utils/ValidComponentChildren'); +var createChainedFunction = require('./utils/createChainedFunction'); +var ListGroup = React.createClass({displayName: 'ListGroup', propTypes: { - pullRight: React.PropTypes.bool, - title: React.PropTypes.node, - href: React.PropTypes.string, - dropdownTitle: React.PropTypes.node, - onClick: React.PropTypes.func, - onSelect: React.PropTypes.func, - disabled: React.PropTypes.bool - }, - - getDefaultProps: function () { - return { - dropdownTitle: 'Toggle dropdown' - }; + onClick: React.PropTypes.func }, render: function () { - var groupClasses = { - 'open': this.state.open, - 'dropup': this.props.dropup - }; - - var button = ( - React.createElement(Button, React.__spread({}, - this.props, - {ref: "button", - onClick: this.handleButtonClick, - title: null, - id: null}), - this.props.title + return ( + React.createElement("div", {className: "list-group"}, + ValidComponentChildren.map(this.props.children, this.renderListItem) ) ); + }, - var dropdownButton = ( - React.createElement(Button, React.__spread({}, - this.props, - {ref: "dropdownButton", - className: joinClasses(this.props.className, 'dropdown-toggle'), - onClick: this.handleDropdownClick, - title: null, - id: null}), - React.createElement("span", {className: "sr-only"}, this.props.dropdownTitle), - React.createElement("span", {className: "caret"}) - ) - ); - - return ( - React.createElement(ButtonGroup, { - bsSize: this.props.bsSize, - className: classSet(groupClasses), - id: this.props.id}, - button, - dropdownButton, - React.createElement(DropdownMenu, { - ref: "menu", - onSelect: this.handleOptionSelect, - 'aria-labelledby': this.props.id, - pullRight: this.props.pullRight}, - this.props.children - ) - ) - ); - }, - - handleButtonClick: function (e) { - if (this.state.open) { - this.setDropdownState(false); - } - - if (this.props.onClick) { - this.props.onClick(e); - } - }, - - handleDropdownClick: function (e) { - e.preventDefault(); - - this.setDropdownState(!this.state.open); - }, - - handleOptionSelect: function (key) { - if (this.props.onSelect) { - this.props.onSelect(key); - } - - this.setDropdownState(false); + renderListItem: function (child, index) { + return cloneWithProps(child, { + onClick: createChainedFunction(child.props.onClick, this.props.onClick), + ref: child.ref, + key: child.key ? child.key : index + }); } }); -module.exports = SplitButton; +module.exports = ListGroup; -},{"./BootstrapMixin":7,"./Button":8,"./ButtonGroup":9,"./DropdownMenu":16,"./DropdownStateMixin":17,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],44:[function(require,module,exports){ +},{"./utils/ValidComponentChildren":61,"./utils/classSet":62,"./utils/cloneWithProps":63,"./utils/createChainedFunction":64,"react":258}],31:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); +var BootstrapMixin = require('./BootstrapMixin'); var classSet = require('./utils/classSet'); var cloneWithProps = require('./utils/cloneWithProps'); var ValidComponentChildren = require('./utils/ValidComponentChildren'); -var createChainedFunction = require('./utils/createChainedFunction'); -var BootstrapMixin = require('./BootstrapMixin'); - -var SubNav = React.createClass({displayName: 'SubNav', +var ListGroupItem = React.createClass({displayName: 'ListGroupItem', mixins: [BootstrapMixin], propTypes: { - onSelect: React.PropTypes.func, - active: React.PropTypes.bool, - disabled: React.PropTypes.bool, - href: React.PropTypes.string, - title: React.PropTypes.string, - text: React.PropTypes.node + bsStyle: React.PropTypes.oneOf(['danger','info','success','warning']), + active: React.PropTypes.any, + disabled: React.PropTypes.any, + header: React.PropTypes.node, + onClick: React.PropTypes.func, + eventKey: React.PropTypes.any }, getDefaultProps: function () { return { - bsClass: 'nav' + bsClass: 'list-group-item' }; }, - handleClick: function (e) { - if (this.props.onSelect) { - e.preventDefault(); + render: function () { + var classes = this.getBsClassSet(); - if (!this.props.disabled) { - this.props.onSelect(this.props.eventKey, this.props.href); - } + classes['active'] = this.props.active; + classes['disabled'] = this.props.disabled; + + if (this.props.href || this.props.onClick) { + return this.renderAnchor(classes); + } else { + return this.renderSpan(classes); } }, - isActive: function () { - return this.isChildActive(this); + renderSpan: function (classes) { + return ( + React.createElement("span", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + this.props.header ? this.renderStructuredContent() : this.props.children + ) + ); }, - isChildActive: function (child) { - if (child.props.active) { - return true; - } + renderAnchor: function (classes) { + return ( + React.createElement("a", React.__spread({}, + this.props, + {className: joinClasses(this.props.className, classSet(classes)), + onClick: this.handleClick}), + this.props.header ? this.renderStructuredContent() : this.props.children + ) + ); + }, - if (this.props.activeKey != null && this.props.activeKey === child.props.eventKey) { - return true; + renderStructuredContent: function () { + var header; + if (React.isValidElement(this.props.header)) { + header = cloneWithProps(this.props.header, { + className: 'list-group-item-heading' + }); + } else { + header = ( + React.createElement("h4", {className: "list-group-item-heading"}, + this.props.header + ) + ); } - if (this.props.activeHref != null && this.props.activeHref === child.props.href) { - return true; + var content = ( + React.createElement("p", {className: "list-group-item-text"}, + this.props.children + ) + ); + + return { + header: header, + content: content + }; + }, + + handleClick: function (e) { + if (this.props.onClick) { + e.preventDefault(); + this.props.onClick(this.props.eventKey, this.props.href); } + } +}); - if (child.props.children) { - var isActive = false; +module.exports = ListGroupItem; - ValidComponentChildren.forEach( - child.props.children, - function (child) { - if (this.isChildActive(child)) { - isActive = true; - } - }, - this - ); +},{"./BootstrapMixin":12,"./utils/ValidComponentChildren":61,"./utils/classSet":62,"./utils/cloneWithProps":63,"./utils/joinClasses":66,"react":258}],32:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); - return isActive; - } +var MenuItem = React.createClass({displayName: 'MenuItem', + propTypes: { + header: React.PropTypes.bool, + divider: React.PropTypes.bool, + href: React.PropTypes.string, + title: React.PropTypes.string, + onSelect: React.PropTypes.func, + eventKey: React.PropTypes.any + }, - return false; + getDefaultProps: function () { + return { + href: '#' + }; }, - getChildActiveProp: function (child) { - if (child.props.active) { - return true; - } - if (this.props.activeKey != null) { - if (child.props.eventKey == this.props.activeKey) { - return true; - } - } - if (this.props.activeHref != null) { - if (child.props.href === this.props.activeHref) { - return true; - } + handleClick: function (e) { + if (this.props.onSelect) { + e.preventDefault(); + this.props.onSelect(this.props.eventKey); } + }, - return child.props.active; + renderAnchor: function () { + return ( + React.createElement("a", {onClick: this.handleClick, href: this.props.href, title: this.props.title, tabIndex: "-1"}, + this.props.children + ) + ); }, render: function () { var classes = { - 'active': this.isActive(), - 'disabled': this.props.disabled - }; + 'dropdown-header': this.props.header, + 'divider': this.props.divider + }; + + var children = null; + if (this.props.header) { + children = this.props.children; + } else if (!this.props.divider) { + children = this.renderAnchor(); + } return ( - React.createElement("li", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), - React.createElement("a", { - href: this.props.href, - title: this.props.title, - onClick: this.handleClick, - ref: "anchor"}, - this.props.text - ), - React.createElement("ul", {className: "nav"}, - ValidComponentChildren.map(this.props.children, this.renderNavItem) - ) + React.createElement("li", React.__spread({}, this.props, {role: "presentation", title: null, href: null, + className: joinClasses(this.props.className, classSet(classes))}), + children ) ); - }, - - renderNavItem: function (child, index) { - return cloneWithProps( - child, - { - active: this.getChildActiveProp(child), - onSelect: createChainedFunction(child.props.onSelect, this.props.onSelect), - ref: child.ref, - key: child.key ? child.key : index - } - ); } }); -module.exports = SubNav; +module.exports = MenuItem; +},{"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],33:[function(require,module,exports){ +/* global document:false */ -},{"./BootstrapMixin":7,"./utils/ValidComponentChildren":56,"./utils/classSet":57,"./utils/cloneWithProps":58,"./utils/createChainedFunction":59,"./utils/joinClasses":61,"react":253}],45:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); var classSet = require('./utils/classSet'); -var TransitionEvents = require('./utils/TransitionEvents'); - -var TabPane = React.createClass({displayName: 'TabPane', - getDefaultProps: function () { - return { - animation: true - }; - }, +var BootstrapMixin = require('./BootstrapMixin'); +var FadeMixin = require('./FadeMixin'); +var EventListener = require('./utils/EventListener'); - getInitialState: function () { - return { - animateIn: false, - animateOut: false - }; - }, - componentWillReceiveProps: function (nextProps) { - if (this.props.animation) { - if (!this.state.animateIn && nextProps.active && !this.props.active) { - this.setState({ - animateIn: true - }); - } else if (!this.state.animateOut && !nextProps.active && this.props.active) { - this.setState({ - animateOut: true - }); - } - } - }, +// TODO: +// - aria-labelledby +// - Add `modal-body` div if only one child passed in that doesn't already have it +// - Tests - componentDidUpdate: function () { - if (this.state.animateIn) { - setTimeout(this.startAnimateIn, 0); - } - if (this.state.animateOut) { - TransitionEvents.addEndEventListener( - this.getDOMNode(), - this.stopAnimateOut - ); - } +var Modal = React.createClass({displayName: 'Modal', + mixins: [BootstrapMixin, FadeMixin], + + propTypes: { + title: React.PropTypes.node, + backdrop: React.PropTypes.oneOf(['static', true, false]), + keyboard: React.PropTypes.bool, + closeButton: React.PropTypes.bool, + animation: React.PropTypes.bool, + onRequestHide: React.PropTypes.func.isRequired }, - startAnimateIn: function () { - if (this.isMounted()) { - this.setState({ - animateIn: false - }); - } + getDefaultProps: function () { + return { + bsClass: 'modal', + backdrop: true, + keyboard: true, + animation: true, + closeButton: true + }; }, - stopAnimateOut: function () { - if (this.isMounted()) { - this.setState({ - animateOut: false - }); + render: function () { + var modalStyle = {display: 'block'}; + var dialogClasses = this.getBsClassSet(); + delete dialogClasses.modal; + dialogClasses['modal-dialog'] = true; - if (typeof this.props.onAnimateOutEnd === 'function') { - this.props.onAnimateOutEnd(); - } - } + var classes = { + modal: true, + fade: this.props.animation, + 'in': !this.props.animation || !document.querySelectorAll + }; + + var modal = ( + React.createElement("div", React.__spread({}, + this.props, + {title: null, + tabIndex: "-1", + role: "dialog", + style: modalStyle, + className: joinClasses(this.props.className, classSet(classes)), + onClick: this.props.backdrop === true ? this.handleBackdropClick : null, + ref: "modal"}), + React.createElement("div", {className: classSet(dialogClasses)}, + React.createElement("div", {className: "modal-content"}, + this.props.title ? this.renderHeader() : null, + this.props.children + ) + ) + ) + ); + + return this.props.backdrop ? + this.renderBackdrop(modal) : modal; }, - render: function () { + renderBackdrop: function (modal) { var classes = { - 'tab-pane': true, - 'fade': true, - 'active': this.props.active || this.state.animateOut, - 'in': this.props.active && !this.state.animateIn + 'modal-backdrop': true, + 'fade': this.props.animation }; + classes['in'] = !this.props.animation || !document.querySelectorAll; + + var onClick = this.props.backdrop === true ? + this.handleBackdropClick : null; + return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), - this.props.children + React.createElement("div", null, + React.createElement("div", {className: classSet(classes), ref: "backdrop", onClick: onClick}), + modal ) ); - } -}); + }, -module.exports = TabPane; -},{"./utils/TransitionEvents":55,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],46:[function(require,module,exports){ -var React = require('react'); -var BootstrapMixin = require('./BootstrapMixin'); -var cloneWithProps = require('./utils/cloneWithProps'); + renderHeader: function () { + var closeButton; + if (this.props.closeButton) { + closeButton = ( + React.createElement("button", {type: "button", className: "close", 'aria-hidden': "true", onClick: this.props.onRequestHide}, "×") + ); + } -var ValidComponentChildren = require('./utils/ValidComponentChildren'); -var Nav = require('./Nav'); -var NavItem = require('./NavItem'); + return ( + React.createElement("div", {className: "modal-header"}, + closeButton, + this.renderTitle() + ) + ); + }, -function getDefaultActiveKeyFromChildren(children) { - var defaultActiveKey; + renderTitle: function () { + return ( + React.isValidElement(this.props.title) ? + this.props.title : React.createElement("h4", {className: "modal-title"}, this.props.title) + ); + }, - ValidComponentChildren.forEach(children, function(child) { - if (defaultActiveKey == null) { - defaultActiveKey = child.props.eventKey; - } - }); + iosClickHack: function () { + // IOS only allows click events to be delegated to the document on elements + // it considers 'clickable' - anchors, buttons, etc. We fake a click handler on the + // DOM nodes themselves. Remove if handled by React: https://github.com/facebook/react/issues/1169 + this.refs.modal.getDOMNode().onclick = function () {}; + this.refs.backdrop.getDOMNode().onclick = function () {}; + }, - return defaultActiveKey; -} + componentDidMount: function () { + this._onDocumentKeyupListener = + EventListener.listen(document, 'keyup', this.handleDocumentKeyUp); -var TabbedArea = React.createClass({displayName: 'TabbedArea', - mixins: [BootstrapMixin], + if (this.props.backdrop) { + this.iosClickHack(); + } + }, - propTypes: { - bsStyle: React.PropTypes.oneOf(['tabs','pills']), - animation: React.PropTypes.bool, - onSelect: React.PropTypes.func + componentDidUpdate: function (prevProps) { + if (this.props.backdrop && this.props.backdrop !== prevProps.backdrop) { + this.iosClickHack(); + } }, - getDefaultProps: function () { - return { - bsStyle: "tabs", - animation: true - }; + componentWillUnmount: function () { + this._onDocumentKeyupListener.remove(); }, - getInitialState: function () { - var defaultActiveKey = this.props.defaultActiveKey != null ? - this.props.defaultActiveKey : getDefaultActiveKeyFromChildren(this.props.children); + handleBackdropClick: function (e) { + if (e.target !== e.currentTarget) { + return; + } - // TODO: In __DEV__ mode warn via `console.warn` if no `defaultActiveKey` has - // been set by this point, invalid children or missing key properties are likely the cause. + this.props.onRequestHide(); + }, + + handleDocumentKeyUp: function (e) { + if (this.props.keyboard && e.keyCode === 27) { + this.props.onRequestHide(); + } + } +}); + +module.exports = Modal; + +},{"./BootstrapMixin":12,"./FadeMixin":23,"./utils/EventListener":58,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],34:[function(require,module,exports){ +var React = require('react'); +var OverlayMixin = require('./OverlayMixin'); +var cloneWithProps = require('./utils/cloneWithProps'); + +var createChainedFunction = require('./utils/createChainedFunction'); + +var ModalTrigger = React.createClass({displayName: 'ModalTrigger', + mixins: [OverlayMixin], + propTypes: { + modal: React.PropTypes.node.isRequired + }, + + getInitialState: function () { return { - activeKey: defaultActiveKey, - previousActiveKey: null + isOverlayShown: false }; }, - componentWillReceiveProps: function (nextProps) { - if (nextProps.activeKey != null && nextProps.activeKey !== this.props.activeKey) { - this.setState({ - previousActiveKey: this.props.activeKey - }); - } + show: function () { + this.setState({ + isOverlayShown: true + }); }, - handlePaneAnimateOutEnd: function () { + hide: function () { this.setState({ - previousActiveKey: null + isOverlayShown: false }); }, - render: function () { - var activeKey = - this.props.activeKey != null ? this.props.activeKey : this.state.activeKey; + toggle: function () { + this.setState({ + isOverlayShown: !this.state.isOverlayShown + }); + }, - function renderTabIfSet(child) { - return child.props.tab != null ? this.renderTab(child) : null; + renderOverlay: function () { + if (!this.state.isOverlayShown) { + return React.createElement("span", null); } - var nav = ( - React.createElement(Nav, React.__spread({}, this.props, {activeKey: activeKey, onSelect: this.handleSelect, ref: "tabs"}), - ValidComponentChildren.map(this.props.children, renderTabIfSet, this) - ) + return cloneWithProps( + this.props.modal, + { + onRequestHide: this.hide + } ); + }, - return ( - React.createElement("div", null, - nav, - React.createElement("div", {id: this.props.id, className: "tab-content", ref: "panes"}, - ValidComponentChildren.map(this.props.children, this.renderPane) - ) - ) + render: function () { + var child = React.Children.only(this.props.children); + return cloneWithProps( + child, + { + onClick: createChainedFunction(child.props.onClick, this.toggle) + } ); + } +}); + +module.exports = ModalTrigger; +},{"./OverlayMixin":38,"./utils/cloneWithProps":63,"./utils/createChainedFunction":64,"react":258}],35:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var BootstrapMixin = require('./BootstrapMixin'); +var CollapsableMixin = require('./CollapsableMixin'); +var classSet = require('./utils/classSet'); +var domUtils = require('./utils/domUtils'); +var cloneWithProps = require('./utils/cloneWithProps'); + +var ValidComponentChildren = require('./utils/ValidComponentChildren'); +var createChainedFunction = require('./utils/createChainedFunction'); + + +var Nav = React.createClass({displayName: 'Nav', + mixins: [BootstrapMixin, CollapsableMixin], + + propTypes: { + bsStyle: React.PropTypes.oneOf(['tabs','pills']), + stacked: React.PropTypes.bool, + justified: React.PropTypes.bool, + onSelect: React.PropTypes.func, + collapsable: React.PropTypes.bool, + expanded: React.PropTypes.bool, + navbar: React.PropTypes.bool, + eventKey: React.PropTypes.any, + right: React.PropTypes.bool }, - getActiveKey: function () { - return this.props.activeKey != null ? this.props.activeKey : this.state.activeKey; + getDefaultProps: function () { + return { + bsClass: 'nav' + }; }, - renderPane: function (child, index) { - var activeKey = this.getActiveKey(); + getCollapsableDOMNode: function () { + return this.getDOMNode(); + }, - return cloneWithProps( - child, - { - active: (child.props.eventKey === activeKey && - (this.state.previousActiveKey == null || !this.props.animation)), - ref: child.ref, - key: child.key ? child.key : index, - animation: this.props.animation, - onAnimateOutEnd: (this.state.previousActiveKey != null && - child.props.eventKey === this.state.previousActiveKey) ? this.handlePaneAnimateOutEnd: null - } - ); + getCollapsableDimensionValue: function () { + var node = this.refs.ul.getDOMNode(), + height = node.offsetHeight, + computedStyles = domUtils.getComputedStyles(node); + + return height + parseInt(computedStyles.marginTop, 10) + parseInt(computedStyles.marginBottom, 10); }, - renderTab: function (child) { - var key = child.props.eventKey; + render: function () { + var classes = this.props.collapsable ? this.getCollapsableClassSet() : {}; + + classes['navbar-collapse'] = this.props.collapsable; + + if (this.props.navbar && !this.props.collapsable) { + return (this.renderUl()); + } + return ( - React.createElement(NavItem, { - ref: 'tab' + key, - eventKey: key}, - child.props.tab + React.createElement("nav", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + this.renderUl() ) ); }, - shouldComponentUpdate: function() { - // Defer any updates to this component during the `onSelect` handler. - return !this._isChanging; + renderUl: function () { + var classes = this.getBsClassSet(); + + classes['nav-stacked'] = this.props.stacked; + classes['nav-justified'] = this.props.justified; + classes['navbar-nav'] = this.props.navbar; + classes['pull-right'] = this.props.pullRight; + classes['navbar-right'] = this.props.right; + + return ( + React.createElement("ul", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes)), ref: "ul"}), + ValidComponentChildren.map(this.props.children, this.renderNavItem) + ) + ); }, - handleSelect: function (key) { - if (this.props.onSelect) { - this._isChanging = true; - this.props.onSelect(key); - this._isChanging = false; - } else if (key !== this.getActiveKey()) { - this.setState({ - activeKey: key, - previousActiveKey: this.getActiveKey() - }); + getChildActiveProp: function (child) { + if (child.props.active) { + return true; + } + if (this.props.activeKey != null) { + if (child.props.eventKey == this.props.activeKey) { + return true; + } + } + if (this.props.activeHref != null) { + if (child.props.href === this.props.activeHref) { + return true; + } } - } -}); - -module.exports = TabbedArea; -},{"./BootstrapMixin":7,"./Nav":30,"./NavItem":31,"./utils/ValidComponentChildren":56,"./utils/cloneWithProps":58,"react":253}],47:[function(require,module,exports){ -var React = require('react'); -var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); -var Table = React.createClass({displayName: 'Table', - propTypes: { - striped: React.PropTypes.bool, - bordered: React.PropTypes.bool, - condensed: React.PropTypes.bool, - hover: React.PropTypes.bool, - responsive: React.PropTypes.bool + return child.props.active; }, - render: function () { - var classes = { - 'table': true, - 'table-striped': this.props.striped, - 'table-bordered': this.props.bordered, - 'table-condensed': this.props.condensed, - 'table-hover': this.props.hover - }; - var table = ( - React.createElement("table", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), - this.props.children - ) + renderNavItem: function (child, index) { + return cloneWithProps( + child, + { + active: this.getChildActiveProp(child), + activeKey: this.props.activeKey, + activeHref: this.props.activeHref, + onSelect: createChainedFunction(child.props.onSelect, this.props.onSelect), + ref: child.ref, + key: child.key ? child.key : index, + navItem: true + } ); - - return this.props.responsive ? ( - React.createElement("div", {className: "table-responsive"}, - table - ) - ) : table; } }); -module.exports = Table; -},{"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],48:[function(require,module,exports){ +module.exports = Nav; + +},{"./BootstrapMixin":12,"./CollapsableMixin":19,"./utils/ValidComponentChildren":61,"./utils/classSet":62,"./utils/cloneWithProps":63,"./utils/createChainedFunction":64,"./utils/domUtils":65,"./utils/joinClasses":66,"react":258}],36:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); var classSet = require('./utils/classSet'); var BootstrapMixin = require('./BootstrapMixin'); - -var Tooltip = React.createClass({displayName: 'Tooltip', +var NavItem = React.createClass({displayName: 'NavItem', mixins: [BootstrapMixin], propTypes: { - placement: React.PropTypes.oneOf(['top','right', 'bottom', 'left']), - positionLeft: React.PropTypes.number, - positionTop: React.PropTypes.number, - arrowOffsetLeft: React.PropTypes.number, - arrowOffsetTop: React.PropTypes.number + onSelect: React.PropTypes.func, + active: React.PropTypes.bool, + disabled: React.PropTypes.bool, + href: React.PropTypes.string, + title: React.PropTypes.string, + eventKey: React.PropTypes.any }, getDefaultProps: function () { return { - placement: 'right' + href: '#' }; }, render: function () { - var classes = {}; - classes['tooltip'] = true; - classes[this.props.placement] = true; - classes['in'] = this.props.positionLeft != null || this.props.positionTop != null; - - var style = {}; - style['left'] = this.props.positionLeft; - style['top'] = this.props.positionTop; - - var arrowStyle = {}; - arrowStyle['left'] = this.props.arrowOffsetLeft; - arrowStyle['top'] = this.props.arrowOffsetTop; + var $__0= + + + + + + this.props,disabled=$__0.disabled,active=$__0.active,href=$__0.href,title=$__0.title,children=$__0.children,props=(function(source, exclusion) {var rest = {};var hasOwn = Object.prototype.hasOwnProperty;if (source == null) {throw new TypeError();}for (var key in source) {if (hasOwn.call(source, key) && !hasOwn.call(exclusion, key)) {rest[key] = source[key];}}return rest;})($__0,{disabled:1,active:1,href:1,title:1,children:1}), + classes = { + 'active': active, + 'disabled': disabled + }; return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes)), style: style}), - React.createElement("div", {className: "tooltip-arrow", style: arrowStyle}), - React.createElement("div", {className: "tooltip-inner"}, - this.props.children - ) + React.createElement("li", React.__spread({}, props, {className: joinClasses(props.className, classSet(classes))}), + React.createElement("a", { + href: href, + title: title, + onClick: this.handleClick, + ref: "anchor"}, + children ) - ); + ) + ); + }, + + handleClick: function (e) { + if (this.props.onSelect) { + e.preventDefault(); + + if (!this.props.disabled) { + this.props.onSelect(this.props.eventKey, this.props.href); + } + } } }); -module.exports = Tooltip; -},{"./BootstrapMixin":7,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],49:[function(require,module,exports){ +module.exports = NavItem; +},{"./BootstrapMixin":12,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],37:[function(require,module,exports){ var React = require('react'); var joinClasses = require('./utils/joinClasses'); -var classSet = require('./utils/classSet'); var BootstrapMixin = require('./BootstrapMixin'); +var classSet = require('./utils/classSet'); +var cloneWithProps = require('./utils/cloneWithProps'); -var Well = React.createClass({displayName: 'Well', - mixins: [BootstrapMixin], - - getDefaultProps: function () { - return { - bsClass: 'well' - }; - }, +var ValidComponentChildren = require('./utils/ValidComponentChildren'); +var createChainedFunction = require('./utils/createChainedFunction'); +var Nav = require('./Nav'); - render: function () { - var classes = this.getBsClassSet(); + +var Navbar = React.createClass({displayName: 'Navbar', + mixins: [BootstrapMixin], + + propTypes: { + fixedTop: React.PropTypes.bool, + fixedBottom: React.PropTypes.bool, + staticTop: React.PropTypes.bool, + inverse: React.PropTypes.bool, + fluid: React.PropTypes.bool, + role: React.PropTypes.string, + componentClass: React.PropTypes.node.isRequired, + brand: React.PropTypes.node, + toggleButton: React.PropTypes.node, + onToggle: React.PropTypes.func, + navExpanded: React.PropTypes.bool, + defaultNavExpanded: React.PropTypes.bool + }, + + getDefaultProps: function () { + return { + bsClass: 'navbar', + bsStyle: 'default', + role: 'navigation', + componentClass: 'Nav' + }; + }, + + getInitialState: function () { + return { + navExpanded: this.props.defaultNavExpanded + }; + }, + + shouldComponentUpdate: function() { + // Defer any updates to this component during the `onSelect` handler. + return !this._isChanging; + }, + + handleToggle: function () { + if (this.props.onToggle) { + this._isChanging = true; + this.props.onToggle(); + this._isChanging = false; + } + + this.setState({ + navExpanded: !this.state.navExpanded + }); + }, + + isNavExpanded: function () { + return this.props.navExpanded != null ? this.props.navExpanded : this.state.navExpanded; + }, + + render: function () { + var classes = this.getBsClassSet(); + var ComponentClass = this.props.componentClass; + + classes['navbar-fixed-top'] = this.props.fixedTop; + classes['navbar-fixed-bottom'] = this.props.fixedBottom; + classes['navbar-static-top'] = this.props.staticTop; + classes['navbar-inverse'] = this.props.inverse; return ( - React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), - this.props.children + React.createElement(ComponentClass, React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + React.createElement("div", {className: this.props.fluid ? 'container-fluid' : 'container'}, + (this.props.brand || this.props.toggleButton || this.props.toggleNavKey) ? this.renderHeader() : null, + ValidComponentChildren.map(this.props.children, this.renderChild) + ) + ) + ); + }, + + renderChild: function (child, index) { + return cloneWithProps(child, { + navbar: true, + collapsable: this.props.toggleNavKey != null && this.props.toggleNavKey === child.props.eventKey, + expanded: this.props.toggleNavKey != null && this.props.toggleNavKey === child.props.eventKey && this.isNavExpanded(), + key: child.key ? child.key : index, + ref: child.ref + }); + }, + + renderHeader: function () { + var brand; + + if (this.props.brand) { + brand = React.isValidElement(this.props.brand) ? + cloneWithProps(this.props.brand, { + className: 'navbar-brand' + }) : React.createElement("span", {className: "navbar-brand"}, this.props.brand); + } + + return ( + React.createElement("div", {className: "navbar-header"}, + brand, + (this.props.toggleButton || this.props.toggleNavKey != null) ? this.renderToggleButton() : null + ) + ); + }, + + renderToggleButton: function () { + var children; + + if (React.isValidElement(this.props.toggleButton)) { + return cloneWithProps(this.props.toggleButton, { + className: 'navbar-toggle', + onClick: createChainedFunction(this.handleToggle, this.props.toggleButton.props.onClick) + }); + } + + children = (this.props.toggleButton != null) ? + this.props.toggleButton : [ + React.createElement("span", {className: "sr-only", key: 0}, "Toggle navigation"), + React.createElement("span", {className: "icon-bar", key: 1}), + React.createElement("span", {className: "icon-bar", key: 2}), + React.createElement("span", {className: "icon-bar", key: 3}) + ]; + + return ( + React.createElement("button", {className: "navbar-toggle", type: "button", onClick: this.handleToggle}, + children ) ); } }); -module.exports = Well; -},{"./BootstrapMixin":7,"./utils/classSet":57,"./utils/joinClasses":61,"react":253}],50:[function(require,module,exports){ +module.exports = Navbar; + +},{"./BootstrapMixin":12,"./Nav":35,"./utils/ValidComponentChildren":61,"./utils/classSet":62,"./utils/cloneWithProps":63,"./utils/createChainedFunction":64,"./utils/joinClasses":66,"react":258}],38:[function(require,module,exports){ +var React = require('react'); +var CustomPropTypes = require('./utils/CustomPropTypes'); + module.exports = { - CLASSES: { - 'alert': 'alert', - 'button': 'btn', - 'button-group': 'btn-group', - 'button-toolbar': 'btn-toolbar', - 'column': 'col', - 'input-group': 'input-group', - 'form': 'form', - 'glyphicon': 'glyphicon', - 'label': 'label', - 'list-group-item': 'list-group-item', - 'panel': 'panel', - 'panel-group': 'panel-group', - 'progress-bar': 'progress-bar', - 'nav': 'nav', - 'navbar': 'navbar', - 'modal': 'modal', - 'row': 'row', - 'well': 'well' + propTypes: { + container: CustomPropTypes.mountable }, - STYLES: { - 'default': 'default', - 'primary': 'primary', - 'success': 'success', - 'info': 'info', - 'warning': 'warning', - 'danger': 'danger', - 'link': 'link', - 'inline': 'inline', - 'tabs': 'tabs', - 'pills': 'pills' + + getDefaultProps: function () { + return { + container: { + // Provide `getDOMNode` fn mocking a React component API. The `document.body` + // reference needs to be contained within this function so that it is not accessed + // in environments where it would not be defined, e.g. nodejs. Equally this is needed + // before the body is defined where `document.body === null`, this ensures + // `document.body` is only accessed after componentDidMount. + getDOMNode: function getDOMNode() { + return document.body; + } + } + }; }, - SIZES: { - 'large': 'lg', - 'medium': 'md', - 'small': 'sm', - 'xsmall': 'xs' + + componentWillUnmount: function () { + this._unrenderOverlay(); + if (this._overlayTarget) { + this.getContainerDOMNode() + .removeChild(this._overlayTarget); + this._overlayTarget = null; + } }, - GLYPHS: [ - 'asterisk', - 'plus', - 'euro', - 'minus', - 'cloud', - 'envelope', - 'pencil', - 'glass', - 'music', - 'search', - 'heart', - 'star', - 'star-empty', - 'user', - 'film', - 'th-large', - 'th', - 'th-list', - 'ok', - 'remove', - 'zoom-in', - 'zoom-out', - 'off', - 'signal', - 'cog', - 'trash', - 'home', - 'file', - 'time', - 'road', - 'download-alt', - 'download', - 'upload', - 'inbox', - 'play-circle', - 'repeat', - 'refresh', - 'list-alt', - 'lock', - 'flag', - 'headphones', - 'volume-off', - 'volume-down', - 'volume-up', - 'qrcode', - 'barcode', - 'tag', - 'tags', - 'book', - 'bookmark', - 'print', - 'camera', - 'font', - 'bold', - 'italic', - 'text-height', - 'text-width', - 'align-left', - 'align-center', - 'align-right', - 'align-justify', - 'list', - 'indent-left', - 'indent-right', - 'facetime-video', - 'picture', - 'map-marker', - 'adjust', - 'tint', - 'edit', - 'share', - 'check', - 'move', - 'step-backward', - 'fast-backward', - 'backward', - 'play', - 'pause', - 'stop', - 'forward', - 'fast-forward', - 'step-forward', - 'eject', - 'chevron-left', - 'chevron-right', - 'plus-sign', - 'minus-sign', - 'remove-sign', - 'ok-sign', - 'question-sign', - 'info-sign', - 'screenshot', - 'remove-circle', - 'ok-circle', - 'ban-circle', - 'arrow-left', - 'arrow-right', - 'arrow-up', - 'arrow-down', - 'share-alt', - 'resize-full', - 'resize-small', - 'exclamation-sign', - 'gift', - 'leaf', - 'fire', - 'eye-open', - 'eye-close', - 'warning-sign', - 'plane', - 'calendar', - 'random', - 'comment', - 'magnet', - 'chevron-up', - 'chevron-down', - 'retweet', - 'shopping-cart', - 'folder-close', - 'folder-open', - 'resize-vertical', - 'resize-horizontal', - 'hdd', - 'bullhorn', - 'bell', - 'certificate', - 'thumbs-up', - 'thumbs-down', - 'hand-right', - 'hand-left', - 'hand-up', - 'hand-down', - 'circle-arrow-right', - 'circle-arrow-left', - 'circle-arrow-up', - 'circle-arrow-down', - 'globe', - 'wrench', - 'tasks', - 'filter', - 'briefcase', - 'fullscreen', - 'dashboard', - 'paperclip', - 'heart-empty', - 'link', - 'phone', - 'pushpin', - 'usd', - 'gbp', - 'sort', - 'sort-by-alphabet', - 'sort-by-alphabet-alt', - 'sort-by-order', - 'sort-by-order-alt', - 'sort-by-attributes', - 'sort-by-attributes-alt', - 'unchecked', - 'expand', - 'collapse-down', - 'collapse-up', - 'log-in', - 'flash', - 'log-out', - 'new-window', - 'record', - 'save', - 'open', - 'saved', - 'import', - 'export', - 'send', - 'floppy-disk', - 'floppy-saved', - 'floppy-remove', - 'floppy-save', - 'floppy-open', - 'credit-card', - 'transfer', - 'cutlery', - 'header', - 'compressed', - 'earphone', - 'phone-alt', - 'tower', - 'stats', - 'sd-video', - 'hd-video', - 'subtitles', - 'sound-stereo', - 'sound-dolby', - 'sound-5-1', - 'sound-6-1', - 'sound-7-1', - 'copyright-mark', - 'registration-mark', - 'cloud-download', - 'cloud-upload', - 'tree-conifer', - 'tree-deciduous' - ] -}; -},{}],51:[function(require,module,exports){ -module.exports = { - Accordion: require('./Accordion'), - Affix: require('./Affix'), - AffixMixin: require('./AffixMixin'), - Alert: require('./Alert'), - BootstrapMixin: require('./BootstrapMixin'), - Badge: require('./Badge'), - Button: require('./Button'), - ButtonGroup: require('./ButtonGroup'), - ButtonToolbar: require('./ButtonToolbar'), - Carousel: require('./Carousel'), - CarouselItem: require('./CarouselItem'), - Col: require('./Col'), - CollapsableMixin: require('./CollapsableMixin'), - DropdownButton: require('./DropdownButton'), - DropdownMenu: require('./DropdownMenu'), - DropdownStateMixin: require('./DropdownStateMixin'), - FadeMixin: require('./FadeMixin'), - Glyphicon: require('./Glyphicon'), - Grid: require('./Grid'), - Input: require('./Input'), - Interpolate: require('./Interpolate'), - Jumbotron: require('./Jumbotron'), - Label: require('./Label'), - ListGroup: require('./ListGroup'), - ListGroupItem: require('./ListGroupItem'), - MenuItem: require('./MenuItem'), - Modal: require('./Modal'), - Nav: require('./Nav'), - Navbar: require('./Navbar'), - NavItem: require('./NavItem'), - ModalTrigger: require('./ModalTrigger'), - OverlayTrigger: require('./OverlayTrigger'), - OverlayMixin: require('./OverlayMixin'), - PageHeader: require('./PageHeader'), - Panel: require('./Panel'), - PanelGroup: require('./PanelGroup'), - PageItem: require('./PageItem'), - Pager: require('./Pager'), - Popover: require('./Popover'), - ProgressBar: require('./ProgressBar'), - Row: require('./Row'), - SplitButton: require('./SplitButton'), - SubNav: require('./SubNav'), - TabbedArea: require('./TabbedArea'), - Table: require('./Table'), - TabPane: require('./TabPane'), - Tooltip: require('./Tooltip'), - Well: require('./Well') -}; + componentDidUpdate: function () { + this._renderOverlay(); + }, -},{"./Accordion":2,"./Affix":3,"./AffixMixin":4,"./Alert":5,"./Badge":6,"./BootstrapMixin":7,"./Button":8,"./ButtonGroup":9,"./ButtonToolbar":10,"./Carousel":11,"./CarouselItem":12,"./Col":13,"./CollapsableMixin":14,"./DropdownButton":15,"./DropdownMenu":16,"./DropdownStateMixin":17,"./FadeMixin":18,"./Glyphicon":19,"./Grid":20,"./Input":21,"./Interpolate":22,"./Jumbotron":23,"./Label":24,"./ListGroup":25,"./ListGroupItem":26,"./MenuItem":27,"./Modal":28,"./ModalTrigger":29,"./Nav":30,"./NavItem":31,"./Navbar":32,"./OverlayMixin":33,"./OverlayTrigger":34,"./PageHeader":35,"./PageItem":36,"./Pager":37,"./Panel":38,"./PanelGroup":39,"./Popover":40,"./ProgressBar":41,"./Row":42,"./SplitButton":43,"./SubNav":44,"./TabPane":45,"./TabbedArea":46,"./Table":47,"./Tooltip":48,"./Well":49}],52:[function(require,module,exports){ -var React = require('react'); + componentDidMount: function () { + this._renderOverlay(); + }, -var ANONYMOUS = '<>'; + _mountOverlayTarget: function () { + this._overlayTarget = document.createElement('div'); + this.getContainerDOMNode() + .appendChild(this._overlayTarget); + }, -var CustomPropTypes = { - /** - * Checks whether a prop provides a DOM element - * - * The element can be provided in two forms: - * - Directly passed - * - Or passed an object which has a `getDOMNode` method which will return the required DOM element - * - * @param props - * @param propName - * @param componentName - * @returns {Error|undefined} - */ - mountable: createMountableChecker() + _renderOverlay: function () { + if (!this._overlayTarget) { + this._mountOverlayTarget(); + } + + // Save reference to help testing + this._overlayInstance = React.render(this.renderOverlay(), this._overlayTarget); + }, + + _unrenderOverlay: function () { + React.unmountComponentAtNode(this._overlayTarget); + this._overlayInstance = null; + }, + + getOverlayDOMNode: function () { + if (!this.isMounted()) { + throw new Error('getOverlayDOMNode(): A component must be mounted to have a DOM node.'); + } + + return this._overlayInstance.getDOMNode(); + }, + + getContainerDOMNode: function () { + return this.props.container.getDOMNode ? + this.props.container.getDOMNode() : this.props.container; + } }; +},{"./utils/CustomPropTypes":57,"react":258}],39:[function(require,module,exports){ +var React = require('react'); +var OverlayMixin = require('./OverlayMixin'); +var domUtils = require('./utils/domUtils'); +var cloneWithProps = require('./utils/cloneWithProps'); + +var createChainedFunction = require('./utils/createChainedFunction'); +var assign = require('./utils/Object.assign'); + /** - * Create chain-able isRequired validator + * Check if value one is inside or equal to the of value * - * Largely copied directly from: - * https://github.com/facebook/react/blob/0.11-stable/src/core/ReactPropTypes.js#L94 + * @param {string} one + * @param {string|array} of + * @returns {boolean} */ -function createChainableTypeChecker(validate) { - function checkType(isRequired, props, propName, componentName) { - componentName = componentName || ANONYMOUS; - if (props[propName] == null) { - if (isRequired) { - return new Error( - 'Required prop `' + propName + '` was not specified in ' + - '`' + componentName + '`.' - ); - } - } else { - return validate(props, propName, componentName); - } +function isOneOf(one, of) { + if (Array.isArray(of)) { + return of.indexOf(one) >= 0; } - - var chainedCheckType = checkType.bind(null, false); - chainedCheckType.isRequired = checkType.bind(null, true); - - return chainedCheckType; + return one === of; } -function createMountableChecker() { - function validate(props, propName, componentName) { - if (typeof props[propName] !== 'object' || - typeof props[propName].getDOMNode !== 'function' && props[propName].nodeType !== 1) { - return new Error( - 'Invalid prop `' + propName + '` supplied to ' + - '`' + componentName + '`, expected a DOM element or an object that has a `getDOMNode` method' - ); - } - } +var OverlayTrigger = React.createClass({displayName: 'OverlayTrigger', + mixins: [OverlayMixin], - return createChainableTypeChecker(validate); -} + propTypes: { + trigger: React.PropTypes.oneOfType([ + React.PropTypes.oneOf(['manual', 'click', 'hover', 'focus']), + React.PropTypes.arrayOf(React.PropTypes.oneOf(['click', 'hover', 'focus'])) + ]), + placement: React.PropTypes.oneOf(['top','right', 'bottom', 'left']), + delay: React.PropTypes.number, + delayShow: React.PropTypes.number, + delayHide: React.PropTypes.number, + defaultOverlayShown: React.PropTypes.bool, + overlay: React.PropTypes.node.isRequired + }, -module.exports = CustomPropTypes; -},{"react":253}],53:[function(require,module,exports){ -/** - * Copyright 2013-2014 Facebook, Inc. - * - * This file contains a modified version of: - * https://github.com/facebook/react/blob/v0.12.0/src/vendor/stubs/EventListener.js - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * TODO: remove in favour of solution provided by: - * https://github.com/facebook/react/issues/285 - */ + getDefaultProps: function () { + return { + placement: 'right', + trigger: ['hover', 'focus'] + }; + }, -/** - * Does not take into account specific nature of platform. - */ -var EventListener = { - /** - * Listen to DOM events during the bubble phase. - * - * @param {DOMEventTarget} target DOM element to register listener on. - * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. - * @param {function} callback Callback function. - * @return {object} Object with a `remove` method. - */ - listen: function(target, eventType, callback) { - if (target.addEventListener) { - target.addEventListener(eventType, callback, false); - return { - remove: function() { - target.removeEventListener(eventType, callback, false); - } - }; - } else if (target.attachEvent) { - target.attachEvent('on' + eventType, callback); - return { - remove: function() { - target.detachEvent('on' + eventType, callback); - } - }; - } - } -}; + getInitialState: function () { + return { + isOverlayShown: this.props.defaultOverlayShown == null ? + false : this.props.defaultOverlayShown, + overlayLeft: null, + overlayTop: null + }; + }, -module.exports = EventListener; + show: function () { + this.setState({ + isOverlayShown: true + }, function() { + this.updateOverlayPosition(); + }); + }, -},{}],54:[function(require,module,exports){ -/** - * Copyright 2014, Facebook, Inc. - * All rights reserved. - * - * This file contains an unmodified version of: - * https://github.com/facebook/react/blob/v0.12.0/src/vendor/stubs/Object.assign.js - * - * This source code is licensed under the BSD-style license found here: - * https://github.com/facebook/react/blob/v0.12.0/LICENSE - * An additional grant of patent rights can be found here: - * https://github.com/facebook/react/blob/v0.12.0/PATENTS - */ + hide: function () { + this.setState({ + isOverlayShown: false + }); + }, -// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign + toggle: function () { + this.state.isOverlayShown ? + this.hide() : this.show(); + }, -function assign(target, sources) { - if (target == null) { - throw new TypeError('Object.assign target cannot be null or undefined'); - } + renderOverlay: function () { + if (!this.state.isOverlayShown) { + return React.createElement("span", null); + } - var to = Object(target); - var hasOwnProperty = Object.prototype.hasOwnProperty; + return cloneWithProps( + this.props.overlay, + { + onRequestHide: this.hide, + placement: this.props.placement, + positionLeft: this.state.overlayLeft, + positionTop: this.state.overlayTop + } + ); + }, - for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { - var nextSource = arguments[nextIndex]; - if (nextSource == null) { - continue; + render: function () { + if (this.props.trigger === 'manual') { + return React.Children.only(this.props.children); } - var from = Object(nextSource); - - // We don't currently support accessors nor proxies. Therefore this - // copy cannot throw. If we ever supported this then we must handle - // exceptions and side-effects. We don't support symbols so they won't - // be transferred. + var props = {}; - for (var key in from) { - if (hasOwnProperty.call(from, key)) { - to[key] = from[key]; - } + if (isOneOf('click', this.props.trigger)) { + props.onClick = createChainedFunction(this.toggle, this.props.onClick); } - } - - return to; -}; -module.exports = assign; + if (isOneOf('hover', this.props.trigger)) { + props.onMouseOver = createChainedFunction(this.handleDelayedShow, this.props.onMouseOver); + props.onMouseOut = createChainedFunction(this.handleDelayedHide, this.props.onMouseOut); + } -},{}],55:[function(require,module,exports){ -/** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This file contains a modified version of: - * https://github.com/facebook/react/blob/v0.12.0/src/addons/transitions/ReactTransitionEvents.js - * - * This source code is licensed under the BSD-style license found here: - * https://github.com/facebook/react/blob/v0.12.0/LICENSE - * An additional grant of patent rights can be found here: - * https://github.com/facebook/react/blob/v0.12.0/PATENTS - */ + if (isOneOf('focus', this.props.trigger)) { + props.onFocus = createChainedFunction(this.handleDelayedShow, this.props.onFocus); + props.onBlur = createChainedFunction(this.handleDelayedHide, this.props.onBlur); + } -var canUseDOM = !!( - typeof window !== 'undefined' && - window.document && - window.document.createElement - ); + return cloneWithProps( + React.Children.only(this.props.children), + props + ); + }, -/** - * EVENT_NAME_MAP is used to determine which event fired when a - * transition/animation ends, based on the style property used to - * define that event. - */ -var EVENT_NAME_MAP = { - transitionend: { - 'transition': 'transitionend', - 'WebkitTransition': 'webkitTransitionEnd', - 'MozTransition': 'mozTransitionEnd', - 'OTransition': 'oTransitionEnd', - 'msTransition': 'MSTransitionEnd' + componentWillUnmount: function() { + clearTimeout(this._hoverDelay); }, - animationend: { - 'animation': 'animationend', - 'WebkitAnimation': 'webkitAnimationEnd', - 'MozAnimation': 'mozAnimationEnd', - 'OAnimation': 'oAnimationEnd', - 'msAnimation': 'MSAnimationEnd' - } -}; + handleDelayedShow: function () { + if (this._hoverDelay != null) { + clearTimeout(this._hoverDelay); + this._hoverDelay = null; + return; + } -var endEvents = []; + var delay = this.props.delayShow != null ? + this.props.delayShow : this.props.delay; -function detectEvents() { - var testEl = document.createElement('div'); - var style = testEl.style; + if (!delay) { + this.show(); + return; + } - // On some platforms, in particular some releases of Android 4.x, - // the un-prefixed "animation" and "transition" properties are defined on the - // style object but the events that fire will still be prefixed, so we need - // to check if the un-prefixed events are useable, and if not remove them - // from the map - if (!('AnimationEvent' in window)) { - delete EVENT_NAME_MAP.animationend.animation; - } - - if (!('TransitionEvent' in window)) { - delete EVENT_NAME_MAP.transitionend.transition; - } + this._hoverDelay = setTimeout(function() { + this._hoverDelay = null; + this.show(); + }.bind(this), delay); + }, - for (var baseEventName in EVENT_NAME_MAP) { - var baseEvents = EVENT_NAME_MAP[baseEventName]; - for (var styleName in baseEvents) { - if (styleName in style) { - endEvents.push(baseEvents[styleName]); - break; - } + handleDelayedHide: function () { + if (this._hoverDelay != null) { + clearTimeout(this._hoverDelay); + this._hoverDelay = null; + return; } - } -} - -if (canUseDOM) { - detectEvents(); -} -// We use the raw {add|remove}EventListener() call because EventListener -// does not know how to remove event listeners and we really should -// clean up. Also, these events are not triggered in older browsers -// so we should be A-OK here. + var delay = this.props.delayHide != null ? + this.props.delayHide : this.props.delay; -function addEventListener(node, eventName, eventListener) { - node.addEventListener(eventName, eventListener, false); -} + if (!delay) { + this.hide(); + return; + } -function removeEventListener(node, eventName, eventListener) { - node.removeEventListener(eventName, eventListener, false); -} + this._hoverDelay = setTimeout(function() { + this._hoverDelay = null; + this.hide(); + }.bind(this), delay); + }, -var ReactTransitionEvents = { - addEndEventListener: function(node, eventListener) { - if (endEvents.length === 0) { - // If CSS transitions are not supported, trigger an "end animation" - // event immediately. - window.setTimeout(eventListener, 0); + updateOverlayPosition: function () { + if (!this.isMounted()) { return; } - endEvents.forEach(function(endEvent) { - addEventListener(node, endEvent, eventListener); + + var pos = this.calcOverlayPosition(); + + this.setState({ + overlayLeft: pos.left, + overlayTop: pos.top }); }, - removeEndEventListener: function(node, eventListener) { - if (endEvents.length === 0) { - return; + calcOverlayPosition: function () { + var childOffset = this.getPosition(); + + var overlayNode = this.getOverlayDOMNode(); + var overlayHeight = overlayNode.offsetHeight; + var overlayWidth = overlayNode.offsetWidth; + + switch (this.props.placement) { + case 'right': + return { + top: childOffset.top + childOffset.height / 2 - overlayHeight / 2, + left: childOffset.left + childOffset.width + }; + case 'left': + return { + top: childOffset.top + childOffset.height / 2 - overlayHeight / 2, + left: childOffset.left - overlayWidth + }; + case 'top': + return { + top: childOffset.top - overlayHeight, + left: childOffset.left + childOffset.width / 2 - overlayWidth / 2 + }; + case 'bottom': + return { + top: childOffset.top + childOffset.height, + left: childOffset.left + childOffset.width / 2 - overlayWidth / 2 + }; + default: + throw new Error('calcOverlayPosition(): No such placement of "' + this.props.placement + '" found.'); } - endEvents.forEach(function(endEvent) { - removeEventListener(node, endEvent, eventListener); + }, + + getPosition: function () { + var node = this.getDOMNode(); + var container = this.getContainerDOMNode(); + + var offset = container.tagName == 'BODY' ? + domUtils.getOffset(node) : domUtils.getPosition(node, container); + + return assign({}, offset, { + height: node.offsetHeight, + width: node.offsetWidth }); } -}; - -module.exports = ReactTransitionEvents; +}); -},{}],56:[function(require,module,exports){ +module.exports = OverlayTrigger; +},{"./OverlayMixin":38,"./utils/Object.assign":59,"./utils/cloneWithProps":63,"./utils/createChainedFunction":64,"./utils/domUtils":65,"react":258}],40:[function(require,module,exports){ var React = require('react'); +var joinClasses = require('./utils/joinClasses'); -/** - * Maps children that are typically specified as `props.children`, - * but only iterates over children that are "valid components". - * - * The mapFunction provided index will be normalised to the components mapped, - * so an invalid component would not increase the index. - * - * @param {?*} children Children tree container. - * @param {function(*, int)} mapFunction. - * @param {*} mapContext Context for mapFunction. - * @return {object} Object containing the ordered map of results. - */ -function mapValidComponents(children, func, context) { - var index = 0; +var PageHeader = React.createClass({displayName: 'PageHeader', - return React.Children.map(children, function (child) { - if (React.isValidElement(child)) { - var lastIndex = index; - index++; - return func.call(context, child, lastIndex); - } + render: function () { + return ( + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, 'page-header')}), + React.createElement("h1", null, this.props.children) + ) + ); + } +}); - return child; - }); -} +module.exports = PageHeader; +},{"./utils/joinClasses":66,"react":258}],41:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); -/** - * Iterates through children that are typically specified as `props.children`, - * but only iterates over children that are "valid components". - * - * The provided forEachFunc(child, index) will be called for each - * leaf child with the index reflecting the position relative to "valid components". - * - * @param {?*} children Children tree container. - * @param {function(*, int)} forEachFunc. - * @param {*} forEachContext Context for forEachContext. - */ -function forEachValidComponents(children, func, context) { - var index = 0; +var PageItem = React.createClass({displayName: 'PageItem', - return React.Children.forEach(children, function (child) { - if (React.isValidElement(child)) { - func.call(context, child, index); - index++; - } - }); -} + propTypes: { + disabled: React.PropTypes.bool, + previous: React.PropTypes.bool, + next: React.PropTypes.bool, + onSelect: React.PropTypes.func, + eventKey: React.PropTypes.any + }, -/** - * Count the number of "valid components" in the Children container. - * - * @param {?*} children Children tree container. - * @returns {number} - */ -function numberOfValidComponents(children) { - var count = 0; + getDefaultProps: function () { + return { + href: '#' + }; + }, - React.Children.forEach(children, function (child) { - if (React.isValidElement(child)) { count++; } - }); + render: function () { + var classes = { + 'disabled': this.props.disabled, + 'previous': this.props.previous, + 'next': this.props.next + }; - return count; -} + return ( + React.createElement("li", React.__spread({}, + this.props, + {className: joinClasses(this.props.className, classSet(classes))}), + React.createElement("a", { + href: this.props.href, + title: this.props.title, + onClick: this.handleSelect, + ref: "anchor"}, + this.props.children + ) + ) + ); + }, -/** - * Determine if the Child container has one or more "valid components". - * - * @param {?*} children Children tree container. - * @returns {boolean} - */ -function hasValidComponent(children) { - var hasValid = false; + handleSelect: function (e) { + if (this.props.onSelect) { + e.preventDefault(); - React.Children.forEach(children, function (child) { - if (!hasValid && React.isValidElement(child)) { - hasValid = true; + if (!this.props.disabled) { + this.props.onSelect(this.props.eventKey, this.props.href); + } } - }); + } +}); - return hasValid; -} +module.exports = PageItem; +},{"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],42:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var cloneWithProps = require('./utils/cloneWithProps'); -module.exports = { - map: mapValidComponents, - forEach: forEachValidComponents, - numberOf: numberOfValidComponents, - hasValidComponent: hasValidComponent -}; -},{"react":253}],57:[function(require,module,exports){ -/** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This file contains an unmodified version of: - * https://github.com/facebook/react/blob/v0.12.0/src/vendor/stubs/cx.js - * - * This source code is licensed under the BSD-style license found here: - * https://github.com/facebook/react/blob/v0.12.0/LICENSE - * An additional grant of patent rights can be found here: - * https://github.com/facebook/react/blob/v0.12.0/PATENTS - */ - -/** - * This function is used to mark string literals representing CSS class names - * so that they can be transformed statically. This allows for modularization - * and minification of CSS class names. - * - * In static_upstream, this function is actually implemented, but it should - * eventually be replaced with something more descriptive, and the transform - * that is used in the main stack should be ported for use elsewhere. - * - * @param string|object className to modularize, or an object of key/values. - * In the object case, the values are conditions that - * determine if the className keys should be included. - * @param [string ...] Variable list of classNames in the string case. - * @return string Renderable space-separated CSS className. - */ -function cx(classNames) { - if (typeof classNames == 'object') { - return Object.keys(classNames).filter(function(className) { - return classNames[className]; - }).join(' '); - } else { - return Array.prototype.join.call(arguments, ' '); - } -} +var ValidComponentChildren = require('./utils/ValidComponentChildren'); +var createChainedFunction = require('./utils/createChainedFunction'); -module.exports = cx; -},{}],58:[function(require,module,exports){ -/** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This file contains modified versions of: - * https://github.com/facebook/react/blob/v0.12.0/src/utils/cloneWithProps.js - * https://github.com/facebook/react/blob/v0.12.0/src/core/ReactPropTransferer.js - * - * This source code is licensed under the BSD-style license found here: - * https://github.com/facebook/react/blob/v0.12.0/LICENSE - * An additional grant of patent rights can be found here: - * https://github.com/facebook/react/blob/v0.12.0/PATENTS - * - * TODO: This should be replaced as soon as cloneWithProps is available via - * the core React package or a separate package. - * @see https://github.com/facebook/react/issues/1906 - */ +var Pager = React.createClass({displayName: 'Pager', -var React = require('react'); -var joinClasses = require('./joinClasses'); -var assign = require("./Object.assign"); + propTypes: { + onSelect: React.PropTypes.func + }, -/** - * Creates a transfer strategy that will merge prop values using the supplied - * `mergeStrategy`. If a prop was previously unset, this just sets it. - * - * @param {function} mergeStrategy - * @return {function} - */ -function createTransferStrategy(mergeStrategy) { - return function(props, key, value) { - if (!props.hasOwnProperty(key)) { - props[key] = value; - } else { - props[key] = mergeStrategy(props[key], value); - } - }; -} + render: function () { + return ( + React.createElement("ul", React.__spread({}, + this.props, + {className: joinClasses(this.props.className, 'pager')}), + ValidComponentChildren.map(this.props.children, this.renderPageItem) + ) + ); + }, -var transferStrategyMerge = createTransferStrategy(function(a, b) { - // `merge` overrides the first object's (`props[key]` above) keys using the - // second object's (`value`) keys. An object's style's existing `propA` would - // get overridden. Flip the order here. - return assign({}, b, a); + renderPageItem: function (child, index) { + return cloneWithProps( + child, + { + onSelect: createChainedFunction(child.props.onSelect, this.props.onSelect), + ref: child.ref, + key: child.key ? child.key : index + } + ); + } }); -function emptyFunction() {} +module.exports = Pager; +},{"./utils/ValidComponentChildren":61,"./utils/cloneWithProps":63,"./utils/createChainedFunction":64,"./utils/joinClasses":66,"react":258}],43:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var cloneWithProps = require('./utils/cloneWithProps'); -/** - * Transfer strategies dictate how props are transferred by `transferPropsTo`. - * NOTE: if you add any more exceptions to this list you should be sure to - * update `cloneWithProps()` accordingly. - */ -var TransferStrategies = { - /** - * Never transfer `children`. - */ - children: emptyFunction, - /** - * Transfer the `className` prop by merging them. - */ - className: createTransferStrategy(joinClasses), - /** - * Transfer the `style` prop (which is an object) by merging them. - */ - style: transferStrategyMerge -}; +var BootstrapMixin = require('./BootstrapMixin'); +var CollapsableMixin = require('./CollapsableMixin'); -/** - * Mutates the first argument by transferring the properties from the second - * argument. - * - * @param {object} props - * @param {object} newProps - * @return {object} - */ -function transferInto(props, newProps) { - for (var thisKey in newProps) { - if (!newProps.hasOwnProperty(thisKey)) { - continue; - } +var Panel = React.createClass({displayName: 'Panel', + mixins: [BootstrapMixin, CollapsableMixin], - var transferStrategy = TransferStrategies[thisKey]; + propTypes: { + onSelect: React.PropTypes.func, + header: React.PropTypes.node, + footer: React.PropTypes.node, + eventKey: React.PropTypes.any + }, - if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) { - transferStrategy(props, thisKey, newProps[thisKey]); - } else if (!props.hasOwnProperty(thisKey)) { - props[thisKey] = newProps[thisKey]; + getDefaultProps: function () { + return { + bsClass: 'panel', + bsStyle: 'default' + }; + }, + + handleSelect: function (e) { + if (this.props.onSelect) { + this._isChanging = true; + this.props.onSelect(this.props.eventKey); + this._isChanging = false; } - } - return props; -} -/** - * Merge two props objects using TransferStrategies. - * - * @param {object} oldProps original props (they take precedence) - * @param {object} newProps new props to merge in - * @return {object} a new object containing both sets of props merged. - */ -function mergeProps(oldProps, newProps) { - return transferInto(assign({}, oldProps), newProps); -} + e.preventDefault(); + this.setState({ + expanded: !this.state.expanded + }); + }, -var ReactPropTransferer = { - mergeProps: mergeProps -}; + shouldComponentUpdate: function () { + return !this._isChanging; + }, -var CHILDREN_PROP = 'children'; + getCollapsableDimensionValue: function () { + return this.refs.body.getDOMNode().offsetHeight; + }, -/** - * Sometimes you want to change the props of a child passed to you. Usually - * this is to add a CSS class. - * - * @param {object} child child component you'd like to clone - * @param {object} props props you'd like to modify. They will be merged - * as if you used `transferPropsTo()`. - * @return {object} a clone of child with props merged in. - */ -function cloneWithProps(child, props) { - var newProps = ReactPropTransferer.mergeProps(props, child.props); + getCollapsableDOMNode: function () { + if (!this.isMounted() || !this.refs || !this.refs.panel) { + return null; + } - // Use `child.props.children` if it is provided. - if (!newProps.hasOwnProperty(CHILDREN_PROP) && - child.props.hasOwnProperty(CHILDREN_PROP)) { - newProps.children = child.props.children; - } + return this.refs.panel.getDOMNode(); + }, - if (React.version.substr(0, 4) === '0.12'){ - var mockLegacyFactory = function(){}; - mockLegacyFactory.isReactLegacyFactory = true; - mockLegacyFactory.type = child.type; + render: function () { + var classes = this.getBsClassSet(); + classes['panel'] = true; - return React.createElement(mockLegacyFactory, newProps); - } + return ( + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes)), + id: this.props.collapsable ? null : this.props.id, onSelect: null}), + this.renderHeading(), + this.props.collapsable ? this.renderCollapsableBody() : this.renderBody(), + this.renderFooter() + ) + ); + }, - // The current API doesn't retain _owner and _context, which is why this - // doesn't use ReactElement.cloneAndReplaceProps. - return React.createElement(child.type, newProps); -} + renderCollapsableBody: function () { + return ( + React.createElement("div", {className: classSet(this.getCollapsableClassSet('panel-collapse')), id: this.props.id, ref: "panel"}, + this.renderBody() + ) + ); + }, -module.exports = cloneWithProps; -},{"./Object.assign":54,"./joinClasses":61,"react":253}],59:[function(require,module,exports){ -/** - * Safe chained function - * - * Will only create a new function if needed, - * otherwise will pass back existing functions or null. - * - * @param {function} one - * @param {function} two - * @returns {function|null} - */ -function createChainedFunction(one, two) { - var hasOne = typeof one === 'function'; - var hasTwo = typeof two === 'function'; - - if (!hasOne && !hasTwo) { return null; } - if (!hasOne) { return two; } - if (!hasTwo) { return one; } - - return function chainedFunction() { - one.apply(this, arguments); - two.apply(this, arguments); - }; -} - -module.exports = createChainedFunction; -},{}],60:[function(require,module,exports){ - -/** - * Shortcut to compute element style - * - * @param {HTMLElement} elem - * @returns {CssStyle} - */ -function getComputedStyles(elem) { - return elem.ownerDocument.defaultView.getComputedStyle(elem, null); -} - -/** - * Get elements offset - * - * TODO: REMOVE JQUERY! - * - * @param {HTMLElement} DOMNode - * @returns {{top: number, left: number}} - */ -function getOffset(DOMNode) { - if (window.jQuery) { - return window.jQuery(DOMNode).offset(); - } - - var docElem = document.documentElement; - var box = { top: 0, left: 0 }; - - // If we don't have gBCR, just use 0,0 rather than error - // BlackBerry 5, iOS 3 (original iPhone) - if ( typeof DOMNode.getBoundingClientRect !== 'undefined' ) { - box = DOMNode.getBoundingClientRect(); - } - - return { - top: box.top + window.pageYOffset - docElem.clientTop, - left: box.left + window.pageXOffset - docElem.clientLeft - }; -} - -/** - * Get elements position - * - * TODO: REMOVE JQUERY! - * - * @param {HTMLElement} elem - * @param {HTMLElement?} offsetParent - * @returns {{top: number, left: number}} - */ -function getPosition(elem, offsetParent) { - if (window.jQuery) { - return window.jQuery(elem).position(); - } - - var offset, - parentOffset = {top: 0, left: 0}; + renderBody: function () { + return ( + React.createElement("div", {className: "panel-body", ref: "body"}, + this.props.children + ) + ); + }, - // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent - if (getComputedStyles(elem).position === 'fixed' ) { - // We assume that getBoundingClientRect is available when computed position is fixed - offset = elem.getBoundingClientRect(); + renderHeading: function () { + var header = this.props.header; - } else { - if (!offsetParent) { - // Get *real* offsetParent - offsetParent = offsetParent(elem); + if (!header) { + return null; } - // Get correct offsets - offset = getOffset(elem); - if ( offsetParent.nodeName !== 'HTML') { - parentOffset = getOffset(offsetParent); + if (!React.isValidElement(header) || Array.isArray(header)) { + header = this.props.collapsable ? + this.renderCollapsableTitle(header) : header; + } else if (this.props.collapsable) { + header = cloneWithProps(header, { + className: 'panel-title', + children: this.renderAnchor(header.props.children) + }); + } else { + header = cloneWithProps(header, { + className: 'panel-title' + }); } - // Add offsetParent borders - parentOffset.top += parseInt(getComputedStyles(offsetParent).borderTopWidth, 10); - parentOffset.left += parseInt(getComputedStyles(offsetParent).borderLeftWidth, 10); - } - - // Subtract parent offsets and element margins - return { - top: offset.top - parentOffset.top - parseInt(getComputedStyles(elem).marginTop, 10), - left: offset.left - parentOffset.left - parseInt(getComputedStyles(elem).marginLeft, 10) - }; -} - -/** - * Get parent element - * - * @param {HTMLElement?} elem - * @returns {HTMLElement} - */ -function offsetParent(elem) { - var docElem = document.documentElement; - var offsetParent = elem.offsetParent || docElem; - - while ( offsetParent && ( offsetParent.nodeName !== 'HTML' && - getComputedStyles(offsetParent).position === 'static' ) ) { - offsetParent = offsetParent.offsetParent; - } - - return offsetParent || docElem; -} + return ( + React.createElement("div", {className: "panel-heading"}, + header + ) + ); + }, -module.exports = { - getComputedStyles: getComputedStyles, - getOffset: getOffset, - getPosition: getPosition, - offsetParent: offsetParent -}; -},{}],61:[function(require,module,exports){ -/** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This file contains an unmodified version of: - * https://github.com/facebook/react/blob/v0.12.0/src/utils/joinClasses.js - * - * This source code is licensed under the BSD-style license found here: - * https://github.com/facebook/react/blob/v0.12.0/LICENSE - * An additional grant of patent rights can be found here: - * https://github.com/facebook/react/blob/v0.12.0/PATENTS - */ + renderAnchor: function (header) { + return ( + React.createElement("a", { + href: '#' + (this.props.id || ''), + className: this.isExpanded() ? null : 'collapsed', + onClick: this.handleSelect}, + header + ) + ); + }, -"use strict"; + renderCollapsableTitle: function (header) { + return ( + React.createElement("h4", {className: "panel-title"}, + this.renderAnchor(header) + ) + ); + }, -/** - * Combines multiple className strings into one. - * http://jsperf.com/joinclasses-args-vs-array - * - * @param {...?string} classes - * @return {string} - */ -function joinClasses(className/*, ... */) { - if (!className) { - className = ''; - } - var nextClass; - var argLength = arguments.length; - if (argLength > 1) { - for (var ii = 1; ii < argLength; ii++) { - nextClass = arguments[ii]; - if (nextClass) { - className = (className ? className + ' ' : '') + nextClass; - } + renderFooter: function () { + if (!this.props.footer) { + return null; } - } - return className; -} -module.exports = joinClasses; + return ( + React.createElement("div", {className: "panel-footer"}, + this.props.footer + ) + ); + } +}); -},{}],62:[function(require,module,exports){ +module.exports = Panel; +},{"./BootstrapMixin":12,"./CollapsableMixin":19,"./utils/classSet":62,"./utils/cloneWithProps":63,"./utils/joinClasses":66,"react":258}],44:[function(require,module,exports){ var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var cloneWithProps = require('./utils/cloneWithProps'); -var Button = require('react-bootstrap/Button'); - -var Navigation = require('react-router/modules/mixins/Navigation'); -var State = require('react-router/modules/mixins/State'); - -var helpers = require('./helpers'); - -ADDITIONAL_RESERVED_PROPS = ['key', 'ref']; +var BootstrapMixin = require('./BootstrapMixin'); +var ValidComponentChildren = require('./utils/ValidComponentChildren'); -var ButtonLink = React.createClass({displayName: 'ButtonLink', - mixins: [State, Navigation], +var PanelGroup = React.createClass({displayName: 'PanelGroup', + mixins: [BootstrapMixin], - additionalReservedProps: ADDITIONAL_RESERVED_PROPS, + propTypes: { + collapsable: React.PropTypes.bool, + activeKey: React.PropTypes.any, + defaultActiveKey: React.PropTypes.any, + onSelect: React.PropTypes.func + }, - getInitialState: function() { + getDefaultProps: function () { return { - href: '#', - isActive: false - } + bsClass: 'panel-group' + }; }, - componentDidMount: function() { - var params = this.getCleanedParams(); - var href = this.makeHref(this.props.to, params, this.props.query || null); - var isActive = this.isActive(this.props.to); + getInitialState: function () { + var defaultActiveKey = this.props.defaultActiveKey; - this.setState({ - href: href, - isActive: isActive - }); + return { + activeKey: defaultActiveKey + }; }, - getCleanedParams: function() { - var reserved = Object.keys(this.refs.button.constructor.propTypes) - .concat(ADDITIONAL_RESERVED_PROPS); + render: function () { + var classes = this.getBsClassSet(); + return ( + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes)), onSelect: null}), + ValidComponentChildren.map(this.props.children, this.renderPanel) + ) + ); + }, - return helpers.withoutProperties(this.props, reserved || []); + renderPanel: function (child, index) { + var activeKey = + this.props.activeKey != null ? this.props.activeKey : this.state.activeKey; + + var props = { + bsStyle: child.props.bsStyle || this.props.bsStyle, + key: child.key ? child.key : index, + ref: child.ref + }; + + if (this.props.accordion) { + props.collapsable = true; + props.expanded = (child.props.eventKey === activeKey); + props.onSelect = this.handleSelect; + } + + return cloneWithProps( + child, + props + ); }, - handleRouteTo: function (e) { - if (helpers.isModifiedEvent(e) || !helpers.isLeftClick(e)) { - return; + shouldComponentUpdate: function() { + // Defer any updates to this component during the `onSelect` handler. + return !this._isChanging; + }, + + handleSelect: function (key) { + if (this.props.onSelect) { + this._isChanging = true; + this.props.onSelect(key); + this._isChanging = false; } - e.preventDefault(); - var params = this.getCleanedParams(); - return this.transitionTo(this.props.to, params, this.props.query || null); + + if (this.state.activeKey === key) { + key = null; + } + + this.setState({ + activeKey: key + }); + } +}); + +module.exports = PanelGroup; +},{"./BootstrapMixin":12,"./utils/ValidComponentChildren":61,"./utils/classSet":62,"./utils/cloneWithProps":63,"./utils/joinClasses":66,"react":258}],45:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var BootstrapMixin = require('./BootstrapMixin'); + + +var Popover = React.createClass({displayName: 'Popover', + mixins: [BootstrapMixin], + + propTypes: { + placement: React.PropTypes.oneOf(['top','right', 'bottom', 'left']), + positionLeft: React.PropTypes.number, + positionTop: React.PropTypes.number, + arrowOffsetLeft: React.PropTypes.number, + arrowOffsetTop: React.PropTypes.number, + title: React.PropTypes.node + }, + + getDefaultProps: function () { + return { + placement: 'right' + }; }, render: function () { + var classes = {}; + classes['popover'] = true; + classes[this.props.placement] = true; + classes['in'] = this.props.positionLeft != null || this.props.positionTop != null; + + var style = {}; + style['left'] = this.props.positionLeft; + style['top'] = this.props.positionTop; + style['display'] = 'block'; + + var arrowStyle = {}; + arrowStyle['left'] = this.props.arrowOffsetLeft; + arrowStyle['top'] = this.props.arrowOffsetTop; + return ( - React.createElement(Button, React.__spread({}, - this.props, - {href: this.state.href, - onClick: this.handleRouteTo, - ref: "button"}), + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes)), style: style, title: null}), + React.createElement("div", {className: "arrow", style: arrowStyle}), + this.props.title ? this.renderTitle() : null, + React.createElement("div", {className: "popover-content"}, this.props.children + ) ) ); + }, + + renderTitle: function() { + return ( + React.createElement("h3", {className: "popover-title"}, this.props.title) + ); } }); -module.exports = ButtonLink; - -},{"./helpers":64,"react":253,"react-bootstrap/Button":8,"react-router/modules/mixins/Navigation":80,"react-router/modules/mixins/State":83}],63:[function(require,module,exports){ +module.exports = Popover; +},{"./BootstrapMixin":12,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],46:[function(require,module,exports){ var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var Interpolate = require('./Interpolate'); +var BootstrapMixin = require('./BootstrapMixin'); +var classSet = require('./utils/classSet'); +var cloneWithProps = require('./utils/cloneWithProps'); -var NavItem = require('react-bootstrap/NavItem') +var ValidComponentChildren = require('./utils/ValidComponentChildren'); -var Navigation = require('react-router/modules/mixins/Navigation'); -var State = require('react-router/modules/mixins/State'); -var helpers = require('./helpers'); +var ProgressBar = React.createClass({displayName: 'ProgressBar', + propTypes: { + min: React.PropTypes.number, + now: React.PropTypes.number, + max: React.PropTypes.number, + label: React.PropTypes.node, + srOnly: React.PropTypes.bool, + striped: React.PropTypes.bool, + active: React.PropTypes.bool + }, -ADDITIONAL_RESERVED_PROPS = [ - 'to', - 'active', - 'activeHref', - 'activeKey', - 'key', - 'navItem', - 'onSelect', - 'ref', - 'children' -]; + mixins: [BootstrapMixin], -var NavItemLink = React.createClass({displayName: 'NavItemLink', - mixins: [State, Navigation], + getDefaultProps: function () { + return { + bsClass: 'progress-bar', + min: 0, + max: 100 + }; + }, - additionalReservedProps: ADDITIONAL_RESERVED_PROPS, + getPercentage: function (now, min, max) { + return Math.ceil((now - min) / (max - min) * 100); + }, - getInitialState: function() { - return { - href: '#', - isActive: false + render: function () { + var classes = { + progress: true + }; + + if (this.props.active) { + classes['progress-striped'] = true; + classes['active'] = true; + } else if (this.props.striped) { + classes['progress-striped'] = true; } - }, - componentDidMount: function() { - var params = this.getCleanedParams(); - var href = this.makeHref(this.props.to, params, this.props.query || null); - var isActive = this.isActive(this.props.to, params, this.props.query || null); + if (!ValidComponentChildren.hasValidComponent(this.props.children)) { + if (!this.props.isChild) { + return ( + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + this.renderProgressBar() + ) + ); + } else { + return ( + this.renderProgressBar() + ); + } + } else { + return ( + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + ValidComponentChildren.map(this.props.children, this.renderChildBar) + ) + ); + } + }, - this.setState({ - href: href, - isActive: isActive + renderChildBar: function (child, index) { + return cloneWithProps(child, { + isChild: true, + key: child.key ? child.key : index, + ref: child.ref }); }, - getCleanedParams: function() { - var reserved = Object.keys(this.refs.navItem.constructor.propTypes) - .concat(this.additionalReservedProps); + renderProgressBar: function () { + var percentage = this.getPercentage( + this.props.now, + this.props.min, + this.props.max + ); - return helpers.withoutProperties(this.props, reserved || []); - }, + var label; - handleRouteTo: function (e) { - if (helpers.isModifiedEvent(e) || !helpers.isLeftClick(e)) { - return; + if (typeof this.props.label === "string") { + label = this.renderLabel(percentage); + } else if (this.props.label) { + label = this.props.label; } - e.preventDefault(); - var params = this.getCleanedParams(); - return this.transitionTo(this.props.to, params, this.props.query || null); + + if (this.props.srOnly) { + label = this.renderScreenReaderOnlyLabel(label); + } + + var classes = this.getBsClassSet(); + + return ( + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes)), role: "progressbar", + style: {width: percentage + '%'}, + 'aria-valuenow': this.props.now, + 'aria-valuemin': this.props.min, + 'aria-valuemax': this.props.max}), + label + ) + ); }, - render: function() { + renderLabel: function (percentage) { + var InterpolateClass = this.props.interpolateClass || Interpolate; + return ( - React.createElement(NavItem, React.__spread({}, - this.props, - {href: this.state.href, - active: this.state.isActive, - onClick: this.handleRouteTo, - ref: "navItem"}), - this.props.children + React.createElement(InterpolateClass, { + now: this.props.now, + min: this.props.min, + max: this.props.max, + percent: percentage, + bsStyle: this.props.bsStyle}, + this.props.label + ) + ); + }, + + renderScreenReaderOnlyLabel: function (label) { + return ( + React.createElement("span", {className: "sr-only"}, + label ) ); } }); -module.exports = NavItemLink; +module.exports = ProgressBar; -},{"./helpers":64,"react":253,"react-bootstrap/NavItem":31,"react-router/modules/mixins/Navigation":80,"react-router/modules/mixins/State":83}],64:[function(require,module,exports){ -exports.isLeftClick = function(event) { - return event.button === 0; -}; +},{"./BootstrapMixin":12,"./Interpolate":27,"./utils/ValidComponentChildren":61,"./utils/classSet":62,"./utils/cloneWithProps":63,"./utils/joinClasses":66,"react":258}],47:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); -exports.isModifiedEvent = function(event) { - return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); -}; +var Row = React.createClass({displayName: 'Row', + propTypes: { + componentClass: React.PropTypes.node.isRequired + }, -exports.withoutProperties = function(object, properties) { - var property, result; - result = {}; - for (property in object) { - if (object.hasOwnProperty(property) && properties.indexOf(property) == -1) { - result[property] = object[property]; - } - } - return result; -}; + getDefaultProps: function () { + return { + componentClass: 'div' + }; + }, -},{}],65:[function(require,module,exports){ -var NavItemLink = require('./NavItemLink'); -var ButtonLink = require('./ButtonLink'); + render: function () { + var ComponentClass = this.props.componentClass; -module.exports = { - NavItemLink: NavItemLink, - ButtonLink: ButtonLink -}; + return ( + React.createElement(ComponentClass, React.__spread({}, this.props, {className: joinClasses(this.props.className, 'row')}), + this.props.children + ) + ); + } +}); -},{"./ButtonLink":62,"./NavItemLink":63}],66:[function(require,module,exports){ -/** - * Actions that modify the URL. - */ -var LocationActions = { +module.exports = Row; +},{"./utils/joinClasses":66,"react":258}],48:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var BootstrapMixin = require('./BootstrapMixin'); +var DropdownStateMixin = require('./DropdownStateMixin'); +var Button = require('./Button'); +var ButtonGroup = require('./ButtonGroup'); +var DropdownMenu = require('./DropdownMenu'); - /** - * Indicates a new location is being pushed to the history stack. - */ - PUSH: 'push', +var SplitButton = React.createClass({displayName: 'SplitButton', + mixins: [BootstrapMixin, DropdownStateMixin], - /** - * Indicates the current location should be replaced. - */ - REPLACE: 'replace', + propTypes: { + pullRight: React.PropTypes.bool, + title: React.PropTypes.node, + href: React.PropTypes.string, + dropdownTitle: React.PropTypes.node, + onClick: React.PropTypes.func, + onSelect: React.PropTypes.func, + disabled: React.PropTypes.bool + }, - /** - * Indicates the most recent entry should be removed from the history stack. - */ - POP: 'pop' + getDefaultProps: function () { + return { + dropdownTitle: 'Toggle dropdown' + }; + }, -}; + render: function () { + var groupClasses = { + 'open': this.state.open, + 'dropup': this.props.dropup + }; -module.exports = LocationActions; + var button = ( + React.createElement(Button, React.__spread({}, + this.props, + {ref: "button", + onClick: this.handleButtonClick, + title: null, + id: null}), + this.props.title + ) + ); -},{}],67:[function(require,module,exports){ -var LocationActions = require('../actions/LocationActions'); + var dropdownButton = ( + React.createElement(Button, React.__spread({}, + this.props, + {ref: "dropdownButton", + className: joinClasses(this.props.className, 'dropdown-toggle'), + onClick: this.handleDropdownClick, + title: null, + id: null}), + React.createElement("span", {className: "sr-only"}, this.props.dropdownTitle), + React.createElement("span", {className: "caret"}) + ) + ); -/** - * A scroll behavior that attempts to imitate the default behavior - * of modern browsers. - */ -var ImitateBrowserBehavior = { + return ( + React.createElement(ButtonGroup, { + bsSize: this.props.bsSize, + className: classSet(groupClasses), + id: this.props.id}, + button, + dropdownButton, + React.createElement(DropdownMenu, { + ref: "menu", + onSelect: this.handleOptionSelect, + 'aria-labelledby': this.props.id, + pullRight: this.props.pullRight}, + this.props.children + ) + ) + ); + }, - updateScrollPosition: function (position, actionType) { - switch (actionType) { - case LocationActions.PUSH: - case LocationActions.REPLACE: - window.scrollTo(0, 0); - break; - case LocationActions.POP: - if (position) { - window.scrollTo(position.x, position.y); - } else { - window.scrollTo(0, 0); - } - break; + handleButtonClick: function (e) { + if (this.state.open) { + this.setDropdownState(false); } - } - -}; - -module.exports = ImitateBrowserBehavior; - -},{"../actions/LocationActions":66}],68:[function(require,module,exports){ -/** - * A scroll behavior that always scrolls to the top of the page - * after a transition. - */ -var ScrollToTopBehavior = { - - updateScrollPosition: function () { - window.scrollTo(0, 0); - } -}; - -module.exports = ScrollToTopBehavior; - -},{}],69:[function(require,module,exports){ -var React = require('react'); -var FakeNode = require('../mixins/FakeNode'); -var PropTypes = require('../utils/PropTypes'); + if (this.props.onClick) { + this.props.onClick(e); + } + }, -/** - * A component is a special kind of that - * renders when its parent matches but none of its siblings do. - * Only one such route may be used at any given level in the - * route hierarchy. - */ -var DefaultRoute = React.createClass({ + handleDropdownClick: function (e) { + e.preventDefault(); - displayName: 'DefaultRoute', + this.setDropdownState(!this.state.open); + }, - mixins: [ FakeNode ], + handleOptionSelect: function (key) { + if (this.props.onSelect) { + this.props.onSelect(key); + } - propTypes: { - name: React.PropTypes.string, - path: PropTypes.falsy, - handler: React.PropTypes.func.isRequired + this.setDropdownState(false); } - }); -module.exports = DefaultRoute; +module.exports = SplitButton; -},{"../mixins/FakeNode":79,"../utils/PropTypes":88,"react":253}],70:[function(require,module,exports){ +},{"./BootstrapMixin":12,"./Button":13,"./ButtonGroup":14,"./DropdownMenu":21,"./DropdownStateMixin":22,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],49:[function(require,module,exports){ var React = require('react'); -var classSet = require('react/lib/cx'); -var assign = require('react/lib/Object.assign'); -var Navigation = require('../mixins/Navigation'); -var State = require('../mixins/State'); - -function isLeftClickEvent(event) { - return event.button === 0; -} - -function isModifiedEvent(event) { - return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); -} +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var cloneWithProps = require('./utils/cloneWithProps'); -/** - * components are used to create an element that links to a route. - * When that route is active, the link gets an "active" class name (or the - * value of its `activeClassName` prop). - * - * For example, assuming you have the following route: - * - * - * - * You could use the following component to link to that route: - * - * - * - * In addition to params, links may pass along query string parameters - * using the `query` prop. - * - * - */ -var Link = React.createClass({ +var ValidComponentChildren = require('./utils/ValidComponentChildren'); +var createChainedFunction = require('./utils/createChainedFunction'); +var BootstrapMixin = require('./BootstrapMixin'); - displayName: 'Link', - mixins: [ Navigation, State ], +var SubNav = React.createClass({displayName: 'SubNav', + mixins: [BootstrapMixin], propTypes: { - activeClassName: React.PropTypes.string.isRequired, - to: React.PropTypes.string.isRequired, - params: React.PropTypes.object, - query: React.PropTypes.object, - onClick: React.PropTypes.func + onSelect: React.PropTypes.func, + active: React.PropTypes.bool, + disabled: React.PropTypes.bool, + href: React.PropTypes.string, + title: React.PropTypes.string, + text: React.PropTypes.node }, getDefaultProps: function () { return { - activeClassName: 'active' + bsClass: 'nav' }; }, - handleClick: function (event) { - var allowTransition = true; - var clickResult; + handleClick: function (e) { + if (this.props.onSelect) { + e.preventDefault(); - if (this.props.onClick) - clickResult = this.props.onClick(event); + if (!this.props.disabled) { + this.props.onSelect(this.props.eventKey, this.props.href); + } + } + }, - if (isModifiedEvent(event) || !isLeftClickEvent(event)) - return; + isActive: function () { + return this.isChildActive(this); + }, - if (clickResult === false || event.defaultPrevented === true) - allowTransition = false; + isChildActive: function (child) { + if (child.props.active) { + return true; + } - event.preventDefault(); + if (this.props.activeKey != null && this.props.activeKey === child.props.eventKey) { + return true; + } - if (allowTransition) - this.transitionTo(this.props.to, this.props.params, this.props.query); - }, + if (this.props.activeHref != null && this.props.activeHref === child.props.href) { + return true; + } - /** - * Returns the value of the "href" attribute to use on the DOM element. - */ - getHref: function () { - return this.makeHref(this.props.to, this.props.params, this.props.query); - }, + if (child.props.children) { + var isActive = false; - /** - * Returns the value of the "class" attribute to use on the DOM element, which contains - * the value of the activeClassName property when this is active. - */ - getClassName: function () { - var classNames = {}; + ValidComponentChildren.forEach( + child.props.children, + function (child) { + if (this.isChildActive(child)) { + isActive = true; + } + }, + this + ); - if (this.props.className) - classNames[this.props.className] = true; + return isActive; + } - if (this.isActive(this.props.to, this.props.params, this.props.query)) - classNames[this.props.activeClassName] = true; + return false; + }, - return classSet(classNames); + getChildActiveProp: function (child) { + if (child.props.active) { + return true; + } + if (this.props.activeKey != null) { + if (child.props.eventKey == this.props.activeKey) { + return true; + } + } + if (this.props.activeHref != null) { + if (child.props.href === this.props.activeHref) { + return true; + } + } + + return child.props.active; }, render: function () { - var props = assign({}, this.props, { - href: this.getHref(), - className: this.getClassName(), - onClick: this.handleClick - }); + var classes = { + 'active': this.isActive(), + 'disabled': this.props.disabled + }; - return React.DOM.a(props, this.props.children); - } + return ( + React.createElement("li", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + React.createElement("a", { + href: this.props.href, + title: this.props.title, + onClick: this.handleClick, + ref: "anchor"}, + this.props.text + ), + React.createElement("ul", {className: "nav"}, + ValidComponentChildren.map(this.props.children, this.renderNavItem) + ) + ) + ); + }, + renderNavItem: function (child, index) { + return cloneWithProps( + child, + { + active: this.getChildActiveProp(child), + onSelect: createChainedFunction(child.props.onSelect, this.props.onSelect), + ref: child.ref, + key: child.key ? child.key : index + } + ); + } }); -module.exports = Link; +module.exports = SubNav; -},{"../mixins/Navigation":80,"../mixins/State":83,"react":253,"react/lib/Object.assign":132,"react/lib/cx":211}],71:[function(require,module,exports){ +},{"./BootstrapMixin":12,"./utils/ValidComponentChildren":61,"./utils/classSet":62,"./utils/cloneWithProps":63,"./utils/createChainedFunction":64,"./utils/joinClasses":66,"react":258}],50:[function(require,module,exports){ var React = require('react'); -var FakeNode = require('../mixins/FakeNode'); -var PropTypes = require('../utils/PropTypes'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var TransitionEvents = require('./utils/TransitionEvents'); -/** - * A is a special kind of that - * renders when the beginning of its parent's path matches - * but none of its siblings do, including any . - * Only one such route may be used at any given level in the - * route hierarchy. - */ -var NotFoundRoute = React.createClass({ +var TabPane = React.createClass({displayName: 'TabPane', + getDefaultProps: function () { + return { + animation: true + }; + }, - displayName: 'NotFoundRoute', + getInitialState: function () { + return { + animateIn: false, + animateOut: false + }; + }, - mixins: [ FakeNode ], + componentWillReceiveProps: function (nextProps) { + if (this.props.animation) { + if (!this.state.animateIn && nextProps.active && !this.props.active) { + this.setState({ + animateIn: true + }); + } else if (!this.state.animateOut && !nextProps.active && this.props.active) { + this.setState({ + animateOut: true + }); + } + } + }, - propTypes: { - name: React.PropTypes.string, - path: PropTypes.falsy, - handler: React.PropTypes.func.isRequired - } + componentDidUpdate: function () { + if (this.state.animateIn) { + setTimeout(this.startAnimateIn, 0); + } + if (this.state.animateOut) { + TransitionEvents.addEndEventListener( + this.getDOMNode(), + this.stopAnimateOut + ); + } + }, -}); + startAnimateIn: function () { + if (this.isMounted()) { + this.setState({ + animateIn: false + }); + } + }, -module.exports = NotFoundRoute; + stopAnimateOut: function () { + if (this.isMounted()) { + this.setState({ + animateOut: false + }); -},{"../mixins/FakeNode":79,"../utils/PropTypes":88,"react":253}],72:[function(require,module,exports){ -var React = require('react'); -var FakeNode = require('../mixins/FakeNode'); -var PropTypes = require('../utils/PropTypes'); + if (typeof this.props.onAnimateOutEnd === 'function') { + this.props.onAnimateOutEnd(); + } + } + }, -/** - * A component is a special kind of that always - * redirects to another route when it matches. - */ -var Redirect = React.createClass({ + render: function () { + var classes = { + 'tab-pane': true, + 'fade': true, + 'active': this.props.active || this.state.animateOut, + 'in': this.props.active && !this.state.animateIn + }; - displayName: 'Redirect', + return ( + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + this.props.children + ) + ); + } +}); - mixins: [ FakeNode ], +module.exports = TabPane; +},{"./utils/TransitionEvents":60,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],51:[function(require,module,exports){ +var React = require('react'); +var BootstrapMixin = require('./BootstrapMixin'); +var cloneWithProps = require('./utils/cloneWithProps'); - propTypes: { - path: React.PropTypes.string, - from: React.PropTypes.string, // Alias for path. - to: React.PropTypes.string, - handler: PropTypes.falsy - } +var ValidComponentChildren = require('./utils/ValidComponentChildren'); +var Nav = require('./Nav'); +var NavItem = require('./NavItem'); -}); +function getDefaultActiveKeyFromChildren(children) { + var defaultActiveKey; -module.exports = Redirect; + ValidComponentChildren.forEach(children, function(child) { + if (defaultActiveKey == null) { + defaultActiveKey = child.props.eventKey; + } + }); -},{"../mixins/FakeNode":79,"../utils/PropTypes":88,"react":253}],73:[function(require,module,exports){ -var React = require('react'); -var FakeNode = require('../mixins/FakeNode'); + return defaultActiveKey; +} -/** - * components specify components that are rendered to the page when the - * URL matches a given pattern. - * - * Routes are arranged in a nested tree structure. When a new URL is requested, - * the tree is searched depth-first to find a route whose path matches the URL. - * When one is found, all routes in the tree that lead to it are considered - * "active" and their components are rendered into the DOM, nested in the same - * order as they are in the tree. - * - * The preferred way to configure a router is using JSX. The XML-like syntax is - * a great way to visualize how routes are laid out in an application. - * - * var routes = [ - * - * - * - * - * - * ]; - * - * Router.run(routes, function (Handler) { - * React.render(, document.body); - * }); - * - * Handlers for Route components that contain children can render their active - * child route using a element. - * - * var App = React.createClass({ - * render: function () { - * return ( - *
- * - *
- * ); - * } - * }); - */ -var Route = React.createClass({ - - displayName: 'Route', - - mixins: [ FakeNode ], +var TabbedArea = React.createClass({displayName: 'TabbedArea', + mixins: [BootstrapMixin], propTypes: { - name: React.PropTypes.string, - path: React.PropTypes.string, - handler: React.PropTypes.func.isRequired, - ignoreScrollBehavior: React.PropTypes.bool - } - -}); - -module.exports = Route; - -},{"../mixins/FakeNode":79,"react":253}],74:[function(require,module,exports){ -var React = require('react'); - -/** - * A component renders the active child route handler - * when routes are nested. - */ -var RouteHandler = React.createClass({ - - displayName: 'RouteHandler', + bsStyle: React.PropTypes.oneOf(['tabs','pills']), + animation: React.PropTypes.bool, + onSelect: React.PropTypes.func + }, getDefaultProps: function () { return { - ref: '__routeHandler__' + bsStyle: "tabs", + animation: true }; }, - contextTypes: { - getRouteAtDepth: React.PropTypes.func.isRequired, - getRouteComponents: React.PropTypes.func.isRequired, - routeHandlers: React.PropTypes.array.isRequired - }, + getInitialState: function () { + var defaultActiveKey = this.props.defaultActiveKey != null ? + this.props.defaultActiveKey : getDefaultActiveKeyFromChildren(this.props.children); - childContextTypes: { - routeHandlers: React.PropTypes.array.isRequired - }, + // TODO: In __DEV__ mode warn via `console.warn` if no `defaultActiveKey` has + // been set by this point, invalid children or missing key properties are likely the cause. - getChildContext: function () { return { - routeHandlers: this.context.routeHandlers.concat([ this ]) + activeKey: defaultActiveKey, + previousActiveKey: null }; }, - getRouteDepth: function () { - return this.context.routeHandlers.length - 1; - }, - - componentDidMount: function () { - this._updateRouteComponent(); - }, - - componentDidUpdate: function () { - this._updateRouteComponent(); + componentWillReceiveProps: function (nextProps) { + if (nextProps.activeKey != null && nextProps.activeKey !== this.props.activeKey) { + this.setState({ + previousActiveKey: this.props.activeKey + }); + } }, - _updateRouteComponent: function () { - var depth = this.getRouteDepth(); - var components = this.context.getRouteComponents(); - components[depth] = this.refs[this.props.ref]; + handlePaneAnimateOutEnd: function () { + this.setState({ + previousActiveKey: null + }); }, render: function () { - var route = this.context.getRouteAtDepth(this.getRouteDepth()); - return route ? React.createElement(route.handler, this.props) : null; - } + var activeKey = + this.props.activeKey != null ? this.props.activeKey : this.state.activeKey; -}); + function renderTabIfSet(child) { + return child.props.tab != null ? this.renderTab(child) : null; + } -module.exports = RouteHandler; + var nav = ( + React.createElement(Nav, React.__spread({}, this.props, {activeKey: activeKey, onSelect: this.handleSelect, ref: "tabs"}), + ValidComponentChildren.map(this.props.children, renderTabIfSet, this) + ) + ); -},{"react":253}],75:[function(require,module,exports){ -exports.DefaultRoute = require('./components/DefaultRoute'); -exports.Link = require('./components/Link'); -exports.NotFoundRoute = require('./components/NotFoundRoute'); -exports.Redirect = require('./components/Redirect'); -exports.Route = require('./components/Route'); -exports.RouteHandler = require('./components/RouteHandler'); + return ( + React.createElement("div", null, + nav, + React.createElement("div", {id: this.props.id, className: "tab-content", ref: "panes"}, + ValidComponentChildren.map(this.props.children, this.renderPane) + ) + ) + ); + }, -exports.HashLocation = require('./locations/HashLocation'); -exports.HistoryLocation = require('./locations/HistoryLocation'); -exports.RefreshLocation = require('./locations/RefreshLocation'); + getActiveKey: function () { + return this.props.activeKey != null ? this.props.activeKey : this.state.activeKey; + }, -exports.ImitateBrowserBehavior = require('./behaviors/ImitateBrowserBehavior'); -exports.ScrollToTopBehavior = require('./behaviors/ScrollToTopBehavior'); + renderPane: function (child, index) { + var activeKey = this.getActiveKey(); -exports.Navigation = require('./mixins/Navigation'); -exports.State = require('./mixins/State'); + return cloneWithProps( + child, + { + active: (child.props.eventKey === activeKey && + (this.state.previousActiveKey == null || !this.props.animation)), + ref: child.ref, + key: child.key ? child.key : index, + animation: this.props.animation, + onAnimateOutEnd: (this.state.previousActiveKey != null && + child.props.eventKey === this.state.previousActiveKey) ? this.handlePaneAnimateOutEnd: null + } + ); + }, -exports.create = require('./utils/createRouter'); -exports.run = require('./utils/runRouter'); + renderTab: function (child) { + var key = child.props.eventKey; + return ( + React.createElement(NavItem, { + ref: 'tab' + key, + eventKey: key}, + child.props.tab + ) + ); + }, -},{"./behaviors/ImitateBrowserBehavior":67,"./behaviors/ScrollToTopBehavior":68,"./components/DefaultRoute":69,"./components/Link":70,"./components/NotFoundRoute":71,"./components/Redirect":72,"./components/Route":73,"./components/RouteHandler":74,"./locations/HashLocation":76,"./locations/HistoryLocation":77,"./locations/RefreshLocation":78,"./mixins/Navigation":80,"./mixins/State":83,"./utils/createRouter":91,"./utils/runRouter":95}],76:[function(require,module,exports){ -var invariant = require('react/lib/invariant'); -var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; -var LocationActions = require('../actions/LocationActions'); -var Path = require('../utils/Path'); + shouldComponentUpdate: function() { + // Defer any updates to this component during the `onSelect` handler. + return !this._isChanging; + }, -/** - * Returns the current URL path from `window.location.hash`, including query string - */ -function getHashPath() { - invariant( - canUseDOM, - 'getHashPath needs a DOM' - ); + handleSelect: function (key) { + if (this.props.onSelect) { + this._isChanging = true; + this.props.onSelect(key); + this._isChanging = false; + } else if (key !== this.getActiveKey()) { + this.setState({ + activeKey: key, + previousActiveKey: this.getActiveKey() + }); + } + } +}); - return Path.decode( - window.location.hash.substr(1) - ); -} +module.exports = TabbedArea; +},{"./BootstrapMixin":12,"./Nav":35,"./NavItem":36,"./utils/ValidComponentChildren":61,"./utils/cloneWithProps":63,"react":258}],52:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); -var _actionType; +var Table = React.createClass({displayName: 'Table', + propTypes: { + striped: React.PropTypes.bool, + bordered: React.PropTypes.bool, + condensed: React.PropTypes.bool, + hover: React.PropTypes.bool, + responsive: React.PropTypes.bool + }, -function ensureSlash() { - var path = getHashPath(); + render: function () { + var classes = { + 'table': true, + 'table-striped': this.props.striped, + 'table-bordered': this.props.bordered, + 'table-condensed': this.props.condensed, + 'table-hover': this.props.hover + }; + var table = ( + React.createElement("table", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + this.props.children + ) + ); - if (path.charAt(0) === '/') - return true; + return this.props.responsive ? ( + React.createElement("div", {className: "table-responsive"}, + table + ) + ) : table; + } +}); - HashLocation.replace('/' + path); +module.exports = Table; +},{"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],53:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var BootstrapMixin = require('./BootstrapMixin'); - return false; -} -var _changeListeners = []; +var Tooltip = React.createClass({displayName: 'Tooltip', + mixins: [BootstrapMixin], -function notifyChange(type) { - var change = { - path: getHashPath(), - type: type - }; - - _changeListeners.forEach(function (listener) { - listener(change); - }); -} - -var _isListening = false; - -function onHashChange() { - if (ensureSlash()) { - // If we don't have an _actionType then all we know is the hash - // changed. It was probably caused by the user clicking the Back - // button, but may have also been the Forward button or manual - // manipulation. So just guess 'pop'. - notifyChange(_actionType || LocationActions.POP); - _actionType = null; - } -} - -/** - * A Location that uses `window.location.hash`. - */ -var HashLocation = { - - addChangeListener: function (listener) { - _changeListeners.push(listener); - - // Do this BEFORE listening for hashchange. - ensureSlash(); - - if (_isListening) - return; - - if (window.addEventListener) { - window.addEventListener('hashchange', onHashChange, false); - } else { - window.attachEvent('onhashchange', onHashChange); - } - - _isListening = true; + propTypes: { + placement: React.PropTypes.oneOf(['top','right', 'bottom', 'left']), + positionLeft: React.PropTypes.number, + positionTop: React.PropTypes.number, + arrowOffsetLeft: React.PropTypes.number, + arrowOffsetTop: React.PropTypes.number }, - push: function (path) { - _actionType = LocationActions.PUSH; - window.location.hash = Path.encode(path); + getDefaultProps: function () { + return { + placement: 'right' + }; }, - replace: function (path) { - _actionType = LocationActions.REPLACE; - window.location.replace(window.location.pathname + '#' + Path.encode(path)); - }, + render: function () { + var classes = {}; + classes['tooltip'] = true; + classes[this.props.placement] = true; + classes['in'] = this.props.positionLeft != null || this.props.positionTop != null; - pop: function () { - _actionType = LocationActions.POP; - window.history.back(); - }, + var style = {}; + style['left'] = this.props.positionLeft; + style['top'] = this.props.positionTop; - getCurrentPath: getHashPath, + var arrowStyle = {}; + arrowStyle['left'] = this.props.arrowOffsetLeft; + arrowStyle['top'] = this.props.arrowOffsetTop; - toString: function () { - return ''; + return ( + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes)), style: style}), + React.createElement("div", {className: "tooltip-arrow", style: arrowStyle}), + React.createElement("div", {className: "tooltip-inner"}, + this.props.children + ) + ) + ); } +}); -}; - -module.exports = HashLocation; - -},{"../actions/LocationActions":66,"../utils/Path":86,"react/lib/ExecutionEnvironment":127,"react/lib/invariant":233}],77:[function(require,module,exports){ -var invariant = require('react/lib/invariant'); -var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; -var LocationActions = require('../actions/LocationActions'); -var Path = require('../utils/Path'); - -/** - * Returns the current URL path from `window.location`, including query string - */ -function getWindowPath() { - invariant( - canUseDOM, - 'getWindowPath needs a DOM' - ); - - return Path.decode( - window.location.pathname + window.location.search - ); -} - -var _changeListeners = []; - -function notifyChange(type) { - var change = { - path: getWindowPath(), - type: type - }; - - _changeListeners.forEach(function (listener) { - listener(change); - }); -} - -var _isListening = false; - -function onPopState() { - notifyChange(LocationActions.POP); -} - -/** - * A Location that uses HTML5 history. - */ -var HistoryLocation = { - - addChangeListener: function (listener) { - _changeListeners.push(listener); - - if (_isListening) - return; - - if (window.addEventListener) { - window.addEventListener('popstate', onPopState, false); - } else { - window.attachEvent('popstate', onPopState); - } - - _isListening = true; - }, - - push: function (path) { - window.history.pushState({ path: path }, '', Path.encode(path)); - notifyChange(LocationActions.PUSH); - }, +module.exports = Tooltip; +},{"./BootstrapMixin":12,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],54:[function(require,module,exports){ +var React = require('react'); +var joinClasses = require('./utils/joinClasses'); +var classSet = require('./utils/classSet'); +var BootstrapMixin = require('./BootstrapMixin'); - replace: function (path) { - window.history.replaceState({ path: path }, '', Path.encode(path)); - notifyChange(LocationActions.REPLACE); - }, +var Well = React.createClass({displayName: 'Well', + mixins: [BootstrapMixin], - pop: function () { - window.history.back(); + getDefaultProps: function () { + return { + bsClass: 'well' + }; }, - getCurrentPath: getWindowPath, + render: function () { + var classes = this.getBsClassSet(); - toString: function () { - return ''; + return ( + React.createElement("div", React.__spread({}, this.props, {className: joinClasses(this.props.className, classSet(classes))}), + this.props.children + ) + ); } +}); -}; - -module.exports = HistoryLocation; - -},{"../actions/LocationActions":66,"../utils/Path":86,"react/lib/ExecutionEnvironment":127,"react/lib/invariant":233}],78:[function(require,module,exports){ -var HistoryLocation = require('./HistoryLocation'); -var Path = require('../utils/Path'); - -/** - * A Location that uses full page refreshes. This is used as - * the fallback for HistoryLocation in browsers that do not - * support the HTML5 history API. - */ -var RefreshLocation = { - - push: function (path) { - window.location = Path.encode(path); +module.exports = Well; +},{"./BootstrapMixin":12,"./utils/classSet":62,"./utils/joinClasses":66,"react":258}],55:[function(require,module,exports){ +module.exports = { + CLASSES: { + 'alert': 'alert', + 'button': 'btn', + 'button-group': 'btn-group', + 'button-toolbar': 'btn-toolbar', + 'column': 'col', + 'input-group': 'input-group', + 'form': 'form', + 'glyphicon': 'glyphicon', + 'label': 'label', + 'list-group-item': 'list-group-item', + 'panel': 'panel', + 'panel-group': 'panel-group', + 'progress-bar': 'progress-bar', + 'nav': 'nav', + 'navbar': 'navbar', + 'modal': 'modal', + 'row': 'row', + 'well': 'well' }, - - replace: function (path) { - window.location.replace(Path.encode(path)); + STYLES: { + 'default': 'default', + 'primary': 'primary', + 'success': 'success', + 'info': 'info', + 'warning': 'warning', + 'danger': 'danger', + 'link': 'link', + 'inline': 'inline', + 'tabs': 'tabs', + 'pills': 'pills' }, - - pop: function () { - window.history.back(); + SIZES: { + 'large': 'lg', + 'medium': 'md', + 'small': 'sm', + 'xsmall': 'xs' }, + GLYPHS: [ + 'asterisk', + 'plus', + 'euro', + 'minus', + 'cloud', + 'envelope', + 'pencil', + 'glass', + 'music', + 'search', + 'heart', + 'star', + 'star-empty', + 'user', + 'film', + 'th-large', + 'th', + 'th-list', + 'ok', + 'remove', + 'zoom-in', + 'zoom-out', + 'off', + 'signal', + 'cog', + 'trash', + 'home', + 'file', + 'time', + 'road', + 'download-alt', + 'download', + 'upload', + 'inbox', + 'play-circle', + 'repeat', + 'refresh', + 'list-alt', + 'lock', + 'flag', + 'headphones', + 'volume-off', + 'volume-down', + 'volume-up', + 'qrcode', + 'barcode', + 'tag', + 'tags', + 'book', + 'bookmark', + 'print', + 'camera', + 'font', + 'bold', + 'italic', + 'text-height', + 'text-width', + 'align-left', + 'align-center', + 'align-right', + 'align-justify', + 'list', + 'indent-left', + 'indent-right', + 'facetime-video', + 'picture', + 'map-marker', + 'adjust', + 'tint', + 'edit', + 'share', + 'check', + 'move', + 'step-backward', + 'fast-backward', + 'backward', + 'play', + 'pause', + 'stop', + 'forward', + 'fast-forward', + 'step-forward', + 'eject', + 'chevron-left', + 'chevron-right', + 'plus-sign', + 'minus-sign', + 'remove-sign', + 'ok-sign', + 'question-sign', + 'info-sign', + 'screenshot', + 'remove-circle', + 'ok-circle', + 'ban-circle', + 'arrow-left', + 'arrow-right', + 'arrow-up', + 'arrow-down', + 'share-alt', + 'resize-full', + 'resize-small', + 'exclamation-sign', + 'gift', + 'leaf', + 'fire', + 'eye-open', + 'eye-close', + 'warning-sign', + 'plane', + 'calendar', + 'random', + 'comment', + 'magnet', + 'chevron-up', + 'chevron-down', + 'retweet', + 'shopping-cart', + 'folder-close', + 'folder-open', + 'resize-vertical', + 'resize-horizontal', + 'hdd', + 'bullhorn', + 'bell', + 'certificate', + 'thumbs-up', + 'thumbs-down', + 'hand-right', + 'hand-left', + 'hand-up', + 'hand-down', + 'circle-arrow-right', + 'circle-arrow-left', + 'circle-arrow-up', + 'circle-arrow-down', + 'globe', + 'wrench', + 'tasks', + 'filter', + 'briefcase', + 'fullscreen', + 'dashboard', + 'paperclip', + 'heart-empty', + 'link', + 'phone', + 'pushpin', + 'usd', + 'gbp', + 'sort', + 'sort-by-alphabet', + 'sort-by-alphabet-alt', + 'sort-by-order', + 'sort-by-order-alt', + 'sort-by-attributes', + 'sort-by-attributes-alt', + 'unchecked', + 'expand', + 'collapse-down', + 'collapse-up', + 'log-in', + 'flash', + 'log-out', + 'new-window', + 'record', + 'save', + 'open', + 'saved', + 'import', + 'export', + 'send', + 'floppy-disk', + 'floppy-saved', + 'floppy-remove', + 'floppy-save', + 'floppy-open', + 'credit-card', + 'transfer', + 'cutlery', + 'header', + 'compressed', + 'earphone', + 'phone-alt', + 'tower', + 'stats', + 'sd-video', + 'hd-video', + 'subtitles', + 'sound-stereo', + 'sound-dolby', + 'sound-5-1', + 'sound-6-1', + 'sound-7-1', + 'copyright-mark', + 'registration-mark', + 'cloud-download', + 'cloud-upload', + 'tree-conifer', + 'tree-deciduous' + ] +}; - getCurrentPath: HistoryLocation.getCurrentPath, - - toString: function () { - return ''; - } - -}; - -module.exports = RefreshLocation; - -},{"../utils/Path":86,"./HistoryLocation":77}],79:[function(require,module,exports){ -var invariant = require('react/lib/invariant'); - -var FakeNode = { - - render: function () { - invariant( - false, - '%s elements should not be rendered', - this.constructor.displayName - ); - } - -}; - -module.exports = FakeNode; - -},{"react/lib/invariant":233}],80:[function(require,module,exports){ -var React = require('react'); - -/** - * A mixin for components that modify the URL. - * - * Example: - * - * var MyLink = React.createClass({ - * mixins: [ Router.Navigation ], - * handleClick: function (event) { - * event.preventDefault(); - * this.transitionTo('aRoute', { the: 'params' }, { the: 'query' }); - * }, - * render: function () { - * return ( - *
Click me! - * ); - * } - * }); - */ -var Navigation = { - - contextTypes: { - makePath: React.PropTypes.func.isRequired, - makeHref: React.PropTypes.func.isRequired, - transitionTo: React.PropTypes.func.isRequired, - replaceWith: React.PropTypes.func.isRequired, - goBack: React.PropTypes.func.isRequired - }, - - /** - * Returns an absolute URL path created from the given route - * name, URL parameters, and query values. - */ - makePath: function (to, params, query) { - return this.context.makePath(to, params, query); - }, - - /** - * Returns a string that may safely be used as the href of a - * link to the route with the given name. - */ - makeHref: function (to, params, query) { - return this.context.makeHref(to, params, query); - }, - - /** - * Transitions to the URL specified in the arguments by pushing - * a new URL onto the history stack. - */ - transitionTo: function (to, params, query) { - this.context.transitionTo(to, params, query); - }, - - /** - * Transitions to the URL specified in the arguments by replacing - * the current URL in the history stack. - */ - replaceWith: function (to, params, query) { - this.context.replaceWith(to, params, query); - }, - - /** - * Transitions to the previous URL. - */ - goBack: function () { - this.context.goBack(); - } - -}; - -module.exports = Navigation; - -},{"react":253}],81:[function(require,module,exports){ -var React = require('react'); - -/** - * Provides the router with context for Router.Navigation. - */ -var NavigationContext = { - - childContextTypes: { - makePath: React.PropTypes.func.isRequired, - makeHref: React.PropTypes.func.isRequired, - transitionTo: React.PropTypes.func.isRequired, - replaceWith: React.PropTypes.func.isRequired, - goBack: React.PropTypes.func.isRequired - }, - - getChildContext: function () { - return { - makePath: this.constructor.makePath, - makeHref: this.constructor.makeHref, - transitionTo: this.constructor.transitionTo, - replaceWith: this.constructor.replaceWith, - goBack: this.constructor.goBack - }; - } - -}; - -module.exports = NavigationContext; - -},{"react":253}],82:[function(require,module,exports){ -var invariant = require('react/lib/invariant'); -var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; -var getWindowScrollPosition = require('../utils/getWindowScrollPosition'); - -function shouldUpdateScroll(state, prevState) { - if (!prevState) - return true; - - // Don't update scroll position when only the query has changed. - if (state.pathname === prevState.pathname) - return false; - - var routes = state.routes; - var prevRoutes = prevState.routes; - - var sharedAncestorRoutes = routes.filter(function (route) { - return prevRoutes.indexOf(route) !== -1; - }); - - return !sharedAncestorRoutes.some(function (route) { - return route.ignoreScrollBehavior; - }); -} - -/** - * Provides the router with the ability to manage window scroll position - * according to its scroll behavior. - */ -var Scrolling = { - - statics: { - /** - * Records curent scroll position as the last known position for the given URL path. - */ - recordScrollPosition: function (path) { - if (!this.scrollHistory) - this.scrollHistory = {}; - - this.scrollHistory[path] = getWindowScrollPosition(); - }, - - /** - * Returns the last known scroll position for the given URL path. - */ - getScrollPosition: function (path) { - if (!this.scrollHistory) - this.scrollHistory = {}; - - return this.scrollHistory[path] || null; - } - }, - - componentWillMount: function () { - invariant( - this.getScrollBehavior() == null || canUseDOM, - 'Cannot use scroll behavior without a DOM' - ); - }, - - componentDidMount: function () { - this._updateScroll(); - }, - - componentDidUpdate: function (prevProps, prevState) { - this._updateScroll(prevState); - }, - - _updateScroll: function (prevState) { - if (!shouldUpdateScroll(this.state, prevState)) - return; - - var scrollBehavior = this.getScrollBehavior(); - - if (scrollBehavior) - scrollBehavior.updateScrollPosition( - this.constructor.getScrollPosition(this.state.path), - this.state.action - ); - } - -}; - -module.exports = Scrolling; - -},{"../utils/getWindowScrollPosition":93,"react/lib/ExecutionEnvironment":127,"react/lib/invariant":233}],83:[function(require,module,exports){ -var React = require('react'); - -/** - * A mixin for components that need to know the path, routes, URL - * params and query that are currently active. - * - * Example: - * - * var AboutLink = React.createClass({ - * mixins: [ Router.State ], - * render: function () { - * var className = this.props.className; - * - * if (this.isActive('about')) - * className += ' is-active'; - * - * return React.DOM.a({ className: className }, this.props.children); - * } - * }); - */ -var State = { - - contextTypes: { - getCurrentPath: React.PropTypes.func.isRequired, - getCurrentRoutes: React.PropTypes.func.isRequired, - getCurrentPathname: React.PropTypes.func.isRequired, - getCurrentParams: React.PropTypes.func.isRequired, - getCurrentQuery: React.PropTypes.func.isRequired, - isActive: React.PropTypes.func.isRequired - }, - - /** - * Returns the current URL path. - */ - getPath: function () { - return this.context.getCurrentPath(); - }, - - /** - * Returns an array of the routes that are currently active. - */ - getRoutes: function () { - return this.context.getCurrentRoutes(); - }, - - /** - * Returns the current URL path without the query string. - */ - getPathname: function () { - return this.context.getCurrentPathname(); - }, - - /** - * Returns an object of the URL params that are currently active. - */ - getParams: function () { - return this.context.getCurrentParams(); - }, - - /** - * Returns an object of the query params that are currently active. - */ - getQuery: function () { - return this.context.getCurrentQuery(); - }, - - /** - * A helper method to determine if a given route, params, and query - * are active. - */ - isActive: function (to, params, query) { - return this.context.isActive(to, params, query); - } - -}; - -module.exports = State; - -},{"react":253}],84:[function(require,module,exports){ -var React = require('react'); -var assign = require('react/lib/Object.assign'); -var Path = require('../utils/Path'); - -function routeIsActive(activeRoutes, routeName) { - return activeRoutes.some(function (route) { - return route.name === routeName; - }); -} - -function paramsAreActive(activeParams, params) { - for (var property in params) - if (String(activeParams[property]) !== String(params[property])) - return false; - - return true; -} - -function queryIsActive(activeQuery, query) { - for (var property in query) - if (String(activeQuery[property]) !== String(query[property])) - return false; - - return true; -} - -/** - * Provides the router with context for Router.State. - */ -var StateContext = { - - /** - * Returns the current URL path + query string. - */ - getCurrentPath: function () { - return this.state.path; - }, - - /** - * Returns a read-only array of the currently active routes. - */ - getCurrentRoutes: function () { - return this.state.routes.slice(0); - }, - - /** - * Returns the current URL path without the query string. - */ - getCurrentPathname: function () { - return this.state.pathname; - }, - - /** - * Returns a read-only object of the currently active URL parameters. - */ - getCurrentParams: function () { - return assign({}, this.state.params); - }, - - /** - * Returns a read-only object of the currently active query parameters. - */ - getCurrentQuery: function () { - return assign({}, this.state.query); - }, - - /** - * Returns true if the given route, params, and query are active. - */ - isActive: function (to, params, query) { - if (Path.isAbsolute(to)) - return to === this.state.path; - - return routeIsActive(this.state.routes, to) && - paramsAreActive(this.state.params, params) && - (query == null || queryIsActive(this.state.query, query)); - }, - - childContextTypes: { - getCurrentPath: React.PropTypes.func.isRequired, - getCurrentRoutes: React.PropTypes.func.isRequired, - getCurrentPathname: React.PropTypes.func.isRequired, - getCurrentParams: React.PropTypes.func.isRequired, - getCurrentQuery: React.PropTypes.func.isRequired, - isActive: React.PropTypes.func.isRequired - }, - - getChildContext: function () { - return { - getCurrentPath: this.getCurrentPath, - getCurrentRoutes: this.getCurrentRoutes, - getCurrentPathname: this.getCurrentPathname, - getCurrentParams: this.getCurrentParams, - getCurrentQuery: this.getCurrentQuery, - isActive: this.isActive - }; - } - -}; - -module.exports = StateContext; - -},{"../utils/Path":86,"react":253,"react/lib/Object.assign":132}],85:[function(require,module,exports){ -/** - * Represents a cancellation caused by navigating away - * before the previous transition has fully resolved. - */ -function Cancellation() { } - -module.exports = Cancellation; - -},{}],86:[function(require,module,exports){ -var invariant = require('react/lib/invariant'); -var merge = require('qs/lib/utils').merge; -var qs = require('qs'); - -var paramCompileMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g; -var paramInjectMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g; -var paramInjectTrailingSlashMatcher = /\/\/\?|\/\?/g; -var queryMatcher = /\?(.+)/; - -var _compiledPatterns = {}; - -function compilePattern(pattern) { - if (!(pattern in _compiledPatterns)) { - var paramNames = []; - var source = pattern.replace(paramCompileMatcher, function (match, paramName) { - if (paramName) { - paramNames.push(paramName); - return '([^/?#]+)'; - } else if (match === '*') { - paramNames.push('splat'); - return '(.*?)'; - } else { - return '\\' + match; - } - }); - - _compiledPatterns[pattern] = { - matcher: new RegExp('^' + source + '$', 'i'), - paramNames: paramNames - }; - } - - return _compiledPatterns[pattern]; -} - -var Path = { - - /** - * Safely decodes special characters in the given URL path. - */ - decode: function (path) { - return decodeURI(path.replace(/\+/g, ' ')); - }, - - /** - * Safely encodes special characters in the given URL path. - */ - encode: function (path) { - return encodeURI(path).replace(/%20/g, '+'); - }, - - /** - * Returns an array of the names of all parameters in the given pattern. - */ - extractParamNames: function (pattern) { - return compilePattern(pattern).paramNames; - }, - - /** - * Extracts the portions of the given URL path that match the given pattern - * and returns an object of param name => value pairs. Returns null if the - * pattern does not match the given path. - */ - extractParams: function (pattern, path) { - var object = compilePattern(pattern); - var match = path.match(object.matcher); - - if (!match) - return null; - - var params = {}; - - object.paramNames.forEach(function (paramName, index) { - params[paramName] = match[index + 1]; - }); - - return params; - }, - - /** - * Returns a version of the given route path with params interpolated. Throws - * if there is a dynamic segment of the route path for which there is no param. - */ - injectParams: function (pattern, params) { - params = params || {}; - - var splatIndex = 0; - - return pattern.replace(paramInjectMatcher, function (match, paramName) { - paramName = paramName || 'splat'; - - // If param is optional don't check for existence - if (paramName.slice(-1) !== '?') { - invariant( - params[paramName] != null, - 'Missing "' + paramName + '" parameter for path "' + pattern + '"' - ); - } else { - paramName = paramName.slice(0, -1); - - if (params[paramName] == null) - return ''; - } - - var segment; - if (paramName === 'splat' && Array.isArray(params[paramName])) { - segment = params[paramName][splatIndex++]; - - invariant( - segment != null, - 'Missing splat # ' + splatIndex + ' for path "' + pattern + '"' - ); - } else { - segment = params[paramName]; - } - - return segment; - }).replace(paramInjectTrailingSlashMatcher, '/'); - }, - - /** - * Returns an object that is the result of parsing any query string contained - * in the given path, null if the path contains no query string. - */ - extractQuery: function (path) { - var match = path.match(queryMatcher); - return match && qs.parse(match[1]); - }, - - /** - * Returns a version of the given path without the query string. - */ - withoutQuery: function (path) { - return path.replace(queryMatcher, ''); - }, - - /** - * Returns a version of the given path with the parameters in the given - * query merged into the query string. - */ - withQuery: function (path, query) { - var existingQuery = Path.extractQuery(path); - - if (existingQuery) - query = query ? merge(existingQuery, query) : existingQuery; - - var queryString = query && qs.stringify(query); - - if (queryString) - return Path.withoutQuery(path) + '?' + queryString; - - return path; - }, - - /** - * Returns true if the given path is absolute. - */ - isAbsolute: function (path) { - return path.charAt(0) === '/'; - }, - - /** - * Returns a normalized version of the given path. - */ - normalize: function (path, parentRoute) { - return path.replace(/^\/*/, '/'); - }, - - /** - * Joins two URL paths together. - */ - join: function (a, b) { - return a.replace(/\/*$/, '/') + b; - } - -}; - -module.exports = Path; - -},{"qs":97,"qs/lib/utils":101,"react/lib/invariant":233}],87:[function(require,module,exports){ -var Promise = require('when/lib/Promise'); - -// TODO: Use process.env.NODE_ENV check + envify to enable -// when's promise monitor here when in dev. - -module.exports = Promise; - -},{"when/lib/Promise":102}],88:[function(require,module,exports){ -var PropTypes = { - - /** - * Requires that the value of a prop be falsy. - */ - falsy: function (props, propName, elementName) { - if (props[propName]) - return new Error('<' + elementName + '> may not have a "' + propName + '" prop'); - } - -}; - -module.exports = PropTypes; - -},{}],89:[function(require,module,exports){ -/** - * Encapsulates a redirect to the given route. - */ -function Redirect(to, params, query) { - this.to = to; - this.params = params; - this.query = query; -} - -module.exports = Redirect; - -},{}],90:[function(require,module,exports){ -var assign = require('react/lib/Object.assign'); -var reversedArray = require('./reversedArray'); -var Redirect = require('./Redirect'); -var Promise = require('./Promise'); - -/** - * Runs all hook functions serially and calls callback(error) when finished. - * A hook may return a promise if it needs to execute asynchronously. - */ -function runHooks(hooks, callback) { - try { - var promise = hooks.reduce(function (promise, hook) { - // The first hook to use transition.wait makes the rest - // of the transition async from that point forward. - return promise ? promise.then(hook) : hook(); - }, null); - } catch (error) { - return callback(error); // Sync error. - } - - if (promise) { - // Use setTimeout to break the promise chain. - promise.then(function () { - setTimeout(callback); - }, function (error) { - setTimeout(function () { - callback(error); - }); - }); - } else { - callback(); - } -} - -/** - * Calls the willTransitionFrom hook of all handlers in the given matches - * serially in reverse with the transition object and the current instance of - * the route's handler, so that the deepest nested handlers are called first. - * Calls callback(error) when finished. - */ -function runTransitionFromHooks(transition, routes, components, callback) { - components = reversedArray(components); - - var hooks = reversedArray(routes).map(function (route, index) { - return function () { - var handler = route.handler; - - if (!transition.isAborted && handler.willTransitionFrom) - return handler.willTransitionFrom(transition, components[index]); - - var promise = transition._promise; - transition._promise = null; - - return promise; - }; - }); - - runHooks(hooks, callback); -} - -/** - * Calls the willTransitionTo hook of all handlers in the given matches - * serially with the transition object and any params that apply to that - * handler. Calls callback(error) when finished. - */ -function runTransitionToHooks(transition, routes, params, query, callback) { - var hooks = routes.map(function (route) { - return function () { - var handler = route.handler; - - if (!transition.isAborted && handler.willTransitionTo) - handler.willTransitionTo(transition, params, query); - - var promise = transition._promise; - transition._promise = null; - - return promise; - }; - }); - - runHooks(hooks, callback); -} - -/** - * Encapsulates a transition to a given path. - * - * The willTransitionTo and willTransitionFrom handlers receive - * an instance of this class as their first argument. - */ -function Transition(path, retry) { - this.path = path; - this.abortReason = null; - this.isAborted = false; - this.retry = retry.bind(this); - this._promise = null; -} - -assign(Transition.prototype, { - - abort: function (reason) { - if (this.isAborted) { - // First abort wins. - return; - } - - this.abortReason = reason; - this.isAborted = true; - }, - - redirect: function (to, params, query) { - this.abort(new Redirect(to, params, query)); - }, - - wait: function (value) { - this._promise = Promise.resolve(value); - }, - - from: function (routes, components, callback) { - return runTransitionFromHooks(this, routes, components, callback); - }, - - to: function (routes, params, query, callback) { - return runTransitionToHooks(this, routes, params, query, callback); - } - -}); - -module.exports = Transition; - -},{"./Promise":87,"./Redirect":89,"./reversedArray":94,"react/lib/Object.assign":132}],91:[function(require,module,exports){ -(function (process){ -var React = require('react'); -var warning = require('react/lib/warning'); -var invariant = require('react/lib/invariant'); -var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; -var ImitateBrowserBehavior = require('../behaviors/ImitateBrowserBehavior'); -var RouteHandler = require('../components/RouteHandler'); -var LocationActions = require('../actions/LocationActions'); -var HashLocation = require('../locations/HashLocation'); -var HistoryLocation = require('../locations/HistoryLocation'); -var RefreshLocation = require('../locations/RefreshLocation'); -var NavigationContext = require('../mixins/NavigationContext'); -var StateContext = require('../mixins/StateContext'); -var Scrolling = require('../mixins/Scrolling'); -var createRoutesFromChildren = require('./createRoutesFromChildren'); -var supportsHistory = require('./supportsHistory'); -var Transition = require('./Transition'); -var PropTypes = require('./PropTypes'); -var Redirect = require('./Redirect'); -var Cancellation = require('./Cancellation'); -var Path = require('./Path'); - -/** - * The default location for new routers. - */ -var DEFAULT_LOCATION = canUseDOM ? HashLocation : '/'; - -/** - * The default scroll behavior for new routers. - */ -var DEFAULT_SCROLL_BEHAVIOR = canUseDOM ? ImitateBrowserBehavior : null; - -/** - * The default error handler for new routers. - */ -function defaultErrorHandler(error) { - // Throw so we don't silently swallow async errors. - throw error; // This error probably originated in a transition hook. -} - -/** - * The default aborted transition handler for new routers. - */ -function defaultAbortHandler(abortReason, location) { - if (typeof location === 'string') - throw new Error('Unhandled aborted transition! Reason: ' + abortReason); - - if (abortReason instanceof Cancellation) { - return; - } else if (abortReason instanceof Redirect) { - location.replace(this.makePath(abortReason.to, abortReason.params, abortReason.query)); - } else { - location.pop(); - } -} - -function findMatch(pathname, routes, defaultRoute, notFoundRoute) { - var match, route, params; - - for (var i = 0, len = routes.length; i < len; ++i) { - route = routes[i]; - - // Check the subtree first to find the most deeply-nested match. - match = findMatch(pathname, route.childRoutes, route.defaultRoute, route.notFoundRoute); - - if (match != null) { - match.routes.unshift(route); - return match; - } - - // No routes in the subtree matched, so check this route. - params = Path.extractParams(route.path, pathname); - - if (params) - return createMatch(route, params); - } - - // No routes matched, so try the default route if there is one. - if (defaultRoute && (params = Path.extractParams(defaultRoute.path, pathname))) - return createMatch(defaultRoute, params); - - // Last attempt: does the "not found" route match? - if (notFoundRoute && (params = Path.extractParams(notFoundRoute.path, pathname))) - return createMatch(notFoundRoute, params); - - return match; -} - -function createMatch(route, params) { - return { routes: [ route ], params: params }; -} - -function hasMatch(routes, route, prevParams, nextParams) { - return routes.some(function (r) { - if (r !== route) - return false; - - var paramNames = route.paramNames; - var paramName; - - for (var i = 0, len = paramNames.length; i < len; ++i) { - paramName = paramNames[i]; - - if (nextParams[paramName] !== prevParams[paramName]) - return false; - } - - return true; - }); -} - -/** - * Creates and returns a new router using the given options. A router - * is a ReactComponent class that knows how to react to changes in the - * URL and keep the contents of the page in sync. - * - * Options may be any of the following: - * - * - routes (required) The route config - * - location The location to use. Defaults to HashLocation when - * the DOM is available, "/" otherwise - * - scrollBehavior The scroll behavior to use. Defaults to ImitateBrowserBehavior - * when the DOM is available, null otherwise - * - onError A function that is used to handle errors - * - onAbort A function that is used to handle aborted transitions - * - * When rendering in a server-side environment, the location should simply - * be the URL path that was used in the request, including the query string. - */ -function createRouter(options) { - options = options || {}; - - if (typeof options === 'function') { - options = { routes: options }; // Router.create() - } else if (Array.isArray(options)) { - options = { routes: options }; // Router.create([ , ]) - } - - var routes = []; - var namedRoutes = {}; - var components = []; - var location = options.location || DEFAULT_LOCATION; - var scrollBehavior = options.scrollBehavior || DEFAULT_SCROLL_BEHAVIOR; - var onError = options.onError || defaultErrorHandler; - var onAbort = options.onAbort || defaultAbortHandler; - var state = {}; - var nextState = {}; - var pendingTransition = null; - - function updateState() { - state = nextState; - nextState = {}; - } - - // Automatically fall back to full page refreshes in - // browsers that don't support the HTML history API. - if (location === HistoryLocation && !supportsHistory()) - location = RefreshLocation; - - var router = React.createClass({ - - displayName: 'Router', - - mixins: [ NavigationContext, StateContext, Scrolling ], - - statics: { - - defaultRoute: null, - notFoundRoute: null, - - /** - * Adds routes to this router from the given children object (see ReactChildren). - */ - addRoutes: function (children) { - routes.push.apply(routes, createRoutesFromChildren(children, this, namedRoutes)); - }, - - /** - * Returns an absolute URL path created from the given route - * name, URL parameters, and query. - */ - makePath: function (to, params, query) { - var path; - if (Path.isAbsolute(to)) { - path = Path.normalize(to); - } else { - var route = namedRoutes[to]; - - invariant( - route, - 'Unable to find ', - to - ); - - path = route.path; - } - - return Path.withQuery(Path.injectParams(path, params), query); - }, - - /** - * Returns a string that may safely be used as the href of a link - * to the route with the given name, URL parameters, and query. - */ - makeHref: function (to, params, query) { - var path = this.makePath(to, params, query); - return (location === HashLocation) ? '#' + path : path; - }, - - /** - * Transitions to the URL specified in the arguments by pushing - * a new URL onto the history stack. - */ - transitionTo: function (to, params, query) { - invariant( - typeof location !== 'string', - 'You cannot use transitionTo with a static location' - ); - - var path = this.makePath(to, params, query); - - if (pendingTransition) { - // Replace so pending location does not stay in history. - location.replace(path); - } else { - location.push(path); - } - }, - - /** - * Transitions to the URL specified in the arguments by replacing - * the current URL in the history stack. - */ - replaceWith: function (to, params, query) { - invariant( - typeof location !== 'string', - 'You cannot use replaceWith with a static location' - ); - - location.replace(this.makePath(to, params, query)); - }, - - /** - * Transitions to the previous URL. - */ - goBack: function () { - invariant( - typeof location !== 'string', - 'You cannot use goBack with a static location' - ); - - location.pop(); - }, - - /** - * Performs a match of the given pathname against this router and returns an object - * with the { routes, params } that match. Returns null if no match can be made. - */ - match: function (pathname) { - return findMatch(pathname, routes, this.defaultRoute, this.notFoundRoute) || null; - }, - - /** - * Performs a transition to the given path and calls callback(error, abortReason) - * when the transition is finished. If both arguments are null the router's state - * was updated. Otherwise the transition did not complete. - * - * In a transition, a router first determines which routes are involved by beginning - * with the current route, up the route tree to the first parent route that is shared - * with the destination route, and back down the tree to the destination route. The - * willTransitionFrom hook is invoked on all route handlers we're transitioning away - * from, in reverse nesting order. Likewise, the willTransitionTo hook is invoked on - * all route handlers we're transitioning to. - * - * Both willTransitionFrom and willTransitionTo hooks may either abort or redirect the - * transition. To resolve asynchronously, they may use transition.wait(promise). If no - * hooks wait, the transition is fully synchronous. - */ - dispatch: function (path, action, callback) { - if (pendingTransition) { - pendingTransition.abort(new Cancellation); - pendingTransition = null; - } - - var prevPath = state.path; - if (prevPath === path) - return; // Nothing to do! - - // Record the scroll position as early as possible to - // get it before browsers try update it automatically. - if (prevPath && action !== LocationActions.REPLACE) - this.recordScrollPosition(prevPath); - - var pathname = Path.withoutQuery(path); - var match = this.match(pathname); - - warning( - match != null, - 'No route matches path "%s". Make sure you have somewhere in your routes', - path, path - ); - - if (match == null) - match = {}; - - var prevRoutes = state.routes || []; - var prevParams = state.params || {}; - - var nextRoutes = match.routes || []; - var nextParams = match.params || {}; - var nextQuery = Path.extractQuery(path) || {}; - - var fromRoutes, toRoutes; - if (prevRoutes.length) { - fromRoutes = prevRoutes.filter(function (route) { - return !hasMatch(nextRoutes, route, prevParams, nextParams); - }); - - toRoutes = nextRoutes.filter(function (route) { - return !hasMatch(prevRoutes, route, prevParams, nextParams); - }); - } else { - fromRoutes = []; - toRoutes = nextRoutes; - } - - var transition = new Transition(path, this.replaceWith.bind(this, path)); - pendingTransition = transition; - - transition.from(fromRoutes, components, function (error) { - if (error || transition.isAborted) - return callback.call(router, error, transition); - - transition.to(toRoutes, nextParams, nextQuery, function (error) { - if (error || transition.isAborted) - return callback.call(router, error, transition); - - nextState.path = path; - nextState.action = action; - nextState.pathname = pathname; - nextState.routes = nextRoutes; - nextState.params = nextParams; - nextState.query = nextQuery; - - callback.call(router, null, transition); - }); - }); - }, - - /** - * Starts this router and calls callback(router, state) when the route changes. - * - * If the router's location is static (i.e. a URL path in a server environment) - * the callback is called only once. Otherwise, the location should be one of the - * Router.*Location objects (e.g. Router.HashLocation or Router.HistoryLocation). - */ - run: function (callback) { - function dispatchHandler(error, transition) { - pendingTransition = null; - - if (error) { - onError.call(router, error); - } else if (transition.isAborted) { - onAbort.call(router, transition.abortReason, location); - } else { - callback.call(router, router, nextState); - } - } - - if (typeof location === 'string') { - warning( - !canUseDOM || process.env.NODE_ENV === 'test', - 'You should not use a static location in a DOM environment because ' + - 'the router will not be kept in sync with the current URL' - ); - - // Dispatch the location. - router.dispatch(location, null, dispatchHandler); - } else { - invariant( - canUseDOM, - 'You cannot use %s in a non-DOM environment', - location - ); - - // Listen for changes to the location. - function changeListener(change) { - router.dispatch(change.path, change.type, dispatchHandler); - } - - if (location.addChangeListener) - location.addChangeListener(changeListener); - - // Bootstrap using the current path. - router.dispatch(location.getCurrentPath(), null, dispatchHandler); - } - } - - }, +},{}],56:[function(require,module,exports){ +module.exports = { + Accordion: require('./Accordion'), + Affix: require('./Affix'), + AffixMixin: require('./AffixMixin'), + Alert: require('./Alert'), + BootstrapMixin: require('./BootstrapMixin'), + Badge: require('./Badge'), + Button: require('./Button'), + ButtonGroup: require('./ButtonGroup'), + ButtonToolbar: require('./ButtonToolbar'), + Carousel: require('./Carousel'), + CarouselItem: require('./CarouselItem'), + Col: require('./Col'), + CollapsableMixin: require('./CollapsableMixin'), + DropdownButton: require('./DropdownButton'), + DropdownMenu: require('./DropdownMenu'), + DropdownStateMixin: require('./DropdownStateMixin'), + FadeMixin: require('./FadeMixin'), + Glyphicon: require('./Glyphicon'), + Grid: require('./Grid'), + Input: require('./Input'), + Interpolate: require('./Interpolate'), + Jumbotron: require('./Jumbotron'), + Label: require('./Label'), + ListGroup: require('./ListGroup'), + ListGroupItem: require('./ListGroupItem'), + MenuItem: require('./MenuItem'), + Modal: require('./Modal'), + Nav: require('./Nav'), + Navbar: require('./Navbar'), + NavItem: require('./NavItem'), + ModalTrigger: require('./ModalTrigger'), + OverlayTrigger: require('./OverlayTrigger'), + OverlayMixin: require('./OverlayMixin'), + PageHeader: require('./PageHeader'), + Panel: require('./Panel'), + PanelGroup: require('./PanelGroup'), + PageItem: require('./PageItem'), + Pager: require('./Pager'), + Popover: require('./Popover'), + ProgressBar: require('./ProgressBar'), + Row: require('./Row'), + SplitButton: require('./SplitButton'), + SubNav: require('./SubNav'), + TabbedArea: require('./TabbedArea'), + Table: require('./Table'), + TabPane: require('./TabPane'), + Tooltip: require('./Tooltip'), + Well: require('./Well') +}; - propTypes: { - children: PropTypes.falsy - }, +},{"./Accordion":7,"./Affix":8,"./AffixMixin":9,"./Alert":10,"./Badge":11,"./BootstrapMixin":12,"./Button":13,"./ButtonGroup":14,"./ButtonToolbar":15,"./Carousel":16,"./CarouselItem":17,"./Col":18,"./CollapsableMixin":19,"./DropdownButton":20,"./DropdownMenu":21,"./DropdownStateMixin":22,"./FadeMixin":23,"./Glyphicon":24,"./Grid":25,"./Input":26,"./Interpolate":27,"./Jumbotron":28,"./Label":29,"./ListGroup":30,"./ListGroupItem":31,"./MenuItem":32,"./Modal":33,"./ModalTrigger":34,"./Nav":35,"./NavItem":36,"./Navbar":37,"./OverlayMixin":38,"./OverlayTrigger":39,"./PageHeader":40,"./PageItem":41,"./Pager":42,"./Panel":43,"./PanelGroup":44,"./Popover":45,"./ProgressBar":46,"./Row":47,"./SplitButton":48,"./SubNav":49,"./TabPane":50,"./TabbedArea":51,"./Table":52,"./Tooltip":53,"./Well":54}],57:[function(require,module,exports){ +var React = require('react'); - getLocation: function () { - return location; - }, +var ANONYMOUS = '<>'; - getScrollBehavior: function () { - return scrollBehavior; - }, +var CustomPropTypes = { + /** + * Checks whether a prop provides a DOM element + * + * The element can be provided in two forms: + * - Directly passed + * - Or passed an object which has a `getDOMNode` method which will return the required DOM element + * + * @param props + * @param propName + * @param componentName + * @returns {Error|undefined} + */ + mountable: createMountableChecker() +}; - getRouteAtDepth: function (depth) { - var routes = this.state.routes; - return routes && routes[depth]; - }, +/** + * Create chain-able isRequired validator + * + * Largely copied directly from: + * https://github.com/facebook/react/blob/0.11-stable/src/core/ReactPropTypes.js#L94 + */ +function createChainableTypeChecker(validate) { + function checkType(isRequired, props, propName, componentName) { + componentName = componentName || ANONYMOUS; + if (props[propName] == null) { + if (isRequired) { + return new Error( + 'Required prop `' + propName + '` was not specified in ' + + '`' + componentName + '`.' + ); + } + } else { + return validate(props, propName, componentName); + } + } - getRouteComponents: function () { - return components; - }, + var chainedCheckType = checkType.bind(null, false); + chainedCheckType.isRequired = checkType.bind(null, true); - getInitialState: function () { - updateState(); - return state; - }, + return chainedCheckType; +} - componentWillReceiveProps: function () { - updateState(); - this.setState(state); - }, +function createMountableChecker() { + function validate(props, propName, componentName) { + if (typeof props[propName] !== 'object' || + typeof props[propName].getDOMNode !== 'function' && props[propName].nodeType !== 1) { + return new Error( + 'Invalid prop `' + propName + '` supplied to ' + + '`' + componentName + '`, expected a DOM element or an object that has a `getDOMNode` method' + ); + } + } - render: function () { - return this.getRouteAtDepth(0) ? React.createElement(RouteHandler, this.props) : null; - }, + return createChainableTypeChecker(validate); +} - childContextTypes: { - getRouteAtDepth: React.PropTypes.func.isRequired, - getRouteComponents: React.PropTypes.func.isRequired, - routeHandlers: React.PropTypes.array.isRequired - }, +module.exports = CustomPropTypes; +},{"react":258}],58:[function(require,module,exports){ +/** + * Copyright 2013-2014 Facebook, Inc. + * + * This file contains a modified version of: + * https://github.com/facebook/react/blob/v0.12.0/src/vendor/stubs/EventListener.js + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * TODO: remove in favour of solution provided by: + * https://github.com/facebook/react/issues/285 + */ - getChildContext: function () { +/** + * Does not take into account specific nature of platform. + */ +var EventListener = { + /** + * Listen to DOM events during the bubble phase. + * + * @param {DOMEventTarget} target DOM element to register listener on. + * @param {string} eventType Event type, e.g. 'click' or 'mouseover'. + * @param {function} callback Callback function. + * @return {object} Object with a `remove` method. + */ + listen: function(target, eventType, callback) { + if (target.addEventListener) { + target.addEventListener(eventType, callback, false); return { - getRouteComponents: this.getRouteComponents, - getRouteAtDepth: this.getRouteAtDepth, - routeHandlers: [ this ] + remove: function() { + target.removeEventListener(eventType, callback, false); + } + }; + } else if (target.attachEvent) { + target.attachEvent('on' + eventType, callback); + return { + remove: function() { + target.detachEvent('on' + eventType, callback); + } }; } + } +}; - }); - - if (options.routes) - router.addRoutes(options.routes); - - return router; -} - -module.exports = createRouter; - -}).call(this,require('_process')) -},{"../actions/LocationActions":66,"../behaviors/ImitateBrowserBehavior":67,"../components/RouteHandler":74,"../locations/HashLocation":76,"../locations/HistoryLocation":77,"../locations/RefreshLocation":78,"../mixins/NavigationContext":81,"../mixins/Scrolling":82,"../mixins/StateContext":84,"./Cancellation":85,"./Path":86,"./PropTypes":88,"./Redirect":89,"./Transition":90,"./createRoutesFromChildren":92,"./supportsHistory":96,"_process":258,"react":253,"react/lib/ExecutionEnvironment":127,"react/lib/invariant":233,"react/lib/warning":252}],92:[function(require,module,exports){ -var React = require('react'); -var warning = require('react/lib/warning'); -var invariant = require('react/lib/invariant'); -var DefaultRoute = require('../components/DefaultRoute'); -var NotFoundRoute = require('../components/NotFoundRoute'); -var Redirect = require('../components/Redirect'); -var Route = require('../components/Route'); -var Path = require('./Path'); - -var CONFIG_ELEMENT_TYPES = [ - DefaultRoute.type, - NotFoundRoute.type, - Redirect.type, - Route.type -]; - -function createRedirectHandler(to, _params, _query) { - return React.createClass({ - statics: { - willTransitionTo: function (transition, params, query) { - transition.redirect(to, _params || params, _query || query); - } - }, +module.exports = EventListener; - render: function () { - return null; - } - }); -} +},{}],59:[function(require,module,exports){ +/** + * Copyright 2014, Facebook, Inc. + * All rights reserved. + * + * This file contains an unmodified version of: + * https://github.com/facebook/react/blob/v0.12.0/src/vendor/stubs/Object.assign.js + * + * This source code is licensed under the BSD-style license found here: + * https://github.com/facebook/react/blob/v0.12.0/LICENSE + * An additional grant of patent rights can be found here: + * https://github.com/facebook/react/blob/v0.12.0/PATENTS + */ -function checkPropTypes(componentName, propTypes, props) { - for (var propName in propTypes) { - if (propTypes.hasOwnProperty(propName)) { - var error = propTypes[propName](props, propName, componentName); +// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign - if (error instanceof Error) - warning(false, error.message); - } +function assign(target, sources) { + if (target == null) { + throw new TypeError('Object.assign target cannot be null or undefined'); } -} -function createRoute(element, parentRoute, namedRoutes) { - var type = element.type; - var props = element.props; - var componentName = (type && type.displayName) || 'UnknownComponent'; + var to = Object(target); + var hasOwnProperty = Object.prototype.hasOwnProperty; - invariant( - CONFIG_ELEMENT_TYPES.indexOf(type) !== -1, - 'Unrecognized route configuration element "<%s>"', - componentName - ); + for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { + var nextSource = arguments[nextIndex]; + if (nextSource == null) { + continue; + } - if (type.propTypes) - checkPropTypes(componentName, type.propTypes, props); + var from = Object(nextSource); - var route = { name: props.name }; + // We don't currently support accessors nor proxies. Therefore this + // copy cannot throw. If we ever supported this then we must handle + // exceptions and side-effects. We don't support symbols so they won't + // be transferred. - if (props.ignoreScrollBehavior) { - route.ignoreScrollBehavior = true; + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } } - if (type === Redirect.type) { - route.handler = createRedirectHandler(props.to, props.params, props.query); - props.path = props.path || props.from || '*'; - } else { - route.handler = props.handler; - } + return to; +}; - var parentPath = (parentRoute && parentRoute.path) || '/'; +module.exports = assign; - if ((props.path || props.name) && type !== DefaultRoute.type && type !== NotFoundRoute.type) { - var path = props.path || props.name; +},{}],60:[function(require,module,exports){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This file contains a modified version of: + * https://github.com/facebook/react/blob/v0.12.0/src/addons/transitions/ReactTransitionEvents.js + * + * This source code is licensed under the BSD-style license found here: + * https://github.com/facebook/react/blob/v0.12.0/LICENSE + * An additional grant of patent rights can be found here: + * https://github.com/facebook/react/blob/v0.12.0/PATENTS + */ - // Relative paths extend their parent. - if (!Path.isAbsolute(path)) - path = Path.join(parentPath, path); +var canUseDOM = !!( + typeof window !== 'undefined' && + window.document && + window.document.createElement + ); - route.path = Path.normalize(path); - } else { - route.path = parentPath; +/** + * EVENT_NAME_MAP is used to determine which event fired when a + * transition/animation ends, based on the style property used to + * define that event. + */ +var EVENT_NAME_MAP = { + transitionend: { + 'transition': 'transitionend', + 'WebkitTransition': 'webkitTransitionEnd', + 'MozTransition': 'mozTransitionEnd', + 'OTransition': 'oTransitionEnd', + 'msTransition': 'MSTransitionEnd' + }, - if (type === NotFoundRoute.type) - route.path += '*'; + animationend: { + 'animation': 'animationend', + 'WebkitAnimation': 'webkitAnimationEnd', + 'MozAnimation': 'mozAnimationEnd', + 'OAnimation': 'oAnimationEnd', + 'msAnimation': 'MSAnimationEnd' } +}; - route.paramNames = Path.extractParamNames(route.path); - - // Make sure the route's path has all params its parent needs. - if (parentRoute && Array.isArray(parentRoute.paramNames)) { - parentRoute.paramNames.forEach(function (paramName) { - invariant( - route.paramNames.indexOf(paramName) !== -1, - 'The nested route path "%s" is missing the "%s" parameter of its parent path "%s"', - route.path, paramName, parentRoute.path - ); - }); - } +var endEvents = []; - // Make sure the route can be looked up by s. - if (props.name) { - invariant( - namedRoutes[props.name] == null, - 'You cannot use the name "%s" for more than one route', - props.name - ); +function detectEvents() { + var testEl = document.createElement('div'); + var style = testEl.style; - namedRoutes[props.name] = route; + // On some platforms, in particular some releases of Android 4.x, + // the un-prefixed "animation" and "transition" properties are defined on the + // style object but the events that fire will still be prefixed, so we need + // to check if the un-prefixed events are useable, and if not remove them + // from the map + if (!('AnimationEvent' in window)) { + delete EVENT_NAME_MAP.animationend.animation; } - // Handle . - if (type === NotFoundRoute.type) { - invariant( - parentRoute, - ' must have a parent ' - ); + if (!('TransitionEvent' in window)) { + delete EVENT_NAME_MAP.transitionend.transition; + } - invariant( - parentRoute.notFoundRoute == null, - 'You may not have more than one per ' - ); + for (var baseEventName in EVENT_NAME_MAP) { + var baseEvents = EVENT_NAME_MAP[baseEventName]; + for (var styleName in baseEvents) { + if (styleName in style) { + endEvents.push(baseEvents[styleName]); + break; + } + } + } +} - parentRoute.notFoundRoute = route; +if (canUseDOM) { + detectEvents(); +} - return null; - } +// We use the raw {add|remove}EventListener() call because EventListener +// does not know how to remove event listeners and we really should +// clean up. Also, these events are not triggered in older browsers +// so we should be A-OK here. - // Handle . - if (type === DefaultRoute.type) { - invariant( - parentRoute, - ' must have a parent ' - ); +function addEventListener(node, eventName, eventListener) { + node.addEventListener(eventName, eventListener, false); +} - invariant( - parentRoute.defaultRoute == null, - 'You may not have more than one per ' - ); +function removeEventListener(node, eventName, eventListener) { + node.removeEventListener(eventName, eventListener, false); +} - parentRoute.defaultRoute = route; +var ReactTransitionEvents = { + addEndEventListener: function(node, eventListener) { + if (endEvents.length === 0) { + // If CSS transitions are not supported, trigger an "end animation" + // event immediately. + window.setTimeout(eventListener, 0); + return; + } + endEvents.forEach(function(endEvent) { + addEventListener(node, endEvent, eventListener); + }); + }, - return null; + removeEndEventListener: function(node, eventListener) { + if (endEvents.length === 0) { + return; + } + endEvents.forEach(function(endEvent) { + removeEventListener(node, endEvent, eventListener); + }); } +}; - route.childRoutes = createRoutesFromChildren(props.children, route, namedRoutes); +module.exports = ReactTransitionEvents; - return route; -} +},{}],61:[function(require,module,exports){ +var React = require('react'); /** - * Creates and returns an array of route objects from the given ReactChildren. + * Maps children that are typically specified as `props.children`, + * but only iterates over children that are "valid components". + * + * The mapFunction provided index will be normalised to the components mapped, + * so an invalid component would not increase the index. + * + * @param {?*} children Children tree container. + * @param {function(*, int)} mapFunction. + * @param {*} mapContext Context for mapFunction. + * @return {object} Object containing the ordered map of results. */ -function createRoutesFromChildren(children, parentRoute, namedRoutes) { - var routes = []; +function mapValidComponents(children, func, context) { + var index = 0; - React.Children.forEach(children, function (child) { - // Exclude s and s. - if (child = createRoute(child, parentRoute, namedRoutes)) - routes.push(child); - }); + return React.Children.map(children, function (child) { + if (React.isValidElement(child)) { + var lastIndex = index; + index++; + return func.call(context, child, lastIndex); + } - return routes; + return child; + }); } -module.exports = createRoutesFromChildren; - -},{"../components/DefaultRoute":69,"../components/NotFoundRoute":71,"../components/Redirect":72,"../components/Route":73,"./Path":86,"react":253,"react/lib/invariant":233,"react/lib/warning":252}],93:[function(require,module,exports){ -var invariant = require('react/lib/invariant'); -var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; - /** - * Returns the current scroll position of the window as { x, y }. + * Iterates through children that are typically specified as `props.children`, + * but only iterates over children that are "valid components". + * + * The provided forEachFunc(child, index) will be called for each + * leaf child with the index reflecting the position relative to "valid components". + * + * @param {?*} children Children tree container. + * @param {function(*, int)} forEachFunc. + * @param {*} forEachContext Context for forEachContext. */ -function getWindowScrollPosition() { - invariant( - canUseDOM, - 'Cannot get current scroll position without a DOM' - ); +function forEachValidComponents(children, func, context) { + var index = 0; - return { - x: window.scrollX, - y: window.scrollY - }; + return React.Children.forEach(children, function (child) { + if (React.isValidElement(child)) { + func.call(context, child, index); + index++; + } + }); } -module.exports = getWindowScrollPosition; - -},{"react/lib/ExecutionEnvironment":127,"react/lib/invariant":233}],94:[function(require,module,exports){ -function reversedArray(array) { - return array.slice(0).reverse(); -} +/** + * Count the number of "valid components" in the Children container. + * + * @param {?*} children Children tree container. + * @returns {number} + */ +function numberOfValidComponents(children) { + var count = 0; -module.exports = reversedArray; + React.Children.forEach(children, function (child) { + if (React.isValidElement(child)) { count++; } + }); -},{}],95:[function(require,module,exports){ -var createRouter = require('./createRouter'); + return count; +} /** - * A high-level convenience method that creates, configures, and - * runs a router in one shot. The method signature is: - * - * Router.run(routes[, location ], callback); - * - * Using `window.location.hash` to manage the URL, you could do: - * - * Router.run(routes, function (Handler) { - * React.render(, document.body); - * }); - * - * Using HTML5 history and a custom "cursor" prop: - * - * Router.run(routes, Router.HistoryLocation, function (Handler) { - * React.render(, document.body); - * }); - * - * Returns the newly created router. - * - * Note: If you need to specify further options for your router such - * as error/abort handling or custom scroll behavior, use Router.create - * instead. + * Determine if the Child container has one or more "valid components". * - * var router = Router.create(options); - * router.run(function (Handler) { - * // ... - * }); + * @param {?*} children Children tree container. + * @returns {boolean} */ -function runRouter(routes, location, callback) { - if (typeof location === 'function') { - callback = location; - location = null; - } +function hasValidComponent(children) { + var hasValid = false; - var router = createRouter({ - routes: routes, - location: location + React.Children.forEach(children, function (child) { + if (!hasValid && React.isValidElement(child)) { + hasValid = true; + } }); - router.run(callback); - - return router; + return hasValid; } -module.exports = runRouter; +module.exports = { + map: mapValidComponents, + forEach: forEachValidComponents, + numberOf: numberOfValidComponents, + hasValidComponent: hasValidComponent +}; +},{"react":258}],62:[function(require,module,exports){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This file contains an unmodified version of: + * https://github.com/facebook/react/blob/v0.12.0/src/vendor/stubs/cx.js + * + * This source code is licensed under the BSD-style license found here: + * https://github.com/facebook/react/blob/v0.12.0/LICENSE + * An additional grant of patent rights can be found here: + * https://github.com/facebook/react/blob/v0.12.0/PATENTS + */ -},{"./createRouter":91}],96:[function(require,module,exports){ -function supportsHistory() { - /*! taken from modernizr - * https://github.com/Modernizr/Modernizr/blob/master/LICENSE - * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js - */ - var ua = navigator.userAgent; - if ((ua.indexOf('Android 2.') !== -1 || - (ua.indexOf('Android 4.0') !== -1)) && - ua.indexOf('Mobile Safari') !== -1 && - ua.indexOf('Chrome') === -1) { - return false; +/** + * This function is used to mark string literals representing CSS class names + * so that they can be transformed statically. This allows for modularization + * and minification of CSS class names. + * + * In static_upstream, this function is actually implemented, but it should + * eventually be replaced with something more descriptive, and the transform + * that is used in the main stack should be ported for use elsewhere. + * + * @param string|object className to modularize, or an object of key/values. + * In the object case, the values are conditions that + * determine if the className keys should be included. + * @param [string ...] Variable list of classNames in the string case. + * @return string Renderable space-separated CSS className. + */ +function cx(classNames) { + if (typeof classNames == 'object') { + return Object.keys(classNames).filter(function(className) { + return classNames[className]; + }).join(' '); + } else { + return Array.prototype.join.call(arguments, ' '); } - return (window.history && 'pushState' in window.history); } -module.exports = supportsHistory; - -},{}],97:[function(require,module,exports){ -module.exports = require('./lib'); - -},{"./lib":98}],98:[function(require,module,exports){ -// Load modules - -var Stringify = require('./stringify'); -var Parse = require('./parse'); - - -// Declare internals - -var internals = {}; - - -module.exports = { - stringify: Stringify, - parse: Parse -}; +module.exports = cx; +},{}],63:[function(require,module,exports){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This file contains modified versions of: + * https://github.com/facebook/react/blob/v0.12.0/src/utils/cloneWithProps.js + * https://github.com/facebook/react/blob/v0.12.0/src/core/ReactPropTransferer.js + * + * This source code is licensed under the BSD-style license found here: + * https://github.com/facebook/react/blob/v0.12.0/LICENSE + * An additional grant of patent rights can be found here: + * https://github.com/facebook/react/blob/v0.12.0/PATENTS + * + * TODO: This should be replaced as soon as cloneWithProps is available via + * the core React package or a separate package. + * @see https://github.com/facebook/react/issues/1906 + */ -},{"./parse":99,"./stringify":100}],99:[function(require,module,exports){ -// Load modules +var React = require('react'); +var joinClasses = require('./joinClasses'); +var assign = require("./Object.assign"); -var Utils = require('./utils'); +/** + * Creates a transfer strategy that will merge prop values using the supplied + * `mergeStrategy`. If a prop was previously unset, this just sets it. + * + * @param {function} mergeStrategy + * @return {function} + */ +function createTransferStrategy(mergeStrategy) { + return function(props, key, value) { + if (!props.hasOwnProperty(key)) { + props[key] = value; + } else { + props[key] = mergeStrategy(props[key], value); + } + }; +} +var transferStrategyMerge = createTransferStrategy(function(a, b) { + // `merge` overrides the first object's (`props[key]` above) keys using the + // second object's (`value`) keys. An object's style's existing `propA` would + // get overridden. Flip the order here. + return assign({}, b, a); +}); -// Declare internals +function emptyFunction() {} -var internals = { - delimiter: '&', - depth: 5, - arrayLimit: 20, - parameterLimit: 1000 +/** + * Transfer strategies dictate how props are transferred by `transferPropsTo`. + * NOTE: if you add any more exceptions to this list you should be sure to + * update `cloneWithProps()` accordingly. + */ +var TransferStrategies = { + /** + * Never transfer `children`. + */ + children: emptyFunction, + /** + * Transfer the `className` prop by merging them. + */ + className: createTransferStrategy(joinClasses), + /** + * Transfer the `style` prop (which is an object) by merging them. + */ + style: transferStrategyMerge }; +/** + * Mutates the first argument by transferring the properties from the second + * argument. + * + * @param {object} props + * @param {object} newProps + * @return {object} + */ +function transferInto(props, newProps) { + for (var thisKey in newProps) { + if (!newProps.hasOwnProperty(thisKey)) { + continue; + } -internals.parseValues = function (str, options) { - - var obj = {}; - var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); + var transferStrategy = TransferStrategies[thisKey]; - for (var i = 0, il = parts.length; i < il; ++i) { - var part = parts[i]; - var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; + if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) { + transferStrategy(props, thisKey, newProps[thisKey]); + } else if (!props.hasOwnProperty(thisKey)) { + props[thisKey] = newProps[thisKey]; + } + } + return props; +} - if (pos === -1) { - obj[Utils.decode(part)] = ''; - } - else { - var key = Utils.decode(part.slice(0, pos)); - var val = Utils.decode(part.slice(pos + 1)); +/** + * Merge two props objects using TransferStrategies. + * + * @param {object} oldProps original props (they take precedence) + * @param {object} newProps new props to merge in + * @return {object} a new object containing both sets of props merged. + */ +function mergeProps(oldProps, newProps) { + return transferInto(assign({}, oldProps), newProps); +} - if (!obj[key]) { - obj[key] = val; - } - else { - obj[key] = [].concat(obj[key]).concat(val); - } - } - } - return obj; +var ReactPropTransferer = { + mergeProps: mergeProps }; +var CHILDREN_PROP = 'children'; -internals.parseObject = function (chain, val, options) { - - if (!chain.length) { - return val; - } - - var root = chain.shift(); +/** + * Sometimes you want to change the props of a child passed to you. Usually + * this is to add a CSS class. + * + * @param {object} child child component you'd like to clone + * @param {object} props props you'd like to modify. They will be merged + * as if you used `transferPropsTo()`. + * @return {object} a clone of child with props merged in. + */ +function cloneWithProps(child, props) { + var newProps = ReactPropTransferer.mergeProps(props, child.props); - var obj = {}; - if (root === '[]') { - obj = []; - obj = obj.concat(internals.parseObject(chain, val, options)); - } - else { - var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; - var index = parseInt(cleanRoot, 10); - if (!isNaN(index) && - root !== cleanRoot && - index <= options.arrayLimit) { + // Use `child.props.children` if it is provided. + if (!newProps.hasOwnProperty(CHILDREN_PROP) && + child.props.hasOwnProperty(CHILDREN_PROP)) { + newProps.children = child.props.children; + } - obj = []; - obj[index] = internals.parseObject(chain, val, options); - } - else { - obj[cleanRoot] = internals.parseObject(chain, val, options); - } - } + if (React.version.substr(0, 4) === '0.12'){ + var mockLegacyFactory = function(){}; + mockLegacyFactory.isReactLegacyFactory = true; + mockLegacyFactory.type = child.type; - return obj; -}; + return React.createElement(mockLegacyFactory, newProps); + } + // The current API doesn't retain _owner and _context, which is why this + // doesn't use ReactElement.cloneAndReplaceProps. + return React.createElement(child.type, newProps); +} -internals.parseKeys = function (key, val, options) { +module.exports = cloneWithProps; +},{"./Object.assign":59,"./joinClasses":66,"react":258}],64:[function(require,module,exports){ +/** + * Safe chained function + * + * Will only create a new function if needed, + * otherwise will pass back existing functions or null. + * + * @param {function} one + * @param {function} two + * @returns {function|null} + */ +function createChainedFunction(one, two) { + var hasOne = typeof one === 'function'; + var hasTwo = typeof two === 'function'; - if (!key) { - return; - } + if (!hasOne && !hasTwo) { return null; } + if (!hasOne) { return two; } + if (!hasTwo) { return one; } - // The regex chunks + return function chainedFunction() { + one.apply(this, arguments); + two.apply(this, arguments); + }; +} - var parent = /^([^\[\]]*)/; - var child = /(\[[^\[\]]*\])/g; +module.exports = createChainedFunction; +},{}],65:[function(require,module,exports){ - // Get the parent +/** + * Shortcut to compute element style + * + * @param {HTMLElement} elem + * @returns {CssStyle} + */ +function getComputedStyles(elem) { + return elem.ownerDocument.defaultView.getComputedStyle(elem, null); +} - var segment = parent.exec(key); +/** + * Get elements offset + * + * TODO: REMOVE JQUERY! + * + * @param {HTMLElement} DOMNode + * @returns {{top: number, left: number}} + */ +function getOffset(DOMNode) { + if (window.jQuery) { + return window.jQuery(DOMNode).offset(); + } - // Don't allow them to overwrite object prototype properties + var docElem = document.documentElement; + var box = { top: 0, left: 0 }; - if (Object.prototype.hasOwnProperty(segment[1])) { - return; - } + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof DOMNode.getBoundingClientRect !== 'undefined' ) { + box = DOMNode.getBoundingClientRect(); + } - // Stash the parent if it exists + return { + top: box.top + window.pageYOffset - docElem.clientTop, + left: box.left + window.pageXOffset - docElem.clientLeft + }; +} - var keys = []; - if (segment[1]) { - keys.push(segment[1]); - } +/** + * Get elements position + * + * TODO: REMOVE JQUERY! + * + * @param {HTMLElement} elem + * @param {HTMLElement?} offsetParent + * @returns {{top: number, left: number}} + */ +function getPosition(elem, offsetParent) { + if (window.jQuery) { + return window.jQuery(elem).position(); + } - // Loop through children appending to the array until we hit depth + var offset, + parentOffset = {top: 0, left: 0}; - var i = 0; - while ((segment = child.exec(key)) !== null && i < options.depth) { + // Fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent + if (getComputedStyles(elem).position === 'fixed' ) { + // We assume that getBoundingClientRect is available when computed position is fixed + offset = elem.getBoundingClientRect(); - ++i; - if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { - keys.push(segment[1]); - } + } else { + if (!offsetParent) { + // Get *real* offsetParent + offsetParent = offsetParent(elem); } - // If there's a remainder, just add whatever is left - - if (segment) { - keys.push('[' + key.slice(segment.index) + ']'); + // Get correct offsets + offset = getOffset(elem); + if ( offsetParent.nodeName !== 'HTML') { + parentOffset = getOffset(offsetParent); } - return internals.parseObject(keys, val, options); -}; - + // Add offsetParent borders + parentOffset.top += parseInt(getComputedStyles(offsetParent).borderTopWidth, 10); + parentOffset.left += parseInt(getComputedStyles(offsetParent).borderLeftWidth, 10); + } -module.exports = function (str, options) { + // Subtract parent offsets and element margins + return { + top: offset.top - parentOffset.top - parseInt(getComputedStyles(elem).marginTop, 10), + left: offset.left - parentOffset.left - parseInt(getComputedStyles(elem).marginLeft, 10) + }; +} - if (str === '' || - str === null || - typeof str === 'undefined') { +/** + * Get parent element + * + * @param {HTMLElement?} elem + * @returns {HTMLElement} + */ +function offsetParent(elem) { + var docElem = document.documentElement; + var offsetParent = elem.offsetParent || docElem; - return {}; - } + while ( offsetParent && ( offsetParent.nodeName !== 'HTML' && + getComputedStyles(offsetParent).position === 'static' ) ) { + offsetParent = offsetParent.offsetParent; + } - options = options || {}; - options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter; - options.depth = typeof options.depth === 'number' ? options.depth : internals.depth; - options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit; - options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit; + return offsetParent || docElem; +} - var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str; - var obj = {}; +module.exports = { + getComputedStyles: getComputedStyles, + getOffset: getOffset, + getPosition: getPosition, + offsetParent: offsetParent +}; +},{}],66:[function(require,module,exports){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. + * + * This file contains an unmodified version of: + * https://github.com/facebook/react/blob/v0.12.0/src/utils/joinClasses.js + * + * This source code is licensed under the BSD-style license found here: + * https://github.com/facebook/react/blob/v0.12.0/LICENSE + * An additional grant of patent rights can be found here: + * https://github.com/facebook/react/blob/v0.12.0/PATENTS + */ - // Iterate over the keys and setup the new object +"use strict"; - var keys = Object.keys(tempObj); - for (var i = 0, il = keys.length; i < il; ++i) { - var key = keys[i]; - var newObj = internals.parseKeys(key, tempObj[key], options); - obj = Utils.merge(obj, newObj); +/** + * Combines multiple className strings into one. + * http://jsperf.com/joinclasses-args-vs-array + * + * @param {...?string} classes + * @return {string} + */ +function joinClasses(className/*, ... */) { + if (!className) { + className = ''; + } + var nextClass; + var argLength = arguments.length; + if (argLength > 1) { + for (var ii = 1; ii < argLength; ii++) { + nextClass = arguments[ii]; + if (nextClass) { + className = (className ? className + ' ' : '') + nextClass; + } } + } + return className; +} - return Utils.compact(obj); -}; - -},{"./utils":101}],100:[function(require,module,exports){ -// Load modules - -var Utils = require('./utils'); - - -// Declare internals +module.exports = joinClasses; -var internals = { - delimiter: '&' -}; +},{}],67:[function(require,module,exports){ +var React = require('react'); +var Button = require('react-bootstrap/Button'); -internals.stringify = function (obj, prefix) { +var Navigation = require('react-router/modules/mixins/Navigation'); +var State = require('react-router/modules/mixins/State'); - if (Utils.isBuffer(obj)) { - obj = obj.toString(); - } - else if (obj instanceof Date) { - obj = obj.toISOString(); - } - else if (obj === null) { - obj = ''; - } +var helpers = require('./helpers'); - if (typeof obj === 'string' || - typeof obj === 'number' || - typeof obj === 'boolean') { +ADDITIONAL_RESERVED_PROPS = ['key', 'ref']; - return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)]; - } +var ButtonLink = React.createClass({displayName: 'ButtonLink', + mixins: [State, Navigation], - var values = []; + additionalReservedProps: ADDITIONAL_RESERVED_PROPS, - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']')); - } + getInitialState: function() { + return { + href: '#' } + }, - return values; -}; - + componentDidMount: function() { + var params = this.getCleanedParams(); + var href = this.makeHref(this.props.to, params, this.props.query || null); -module.exports = function (obj, options) { + this.setState({ + href: href + }); + }, - options = options || {}; - var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter; + getCleanedParams: function() { + var reserved = Object.keys(this.refs.button.constructor.propTypes) + .concat(ADDITIONAL_RESERVED_PROPS); - var keys = []; + return helpers.withoutProperties(this.props, reserved || []); + }, - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - keys = keys.concat(internals.stringify(obj[key], key)); - } + handleRouteTo: function (e) { + if (helpers.isModifiedEvent(e) || !helpers.isLeftClick(e)) { + return; } + e.preventDefault(); + var params = this.getCleanedParams(); + return this.transitionTo(this.props.to, params, this.props.query || null); + }, - return keys.join(delimiter); -}; + render: function () { + return ( + React.createElement(Button, React.__spread({}, + this.props, + {href: this.state.href, + onClick: this.handleRouteTo, + ref: "button"}), + this.props.children + ) + ); + } +}); -},{"./utils":101}],101:[function(require,module,exports){ -(function (Buffer){ -// Load modules +module.exports = ButtonLink; +},{"./helpers":69,"react":258,"react-bootstrap/Button":13,"react-router/modules/mixins/Navigation":85,"react-router/modules/mixins/State":88}],68:[function(require,module,exports){ +var React = require('react'); -// Declare internals +var NavItem = require('react-bootstrap/NavItem') -var internals = {}; +var Navigation = require('react-router/modules/mixins/Navigation'); +var State = require('react-router/modules/mixins/State'); +var helpers = require('./helpers'); -exports.arrayToObject = function (source) { +ADDITIONAL_RESERVED_PROPS = [ + 'to', + 'active', + 'activeHref', + 'activeKey', + 'key', + 'navItem', + 'onSelect', + 'ref', + 'children', + 'query' +]; - var obj = {}; - for (var i = 0, il = source.length; i < il; ++i) { - if (typeof source[i] !== 'undefined') { +var NavItemLink = React.createClass({displayName: 'NavItemLink', + mixins: [State, Navigation], - obj[i] = source[i]; - } - } + additionalReservedProps: ADDITIONAL_RESERVED_PROPS, - return obj; -}; + getInitialState: function() { + return { + params: false + } + }, + componentDidMount: function() { + this.setState({ + params: this.getCleanedParams(this.props) + }); + }, -exports.merge = function (target, source) { + getCleanedParams: function(props) { + var reserved = Object.keys(this.refs.navItem.constructor.propTypes) + .concat(this.additionalReservedProps); - if (!source) { - return target; - } + return helpers.withoutProperties(props, reserved || []); + }, - if (Array.isArray(source)) { - for (var i = 0, il = source.length; i < il; ++i) { - if (typeof source[i] !== 'undefined') { - if (typeof target[i] === 'object') { - target[i] = exports.merge(target[i], source[i]); - } - else { - target[i] = source[i]; - } - } - } + componentWillReceiveProps: function(nextProps) { + this.setState({ + params: this.getCleanedParams(nextProps) + }); + }, - return target; + handleRouteTo: function (e) { + if (helpers.isModifiedEvent(e) || !helpers.isLeftClick(e)) { + return; } + e.preventDefault(); + return this.transitionTo(this.props.to, this.state.params, this.props.query || null); + }, - if (Array.isArray(target)) { - if (typeof source !== 'object') { - target.push(source); - return target; - } - else { - target = exports.arrayToObject(target); - } + render: function() { + if (this.state.params !== false) { + var href = this.makeHref(this.props.to, this.state.params, this.props.query || null); + var active = this.isActive(this.props.to, this.state.params, this.props.query || null); + } else { + var href = "#"; + var active = false; } - var keys = Object.keys(source); - for (var k = 0, kl = keys.length; k < kl; ++k) { - var key = keys[k]; - var value = source[key]; - - if (value && - typeof value === 'object') { + return ( + React.createElement(NavItem, React.__spread({}, + this.props, + {href: href, + active: active, + onClick: this.handleRouteTo, + ref: "navItem"}), + this.props.children + ) + ); + } +}); - if (!target[key]) { - target[key] = value; - } - else { - target[key] = exports.merge(target[key], value); - } - } - else { - target[key] = value; - } - } +module.exports = NavItemLink; - return target; +},{"./helpers":69,"react":258,"react-bootstrap/NavItem":36,"react-router/modules/mixins/Navigation":85,"react-router/modules/mixins/State":88}],69:[function(require,module,exports){ +exports.isLeftClick = function(event) { + return event.button === 0; }; - -exports.decode = function (str) { - - try { - return decodeURIComponent(str.replace(/\+/g, ' ')); - } catch (e) { - return str; - } +exports.isModifiedEvent = function(event) { + return !!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey); }; - -exports.compact = function (obj, refs) { - - if (typeof obj !== 'object' || - obj === null) { - - return obj; - } - - refs = refs || []; - var lookup = refs.indexOf(obj); - if (lookup !== -1) { - return refs[lookup]; +exports.withoutProperties = function(object, properties) { + var property, result; + result = {}; + for (property in object) { + if (object.hasOwnProperty(property) && properties.indexOf(property) == -1) { + result[property] = object[property]; } + } + return result; +}; - refs.push(obj); - - if (Array.isArray(obj)) { - var compacted = []; +},{}],70:[function(require,module,exports){ +var NavItemLink = require('./NavItemLink'); +var ButtonLink = require('./ButtonLink'); - for (var i = 0, l = obj.length; i < l; ++i) { - if (typeof obj[i] !== 'undefined') { - compacted.push(obj[i]); - } - } +module.exports = { + NavItemLink: NavItemLink, + ButtonLink: ButtonLink +}; - return compacted; - } +},{"./ButtonLink":67,"./NavItemLink":68}],71:[function(require,module,exports){ +/** + * Actions that modify the URL. + */ +var LocationActions = { - var keys = Object.keys(obj); - for (var i = 0, il = keys.length; i < il; ++i) { - var key = keys[i]; - obj[key] = exports.compact(obj[key], refs); - } + /** + * Indicates a new location is being pushed to the history stack. + */ + PUSH: 'push', - return obj; -}; + /** + * Indicates the current location should be replaced. + */ + REPLACE: 'replace', + /** + * Indicates the most recent entry should be removed from the history stack. + */ + POP: 'pop' -exports.isRegExp = function (obj) { - return Object.prototype.toString.call(obj) === '[object RegExp]'; }; +module.exports = LocationActions; -exports.isBuffer = function (obj) { +},{}],72:[function(require,module,exports){ +var LocationActions = require('../actions/LocationActions'); - if (typeof Buffer !== 'undefined') { - return Buffer.isBuffer(obj); - } - else { - return false; +/** + * A scroll behavior that attempts to imitate the default behavior + * of modern browsers. + */ +var ImitateBrowserBehavior = { + + updateScrollPosition: function (position, actionType) { + switch (actionType) { + case LocationActions.PUSH: + case LocationActions.REPLACE: + window.scrollTo(0, 0); + break; + case LocationActions.POP: + if (position) { + window.scrollTo(position.x, position.y); + } else { + window.scrollTo(0, 0); + } + break; } -}; + } -}).call(this,require("buffer").Buffer) -},{"buffer":254}],102:[function(require,module,exports){ -/** @license MIT License (c) copyright 2010-2014 original author or authors */ -/** @author Brian Cavalier */ -/** @author John Hann */ +}; -(function(define) { 'use strict'; -define(function (require) { +module.exports = ImitateBrowserBehavior; - var makePromise = require('./makePromise'); - var Scheduler = require('./Scheduler'); - var async = require('./async'); +},{"../actions/LocationActions":71}],73:[function(require,module,exports){ +/** + * A scroll behavior that always scrolls to the top of the page + * after a transition. + */ +var ScrollToTopBehavior = { - return makePromise({ - scheduler: new Scheduler(async) - }); + updateScrollPosition: function () { + window.scrollTo(0, 0); + } -}); -})(typeof define === 'function' && define.amd ? define : function (factory) { module.exports = factory(require); }); +}; -},{"./Scheduler":104,"./async":105,"./makePromise":106}],103:[function(require,module,exports){ -/** @license MIT License (c) copyright 2010-2014 original author or authors */ -/** @author Brian Cavalier */ -/** @author John Hann */ +module.exports = ScrollToTopBehavior; -(function(define) { 'use strict'; -define(function() { - /** - * Circular queue - * @param {number} capacityPow2 power of 2 to which this queue's capacity - * will be set initially. eg when capacityPow2 == 3, queue capacity - * will be 8. - * @constructor - */ - function Queue(capacityPow2) { - this.head = this.tail = this.length = 0; - this.buffer = new Array(1 << capacityPow2); - } +},{}],74:[function(require,module,exports){ +var React = require('react'); +var FakeNode = require('../mixins/FakeNode'); +var PropTypes = require('../utils/PropTypes'); - Queue.prototype.push = function(x) { - if(this.length === this.buffer.length) { - this._ensureCapacity(this.length * 2); - } +/** + * A component is a special kind of that + * renders when its parent matches but none of its siblings do. + * Only one such route may be used at any given level in the + * route hierarchy. + */ +var DefaultRoute = React.createClass({ - this.buffer[this.tail] = x; - this.tail = (this.tail + 1) & (this.buffer.length - 1); - ++this.length; - return this.length; - }; + displayName: 'DefaultRoute', - Queue.prototype.shift = function() { - var x = this.buffer[this.head]; - this.buffer[this.head] = void 0; - this.head = (this.head + 1) & (this.buffer.length - 1); - --this.length; - return x; - }; + mixins: [ FakeNode ], - Queue.prototype._ensureCapacity = function(capacity) { - var head = this.head; - var buffer = this.buffer; - var newBuffer = new Array(capacity); - var i = 0; - var len; + propTypes: { + name: React.PropTypes.string, + path: PropTypes.falsy, + handler: React.PropTypes.func.isRequired + } - if(head === 0) { - len = this.length; - for(; i components are used to create an element that links to a route. + * When that route is active, the link gets an "active" class name (or the + * value of its `activeClassName` prop). + * + * For example, assuming you have the following route: + * + * + * + * You could use the following component to link to that route: + * + * + * + * In addition to params, links may pass along query string parameters + * using the `query` prop. + * + * + */ +var Link = React.createClass({ -(function(define) { 'use strict'; -define(function(require) { + displayName: 'Link', - var Queue = require('./Queue'); + mixins: [ Navigation, State ], - // Credit to Twisol (https://github.com/Twisol) for suggesting - // this type of extensible queue + trampoline approach for next-tick conflation. + propTypes: { + activeClassName: React.PropTypes.string.isRequired, + to: React.PropTypes.string.isRequired, + params: React.PropTypes.object, + query: React.PropTypes.object, + onClick: React.PropTypes.func + }, - /** - * Async task scheduler - * @param {function} async function to schedule a single async function - * @constructor - */ - function Scheduler(async) { - this._async = async; - this._queue = new Queue(15); - this._afterQueue = new Queue(5); - this._running = false; + getDefaultProps: function () { + return { + activeClassName: 'active' + }; + }, - var self = this; - this.drain = function() { - self._drain(); - }; - } + handleClick: function (event) { + var allowTransition = true; + var clickResult; - /** - * Enqueue a task - * @param {{ run:function }} task - */ - Scheduler.prototype.enqueue = function(task) { - this._add(this._queue, task); - }; + if (this.props.onClick) + clickResult = this.props.onClick(event); - /** - * Enqueue a task to run after the main task queue - * @param {{ run:function }} task - */ - Scheduler.prototype.afterQueue = function(task) { - this._add(this._afterQueue, task); - }; + if (isModifiedEvent(event) || !isLeftClickEvent(event)) + return; - /** - * Drain the handler queue entirely, and then the after queue - */ - Scheduler.prototype._drain = function() { - runQueue(this._queue); - this._running = false; - runQueue(this._afterQueue); - }; + if (clickResult === false || event.defaultPrevented === true) + allowTransition = false; - /** - * Add a task to the q, and schedule drain if not already scheduled - * @param {Queue} queue - * @param {{run:function}} task - * @private - */ - Scheduler.prototype._add = function(queue, task) { - queue.push(task); - if(!this._running) { - this._running = true; - this._async(this.drain); - } - }; + event.preventDefault(); - /** - * Run all the tasks in the q - * @param queue - */ - function runQueue(queue) { - while(queue.length > 0) { - queue.shift().run(); - } - } + if (allowTransition) + this.transitionTo(this.props.to, this.props.params, this.props.query); + }, - return Scheduler; + /** + * Returns the value of the "href" attribute to use on the DOM element. + */ + getHref: function () { + return this.makeHref(this.props.to, this.props.params, this.props.query); + }, -}); -}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); })); + /** + * Returns the value of the "class" attribute to use on the DOM element, which contains + * the value of the activeClassName property when this is active. + */ + getClassName: function () { + var classNames = {}; -},{"./Queue":103}],105:[function(require,module,exports){ -(function (process){ -/** @license MIT License (c) copyright 2010-2014 original author or authors */ -/** @author Brian Cavalier */ -/** @author John Hann */ + if (this.props.className) + classNames[this.props.className] = true; -(function(define) { 'use strict'; -define(function(require) { + if (this.isActive(this.props.to, this.props.params, this.props.query)) + classNames[this.props.activeClassName] = true; - // Sniff "best" async scheduling option - // Prefer process.nextTick or MutationObserver, then check for - // vertx and finally fall back to setTimeout + return classSet(classNames); + }, - /*jshint maxcomplexity:6*/ - /*global process,document,setTimeout,MutationObserver,WebKitMutationObserver*/ - var nextTick, MutationObs; + render: function () { + var props = assign({}, this.props, { + href: this.getHref(), + className: this.getClassName(), + onClick: this.handleClick + }); - if (typeof process !== 'undefined' && process !== null && - typeof process.nextTick === 'function') { - nextTick = function(f) { - process.nextTick(f); - }; + return React.DOM.a(props, this.props.children); + } - } else if (MutationObs = - (typeof MutationObserver === 'function' && MutationObserver) || - (typeof WebKitMutationObserver === 'function' && WebKitMutationObserver)) { - nextTick = (function (document, MutationObserver) { - var scheduled; - var el = document.createElement('div'); - var o = new MutationObserver(run); - o.observe(el, { attributes: true }); +}); - function run() { - var f = scheduled; - scheduled = void 0; - f(); - } +module.exports = Link; - return function (f) { - scheduled = f; - el.setAttribute('class', 'x'); - }; - }(document, MutationObs)); +},{"../mixins/Navigation":85,"../mixins/State":88,"react":258,"react/lib/Object.assign":137,"react/lib/cx":216}],76:[function(require,module,exports){ +var React = require('react'); +var FakeNode = require('../mixins/FakeNode'); +var PropTypes = require('../utils/PropTypes'); - } else { - nextTick = (function(cjsRequire) { - var vertx; - try { - // vert.x 1.x || 2.x - vertx = cjsRequire('vertx'); - } catch (ignore) {} +/** + * A is a special kind of that + * renders when the beginning of its parent's path matches + * but none of its siblings do, including any . + * Only one such route may be used at any given level in the + * route hierarchy. + */ +var NotFoundRoute = React.createClass({ - if (vertx) { - if (typeof vertx.runOnLoop === 'function') { - return vertx.runOnLoop; - } - if (typeof vertx.runOnContext === 'function') { - return vertx.runOnContext; - } - } + displayName: 'NotFoundRoute', - // capture setTimeout to avoid being caught by fake timers - // used in time based tests - var capturedSetTimeout = setTimeout; - return function (t) { - capturedSetTimeout(t, 0); - }; - }(require)); - } + mixins: [ FakeNode ], - return nextTick; -}); -}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(require); })); + propTypes: { + name: React.PropTypes.string, + path: PropTypes.falsy, + handler: React.PropTypes.func.isRequired + } -}).call(this,require('_process')) -},{"_process":258}],106:[function(require,module,exports){ -/** @license MIT License (c) copyright 2010-2014 original author or authors */ -/** @author Brian Cavalier */ -/** @author John Hann */ +}); -(function(define) { 'use strict'; -define(function() { +module.exports = NotFoundRoute; - return function makePromise(environment) { +},{"../mixins/FakeNode":84,"../utils/PropTypes":93,"react":258}],77:[function(require,module,exports){ +var React = require('react'); +var FakeNode = require('../mixins/FakeNode'); +var PropTypes = require('../utils/PropTypes'); - var tasks = environment.scheduler; +/** + * A component is a special kind of that always + * redirects to another route when it matches. + */ +var Redirect = React.createClass({ - var objectCreate = Object.create || - function(proto) { - function Child() {} - Child.prototype = proto; - return new Child(); - }; + displayName: 'Redirect', - /** - * Create a promise whose fate is determined by resolver - * @constructor - * @returns {Promise} promise - * @name Promise - */ - function Promise(resolver, handler) { - this._handler = resolver === Handler ? handler : init(resolver); - } + mixins: [ FakeNode ], - /** - * Run the supplied resolver - * @param resolver - * @returns {Pending} - */ - function init(resolver) { - var handler = new Pending(); + propTypes: { + path: React.PropTypes.string, + from: React.PropTypes.string, // Alias for path. + to: React.PropTypes.string, + handler: PropTypes.falsy + } - try { - resolver(promiseResolve, promiseReject, promiseNotify); - } catch (e) { - promiseReject(e); - } +}); - return handler; +module.exports = Redirect; - /** - * Transition from pre-resolution state to post-resolution state, notifying - * all listeners of the ultimate fulfillment or rejection - * @param {*} x resolution value - */ - function promiseResolve (x) { - handler.resolve(x); - } - /** - * Reject this promise with reason, which will be used verbatim - * @param {Error|*} reason rejection reason, strongly suggested - * to be an Error type - */ - function promiseReject (reason) { - handler.reject(reason); - } +},{"../mixins/FakeNode":84,"../utils/PropTypes":93,"react":258}],78:[function(require,module,exports){ +var React = require('react'); +var FakeNode = require('../mixins/FakeNode'); - /** - * Issue a progress event, notifying all progress listeners - * @param {*} x progress event payload to pass to all listeners - */ - function promiseNotify (x) { - handler.notify(x); - } - } +/** + * components specify components that are rendered to the page when the + * URL matches a given pattern. + * + * Routes are arranged in a nested tree structure. When a new URL is requested, + * the tree is searched depth-first to find a route whose path matches the URL. + * When one is found, all routes in the tree that lead to it are considered + * "active" and their components are rendered into the DOM, nested in the same + * order as they are in the tree. + * + * The preferred way to configure a router is using JSX. The XML-like syntax is + * a great way to visualize how routes are laid out in an application. + * + * var routes = [ + * + * + * + * + * + * ]; + * + * Router.run(routes, function (Handler) { + * React.render(, document.body); + * }); + * + * Handlers for Route components that contain children can render their active + * child route using a element. + * + * var App = React.createClass({ + * render: function () { + * return ( + *
+ * + *
+ * ); + * } + * }); + */ +var Route = React.createClass({ - // Creation + displayName: 'Route', - Promise.resolve = resolve; - Promise.reject = reject; - Promise.never = never; + mixins: [ FakeNode ], - Promise._defer = defer; - Promise._handler = getHandler; + propTypes: { + name: React.PropTypes.string, + path: React.PropTypes.string, + handler: React.PropTypes.func.isRequired, + ignoreScrollBehavior: React.PropTypes.bool + } - /** - * Returns a trusted promise. If x is already a trusted promise, it is - * returned, otherwise returns a new trusted Promise which follows x. - * @param {*} x - * @return {Promise} promise - */ - function resolve(x) { - return isPromise(x) ? x - : new Promise(Handler, new Async(getHandler(x))); - } +}); - /** - * Return a reject promise with x as its reason (x is used verbatim) - * @param {*} x - * @returns {Promise} rejected promise - */ - function reject(x) { - return new Promise(Handler, new Async(new Rejected(x))); - } +module.exports = Route; - /** - * Return a promise that remains pending forever - * @returns {Promise} forever-pending promise. - */ - function never() { - return foreverPendingPromise; // Should be frozen - } +},{"../mixins/FakeNode":84,"react":258}],79:[function(require,module,exports){ +var React = require('react'); - /** - * Creates an internal {promise, resolver} pair - * @private - * @returns {Promise} - */ - function defer() { - return new Promise(Handler, new Pending()); - } +/** + * A component renders the active child route handler + * when routes are nested. + */ +var RouteHandler = React.createClass({ - // Transformation and flow control + displayName: 'RouteHandler', - /** - * Transform this promise's fulfillment value, returning a new Promise - * for the transformed result. If the promise cannot be fulfilled, onRejected - * is called with the reason. onProgress *may* be called with updates toward - * this promise's fulfillment. - * @param {function=} onFulfilled fulfillment handler - * @param {function=} onRejected rejection handler - * @deprecated @param {function=} onProgress progress handler - * @return {Promise} new promise - */ - Promise.prototype.then = function(onFulfilled, onRejected) { - var parent = this._handler; - var state = parent.join().state(); + getDefaultProps: function () { + return { + ref: '__routeHandler__' + }; + }, - if ((typeof onFulfilled !== 'function' && state > 0) || - (typeof onRejected !== 'function' && state < 0)) { - // Short circuit: value will not change, simply share handler - return new this.constructor(Handler, parent); - } + contextTypes: { + getRouteAtDepth: React.PropTypes.func.isRequired, + getRouteComponents: React.PropTypes.func.isRequired, + routeHandlers: React.PropTypes.array.isRequired + }, - var p = this._beget(); - var child = p._handler; + childContextTypes: { + routeHandlers: React.PropTypes.array.isRequired + }, - parent.chain(child, parent.receiver, onFulfilled, onRejected, - arguments.length > 2 ? arguments[2] : void 0); + getChildContext: function () { + return { + routeHandlers: this.context.routeHandlers.concat([ this ]) + }; + }, - return p; - }; + getRouteDepth: function () { + return this.context.routeHandlers.length - 1; + }, - /** - * If this promise cannot be fulfilled due to an error, call onRejected to - * handle the error. Shortcut for .then(undefined, onRejected) - * @param {function?} onRejected - * @return {Promise} - */ - Promise.prototype['catch'] = function(onRejected) { - return this.then(void 0, onRejected); - }; + componentDidMount: function () { + this._updateRouteComponent(); + }, - /** - * Creates a new, pending promise of the same type as this promise - * @private - * @returns {Promise} - */ - Promise.prototype._beget = function() { - var parent = this._handler; - var child = new Pending(parent.receiver, parent.join().context); - return new this.constructor(Handler, child); - }; + componentDidUpdate: function () { + this._updateRouteComponent(); + }, - // Array combinators + _updateRouteComponent: function () { + var depth = this.getRouteDepth(); + var components = this.context.getRouteComponents(); + components[depth] = this.refs[this.props.ref]; + }, - Promise.all = all; - Promise.race = race; + render: function () { + var route = this.context.getRouteAtDepth(this.getRouteDepth()); + return route ? React.createElement(route.handler, this.props) : null; + } - /** - * Return a promise that will fulfill when all promises in the - * input array have fulfilled, or will reject when one of the - * promises rejects. - * @param {array} promises array of promises - * @returns {Promise} promise for array of fulfillment values - */ - function all(promises) { - /*jshint maxcomplexity:8*/ - var resolver = new Pending(); - var pending = promises.length >>> 0; - var results = new Array(pending); +}); - var i, h, x, s; - for (i = 0; i < promises.length; ++i) { - x = promises[i]; +module.exports = RouteHandler; - if (x === void 0 && !(i in promises)) { - --pending; - continue; - } +},{"react":258}],80:[function(require,module,exports){ +exports.DefaultRoute = require('./components/DefaultRoute'); +exports.Link = require('./components/Link'); +exports.NotFoundRoute = require('./components/NotFoundRoute'); +exports.Redirect = require('./components/Redirect'); +exports.Route = require('./components/Route'); +exports.RouteHandler = require('./components/RouteHandler'); - if (maybeThenable(x)) { - h = getHandlerMaybeThenable(x); +exports.HashLocation = require('./locations/HashLocation'); +exports.HistoryLocation = require('./locations/HistoryLocation'); +exports.RefreshLocation = require('./locations/RefreshLocation'); - s = h.state(); - if (s === 0) { - h.fold(settleAt, i, results, resolver); - } else if (s > 0) { - results[i] = h.value; - --pending; - } else { - unreportRemaining(promises, i+1, h); - resolver.become(h); - break; - } +exports.ImitateBrowserBehavior = require('./behaviors/ImitateBrowserBehavior'); +exports.ScrollToTopBehavior = require('./behaviors/ScrollToTopBehavior'); - } else { - results[i] = x; - --pending; - } - } +exports.Navigation = require('./mixins/Navigation'); +exports.State = require('./mixins/State'); - if(pending === 0) { - resolver.become(new Fulfilled(results)); - } +exports.create = require('./utils/createRouter'); +exports.run = require('./utils/runRouter'); - return new Promise(Handler, resolver); +},{"./behaviors/ImitateBrowserBehavior":72,"./behaviors/ScrollToTopBehavior":73,"./components/DefaultRoute":74,"./components/Link":75,"./components/NotFoundRoute":76,"./components/Redirect":77,"./components/Route":78,"./components/RouteHandler":79,"./locations/HashLocation":81,"./locations/HistoryLocation":82,"./locations/RefreshLocation":83,"./mixins/Navigation":85,"./mixins/State":88,"./utils/createRouter":96,"./utils/runRouter":100}],81:[function(require,module,exports){ +var invariant = require('react/lib/invariant'); +var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; +var LocationActions = require('../actions/LocationActions'); +var Path = require('../utils/Path'); - function settleAt(i, x, resolver) { - /*jshint validthis:true*/ - this[i] = x; - if(--pending === 0) { - resolver.become(new Fulfilled(this)); - } - } - } +/** + * Returns the current URL path from `window.location.hash`, including query string + */ +function getHashPath() { + invariant( + canUseDOM, + 'getHashPath needs a DOM' + ); - function unreportRemaining(promises, start, rejectedHandler) { - var i, h, x; - for(i=start; i'; + } - inherit(Handler, Pending); +}; - Pending.prototype._state = 0; +module.exports = HashLocation; - Pending.prototype.resolve = function(x) { - this.become(getHandler(x)); - }; +},{"../actions/LocationActions":71,"../utils/Path":91,"react/lib/ExecutionEnvironment":132,"react/lib/invariant":238}],82:[function(require,module,exports){ +var invariant = require('react/lib/invariant'); +var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; +var LocationActions = require('../actions/LocationActions'); +var Path = require('../utils/Path'); - Pending.prototype.reject = function(x) { - if(this.resolved) { - return; - } +/** + * Returns the current URL path from `window.location`, including query string + */ +function getWindowPath() { + invariant( + canUseDOM, + 'getWindowPath needs a DOM' + ); - this.become(new Rejected(x)); - }; + return Path.decode( + window.location.pathname + window.location.search + ); +} - Pending.prototype.join = function() { - if (!this.resolved) { - return this; - } +var _changeListeners = []; - var h = this; +function notifyChange(type) { + var change = { + path: getWindowPath(), + type: type + }; - while (h.handler !== void 0) { - h = h.handler; - if (h === this) { - return this.handler = cycle(); - } - } + _changeListeners.forEach(function (listener) { + listener(change); + }); +} - return h; - }; +var _isListening = false; - Pending.prototype.run = function() { - var q = this.consumers; - var handler = this.join(); - this.consumers = void 0; +function onPopState() { + notifyChange(LocationActions.POP); +} - for (var i = 0; i < q.length; ++i) { - handler.when(q[i]); - } - }; +/** + * A Location that uses HTML5 history. + */ +var HistoryLocation = { + + addChangeListener: function (listener) { + _changeListeners.push(listener); + + if (_isListening) + return; + + if (window.addEventListener) { + window.addEventListener('popstate', onPopState, false); + } else { + window.attachEvent('popstate', onPopState); + } + + _isListening = true; + }, - Pending.prototype.become = function(handler) { - if(this.resolved) { - return; - } + push: function (path) { + window.history.pushState({ path: path }, '', Path.encode(path)); + notifyChange(LocationActions.PUSH); + }, - this.resolved = true; - this.handler = handler; - if(this.consumers !== void 0) { - tasks.enqueue(this); - } + replace: function (path) { + window.history.replaceState({ path: path }, '', Path.encode(path)); + notifyChange(LocationActions.REPLACE); + }, - if(this.context !== void 0) { - handler._report(this.context); - } - }; + pop: function () { + window.history.back(); + }, - Pending.prototype.when = function(continuation) { - if(this.resolved) { - tasks.enqueue(new ContinuationTask(continuation, this.handler)); - } else { - if(this.consumers === void 0) { - this.consumers = [continuation]; - } else { - this.consumers.push(continuation); - } - } - }; + getCurrentPath: getWindowPath, - Pending.prototype.notify = function(x) { - if(!this.resolved) { - tasks.enqueue(new ProgressTask(x, this)); - } - }; + toString: function () { + return ''; + } - Pending.prototype.fail = function(context) { - var c = typeof context === 'undefined' ? this.context : context; - this.resolved && this.handler.join().fail(c); - }; +}; - Pending.prototype._report = function(context) { - this.resolved && this.handler.join()._report(context); - }; +module.exports = HistoryLocation; - Pending.prototype._unreport = function() { - this.resolved && this.handler.join()._unreport(); - }; +},{"../actions/LocationActions":71,"../utils/Path":91,"react/lib/ExecutionEnvironment":132,"react/lib/invariant":238}],83:[function(require,module,exports){ +var HistoryLocation = require('./HistoryLocation'); +var Path = require('../utils/Path'); - /** - * Wrap another handler and force it into a future stack - * @param {object} handler - * @constructor - */ - function Async(handler) { - this.handler = handler; - } +/** + * A Location that uses full page refreshes. This is used as + * the fallback for HistoryLocation in browsers that do not + * support the HTML5 history API. + */ +var RefreshLocation = { - inherit(Handler, Async); + push: function (path) { + window.location = Path.encode(path); + }, - Async.prototype.when = function(continuation) { - tasks.enqueue(new ContinuationTask(continuation, this)); - }; + replace: function (path) { + window.location.replace(Path.encode(path)); + }, - Async.prototype._report = function(context) { - this.join()._report(context); - }; + pop: function () { + window.history.back(); + }, - Async.prototype._unreport = function() { - this.join()._unreport(); - }; + getCurrentPath: HistoryLocation.getCurrentPath, - /** - * Handler that wraps an untrusted thenable and assimilates it in a future stack - * @param {function} then - * @param {{then: function}} thenable - * @constructor - */ - function Thenable(then, thenable) { - Pending.call(this); - tasks.enqueue(new AssimilateTask(then, thenable, this)); - } + toString: function () { + return ''; + } - inherit(Pending, Thenable); +}; - /** - * Handler for a fulfilled promise - * @param {*} x fulfillment value - * @constructor - */ - function Fulfilled(x) { - Promise.createContext(this); - this.value = x; - } +module.exports = RefreshLocation; - inherit(Handler, Fulfilled); +},{"../utils/Path":91,"./HistoryLocation":82}],84:[function(require,module,exports){ +var invariant = require('react/lib/invariant'); - Fulfilled.prototype._state = 1; +var FakeNode = { - Fulfilled.prototype.fold = function(f, z, c, to) { - runContinuation3(f, z, this, c, to); - }; + render: function () { + invariant( + false, + '%s elements should not be rendered', + this.constructor.displayName + ); + } - Fulfilled.prototype.when = function(cont) { - runContinuation1(cont.fulfilled, this, cont.receiver, cont.resolver); - }; +}; - var errorId = 0; +module.exports = FakeNode; - /** - * Handler for a rejected promise - * @param {*} x rejection reason - * @constructor - */ - function Rejected(x) { - Promise.createContext(this); +},{"react/lib/invariant":238}],85:[function(require,module,exports){ +var React = require('react'); - this.id = ++errorId; - this.value = x; - this.handled = false; - this.reported = false; +/** + * A mixin for components that modify the URL. + * + * Example: + * + * var MyLink = React.createClass({ + * mixins: [ Router.Navigation ], + * handleClick: function (event) { + * event.preventDefault(); + * this.transitionTo('aRoute', { the: 'params' }, { the: 'query' }); + * }, + * render: function () { + * return ( + *
Click me! + * ); + * } + * }); + */ +var Navigation = { - this._report(); - } + contextTypes: { + makePath: React.PropTypes.func.isRequired, + makeHref: React.PropTypes.func.isRequired, + transitionTo: React.PropTypes.func.isRequired, + replaceWith: React.PropTypes.func.isRequired, + goBack: React.PropTypes.func.isRequired + }, - inherit(Handler, Rejected); + /** + * Returns an absolute URL path created from the given route + * name, URL parameters, and query values. + */ + makePath: function (to, params, query) { + return this.context.makePath(to, params, query); + }, - Rejected.prototype._state = -1; + /** + * Returns a string that may safely be used as the href of a + * link to the route with the given name. + */ + makeHref: function (to, params, query) { + return this.context.makeHref(to, params, query); + }, - Rejected.prototype.fold = function(f, z, c, to) { - to.become(this); - }; + /** + * Transitions to the URL specified in the arguments by pushing + * a new URL onto the history stack. + */ + transitionTo: function (to, params, query) { + this.context.transitionTo(to, params, query); + }, - Rejected.prototype.when = function(cont) { - if(typeof cont.rejected === 'function') { - this._unreport(); - } - runContinuation1(cont.rejected, this, cont.receiver, cont.resolver); - }; + /** + * Transitions to the URL specified in the arguments by replacing + * the current URL in the history stack. + */ + replaceWith: function (to, params, query) { + this.context.replaceWith(to, params, query); + }, - Rejected.prototype._report = function(context) { - tasks.afterQueue(new ReportTask(this, context)); - }; + /** + * Transitions to the previous URL. + */ + goBack: function () { + this.context.goBack(); + } - Rejected.prototype._unreport = function() { - this.handled = true; - tasks.afterQueue(new UnreportTask(this)); - }; +}; - Rejected.prototype.fail = function(context) { - Promise.onFatalRejection(this, context === void 0 ? this.context : context); - }; +module.exports = Navigation; - function ReportTask(rejection, context) { - this.rejection = rejection; - this.context = context; - } +},{"react":258}],86:[function(require,module,exports){ +var React = require('react'); - ReportTask.prototype.run = function() { - if(!this.rejection.handled) { - this.rejection.reported = true; - Promise.onPotentiallyUnhandledRejection(this.rejection, this.context); - } - }; +/** + * Provides the router with context for Router.Navigation. + */ +var NavigationContext = { + + childContextTypes: { + makePath: React.PropTypes.func.isRequired, + makeHref: React.PropTypes.func.isRequired, + transitionTo: React.PropTypes.func.isRequired, + replaceWith: React.PropTypes.func.isRequired, + goBack: React.PropTypes.func.isRequired + }, - function UnreportTask(rejection) { - this.rejection = rejection; - } + getChildContext: function () { + return { + makePath: this.constructor.makePath, + makeHref: this.constructor.makeHref, + transitionTo: this.constructor.transitionTo, + replaceWith: this.constructor.replaceWith, + goBack: this.constructor.goBack + }; + } - UnreportTask.prototype.run = function() { - if(this.rejection.reported) { - Promise.onPotentiallyUnhandledRejectionHandled(this.rejection); - } - }; +}; - // Unhandled rejection hooks - // By default, everything is a noop +module.exports = NavigationContext; - // TODO: Better names: "annotate"? - Promise.createContext - = Promise.enterContext - = Promise.exitContext - = Promise.onPotentiallyUnhandledRejection - = Promise.onPotentiallyUnhandledRejectionHandled - = Promise.onFatalRejection - = noop; +},{"react":258}],87:[function(require,module,exports){ +var invariant = require('react/lib/invariant'); +var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; +var getWindowScrollPosition = require('../utils/getWindowScrollPosition'); - // Errors and singletons +function shouldUpdateScroll(state, prevState) { + if (!prevState) + return true; - var foreverPendingHandler = new Handler(); - var foreverPendingPromise = new Promise(Handler, foreverPendingHandler); + // Don't update scroll position when only the query has changed. + if (state.pathname === prevState.pathname) + return false; - function cycle() { - return new Rejected(new TypeError('Promise cycle')); - } + var routes = state.routes; + var prevRoutes = prevState.routes; - // Task runners + var sharedAncestorRoutes = routes.filter(function (route) { + return prevRoutes.indexOf(route) !== -1; + }); - /** - * Run a single consumer - * @constructor - */ - function ContinuationTask(continuation, handler) { - this.continuation = continuation; - this.handler = handler; - } + return !sharedAncestorRoutes.some(function (route) { + return route.ignoreScrollBehavior; + }); +} - ContinuationTask.prototype.run = function() { - this.handler.join().when(this.continuation); - }; +/** + * Provides the router with the ability to manage window scroll position + * according to its scroll behavior. + */ +var Scrolling = { - /** - * Run a queue of progress handlers - * @constructor - */ - function ProgressTask(value, handler) { - this.handler = handler; - this.value = value; - } + statics: { + /** + * Records curent scroll position as the last known position for the given URL path. + */ + recordScrollPosition: function (path) { + if (!this.scrollHistory) + this.scrollHistory = {}; - ProgressTask.prototype.run = function() { - var q = this.handler.consumers; - if(q === void 0) { - return; - } + this.scrollHistory[path] = getWindowScrollPosition(); + }, - for (var c, i = 0; i < q.length; ++i) { - c = q[i]; - runNotify(c.progress, this.value, this.handler, c.receiver, c.resolver); - } - }; + /** + * Returns the last known scroll position for the given URL path. + */ + getScrollPosition: function (path) { + if (!this.scrollHistory) + this.scrollHistory = {}; - /** - * Assimilate a thenable, sending it's value to resolver - * @param {function} then - * @param {object|function} thenable - * @param {object} resolver - * @constructor - */ - function AssimilateTask(then, thenable, resolver) { - this._then = then; - this.thenable = thenable; - this.resolver = resolver; - } + return this.scrollHistory[path] || null; + } + }, - AssimilateTask.prototype.run = function() { - var h = this.resolver; - tryAssimilate(this._then, this.thenable, _resolve, _reject, _notify); + componentWillMount: function () { + invariant( + this.getScrollBehavior() == null || canUseDOM, + 'Cannot use scroll behavior without a DOM' + ); + }, - function _resolve(x) { h.resolve(x); } - function _reject(x) { h.reject(x); } - function _notify(x) { h.notify(x); } - }; + componentDidMount: function () { + this._updateScroll(); + }, - function tryAssimilate(then, thenable, resolve, reject, notify) { - try { - then.call(thenable, resolve, reject, notify); - } catch (e) { - reject(e); - } - } + componentDidUpdate: function (prevProps, prevState) { + this._updateScroll(prevState); + }, - // Other helpers + _updateScroll: function (prevState) { + if (!shouldUpdateScroll(this.state, prevState)) + return; - /** - * @param {*} x - * @returns {boolean} true iff x is a trusted Promise - */ - function isPromise(x) { - return x instanceof Promise; - } + var scrollBehavior = this.getScrollBehavior(); - /** - * Test just enough to rule out primitives, in order to take faster - * paths in some code - * @param {*} x - * @returns {boolean} false iff x is guaranteed *not* to be a thenable - */ - function maybeThenable(x) { - return (typeof x === 'object' || typeof x === 'function') && x !== null; - } + if (scrollBehavior) + scrollBehavior.updateScrollPosition( + this.constructor.getScrollPosition(this.state.path), + this.state.action + ); + } - function runContinuation1(f, h, receiver, next) { - if(typeof f !== 'function') { - return next.become(h); - } +}; - Promise.enterContext(h); - tryCatchReject(f, h.value, receiver, next); - Promise.exitContext(); - } +module.exports = Scrolling; - function runContinuation3(f, x, h, receiver, next) { - if(typeof f !== 'function') { - return next.become(h); - } +},{"../utils/getWindowScrollPosition":98,"react/lib/ExecutionEnvironment":132,"react/lib/invariant":238}],88:[function(require,module,exports){ +var React = require('react'); - Promise.enterContext(h); - tryCatchReject3(f, x, h.value, receiver, next); - Promise.exitContext(); - } +/** + * A mixin for components that need to know the path, routes, URL + * params and query that are currently active. + * + * Example: + * + * var AboutLink = React.createClass({ + * mixins: [ Router.State ], + * render: function () { + * var className = this.props.className; + * + * if (this.isActive('about')) + * className += ' is-active'; + * + * return React.DOM.a({ className: className }, this.props.children); + * } + * }); + */ +var State = { - function runNotify(f, x, h, receiver, next) { - if(typeof f !== 'function') { - return next.notify(x); - } + contextTypes: { + getCurrentPath: React.PropTypes.func.isRequired, + getCurrentRoutes: React.PropTypes.func.isRequired, + getCurrentPathname: React.PropTypes.func.isRequired, + getCurrentParams: React.PropTypes.func.isRequired, + getCurrentQuery: React.PropTypes.func.isRequired, + isActive: React.PropTypes.func.isRequired + }, - Promise.enterContext(h); - tryCatchReturn(f, x, receiver, next); - Promise.exitContext(); - } + /** + * Returns the current URL path. + */ + getPath: function () { + return this.context.getCurrentPath(); + }, - /** - * Return f.call(thisArg, x), or if it throws return a rejected promise for - * the thrown exception - */ - function tryCatchReject(f, x, thisArg, next) { - try { - next.become(getHandler(f.call(thisArg, x))); - } catch(e) { - next.become(new Rejected(e)); - } - } + /** + * Returns an array of the routes that are currently active. + */ + getRoutes: function () { + return this.context.getCurrentRoutes(); + }, + + /** + * Returns the current URL path without the query string. + */ + getPathname: function () { + return this.context.getCurrentPathname(); + }, - /** - * Same as above, but includes the extra argument parameter. - */ - function tryCatchReject3(f, x, y, thisArg, next) { - try { - f.call(thisArg, x, y, next); - } catch(e) { - next.become(new Rejected(e)); - } - } + /** + * Returns an object of the URL params that are currently active. + */ + getParams: function () { + return this.context.getCurrentParams(); + }, - /** - * Return f.call(thisArg, x), or if it throws, *return* the exception - */ - function tryCatchReturn(f, x, thisArg, next) { - try { - next.notify(f.call(thisArg, x)); - } catch(e) { - next.notify(e); - } - } + /** + * Returns an object of the query params that are currently active. + */ + getQuery: function () { + return this.context.getCurrentQuery(); + }, - function inherit(Parent, Child) { - Child.prototype = objectCreate(Parent.prototype); - Child.prototype.constructor = Child; - } + /** + * A helper method to determine if a given route, params, and query + * are active. + */ + isActive: function (to, params, query) { + return this.context.isActive(to, params, query); + } - function noop() {} +}; - return Promise; - }; -}); -}(typeof define === 'function' && define.amd ? define : function(factory) { module.exports = factory(); })); +module.exports = State; -},{}],107:[function(require,module,exports){ -/** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule AutoFocusMixin - * @typechecks static-only - */ +},{"react":258}],89:[function(require,module,exports){ +var React = require('react'); +var assign = require('react/lib/Object.assign'); +var Path = require('../utils/Path'); -"use strict"; +function routeIsActive(activeRoutes, routeName) { + return activeRoutes.some(function (route) { + return route.name === routeName; + }); +} -var focusNode = require("./focusNode"); +function paramsAreActive(activeParams, params) { + for (var property in params) + if (String(activeParams[property]) !== String(params[property])) + return false; -var AutoFocusMixin = { - componentDidMount: function() { - if (this.props.autoFocus) { - focusNode(this.getDOMNode()); - } - } -}; + return true; +} -module.exports = AutoFocusMixin; +function queryIsActive(activeQuery, query) { + for (var property in query) + if (String(activeQuery[property]) !== String(query[property])) + return false; + + return true; +} -},{"./focusNode":218}],108:[function(require,module,exports){ /** - * Copyright 2013 Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule BeforeInputEventPlugin - * @typechecks static-only + * Provides the router with context for Router.State. */ +var StateContext = { -"use strict"; + /** + * Returns the current URL path + query string. + */ + getCurrentPath: function () { + return this.state.path; + }, -var EventConstants = require("./EventConstants"); -var EventPropagators = require("./EventPropagators"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var SyntheticInputEvent = require("./SyntheticInputEvent"); + /** + * Returns a read-only array of the currently active routes. + */ + getCurrentRoutes: function () { + return this.state.routes.slice(0); + }, -var keyOf = require("./keyOf"); + /** + * Returns the current URL path without the query string. + */ + getCurrentPathname: function () { + return this.state.pathname; + }, -var canUseTextInputEvent = ( - ExecutionEnvironment.canUseDOM && - 'TextEvent' in window && - !('documentMode' in document || isPresto()) -); + /** + * Returns a read-only object of the currently active URL parameters. + */ + getCurrentParams: function () { + return assign({}, this.state.params); + }, -/** - * Opera <= 12 includes TextEvent in window, but does not fire - * text input events. Rely on keypress instead. - */ -function isPresto() { - var opera = window.opera; - return ( - typeof opera === 'object' && - typeof opera.version === 'function' && - parseInt(opera.version(), 10) <= 12 - ); -} + /** + * Returns a read-only object of the currently active query parameters. + */ + getCurrentQuery: function () { + return assign({}, this.state.query); + }, -var SPACEBAR_CODE = 32; -var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); + /** + * Returns true if the given route, params, and query are active. + */ + isActive: function (to, params, query) { + if (Path.isAbsolute(to)) + return to === this.state.path; -var topLevelTypes = EventConstants.topLevelTypes; + return routeIsActive(this.state.routes, to) && + paramsAreActive(this.state.params, params) && + (query == null || queryIsActive(this.state.query, query)); + }, -// Events and their corresponding property names. -var eventTypes = { - beforeInput: { - phasedRegistrationNames: { - bubbled: keyOf({onBeforeInput: null}), - captured: keyOf({onBeforeInputCapture: null}) - }, - dependencies: [ - topLevelTypes.topCompositionEnd, - topLevelTypes.topKeyPress, - topLevelTypes.topTextInput, - topLevelTypes.topPaste - ] + childContextTypes: { + getCurrentPath: React.PropTypes.func.isRequired, + getCurrentRoutes: React.PropTypes.func.isRequired, + getCurrentPathname: React.PropTypes.func.isRequired, + getCurrentParams: React.PropTypes.func.isRequired, + getCurrentQuery: React.PropTypes.func.isRequired, + isActive: React.PropTypes.func.isRequired + }, + + getChildContext: function () { + return { + getCurrentPath: this.getCurrentPath, + getCurrentRoutes: this.getCurrentRoutes, + getCurrentPathname: this.getCurrentPathname, + getCurrentParams: this.getCurrentParams, + getCurrentQuery: this.getCurrentQuery, + isActive: this.isActive + }; } -}; -// Track characters inserted via keypress and composition events. -var fallbackChars = null; +}; -// Track whether we've ever handled a keypress on the space key. -var hasSpaceKeypress = false; +module.exports = StateContext; +},{"../utils/Path":91,"react":258,"react/lib/Object.assign":137}],90:[function(require,module,exports){ /** - * Return whether a native keypress event is assumed to be a command. - * This is required because Firefox fires `keypress` events for key commands - * (cut, copy, select-all, etc.) even though no character is inserted. + * Represents a cancellation caused by navigating away + * before the previous transition has fully resolved. */ -function isKeypressCommand(nativeEvent) { - return ( - (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && - // ctrlKey && altKey is equivalent to AltGr, and is not a command. - !(nativeEvent.ctrlKey && nativeEvent.altKey) - ); -} +function Cancellation() { } -/** - * Create an `onBeforeInput` event to match - * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents. - * - * This event plugin is based on the native `textInput` event - * available in Chrome, Safari, Opera, and IE. This event fires after - * `onKeyPress` and `onCompositionEnd`, but before `onInput`. - * - * `beforeInput` is spec'd but not implemented in any browsers, and - * the `input` event does not provide any useful information about what has - * actually been added, contrary to the spec. Thus, `textInput` is the best - * available event to identify the characters that have actually been inserted - * into the target node. - */ -var BeforeInputEventPlugin = { +module.exports = Cancellation; - eventTypes: eventTypes, +},{}],91:[function(require,module,exports){ +var invariant = require('react/lib/invariant'); +var merge = require('qs/lib/utils').merge; +var qs = require('qs'); - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { +var paramCompileMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$]*)|[*.()\[\]\\+|{}^$]/g; +var paramInjectMatcher = /:([a-zA-Z_$][a-zA-Z0-9_$?]*[?]?)|[*]/g; +var paramInjectTrailingSlashMatcher = /\/\/\?|\/\?/g; +var queryMatcher = /\?(.+)/; - var chars; +var _compiledPatterns = {}; - if (canUseTextInputEvent) { - switch (topLevelType) { - case topLevelTypes.topKeyPress: - /** - * If native `textInput` events are available, our goal is to make - * use of them. However, there is a special case: the spacebar key. - * In Webkit, preventing default on a spacebar `textInput` event - * cancels character insertion, but it *also* causes the browser - * to fall back to its default spacebar behavior of scrolling the - * page. - * - * Tracking at: - * https://code.google.com/p/chromium/issues/detail?id=355103 - * - * To avoid this issue, use the keypress event as if no `textInput` - * event is available. - */ - var which = nativeEvent.which; - if (which !== SPACEBAR_CODE) { - return; - } +function compilePattern(pattern) { + if (!(pattern in _compiledPatterns)) { + var paramNames = []; + var source = pattern.replace(paramCompileMatcher, function (match, paramName) { + if (paramName) { + paramNames.push(paramName); + return '([^/?#]+)'; + } else if (match === '*') { + paramNames.push('splat'); + return '(.*?)'; + } else { + return '\\' + match; + } + }); - hasSpaceKeypress = true; - chars = SPACEBAR_CHAR; - break; + _compiledPatterns[pattern] = { + matcher: new RegExp('^' + source + '$', 'i'), + paramNames: paramNames + }; + } - case topLevelTypes.topTextInput: - // Record the characters to be added to the DOM. - chars = nativeEvent.data; + return _compiledPatterns[pattern]; +} - // If it's a spacebar character, assume that we have already handled - // it at the keypress level and bail immediately. Android Chrome - // doesn't give us keycodes, so we need to blacklist it. - if (chars === SPACEBAR_CHAR && hasSpaceKeypress) { - return; - } +var Path = { - // Otherwise, carry on. - break; + /** + * Safely decodes special characters in the given URL path. + */ + decode: function (path) { + return decodeURI(path.replace(/\+/g, ' ')); + }, - default: - // For other native event types, do nothing. - return; - } - } else { - switch (topLevelType) { - case topLevelTypes.topPaste: - // If a paste event occurs after a keypress, throw out the input - // chars. Paste events should not lead to BeforeInput events. - fallbackChars = null; - break; - case topLevelTypes.topKeyPress: - /** - * As of v27, Firefox may fire keypress events even when no character - * will be inserted. A few possibilities: - * - * - `which` is `0`. Arrow keys, Esc key, etc. - * - * - `which` is the pressed key code, but no char is available. - * Ex: 'AltGr + d` in Polish. There is no modified character for - * this key combination and no character is inserted into the - * document, but FF fires the keypress for char code `100` anyway. - * No `input` event will occur. - * - * - `which` is the pressed key code, but a command combination is - * being used. Ex: `Cmd+C`. No character is inserted, and no - * `input` event will occur. - */ - if (nativeEvent.which && !isKeypressCommand(nativeEvent)) { - fallbackChars = String.fromCharCode(nativeEvent.which); - } - break; - case topLevelTypes.topCompositionEnd: - fallbackChars = nativeEvent.data; - break; - } + /** + * Safely encodes special characters in the given URL path. + */ + encode: function (path) { + return encodeURI(path).replace(/%20/g, '+'); + }, - // If no changes have occurred to the fallback string, no relevant - // event has fired and we're done. - if (fallbackChars === null) { - return; - } + /** + * Returns an array of the names of all parameters in the given pattern. + */ + extractParamNames: function (pattern) { + return compilePattern(pattern).paramNames; + }, - chars = fallbackChars; - } + /** + * Extracts the portions of the given URL path that match the given pattern + * and returns an object of param name => value pairs. Returns null if the + * pattern does not match the given path. + */ + extractParams: function (pattern, path) { + var object = compilePattern(pattern); + var match = path.match(object.matcher); - // If no characters are being inserted, no BeforeInput event should - // be fired. - if (!chars) { - return; - } + if (!match) + return null; - var event = SyntheticInputEvent.getPooled( - eventTypes.beforeInput, - topLevelTargetID, - nativeEvent - ); + var params = {}; - event.data = chars; - fallbackChars = null; - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } -}; + object.paramNames.forEach(function (paramName, index) { + params[paramName] = match[index + 1]; + }); -module.exports = BeforeInputEventPlugin; + return params; + }, -},{"./EventConstants":121,"./EventPropagators":126,"./ExecutionEnvironment":127,"./SyntheticInputEvent":195,"./keyOf":240}],109:[function(require,module,exports){ -/** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CSSProperty - */ + /** + * Returns a version of the given route path with params interpolated. Throws + * if there is a dynamic segment of the route path for which there is no param. + */ + injectParams: function (pattern, params) { + params = params || {}; -"use strict"; + var splatIndex = 0; -/** - * CSS properties which accept numbers but are not in units of "px". - */ -var isUnitlessNumber = { - columnCount: true, - fillOpacity: true, - flex: true, - flexGrow: true, - flexShrink: true, - fontWeight: true, - lineClamp: true, - lineHeight: true, - opacity: true, - order: true, - orphans: true, - widows: true, - zIndex: true, - zoom: true -}; + return pattern.replace(paramInjectMatcher, function (match, paramName) { + paramName = paramName || 'splat'; -/** - * @param {string} prefix vendor-specific prefix, eg: Webkit - * @param {string} key style name, eg: transitionDuration - * @return {string} style name prefixed with `prefix`, properly camelCased, eg: - * WebkitTransitionDuration - */ -function prefixKey(prefix, key) { - return prefix + key.charAt(0).toUpperCase() + key.substring(1); -} + // If param is optional don't check for existence + if (paramName.slice(-1) !== '?') { + invariant( + params[paramName] != null, + 'Missing "' + paramName + '" parameter for path "' + pattern + '"' + ); + } else { + paramName = paramName.slice(0, -1); -/** - * Support style names that may come passed in prefixed by adding permutations - * of vendor prefixes. - */ -var prefixes = ['Webkit', 'ms', 'Moz', 'O']; + if (params[paramName] == null) + return ''; + } -// Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an -// infinite loop, because it iterates over the newly added props too. -Object.keys(isUnitlessNumber).forEach(function(prop) { - prefixes.forEach(function(prefix) { - isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop]; - }); -}); + var segment; + if (paramName === 'splat' && Array.isArray(params[paramName])) { + segment = params[paramName][splatIndex++]; -/** - * Most style properties can be unset by doing .style[prop] = '' but IE8 - * doesn't like doing that with shorthand properties so for the properties that - * IE8 breaks on, which are listed here, we instead unset each of the - * individual properties. See http://bugs.jquery.com/ticket/12385. - * The 4-value 'clock' properties like margin, padding, border-width seem to - * behave without any problems. Curiously, list-style works too without any - * special prodding. - */ -var shorthandPropertyExpansions = { - background: { - backgroundImage: true, - backgroundPosition: true, - backgroundRepeat: true, - backgroundColor: true - }, - border: { - borderWidth: true, - borderStyle: true, - borderColor: true + invariant( + segment != null, + 'Missing splat # ' + splatIndex + ' for path "' + pattern + '"' + ); + } else { + segment = params[paramName]; + } + + return segment; + }).replace(paramInjectTrailingSlashMatcher, '/'); }, - borderBottom: { - borderBottomWidth: true, - borderBottomStyle: true, - borderBottomColor: true + + /** + * Returns an object that is the result of parsing any query string contained + * in the given path, null if the path contains no query string. + */ + extractQuery: function (path) { + var match = path.match(queryMatcher); + return match && qs.parse(match[1]); }, - borderLeft: { - borderLeftWidth: true, - borderLeftStyle: true, - borderLeftColor: true + + /** + * Returns a version of the given path without the query string. + */ + withoutQuery: function (path) { + return path.replace(queryMatcher, ''); }, - borderRight: { - borderRightWidth: true, - borderRightStyle: true, - borderRightColor: true + + /** + * Returns a version of the given path with the parameters in the given + * query merged into the query string. + */ + withQuery: function (path, query) { + var existingQuery = Path.extractQuery(path); + + if (existingQuery) + query = query ? merge(existingQuery, query) : existingQuery; + + var queryString = query && qs.stringify(query); + + if (queryString) + return Path.withoutQuery(path) + '?' + queryString; + + return path; }, - borderTop: { - borderTopWidth: true, - borderTopStyle: true, - borderTopColor: true + + /** + * Returns true if the given path is absolute. + */ + isAbsolute: function (path) { + return path.charAt(0) === '/'; }, - font: { - fontStyle: true, - fontVariant: true, - fontWeight: true, - fontSize: true, - lineHeight: true, - fontFamily: true + + /** + * Returns a normalized version of the given path. + */ + normalize: function (path, parentRoute) { + return path.replace(/^\/*/, '/'); + }, + + /** + * Joins two URL paths together. + */ + join: function (a, b) { + return a.replace(/\/*$/, '/') + b; } -}; -var CSSProperty = { - isUnitlessNumber: isUnitlessNumber, - shorthandPropertyExpansions: shorthandPropertyExpansions }; -module.exports = CSSProperty; - -},{}],110:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CSSPropertyOperations - * @typechecks static-only - */ +module.exports = Path; -"use strict"; +},{"qs":102,"qs/lib/utils":106,"react/lib/invariant":238}],92:[function(require,module,exports){ +var Promise = require('when/lib/Promise'); -var CSSProperty = require("./CSSProperty"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); +// TODO: Use process.env.NODE_ENV check + envify to enable +// when's promise monitor here when in dev. -var camelizeStyleName = require("./camelizeStyleName"); -var dangerousStyleValue = require("./dangerousStyleValue"); -var hyphenateStyleName = require("./hyphenateStyleName"); -var memoizeStringOnly = require("./memoizeStringOnly"); -var warning = require("./warning"); +module.exports = Promise; -var processStyleName = memoizeStringOnly(function(styleName) { - return hyphenateStyleName(styleName); -}); +},{"when/lib/Promise":107}],93:[function(require,module,exports){ +var PropTypes = { -var styleFloatAccessor = 'cssFloat'; -if (ExecutionEnvironment.canUseDOM) { - // IE8 only supports accessing cssFloat (standard) as styleFloat - if (document.documentElement.style.cssFloat === undefined) { - styleFloatAccessor = 'styleFloat'; + /** + * Requires that the value of a prop be falsy. + */ + falsy: function (props, propName, elementName) { + if (props[propName]) + return new Error('<' + elementName + '> may not have a "' + propName + '" prop'); } -} -if ("production" !== process.env.NODE_ENV) { - var warnedStyleNames = {}; +}; - var warnHyphenatedStyleName = function(name) { - if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) { - return; - } +module.exports = PropTypes; - warnedStyleNames[name] = true; - ("production" !== process.env.NODE_ENV ? warning( - false, - 'Unsupported style property ' + name + '. Did you mean ' + - camelizeStyleName(name) + '?' - ) : null); - }; +},{}],94:[function(require,module,exports){ +/** + * Encapsulates a redirect to the given route. + */ +function Redirect(to, params, query) { + this.to = to; + this.params = params; + this.query = query; } +module.exports = Redirect; + +},{}],95:[function(require,module,exports){ +var assign = require('react/lib/Object.assign'); +var reversedArray = require('./reversedArray'); +var Redirect = require('./Redirect'); +var Promise = require('./Promise'); + /** - * Operations for dealing with CSS properties. + * Runs all hook functions serially and calls callback(error) when finished. + * A hook may return a promise if it needs to execute asynchronously. */ -var CSSPropertyOperations = { - - /** - * Serializes a mapping of style properties for use as inline styles: - * - * > createMarkupForStyles({width: '200px', height: 0}) - * "width:200px;height:0;" - * - * Undefined values are ignored so that declarative programming is easier. - * The result should be HTML-escaped before insertion into the DOM. - * - * @param {object} styles - * @return {?string} - */ - createMarkupForStyles: function(styles) { - var serialized = ''; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - if ("production" !== process.env.NODE_ENV) { - if (styleName.indexOf('-') > -1) { - warnHyphenatedStyleName(styleName); - } - } - var styleValue = styles[styleName]; - if (styleValue != null) { - serialized += processStyleName(styleName) + ':'; - serialized += dangerousStyleValue(styleName, styleValue) + ';'; - } - } - return serialized || null; - }, +function runHooks(hooks, callback) { + try { + var promise = hooks.reduce(function (promise, hook) { + // The first hook to use transition.wait makes the rest + // of the transition async from that point forward. + return promise ? promise.then(hook) : hook(); + }, null); + } catch (error) { + return callback(error); // Sync error. + } - /** - * Sets the value for multiple styles on a node. If a value is specified as - * '' (empty string), the corresponding style property will be unset. - * - * @param {DOMElement} node - * @param {object} styles - */ - setValueForStyles: function(node, styles) { - var style = node.style; - for (var styleName in styles) { - if (!styles.hasOwnProperty(styleName)) { - continue; - } - if ("production" !== process.env.NODE_ENV) { - if (styleName.indexOf('-') > -1) { - warnHyphenatedStyleName(styleName); - } - } - var styleValue = dangerousStyleValue(styleName, styles[styleName]); - if (styleName === 'float') { - styleName = styleFloatAccessor; - } - if (styleValue) { - style[styleName] = styleValue; - } else { - var expansion = CSSProperty.shorthandPropertyExpansions[styleName]; - if (expansion) { - // Shorthand property that IE8 won't like unsetting, so unset each - // component to placate it - for (var individualStyleName in expansion) { - style[individualStyleName] = ''; - } - } else { - style[styleName] = ''; - } - } - } + if (promise) { + // Use setTimeout to break the promise chain. + promise.then(function () { + setTimeout(callback); + }, function (error) { + setTimeout(function () { + callback(error); + }); + }); + } else { + callback(); } +} + +/** + * Calls the willTransitionFrom hook of all handlers in the given matches + * serially in reverse with the transition object and the current instance of + * the route's handler, so that the deepest nested handlers are called first. + * Calls callback(error) when finished. + */ +function runTransitionFromHooks(transition, routes, components, callback) { + components = reversedArray(components); -}; + var hooks = reversedArray(routes).map(function (route, index) { + return function () { + var handler = route.handler; -module.exports = CSSPropertyOperations; + if (!transition.isAborted && handler.willTransitionFrom) + return handler.willTransitionFrom(transition, components[index]); + + var promise = transition._promise; + transition._promise = null; + + return promise; + }; + }); + + runHooks(hooks, callback); +} -}).call(this,require('_process')) -},{"./CSSProperty":109,"./ExecutionEnvironment":127,"./camelizeStyleName":206,"./dangerousStyleValue":212,"./hyphenateStyleName":231,"./memoizeStringOnly":242,"./warning":252,"_process":258}],111:[function(require,module,exports){ -(function (process){ /** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CallbackQueue + * Calls the willTransitionTo hook of all handlers in the given matches + * serially with the transition object and any params that apply to that + * handler. Calls callback(error) when finished. */ +function runTransitionToHooks(transition, routes, params, query, callback) { + var hooks = routes.map(function (route) { + return function () { + var handler = route.handler; -"use strict"; + if (!transition.isAborted && handler.willTransitionTo) + handler.willTransitionTo(transition, params, query); -var PooledClass = require("./PooledClass"); + var promise = transition._promise; + transition._promise = null; -var assign = require("./Object.assign"); -var invariant = require("./invariant"); + return promise; + }; + }); + + runHooks(hooks, callback); +} /** - * A specialized pseudo-event module to help keep track of components waiting to - * be notified when their DOM representations are available for use. - * - * This implements `PooledClass`, so you should never need to instantiate this. - * Instead, use `CallbackQueue.getPooled()`. + * Encapsulates a transition to a given path. * - * @class ReactMountReady - * @implements PooledClass - * @internal + * The willTransitionTo and willTransitionFrom handlers receive + * an instance of this class as their first argument. */ -function CallbackQueue() { - this._callbacks = null; - this._contexts = null; +function Transition(path, retry) { + this.path = path; + this.abortReason = null; + this.isAborted = false; + this.retry = retry.bind(this); + this._promise = null; } -assign(CallbackQueue.prototype, { +assign(Transition.prototype, { - /** - * Enqueues a callback to be invoked when `notifyAll` is invoked. - * - * @param {function} callback Invoked when `notifyAll` is invoked. - * @param {?object} context Context to call `callback` with. - * @internal - */ - enqueue: function(callback, context) { - this._callbacks = this._callbacks || []; - this._contexts = this._contexts || []; - this._callbacks.push(callback); - this._contexts.push(context); + abort: function (reason) { + if (this.isAborted) { + // First abort wins. + return; + } + + this.abortReason = reason; + this.isAborted = true; }, - /** - * Invokes all enqueued callbacks and clears the queue. This is invoked after - * the DOM representation of a component has been created or updated. - * - * @internal - */ - notifyAll: function() { - var callbacks = this._callbacks; - var contexts = this._contexts; - if (callbacks) { - ("production" !== process.env.NODE_ENV ? invariant( - callbacks.length === contexts.length, - "Mismatched list of contexts in callback queue" - ) : invariant(callbacks.length === contexts.length)); - this._callbacks = null; - this._contexts = null; - for (var i = 0, l = callbacks.length; i < l; i++) { - callbacks[i].call(contexts[i]); - } - callbacks.length = 0; - contexts.length = 0; - } + redirect: function (to, params, query) { + this.abort(new Redirect(to, params, query)); }, - /** - * Resets the internal queue. - * - * @internal - */ - reset: function() { - this._callbacks = null; - this._contexts = null; + wait: function (value) { + this._promise = Promise.resolve(value); }, - /** - * `PooledClass` looks for this. - */ - destructor: function() { - this.reset(); + from: function (routes, components, callback) { + return runTransitionFromHooks(this, routes, components, callback); + }, + + to: function (routes, params, query, callback) { + return runTransitionToHooks(this, routes, params, query, callback); } }); -PooledClass.addPoolingTo(CallbackQueue); +module.exports = Transition; -module.exports = CallbackQueue; +},{"./Promise":92,"./Redirect":94,"./reversedArray":99,"react/lib/Object.assign":137}],96:[function(require,module,exports){ +(function (process){ +var React = require('react'); +var warning = require('react/lib/warning'); +var invariant = require('react/lib/invariant'); +var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; +var ImitateBrowserBehavior = require('../behaviors/ImitateBrowserBehavior'); +var RouteHandler = require('../components/RouteHandler'); +var LocationActions = require('../actions/LocationActions'); +var HashLocation = require('../locations/HashLocation'); +var HistoryLocation = require('../locations/HistoryLocation'); +var RefreshLocation = require('../locations/RefreshLocation'); +var NavigationContext = require('../mixins/NavigationContext'); +var StateContext = require('../mixins/StateContext'); +var Scrolling = require('../mixins/Scrolling'); +var createRoutesFromChildren = require('./createRoutesFromChildren'); +var supportsHistory = require('./supportsHistory'); +var Transition = require('./Transition'); +var PropTypes = require('./PropTypes'); +var Redirect = require('./Redirect'); +var Cancellation = require('./Cancellation'); +var Path = require('./Path'); -}).call(this,require('_process')) -},{"./Object.assign":132,"./PooledClass":133,"./invariant":233,"_process":258}],112:[function(require,module,exports){ /** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. + * The default location for new routers. + */ +var DEFAULT_LOCATION = canUseDOM ? HashLocation : '/'; + +/** + * The default scroll behavior for new routers. + */ +var DEFAULT_SCROLL_BEHAVIOR = canUseDOM ? ImitateBrowserBehavior : null; + +/** + * The default error handler for new routers. + */ +function defaultErrorHandler(error) { + // Throw so we don't silently swallow async errors. + throw error; // This error probably originated in a transition hook. +} + +/** + * The default aborted transition handler for new routers. + */ +function defaultAbortHandler(abortReason, location) { + if (typeof location === 'string') + throw new Error('Unhandled aborted transition! Reason: ' + abortReason); + + if (abortReason instanceof Cancellation) { + return; + } else if (abortReason instanceof Redirect) { + location.replace(this.makePath(abortReason.to, abortReason.params, abortReason.query)); + } else { + location.pop(); + } +} + +function findMatch(pathname, routes, defaultRoute, notFoundRoute) { + var match, route, params; + + for (var i = 0, len = routes.length; i < len; ++i) { + route = routes[i]; + + // Check the subtree first to find the most deeply-nested match. + match = findMatch(pathname, route.childRoutes, route.defaultRoute, route.notFoundRoute); + + if (match != null) { + match.routes.unshift(route); + return match; + } + + // No routes in the subtree matched, so check this route. + params = Path.extractParams(route.path, pathname); + + if (params) + return createMatch(route, params); + } + + // No routes matched, so try the default route if there is one. + if (defaultRoute && (params = Path.extractParams(defaultRoute.path, pathname))) + return createMatch(defaultRoute, params); + + // Last attempt: does the "not found" route match? + if (notFoundRoute && (params = Path.extractParams(notFoundRoute.path, pathname))) + return createMatch(notFoundRoute, params); + + return match; +} + +function createMatch(route, params) { + return { routes: [ route ], params: params }; +} + +function hasMatch(routes, route, prevParams, nextParams) { + return routes.some(function (r) { + if (r !== route) + return false; + + var paramNames = route.paramNames; + var paramName; + + for (var i = 0, len = paramNames.length; i < len; ++i) { + paramName = paramNames[i]; + + if (nextParams[paramName] !== prevParams[paramName]) + return false; + } + + return true; + }); +} + +/** + * Creates and returns a new router using the given options. A router + * is a ReactComponent class that knows how to react to changes in the + * URL and keep the contents of the page in sync. + * + * Options may be any of the following: * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * - routes (required) The route config + * - location The location to use. Defaults to HashLocation when + * the DOM is available, "/" otherwise + * - scrollBehavior The scroll behavior to use. Defaults to ImitateBrowserBehavior + * when the DOM is available, null otherwise + * - onError A function that is used to handle errors + * - onAbort A function that is used to handle aborted transitions * - * @providesModule ChangeEventPlugin + * When rendering in a server-side environment, the location should simply + * be the URL path that was used in the request, including the query string. */ +function createRouter(options) { + options = options || {}; -"use strict"; - -var EventConstants = require("./EventConstants"); -var EventPluginHub = require("./EventPluginHub"); -var EventPropagators = require("./EventPropagators"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var ReactUpdates = require("./ReactUpdates"); -var SyntheticEvent = require("./SyntheticEvent"); - -var isEventSupported = require("./isEventSupported"); -var isTextInputElement = require("./isTextInputElement"); -var keyOf = require("./keyOf"); + if (typeof options === 'function') { + options = { routes: options }; // Router.create() + } else if (Array.isArray(options)) { + options = { routes: options }; // Router.create([ , ]) + } -var topLevelTypes = EventConstants.topLevelTypes; + var routes = []; + var namedRoutes = {}; + var components = []; + var location = options.location || DEFAULT_LOCATION; + var scrollBehavior = options.scrollBehavior || DEFAULT_SCROLL_BEHAVIOR; + var onError = options.onError || defaultErrorHandler; + var onAbort = options.onAbort || defaultAbortHandler; + var state = {}; + var nextState = {}; + var pendingTransition = null; -var eventTypes = { - change: { - phasedRegistrationNames: { - bubbled: keyOf({onChange: null}), - captured: keyOf({onChangeCapture: null}) - }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topChange, - topLevelTypes.topClick, - topLevelTypes.topFocus, - topLevelTypes.topInput, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyUp, - topLevelTypes.topSelectionChange - ] + function updateState() { + state = nextState; + nextState = {}; } -}; -/** - * For IE shims - */ -var activeElement = null; -var activeElementID = null; -var activeElementValue = null; -var activeElementValueProp = null; + // Automatically fall back to full page refreshes in + // browsers that don't support the HTML history API. + if (location === HistoryLocation && !supportsHistory()) + location = RefreshLocation; -/** - * SECTION: handle `change` event - */ -function shouldUseChangeEvent(elem) { - return ( - elem.nodeName === 'SELECT' || - (elem.nodeName === 'INPUT' && elem.type === 'file') - ); -} + var router = React.createClass({ -var doesChangeEventBubble = false; -if (ExecutionEnvironment.canUseDOM) { - // See `handleChange` comment below - doesChangeEventBubble = isEventSupported('change') && ( - !('documentMode' in document) || document.documentMode > 8 - ); -} + displayName: 'Router', -function manualDispatchChangeEvent(nativeEvent) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - activeElementID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); + mixins: [ NavigationContext, StateContext, Scrolling ], - // If change and propertychange bubbled, we'd just bind to it like all the - // other events and have it go through ReactBrowserEventEmitter. Since it - // doesn't, we manually listen for the events and so we have to enqueue and - // process the abstract event manually. - // - // Batching is necessary here in order to ensure that all event handlers run - // before the next rerender (including event handlers attached to ancestor - // elements instead of directly on the input). Without this, controlled - // components don't work properly in conjunction with event bubbling because - // the component is rerendered and the value reverted before all the event - // handlers can run. See https://github.com/facebook/react/issues/708. - ReactUpdates.batchedUpdates(runEventInBatch, event); -} + statics: { -function runEventInBatch(event) { - EventPluginHub.enqueueEvents(event); - EventPluginHub.processEventQueue(); -} + defaultRoute: null, + notFoundRoute: null, -function startWatchingForChangeEventIE8(target, targetID) { - activeElement = target; - activeElementID = targetID; - activeElement.attachEvent('onchange', manualDispatchChangeEvent); -} + /** + * Adds routes to this router from the given children object (see ReactChildren). + */ + addRoutes: function (children) { + routes.push.apply(routes, createRoutesFromChildren(children, this, namedRoutes)); + }, -function stopWatchingForChangeEventIE8() { - if (!activeElement) { - return; - } - activeElement.detachEvent('onchange', manualDispatchChangeEvent); - activeElement = null; - activeElementID = null; -} + /** + * Returns an absolute URL path created from the given route + * name, URL parameters, and query. + */ + makePath: function (to, params, query) { + var path; + if (Path.isAbsolute(to)) { + path = Path.normalize(to); + } else { + var route = namedRoutes[to]; -function getTargetIDForChangeEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topChange) { - return topLevelTargetID; - } -} -function handleEventsForChangeEventIE8( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topFocus) { - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForChangeEventIE8(); - startWatchingForChangeEventIE8(topLevelTarget, topLevelTargetID); - } else if (topLevelType === topLevelTypes.topBlur) { - stopWatchingForChangeEventIE8(); - } -} + invariant( + route, + 'Unable to find ', + to + ); + path = route.path; + } -/** - * SECTION: handle `input` event - */ -var isInputEventSupported = false; -if (ExecutionEnvironment.canUseDOM) { - // IE9 claims to support the input event but fails to trigger it when - // deleting text, so we ignore its input events - isInputEventSupported = isEventSupported('input') && ( - !('documentMode' in document) || document.documentMode > 9 - ); -} + return Path.withQuery(Path.injectParams(path, params), query); + }, -/** - * (For old IE.) Replacement getter/setter for the `value` property that gets - * set on the active element. - */ -var newValueProp = { - get: function() { - return activeElementValueProp.get.call(this); - }, - set: function(val) { - // Cast to a string so we can do equality checks. - activeElementValue = '' + val; - activeElementValueProp.set.call(this, val); - } -}; + /** + * Returns a string that may safely be used as the href of a link + * to the route with the given name, URL parameters, and query. + */ + makeHref: function (to, params, query) { + var path = this.makePath(to, params, query); + return (location === HashLocation) ? '#' + path : path; + }, -/** - * (For old IE.) Starts tracking propertychange events on the passed-in element - * and override the value property so that we can distinguish user events from - * value changes in JS. - */ -function startWatchingForValueChange(target, targetID) { - activeElement = target; - activeElementID = targetID; - activeElementValue = target.value; - activeElementValueProp = Object.getOwnPropertyDescriptor( - target.constructor.prototype, - 'value' - ); + /** + * Transitions to the URL specified in the arguments by pushing + * a new URL onto the history stack. + */ + transitionTo: function (to, params, query) { + invariant( + typeof location !== 'string', + 'You cannot use transitionTo with a static location' + ); - Object.defineProperty(activeElement, 'value', newValueProp); - activeElement.attachEvent('onpropertychange', handlePropertyChange); -} + var path = this.makePath(to, params, query); -/** - * (For old IE.) Removes the event listeners from the currently-tracked element, - * if any exists. - */ -function stopWatchingForValueChange() { - if (!activeElement) { - return; - } + if (pendingTransition) { + // Replace so pending location does not stay in history. + location.replace(path); + } else { + location.push(path); + } + }, + + /** + * Transitions to the URL specified in the arguments by replacing + * the current URL in the history stack. + */ + replaceWith: function (to, params, query) { + invariant( + typeof location !== 'string', + 'You cannot use replaceWith with a static location' + ); - // delete restores the original property definition - delete activeElement.value; - activeElement.detachEvent('onpropertychange', handlePropertyChange); + location.replace(this.makePath(to, params, query)); + }, - activeElement = null; - activeElementID = null; - activeElementValue = null; - activeElementValueProp = null; -} + /** + * Transitions to the previous URL. + */ + goBack: function () { + invariant( + typeof location !== 'string', + 'You cannot use goBack with a static location' + ); -/** - * (For old IE.) Handles a propertychange event, sending a `change` event if - * the value of the active element has changed. - */ -function handlePropertyChange(nativeEvent) { - if (nativeEvent.propertyName !== 'value') { - return; - } - var value = nativeEvent.srcElement.value; - if (value === activeElementValue) { - return; - } - activeElementValue = value; + location.pop(); + }, - manualDispatchChangeEvent(nativeEvent); -} + /** + * Performs a match of the given pathname against this router and returns an object + * with the { routes, params } that match. Returns null if no match can be made. + */ + match: function (pathname) { + return findMatch(pathname, routes, this.defaultRoute, this.notFoundRoute) || null; + }, -/** - * If a `change` event should be fired, returns the target's ID. - */ -function getTargetIDForInputEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topInput) { - // In modern browsers (i.e., not IE8 or IE9), the input event is exactly - // what we want so fall through here and trigger an abstract event - return topLevelTargetID; - } -} + /** + * Performs a transition to the given path and calls callback(error, abortReason) + * when the transition is finished. If both arguments are null the router's state + * was updated. Otherwise the transition did not complete. + * + * In a transition, a router first determines which routes are involved by beginning + * with the current route, up the route tree to the first parent route that is shared + * with the destination route, and back down the tree to the destination route. The + * willTransitionFrom hook is invoked on all route handlers we're transitioning away + * from, in reverse nesting order. Likewise, the willTransitionTo hook is invoked on + * all route handlers we're transitioning to. + * + * Both willTransitionFrom and willTransitionTo hooks may either abort or redirect the + * transition. To resolve asynchronously, they may use transition.wait(promise). If no + * hooks wait, the transition is fully synchronous. + */ + dispatch: function (path, action, callback) { + if (pendingTransition) { + pendingTransition.abort(new Cancellation); + pendingTransition = null; + } -// For IE8 and IE9. -function handleEventsForInputEventIE( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topFocus) { - // In IE8, we can capture almost all .value changes by adding a - // propertychange handler and looking for events with propertyName - // equal to 'value' - // In IE9, propertychange fires for most input events but is buggy and - // doesn't fire when text is deleted, but conveniently, selectionchange - // appears to fire in all of the remaining cases so we catch those and - // forward the event if the value has changed - // In either case, we don't want to call the event handler if the value - // is changed from JS so we redefine a setter for `.value` that updates - // our activeElementValue variable, allowing us to ignore those changes - // - // stopWatching() should be a noop here but we call it just in case we - // missed a blur event somehow. - stopWatchingForValueChange(); - startWatchingForValueChange(topLevelTarget, topLevelTargetID); - } else if (topLevelType === topLevelTypes.topBlur) { - stopWatchingForValueChange(); - } -} + var prevPath = state.path; + if (prevPath === path) + return; // Nothing to do! -// For IE8 and IE9. -function getTargetIDForInputEventIE( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topSelectionChange || - topLevelType === topLevelTypes.topKeyUp || - topLevelType === topLevelTypes.topKeyDown) { - // On the selectionchange event, the target is just document which isn't - // helpful for us so just check activeElement instead. - // - // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire - // propertychange on the first input event after setting `value` from a - // script and fires only keydown, keypress, keyup. Catching keyup usually - // gets it and catching keydown lets us fire an event for the first - // keystroke if user does a key repeat (it'll be a little delayed: right - // before the second keystroke). Other input methods (e.g., paste) seem to - // fire selectionchange normally. - if (activeElement && activeElement.value !== activeElementValue) { - activeElementValue = activeElement.value; - return activeElementID; - } - } -} + // Record the scroll position as early as possible to + // get it before browsers try update it automatically. + if (prevPath && action !== LocationActions.REPLACE) + this.recordScrollPosition(prevPath); + var pathname = Path.withoutQuery(path); + var match = this.match(pathname); -/** - * SECTION: handle `click` event - */ -function shouldUseClickEvent(elem) { - // Use the `click` event to detect changes to checkbox and radio inputs. - // This approach works across all browsers, whereas `change` does not fire - // until `blur` in IE8. - return ( - elem.nodeName === 'INPUT' && - (elem.type === 'checkbox' || elem.type === 'radio') - ); -} + warning( + match != null, + 'No route matches path "%s". Make sure you have somewhere in your routes', + path, path + ); -function getTargetIDForClickEvent( - topLevelType, - topLevelTarget, - topLevelTargetID) { - if (topLevelType === topLevelTypes.topClick) { - return topLevelTargetID; - } -} + if (match == null) + match = {}; -/** - * This plugin creates an `onChange` event that normalizes change events - * across form elements. This event fires at a time when it's possible to - * change the element's value without seeing a flicker. - * - * Supported elements are: - * - input (see `isTextInputElement`) - * - textarea - * - select - */ -var ChangeEventPlugin = { + var prevRoutes = state.routes || []; + var prevParams = state.params || {}; - eventTypes: eventTypes, + var nextRoutes = match.routes || []; + var nextParams = match.params || {}; + var nextQuery = Path.extractQuery(path) || {}; - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { + var fromRoutes, toRoutes; + if (prevRoutes.length) { + fromRoutes = prevRoutes.filter(function (route) { + return !hasMatch(nextRoutes, route, prevParams, nextParams); + }); - var getTargetIDFunc, handleEventFunc; - if (shouldUseChangeEvent(topLevelTarget)) { - if (doesChangeEventBubble) { - getTargetIDFunc = getTargetIDForChangeEvent; - } else { - handleEventFunc = handleEventsForChangeEventIE8; - } - } else if (isTextInputElement(topLevelTarget)) { - if (isInputEventSupported) { - getTargetIDFunc = getTargetIDForInputEvent; - } else { - getTargetIDFunc = getTargetIDForInputEventIE; - handleEventFunc = handleEventsForInputEventIE; - } - } else if (shouldUseClickEvent(topLevelTarget)) { - getTargetIDFunc = getTargetIDForClickEvent; - } + toRoutes = nextRoutes.filter(function (route) { + return !hasMatch(prevRoutes, route, prevParams, nextParams); + }); + } else { + fromRoutes = []; + toRoutes = nextRoutes; + } - if (getTargetIDFunc) { - var targetID = getTargetIDFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); - if (targetID) { - var event = SyntheticEvent.getPooled( - eventTypes.change, - targetID, - nativeEvent - ); - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } - } + var transition = new Transition(path, this.replaceWith.bind(this, path)); + pendingTransition = transition; - if (handleEventFunc) { - handleEventFunc( - topLevelType, - topLevelTarget, - topLevelTargetID - ); - } - } + transition.from(fromRoutes, components, function (error) { + if (error || transition.isAborted) + return callback.call(router, error, transition); -}; + transition.to(toRoutes, nextParams, nextQuery, function (error) { + if (error || transition.isAborted) + return callback.call(router, error, transition); -module.exports = ChangeEventPlugin; + nextState.path = path; + nextState.action = action; + nextState.pathname = pathname; + nextState.routes = nextRoutes; + nextState.params = nextParams; + nextState.query = nextQuery; -},{"./EventConstants":121,"./EventPluginHub":123,"./EventPropagators":126,"./ExecutionEnvironment":127,"./ReactUpdates":185,"./SyntheticEvent":193,"./isEventSupported":234,"./isTextInputElement":236,"./keyOf":240}],113:[function(require,module,exports){ -/** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule ClientReactRootIndex - * @typechecks - */ + callback.call(router, null, transition); + }); + }); + }, -"use strict"; + /** + * Starts this router and calls callback(router, state) when the route changes. + * + * If the router's location is static (i.e. a URL path in a server environment) + * the callback is called only once. Otherwise, the location should be one of the + * Router.*Location objects (e.g. Router.HashLocation or Router.HistoryLocation). + */ + run: function (callback) { + function dispatchHandler(error, transition) { + pendingTransition = null; -var nextReactRootIndex = 0; + if (error) { + onError.call(router, error); + } else if (transition.isAborted) { + onAbort.call(router, transition.abortReason, location); + } else { + callback.call(router, router, nextState); + } + } -var ClientReactRootIndex = { - createReactRootIndex: function() { - return nextReactRootIndex++; - } -}; + if (typeof location === 'string') { + warning( + !canUseDOM || process.env.NODE_ENV === 'test', + 'You should not use a static location in a DOM environment because ' + + 'the router will not be kept in sync with the current URL' + ); -module.exports = ClientReactRootIndex; + // Dispatch the location. + router.dispatch(location, null, dispatchHandler); + } else { + invariant( + canUseDOM, + 'You cannot use %s in a non-DOM environment', + location + ); -},{}],114:[function(require,module,exports){ -/** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule CompositionEventPlugin - * @typechecks static-only - */ + // Listen for changes to the location. + function changeListener(change) { + router.dispatch(change.path, change.type, dispatchHandler); + } -"use strict"; + if (location.addChangeListener) + location.addChangeListener(changeListener); -var EventConstants = require("./EventConstants"); -var EventPropagators = require("./EventPropagators"); -var ExecutionEnvironment = require("./ExecutionEnvironment"); -var ReactInputSelection = require("./ReactInputSelection"); -var SyntheticCompositionEvent = require("./SyntheticCompositionEvent"); + // Bootstrap using the current path. + router.dispatch(location.getCurrentPath(), null, dispatchHandler); + } + } -var getTextContentAccessor = require("./getTextContentAccessor"); -var keyOf = require("./keyOf"); + }, -var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space -var START_KEYCODE = 229; + propTypes: { + children: PropTypes.falsy + }, -var useCompositionEvent = ( - ExecutionEnvironment.canUseDOM && - 'CompositionEvent' in window -); + getLocation: function () { + return location; + }, -// In IE9+, we have access to composition events, but the data supplied -// by the native compositionend event may be incorrect. In Korean, for example, -// the compositionend event contains only one character regardless of -// how many characters have been composed since compositionstart. -// We therefore use the fallback data while still using the native -// events as triggers. -var useFallbackData = ( - !useCompositionEvent || - ( - 'documentMode' in document && - document.documentMode > 8 && - document.documentMode <= 11 - ) -); + getScrollBehavior: function () { + return scrollBehavior; + }, -var topLevelTypes = EventConstants.topLevelTypes; -var currentComposition = null; + getRouteAtDepth: function (depth) { + var routes = this.state.routes; + return routes && routes[depth]; + }, -// Events and their corresponding property names. -var eventTypes = { - compositionEnd: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionEnd: null}), - captured: keyOf({onCompositionEndCapture: null}) + getRouteComponents: function () { + return components; }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionEnd, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] - }, - compositionStart: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionStart: null}), - captured: keyOf({onCompositionStartCapture: null}) + + getInitialState: function () { + updateState(); + return state; }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionStart, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] - }, - compositionUpdate: { - phasedRegistrationNames: { - bubbled: keyOf({onCompositionUpdate: null}), - captured: keyOf({onCompositionUpdateCapture: null}) + + componentWillReceiveProps: function () { + updateState(); + this.setState(state); }, - dependencies: [ - topLevelTypes.topBlur, - topLevelTypes.topCompositionUpdate, - topLevelTypes.topKeyDown, - topLevelTypes.topKeyPress, - topLevelTypes.topKeyUp, - topLevelTypes.topMouseDown - ] - } -}; -/** - * Translate native top level events into event types. - * - * @param {string} topLevelType - * @return {object} - */ -function getCompositionEventType(topLevelType) { - switch (topLevelType) { - case topLevelTypes.topCompositionStart: - return eventTypes.compositionStart; - case topLevelTypes.topCompositionEnd: - return eventTypes.compositionEnd; - case topLevelTypes.topCompositionUpdate: - return eventTypes.compositionUpdate; - } + render: function () { + return this.getRouteAtDepth(0) ? React.createElement(RouteHandler, this.props) : null; + }, + + childContextTypes: { + getRouteAtDepth: React.PropTypes.func.isRequired, + getRouteComponents: React.PropTypes.func.isRequired, + routeHandlers: React.PropTypes.array.isRequired + }, + + getChildContext: function () { + return { + getRouteComponents: this.getRouteComponents, + getRouteAtDepth: this.getRouteAtDepth, + routeHandlers: [ this ] + }; + } + + }); + + if (options.routes) + router.addRoutes(options.routes); + + return router; } -/** - * Does our fallback best-guess model think this event signifies that - * composition has begun? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackStart(topLevelType, nativeEvent) { - return ( - topLevelType === topLevelTypes.topKeyDown && - nativeEvent.keyCode === START_KEYCODE - ); +module.exports = createRouter; + +}).call(this,require('_process')) +},{"../actions/LocationActions":71,"../behaviors/ImitateBrowserBehavior":72,"../components/RouteHandler":79,"../locations/HashLocation":81,"../locations/HistoryLocation":82,"../locations/RefreshLocation":83,"../mixins/NavigationContext":86,"../mixins/Scrolling":87,"../mixins/StateContext":89,"./Cancellation":90,"./Path":91,"./PropTypes":93,"./Redirect":94,"./Transition":95,"./createRoutesFromChildren":97,"./supportsHistory":101,"_process":5,"react":258,"react/lib/ExecutionEnvironment":132,"react/lib/invariant":238,"react/lib/warning":257}],97:[function(require,module,exports){ +var React = require('react'); +var warning = require('react/lib/warning'); +var invariant = require('react/lib/invariant'); +var DefaultRoute = require('../components/DefaultRoute'); +var NotFoundRoute = require('../components/NotFoundRoute'); +var Redirect = require('../components/Redirect'); +var Route = require('../components/Route'); +var Path = require('./Path'); + +var CONFIG_ELEMENT_TYPES = [ + DefaultRoute.type, + NotFoundRoute.type, + Redirect.type, + Route.type +]; + +function createRedirectHandler(to, _params, _query) { + return React.createClass({ + statics: { + willTransitionTo: function (transition, params, query) { + transition.redirect(to, _params || params, _query || query); + } + }, + + render: function () { + return null; + } + }); } -/** - * Does our fallback mode think that this event is the end of composition? - * - * @param {string} topLevelType - * @param {object} nativeEvent - * @return {boolean} - */ -function isFallbackEnd(topLevelType, nativeEvent) { - switch (topLevelType) { - case topLevelTypes.topKeyUp: - // Command keys insert or clear IME input. - return (END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1); - case topLevelTypes.topKeyDown: - // Expect IME keyCode on each keydown. If we get any other - // code we must have exited earlier. - return (nativeEvent.keyCode !== START_KEYCODE); - case topLevelTypes.topKeyPress: - case topLevelTypes.topMouseDown: - case topLevelTypes.topBlur: - // Events are not possible without cancelling IME. - return true; - default: - return false; +function checkPropTypes(componentName, propTypes, props) { + for (var propName in propTypes) { + if (propTypes.hasOwnProperty(propName)) { + var error = propTypes[propName](props, propName, componentName); + + if (error instanceof Error) + warning(false, error.message); + } } } -/** - * Helper class stores information about selection and document state - * so we can figure out what changed at a later date. - * - * @param {DOMEventTarget} root - */ -function FallbackCompositionState(root) { - this.root = root; - this.startSelection = ReactInputSelection.getSelection(root); - this.startValue = this.getText(); -} +function createRoute(element, parentRoute, namedRoutes) { + var type = element.type; + var props = element.props; + var componentName = (type && type.displayName) || 'UnknownComponent'; -/** - * Get current text of input. - * - * @return {string} - */ -FallbackCompositionState.prototype.getText = function() { - return this.root.value || this.root[getTextContentAccessor()]; -}; + invariant( + CONFIG_ELEMENT_TYPES.indexOf(type) !== -1, + 'Unrecognized route configuration element "<%s>"', + componentName + ); -/** - * Text that has changed since the start of composition. - * - * @return {string} - */ -FallbackCompositionState.prototype.getData = function() { - var endValue = this.getText(); - var prefixLength = this.startSelection.start; - var suffixLength = this.startValue.length - this.startSelection.end; + if (type.propTypes) + checkPropTypes(componentName, type.propTypes, props); - return endValue.substr( - prefixLength, - endValue.length - suffixLength - prefixLength - ); -}; + var route = { name: props.name }; -/** - * This plugin creates `onCompositionStart`, `onCompositionUpdate` and - * `onCompositionEnd` events on inputs, textareas and contentEditable - * nodes. - */ -var CompositionEventPlugin = { + if (props.ignoreScrollBehavior) { + route.ignoreScrollBehavior = true; + } - eventTypes: eventTypes, + if (type === Redirect.type) { + route.handler = createRedirectHandler(props.to, props.params, props.query); + props.path = props.path || props.from || '*'; + } else { + route.handler = props.handler; + } - /** - * @param {string} topLevelType Record from `EventConstants`. - * @param {DOMEventTarget} topLevelTarget The listening component root node. - * @param {string} topLevelTargetID ID of `topLevelTarget`. - * @param {object} nativeEvent Native browser event. - * @return {*} An accumulation of synthetic events. - * @see {EventPluginHub.extractEvents} - */ - extractEvents: function( - topLevelType, - topLevelTarget, - topLevelTargetID, - nativeEvent) { + var parentPath = (parentRoute && parentRoute.path) || '/'; - var eventType; - var data; + if ((props.path || props.name) && type !== DefaultRoute.type && type !== NotFoundRoute.type) { + var path = props.path || props.name; - if (useCompositionEvent) { - eventType = getCompositionEventType(topLevelType); - } else if (!currentComposition) { - if (isFallbackStart(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionStart; - } - } else if (isFallbackEnd(topLevelType, nativeEvent)) { - eventType = eventTypes.compositionEnd; - } + // Relative paths extend their parent. + if (!Path.isAbsolute(path)) + path = Path.join(parentPath, path); - if (useFallbackData) { - // The current composition is stored statically and must not be - // overwritten while composition continues. - if (!currentComposition && eventType === eventTypes.compositionStart) { - currentComposition = new FallbackCompositionState(topLevelTarget); - } else if (eventType === eventTypes.compositionEnd) { - if (currentComposition) { - data = currentComposition.getData(); - currentComposition = null; - } - } - } + route.path = Path.normalize(path); + } else { + route.path = parentPath; - if (eventType) { - var event = SyntheticCompositionEvent.getPooled( - eventType, - topLevelTargetID, - nativeEvent + if (type === NotFoundRoute.type) + route.path += '*'; + } + + route.paramNames = Path.extractParamNames(route.path); + + // Make sure the route's path has all params its parent needs. + if (parentRoute && Array.isArray(parentRoute.paramNames)) { + parentRoute.paramNames.forEach(function (paramName) { + invariant( + route.paramNames.indexOf(paramName) !== -1, + 'The nested route path "%s" is missing the "%s" parameter of its parent path "%s"', + route.path, paramName, parentRoute.path ); - if (data) { - // Inject data generated from fallback path into the synthetic event. - // This matches the property of native CompositionEventInterface. - event.data = data; - } - EventPropagators.accumulateTwoPhaseDispatches(event); - return event; - } + }); } -}; -module.exports = CompositionEventPlugin; + // Make sure the route can be looked up by s. + if (props.name) { + invariant( + namedRoutes[props.name] == null, + 'You cannot use the name "%s" for more than one route', + props.name + ); -},{"./EventConstants":121,"./EventPropagators":126,"./ExecutionEnvironment":127,"./ReactInputSelection":165,"./SyntheticCompositionEvent":191,"./getTextContentAccessor":228,"./keyOf":240}],115:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMChildrenOperations - * @typechecks static-only - */ + namedRoutes[props.name] = route; + } -"use strict"; + // Handle . + if (type === NotFoundRoute.type) { + invariant( + parentRoute, + ' must have a parent ' + ); -var Danger = require("./Danger"); -var ReactMultiChildUpdateTypes = require("./ReactMultiChildUpdateTypes"); + invariant( + parentRoute.notFoundRoute == null, + 'You may not have more than one per ' + ); -var getTextContentAccessor = require("./getTextContentAccessor"); -var invariant = require("./invariant"); + parentRoute.notFoundRoute = route; -/** - * The DOM property to use when setting text content. - * - * @type {string} - * @private - */ -var textContentAccessor = getTextContentAccessor(); + return null; + } -/** - * Inserts `childNode` as a child of `parentNode` at the `index`. - * - * @param {DOMElement} parentNode Parent node in which to insert. - * @param {DOMElement} childNode Child node to insert. - * @param {number} index Index at which to insert the child. - * @internal - */ -function insertChildAt(parentNode, childNode, index) { - // By exploiting arrays returning `undefined` for an undefined index, we can - // rely exclusively on `insertBefore(node, null)` instead of also using - // `appendChild(node)`. However, using `undefined` is not allowed by all - // browsers so we must replace it with `null`. - parentNode.insertBefore( - childNode, - parentNode.childNodes[index] || null - ); -} + // Handle . + if (type === DefaultRoute.type) { + invariant( + parentRoute, + ' must have a parent ' + ); + + invariant( + parentRoute.defaultRoute == null, + 'You may not have more than one per ' + ); + + parentRoute.defaultRoute = route; + + return null; + } -var updateTextContent; -if (textContentAccessor === 'textContent') { - /** - * Sets the text content of `node` to `text`. - * - * @param {DOMElement} node Node to change - * @param {string} text New text content - */ - updateTextContent = function(node, text) { - node.textContent = text; - }; -} else { - /** - * Sets the text content of `node` to `text`. - * - * @param {DOMElement} node Node to change - * @param {string} text New text content - */ - updateTextContent = function(node, text) { - // In order to preserve newlines correctly, we can't use .innerText to set - // the contents (see #1080), so we empty the element then append a text node - while (node.firstChild) { - node.removeChild(node.firstChild); - } - if (text) { - var doc = node.ownerDocument || document; - node.appendChild(doc.createTextNode(text)); - } - }; + route.childRoutes = createRoutesFromChildren(props.children, route, namedRoutes); + + return route; } /** - * Operations for updating with DOM children. + * Creates and returns an array of route objects from the given ReactChildren. */ -var DOMChildrenOperations = { - - dangerouslyReplaceNodeWithMarkup: Danger.dangerouslyReplaceNodeWithMarkup, - - updateTextContent: updateTextContent, +function createRoutesFromChildren(children, parentRoute, namedRoutes) { + var routes = []; - /** - * Updates a component's children by processing a series of updates. The - * update configurations are each expected to have a `parentNode` property. - * - * @param {array} updates List of update configurations. - * @param {array} markupList List of markup strings. - * @internal - */ - processUpdates: function(updates, markupList) { - var update; - // Mapping from parent IDs to initial child orderings. - var initialChildren = null; - // List of children that will be moved or removed. - var updatedChildren = null; + React.Children.forEach(children, function (child) { + // Exclude s and s. + if (child = createRoute(child, parentRoute, namedRoutes)) + routes.push(child); + }); - for (var i = 0; update = updates[i]; i++) { - if (update.type === ReactMultiChildUpdateTypes.MOVE_EXISTING || - update.type === ReactMultiChildUpdateTypes.REMOVE_NODE) { - var updatedIndex = update.fromIndex; - var updatedChild = update.parentNode.childNodes[updatedIndex]; - var parentID = update.parentID; + return routes; +} - ("production" !== process.env.NODE_ENV ? invariant( - updatedChild, - 'processUpdates(): Unable to find child %s of element. This ' + - 'probably means the DOM was unexpectedly mutated (e.g., by the ' + - 'browser), usually due to forgetting a when using tables, ' + - 'nesting tags like
,

, or , or using non-SVG elements '+ - 'in an parent. Try inspecting the child nodes of the element ' + - 'with React ID `%s`.', - updatedIndex, - parentID - ) : invariant(updatedChild)); +module.exports = createRoutesFromChildren; - initialChildren = initialChildren || {}; - initialChildren[parentID] = initialChildren[parentID] || []; - initialChildren[parentID][updatedIndex] = updatedChild; +},{"../components/DefaultRoute":74,"../components/NotFoundRoute":76,"../components/Redirect":77,"../components/Route":78,"./Path":91,"react":258,"react/lib/invariant":238,"react/lib/warning":257}],98:[function(require,module,exports){ +var invariant = require('react/lib/invariant'); +var canUseDOM = require('react/lib/ExecutionEnvironment').canUseDOM; - updatedChildren = updatedChildren || []; - updatedChildren.push(updatedChild); - } - } +/** + * Returns the current scroll position of the window as { x, y }. + */ +function getWindowScrollPosition() { + invariant( + canUseDOM, + 'Cannot get current scroll position without a DOM' + ); - var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); + return { + x: window.scrollX, + y: window.scrollY + }; +} - // Remove updated children first so that `toIndex` is consistent. - if (updatedChildren) { - for (var j = 0; j < updatedChildren.length; j++) { - updatedChildren[j].parentNode.removeChild(updatedChildren[j]); - } - } +module.exports = getWindowScrollPosition; - for (var k = 0; update = updates[k]; k++) { - switch (update.type) { - case ReactMultiChildUpdateTypes.INSERT_MARKUP: - insertChildAt( - update.parentNode, - renderedMarkup[update.markupIndex], - update.toIndex - ); - break; - case ReactMultiChildUpdateTypes.MOVE_EXISTING: - insertChildAt( - update.parentNode, - initialChildren[update.parentID][update.fromIndex], - update.toIndex - ); - break; - case ReactMultiChildUpdateTypes.TEXT_CONTENT: - updateTextContent( - update.parentNode, - update.textContent - ); - break; - case ReactMultiChildUpdateTypes.REMOVE_NODE: - // Already removed by the for-loop above. - break; - } - } - } +},{"react/lib/ExecutionEnvironment":132,"react/lib/invariant":238}],99:[function(require,module,exports){ +function reversedArray(array) { + return array.slice(0).reverse(); +} -}; +module.exports = reversedArray; -module.exports = DOMChildrenOperations; +},{}],100:[function(require,module,exports){ +var createRouter = require('./createRouter'); -}).call(this,require('_process')) -},{"./Danger":118,"./ReactMultiChildUpdateTypes":171,"./getTextContentAccessor":228,"./invariant":233,"_process":258}],116:[function(require,module,exports){ -(function (process){ /** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. + * A high-level convenience method that creates, configures, and + * runs a router in one shot. The method signature is: * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. + * Router.run(routes[, location ], callback); * - * @providesModule DOMProperty - * @typechecks static-only + * Using `window.location.hash` to manage the URL, you could do: + * + * Router.run(routes, function (Handler) { + * React.render(, document.body); + * }); + * + * Using HTML5 history and a custom "cursor" prop: + * + * Router.run(routes, Router.HistoryLocation, function (Handler) { + * React.render(, document.body); + * }); + * + * Returns the newly created router. + * + * Note: If you need to specify further options for your router such + * as error/abort handling or custom scroll behavior, use Router.create + * instead. + * + * var router = Router.create(options); + * router.run(function (Handler) { + * // ... + * }); */ +function runRouter(routes, location, callback) { + if (typeof location === 'function') { + callback = location; + location = null; + } -/*jslint bitwise: true */ - -"use strict"; + var router = createRouter({ + routes: routes, + location: location + }); -var invariant = require("./invariant"); + router.run(callback); -function checkMask(value, bitmask) { - return (value & bitmask) === bitmask; + return router; } -var DOMPropertyInjection = { - /** - * Mapping from normalized, camelcased property names to a configuration that - * specifies how the associated DOM property should be accessed or rendered. - */ - MUST_USE_ATTRIBUTE: 0x1, - MUST_USE_PROPERTY: 0x2, - HAS_SIDE_EFFECTS: 0x4, - HAS_BOOLEAN_VALUE: 0x8, - HAS_NUMERIC_VALUE: 0x10, - HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, - HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, +module.exports = runRouter; - /** - * Inject some specialized knowledge about the DOM. This takes a config object - * with the following properties: - * - * isCustomAttribute: function that given an attribute name will return true - * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* - * attributes where it's impossible to enumerate all of the possible - * attribute names, - * - * Properties: object mapping DOM property name to one of the - * DOMPropertyInjection constants or null. If your attribute isn't in here, - * it won't get written to the DOM. - * - * DOMAttributeNames: object mapping React attribute name to the DOM - * attribute name. Attribute names not specified use the **lowercase** - * normalized name. - * - * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. - * Property names not specified use the normalized name. - * - * DOMMutationMethods: Properties that require special mutation methods. If - * `value` is undefined, the mutation method should unset the property. - * - * @param {object} domPropertyConfig the config as described above. +},{"./createRouter":96}],101:[function(require,module,exports){ +function supportsHistory() { + /*! taken from modernizr + * https://github.com/Modernizr/Modernizr/blob/master/LICENSE + * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js */ - injectDOMPropertyConfig: function(domPropertyConfig) { - var Properties = domPropertyConfig.Properties || {}; - var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; - var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; - var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; + var ua = navigator.userAgent; + if ((ua.indexOf('Android 2.') !== -1 || + (ua.indexOf('Android 4.0') !== -1)) && + ua.indexOf('Mobile Safari') !== -1 && + ua.indexOf('Chrome') === -1) { + return false; + } + return (window.history && 'pushState' in window.history); +} + +module.exports = supportsHistory; + +},{}],102:[function(require,module,exports){ +module.exports = require('./lib'); + +},{"./lib":103}],103:[function(require,module,exports){ +// Load modules - if (domPropertyConfig.isCustomAttribute) { - DOMProperty._isCustomAttributeFunctions.push( - domPropertyConfig.isCustomAttribute - ); - } +var Stringify = require('./stringify'); +var Parse = require('./parse'); - for (var propName in Properties) { - ("production" !== process.env.NODE_ENV ? invariant( - !DOMProperty.isStandardName.hasOwnProperty(propName), - 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + - '\'%s\' which has already been injected. You may be accidentally ' + - 'injecting the same DOM property config twice, or you may be ' + - 'injecting two configs that have conflicting property names.', - propName - ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName))); - DOMProperty.isStandardName[propName] = true; +// Declare internals - var lowerCased = propName.toLowerCase(); - DOMProperty.getPossibleStandardName[lowerCased] = propName; +var internals = {}; - if (DOMAttributeNames.hasOwnProperty(propName)) { - var attributeName = DOMAttributeNames[propName]; - DOMProperty.getPossibleStandardName[attributeName] = propName; - DOMProperty.getAttributeName[propName] = attributeName; - } else { - DOMProperty.getAttributeName[propName] = lowerCased; - } - DOMProperty.getPropertyName[propName] = - DOMPropertyNames.hasOwnProperty(propName) ? - DOMPropertyNames[propName] : - propName; +module.exports = { + stringify: Stringify, + parse: Parse +}; - if (DOMMutationMethods.hasOwnProperty(propName)) { - DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; - } else { - DOMProperty.getMutationMethod[propName] = null; - } +},{"./parse":104,"./stringify":105}],104:[function(require,module,exports){ +// Load modules - var propConfig = Properties[propName]; - DOMProperty.mustUseAttribute[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); - DOMProperty.mustUseProperty[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); - DOMProperty.hasSideEffects[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); - DOMProperty.hasBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); - DOMProperty.hasNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); - DOMProperty.hasPositiveNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); - DOMProperty.hasOverloadedBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); +var Utils = require('./utils'); - ("production" !== process.env.NODE_ENV ? invariant( - !DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName], - 'DOMProperty: Cannot require using both attribute and property: %s', - propName - ) : invariant(!DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName])); - ("production" !== process.env.NODE_ENV ? invariant( - DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName], - 'DOMProperty: Properties that have side effects must use property: %s', - propName - ) : invariant(DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName])); - ("production" !== process.env.NODE_ENV ? invariant( - !!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, - 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + - 'numeric value, but not a combination: %s', - propName - ) : invariant(!!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1)); + +// Declare internals + +var internals = { + delimiter: '&', + depth: 5, + arrayLimit: 20, + parameterLimit: 1000 +}; + + +internals.parseValues = function (str, options) { + + var obj = {}; + var parts = str.split(options.delimiter, options.parameterLimit === Infinity ? undefined : options.parameterLimit); + + for (var i = 0, il = parts.length; i < il; ++i) { + var part = parts[i]; + var pos = part.indexOf(']=') === -1 ? part.indexOf('=') : part.indexOf(']=') + 1; + + if (pos === -1) { + obj[Utils.decode(part)] = ''; + } + else { + var key = Utils.decode(part.slice(0, pos)); + var val = Utils.decode(part.slice(pos + 1)); + + if (!obj[key]) { + obj[key] = val; + } + else { + obj[key] = [].concat(obj[key]).concat(val); + } + } } - } + + return obj; }; -var defaultValueCache = {}; -/** - * DOMProperty exports lookup objects that can be used like functions: - * - * > DOMProperty.isValid['id'] - * true - * > DOMProperty.isValid['foobar'] - * undefined - * - * Although this may be confusing, it performs better in general. - * - * @see http://jsperf.com/key-exists - * @see http://jsperf.com/key-missing - */ -var DOMProperty = { - ID_ATTRIBUTE_NAME: 'data-reactid', +internals.parseObject = function (chain, val, options) { - /** - * Checks whether a property name is a standard property. - * @type {Object} - */ - isStandardName: {}, + if (!chain.length) { + return val; + } - /** - * Mapping from lowercase property names to the properly cased version, used - * to warn in the case of missing properties. - * @type {Object} - */ - getPossibleStandardName: {}, + var root = chain.shift(); - /** - * Mapping from normalized names to attribute names that differ. Attribute - * names are used when rendering markup or with `*Attribute()`. - * @type {Object} - */ - getAttributeName: {}, + var obj = {}; + if (root === '[]') { + obj = []; + obj = obj.concat(internals.parseObject(chain, val, options)); + } + else { + var cleanRoot = root[0] === '[' && root[root.length - 1] === ']' ? root.slice(1, root.length - 1) : root; + var index = parseInt(cleanRoot, 10); + if (!isNaN(index) && + root !== cleanRoot && + index <= options.arrayLimit) { - /** - * Mapping from normalized names to properties on DOM node instances. - * (This includes properties that mutate due to external factors.) - * @type {Object} - */ - getPropertyName: {}, + obj = []; + obj[index] = internals.parseObject(chain, val, options); + } + else { + obj[cleanRoot] = internals.parseObject(chain, val, options); + } + } - /** - * Mapping from normalized names to mutation methods. This will only exist if - * mutation cannot be set simply by the property or `setAttribute()`. - * @type {Object} - */ - getMutationMethod: {}, + return obj; +}; - /** - * Whether the property must be accessed and mutated as an object property. - * @type {Object} - */ - mustUseAttribute: {}, - /** - * Whether the property must be accessed and mutated using `*Attribute()`. - * (This includes anything that fails ` in `.) - * @type {Object} - */ - mustUseProperty: {}, +internals.parseKeys = function (key, val, options) { - /** - * Whether or not setting a value causes side effects such as triggering - * resources to be loaded or text selection changes. We must ensure that - * the value is only set if it has changed. - * @type {Object} - */ - hasSideEffects: {}, + if (!key) { + return; + } - /** - * Whether the property should be removed when set to a falsey value. - * @type {Object} - */ - hasBooleanValue: {}, + // The regex chunks - /** - * Whether the property must be numeric or parse as a - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasNumericValue: {}, + var parent = /^([^\[\]]*)/; + var child = /(\[[^\[\]]*\])/g; - /** - * Whether the property must be positive numeric or parse as a positive - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasPositiveNumericValue: {}, + // Get the parent - /** - * Whether the property can be used as a flag as well as with a value. Removed - * when strictly equal to false; present without a value when strictly equal - * to true; present with a value otherwise. - * @type {Object} - */ - hasOverloadedBooleanValue: {}, + var segment = parent.exec(key); + + // Don't allow them to overwrite object prototype properties + + if (Object.prototype.hasOwnProperty(segment[1])) { + return; + } + + // Stash the parent if it exists + + var keys = []; + if (segment[1]) { + keys.push(segment[1]); + } + + // Loop through children appending to the array until we hit depth - /** - * All of the isCustomAttribute() functions that have been injected. - */ - _isCustomAttributeFunctions: [], + var i = 0; + while ((segment = child.exec(key)) !== null && i < options.depth) { - /** - * Checks whether a property name is a custom attribute. - * @method - */ - isCustomAttribute: function(attributeName) { - for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { - var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; - if (isCustomAttributeFn(attributeName)) { - return true; - } + ++i; + if (!Object.prototype.hasOwnProperty(segment[1].replace(/\[|\]/g, ''))) { + keys.push(segment[1]); + } } - return false; - }, - /** - * Returns the default property value for a DOM property (i.e., not an - * attribute). Most default values are '' or false, but not all. Worse yet, - * some (in particular, `type`) vary depending on the type of element. - * - * TODO: Is it better to grab all the possible properties when creating an - * element to avoid having to create the same element twice? - */ - getDefaultValueForProperty: function(nodeName, prop) { - var nodeDefaults = defaultValueCache[nodeName]; - var testElement; - if (!nodeDefaults) { - defaultValueCache[nodeName] = nodeDefaults = {}; - } - if (!(prop in nodeDefaults)) { - testElement = document.createElement(nodeName); - nodeDefaults[prop] = testElement[prop]; + // If there's a remainder, just add whatever is left + + if (segment) { + keys.push('[' + key.slice(segment.index) + ']'); } - return nodeDefaults[prop]; - }, - injection: DOMPropertyInjection + return internals.parseObject(keys, val, options); }; -module.exports = DOMProperty; - -}).call(this,require('_process')) -},{"./invariant":233,"_process":258}],117:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule DOMPropertyOperations - * @typechecks static-only - */ -"use strict"; +module.exports = function (str, options) { -var DOMProperty = require("./DOMProperty"); + if (str === '' || + str === null || + typeof str === 'undefined') { -var escapeTextForBrowser = require("./escapeTextForBrowser"); -var memoizeStringOnly = require("./memoizeStringOnly"); -var warning = require("./warning"); + return {}; + } -function shouldIgnoreValue(name, value) { - return value == null || - (DOMProperty.hasBooleanValue[name] && !value) || - (DOMProperty.hasNumericValue[name] && isNaN(value)) || - (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) || - (DOMProperty.hasOverloadedBooleanValue[name] && value === false); -} + options = options || {}; + options.delimiter = typeof options.delimiter === 'string' || Utils.isRegExp(options.delimiter) ? options.delimiter : internals.delimiter; + options.depth = typeof options.depth === 'number' ? options.depth : internals.depth; + options.arrayLimit = typeof options.arrayLimit === 'number' ? options.arrayLimit : internals.arrayLimit; + options.parameterLimit = typeof options.parameterLimit === 'number' ? options.parameterLimit : internals.parameterLimit; -var processAttributeNameAndPrefix = memoizeStringOnly(function(name) { - return escapeTextForBrowser(name) + '="'; -}); + var tempObj = typeof str === 'string' ? internals.parseValues(str, options) : str; + var obj = {}; -if ("production" !== process.env.NODE_ENV) { - var reactProps = { - children: true, - dangerouslySetInnerHTML: true, - key: true, - ref: true - }; - var warnedProperties = {}; + // Iterate over the keys and setup the new object - var warnUnknownProperty = function(name) { - if (reactProps.hasOwnProperty(name) && reactProps[name] || - warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { - return; + var keys = Object.keys(tempObj); + for (var i = 0, il = keys.length; i < il; ++i) { + var key = keys[i]; + var newObj = internals.parseKeys(key, tempObj[key], options); + obj = Utils.merge(obj, newObj); } - warnedProperties[name] = true; - var lowerCasedName = name.toLowerCase(); + return Utils.compact(obj); +}; - // data-* attributes should be lowercase; suggest the lowercase version - var standardName = ( - DOMProperty.isCustomAttribute(lowerCasedName) ? - lowerCasedName : - DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? - DOMProperty.getPossibleStandardName[lowerCasedName] : - null - ); +},{"./utils":106}],105:[function(require,module,exports){ +// Load modules - // For now, only warn when we have a suggested correction. This prevents - // logging too much when using transferPropsTo. - ("production" !== process.env.NODE_ENV ? warning( - standardName == null, - 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?' - ) : null); +var Utils = require('./utils'); - }; -} -/** - * Operations for dealing with DOM properties. - */ -var DOMPropertyOperations = { +// Declare internals - /** - * Creates markup for the ID property. - * - * @param {string} id Unescaped ID. - * @return {string} Markup string. - */ - createMarkupForID: function(id) { - return processAttributeNameAndPrefix(DOMProperty.ID_ATTRIBUTE_NAME) + - escapeTextForBrowser(id) + '"'; - }, +var internals = { + delimiter: '&' +}; - /** - * Creates markup for a property. - * - * @param {string} name - * @param {*} value - * @return {?string} Markup string, or null if the property was invalid. - */ - createMarkupForProperty: function(name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - if (shouldIgnoreValue(name, value)) { - return ''; - } - var attributeName = DOMProperty.getAttributeName[name]; - if (DOMProperty.hasBooleanValue[name] || - (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) { - return escapeTextForBrowser(attributeName); - } - return processAttributeNameAndPrefix(attributeName) + - escapeTextForBrowser(value) + '"'; - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - return ''; - } - return processAttributeNameAndPrefix(name) + - escapeTextForBrowser(value) + '"'; - } else if ("production" !== process.env.NODE_ENV) { - warnUnknownProperty(name); + +internals.stringify = function (obj, prefix) { + + if (Utils.isBuffer(obj)) { + obj = obj.toString(); + } + else if (obj instanceof Date) { + obj = obj.toISOString(); + } + else if (obj === null) { + obj = ''; } - return null; - }, - /** - * Sets the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - * @param {*} value - */ - setValueForProperty: function(node, name, value) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; - if (mutationMethod) { - mutationMethod(node, value); - } else if (shouldIgnoreValue(name, value)) { - this.deleteValueForProperty(node, name); - } else if (DOMProperty.mustUseAttribute[name]) { - // `setAttribute` with objects becomes only `[object]` in IE8/9, - // ('' + value) makes it output the correct toString()-value. - node.setAttribute(DOMProperty.getAttributeName[name], '' + value); - } else { - var propName = DOMProperty.getPropertyName[name]; - // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the - // property type before comparing; only `value` does and is string. - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== ('' + value)) { - // Contrary to `setAttribute`, object properties are properly - // `toString`ed by IE8/9. - node[propName] = value; - } - } - } else if (DOMProperty.isCustomAttribute(name)) { - if (value == null) { - node.removeAttribute(name); - } else { - node.setAttribute(name, '' + value); - } - } else if ("production" !== process.env.NODE_ENV) { - warnUnknownProperty(name); + if (typeof obj === 'string' || + typeof obj === 'number' || + typeof obj === 'boolean') { + + return [encodeURIComponent(prefix) + '=' + encodeURIComponent(obj)]; } - }, - /** - * Deletes the value for a property on a node. - * - * @param {DOMElement} node - * @param {string} name - */ - deleteValueForProperty: function(node, name) { - if (DOMProperty.isStandardName.hasOwnProperty(name) && - DOMProperty.isStandardName[name]) { - var mutationMethod = DOMProperty.getMutationMethod[name]; - if (mutationMethod) { - mutationMethod(node, undefined); - } else if (DOMProperty.mustUseAttribute[name]) { - node.removeAttribute(DOMProperty.getAttributeName[name]); - } else { - var propName = DOMProperty.getPropertyName[name]; - var defaultValue = DOMProperty.getDefaultValueForProperty( - node.nodeName, - propName - ); - if (!DOMProperty.hasSideEffects[name] || - ('' + node[propName]) !== defaultValue) { - node[propName] = defaultValue; + var values = []; + + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + values = values.concat(internals.stringify(obj[key], prefix + '[' + key + ']')); } - } - } else if (DOMProperty.isCustomAttribute(name)) { - node.removeAttribute(name); - } else if ("production" !== process.env.NODE_ENV) { - warnUnknownProperty(name); } - } + return values; }; -module.exports = DOMPropertyOperations; -}).call(this,require('_process')) -},{"./DOMProperty":116,"./escapeTextForBrowser":216,"./memoizeStringOnly":242,"./warning":252,"_process":258}],118:[function(require,module,exports){ -(function (process){ -/** - * Copyright 2013-2014, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - * @providesModule Danger - * @typechecks static-only - */ +module.exports = function (obj, options) { -/*jslint evil: true, sub: true */ + options = options || {}; + var delimiter = typeof options.delimiter === 'undefined' ? internals.delimiter : options.delimiter; -"use strict"; + var keys = []; -var ExecutionEnvironment = require("./ExecutionEnvironment"); + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + keys = keys.concat(internals.stringify(obj[key], key)); + } + } -var createNodesFromMarkup = require("./createNodesFromMarkup"); -var emptyFunction = require("./emptyFunction"); -var getMarkupWrap = require("./getMarkupWrap"); -var invariant = require("./invariant"); + return keys.join(delimiter); +}; -var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; -var RESULT_INDEX_ATTR = 'data-danger-index'; +},{"./utils":106}],106:[function(require,module,exports){ +(function (Buffer){ +// Load modules -/** - * Extracts the `nodeName` from a string of markup. - * - * NOTE: Extracting the `nodeName` does not require a regular expression match - * because we make assumptions about React-generated markup (i.e. there are no - * spaces surrounding the opening tag and there is at least one attribute). - * - * @param {string} markup String of markup. - * @return {string} Node name of the supplied markup. - * @see http://jsperf.com/extract-nodename - */ -function getNodeName(markup) { - return markup.substring(1, markup.indexOf(' ')); -} -var Danger = { +// Declare internals - /** - * Renders markup into an array of nodes. The markup is expected to render - * into a list of root nodes. Also, the length of `resultList` and - * `markupList` should be the same. - * - * @param {array} markupList List of markup strings to render. - * @return {array} List of rendered nodes. - * @internal - */ - dangerouslyRenderMarkup: function(markupList) { - ("production" !== process.env.NODE_ENV ? invariant( - ExecutionEnvironment.canUseDOM, - 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + - 'thread. Make sure `window` and `document` are available globally ' + - 'before requiring React when unit testing or use ' + - 'React.renderToString for server rendering.' - ) : invariant(ExecutionEnvironment.canUseDOM)); - var nodeName; - var markupByNodeName = {}; - // Group markup by `nodeName` if a wrap is necessary, else by '*'. - for (var i = 0; i < markupList.length; i++) { - ("production" !== process.env.NODE_ENV ? invariant( - markupList[i], - 'dangerouslyRenderMarkup(...): Missing markup.' - ) : invariant(markupList[i])); - nodeName = getNodeName(markupList[i]); - nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; - markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; - markupByNodeName[nodeName][i] = markupList[i]; - } - var resultList = []; - var resultListAssignmentCount = 0; - for (nodeName in markupByNodeName) { - if (!markupByNodeName.hasOwnProperty(nodeName)) { - continue; - } - var markupListByNodeName = markupByNodeName[nodeName]; +var internals = {}; - // This for-in loop skips the holes of the sparse array. The order of - // iteration should follow the order of assignment, which happens to match - // numerical index order, but we don't rely on that. - for (var resultIndex in markupListByNodeName) { - if (markupListByNodeName.hasOwnProperty(resultIndex)) { - var markup = markupListByNodeName[resultIndex]; - // Push the requested markup with an additional RESULT_INDEX_ATTR - // attribute. If the markup does not start with a < character, it - // will be discarded below (with an appropriate console.error). - markupListByNodeName[resultIndex] = markup.replace( - OPEN_TAG_NAME_EXP, - // This index will be parsed back out below. - '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' - ); +exports.arrayToObject = function (source) { + + var obj = {}; + for (var i = 0, il = source.length; i < il; ++i) { + if (typeof source[i] !== 'undefined') { + + obj[i] = source[i]; } - } + } - // Render each group of markup with similar wrapping `nodeName`. - var renderNodes = createNodesFromMarkup( - markupListByNodeName.join(''), - emptyFunction // Do nothing special with

, or , or using non-SVG elements '+ + 'in an parent. Try inspecting the child nodes of the element ' + + 'with React ID `%s`.', + updatedIndex, + parentID + ) : invariant(updatedChild)); + + initialChildren = initialChildren || {}; + initialChildren[parentID] = initialChildren[parentID] || []; + initialChildren[parentID][updatedIndex] = updatedChild; + + updatedChildren = updatedChildren || []; + updatedChildren.push(updatedChild); + } + } + + var renderedMarkup = Danger.dangerouslyRenderMarkup(markupList); + + // Remove updated children first so that `toIndex` is consistent. + if (updatedChildren) { + for (var j = 0; j < updatedChildren.length; j++) { + updatedChildren[j].parentNode.removeChild(updatedChildren[j]); + } + } + + for (var k = 0; update = updates[k]; k++) { + switch (update.type) { + case ReactMultiChildUpdateTypes.INSERT_MARKUP: + insertChildAt( + update.parentNode, + renderedMarkup[update.markupIndex], + update.toIndex + ); + break; + case ReactMultiChildUpdateTypes.MOVE_EXISTING: + insertChildAt( + update.parentNode, + initialChildren[update.parentID][update.fromIndex], + update.toIndex + ); + break; + case ReactMultiChildUpdateTypes.TEXT_CONTENT: + updateTextContent( + update.parentNode, + update.textContent + ); + break; + case ReactMultiChildUpdateTypes.REMOVE_NODE: + // Already removed by the for-loop above. + break; + } + } + } + +}; + +module.exports = DOMChildrenOperations; + +}).call(this,require('_process')) +},{"./Danger":123,"./ReactMultiChildUpdateTypes":176,"./getTextContentAccessor":233,"./invariant":238,"_process":5}],121:[function(require,module,exports){ +(function (process){ +/** + * Copyright 2013-2014, Facebook, Inc. + * All rights reserved. * - * Components can also be "owned" by other components. Being owned by another - * component means being constructed by that component. This is different from - * being the child of a component, which means having a DOM representation that - * is a child of the DOM representation of that component. + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. * - * @class ReactComponent + * @providesModule DOMProperty + * @typechecks static-only */ -var ReactComponent = { - injection: { - injectEnvironment: function(ReactComponentEnvironment) { - ("production" !== process.env.NODE_ENV ? invariant( - !injected, - 'ReactComponent: injectEnvironment() can only be called once.' - ) : invariant(!injected)); - mountImageIntoNode = ReactComponentEnvironment.mountImageIntoNode; - unmountIDFromEnvironment = - ReactComponentEnvironment.unmountIDFromEnvironment; - ReactComponent.BackendIDOperations = - ReactComponentEnvironment.BackendIDOperations; - injected = true; - } - }, +/*jslint bitwise: true */ - /** - * @internal - */ - LifeCycle: ComponentLifeCycle, +"use strict"; + +var invariant = require("./invariant"); +function checkMask(value, bitmask) { + return (value & bitmask) === bitmask; +} + +var DOMPropertyInjection = { /** - * Injected module that provides ability to mutate individual properties. - * Injected into the base class because many different subclasses need access - * to this. - * - * @internal + * Mapping from normalized, camelcased property names to a configuration that + * specifies how the associated DOM property should be accessed or rendered. */ - BackendIDOperations: null, + MUST_USE_ATTRIBUTE: 0x1, + MUST_USE_PROPERTY: 0x2, + HAS_SIDE_EFFECTS: 0x4, + HAS_BOOLEAN_VALUE: 0x8, + HAS_NUMERIC_VALUE: 0x10, + HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, + HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, /** - * Base functionality for every ReactComponent constructor. Mixed into the - * `ReactComponent` prototype, but exposed statically for easy access. + * Inject some specialized knowledge about the DOM. This takes a config object + * with the following properties: * - * @lends {ReactComponent.prototype} + * isCustomAttribute: function that given an attribute name will return true + * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* + * attributes where it's impossible to enumerate all of the possible + * attribute names, + * + * Properties: object mapping DOM property name to one of the + * DOMPropertyInjection constants or null. If your attribute isn't in here, + * it won't get written to the DOM. + * + * DOMAttributeNames: object mapping React attribute name to the DOM + * attribute name. Attribute names not specified use the **lowercase** + * normalized name. + * + * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. + * Property names not specified use the normalized name. + * + * DOMMutationMethods: Properties that require special mutation methods. If + * `value` is undefined, the mutation method should unset the property. + * + * @param {object} domPropertyConfig the config as described above. */ - Mixin: { - - /** - * Checks whether or not this component is mounted. - * - * @return {boolean} True if mounted, false otherwise. - * @final - * @protected - */ - isMounted: function() { - return this._lifeCycleState === ComponentLifeCycle.MOUNTED; - }, + injectDOMPropertyConfig: function(domPropertyConfig) { + var Properties = domPropertyConfig.Properties || {}; + var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; + var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; + var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; - /** - * Sets a subset of the props. - * - * @param {object} partialProps Subset of the next props. - * @param {?function} callback Called after props are updated. - * @final - * @public - */ - setProps: function(partialProps, callback) { - // Merge with the pending element if it exists, otherwise with existing - // element props. - var element = this._pendingElement || this._currentElement; - this.replaceProps( - assign({}, element.props, partialProps), - callback + if (domPropertyConfig.isCustomAttribute) { + DOMProperty._isCustomAttributeFunctions.push( + domPropertyConfig.isCustomAttribute ); - }, + } - /** - * Replaces all of the props. - * - * @param {object} props New props. - * @param {?function} callback Called after props are updated. - * @final - * @public - */ - replaceProps: function(props, callback) { - ("production" !== process.env.NODE_ENV ? invariant( - this.isMounted(), - 'replaceProps(...): Can only update a mounted component.' - ) : invariant(this.isMounted())); + for (var propName in Properties) { ("production" !== process.env.NODE_ENV ? invariant( - this._mountDepth === 0, - 'replaceProps(...): You called `setProps` or `replaceProps` on a ' + - 'component with a parent. This is an anti-pattern since props will ' + - 'get reactively updated when rendered. Instead, change the owner\'s ' + - '`render` method to pass the correct value as props to the component ' + - 'where it is created.' - ) : invariant(this._mountDepth === 0)); - // This is a deoptimized path. We optimize for always having a element. - // This creates an extra internal element. - this._pendingElement = ReactElement.cloneAndReplaceProps( - this._pendingElement || this._currentElement, - props - ); - ReactUpdates.enqueueUpdate(this, callback); - }, - - /** - * Schedule a partial update to the props. Only used for internal testing. - * - * @param {object} partialProps Subset of the next props. - * @param {?function} callback Called after props are updated. - * @final - * @internal - */ - _setPropsInternal: function(partialProps, callback) { - // This is a deoptimized path. We optimize for always having a element. - // This creates an extra internal element. - var element = this._pendingElement || this._currentElement; - this._pendingElement = ReactElement.cloneAndReplaceProps( - element, - assign({}, element.props, partialProps) - ); - ReactUpdates.enqueueUpdate(this, callback); - }, - - /** - * Base constructor for all React components. - * - * Subclasses that override this method should make sure to invoke - * `ReactComponent.Mixin.construct.call(this, ...)`. - * - * @param {ReactElement} element - * @internal - */ - construct: function(element) { - // This is the public exposed props object after it has been processed - // with default props. The element's props represents the true internal - // state of the props. - this.props = element.props; - // Record the component responsible for creating this component. - // This is accessible through the element but we maintain an extra - // field for compatibility with devtools and as a way to make an - // incremental update. TODO: Consider deprecating this field. - this._owner = element._owner; - - // All components start unmounted. - this._lifeCycleState = ComponentLifeCycle.UNMOUNTED; + !DOMProperty.isStandardName.hasOwnProperty(propName), + 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + + '\'%s\' which has already been injected. You may be accidentally ' + + 'injecting the same DOM property config twice, or you may be ' + + 'injecting two configs that have conflicting property names.', + propName + ) : invariant(!DOMProperty.isStandardName.hasOwnProperty(propName))); - // See ReactUpdates. - this._pendingCallbacks = null; + DOMProperty.isStandardName[propName] = true; - // We keep the old element and a reference to the pending element - // to track updates. - this._currentElement = element; - this._pendingElement = null; - }, + var lowerCased = propName.toLowerCase(); + DOMProperty.getPossibleStandardName[lowerCased] = propName; - /** - * Initializes the component, renders markup, and registers event listeners. - * - * NOTE: This does not insert any nodes into the DOM. - * - * Subclasses that override this method should make sure to invoke - * `ReactComponent.Mixin.mountComponent.call(this, ...)`. - * - * @param {string} rootID DOM ID of the root node. - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @param {number} mountDepth number of components in the owner hierarchy. - * @return {?string} Rendered markup to be inserted into the DOM. - * @internal - */ - mountComponent: function(rootID, transaction, mountDepth) { - ("production" !== process.env.NODE_ENV ? invariant( - !this.isMounted(), - 'mountComponent(%s, ...): Can only mount an unmounted component. ' + - 'Make sure to avoid storing components between renders or reusing a ' + - 'single component instance in multiple places.', - rootID - ) : invariant(!this.isMounted())); - var ref = this._currentElement.ref; - if (ref != null) { - var owner = this._currentElement._owner; - ReactOwner.addComponentAsRefTo(this, ref, owner); - } - this._rootNodeID = rootID; - this._lifeCycleState = ComponentLifeCycle.MOUNTED; - this._mountDepth = mountDepth; - // Effectively: return ''; - }, + if (DOMAttributeNames.hasOwnProperty(propName)) { + var attributeName = DOMAttributeNames[propName]; + DOMProperty.getPossibleStandardName[attributeName] = propName; + DOMProperty.getAttributeName[propName] = attributeName; + } else { + DOMProperty.getAttributeName[propName] = lowerCased; + } - /** - * Releases any resources allocated by `mountComponent`. - * - * NOTE: This does not remove any nodes from the DOM. - * - * Subclasses that override this method should make sure to invoke - * `ReactComponent.Mixin.unmountComponent.call(this)`. - * - * @internal - */ - unmountComponent: function() { - ("production" !== process.env.NODE_ENV ? invariant( - this.isMounted(), - 'unmountComponent(): Can only unmount a mounted component.' - ) : invariant(this.isMounted())); - var ref = this._currentElement.ref; - if (ref != null) { - ReactOwner.removeComponentAsRefFrom(this, ref, this._owner); + DOMProperty.getPropertyName[propName] = + DOMPropertyNames.hasOwnProperty(propName) ? + DOMPropertyNames[propName] : + propName; + + if (DOMMutationMethods.hasOwnProperty(propName)) { + DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; + } else { + DOMProperty.getMutationMethod[propName] = null; } - unmountIDFromEnvironment(this._rootNodeID); - this._rootNodeID = null; - this._lifeCycleState = ComponentLifeCycle.UNMOUNTED; - }, - /** - * Given a new instance of this component, updates the rendered DOM nodes - * as if that instance was rendered instead. - * - * Subclasses that override this method should make sure to invoke - * `ReactComponent.Mixin.receiveComponent.call(this, ...)`. - * - * @param {object} nextComponent Next set of properties. - * @param {ReactReconcileTransaction} transaction - * @internal - */ - receiveComponent: function(nextElement, transaction) { + var propConfig = Properties[propName]; + DOMProperty.mustUseAttribute[propName] = + checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); + DOMProperty.mustUseProperty[propName] = + checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); + DOMProperty.hasSideEffects[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); + DOMProperty.hasBooleanValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); + DOMProperty.hasNumericValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); + DOMProperty.hasPositiveNumericValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); + DOMProperty.hasOverloadedBooleanValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); + ("production" !== process.env.NODE_ENV ? invariant( - this.isMounted(), - 'receiveComponent(...): Can only update a mounted component.' - ) : invariant(this.isMounted())); - this._pendingElement = nextElement; - this.performUpdateIfNecessary(transaction); - }, + !DOMProperty.mustUseAttribute[propName] || + !DOMProperty.mustUseProperty[propName], + 'DOMProperty: Cannot require using both attribute and property: %s', + propName + ) : invariant(!DOMProperty.mustUseAttribute[propName] || + !DOMProperty.mustUseProperty[propName])); + ("production" !== process.env.NODE_ENV ? invariant( + DOMProperty.mustUseProperty[propName] || + !DOMProperty.hasSideEffects[propName], + 'DOMProperty: Properties that have side effects must use property: %s', + propName + ) : invariant(DOMProperty.mustUseProperty[propName] || + !DOMProperty.hasSideEffects[propName])); + ("production" !== process.env.NODE_ENV ? invariant( + !!DOMProperty.hasBooleanValue[propName] + + !!DOMProperty.hasNumericValue[propName] + + !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, + 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + + 'numeric value, but not a combination: %s', + propName + ) : invariant(!!DOMProperty.hasBooleanValue[propName] + + !!DOMProperty.hasNumericValue[propName] + + !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1)); + } + } +}; +var defaultValueCache = {}; - /** - * If `_pendingElement` is set, update the component. - * - * @param {ReactReconcileTransaction} transaction - * @internal - */ - performUpdateIfNecessary: function(transaction) { - if (this._pendingElement == null) { - return; - } - var prevElement = this._currentElement; - var nextElement = this._pendingElement; - this._currentElement = nextElement; - this.props = nextElement.props; - this._owner = nextElement._owner; - this._pendingElement = null; - this.updateComponent(transaction, prevElement); - }, +/** + * DOMProperty exports lookup objects that can be used like functions: + * + * > DOMProperty.isValid['id'] + * true + * > DOMProperty.isValid['foobar'] + * undefined + * + * Although this may be confusing, it performs better in general. + * + * @see http://jsperf.com/key-exists + * @see http://jsperf.com/key-missing + */ +var DOMProperty = { - /** - * Updates the component's currently mounted representation. - * - * @param {ReactReconcileTransaction} transaction - * @param {object} prevElement - * @internal - */ - updateComponent: function(transaction, prevElement) { - var nextElement = this._currentElement; + ID_ATTRIBUTE_NAME: 'data-reactid', - // If either the owner or a `ref` has changed, make sure the newest owner - // has stored a reference to `this`, and the previous owner (if different) - // has forgotten the reference to `this`. We use the element instead - // of the public this.props because the post processing cannot determine - // a ref. The ref conceptually lives on the element. + /** + * Checks whether a property name is a standard property. + * @type {Object} + */ + isStandardName: {}, - // TODO: Should this even be possible? The owner cannot change because - // it's forbidden by shouldUpdateReactComponent. The ref can change - // if you swap the keys of but not the refs. Reconsider where this check - // is made. It probably belongs where the key checking and - // instantiateReactComponent is done. + /** + * Mapping from lowercase property names to the properly cased version, used + * to warn in the case of missing properties. + * @type {Object} + */ + getPossibleStandardName: {}, - if (nextElement._owner !== prevElement._owner || - nextElement.ref !== prevElement.ref) { - if (prevElement.ref != null) { - ReactOwner.removeComponentAsRefFrom( - this, prevElement.ref, prevElement._owner - ); - } - // Correct, even if the owner is the same, and only the ref has changed. - if (nextElement.ref != null) { - ReactOwner.addComponentAsRefTo( - this, - nextElement.ref, - nextElement._owner - ); - } - } - }, + /** + * Mapping from normalized names to attribute names that differ. Attribute + * names are used when rendering markup or with `*Attribute()`. + * @type {Object} + */ + getAttributeName: {}, - /** - * Mounts this component and inserts it into the DOM. - * - * @param {string} rootID DOM ID of the root node. - * @param {DOMElement} container DOM element to mount into. - * @param {boolean} shouldReuseMarkup If true, do not insert markup - * @final - * @internal - * @see {ReactMount.render} - */ - mountComponentIntoNode: function(rootID, container, shouldReuseMarkup) { - var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(); - transaction.perform( - this._mountComponentIntoNode, - this, - rootID, - container, - transaction, - shouldReuseMarkup - ); - ReactUpdates.ReactReconcileTransaction.release(transaction); - }, + /** + * Mapping from normalized names to properties on DOM node instances. + * (This includes properties that mutate due to external factors.) + * @type {Object} + */ + getPropertyName: {}, - /** - * @param {string} rootID DOM ID of the root node. - * @param {DOMElement} container DOM element to mount into. - * @param {ReactReconcileTransaction} transaction - * @param {boolean} shouldReuseMarkup If true, do not insert markup - * @final - * @private - */ - _mountComponentIntoNode: function( - rootID, - container, - transaction, - shouldReuseMarkup) { - var markup = this.mountComponent(rootID, transaction, 0); - mountImageIntoNode(markup, container, shouldReuseMarkup); - }, + /** + * Mapping from normalized names to mutation methods. This will only exist if + * mutation cannot be set simply by the property or `setAttribute()`. + * @type {Object} + */ + getMutationMethod: {}, + + /** + * Whether the property must be accessed and mutated as an object property. + * @type {Object} + */ + mustUseAttribute: {}, + + /** + * Whether the property must be accessed and mutated using `*Attribute()`. + * (This includes anything that fails ` in `.) + * @type {Object} + */ + mustUseProperty: {}, + + /** + * Whether or not setting a value causes side effects such as triggering + * resources to be loaded or text selection changes. We must ensure that + * the value is only set if it has changed. + * @type {Object} + */ + hasSideEffects: {}, + + /** + * Whether the property should be removed when set to a falsey value. + * @type {Object} + */ + hasBooleanValue: {}, - /** - * Checks if this component is owned by the supplied `owner` component. - * - * @param {ReactComponent} owner Component to check. - * @return {boolean} True if `owners` owns this component. - * @final - * @internal - */ - isOwnedBy: function(owner) { - return this._owner === owner; - }, + /** + * Whether the property must be numeric or parse as a + * numeric and should be removed when set to a falsey value. + * @type {Object} + */ + hasNumericValue: {}, - /** - * Gets another component, that shares the same owner as this one, by ref. - * - * @param {string} ref of a sibling Component. - * @return {?ReactComponent} the actual sibling Component. - * @final - * @internal - */ - getSiblingByRef: function(ref) { - var owner = this._owner; - if (!owner || !owner.refs) { - return null; + /** + * Whether the property must be positive numeric or parse as a positive + * numeric and should be removed when set to a falsey value. + * @type {Object} + */ + hasPositiveNumericValue: {}, + + /** + * Whether the property can be used as a flag as well as with a value. Removed + * when strictly equal to false; present without a value when strictly equal + * to true; present with a value otherwise. + * @type {Object} + */ + hasOverloadedBooleanValue: {}, + + /** + * All of the isCustomAttribute() functions that have been injected. + */ + _isCustomAttributeFunctions: [], + + /** + * Checks whether a property name is a custom attribute. + * @method + */ + isCustomAttribute: function(attributeName) { + for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { + var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; + if (isCustomAttributeFn(attributeName)) { + return true; } - return owner.refs[ref]; } - } + return false; + }, + + /** + * Returns the default property value for a DOM property (i.e., not an + * attribute). Most default values are '' or false, but not all. Worse yet, + * some (in particular, `type`) vary depending on the type of element. + * + * TODO: Is it better to grab all the possible properties when creating an + * element to avoid having to create the same element twice? + */ + getDefaultValueForProperty: function(nodeName, prop) { + var nodeDefaults = defaultValueCache[nodeName]; + var testElement; + if (!nodeDefaults) { + defaultValueCache[nodeName] = nodeDefaults = {}; + } + if (!(prop in nodeDefaults)) { + testElement = document.createElement(nodeName); + nodeDefaults[prop] = testElement[prop]; + } + return nodeDefaults[prop]; + }, + + injection: DOMPropertyInjection }; -module.exports = ReactComponent; +module.exports = DOMProperty; }).call(this,require('_process')) -},{"./Object.assign":132,"./ReactElement":158,"./ReactOwner":173,"./ReactUpdates":185,"./invariant":233,"./keyMirror":239,"_process":258}],139:[function(require,module,exports){ +},{"./invariant":238,"_process":5}],122:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2014, Facebook, Inc. @@ -13978,119 +11886,194 @@ module.exports = ReactComponent; * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactComponentBrowserEnvironment + * @providesModule DOMPropertyOperations + * @typechecks static-only */ -/*jslint evil: true */ - "use strict"; -var ReactDOMIDOperations = require("./ReactDOMIDOperations"); -var ReactMarkupChecksum = require("./ReactMarkupChecksum"); -var ReactMount = require("./ReactMount"); -var ReactPerf = require("./ReactPerf"); -var ReactReconcileTransaction = require("./ReactReconcileTransaction"); +var DOMProperty = require("./DOMProperty"); -var getReactRootElementInContainer = require("./getReactRootElementInContainer"); -var invariant = require("./invariant"); -var setInnerHTML = require("./setInnerHTML"); +var escapeTextForBrowser = require("./escapeTextForBrowser"); +var memoizeStringOnly = require("./memoizeStringOnly"); +var warning = require("./warning"); +function shouldIgnoreValue(name, value) { + return value == null || + (DOMProperty.hasBooleanValue[name] && !value) || + (DOMProperty.hasNumericValue[name] && isNaN(value)) || + (DOMProperty.hasPositiveNumericValue[name] && (value < 1)) || + (DOMProperty.hasOverloadedBooleanValue[name] && value === false); +} -var ELEMENT_NODE_TYPE = 1; -var DOC_NODE_TYPE = 9; +var processAttributeNameAndPrefix = memoizeStringOnly(function(name) { + return escapeTextForBrowser(name) + '="'; +}); + +if ("production" !== process.env.NODE_ENV) { + var reactProps = { + children: true, + dangerouslySetInnerHTML: true, + key: true, + ref: true + }; + var warnedProperties = {}; + + var warnUnknownProperty = function(name) { + if (reactProps.hasOwnProperty(name) && reactProps[name] || + warnedProperties.hasOwnProperty(name) && warnedProperties[name]) { + return; + } + + warnedProperties[name] = true; + var lowerCasedName = name.toLowerCase(); + + // data-* attributes should be lowercase; suggest the lowercase version + var standardName = ( + DOMProperty.isCustomAttribute(lowerCasedName) ? + lowerCasedName : + DOMProperty.getPossibleStandardName.hasOwnProperty(lowerCasedName) ? + DOMProperty.getPossibleStandardName[lowerCasedName] : + null + ); + + // For now, only warn when we have a suggested correction. This prevents + // logging too much when using transferPropsTo. + ("production" !== process.env.NODE_ENV ? warning( + standardName == null, + 'Unknown DOM property ' + name + '. Did you mean ' + standardName + '?' + ) : null); + }; +} /** - * Abstracts away all functionality of `ReactComponent` requires knowledge of - * the browser context. + * Operations for dealing with DOM properties. */ -var ReactComponentBrowserEnvironment = { - ReactReconcileTransaction: ReactReconcileTransaction, - - BackendIDOperations: ReactDOMIDOperations, +var DOMPropertyOperations = { /** - * If a particular environment requires that some resources be cleaned up, - * specify this in the injected Mixin. In the DOM, we would likely want to - * purge any cached node ID lookups. + * Creates markup for the ID property. * - * @private + * @param {string} id Unescaped ID. + * @return {string} Markup string. */ - unmountIDFromEnvironment: function(rootNodeID) { - ReactMount.purgeID(rootNodeID); + createMarkupForID: function(id) { + return processAttributeNameAndPrefix(DOMProperty.ID_ATTRIBUTE_NAME) + + escapeTextForBrowser(id) + '"'; }, /** - * @param {string} markup Markup string to place into the DOM Element. - * @param {DOMElement} container DOM Element to insert markup into. - * @param {boolean} shouldReuseMarkup Should reuse the existing markup in the - * container if possible. + * Creates markup for a property. + * + * @param {string} name + * @param {*} value + * @return {?string} Markup string, or null if the property was invalid. */ - mountImageIntoNode: ReactPerf.measure( - 'ReactComponentBrowserEnvironment', - 'mountImageIntoNode', - function(markup, container, shouldReuseMarkup) { - ("production" !== process.env.NODE_ENV ? invariant( - container && ( - container.nodeType === ELEMENT_NODE_TYPE || - container.nodeType === DOC_NODE_TYPE - ), - 'mountComponentIntoNode(...): Target container is not valid.' - ) : invariant(container && ( - container.nodeType === ELEMENT_NODE_TYPE || - container.nodeType === DOC_NODE_TYPE - ))); - - if (shouldReuseMarkup) { - if (ReactMarkupChecksum.canReuseMarkup( - markup, - getReactRootElementInContainer(container))) { - return; - } else { - ("production" !== process.env.NODE_ENV ? invariant( - container.nodeType !== DOC_NODE_TYPE, - 'You\'re trying to render a component to the document using ' + - 'server rendering but the checksum was invalid. This usually ' + - 'means you rendered a different component type or props on ' + - 'the client from the one on the server, or your render() ' + - 'methods are impure. React cannot handle this case due to ' + - 'cross-browser quirks by rendering at the document root. You ' + - 'should look for environment dependent code in your components ' + - 'and ensure the props are the same client and server side.' - ) : invariant(container.nodeType !== DOC_NODE_TYPE)); + createMarkupForProperty: function(name, value) { + if (DOMProperty.isStandardName.hasOwnProperty(name) && + DOMProperty.isStandardName[name]) { + if (shouldIgnoreValue(name, value)) { + return ''; + } + var attributeName = DOMProperty.getAttributeName[name]; + if (DOMProperty.hasBooleanValue[name] || + (DOMProperty.hasOverloadedBooleanValue[name] && value === true)) { + return escapeTextForBrowser(attributeName); + } + return processAttributeNameAndPrefix(attributeName) + + escapeTextForBrowser(value) + '"'; + } else if (DOMProperty.isCustomAttribute(name)) { + if (value == null) { + return ''; + } + return processAttributeNameAndPrefix(name) + + escapeTextForBrowser(value) + '"'; + } else if ("production" !== process.env.NODE_ENV) { + warnUnknownProperty(name); + } + return null; + }, - if ("production" !== process.env.NODE_ENV) { - console.warn( - 'React attempted to use reuse markup in a container but the ' + - 'checksum was invalid. This generally means that you are ' + - 'using server rendering and the markup generated on the ' + - 'server was not what the client was expecting. React injected ' + - 'new markup to compensate which works but you have lost many ' + - 'of the benefits of server rendering. Instead, figure out ' + - 'why the markup being generated is different on the client ' + - 'or server.' - ); - } + /** + * Sets the value for a property on a node. + * + * @param {DOMElement} node + * @param {string} name + * @param {*} value + */ + setValueForProperty: function(node, name, value) { + if (DOMProperty.isStandardName.hasOwnProperty(name) && + DOMProperty.isStandardName[name]) { + var mutationMethod = DOMProperty.getMutationMethod[name]; + if (mutationMethod) { + mutationMethod(node, value); + } else if (shouldIgnoreValue(name, value)) { + this.deleteValueForProperty(node, name); + } else if (DOMProperty.mustUseAttribute[name]) { + // `setAttribute` with objects becomes only `[object]` in IE8/9, + // ('' + value) makes it output the correct toString()-value. + node.setAttribute(DOMProperty.getAttributeName[name], '' + value); + } else { + var propName = DOMProperty.getPropertyName[name]; + // Must explicitly cast values for HAS_SIDE_EFFECTS-properties to the + // property type before comparing; only `value` does and is string. + if (!DOMProperty.hasSideEffects[name] || + ('' + node[propName]) !== ('' + value)) { + // Contrary to `setAttribute`, object properties are properly + // `toString`ed by IE8/9. + node[propName] = value; } } + } else if (DOMProperty.isCustomAttribute(name)) { + if (value == null) { + node.removeAttribute(name); + } else { + node.setAttribute(name, '' + value); + } + } else if ("production" !== process.env.NODE_ENV) { + warnUnknownProperty(name); + } + }, - ("production" !== process.env.NODE_ENV ? invariant( - container.nodeType !== DOC_NODE_TYPE, - 'You\'re trying to render a component to the document but ' + - 'you didn\'t use server rendering. We can\'t do this ' + - 'without using server rendering due to cross-browser quirks. ' + - 'See renderComponentToString() for server rendering.' - ) : invariant(container.nodeType !== DOC_NODE_TYPE)); - - setInnerHTML(container, markup); + /** + * Deletes the value for a property on a node. + * + * @param {DOMElement} node + * @param {string} name + */ + deleteValueForProperty: function(node, name) { + if (DOMProperty.isStandardName.hasOwnProperty(name) && + DOMProperty.isStandardName[name]) { + var mutationMethod = DOMProperty.getMutationMethod[name]; + if (mutationMethod) { + mutationMethod(node, undefined); + } else if (DOMProperty.mustUseAttribute[name]) { + node.removeAttribute(DOMProperty.getAttributeName[name]); + } else { + var propName = DOMProperty.getPropertyName[name]; + var defaultValue = DOMProperty.getDefaultValueForProperty( + node.nodeName, + propName + ); + if (!DOMProperty.hasSideEffects[name] || + ('' + node[propName]) !== defaultValue) { + node[propName] = defaultValue; + } + } + } else if (DOMProperty.isCustomAttribute(name)) { + node.removeAttribute(name); + } else if ("production" !== process.env.NODE_ENV) { + warnUnknownProperty(name); } - ) + } + }; -module.exports = ReactComponentBrowserEnvironment; +module.exports = DOMPropertyOperations; }).call(this,require('_process')) -},{"./ReactDOMIDOperations":147,"./ReactMarkupChecksum":168,"./ReactMount":169,"./ReactPerf":174,"./ReactReconcileTransaction":180,"./getReactRootElementInContainer":227,"./invariant":233,"./setInnerHTML":247,"_process":258}],140:[function(require,module,exports){ +},{"./DOMProperty":121,"./escapeTextForBrowser":221,"./memoizeStringOnly":247,"./warning":257,"_process":5}],123:[function(require,module,exports){ (function (process){ /** * Copyright 2013-2014, Facebook, Inc. @@ -14100,1437 +12083,1676 @@ module.exports = ReactComponentBrowserEnvironment; * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * - * @providesModule ReactCompositeComponent + * @providesModule Danger + * @typechecks static-only */ +/*jslint evil: true, sub: true */ + "use strict"; -var ReactComponent = require("./ReactComponent"); -var ReactContext = require("./ReactContext"); -var ReactCurrentOwner = require("./ReactCurrentOwner"); -var ReactElement = require("./ReactElement"); -var ReactElementValidator = require("./ReactElementValidator"); -var ReactEmptyComponent = require("./ReactEmptyComponent"); -var ReactErrorUtils = require("./ReactErrorUtils"); -var ReactLegacyElement = require("./ReactLegacyElement"); -var ReactOwner = require("./ReactOwner"); -var ReactPerf = require("./ReactPerf"); -var ReactPropTransferer = require("./ReactPropTransferer"); -var ReactPropTypeLocations = require("./ReactPropTypeLocations"); -var ReactPropTypeLocationNames = require("./ReactPropTypeLocationNames"); -var ReactUpdates = require("./ReactUpdates"); +var ExecutionEnvironment = require("./ExecutionEnvironment"); -var assign = require("./Object.assign"); -var instantiateReactComponent = require("./instantiateReactComponent"); +var createNodesFromMarkup = require("./createNodesFromMarkup"); +var emptyFunction = require("./emptyFunction"); +var getMarkupWrap = require("./getMarkupWrap"); var invariant = require("./invariant"); -var keyMirror = require("./keyMirror"); -var keyOf = require("./keyOf"); -var monitorCodeUse = require("./monitorCodeUse"); -var mapObject = require("./mapObject"); -var shouldUpdateReactComponent = require("./shouldUpdateReactComponent"); -var warning = require("./warning"); - -var MIXINS_KEY = keyOf({mixins: null}); - -/** - * Policies that describe methods in `ReactCompositeComponentInterface`. - */ -var SpecPolicy = keyMirror({ - /** - * These methods may be defined only once by the class specification or mixin. - */ - DEFINE_ONCE: null, - /** - * These methods may be defined by both the class specification and mixins. - * Subsequent definitions will be chained. These methods must return void. - */ - DEFINE_MANY: null, - /** - * These methods are overriding the base ReactCompositeComponent class. - */ - OVERRIDE_BASE: null, - /** - * These methods are similar to DEFINE_MANY, except we assume they return - * objects. We try to merge the keys of the return values of all the mixed in - * functions. If there is a key conflict we throw. - */ - DEFINE_MANY_MERGED: null -}); - -var injectedMixins = []; +var OPEN_TAG_NAME_EXP = /^(<[^ \/>]+)/; +var RESULT_INDEX_ATTR = 'data-danger-index'; /** - * Composite components are higher-level components that compose other composite - * or native components. - * - * To create a new type of `ReactCompositeComponent`, pass a specification of - * your new class to `React.createClass`. The only requirement of your class - * specification is that you implement a `render` method. - * - * var MyComponent = React.createClass({ - * render: function() { - * return

; - * } - * }); + * Extracts the `nodeName` from a string of markup. * - * The class specification supports a specific protocol of methods that have - * special meaning (e.g. `render`). See `ReactCompositeComponentInterface` for - * more the comprehensive protocol. Any other properties and methods in the - * class specification will available on the prototype. + * NOTE: Extracting the `nodeName` does not require a regular expression match + * because we make assumptions about React-generated markup (i.e. there are no + * spaces surrounding the opening tag and there is at least one attribute). * - * @interface ReactCompositeComponentInterface - * @internal + * @param {string} markup String of markup. + * @return {string} Node name of the supplied markup. + * @see http://jsperf.com/extract-nodename */ -var ReactCompositeComponentInterface = { +function getNodeName(markup) { + return markup.substring(1, markup.indexOf(' ')); +} - /** - * An array of Mixin objects to include when defining your component. - * - * @type {array} - * @optional - */ - mixins: SpecPolicy.DEFINE_MANY, +var Danger = { /** - * An object containing properties and methods that should be defined on - * the component's constructor instead of its prototype (static methods). + * Renders markup into an array of nodes. The markup is expected to render + * into a list of root nodes. Also, the length of `resultList` and + * `markupList` should be the same. * - * @type {object} - * @optional + * @param {array} markupList List of markup strings to render. + * @return {array} List of rendered nodes. + * @internal */ - statics: SpecPolicy.DEFINE_MANY, + dangerouslyRenderMarkup: function(markupList) { + ("production" !== process.env.NODE_ENV ? invariant( + ExecutionEnvironment.canUseDOM, + 'dangerouslyRenderMarkup(...): Cannot render markup in a worker ' + + 'thread. Make sure `window` and `document` are available globally ' + + 'before requiring React when unit testing or use ' + + 'React.renderToString for server rendering.' + ) : invariant(ExecutionEnvironment.canUseDOM)); + var nodeName; + var markupByNodeName = {}; + // Group markup by `nodeName` if a wrap is necessary, else by '*'. + for (var i = 0; i < markupList.length; i++) { + ("production" !== process.env.NODE_ENV ? invariant( + markupList[i], + 'dangerouslyRenderMarkup(...): Missing markup.' + ) : invariant(markupList[i])); + nodeName = getNodeName(markupList[i]); + nodeName = getMarkupWrap(nodeName) ? nodeName : '*'; + markupByNodeName[nodeName] = markupByNodeName[nodeName] || []; + markupByNodeName[nodeName][i] = markupList[i]; + } + var resultList = []; + var resultListAssignmentCount = 0; + for (nodeName in markupByNodeName) { + if (!markupByNodeName.hasOwnProperty(nodeName)) { + continue; + } + var markupListByNodeName = markupByNodeName[nodeName]; - /** - * Definition of prop types for this component. - * - * @type {object} - * @optional - */ - propTypes: SpecPolicy.DEFINE_MANY, + // This for-in loop skips the holes of the sparse array. The order of + // iteration should follow the order of assignment, which happens to match + // numerical index order, but we don't rely on that. + for (var resultIndex in markupListByNodeName) { + if (markupListByNodeName.hasOwnProperty(resultIndex)) { + var markup = markupListByNodeName[resultIndex]; + + // Push the requested markup with an additional RESULT_INDEX_ATTR + // attribute. If the markup does not start with a < character, it + // will be discarded below (with an appropriate console.error). + markupListByNodeName[resultIndex] = markup.replace( + OPEN_TAG_NAME_EXP, + // This index will be parsed back out below. + '$1 ' + RESULT_INDEX_ATTR + '="' + resultIndex + '" ' + ); + } + } + + // Render each group of markup with similar wrapping `nodeName`. + var renderNodes = createNodesFromMarkup( + markupListByNodeName.join(''), + emptyFunction // Do nothing special with