diff --git a/gulpfile.js b/gulpfile.js new file mode 100644 index 0000000..ad0e1db --- /dev/null +++ b/gulpfile.js @@ -0,0 +1,21 @@ +"use strict"; + +var gulp = require("gulp"); +var react = require("gulp-react"); +var concat = require("gulp-concat"); +var watch = require("gulp-watch"); +var plumber = require("gulp-plumber"); + +gulp.task('default', ['compile']); + +gulp.task('compile', function () { + return gulp.src('lib/react/**') + .pipe(plumber()) + .pipe(concat('app.js')) + .pipe(react()) + .pipe(gulp.dest('public/js/')); +}); + +gulp.task('watch', function () { + gulp.watch('lib/react/**', ['compile']); +}); \ No newline at end of file diff --git a/lib/gather/controller.js b/lib/gather/controller.js index 3496d97..f126cbb 100644 --- a/lib/gather/controller.js +++ b/lib/gather/controller.js @@ -53,7 +53,11 @@ async.parallel(instructions, function (error) { console.log("Error while adding gatherers", error); } else { console.log("Loaded gatherers"); - + gather.gatherers.forEach(function (gatherer, index, array) { + var candidate = Math.floor(Math.random() * array.length); + array[index].leaderVote = array[candidate].id; + }); + console.log("Assigned vote for each gatherer"); } }); @@ -65,7 +69,7 @@ module.exports = function (namespace) { namespace.sockets.forEach(function (socket) { socket.emit("gather:refresh", { gather: gather.toJson(), - currentUser: socket._user + currentGatherer: gather.getGatherer(socket._user) }); }); }; diff --git a/lib/gather/gather.js b/lib/gather/gather.js index 637f26e..e08161b 100644 --- a/lib/gather/gather.js +++ b/lib/gather/gather.js @@ -164,6 +164,14 @@ Gather.prototype.voteForLeader = function (voter, candidate) { }); }; +Gather.prototype.getGatherer = function (user) { + var matchingGatherer = null; + this.gatherers.forEach(function (gatherer) { + if (gatherer.id === user.id) matchingGatherer = gatherer; + }); + return matchingGatherer; +}; + // Gather States // - Gathering // - Election diff --git a/lib/react/app.jsx b/lib/react/app.jsx deleted file mode 100644 index fa35ebb..0000000 --- a/lib/react/app.jsx +++ /dev/null @@ -1,573 +0,0 @@ -$(function () { - -"use strict"; - -var UserCounter = React.createClass({ - render: function () { - return ( -
  • - - Online - {this.props.count} - -
  • - ); - } -}); - -var UserLogin = React.createClass({ - authorizeId: function (id) { - id = parseInt(id, 10); - socket.emit("users:authorize", { - id: id - }); - }, - handleSubmit: function (e) { - e.preventDefault(); - var id = React.findDOMNode(this.refs.authorize_id).value.trim(); - if (!id) return; - React.findDOMNode(this.refs.authorize_id).value = ''; - this.authorizeId(id); - return; - }, - render: function () { - return ( -
    -
    - - - - -
    -
    -

    Just a temporary measure until genuine authentication is implemented

    -
    -
    - ); - } -}) - -var UserMenu = React.createClass({ - getDefaultProps: function () { - return { - count: 0, - users: [] - }; - }, - componentDidMount: function () { - socket.on('users:update', this.updateUsers); - }, - updateUsers: function (data) { - this.setProps({ - count: data.count, - users: data.users - }); - }, - render: function () { - var users = this.props.users.map(function (user) { - return ( -
  • {user.username}
  • - ); - }); - return ( - - ); - } -}); - -var Chatroom = React.createClass({ - getDefaultProps: function () { - return { - history: [] - }; - }, - componentDidMount: function () { - var self = this; - var TIMER_INTERVAL = 60000; // Every minute - - socket.on("message:new", function (data) { - var history = self.props.history; - history.push(data); - self.setProps({ - history: history - }); - self.scrollToBottom(); - }); - - // Message History Retrieved - socket.on("message:refresh", function (data) { - self.setProps({ - history: data.chatHistory - }); - self.scrollToBottom(); - }); - - socket.emit("message:refresh", {}); - - self.timer = setInterval(function () { - if (self.refs.messages) self.refs.messages.refreshTime(); - }, TIMER_INTERVAL); - }, - - componentDidUnmount: function () { - clearInterval(this.timer); - }, - sendMessage: function (message) { - socket.emit("newMessage", {message: message}); - }, - scrollToBottom: function () { - var node = React.findDOMNode(this.refs.messageContainer); - node.scrollTop = node.scrollHeight; - }, - render: function () { - var messages = this.props.history.map(function (message) { - return ( - - ); - }); - return ( -
    -
    Gather Chat
    -
    -
      - {messages} -
    -
    -
    - -
    -
    - ); - } -}); - -var ChatMessage = React.createClass({ - getInitialState: function () { - return { - timeAgo: $.timeago(this.props.createdAt) - } - }, - refreshTime: function () { - var self = this; - self.setState({ - timeAgo: $.timeago(self.props.createdAt) - }); - }, - render: function () { - return ( -
  • - - User Avatar - -
    -
    - {this.props.username} - - {this.state.timeAgo} - -
    -

    {this.props.content}

    -
    -
  • - ); - } -}); - -var CurrentUser = React.createClass({ - componentDidMount: function () { - var self = this; - socket.on("users:update", function (data) { - self.setProps({ - user: data.currentUser - }); - }); - socket.emit("users:refresh", {}); - }, - render: function () { - if (this.props.user) { - return ( - {this.props.user.username}  User Avatar - ); - } else { - return false; - } - } -}); - -var VoteButton = React.createClass({ - cancelVote: function (e) { - socket.emit("gather:vote", { - leader: { - candidate: null - } - }); - }, - vote: function (e) { - e.preventDefault(); - socket.emit("gather:vote", { - leader: { - candidate: parseInt(e.target.value, 10) - } - }); - }, - render: function () { - if (this.props.currentGatherer === null) { - return false; - } - if (this.props.currentGatherer.leaderVote === this.props.candidate.id) { - return ( - - ); - } else { - return ( - - ); - } - } -}); - -var MessageBar = React.createClass({ - sendMessage: function (content) { - socket.emit("message:new", { - content: content - }); - }, - handleSubmit: function (e) { - e.preventDefault(); - var content = React.findDOMNode(this.refs.content).value.trim(); - if (!content) return; - React.findDOMNode(this.refs.content).value = ''; - this.sendMessage(content); - return; - }, - render: function () { - return ( -
    -
    - - - - -
    -
    - ); - } -}); - -var JoinGatherButton = React.createClass({ - joinGather: function (e) { - e.preventDefault(); - socket.emit("gather:join", {}); - }, - render: function () { - var message = this.props.buttonName || "Join Gather"; - var buttonClass = "btn btn-primary"; - if (this.props.buttonClass) { - buttonClass += " " + this.props.buttonClass; - } - return () - } -}); - -var GatherProgress = React.createClass({ - gatheringProgress: function () { - var num = this.props.gather.gatherers.length; - var den = 12; - return { - num: num, - den: den, - message: num + " / " + den - }; - }, - electionProgress: function () { - var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { - if (gatherer.leaderVote) acc++; - return acc; - }, 0); - var den = 12; - return { - num: num, - den: den, - message: den - num + " more votes required" - }; - }, - selectionProgress: function () { - var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { - if (gatherer.team !== "lobby") acc++; - return acc; - }, 0); - var den = 12; - - return { - num: num, - den: den, - message: num + " out of " + den + " players assigned" - }; - }, - render: function () { - var progress; - var gatherState = this.props.gather.state; - if (gatherState === 'gathering' && this.props.gather.gatherers.length) { - progress = this.gatheringProgress(); - } else if (gatherState === 'election') { - progress = this.electionProgress(); - } else if (gatherState === 'selection') { - progress = this.selectionProgress(); - } - if (progress) { - var style = { - width: Math.round((progress.num / progress.den * 100)) + "%" - }; - return ( -
    -

    Gather Progress

    -
    -
    - {progress.message} -
    -
    -
    - ); - } else { - return false; - } - } -}); - -var Gather = React.createClass({ - getDefaultProps: function () { - return { - gather: { - gatherers: [] - } - } - }, - joinedGather: function () { - var self = this; - return this.props.gather.gatherers.some(function (gatherer) { - return gatherer.user.id === self.props.currentUser.id; - }); - }, - componentDidMount: function () { - var self = this; - socket.on("gather:refresh", function (data) { - self.setProps({ - gather: data.gather, - currentUser: data.currentUser - }); - }); - }, - stateDescription: function () { - switch(this.props.gather.state) { - case "gathering": - return "Waiting for more gatherers"; - case "election": - return "Currently voting for team leaders"; - case "selection": - return "Waiting for leaders to picking teams"; - case "done": - return "Gather completed"; - default: - return "Initialising gather"; - } - }, - leaveGather: function (e) { - e.preventDefault(); - socket.emit("gather:leave", {}); - }, - inviteToGather: function (e) { - e.preventDefault(); - }, - currentGatherer: function () { - var current = null; - var self = this; - this.props.gather.gatherers.forEach(function (gatherer) { - if (gatherer.id === self.props.currentUser.id) current = gatherer; - }); - return current; - }, - render: function () { - var joinButton; - if (this.joinedGather()) { - joinButton = (
  • ); - } else { - joinButton = (
  • ); - } - var inviteButton; - if (this.props.gather.state === 'gathering') { - inviteButton = (
  • ); - } - return ( -
    -
    - NS2 Gather - {this.props.gather.gatherers.length} -
    - {this.stateDescription()} -
    - - -
    -
      - {inviteButton} - {joinButton} -
    -
    -
    - ); - } -}); - -var LeaderPoll = React.createClass({ - render: function () { - return ( -
    -
    - ); - } -}); - -var Gatherers = React.createClass({ - render: function () { - var self = this; - var gatherers = this.props.gather.gatherers.map(function (gatherer) { - var lifeforms = ( - gatherer.user.ability.lifeforms.map(function (lifeform) { - return ({lifeform}); - }) - ); - - var commBadge; - if (gatherer.user.ability.commander) { - commBadge = (Commander); - } - - var division = ({gatherer.user.ability.division}); - var action = lifeforms; - if (self.props.gather.state === "election") { - var votes = self.props.gather.gatherers.reduce(function (acc, voter) { - if (voter.leaderVote === gatherer.id) acc++; - return acc; - }, 0) - action = ( -
    - {votes + " votes"}   - - -
    - ); - } - - return ( - - {commBadge} - {gatherer.user.username} - {division}  - {action}  - - ); - }) - if (this.props.gather.gatherers.length) { - return ( -
    -
    -
    -
    Roster
    -
    - - - {gatherers} - -
    -
    -
    - ); - } else { - return (
    ); - } - } -}); - -var socket; - -function initialiseComponents () { - var socketUrl = window.location.protocol + "//" + window.location.host; - socket = io(socketUrl) - .on("connect", function () { - console.log("Connected"); - }) - .on("reconnect", function () { - console.log("Reconnected"); - }) - .on("disconnect", function () { - console.log("Disconnected") - }); - - React.render(, document.getElementById('side-menu')); - React.render(, document.getElementById('chatroom')); - React.render(, document.getElementById('gathers')); - React.render(, document.getElementById('currentuser')); -}; - -initialiseComponents(); - - - -}); - diff --git a/lib/react/gather.jsx b/lib/react/gather.jsx new file mode 100644 index 0000000..4e3ab91 --- /dev/null +++ b/lib/react/gather.jsx @@ -0,0 +1,354 @@ +"use strict"; + +var VoteButton = React.createClass({ + cancelVote: function (e) { + socket.emit("gather:vote", { + leader: { + candidate: null + } + }); + }, + vote: function (e) { + e.preventDefault(); + socket.emit("gather:vote", { + leader: { + candidate: parseInt(e.target.value, 10) + } + }); + }, + render: function () { + if (this.props.currentGatherer === null) { + return false; + } + if (this.props.currentGatherer.leaderVote === this.props.candidate.id) { + return ( + + ); + } else { + return ( + + ); + } + } +}); + +var JoinGatherButton = React.createClass({ + joinGather: function (e) { + e.preventDefault(); + socket.emit("gather:join", {}); + }, + render: function () { + var message = this.props.buttonName || "Join Gather"; + var buttonClass = "btn btn-primary"; + if (this.props.buttonClass) { + buttonClass += " " + this.props.buttonClass; + } + return () + } +}); + +var SelectPlayerButton = React.createClass({ + selectPlayer: function (e) { + e.preventDefault(); + }, + render: function () { + if (!this.props.currentGatherer.leader) { + return false; + } else { + return ( + ); + } + } +}) + +var GatherTeams = React.createClass({ + alienGatherers: function () { + return this.props.gather.gatherers.filter(function (gatherer) { + return gatherer.team === "alien"; + }).sort(function (gatherer) { + return (gatherer.leader) ? 1 : 0; + }); + }, + marineGatherers: function () { + return this.props.gather.gatherers.filter(function (gatherer) { + return gatherer.team === "marine"; + }).sort(function (gatherer) { + return (gatherer.leader) ? 1 : 0; + }); + }, + render: function () { + var extractGatherer = function (gatherer) { + var image; + if (gatherer.leader) { + image = (Commander); + } + return ( + + {image} + {gatherer.user.username} + + ); + } + var marines = this.marineGatherers().map(extractGatherer); + var aliens = this.alienGatherers().map(extractGatherer); + return ( +
    +
    +
    +
    +
    + Aliens +
    + + + {aliens} + +
    +
    +
    +
    +
    +
    + Marines +
    + + + {marines} + +
    +
    +
    +
    +
    + ); + } +}) + +var GatherProgress = React.createClass({ + stateDescription: function () { + switch(this.props.gather.state) { + case "gathering": + return "Waiting for more gatherers."; + case "election": + return "Currently voting for team leaders."; + case "selection": + return "Waiting for leaders to picking teams."; + case "done": + return "Gather completed."; + default: + return "Initialising gather."; + } + }, + gatheringProgress: function () { + var num = this.props.gather.gatherers.length; + var den = 12; + var remaining = den - num; + var message = (remaining === 1) ? "Waiting for last player" : "Waiting for " + remaining + " more players"; + return { + num: num, + den: den, + message: message + }; + }, + electionProgress: function () { + var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { + if (gatherer.leaderVote) acc++; + return acc; + }, 0); + var den = 12; + return { + num: num, + den: den, + message: den - num + " more votes required" + }; + }, + selectionProgress: function () { + var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { + if (gatherer.team !== "lobby") acc++; + return acc; + }, 0); + var den = 12; + + return { + num: num, + den: den, + message: num + " out of " + den + " players assigned" + }; + }, + render: function () { + var progress; + var gatherState = this.props.gather.state; + if (gatherState === 'gathering' && this.props.gather.gatherers.length) { + progress = this.gatheringProgress(); + } else if (gatherState === 'election') { + progress = this.electionProgress(); + } else if (gatherState === 'selection') { + progress = this.selectionProgress(); + } + if (progress) { + var style = { + width: Math.round((progress.num / progress.den * 100)) + "%" + }; + return ( +
    +

    {this.stateDescription()} {progress.message}

    +
    +
    +
    +
    +
    + ); + } else { + return false; + } + } +}); + +var Gather = React.createClass({ + getDefaultProps: function () { + return { + gather: { + gatherers: [] + } + } + }, + joinedGather: function () { + return this.props.currentGatherer !== null; + }, + componentDidMount: function () { + var self = this; + socket.on("gather:refresh", function (data) { + self.setProps({ + gather: data.gather, + currentGatherer: data.currentGatherer + }); + }); + }, + leaveGather: function (e) { + e.preventDefault(); + socket.emit("gather:leave", {}); + }, + inviteToGather: function (e) { + e.preventDefault(); + }, + render: function () { + var joinButton; + if (this.joinedGather()) { + joinButton = (
  • ); + } else { + joinButton = (
  • ); + } + var inviteButton; + if (this.props.gather.state === 'gathering') { + inviteButton = (
  • ); + } + var gatherTeams; + if (this.props.gather.state === 'selection') { + gatherTeams = + } + return ( +
    +
    + NS2 Gather + {this.props.gather.gatherers.length} +
    + + {gatherTeams} + +
    +
      + {inviteButton} + {joinButton} +
    +
    +
    + ); + } +}); + +var Gatherers = React.createClass({ + render: function () { + var self = this; + var gatherers = this.props.gather.gatherers.map(function (gatherer) { + var lifeforms = ( + gatherer.user.ability.lifeforms.map(function (lifeform) { + return ({lifeform}); + }) + ); + + // Switch this to online status + var online= ( ); + + var division = ({gatherer.user.ability.division}); + var action = lifeforms; + if (self.props.gather.state === "election") { + var votes = self.props.gather.gatherers.reduce(function (acc, voter) { + if (voter.leaderVote === gatherer.id) acc++; + return acc; + }, 0) + action = ( + + {votes + " votes"}   + + + ); + } + + return ( + + {online} + {gatherer.user.username} + {division}  + {action}  + + ); + }) + if (this.props.gather.gatherers.length) { + return ( +
    +
    +
    +
    Roster
    +
    + + + {gatherers} + +
    +
    +
    + ); + } else { + return (
    ); + } + } +}); + + + diff --git a/lib/react/init.jsx b/lib/react/init.jsx new file mode 100644 index 0000000..dfbbd5c --- /dev/null +++ b/lib/react/init.jsx @@ -0,0 +1,22 @@ +"use strict"; + +var socket; + +function initialiseComponents () { + var socketUrl = window.location.protocol + "//" + window.location.host; + socket = io(socketUrl) + .on("connect", function () { + console.log("Connected"); + }) + .on("reconnect", function () { + console.log("Reconnected"); + }) + .on("disconnect", function () { + console.log("Disconnected") + }); + + React.render(, document.getElementById('side-menu')); + React.render(, document.getElementById('chatroom')); + React.render(, document.getElementById('gathers')); + React.render(, document.getElementById('currentuser')); +}; \ No newline at end of file diff --git a/lib/react/message.jsx b/lib/react/message.jsx new file mode 100644 index 0000000..503a97d --- /dev/null +++ b/lib/react/message.jsx @@ -0,0 +1,146 @@ +"use strict"; + +var Chatroom = React.createClass({ + getDefaultProps: function () { + return { + history: [] + }; + }, + componentDidMount: function () { + var self = this; + var TIMER_INTERVAL = 60000; // Every minute + + socket.on("message:new", function (data) { + var history = self.props.history; + history.push(data); + self.setProps({ + history: history + }); + self.scrollToBottom(); + }); + + // Message History Retrieved + socket.on("message:refresh", function (data) { + self.setProps({ + history: data.chatHistory + }); + self.scrollToBottom(); + }); + + socket.emit("message:refresh", {}); + + self.timer = setInterval(function () { + if (self.refs.messages) self.refs.messages.refreshTime(); + }, TIMER_INTERVAL); + }, + + componentDidUnmount: function () { + clearInterval(this.timer); + }, + sendMessage: function (message) { + socket.emit("newMessage", {message: message}); + }, + scrollToBottom: function () { + var node = React.findDOMNode(this.refs.messageContainer); + node.scrollTop = node.scrollHeight; + }, + render: function () { + var messages = this.props.history.map(function (message) { + return ( + + ); + }); + return ( +
    +
    Gather Chat
    +
    +
      + {messages} +
    +
    +
    + +
    +
    + ); + } +}); + +var ChatMessage = React.createClass({ + getInitialState: function () { + return { + timeAgo: $.timeago(this.props.createdAt) + } + }, + refreshTime: function () { + var self = this; + self.setState({ + timeAgo: $.timeago(self.props.createdAt) + }); + }, + render: function () { + return ( +
  • + + User Avatar + +
    +
    + {this.props.username} + + {this.state.timeAgo} + +
    +

    {this.props.content}

    +
    +
  • + ); + } +}); + +var MessageBar = React.createClass({ + sendMessage: function (content) { + socket.emit("message:new", { + content: content + }); + }, + handleSubmit: function (e) { + e.preventDefault(); + var content = React.findDOMNode(this.refs.content).value.trim(); + if (!content) return; + React.findDOMNode(this.refs.content).value = ''; + this.sendMessage(content); + return; + }, + render: function () { + return ( +
    +
    + + + + +
    +
    + ); + } +}); diff --git a/lib/react/user.jsx b/lib/react/user.jsx new file mode 100644 index 0000000..9c6fe65 --- /dev/null +++ b/lib/react/user.jsx @@ -0,0 +1,111 @@ +"use strict"; + +var UserCounter = React.createClass({ + render: function () { + return ( +
  • + + Online + {this.props.count} + +
  • + ); + } +}); + +var UserLogin = React.createClass({ + authorizeId: function (id) { + id = parseInt(id, 10); + socket.emit("users:authorize", { + id: id + }); + }, + handleSubmit: function (e) { + e.preventDefault(); + var id = React.findDOMNode(this.refs.authorize_id).value.trim(); + if (!id) return; + React.findDOMNode(this.refs.authorize_id).value = ''; + this.authorizeId(id); + return; + }, + render: function () { + return ( +
    +
    + + + + +
    +
    +

    Just a temporary measure until genuine authentication is implemented

    +
    +
    + ); + } +}) + +var UserMenu = React.createClass({ + getDefaultProps: function () { + return { + count: 0, + users: [] + }; + }, + componentDidMount: function () { + socket.on('users:update', this.updateUsers); + }, + updateUsers: function (data) { + this.setProps({ + count: data.count, + users: data.users + }); + }, + render: function () { + var users = this.props.users.map(function (user) { + return ( +
  • {user.username}
  • + ); + }); + return ( +
      + + {users} +


    • +
    + ); + } +}); + +var CurrentUser = React.createClass({ + componentDidMount: function () { + var self = this; + socket.on("users:update", function (data) { + self.setProps({ + user: data.currentUser + }); + }); + socket.emit("users:refresh", {}); + }, + render: function () { + if (this.props.user) { + return ( + {this.props.user.username}  User Avatar + ); + } else { + return false; + } + } +}); diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 73e051f..c08b804 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -2,6 +2,11 @@ "name": "sws_gathers", "version": "1.0.0", "dependencies": { + "async": { + "version": "1.4.0", + "from": "async@", + "resolved": "https://registry.npmjs.org/async/-/async-1.4.0.tgz" + }, "express": { "version": "4.13.1", "from": "express@", @@ -405,6 +410,781 @@ "from": "extend@", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz" }, + "gulp": { + "version": "3.9.0", + "from": "gulp@", + "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.0.tgz", + "dependencies": { + "archy": { + "version": "1.0.0", + "from": "archy@^1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz" + }, + "chalk": { + "version": "1.1.0", + "from": "chalk@^1.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.0.tgz", + "dependencies": { + "ansi-styles": { + "version": "2.1.0", + "from": "ansi-styles@^2.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.1.0.tgz" + }, + "escape-string-regexp": { + "version": "1.0.3", + "from": "escape-string-regexp@^1.0.2", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.3.tgz" + }, + "has-ansi": { + "version": "2.0.0", + "from": "has-ansi@^2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "dependencies": { + "ansi-regex": { + "version": "2.0.0", + "from": "ansi-regex@^2.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" + } + } + }, + "strip-ansi": { + "version": "3.0.0", + "from": "strip-ansi@^3.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.0.tgz", + "dependencies": { + "ansi-regex": { + "version": "2.0.0", + "from": "ansi-regex@^2.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz" + } + } + }, + "supports-color": { + "version": "2.0.0", + "from": "supports-color@^2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz" + } + } + }, + "deprecated": { + "version": "0.0.1", + "from": "deprecated@^0.0.1", + "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz" + }, + "gulp-util": { + "version": "3.0.6", + "from": "gulp-util@^3.0.0", + "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.6.tgz", + "dependencies": { + "array-differ": { + "version": "1.0.0", + "from": "array-differ@^1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz" + }, + "array-uniq": { + "version": "1.0.2", + "from": "array-uniq@^1.0.2", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.2.tgz" + }, + "beeper": { + "version": "1.1.0", + "from": "beeper@^1.0.0", + "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.0.tgz" + }, + "dateformat": { + "version": "1.0.11", + "from": "dateformat@^1.0.11", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.11.tgz", + "dependencies": { + "get-stdin": { + "version": "4.0.1", + "from": "get-stdin@*", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz" + }, + "meow": { + "version": "3.3.0", + "from": "meow@*", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.3.0.tgz", + "dependencies": { + "camelcase-keys": { + "version": "1.0.0", + "from": "camelcase-keys@^1.0.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-1.0.0.tgz", + "dependencies": { + "camelcase": { + "version": "1.1.0", + "from": "camelcase@^1.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.1.0.tgz" + }, + "map-obj": { + "version": "1.0.1", + "from": "map-obj@^1.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz" + } + } + }, + "indent-string": { + "version": "1.2.2", + "from": "indent-string@^1.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-1.2.2.tgz", + "dependencies": { + "repeating": { + "version": "1.1.3", + "from": "repeating@^1.1.0", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz", + "dependencies": { + "is-finite": { + "version": "1.0.1", + "from": "is-finite@^1.0.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.1.tgz", + "dependencies": { + "number-is-nan": { + "version": "1.0.0", + "from": "number-is-nan@^1.0.0", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.0.tgz" + } + } + } + } + } + } + } + } + } + } + }, + "lodash._reescape": { + "version": "3.0.0", + "from": "lodash._reescape@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz" + }, + "lodash._reevaluate": { + "version": "3.0.0", + "from": "lodash._reevaluate@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz" + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "from": "lodash._reinterpolate@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz" + }, + "lodash.template": { + "version": "3.6.2", + "from": "lodash.template@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", + "dependencies": { + "lodash._basecopy": { + "version": "3.0.1", + "from": "lodash._basecopy@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz" + }, + "lodash._basetostring": { + "version": "3.0.1", + "from": "lodash._basetostring@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz" + }, + "lodash._basevalues": { + "version": "3.0.0", + "from": "lodash._basevalues@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz" + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "from": "lodash._isiterateecall@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz" + }, + "lodash.escape": { + "version": "3.0.0", + "from": "lodash.escape@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.0.0.tgz" + }, + "lodash.keys": { + "version": "3.1.2", + "from": "lodash.keys@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "dependencies": { + "lodash._getnative": { + "version": "3.9.1", + "from": "lodash._getnative@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz" + }, + "lodash.isarguments": { + "version": "3.0.4", + "from": "lodash.isarguments@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.0.4.tgz" + }, + "lodash.isarray": { + "version": "3.0.4", + "from": "lodash.isarray@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz" + } + } + }, + "lodash.restparam": { + "version": "3.6.1", + "from": "lodash.restparam@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz" + }, + "lodash.templatesettings": { + "version": "3.1.0", + "from": "lodash.templatesettings@^3.0.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.0.tgz" + } + } + }, + "multipipe": { + "version": "0.1.2", + "from": "multipipe@^0.1.2", + "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", + "dependencies": { + "duplexer2": { + "version": "0.0.2", + "from": "duplexer2@0.0.2", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", + "dependencies": { + "readable-stream": { + "version": "1.1.13", + "from": "readable-stream@~1.1.9", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "from": "core-util-is@~1.0.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@~0.10.x", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@~2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } + } + } + } + } + }, + "object-assign": { + "version": "3.0.0", + "from": "object-assign@^3.0.0", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz" + }, + "replace-ext": { + "version": "0.0.1", + "from": "replace-ext@0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz" + }, + "through2": { + "version": "2.0.0", + "from": "through2@^2.0.0", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.0.tgz", + "dependencies": { + "readable-stream": { + "version": "2.0.2", + "from": "readable-stream@~2.0.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.2.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "from": "core-util-is@~1.0.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@~2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "process-nextick-args": { + "version": "1.0.2", + "from": "process-nextick-args@~1.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.2.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@~0.10.x", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "util-deprecate": { + "version": "1.0.1", + "from": "util-deprecate@~1.0.1", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.1.tgz" + } + } + }, + "xtend": { + "version": "4.0.0", + "from": "xtend@>=4.0.0 <4.1.0-0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz" + } + } + }, + "vinyl": { + "version": "0.5.0", + "from": "vinyl@^0.5.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.0.tgz", + "dependencies": { + "clone": { + "version": "1.0.2", + "from": "clone@^1.0.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz" + }, + "clone-stats": { + "version": "0.0.1", + "from": "clone-stats@^0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz" + } + } + } + } + }, + "interpret": { + "version": "0.6.5", + "from": "interpret@^0.6.2", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-0.6.5.tgz" + }, + "liftoff": { + "version": "2.1.0", + "from": "liftoff@^2.1.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.1.0.tgz", + "dependencies": { + "extend": { + "version": "2.0.1", + "from": "extend@^2.0.1", + "resolved": "https://registry.npmjs.org/extend/-/extend-2.0.1.tgz" + }, + "findup-sync": { + "version": "0.2.1", + "from": "findup-sync@^0.2.1", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.2.1.tgz", + "dependencies": { + "glob": { + "version": "4.3.5", + "from": "glob@~4.3.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.3.5.tgz", + "dependencies": { + "inflight": { + "version": "1.0.4", + "from": "inflight@^1.0.4", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@1", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "minimatch": { + "version": "2.0.10", + "from": "minimatch@^2.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "dependencies": { + "brace-expansion": { + "version": "1.1.0", + "from": "brace-expansion@^1.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.0.tgz", + "dependencies": { + "balanced-match": { + "version": "0.2.0", + "from": "balanced-match@^0.2.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + } + } + } + }, + "once": { + "version": "1.3.2", + "from": "once@^1.3.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@1", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + } + } + } + } + }, + "flagged-respawn": { + "version": "0.3.1", + "from": "flagged-respawn@^0.3.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.1.tgz" + }, + "rechoir": { + "version": "0.6.2", + "from": "rechoir@^0.6.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz" + }, + "resolve": { + "version": "1.1.6", + "from": "resolve@^1.1.6", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.6.tgz" + } + } + }, + "minimist": { + "version": "1.1.2", + "from": "minimist@^1.1.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.2.tgz" + }, + "orchestrator": { + "version": "0.3.7", + "from": "orchestrator@^0.3.0", + "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.7.tgz", + "dependencies": { + "end-of-stream": { + "version": "0.1.5", + "from": "end-of-stream@~0.1.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", + "dependencies": { + "once": { + "version": "1.3.2", + "from": "once@~1.3.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@1", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + } + } + }, + "sequencify": { + "version": "0.0.7", + "from": "sequencify@~0.0.7", + "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz" + }, + "stream-consume": { + "version": "0.1.0", + "from": "stream-consume@~0.1.0", + "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz" + } + } + }, + "pretty-hrtime": { + "version": "1.0.0", + "from": "pretty-hrtime@^1.0.0", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.0.tgz" + }, + "semver": { + "version": "4.3.6", + "from": "semver@^4.1.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz" + }, + "tildify": { + "version": "1.1.0", + "from": "tildify@^1.0.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.1.0.tgz", + "dependencies": { + "os-homedir": { + "version": "1.0.1", + "from": "os-homedir@^1.0.0", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.1.tgz" + } + } + }, + "v8flags": { + "version": "2.0.9", + "from": "v8flags@^2.0.2", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.0.9.tgz", + "dependencies": { + "user-home": { + "version": "1.1.1", + "from": "user-home@^1.1.1", + "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz" + } + } + }, + "vinyl-fs": { + "version": "0.3.13", + "from": "vinyl-fs@^0.3.0", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.13.tgz", + "dependencies": { + "defaults": { + "version": "1.0.2", + "from": "defaults@^1.0.0", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.2.tgz", + "dependencies": { + "clone": { + "version": "0.1.19", + "from": "clone@~0.1.5", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.1.19.tgz" + } + } + }, + "glob-stream": { + "version": "3.1.18", + "from": "glob-stream@^3.1.5", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", + "dependencies": { + "glob": { + "version": "4.5.3", + "from": "glob@^4.3.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", + "dependencies": { + "inflight": { + "version": "1.0.4", + "from": "inflight@^1.0.4", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.4.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@1", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@2", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + }, + "once": { + "version": "1.3.2", + "from": "once@^1.3.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.2.tgz", + "dependencies": { + "wrappy": { + "version": "1.0.1", + "from": "wrappy@1", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.1.tgz" + } + } + } + } + }, + "minimatch": { + "version": "2.0.10", + "from": "minimatch@^2.0.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "dependencies": { + "brace-expansion": { + "version": "1.1.0", + "from": "brace-expansion@^1.0.0", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.0.tgz", + "dependencies": { + "balanced-match": { + "version": "0.2.0", + "from": "balanced-match@^0.2.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.0.tgz" + }, + "concat-map": { + "version": "0.0.1", + "from": "concat-map@0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" + } + } + } + } + }, + "ordered-read-streams": { + "version": "0.1.0", + "from": "ordered-read-streams@^0.1.0", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz" + }, + "glob2base": { + "version": "0.0.12", + "from": "glob2base@^0.0.12", + "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", + "dependencies": { + "find-index": { + "version": "0.1.1", + "from": "find-index@^0.1.1", + "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz" + } + } + }, + "unique-stream": { + "version": "1.0.0", + "from": "unique-stream@^1.0.0", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz" + } + } + }, + "glob-watcher": { + "version": "0.0.6", + "from": "glob-watcher@^0.0.6", + "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", + "dependencies": { + "gaze": { + "version": "0.5.1", + "from": "gaze@^0.5.1", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.1.tgz", + "dependencies": { + "globule": { + "version": "0.1.0", + "from": "globule@~0.1.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", + "dependencies": { + "lodash": { + "version": "1.0.2", + "from": "lodash@~1.0.1", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz" + }, + "glob": { + "version": "3.1.21", + "from": "glob@~3.1.21", + "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", + "dependencies": { + "graceful-fs": { + "version": "1.2.3", + "from": "graceful-fs@~1.2.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz" + }, + "inherits": { + "version": "1.0.0", + "from": "inherits@1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.0.tgz" + } + } + }, + "minimatch": { + "version": "0.2.14", + "from": "minimatch@~0.2.11", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", + "dependencies": { + "lru-cache": { + "version": "2.6.5", + "from": "lru-cache@2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz" + }, + "sigmund": { + "version": "1.0.1", + "from": "sigmund@~1.0.0", + "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz" + } + } + } + } + } + } + } + } + }, + "graceful-fs": { + "version": "3.0.8", + "from": "graceful-fs@^3.0.0", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.8.tgz" + }, + "mkdirp": { + "version": "0.5.1", + "from": "mkdirp@^0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "dependencies": { + "minimist": { + "version": "0.0.8", + "from": "minimist@0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz" + } + } + }, + "strip-bom": { + "version": "1.0.0", + "from": "strip-bom@^1.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", + "dependencies": { + "first-chunk-stream": { + "version": "1.0.0", + "from": "first-chunk-stream@^1.0.0", + "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz" + }, + "is-utf8": { + "version": "0.2.0", + "from": "is-utf8@^0.2.0", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.0.tgz" + } + } + }, + "through2": { + "version": "0.6.5", + "from": "through2@^0.6.1", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "dependencies": { + "readable-stream": { + "version": "1.0.33", + "from": "readable-stream@>=1.0.33-1 <1.1.0-0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz", + "dependencies": { + "core-util-is": { + "version": "1.0.1", + "from": "core-util-is@~1.0.0", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz" + }, + "isarray": { + "version": "0.0.1", + "from": "isarray@0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz" + }, + "string_decoder": { + "version": "0.10.31", + "from": "string_decoder@~0.10.x", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz" + }, + "inherits": { + "version": "2.0.1", + "from": "inherits@~2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz" + } + } + }, + "xtend": { + "version": "4.0.0", + "from": "xtend@>=4.0.0 <4.1.0-0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz" + } + } + }, + "vinyl": { + "version": "0.4.6", + "from": "vinyl@^0.4.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "dependencies": { + "clone": { + "version": "0.2.0", + "from": "clone@^0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz" + }, + "clone-stats": { + "version": "0.0.1", + "from": "clone-stats@^0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz" + } + } + } + } + } + } + }, "javascript-state-machine": { "version": "2.3.5", "from": "javascript-state-machine@", diff --git a/package.json b/package.json index af576e5..91b1369 100644 --- a/package.json +++ b/package.json @@ -10,8 +10,8 @@ "scripts": { "test": "NODE_ENV=test mocha spec/", "start": "npm run compile && node index.js", - "compile:dev": "node_modules/react-tools/bin/jsx --watch --no-cache-dir --source-map-inline -x jsx lib/react/ public/js/", - "compile": "node_modules/react-tools/bin/jsx -x jsx lib/react/ public/js/", + "watch": "node_modules/gulp/bin/gulp.js watch", + "compile": "node_modules/gulp/bin/gulp.js", "dev": "nodemon index.js" }, "repository": { @@ -29,16 +29,22 @@ "express": "~4.13.1", "express-handlebars": "~2.0.1", "extend": "^3.0.0", + "gulp": "^3.9.0", + "gulp-concat": "^2.6.0", + "gulp-react": "^3.0.1", "javascript-state-machine": "^2.3.5", "morgan": "~1.6.1", "node-mysql": "~0.4.2", "react-tools": "~0.13.3", "request": "~2.60.0", "socket.io": "~1.3.5", + "gulp-watch": "^4.3.4", "winston": "~1.0.1" }, "devDependencies": { "chai": "~3.1.0", + "gulp": "^3.9.0", + "gulp-plumber": "^1.0.1", "mocha": "~2.2.5", "nodemon": "~1.3.7", "supertest": "~1.0.1" diff --git a/public/css/app.css b/public/css/app.css index 750a8af..5eb4315 100644 --- a/public/css/app.css +++ b/public/css/app.css @@ -19,4 +19,14 @@ .signin { margin: 0px 10px; +} + +.user-online { + border-radius: 50%; + width: 10px; + height: 10px; + + background-image: -moz-radial-gradient(45px 45px 45deg, circle cover, yellow 0%, orange 100%, red 95%); + background-image: -webkit-radial-gradient(45px 45px, circle cover, yellow, orange); + background-image: radial-gradient(45px 45px 45deg, circle cover, yellow 0%, orange 100%, red 95%); } \ No newline at end of file diff --git a/public/js/app.js b/public/js/app.js index 988e1a8..0314448 100644 --- a/public/js/app.js +++ b/public/js/app.js @@ -1,93 +1,382 @@ -$(function () { - "use strict"; -var UserCounter = React.createClass({displayName: "UserCounter", +var VoteButton = React.createClass({displayName: "VoteButton", + cancelVote: function (e) { + socket.emit("gather:vote", { + leader: { + candidate: null + } + }); + }, + vote: function (e) { + e.preventDefault(); + socket.emit("gather:vote", { + leader: { + candidate: parseInt(e.target.value, 10) + } + }); + }, render: function () { - return ( - React.createElement("li", null, - React.createElement("a", {href: "#"}, - React.createElement("i", {className: "fa fa-users fa-fw"}), " Online", - React.createElement("span", {className: "badge add-left"}, " ", this.props.count, " ") + if (this.props.currentGatherer === null) { + return false; + } + if (this.props.currentGatherer.leaderVote === this.props.candidate.id) { + return ( + React.createElement("button", { + onClick: this.cancelVote, + className: "btn btn-xs btn-success"}, "Voted" ) - ) - ); + ); + } else { + return ( + React.createElement("button", { + onClick: this.vote, + className: "btn btn-xs btn-default", + value: this.props.candidate.id}, "Vote" + ) + ); + } } }); -var UserLogin = React.createClass({displayName: "UserLogin", - authorizeId: function (id) { - id = parseInt(id, 10); - socket.emit("users:authorize", { - id: id - }); - }, - handleSubmit: function (e) { +var JoinGatherButton = React.createClass({displayName: "JoinGatherButton", + joinGather: function (e) { e.preventDefault(); - var id = React.findDOMNode(this.refs.authorize_id).value.trim(); - if (!id) return; - React.findDOMNode(this.refs.authorize_id).value = ''; - this.authorizeId(id); - return; + socket.emit("gather:join", {}); }, render: function () { + var message = this.props.buttonName || "Join Gather"; + var buttonClass = "btn btn-primary"; + if (this.props.buttonClass) { + buttonClass += " " + this.props.buttonClass; + } + return (React.createElement("button", { + onClick: this.joinGather, + className: buttonClass}, message)) + } +}); + +var SelectPlayerButton = React.createClass({displayName: "SelectPlayerButton", + selectPlayer: function (e) { + e.preventDefault(); + }, + render: function () { + if (!this.props.currentGatherer.leader) { + return false; + } else { + return (React.createElement("button", { + onClick: this.selectPlayer, + className: "btn btn-xs btn-primary"}, " Select" + ) + ); + } + } +}) + +var GatherTeams = React.createClass({displayName: "GatherTeams", + alienGatherers: function () { + return this.props.gather.gatherers.filter(function (gatherer) { + return gatherer.team === "alien"; + }).sort(function (gatherer) { + return (gatherer.leader) ? 1 : 0; + }); + }, + marineGatherers: function () { + return this.props.gather.gatherers.filter(function (gatherer) { + return gatherer.team === "marine"; + }).sort(function (gatherer) { + return (gatherer.leader) ? 1 : 0; + }); + }, + render: function () { + var extractGatherer = function (gatherer) { + var image; + if (gatherer.leader) { + image = (React.createElement("img", {src: "/images/commander.png", + alt: "Commander", + height: "20", + width: "20"})); + } + return ( + React.createElement("tr", {key: gatherer.id}, + React.createElement("td", {className: "col-md-1"}, image), + React.createElement("td", {className: "col-md-11"}, gatherer.user.username) + ) + ); + } + var marines = this.marineGatherers().map(extractGatherer); + var aliens = this.alienGatherers().map(extractGatherer); return ( - React.createElement("form", {onSubmit: this.handleSubmit}, - React.createElement("div", {className: "input-group signin"}, - React.createElement("input", { - id: "btn-input", - type: "text", - className: "form-control", - ref: "authorize_id", - placeholder: "Choose an ID..."}), - React.createElement("span", {className: "input-group-btn"}, - React.createElement("input", { - type: "submit", - className: "btn btn-primary", - id: "btn-chat", - value: "Login"}) + React.createElement("div", {className: "panel-body"}, + React.createElement("div", {className: "row"}, + React.createElement("div", {className: "col-md-6"}, + React.createElement("div", {className: "panel panel-default"}, + React.createElement("div", {className: "panel-heading"}, + "Aliens" + ), + React.createElement("table", {className: "table"}, + React.createElement("tbody", null, + aliens + ) + ) + ) + ), + React.createElement("div", {className: "col-md-6"}, + React.createElement("div", {className: "panel panel-default"}, + React.createElement("div", {className: "panel-heading"}, + "Marines" + ), + React.createElement("table", {className: "table"}, + React.createElement("tbody", null, + marines + ) + ) + ) ) - ), - React.createElement("div", {className: "signin"}, - React.createElement("p", {className: "text-center"}, React.createElement("small", null, "Just a temporary measure until genuine authentication is implemented")) ) ) ); } }) -var UserMenu = React.createClass({displayName: "UserMenu", - getDefaultProps: function () { +var GatherProgress = React.createClass({displayName: "GatherProgress", + stateDescription: function () { + switch(this.props.gather.state) { + case "gathering": + return "Waiting for more gatherers."; + case "election": + return "Currently voting for team leaders."; + case "selection": + return "Waiting for leaders to picking teams."; + case "done": + return "Gather completed."; + default: + return "Initialising gather."; + } + }, + gatheringProgress: function () { + var num = this.props.gather.gatherers.length; + var den = 12; + var remaining = den - num; + var message = (remaining === 1) ? "Waiting for last player" : "Waiting for " + remaining + " more players"; return { - count: 0, - users: [] + num: num, + den: den, + message: message }; }, - componentDidMount: function () { - socket.on('users:update', this.updateUsers); + electionProgress: function () { + var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { + if (gatherer.leaderVote) acc++; + return acc; + }, 0); + var den = 12; + return { + num: num, + den: den, + message: den - num + " more votes required" + }; }, - updateUsers: function (data) { - this.setProps({ - count: data.count, - users: data.users - }); + selectionProgress: function () { + var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { + if (gatherer.team !== "lobby") acc++; + return acc; + }, 0); + var den = 12; + + return { + num: num, + den: den, + message: num + " out of " + den + " players assigned" + }; }, render: function () { - var users = this.props.users.map(function (user) { + var progress; + var gatherState = this.props.gather.state; + if (gatherState === 'gathering' && this.props.gather.gatherers.length) { + progress = this.gatheringProgress(); + } else if (gatherState === 'election') { + progress = this.electionProgress(); + } else if (gatherState === 'selection') { + progress = this.selectionProgress(); + } + if (progress) { + var style = { + width: Math.round((progress.num / progress.den * 100)) + "%" + }; return ( - React.createElement("li", {key: user.id}, React.createElement("a", {href: "#"}, user.username)) + React.createElement("div", {className: "panel-body"}, + React.createElement("p", null, React.createElement("strong", null, this.stateDescription()), " ", progress.message), + React.createElement("div", {className: "progress"}, + React.createElement("div", {className: "progress-bar progress-bar-striped active", + "data-role": "progressbar", + "data-aria-valuenow": progress.num, + "data-aria-valuemin": "0", + "data-aria-valuemax": progress.den, + style: style} + ) + ) + ) ); + } else { + return false; + } + } +}); + +var Gather = React.createClass({displayName: "Gather", + getDefaultProps: function () { + return { + gather: { + gatherers: [] + } + } + }, + joinedGather: function () { + return this.props.currentGatherer !== null; + }, + componentDidMount: function () { + var self = this; + socket.on("gather:refresh", function (data) { + self.setProps({ + gather: data.gather, + currentGatherer: data.currentGatherer + }); }); + }, + leaveGather: function (e) { + e.preventDefault(); + socket.emit("gather:leave", {}); + }, + inviteToGather: function (e) { + e.preventDefault(); + }, + render: function () { + var joinButton; + if (this.joinedGather()) { + joinButton = (React.createElement("li", null, React.createElement("button", { + onClick: this.leaveGather, + className: "btn btn-danger"}, "Leave Gather"))); + } else { + joinButton = (React.createElement("li", null, React.createElement(JoinGatherButton, null))); + } + var inviteButton; + if (this.props.gather.state === 'gathering') { + inviteButton = (React.createElement("li", null, React.createElement("button", { + onClick: this.inviteToGather, + className: "btn btn-primary"}, "Invite to Gather"))); + } + var gatherTeams; + if (this.props.gather.state === 'selection') { + gatherTeams = React.createElement(GatherTeams, {gather: this.props.gather}) + } return ( - React.createElement("ul", {className: "nav", id: "side-menu"}, - React.createElement(UserCounter, React.__spread({}, this.props)), - users, - React.createElement("li", null, React.createElement("br", null), React.createElement(UserLogin, null), React.createElement("br", null)) + React.createElement("div", {className: "panel panel-default"}, + React.createElement("div", {className: "panel-heading"}, + React.createElement("strong", null, "NS2 Gather "), + React.createElement("span", {className: "badge add-left"}, this.props.gather.gatherers.length) + ), + React.createElement(Gatherers, {gather: this.props.gather, currentGatherer: this.props.currentGatherer}), + gatherTeams, + React.createElement(GatherProgress, {gather: this.props.gather}), + React.createElement("div", {className: "panel-footer text-right"}, + React.createElement("ul", {className: "list-inline"}, + inviteButton, + joinButton + ) + ) ) ); } }); +var Gatherers = React.createClass({displayName: "Gatherers", + render: function () { + var self = this; + var gatherers = this.props.gather.gatherers.map(function (gatherer) { + var lifeforms = ( + gatherer.user.ability.lifeforms.map(function (lifeform) { + return (React.createElement("span", {className: "label label-default"}, lifeform)); + }) + ); + + // Switch this to online status + var online= (React.createElement("span", {src: "/images/commander.png", + alt: "online", + className: "user-online"}, " ")); + + var division = (React.createElement("span", {className: "label label-primary"}, gatherer.user.ability.division)); + var action = lifeforms; + if (self.props.gather.state === "election") { + var votes = self.props.gather.gatherers.reduce(function (acc, voter) { + if (voter.leaderVote === gatherer.id) acc++; + return acc; + }, 0) + action = ( + React.createElement("span", null, + React.createElement("small", null, votes + " votes", "  "), + React.createElement(VoteButton, {currentGatherer: self.props.currentGatherer, candidate: gatherer}) + ) + ); + } + + return ( + React.createElement("tr", {key: gatherer.user.id}, + React.createElement("td", {className: "col-md-1"}, online), + React.createElement("td", {className: "col-md-5"}, gatherer.user.username), + React.createElement("td", {className: "col-md-3"}, division, " "), + React.createElement("td", {className: "col-md-2 text-right"}, action, " ") + ) + ); + }) + if (this.props.gather.gatherers.length) { + return ( + React.createElement("div", {className: "panel-body"}, + React.createElement("div", {className: "panel panel-default"}, + React.createElement("div", {className: "panel-heading"}, + React.createElement("h5", {className: "panel-title"}, "Roster") + ), + React.createElement("table", {className: "table roster-table"}, + React.createElement("tbody", null, + gatherers + ) + ) + ) + ) + ); + } else { + return (React.createElement("div", {className: "panel-body text-center"}, React.createElement(JoinGatherButton, {buttonClass: "btn-lg", buttonName: "Start a Gather"}))); + } + } +}); + + + + +"use strict"; + +var socket; + +function initialiseComponents () { + var socketUrl = window.location.protocol + "//" + window.location.host; + socket = io(socketUrl) + .on("connect", function () { + console.log("Connected"); + }) + .on("reconnect", function () { + console.log("Reconnected"); + }) + .on("disconnect", function () { + console.log("Disconnected") + }); + + React.render(React.createElement(UserMenu, null), document.getElementById('side-menu')); + React.render(React.createElement(Chatroom, null), document.getElementById('chatroom')); + React.render(React.createElement(Gather, null), document.getElementById('gathers')); + React.render(React.createElement(CurrentUser, null), document.getElementById('currentuser')); +}; +"use strict"; + var Chatroom = React.createClass({displayName: "Chatroom", getDefaultProps: function () { return { @@ -196,69 +485,6 @@ var ChatMessage = React.createClass({displayName: "ChatMessage", } }); -var CurrentUser = React.createClass({displayName: "CurrentUser", - componentDidMount: function () { - var self = this; - socket.on("users:update", function (data) { - self.setProps({ - user: data.currentUser - }); - }); - socket.emit("users:refresh", {}); - }, - render: function () { - if (this.props.user) { - return ( - React.createElement("a", {href: "#"}, this.props.user.username, "  ", React.createElement("img", {src: this.props.user.avatar, - alt: "User Avatar", - height: "20", - width: "20"})) - ); - } else { - return false; - } - } -}); - -var VoteButton = React.createClass({displayName: "VoteButton", - cancelVote: function (e) { - socket.emit("gather:vote", { - leader: { - candidate: null - } - }); - }, - vote: function (e) { - e.preventDefault(); - socket.emit("gather:vote", { - leader: { - candidate: parseInt(e.target.value, 10) - } - }); - }, - render: function () { - if (this.props.currentGatherer === null) { - return false; - } - if (this.props.currentGatherer.leaderVote === this.props.candidate.id) { - return ( - React.createElement("button", { - onClick: this.cancelVote, - className: "btn btn-xs btn-success"}, "Voted" - ) - ); - } else { - return ( - React.createElement("button", { - onClick: this.vote, - className: "btn btn-xs btn-default", - value: this.props.candidate.id}, "Vote" - ) - ); - } - } -}); - var MessageBar = React.createClass({displayName: "MessageBar", sendMessage: function (content) { socket.emit("message:new", { @@ -296,280 +522,114 @@ var MessageBar = React.createClass({displayName: "MessageBar", } }); -var JoinGatherButton = React.createClass({displayName: "JoinGatherButton", - joinGather: function (e) { - e.preventDefault(); - socket.emit("gather:join", {}); - }, +"use strict"; + +var UserCounter = React.createClass({displayName: "UserCounter", render: function () { - var message = this.props.buttonName || "Join Gather"; - var buttonClass = "btn btn-primary"; - if (this.props.buttonClass) { - buttonClass += " " + this.props.buttonClass; - } - return (React.createElement("button", { - onClick: this.joinGather, - className: buttonClass}, message)) + return ( + React.createElement("li", null, + React.createElement("a", {href: "#"}, + React.createElement("i", {className: "fa fa-users fa-fw"}), " Online", + React.createElement("span", {className: "badge add-left"}, " ", this.props.count, " ") + ) + ) + ); } }); -var GatherProgress = React.createClass({displayName: "GatherProgress", - gatheringProgress: function () { - var num = this.props.gather.gatherers.length; - var den = 12; - return { - num: num, - den: den, - message: num + " / " + den - }; +var UserLogin = React.createClass({displayName: "UserLogin", + authorizeId: function (id) { + id = parseInt(id, 10); + socket.emit("users:authorize", { + id: id + }); }, - electionProgress: function () { - var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { - if (gatherer.leaderVote) acc++; - return acc; - }, 0); - var den = 12; - return { - num: num, - den: den, - message: den - num + " more votes required" - }; - }, - selectionProgress: function () { - var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { - if (gatherer.team !== "lobby") acc++; - return acc; - }, 0); - var den = 12; - - return { - num: num, - den: den, - message: num + " out of " + den + " players assigned" - }; + handleSubmit: function (e) { + e.preventDefault(); + var id = React.findDOMNode(this.refs.authorize_id).value.trim(); + if (!id) return; + React.findDOMNode(this.refs.authorize_id).value = ''; + this.authorizeId(id); + return; }, render: function () { - var progress; - var gatherState = this.props.gather.state; - if (gatherState === 'gathering' && this.props.gather.gatherers.length) { - progress = this.gatheringProgress(); - } else if (gatherState === 'election') { - progress = this.electionProgress(); - } else if (gatherState === 'selection') { - progress = this.selectionProgress(); - } - if (progress) { - var style = { - width: Math.round((progress.num / progress.den * 100)) + "%" - }; - return ( - React.createElement("div", {className: "panel-body"}, - React.createElement("p", null, "Gather Progress"), - React.createElement("div", {className: "progress"}, - React.createElement("div", {className: "progress-bar progress-bar-striped active", - "data-role": "progressbar", - "data-aria-valuenow": progress.num, - "data-aria-valuemin": "0", - "data-aria-valuemax": progress.den, - style: style}, - progress.message - ) - ) + return ( + React.createElement("form", {onSubmit: this.handleSubmit}, + React.createElement("div", {className: "input-group signin"}, + React.createElement("input", { + id: "btn-input", + type: "text", + className: "form-control", + ref: "authorize_id", + placeholder: "Choose an ID..."}), + React.createElement("span", {className: "input-group-btn"}, + React.createElement("input", { + type: "submit", + className: "btn btn-primary", + id: "btn-chat", + value: "Login"}) + ) + ), + React.createElement("div", {className: "signin"}, + React.createElement("p", {className: "text-center"}, React.createElement("small", null, "Just a temporary measure until genuine authentication is implemented")) ) + ) + ); + } +}) + +var UserMenu = React.createClass({displayName: "UserMenu", + getDefaultProps: function () { + return { + count: 0, + users: [] + }; + }, + componentDidMount: function () { + socket.on('users:update', this.updateUsers); + }, + updateUsers: function (data) { + this.setProps({ + count: data.count, + users: data.users + }); + }, + render: function () { + var users = this.props.users.map(function (user) { + return ( + React.createElement("li", {key: user.id}, React.createElement("a", {href: "#"}, user.username)) + ); + }); + return ( + React.createElement("ul", {className: "nav", id: "side-menu"}, + React.createElement(UserCounter, React.__spread({}, this.props)), + users, + React.createElement("li", null, React.createElement("br", null), React.createElement(UserLogin, null), React.createElement("br", null)) + ) + ); + } +}); + +var CurrentUser = React.createClass({displayName: "CurrentUser", + componentDidMount: function () { + var self = this; + socket.on("users:update", function (data) { + self.setProps({ + user: data.currentUser + }); + }); + socket.emit("users:refresh", {}); + }, + render: function () { + if (this.props.user) { + return ( + React.createElement("a", {href: "#"}, this.props.user.username, "  ", React.createElement("img", {src: this.props.user.avatar, + alt: "User Avatar", + height: "20", + width: "20"})) ); } else { return false; } } }); - -var Gather = React.createClass({displayName: "Gather", - getDefaultProps: function () { - return { - gather: { - gatherers: [] - } - } - }, - joinedGather: function () { - var self = this; - return this.props.gather.gatherers.some(function (gatherer) { - return gatherer.user.id === self.props.currentUser.id; - }); - }, - componentDidMount: function () { - var self = this; - socket.on("gather:refresh", function (data) { - self.setProps({ - gather: data.gather, - currentUser: data.currentUser - }); - }); - }, - stateDescription: function () { - switch(this.props.gather.state) { - case "gathering": - return "Waiting for more gatherers"; - case "election": - return "Currently voting for team leaders"; - case "selection": - return "Waiting for leaders to picking teams"; - case "done": - return "Gather completed"; - default: - return "Initialising gather"; - } - }, - leaveGather: function (e) { - e.preventDefault(); - socket.emit("gather:leave", {}); - }, - inviteToGather: function (e) { - e.preventDefault(); - }, - currentGatherer: function () { - var current = null; - var self = this; - this.props.gather.gatherers.forEach(function (gatherer) { - if (gatherer.id === self.props.currentUser.id) current = gatherer; - }); - return current; - }, - render: function () { - var joinButton; - if (this.joinedGather()) { - joinButton = (React.createElement("li", null, React.createElement("button", { - onClick: this.leaveGather, - className: "btn btn-danger"}, "Leave Gather"))); - } else { - joinButton = (React.createElement("li", null, React.createElement(JoinGatherButton, null))); - } - var inviteButton; - if (this.props.gather.state === 'gathering') { - inviteButton = (React.createElement("li", null, React.createElement("button", { - onClick: this.inviteToGather, - className: "btn btn-primary"}, "Invite to Gather"))); - } - return ( - React.createElement("div", {className: "panel panel-default"}, - React.createElement("div", {className: "panel-heading"}, - React.createElement("strong", null, "NS2 Gather "), - React.createElement("span", {className: "badge add-left"}, this.props.gather.gatherers.length), - React.createElement("br", null), - this.stateDescription() - ), - React.createElement(Gatherers, {gather: this.props.gather, currentGatherer: this.currentGatherer()}), - React.createElement(GatherProgress, {gather: this.props.gather}), - React.createElement("div", {className: "panel-footer text-right"}, - React.createElement("ul", {className: "list-inline"}, - inviteButton, - joinButton - ) - ) - ) - ); - } -}); - -var LeaderPoll = React.createClass({displayName: "LeaderPoll", - render: function () { - return ( - React.createElement("div", {className: "panel-body"} - ) - ); - } -}); - -var Gatherers = React.createClass({displayName: "Gatherers", - render: function () { - var self = this; - var gatherers = this.props.gather.gatherers.map(function (gatherer) { - var lifeforms = ( - gatherer.user.ability.lifeforms.map(function (lifeform) { - return (React.createElement("span", {className: "label label-default"}, lifeform)); - }) - ); - - var commBadge; - if (gatherer.user.ability.commander) { - commBadge = (React.createElement("img", {src: "/images/commander.png", - alt: "Commander", - height: "20", - width: "20"})); - } - - var division = (React.createElement("span", {className: "label label-primary"}, gatherer.user.ability.division)); - var action = lifeforms; - if (self.props.gather.state === "election") { - var votes = self.props.gather.gatherers.reduce(function (acc, voter) { - if (voter.leaderVote === gatherer.id) acc++; - return acc; - }, 0) - action = ( - React.createElement("div", {className: "text-right"}, - React.createElement("small", null, votes + " votes", "  "), - - React.createElement(VoteButton, {currentGatherer: self.props.currentGatherer, candidate: gatherer}) - ) - ); - } - - return ( - React.createElement("tr", {key: gatherer.user.id}, - React.createElement("td", {className: "col-md-1"}, commBadge), - React.createElement("td", {className: "col-md-5"}, gatherer.user.username), - React.createElement("td", {className: "col-md-3"}, division, " "), - React.createElement("td", {className: "col-md-2"}, action, " ") - ) - ); - }) - if (this.props.gather.gatherers.length) { - return ( - React.createElement("div", {className: "panel-body"}, - React.createElement("div", {className: "panel panel-default"}, - React.createElement("div", {className: "panel-heading"}, - React.createElement("h5", {className: "panel-title"}, "Roster") - ), - React.createElement("table", {className: "table roster-table"}, - React.createElement("tbody", null, - gatherers - ) - ) - ) - ) - ); - } else { - return (React.createElement("div", {className: "panel-body text-center"}, React.createElement(JoinGatherButton, {buttonClass: "btn-lg", buttonName: "Start a Gather"}))); - } - } -}); - -var socket; - -function initialiseComponents () { - var socketUrl = window.location.protocol + "//" + window.location.host; - socket = io(socketUrl) - .on("connect", function () { - console.log("Connected"); - }) - .on("reconnect", function () { - console.log("Reconnected"); - }) - .on("disconnect", function () { - console.log("Disconnected") - }); - - React.render(React.createElement(UserMenu, null), document.getElementById('side-menu')); - React.render(React.createElement(Chatroom, null), document.getElementById('chatroom')); - React.render(React.createElement(Gather, null), document.getElementById('gathers')); - React.render(React.createElement(CurrentUser, null), document.getElementById('currentuser')); -}; - -initialiseComponents(); - - - -}); - - -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtZWQuanMiLCJzb3VyY2VzIjpbbnVsbF0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLENBQUMsQ0FBQyxZQUFZOztBQUVkLFlBQVksQ0FBQzs7QUFFYixJQUFJLGlDQUFpQywyQkFBQTtDQUNwQyxNQUFNLEVBQUUsWUFBWTtFQUNuQjtHQUNDLG9CQUFBLElBQUcsRUFBQSxJQUFDLEVBQUE7SUFDSCxvQkFBQSxHQUFFLEVBQUEsQ0FBQSxDQUFDLElBQUEsRUFBSSxDQUFDLEdBQUksQ0FBQSxFQUFBO0tBQ1gsb0JBQUEsR0FBRSxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxtQkFBb0IsQ0FBSSxDQUFBLEVBQUEsU0FBQSxFQUFBLENBQUE7QUFBQSxLQUNyQyxvQkFBQSxNQUFLLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLGdCQUFpQixDQUFBLEVBQUEsR0FBQSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFDLEdBQVEsQ0FBQTtJQUN6RCxDQUFBO0dBQ0EsQ0FBQTtJQUNKO0VBQ0Y7QUFDRixDQUFDLENBQUMsQ0FBQzs7QUFFSCxJQUFJLCtCQUErQix5QkFBQTtDQUNsQyxXQUFXLEVBQUUsVUFBVSxFQUFFLEVBQUU7RUFDMUIsRUFBRSxHQUFHLFFBQVEsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7RUFDdEIsTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtHQUM5QixFQUFFLEVBQUUsRUFBRTtHQUNOLENBQUMsQ0FBQztFQUNIO0NBQ0QsWUFBWSxFQUFFLFVBQVUsQ0FBQyxFQUFFO0VBQzFCLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztFQUNuQixJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0VBQ2hFLElBQUksQ0FBQyxFQUFFLEVBQUUsT0FBTztFQUNoQixLQUFLLENB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QUFFLFlBQVk7R0FDN0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUM7QUFDOUIsR0FBRyxDQUFDLENBQUM7O0NBRUosS0FBSyxDQUFDLE1BQU0sQ0FBQyxvQkFBQyxRQUFRLEVBQUEsSUFBQSxDQUFHLENBQUEsRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUM7Q0FDakUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxvQkFBQyxRQUFRLEVBQUEsSUFBQSxDQUFHLENBQUEsRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7Q0FDaEUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxvQkFBQyxNQUFNLEVBQUEsSUFBQSxDQUFHLENBQUEsRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7Q0FDN0QsS0FBSyxDQUFDLE1BQU0sQ0FBQyxvQkFBQyxXQUFXLEVBQUEsSUFBQSxDQUFHLENBQUEsRUFBRSxRQUFRLENBQUMsY0FBYyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7QUFDdkUsQ0FBQyxDQUFDOztBQUVGLG9CQUFvQixFQUFFLENBQUM7QUFDdkI7QUFDQTs7QUFFQSxDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIiQoZnVuY3Rpb24gKCkge1xuXG5cInVzZSBzdHJpY3RcIjtcblxudmFyIFVzZXJDb3VudGVyID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0PGxpPlxuXHRcdFx0XHQ8YSBocmVmPVwiI1wiPlxuXHRcdFx0XHRcdDxpIGNsYXNzTmFtZT1cImZhIGZhLXVzZXJzIGZhLWZ3XCI+PC9pPiBPbmxpbmUgXG5cdFx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiYmFkZ2UgYWRkLWxlZnRcIj4ge3RoaXMucHJvcHMuY291bnR9IDwvc3Bhbj5cblx0XHRcdFx0PC9hPlxuXHRcdFx0PC9saT5cblx0XHQpO1xuXHR9XG59KTtcblxudmFyIFVzZXJMb2dpbiA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0YXV0aG9yaXplSWQ6IGZ1bmN0aW9uIChpZCkge1xuXHRcdGlkID0gcGFyc2VJbnQoaWQsIDEwKTtcblx0XHRzb2NrZXQuZW1pdChcInVzZXJzOmF1dGhvcml6ZVwiLCB7XG5cdFx0XHRpZDogaWRcblx0XHR9KTtcblx0fSxcblx0aGFuZGxlU3VibWl0OiBmdW5jdGlvbiAoZSkge1xuXHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHR2YXIgaWQgPSBSZWFjdC5maW5kRE9NTm9kZSh0aGlzLnJlZnMuYXV0aG9yaXplX2lkKS52YWx1ZS50cmltKCk7XG5cdFx0aWYgKCFpZCkgcmV0dXJuO1xuXHRcdFJlYWN0LmZpbmRET01Ob2RlKHRoaXMucmVmcy5hdXRob3JpemVfaWQpLnZhbHVlID0gJyc7XG5cdFx0dGhpcy5hdXRob3JpemVJZChpZCk7XG5cdFx0cmV0dXJuO1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0PGZvcm0gb25TdWJtaXQ9e3RoaXMuaGFuZGxlU3VibWl0fSA+XG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiaW5wdXQtZ3JvdXAgc2lnbmluXCI+XG5cdFx0XHRcdFx0PGlucHV0IFxuXHRcdFx0XHRcdFx0aWQ9XCJidG4taW5wdXRcIiBcblx0XHRcdFx0XHRcdHR5cGU9XCJ0ZXh0XCIgXG5cdFx0XHRcdFx0XHRjbGFzc05hbWU9XCJmb3JtLWNvbnRyb2xcIiBcblx0XHRcdFx0XHRcdHJlZj1cImF1dGhvcml6ZV9pZFwiXG5cdFx0XHRcdFx0XHRwbGFjZWhvbGRlcj1cIkNob29zZSBhbiBJRC4uLlwiIC8+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiaW5wdXQtZ3JvdXAtYnRuXCI+XG5cdFx0XHRcdFx0XHQ8aW5wdXQgXG5cdFx0XHRcdFx0XHRcdHR5cGU9XCJzdWJtaXRcIiBcblx0XHRcdFx0XHRcdFx0Y2xhc3NOYW1lPVwiYnRuIGJ0bi1wcmltYXJ5XCIgXG5cdFx0XHRcdFx0XHRcdGlkPVwiYnRuLWNoYXRcIiBcblx0XHRcdFx0XHRcdFx0dmFsdWU9XCJMb2dpblwiIC8+XG5cdFx0XHRcdFx0PC9zcGFuPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJzaWduaW5cIj5cblx0XHRcdFx0PHAgY2xhc3NOYW1lPVwidGV4dC1jZW50ZXJcIj48c21hbGw+SnVzdCBhIHRlbXBvcmFyeSBtZWFzdXJlIHVudGlsIGdlbnVpbmUgYXV0aGVudGljYXRpb24gaXMgaW1wbGVtZW50ZWQ8L3NtYWxsPjwvcD5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHQ8L2Zvcm0+XG5cdFx0KTtcblx0fVxufSlcblxudmFyIFVzZXJNZW51ID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0Y291bnQ6IDAsXG5cdFx0XHR1c2VyczogW11cblx0XHR9O1xuXHR9LFxuXHRjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gKCkge1xuXHRcdHNvY2tldC5vbigndXNlcnM6dXBkYXRlJywgdGhpcy51cGRhdGVVc2Vycyk7XG5cdH0sXG5cdHVwZGF0ZVVzZXJzOiBmdW5jdGlvbiAoZGF0YSkge1xuXHRcdHRoaXMuc2V0UHJvcHMoe1xuXHRcdFx0Y291bnQ6IGRhdGEuY291bnQsXG5cdFx0XHR1c2VyczogZGF0YS51c2Vyc1xuXHRcdH0pO1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgdXNlcnMgPSB0aGlzLnByb3BzLnVzZXJzLm1hcChmdW5jdGlvbiAodXNlcikge1xuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0PGxpIGtleT17dXNlci5pZH0+PGEgaHJlZj1cIiNcIj57dXNlci51c2VybmFtZX08L2E+PC9saT5cblx0XHRcdCk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIChcblx0XHRcdDx1bCBjbGFzc05hbWU9XCJuYXZcIiBpZD1cInNpZGUtbWVudVwiPlxuXHRcdFx0XHQ8VXNlckNvdW50ZXIgey4uLnRoaXMucHJvcHN9IC8+XG5cdFx0XHRcdHt1c2Vyc31cblx0XHRcdFx0PGxpPjxiciAvPjxVc2VyTG9naW4gLz48YnIgLz48L2xpPlxuXHRcdFx0PC91bD5cblx0XHQpO1xuXHR9XG59KTtcblxudmFyIENoYXRyb29tID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0aGlzdG9yeTogW11cblx0XHR9O1xuXHR9LFxuXHRjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHR2YXIgVElNRVJfSU5URVJWQUwgPSA2MDAwMDsgLy8gRXZlcnkgbWludXRlXG5cblx0XHRzb2NrZXQub24oXCJtZXNzYWdlOm5ld1wiLCBmdW5jdGlvbiAoZGF0YSkge1xuXHRcdFx0dmFyIGhpc3RvcnkgPSBzZWxmLnByb3BzLmhpc3Rvcnk7XG5cdFx0XHRoaXN0b3J5LnB1c2goZGF0YSk7XG5cdFx0XHRzZWxmLnNldFByb3BzKHtcblx0XHRcdFx0aGlzdG9yeTogaGlzdG9yeVxuXHRcdFx0fSk7XG5cdFx0XHRzZWxmLnNjcm9sbFRvQm90dG9tKCk7XG5cdFx0fSk7XG5cblx0XHQvLyBNZXNzYWdlIEhpc3RvcnkgUmV0cmlldmVkXG5cdFx0c29ja2V0Lm9uKFwibWVzc2FnZTpyZWZyZXNoXCIsIGZ1bmN0aW9uIChkYXRhKSB7XG5cdFx0XHRzZWxmLnNldFByb3BzKHtcblx0XHRcdFx0aGlzdG9yeTogZGF0YS5jaGF0SGlzdG9yeVxuXHRcdFx0fSk7XG5cdFx0XHRzZWxmLnNjcm9sbFRvQm90dG9tKCk7XG5cdFx0fSk7XG5cblx0XHRzb2NrZXQuZW1pdChcIm1lc3NhZ2U6cmVmcmVzaFwiLCB7fSk7XG5cblx0XHRzZWxmLnRpbWVyID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkge1xuXHRcdFx0aWYgKHNlbGYucmVmcy5tZXNzYWdlcykgc2VsZi5yZWZzLm1lc3NhZ2VzLnJlZnJlc2hUaW1lKCk7XG5cdFx0fSwgVElNRVJfSU5URVJWQUwpO1xuXHR9LFxuXG5cdGNvbXBvbmVudERpZFVubW91bnQ6IGZ1bmN0aW9uICgpIHtcblx0XHRjbGVhckludGVydmFsKHRoaXMudGltZXIpO1xuXHR9LFxuXHRzZW5kTWVzc2FnZTogZnVuY3Rpb24gKG1lc3NhZ2UpIHtcblx0XHRzb2NrZXQuZW1pdChcIm5ld01lc3NhZ2VcIiwge21lc3NhZ2U6IG1lc3NhZ2V9KTtcblx0fSxcblx0c2Nyb2xsVG9Cb3R0b206IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgbm9kZSA9IFJlYWN0LmZpbmRET01Ob2RlKHRoaXMucmVmcy5tZXNzYWdlQ29udGFpbmVyKTtcblx0ICBub2RlLnNjcm9sbFRvcCA9IG5vZGUuc2Nyb2xsSGVpZ2h0O1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgbWVzc2FnZXMgPSB0aGlzLnByb3BzLmhpc3RvcnkubWFwKGZ1bmN0aW9uIChtZXNzYWdlKSB7XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHQ8Q2hhdE1lc3NhZ2UgXG5cdFx0XHRcdFx0YXZhdGFyPXttZXNzYWdlLmF1dGhvci5hdmF0YXJ9IFxuXHRcdFx0XHRcdHVzZXJuYW1lPXttZXNzYWdlLmF1dGhvci51c2VybmFtZX1cblx0XHRcdFx0XHRjb250ZW50PXttZXNzYWdlLmNvbnRlbnR9XG5cdFx0XHRcdFx0cmVmPVwibWVzc2FnZXNcIlxuXHRcdFx0XHRcdGNyZWF0ZWRBdD17bWVzc2FnZS5jcmVhdGVkQXR9IC8+XG5cdFx0XHQpO1xuXHRcdH0pO1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsIHBhbmVsLWRlZmF1bHRcIj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1oZWFkaW5nXCI+R2F0aGVyIENoYXQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1ib2R5XCI+XG5cdFx0XHRcdFx0PHVsIGNsYXNzTmFtZT1cImNoYXRcIiBpZD1cImNoYXRtZXNzYWdlc1wiIHJlZj1cIm1lc3NhZ2VDb250YWluZXJcIj5cblx0XHRcdFx0XHRcdHttZXNzYWdlc31cblx0XHRcdFx0XHQ8L3VsPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1mb290ZXJcIj5cblx0XHRcdFx0XHQ8TWVzc2FnZUJhciAvPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgQ2hhdE1lc3NhZ2UgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiB7XG5cdFx0XHR0aW1lQWdvOiAkLnRpbWVhZ28odGhpcy5wcm9wcy5jcmVhdGVkQXQpXG5cdFx0fVxuXHR9LFxuXHRyZWZyZXNoVGltZTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRzZWxmLnNldFN0YXRlKHtcblx0XHRcdHRpbWVBZ286ICQudGltZWFnbyhzZWxmLnByb3BzLmNyZWF0ZWRBdClcblx0XHR9KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdDxsaSBjbGFzc05hbWU9XCJsZWZ0IGNsZWFyZml4XCI+XG5cdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cImNoYXQtaW1nIHB1bGwtbGVmdFwiPlxuXHRcdFx0XHRcdFx0PGltZyBcblx0XHRcdFx0XHRcdFx0c3JjPXt0aGlzLnByb3BzLmF2YXRhcn0gXG5cdFx0XHRcdFx0XHRcdGFsdD1cIlVzZXIgQXZhdGFyXCIgXG5cdFx0XHRcdFx0XHRcdGhlaWdodD1cIjQwXCJcblx0XHRcdFx0XHRcdFx0d2lkdGg9XCI0MFwiXG5cdFx0XHRcdFx0XHRcdGNsYXNzTmFtZT1cImltZy1jaXJjbGVcIiAvPlxuXHRcdFx0XHQ8L3NwYW4+XG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiY2hhdC1ib2R5IGNsZWFyZml4XCI+XG5cdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJoZWFkZXJcIj5cblx0XHRcdFx0XHRcdDxzdHJvbmcgY2xhc3NOYW1lPVwicHJpbWFyeS1mb250XCI+e3RoaXMucHJvcHMudXNlcm5hbWV9PC9zdHJvbmc+XG5cdFx0XHRcdFx0XHQ8c21hbGwgY2xhc3NOYW1lPVwicHVsbC1yaWdodCB0ZXh0LW11dGVkXCI+XG5cdFx0XHRcdFx0XHRcdDxpIGNsYXNzTmFtZT1cImZhIGZhLWNsb2NrLW8gZmEtZndcIj48L2k+IHt0aGlzLnN0YXRlLnRpbWVBZ299XG5cdFx0XHRcdFx0XHQ8L3NtYWxsPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDxwPnt0aGlzLnByb3BzLmNvbnRlbnR9PC9wPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvbGk+XG5cdFx0KTtcblx0fVxufSk7XG5cbnZhciBDdXJyZW50VXNlciA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0Y29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0c29ja2V0Lm9uKFwidXNlcnM6dXBkYXRlXCIsIGZ1bmN0aW9uIChkYXRhKSB7XG5cdFx0XHRzZWxmLnNldFByb3BzKHtcblx0XHRcdFx0dXNlcjogZGF0YS5jdXJyZW50VXNlclxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0c29ja2V0LmVtaXQoXCJ1c2VyczpyZWZyZXNoXCIsIHt9KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKHRoaXMucHJvcHMudXNlcikge1xuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0PGEgaHJlZj1cIiNcIj57dGhpcy5wcm9wcy51c2VyLnVzZXJuYW1lfSAmbmJzcDs8aW1nIHNyYz17dGhpcy5wcm9wcy51c2VyLmF2YXRhcn1cblx0XHRcdFx0XHRhbHQ9XCJVc2VyIEF2YXRhclwiIFxuXHRcdFx0XHRcdGhlaWdodD1cIjIwXCJcblx0XHRcdFx0XHR3aWR0aD1cIjIwXCIgLz48L2E+XG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG59KTtcblxudmFyIFZvdGVCdXR0b24gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdGNhbmNlbFZvdGU6IGZ1bmN0aW9uIChlKSB7XG5cdFx0c29ja2V0LmVtaXQoXCJnYXRoZXI6dm90ZVwiLCB7XG5cdFx0XHRsZWFkZXI6IHtcblx0XHRcdFx0Y2FuZGlkYXRlOiBudWxsXG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cdHZvdGU6IGZ1bmN0aW9uIChlKSB7XG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdHNvY2tldC5lbWl0KFwiZ2F0aGVyOnZvdGVcIiwge1xuXHRcdFx0bGVhZGVyOiB7XG5cdFx0XHRcdGNhbmRpZGF0ZTogcGFyc2VJbnQoZS50YXJnZXQudmFsdWUsIDEwKVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHRpZiAodGhpcy5wcm9wcy5jdXJyZW50R2F0aGVyZXIgPT09IG51bGwpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0aWYgKHRoaXMucHJvcHMuY3VycmVudEdhdGhlcmVyLmxlYWRlclZvdGUgPT09IHRoaXMucHJvcHMuY2FuZGlkYXRlLmlkKSB7XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHQ8YnV0dG9uIFxuXHRcdFx0XHRcdG9uQ2xpY2s9e3RoaXMuY2FuY2VsVm90ZX0gXG5cdFx0XHRcdFx0Y2xhc3NOYW1lPVwiYnRuIGJ0bi14cyBidG4tc3VjY2Vzc1wiPlZvdGVkXG5cdFx0XHRcdDwvYnV0dG9uPlxuXHRcdFx0KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0PGJ1dHRvbiBcblx0XHRcdFx0XHRvbkNsaWNrPXt0aGlzLnZvdGV9IFxuXHRcdFx0XHRcdGNsYXNzTmFtZT1cImJ0biBidG4teHMgYnRuLWRlZmF1bHRcIlxuXHRcdFx0XHRcdHZhbHVlPXt0aGlzLnByb3BzLmNhbmRpZGF0ZS5pZH0+Vm90ZVxuXHRcdFx0XHQ8L2J1dHRvbj5cblx0XHRcdCk7XG5cdFx0fVxuXHR9XG59KTtcblxudmFyIE1lc3NhZ2VCYXIgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdHNlbmRNZXNzYWdlOiBmdW5jdGlvbiAoY29udGVudCkge1xuXHRcdHNvY2tldC5lbWl0KFwibWVzc2FnZTpuZXdcIiwge1xuXHRcdFx0Y29udGVudDogY29udGVudFxuXHRcdH0pO1xuXHR9LFxuXHRoYW5kbGVTdWJtaXQ6IGZ1bmN0aW9uIChlKSB7XG5cdFx0ZS5wcmV2ZW50RGVmYXVsdCgpO1xuXHRcdHZhciBjb250ZW50ID0gUmVhY3QuZmluZERPTU5vZGUodGhpcy5yZWZzLmNvbnRlbnQpLnZhbHVlLnRyaW0oKTtcblx0XHRpZiAoIWNvbnRlbnQpIHJldHVybjtcblx0XHRSZWFjdC5maW5kRE9NTm9kZSh0aGlzLnJlZnMuY29udGVudCkudmFsdWUgPSAnJztcblx0XHR0aGlzLnNlbmRNZXNzYWdlKGNvbnRlbnQpO1xuXHRcdHJldHVybjtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdDxmb3JtIG9uU3VibWl0PXt0aGlzLmhhbmRsZVN1Ym1pdH0gPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImlucHV0LWdyb3VwXCI+XG5cdFx0XHRcdFx0PGlucHV0IFxuXHRcdFx0XHRcdFx0aWQ9XCJidG4taW5wdXRcIiBcblx0XHRcdFx0XHRcdHR5cGU9XCJ0ZXh0XCIgXG5cdFx0XHRcdFx0XHRjbGFzc05hbWU9XCJmb3JtLWNvbnRyb2xcIiBcblx0XHRcdFx0XHRcdHJlZj1cImNvbnRlbnRcIlxuXHRcdFx0XHRcdFx0cGxhY2Vob2xkZXI9XCJCZSBwb2xpdGUgcGxlYXNlLi4uXCIgLz5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzc05hbWU9XCJpbnB1dC1ncm91cC1idG5cIj5cblx0XHRcdFx0XHRcdDxpbnB1dCBcblx0XHRcdFx0XHRcdFx0dHlwZT1cInN1Ym1pdFwiIFxuXHRcdFx0XHRcdFx0XHRjbGFzc05hbWU9XCJidG4gYnRuLXByaW1hcnlcIiBcblx0XHRcdFx0XHRcdFx0aWQ9XCJidG4tY2hhdFwiIFxuXHRcdFx0XHRcdFx0XHR2YWx1ZT1cIlNlbmRcIiAvPlxuXHRcdFx0XHRcdDwvc3Bhbj5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHQ8L2Zvcm0+XG5cdFx0KTtcblx0fVxufSk7XG5cbnZhciBKb2luR2F0aGVyQnV0dG9uID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRqb2luR2F0aGVyOiBmdW5jdGlvbiAoZSkge1xuXHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRzb2NrZXQuZW1pdChcImdhdGhlcjpqb2luXCIsIHt9KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIG1lc3NhZ2UgPSB0aGlzLnByb3BzLmJ1dHRvbk5hbWUgfHwgXCJKb2luIEdhdGhlclwiO1xuXHRcdHZhciBidXR0b25DbGFzcyA9IFwiYnRuIGJ0bi1wcmltYXJ5XCI7XG5cdFx0aWYgKHRoaXMucHJvcHMuYnV0dG9uQ2xhc3MpIHtcblx0XHRcdGJ1dHRvbkNsYXNzICs9IFwiIFwiICsgdGhpcy5wcm9wcy5idXR0b25DbGFzcztcblx0XHR9XG5cdFx0cmV0dXJuICg8YnV0dG9uIFxuXHRcdFx0XHRcdFx0XHRvbkNsaWNrPXt0aGlzLmpvaW5HYXRoZXJ9IFxuXHRcdFx0XHRcdFx0XHRjbGFzc05hbWU9e2J1dHRvbkNsYXNzfT57bWVzc2FnZX08L2J1dHRvbj4pXG5cdH1cbn0pO1xuXG52YXIgR2F0aGVyUHJvZ3Jlc3MgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdGdhdGhlcmluZ1Byb2dyZXNzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIG51bSA9IHRoaXMucHJvcHMuZ2F0aGVyLmdhdGhlcmVycy5sZW5ndGg7XG5cdFx0dmFyIGRlbiA9IDEyO1xuXHRcdHJldHVybiB7XG5cdFx0XHRudW06IG51bSxcblx0XHRcdGRlbjogZGVuLFxuXHRcdFx0bWVzc2FnZTogbnVtICsgXCIgLyBcIiArIGRlblxuXHRcdH07XG5cdH0sXG5cdGVsZWN0aW9uUHJvZ3Jlc3M6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgbnVtID0gdGhpcy5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBnYXRoZXJlcikge1xuXHRcdFx0aWYgKGdhdGhlcmVyLmxlYWRlclZvdGUpIGFjYysrO1xuXHRcdFx0cmV0dXJuIGFjYztcblx0XHR9LCAwKTtcblx0XHR2YXIgZGVuID0gMTI7XG5cdFx0cmV0dXJuIHtcblx0XHRcdG51bTogbnVtLFxuXHRcdFx0ZGVuOiBkZW4sXG5cdFx0XHRtZXNzYWdlOiBkZW4gLSBudW0gKyBcIiBtb3JlIHZvdGVzIHJlcXVpcmVkXCJcblx0XHR9O1xuXHR9LFxuXHRzZWxlY3Rpb25Qcm9ncmVzczogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBudW0gPSB0aGlzLnByb3BzLmdhdGhlci5nYXRoZXJlcnMucmVkdWNlKGZ1bmN0aW9uIChhY2MsIGdhdGhlcmVyKSB7XG5cdFx0XHRpZiAoZ2F0aGVyZXIudGVhbSAhPT0gXCJsb2JieVwiKSBhY2MrKztcblx0XHRcdHJldHVybiBhY2M7XG5cdFx0fSwgMCk7XG5cdFx0dmFyIGRlbiA9IDEyO1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdG51bTogbnVtLFxuXHRcdFx0ZGVuOiBkZW4sXG5cdFx0XHRtZXNzYWdlOiBudW0gKyBcIiBvdXQgb2YgXCIgKyBkZW4gKyBcIiBwbGF5ZXJzIGFzc2lnbmVkXCJcblx0XHR9O1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgcHJvZ3Jlc3M7XG5cdFx0dmFyIGdhdGhlclN0YXRlID0gdGhpcy5wcm9wcy5nYXRoZXIuc3RhdGU7XG5cdFx0aWYgKGdhdGhlclN0YXRlID09PSAnZ2F0aGVyaW5nJyAmJiB0aGlzLnByb3BzLmdhdGhlci5nYXRoZXJlcnMubGVuZ3RoKSB7XG5cdFx0XHRwcm9ncmVzcyA9IHRoaXMuZ2F0aGVyaW5nUHJvZ3Jlc3MoKTtcblx0XHR9IGVsc2UgaWYgKGdhdGhlclN0YXRlID09PSAnZWxlY3Rpb24nKSB7XG5cdFx0XHRwcm9ncmVzcyA9IHRoaXMuZWxlY3Rpb25Qcm9ncmVzcygpO1xuXHRcdH0gZWxzZSBpZiAoZ2F0aGVyU3RhdGUgPT09ICdzZWxlY3Rpb24nKSB7XG5cdFx0XHRwcm9ncmVzcyA9IHRoaXMuc2VsZWN0aW9uUHJvZ3Jlc3MoKTtcblx0XHR9XG5cdFx0aWYgKHByb2dyZXNzKSB7XG5cdFx0XHR2YXIgc3R5bGUgPSB7XG5cdFx0XHRcdHdpZHRoOiBNYXRoLnJvdW5kKChwcm9ncmVzcy5udW0gLyBwcm9ncmVzcy5kZW4gKiAxMDApKSArIFwiJVwiXG5cdFx0XHR9O1xuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1ib2R5XCI+XG5cdFx0XHRcdFx0PHA+R2F0aGVyIFByb2dyZXNzPC9wPlxuXHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwicHJvZ3Jlc3NcIj5cblx0XHRcdFx0XHQgIDxkaXYgY2xhc3NOYW1lPVwicHJvZ3Jlc3MtYmFyIHByb2dyZXNzLWJhci1zdHJpcGVkIGFjdGl2ZVwiIFxuXHRcdFx0XHRcdCAgXHRkYXRhLXJvbGU9XCJwcm9ncmVzc2JhclwiIFxuXHRcdFx0XHRcdCAgXHRkYXRhLWFyaWEtdmFsdWVub3c9e3Byb2dyZXNzLm51bX0gXG5cdFx0XHRcdFx0ICBcdGRhdGEtYXJpYS12YWx1ZW1pbj1cIjBcIiBcblx0XHRcdFx0XHQgIFx0ZGF0YS1hcmlhLXZhbHVlbWF4PXtwcm9ncmVzcy5kZW59IFxuXHRcdFx0XHRcdCAgXHRzdHlsZT17c3R5bGV9PlxuXHRcdFx0XHRcdCAgICB7cHJvZ3Jlc3MubWVzc2FnZX1cblx0XHRcdFx0XHQgIDwvZGl2PlxuXHRcdFx0XHQgIDwvZGl2PlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdH1cbn0pO1xuXG52YXIgR2F0aGVyID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0Z2F0aGVyOiB7XG5cdFx0XHRcdGdhdGhlcmVyczogW11cblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cdGpvaW5lZEdhdGhlcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRyZXR1cm4gdGhpcy5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLnNvbWUoZnVuY3Rpb24gKGdhdGhlcmVyKSB7XG5cdFx0XHRyZXR1cm4gZ2F0aGVyZXIudXNlci5pZCA9PT0gc2VsZi5wcm9wcy5jdXJyZW50VXNlci5pZDtcblx0XHR9KTtcblx0fSxcblx0Y29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0c29ja2V0Lm9uKFwiZ2F0aGVyOnJlZnJlc2hcIiwgZnVuY3Rpb24gKGRhdGEpIHtcblx0XHRcdHNlbGYuc2V0UHJvcHMoe1xuXHRcdFx0XHRnYXRoZXI6IGRhdGEuZ2F0aGVyLFxuXHRcdFx0XHRjdXJyZW50VXNlcjogZGF0YS5jdXJyZW50VXNlclxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH0sXG5cdHN0YXRlRGVzY3JpcHRpb246IGZ1bmN0aW9uICgpIHtcblx0XHRzd2l0Y2godGhpcy5wcm9wcy5nYXRoZXIuc3RhdGUpIHtcblx0XHRcdGNhc2UgXCJnYXRoZXJpbmdcIjpcblx0XHRcdFx0cmV0dXJuIFwiV2FpdGluZyBmb3IgbW9yZSBnYXRoZXJlcnNcIjtcblx0XHRcdGNhc2UgXCJlbGVjdGlvblwiOlxuXHRcdFx0XHRyZXR1cm4gXCJDdXJyZW50bHkgdm90aW5nIGZvciB0ZWFtIGxlYWRlcnNcIjtcblx0XHRcdGNhc2UgXCJzZWxlY3Rpb25cIjpcblx0XHRcdFx0cmV0dXJuIFwiV2FpdGluZyBmb3IgbGVhZGVycyB0byBwaWNraW5nIHRlYW1zXCI7XG5cdFx0XHRjYXNlIFwiZG9uZVwiOlxuXHRcdFx0XHRyZXR1cm4gXCJHYXRoZXIgY29tcGxldGVkXCI7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHRyZXR1cm4gXCJJbml0aWFsaXNpbmcgZ2F0aGVyXCI7XG5cdFx0fVxuXHR9LFxuXHRsZWF2ZUdhdGhlcjogZnVuY3Rpb24gKGUpIHtcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0c29ja2V0LmVtaXQoXCJnYXRoZXI6bGVhdmVcIiwge30pO1xuXHR9LFxuXHRpbnZpdGVUb0dhdGhlcjogZnVuY3Rpb24gKGUpIHtcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdH0sXG5cdGN1cnJlbnRHYXRoZXJlcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjdXJyZW50ID0gbnVsbDtcblx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0dGhpcy5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLmZvckVhY2goZnVuY3Rpb24gKGdhdGhlcmVyKSB7XG5cdFx0XHRpZiAoZ2F0aGVyZXIuaWQgPT09IHNlbGYucHJvcHMuY3VycmVudFVzZXIuaWQpIGN1cnJlbnQgPSBnYXRoZXJlcjtcblx0XHR9KTtcblx0XHRyZXR1cm4gY3VycmVudDtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGpvaW5CdXR0b247XG5cdFx0aWYgKHRoaXMuam9pbmVkR2F0aGVyKCkpIHtcblx0XHRcdGpvaW5CdXR0b24gPSAoPGxpPjxidXR0b24gXG5cdFx0XHRcdFx0XHRcdG9uQ2xpY2s9e3RoaXMubGVhdmVHYXRoZXJ9IFxuXHRcdFx0XHRcdFx0XHRjbGFzc05hbWU9XCJidG4gYnRuLWRhbmdlclwiPkxlYXZlIEdhdGhlcjwvYnV0dG9uPjwvbGk+KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0am9pbkJ1dHRvbiA9ICg8bGk+PEpvaW5HYXRoZXJCdXR0b24gLz48L2xpPik7XG5cdFx0fVxuXHRcdHZhciBpbnZpdGVCdXR0b247XG5cdFx0aWYgKHRoaXMucHJvcHMuZ2F0aGVyLnN0YXRlID09PSAnZ2F0aGVyaW5nJykge1xuXHRcdFx0aW52aXRlQnV0dG9uID0gKDxsaT48YnV0dG9uXG5cdFx0XHRcdFx0XHRcdG9uQ2xpY2s9e3RoaXMuaW52aXRlVG9HYXRoZXJ9XG5cdFx0XHRcdFx0XHRcdGNsYXNzTmFtZT1cImJ0biBidG4tcHJpbWFyeVwiPkludml0ZSB0byBHYXRoZXI8L2J1dHRvbj48L2xpPik7XG5cdFx0fVxuXHRcdHJldHVybiAoXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsIHBhbmVsLWRlZmF1bHRcIj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1oZWFkaW5nXCI+XG5cdFx0XHRcdFx0PHN0cm9uZz5OUzIgR2F0aGVyIDwvc3Ryb25nPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cImJhZGdlIGFkZC1sZWZ0XCI+e3RoaXMucHJvcHMuZ2F0aGVyLmdhdGhlcmVycy5sZW5ndGh9PC9zcGFuPlxuXHRcdFx0XHRcdDxiciAvPlxuXHRcdFx0XHRcdHt0aGlzLnN0YXRlRGVzY3JpcHRpb24oKX1cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdDxHYXRoZXJlcnMgZ2F0aGVyPXt0aGlzLnByb3BzLmdhdGhlcn0gY3VycmVudEdhdGhlcmVyPXt0aGlzLmN1cnJlbnRHYXRoZXJlcigpfSAvPlxuXHRcdFx0XHQ8R2F0aGVyUHJvZ3Jlc3MgZ2F0aGVyPXt0aGlzLnByb3BzLmdhdGhlcn0gLz5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1mb290ZXIgdGV4dC1yaWdodFwiPlxuXHRcdFx0XHRcdDx1bCBjbGFzc05hbWU9XCJsaXN0LWlubGluZVwiPlxuXHRcdFx0XHRcdFx0e2ludml0ZUJ1dHRvbn1cblx0XHRcdFx0XHRcdHtqb2luQnV0dG9ufVxuXHRcdFx0XHRcdDwvdWw+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9kaXY+XG5cdFx0KTtcblx0fVxufSk7XG5cbnZhciBMZWFkZXJQb2xsID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gKFxuXHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1ib2R5XCI+XG5cdFx0XHQ8L2Rpdj5cblx0XHQpO1xuXHR9XG59KTtcblxudmFyIEdhdGhlcmVycyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlbGYgPSB0aGlzO1xuXHRcdHZhciBnYXRoZXJlcnMgPSB0aGlzLnByb3BzLmdhdGhlci5nYXRoZXJlcnMubWFwKGZ1bmN0aW9uIChnYXRoZXJlcikge1xuXHRcdFx0dmFyIGxpZmVmb3JtcyA9IChcblx0XHRcdFx0Z2F0aGVyZXIudXNlci5hYmlsaXR5LmxpZmVmb3Jtcy5tYXAoZnVuY3Rpb24gKGxpZmVmb3JtKSB7XG5cdFx0XHRcdFx0cmV0dXJuICg8c3BhbiBjbGFzc05hbWU9XCJsYWJlbCBsYWJlbC1kZWZhdWx0XCI+e2xpZmVmb3JtfTwvc3Bhbj4pO1xuXHRcdFx0XHR9KVxuXHRcdFx0KTtcblxuXHRcdFx0dmFyIGNvbW1CYWRnZTtcblx0XHRcdGlmIChnYXRoZXJlci51c2VyLmFiaWxpdHkuY29tbWFuZGVyKSB7XG5cdFx0XHRcdGNvbW1CYWRnZSA9ICg8aW1nIHNyYz1cIi9pbWFnZXMvY29tbWFuZGVyLnBuZ1wiIFxuXHRcdFx0XHRcdFx0XHRhbHQ9XCJDb21tYW5kZXJcIiBcblx0XHRcdFx0XHRcdFx0aGVpZ2h0PVwiMjBcIlxuXHRcdFx0XHRcdFx0XHR3aWR0aD1cIjIwXCIgLz4pO1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgZGl2aXNpb24gPSAoPHNwYW4gY2xhc3NOYW1lPVwibGFiZWwgbGFiZWwtcHJpbWFyeVwiPntnYXRoZXJlci51c2VyLmFiaWxpdHkuZGl2aXNpb259PC9zcGFuPik7XG5cdFx0XHR2YXIgYWN0aW9uID0gbGlmZWZvcm1zO1xuXHRcdFx0aWYgKHNlbGYucHJvcHMuZ2F0aGVyLnN0YXRlID09PSBcImVsZWN0aW9uXCIpIHtcblx0XHRcdFx0dmFyIHZvdGVzID0gc2VsZi5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCB2b3Rlcikge1xuXHRcdFx0XHRcdGlmICh2b3Rlci5sZWFkZXJWb3RlID09PSBnYXRoZXJlci5pZCkgYWNjKys7XG5cdFx0XHRcdFx0cmV0dXJuIGFjYztcblx0XHRcdFx0fSwgMClcblx0XHRcdFx0YWN0aW9uID0gKFxuXHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwidGV4dC1yaWdodFwiPlxuXHRcdFx0XHRcdDxzbWFsbD57dm90ZXMgKyBcIiB2b3Rlc1wifSAmbmJzcDs8L3NtYWxsPlxuXG5cdFx0XHRcdFx0PFZvdGVCdXR0b24gY3VycmVudEdhdGhlcmVyPXtzZWxmLnByb3BzLmN1cnJlbnRHYXRoZXJlcn0gY2FuZGlkYXRlPXtnYXRoZXJlcn0gLz5cblx0XHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0KTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0PHRyIGtleT17Z2F0aGVyZXIudXNlci5pZH0+XG5cdFx0XHRcdFx0PHRkIGNsYXNzTmFtZT1cImNvbC1tZC0xXCI+e2NvbW1CYWRnZX08L3RkPlxuXHRcdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJjb2wtbWQtNVwiPntnYXRoZXJlci51c2VyLnVzZXJuYW1lfTwvdGQ+XG5cdFx0XHRcdFx0PHRkIGNsYXNzTmFtZT1cImNvbC1tZC0zXCI+e2RpdmlzaW9ufSZuYnNwOzwvdGQ+XG5cdFx0XHRcdFx0PHRkIGNsYXNzTmFtZT1cImNvbC1tZC0yXCI+e2FjdGlvbn0mbmJzcDs8L3RkPlxuXHRcdFx0XHQ8L3RyPlxuXHRcdFx0KTtcblx0XHR9KVxuXHRcdGlmICh0aGlzLnByb3BzLmdhdGhlci5nYXRoZXJlcnMubGVuZ3RoKSB7XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsLWJvZHlcIj5cblx0XHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsIHBhbmVsLWRlZmF1bHRcIj5cblx0XHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwicGFuZWwtaGVhZGluZ1wiPlxuXHRcdFx0XHRcdFx0XHQ8aDUgY2xhc3NOYW1lPVwicGFuZWwtdGl0bGVcIj5Sb3N0ZXI8L2g1PlxuXHRcdFx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdFx0XHQ8dGFibGUgY2xhc3NOYW1lPVwidGFibGUgcm9zdGVyLXRhYmxlXCI+XG5cdFx0XHRcdFx0XHRcdDx0Ym9keT5cblx0XHRcdFx0XHRcdFx0XHR7Z2F0aGVyZXJzfVxuXHRcdFx0XHRcdFx0XHQ8L3Rib2R5PlxuXHRcdFx0XHRcdFx0PC90YWJsZT5cblx0XHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gKDxkaXYgY2xhc3NOYW1lPVwicGFuZWwtYm9keSB0ZXh0LWNlbnRlclwiPjxKb2luR2F0aGVyQnV0dG9uIGJ1dHRvbkNsYXNzPVwiYnRuLWxnXCIgYnV0dG9uTmFtZT1cIlN0YXJ0IGEgR2F0aGVyXCIgLz48L2Rpdj4pO1xuXHRcdH1cblx0fVxufSk7XG5cbnZhciBzb2NrZXQ7XG5cbmZ1bmN0aW9uIGluaXRpYWxpc2VDb21wb25lbnRzICgpIHtcblx0dmFyIHNvY2tldFVybCA9IHdpbmRvdy5sb2NhdGlvbi5wcm90b2NvbCArIFwiLy9cIiArIHdpbmRvdy5sb2NhdGlvbi5ob3N0O1xuXHRzb2NrZXQgPSBpbyhzb2NrZXRVcmwpXG5cdFx0Lm9uKFwiY29ubmVjdFwiLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIkNvbm5lY3RlZFwiKTtcblx0XHR9KVxuXHRcdC5vbihcInJlY29ubmVjdFwiLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIlJlY29ubmVjdGVkXCIpO1xuXHRcdH0pXG5cdFx0Lm9uKFwiZGlzY29ubmVjdFwiLCBmdW5jdGlvbiAoKSB7XG5cdFx0XHRjb25zb2xlLmxvZyhcIkRpc2Nvbm5lY3RlZFwiKVxuXHRcdH0pO1xuXG5cdFJlYWN0LnJlbmRlcig8VXNlck1lbnUgLz4sIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdzaWRlLW1lbnUnKSk7XG5cdFJlYWN0LnJlbmRlcig8Q2hhdHJvb20gLz4sIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdjaGF0cm9vbScpKTtcblx0UmVhY3QucmVuZGVyKDxHYXRoZXIgLz4sIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdnYXRoZXJzJykpO1xuXHRSZWFjdC5yZW5kZXIoPEN1cnJlbnRVc2VyIC8+LCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY3VycmVudHVzZXInKSk7XG59O1xuXG5pbml0aWFsaXNlQ29tcG9uZW50cygpO1xuXG5cblxufSk7XG5cbiJdfQ== \ No newline at end of file diff --git a/public/js/client.js b/public/js/client.js new file mode 100644 index 0000000..9732ed5 --- /dev/null +++ b/public/js/client.js @@ -0,0 +1,4 @@ +$(function () { + initialiseComponents(); + +}); diff --git a/public/js/gather.js b/public/js/gather.js new file mode 100644 index 0000000..88e6e3c --- /dev/null +++ b/public/js/gather.js @@ -0,0 +1,282 @@ +"use strict"; + +var VoteButton = React.createClass({displayName: "VoteButton", + cancelVote: function (e) { + socket.emit("gather:vote", { + leader: { + candidate: null + } + }); + }, + vote: function (e) { + e.preventDefault(); + socket.emit("gather:vote", { + leader: { + candidate: parseInt(e.target.value, 10) + } + }); + }, + render: function () { + if (this.props.currentGatherer === null) { + return false; + } + if (this.props.currentGatherer.leaderVote === this.props.candidate.id) { + return ( + React.createElement("button", { + onClick: this.cancelVote, + className: "btn btn-xs btn-success"}, "Voted" + ) + ); + } else { + return ( + React.createElement("button", { + onClick: this.vote, + className: "btn btn-xs btn-default", + value: this.props.candidate.id}, "Vote" + ) + ); + } + } +}); + +var JoinGatherButton = React.createClass({displayName: "JoinGatherButton", + joinGather: function (e) { + e.preventDefault(); + socket.emit("gather:join", {}); + }, + render: function () { + var message = this.props.buttonName || "Join Gather"; + var buttonClass = "btn btn-primary"; + if (this.props.buttonClass) { + buttonClass += " " + this.props.buttonClass; + } + return (React.createElement("button", { + onClick: this.joinGather, + className: buttonClass}, message)) + } +}); + +var GatherProgress = React.createClass({displayName: "GatherProgress", + stateDescription: function () { + switch(this.props.gather.state) { + case "gathering": + return "Waiting for more gatherers."; + case "election": + return "Currently voting for team leaders."; + case "selection": + return "Waiting for leaders to picking teams."; + case "done": + return "Gather completed."; + default: + return "Initialising gather."; + } + }, + gatheringProgress: function () { + var num = this.props.gather.gatherers.length; + var den = 12; + var remaining = den - num; + var message = (remaining === 1) ? "Waiting for last player" : "Waiting for " + remaining + " more players"; + return { + num: num, + den: den, + message: message + }; + }, + electionProgress: function () { + var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { + if (gatherer.leaderVote) acc++; + return acc; + }, 0); + var den = 12; + return { + num: num, + den: den, + message: den - num + " more votes required" + }; + }, + selectionProgress: function () { + var num = this.props.gather.gatherers.reduce(function (acc, gatherer) { + if (gatherer.team !== "lobby") acc++; + return acc; + }, 0); + var den = 12; + + return { + num: num, + den: den, + message: num + " out of " + den + " players assigned" + }; + }, + render: function () { + var progress; + var gatherState = this.props.gather.state; + if (gatherState === 'gathering' && this.props.gather.gatherers.length) { + progress = this.gatheringProgress(); + } else if (gatherState === 'election') { + progress = this.electionProgress(); + } else if (gatherState === 'selection') { + progress = this.selectionProgress(); + } + if (progress) { + var style = { + width: Math.round((progress.num / progress.den * 100)) + "%" + }; + return ( + React.createElement("div", {className: "panel-body"}, + React.createElement("p", null, React.createElement("strong", null, this.stateDescription()), " ", progress.message), + React.createElement("div", {className: "progress"}, + React.createElement("div", {className: "progress-bar progress-bar-striped active", + "data-role": "progressbar", + "data-aria-valuenow": progress.num, + "data-aria-valuemin": "0", + "data-aria-valuemax": progress.den, + style: style} + ) + ) + ) + ); + } else { + return false; + } + } +}); + +var Gather = React.createClass({displayName: "Gather", + getDefaultProps: function () { + return { + gather: { + gatherers: [] + } + } + }, + joinedGather: function () { + var self = this; + return this.props.gather.gatherers.some(function (gatherer) { + return gatherer.user.id === self.props.currentUser.id; + }); + }, + componentDidMount: function () { + var self = this; + socket.on("gather:refresh", function (data) { + self.setProps({ + gather: data.gather, + currentUser: data.currentUser + }); + }); + }, + leaveGather: function (e) { + e.preventDefault(); + socket.emit("gather:leave", {}); + }, + inviteToGather: function (e) { + e.preventDefault(); + }, + currentGatherer: function () { + var current = null; + var self = this; + this.props.gather.gatherers.forEach(function (gatherer) { + if (gatherer.id === self.props.currentUser.id) current = gatherer; + }); + return current; + }, + render: function () { + var joinButton; + if (this.joinedGather()) { + joinButton = (React.createElement("li", null, React.createElement("button", { + onClick: this.leaveGather, + className: "btn btn-danger"}, "Leave Gather"))); + } else { + joinButton = (React.createElement("li", null, React.createElement(JoinGatherButton, null))); + } + var inviteButton; + if (this.props.gather.state === 'gathering') { + inviteButton = (React.createElement("li", null, React.createElement("button", { + onClick: this.inviteToGather, + className: "btn btn-primary"}, "Invite to Gather"))); + } + return ( + React.createElement("div", {className: "panel panel-default"}, + React.createElement("div", {className: "panel-heading"}, + React.createElement("strong", null, "NS2 Gather "), + React.createElement("span", {className: "badge add-left"}, this.props.gather.gatherers.length) + ), + React.createElement(Gatherers, {gather: this.props.gather, currentGatherer: this.currentGatherer()}), + React.createElement(GatherProgress, {gather: this.props.gather}), + React.createElement("div", {className: "panel-footer text-right"}, + React.createElement("ul", {className: "list-inline"}, + inviteButton, + joinButton + ) + ) + ) + ); + } +}); + +var Gatherers = React.createClass({displayName: "Gatherers", + render: function () { + var self = this; + var gatherers = this.props.gather.gatherers.map(function (gatherer) { + var lifeforms = ( + gatherer.user.ability.lifeforms.map(function (lifeform) { + return (React.createElement("span", {className: "label label-default"}, lifeform)); + }) + ); + + var commBadge; + if (gatherer.user.ability.commander) { + commBadge = (React.createElement("img", {src: "/images/commander.png", + alt: "Commander", + height: "20", + width: "20"})); + } + + var division = (React.createElement("span", {className: "label label-primary"}, gatherer.user.ability.division)); + var action = lifeforms; + if (self.props.gather.state === "election") { + var votes = self.props.gather.gatherers.reduce(function (acc, voter) { + if (voter.leaderVote === gatherer.id) acc++; + return acc; + }, 0) + action = ( + React.createElement("span", null, + React.createElement("small", null, votes + " votes", "  "), + React.createElement(VoteButton, {currentGatherer: self.props.currentGatherer, candidate: gatherer}) + ) + ); + } + + return ( + React.createElement("tr", {key: gatherer.user.id}, + React.createElement("td", {className: "col-md-1"}, commBadge), + React.createElement("td", {className: "col-md-5"}, gatherer.user.username), + React.createElement("td", {className: "col-md-3"}, division, " "), + React.createElement("td", {className: "col-md-2 text-right"}, action, " ") + ) + ); + }) + if (this.props.gather.gatherers.length) { + return ( + React.createElement("div", {className: "panel-body"}, + React.createElement("div", {className: "panel panel-default"}, + React.createElement("div", {className: "panel-heading"}, + React.createElement("h5", {className: "panel-title"}, "Roster") + ), + React.createElement("table", {className: "table roster-table"}, + React.createElement("tbody", null, + gatherers + ) + ) + ) + ) + ); + } else { + return (React.createElement("div", {className: "panel-body text-center"}, React.createElement(JoinGatherButton, {buttonClass: "btn-lg", buttonName: "Start a Gather"}))); + } + } +}); + + + + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtZWQuanMiLCJzb3VyY2VzIjpbbnVsbF0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVksQ0FBQzs7QUFFYixJQUFJLGdDQUFnQywwQkFBQTtDQUNuQyxVQUFVLEVBQUUsVUFBVSxDQUFDLEVBQUU7RUFDeEIsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7R0FDMUIsTUFBTSxFQUFFO0lBQ1AsU0FBUyxFQUFFLElBQUk7SUFDZjtHQUNELENBQUMsQ0FBQztFQUNIO0NBQ0QsSUFBSSxFQUFFLFVBQVUsQ0FBQyxFQUFFO0VBQ2xCLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztFQUNuQixNQUFNLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRTtHQUMxQixNQUFNLEVBQUU7SUFDUCxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQztJQUN2QztHQUNELENBQUMsQ0FBQztFQUNIO0NBQ0QsTUFBTSxFQUFFLFlBQVk7RUFDbkIsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLGVBQWUsS0FBSyxJQUFJLEVBQUU7R0FDeEMsT0FBTyxLQUFLLENBQUM7R0FDYjtFQUNELElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxlQUFlLENBQUMsVUFBVSxLQUFLLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRTtHQUN0RTtJQUNDLG9CQUFBLFFBQU8sRUFBQSxDQUFBO0tBQ04sT0FBQSxFQUFPLENBQUUsSUFBSSxDQUFDLFVBQVUsRUFBQztLQUN6QixTQUFBLEVBQVMsQ0FBQyx3QkFBeUIsQ0FBQSxFQUFBLE9BQUE7QUFBQSxJQUMzQixDQUFBO0tBQ1I7R0FDRixNQUFNO0dBQ047SUFDQyxvQkFBQSxRQUFPLEVBQUEsQ0FBQTtLQUNOLE9BQUEsRUFBTyxDQUFFLElBQUksQ0FBQyxJQUFJLEVBQUM7S0FDbkIsU0FBQSxFQUFTLENBQUMsd0JBQUEsRUFBd0I7S0FDbEMsS0FBQSxFQUFL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LENBQUE7SUFDbkQsQ0FBQTtLQUNKO0dBQ0YsQ0FBQztFQUNGLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRTtHQUN2QztJQUNDLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsWUFBYSxDQUFBLEVBQUE7S0FDM0Isb0JBQUEsS0FBSSxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxxQkFBc0IsQ0FBQSxFQUFBO01BQ3BDLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsZUFBZ0IsQ0FBQSxFQUFBO09BQzlCLG9CQUFBLElBQUcsRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsYUFBYyxDQUFBLEVBQUEsUUFBVyxDQUFBO01BQ2xDLENBQUEsRUFBQTtNQUNOLG9CQUFBLE9BQU0sRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsb0JBQXFCLENBQUEsRUFBQTtPQUNyQyxvQkFBQSxPQUFNLEVBQUEsSUFBQyxFQUFBO1FBQ0wsU0FBVTtPQUNKLENBQUE7TUFDRCxDQUFBO0tBQ0gsQ0FBQTtJQUNELENBQUE7S0FDTDtHQUNGLE1BQU07R0FDTixRQUFRLG9CQUFBLEtBQUksRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsd0JBQXlCLENBQUEsRUFBQSxvQkFBQyxnQkFBZ0IsRUFBQSxDQUFBLENBQUMsV0FBQSxFQUFXLENBQUMsUUFBQSxFQUFRLENBQUMsVUFBQSxFQUFVLENBQUMsZ0JBQWdCLENBQUEsQ0FBRyxDQUFNLENBQUEsRUFBRTtHQUM3SDtFQUNEO0FBQ0YsQ0FBQyxDQUFDLENBQUM7QUFDSDtBQUNBIiwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBWb3RlQnV0dG9uID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRjYW5jZWxWb3RlOiBmdW5jdGlvbiAoZSkge1xuXHRcdHNvY2tldC5lbWl0KFwiZ2F0aGVyOnZvdGVcIiwge1xuXHRcdFx0bGVhZGVyOiB7XG5cdFx0XHRcdGNhbmRpZGF0ZTogbnVsbFxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXHR2b3RlOiBmdW5jdGlvbiAoZSkge1xuXHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRzb2NrZXQuZW1pdChcImdhdGhlcjp2b3RlXCIsIHtcblx0XHRcdGxlYWRlcjoge1xuXHRcdFx0XHRjYW5kaWRhdGU6IHBhcnNlSW50KGUudGFyZ2V0LnZhbHVlLCAxMClcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKHRoaXMucHJvcHMuY3VycmVudEdhdGhlcmVyID09PSBudWxsKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHRcdGlmICh0aGlzLnByb3BzLmN1cnJlbnRHYXRoZXJlci5sZWFkZXJWb3RlID09PSB0aGlzLnByb3BzLmNhbmRpZGF0ZS5pZCkge1xuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0PGJ1dHRvbiBcblx0XHRcdFx0XHRvbkNsaWNrPXt0aGlzLmNhbmNlbFZvdGV9IFxuXHRcdFx0XHRcdGNsYXNzTmFtZT1cImJ0biBidG4teHMgYnRuLXN1Y2Nlc3NcIj5Wb3RlZFxuXHRcdFx0XHQ8L2J1dHRvbj5cblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdDxidXR0b24gXG5cdFx0XHRcdFx0b25DbGljaz17dGhpcy52b3RlfSBcblx0XHRcdFx0XHRjbGFzc05hbWU9XCJidG4gYnRuLXhzIGJ0bi1kZWZhdWx0XCJcblx0XHRcdFx0XHR2YWx1ZT17dGhpcy5wcm9wcy5jYW5kaWRhdGUuaWR9PlZvdGVcblx0XHRcdFx0PC9idXR0b24+XG5cdFx0XHQpO1xuXHRcdH1cblx0fVxufSk7XG5cbnZhciBKb2luR2F0aGVyQnV0dG9uID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRqb2luR2F0aGVyOiBmdW5jdGlvbiAoZSkge1xuXHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHRzb2NrZXQuZW1pdChcImdhdGhlcjpqb2luXCIsIHt9KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIG1lc3NhZ2UgPSB0aGlzLnByb3BzLmJ1dHRvbk5hbWUgfHwgXCJKb2luIEdhdGhlclwiO1xuXHRcdHZhciBidXR0b25DbGFzcyA9IFwiYnRuIGJ0bi1wcmltYXJ5XCI7XG5cdFx0aWYgKHRoaXMucHJvcHMuYnV0dG9uQ2xhc3MpIHtcblx0XHRcdGJ1dHRvbkNsYXNzICs9IFwiIFwiICsgdGhpcy5wcm9wcy5idXR0b25DbGFzcztcblx0XHR9XG5cdFx0cmV0dXJuICg8YnV0dG9uIFxuXHRcdFx0XHRcdFx0XHRvbkNsaWNrPXt0aGlzLmpvaW5HYXRoZXJ9IFxuXHRcdFx0XHRcdFx0XHRjbGFzc05hbWU9e2J1dHRvbkNsYXNzfT57bWVzc2FnZX08L2J1dHRvbj4pXG5cdH1cbn0pO1xuXG52YXIgR2F0aGVyUHJvZ3Jlc3MgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdHN0YXRlRGVzY3JpcHRpb246IGZ1bmN0aW9uICgpIHtcblx0XHRzd2l0Y2godGhpcy5wcm9wcy5nYXRoZXIuc3RhdGUpIHtcblx0XHRcdGNhc2UgXCJnYXRoZXJpbmdcIjpcblx0XHRcdFx0cmV0dXJuIFwiV2FpdGluZyBmb3IgbW9yZSBnYXRoZXJlcnMuXCI7XG5cdFx0XHRjYXNlIFwiZWxlY3Rpb25cIjpcblx0XHRcdFx0cmV0dXJuIFwiQ3VycmVudGx5IHZvdGluZyBmb3IgdGVhbSBsZWFkZXJzLlwiO1xuXHRcdFx0Y2FzZSBcInNlbGVjdGlvblwiOlxuXHRcdFx0XHRyZXR1cm4gXCJXYWl0aW5nIGZvciBsZWFkZXJzIHRvIHBpY2tpbmcgdGVhbXMuXCI7XG5cdFx0XHRjYXNlIFwiZG9uZVwiOlxuXHRcdFx0XHRyZXR1cm4gXCJHYXRoZXIgY29tcGxldGVkLlwiO1xuXHRcdFx0ZGVmYXVsdDpcblx0XHRcdFx0cmV0dXJuIFwiSW5pdGlhbGlzaW5nIGdhdGhlci5cIjtcblx0XHR9XG5cdH0sXG5cdGdhdGhlcmluZ1Byb2dyZXNzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIG51bSA9IHRoaXMucHJvcHMuZ2F0aGVyLmdhdGhlcmVycy5sZW5ndGg7XG5cdFx0dmFyIGRlbiA9IDEyO1xuXHRcdHZhciByZW1haW5pbmcgPSBkZW4gLSBudW07XG5cdFx0dmFyIG1lc3NhZ2UgPSAocmVtYWluaW5nID09PSAxKSA/IFwiV2FpdGluZyBmb3IgbGFzdCBwbGF5ZXJcIiA6IFwiV2FpdGluZyBmb3IgXCIgKyByZW1haW5pbmcgKyBcIiBtb3JlIHBsYXllcnNcIjtcblx0XHRyZXR1cm4ge1xuXHRcdFx0bnVtOiBudW0sXG5cdFx0XHRkZW46IGRlbixcblx0XHRcdG1lc3NhZ2U6IG1lc3NhZ2Vcblx0XHR9O1xuXHR9LFxuXHRlbGVjdGlvblByb2dyZXNzOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIG51bSA9IHRoaXMucHJvcHMuZ2F0aGVyLmdhdGhlcmVycy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgZ2F0aGVyZXIpIHtcblx0XHRcdGlmIChnYXRoZXJlci5sZWFkZXJWb3RlKSBhY2MrKztcblx0XHRcdHJldHVybiBhY2M7XG5cdFx0fSwgMCk7XG5cdFx0dmFyIGRlbiA9IDEyO1xuXHRcdHJldHVybiB7XG5cdFx0XHRudW06IG51bSxcblx0XHRcdGRlbjogZGVuLFxuXHRcdFx0bWVzc2FnZTogZGVuIC0gbnVtICsgXCIgbW9yZSB2b3RlcyByZXF1aXJlZFwiXG5cdFx0fTtcblx0fSxcblx0c2VsZWN0aW9uUHJvZ3Jlc3M6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgbnVtID0gdGhpcy5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCBnYXRoZXJlcikge1xuXHRcdFx0aWYgKGdhdGhlcmVyLnRlYW0gIT09IFwibG9iYnlcIikgYWNjKys7XG5cdFx0XHRyZXR1cm4gYWNjO1xuXHRcdH0sIDApO1xuXHRcdHZhciBkZW4gPSAxMjtcblxuXHRcdHJldHVybiB7XG5cdFx0XHRudW06IG51bSxcblx0XHRcdGRlbjogZGVuLFxuXHRcdFx0bWVzc2FnZTogbnVtICsgXCIgb3V0IG9mIFwiICsgZGVuICsgXCIgcGxheWVycyBhc3NpZ25lZFwiXG5cdFx0fTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHByb2dyZXNzO1xuXHRcdHZhciBnYXRoZXJTdGF0ZSA9IHRoaXMucHJvcHMuZ2F0aGVyLnN0YXRlO1xuXHRcdGlmIChnYXRoZXJTdGF0ZSA9PT0gJ2dhdGhlcmluZycgJiYgdGhpcy5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLmxlbmd0aCkge1xuXHRcdFx0cHJvZ3Jlc3MgPSB0aGlzLmdhdGhlcmluZ1Byb2dyZXNzKCk7XG5cdFx0fSBlbHNlIGlmIChnYXRoZXJTdGF0ZSA9PT0gJ2VsZWN0aW9uJykge1xuXHRcdFx0cHJvZ3Jlc3MgPSB0aGlzLmVsZWN0aW9uUHJvZ3Jlc3MoKTtcblx0XHR9IGVsc2UgaWYgKGdhdGhlclN0YXRlID09PSAnc2VsZWN0aW9uJykge1xuXHRcdFx0cHJvZ3Jlc3MgPSB0aGlzLnNlbGVjdGlvblByb2dyZXNzKCk7XG5cdFx0fVxuXHRcdGlmIChwcm9ncmVzcykge1xuXHRcdFx0dmFyIHN0eWxlID0ge1xuXHRcdFx0XHR3aWR0aDogTWF0aC5yb3VuZCgocHJvZ3Jlc3MubnVtIC8gcHJvZ3Jlc3MuZGVuICogMTAwKSkgKyBcIiVcIlxuXHRcdFx0fTtcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwicGFuZWwtYm9keVwiPlxuXHRcdFx0XHRcdDxwPjxzdHJvbmc+e3RoaXMuc3RhdGVEZXNjcmlwdGlvbigpfTwvc3Ryb25nPiB7cHJvZ3Jlc3MubWVzc2FnZX08L3A+XG5cdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwcm9ncmVzc1wiPlxuXHRcdFx0XHRcdCAgPGRpdiBjbGFzc05hbWU9XCJwcm9ncmVzcy1iYXIgcHJvZ3Jlc3MtYmFyLXN0cmlwZWQgYWN0aXZlXCIgXG5cdFx0XHRcdFx0ICBcdGRhdGEtcm9sZT1cInByb2dyZXNzYmFyXCIgXG5cdFx0XHRcdFx0ICBcdGRhdGEtYXJpYS12YWx1ZW5vdz17cHJvZ3Jlc3MubnVtfSBcblx0XHRcdFx0XHQgIFx0ZGF0YS1hcmlhLXZhbHVlbWluPVwiMFwiIFxuXHRcdFx0XHRcdCAgXHRkYXRhLWFyaWEtdmFsdWVtYXg9e3Byb2dyZXNzLmRlbn0gXG5cdFx0XHRcdFx0ICBcdHN0eWxlPXtzdHlsZX0+XG5cdFx0XHRcdFx0ICA8L2Rpdj5cblx0XHRcdFx0ICA8L2Rpdj5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG59KTtcblxudmFyIEdhdGhlciA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0Z2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGdhdGhlcjoge1xuXHRcdFx0XHRnYXRoZXJlcnM6IFtdXG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXHRqb2luZWRHYXRoZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0cmV0dXJuIHRoaXMucHJvcHMuZ2F0aGVyLmdhdGhlcmVycy5zb21lKGZ1bmN0aW9uIChnYXRoZXJlcikge1xuXHRcdFx0cmV0dXJuIGdhdGhlcmVyLnVzZXIuaWQgPT09IHNlbGYucHJvcHMuY3VycmVudFVzZXIuaWQ7XG5cdFx0fSk7XG5cdH0sXG5cdGNvbXBvbmVudERpZE1vdW50OiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlbGYgPSB0aGlzO1xuXHRcdHNvY2tldC5vbihcImdhdGhlcjpyZWZyZXNoXCIsIGZ1bmN0aW9uIChkYXRhKSB7XG5cdFx0XHRzZWxmLnNldFByb3BzKHtcblx0XHRcdFx0Z2F0aGVyOiBkYXRhLmdhdGhlcixcblx0XHRcdFx0Y3VycmVudFVzZXI6IGRhdGEuY3VycmVudFVzZXJcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9LFxuXHRsZWF2ZUdhdGhlcjogZnVuY3Rpb24gKGUpIHtcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0c29ja2V0LmVtaXQoXCJnYXRoZXI6bGVhdmVcIiwge30pO1xuXHR9LFxuXHRpbnZpdGVUb0dhdGhlcjogZnVuY3Rpb24gKGUpIHtcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdH0sXG5cdGN1cnJlbnRHYXRoZXJlcjogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBjdXJyZW50ID0gbnVsbDtcblx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0dGhpcy5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLmZvckVhY2goZnVuY3Rpb24gKGdhdGhlcmVyKSB7XG5cdFx0XHRpZiAoZ2F0aGVyZXIuaWQgPT09IHNlbGYucHJvcHMuY3VycmVudFVzZXIuaWQpIGN1cnJlbnQgPSBnYXRoZXJlcjtcblx0XHR9KTtcblx0XHRyZXR1cm4gY3VycmVudDtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIGpvaW5CdXR0b247XG5cdFx0aWYgKHRoaXMuam9pbmVkR2F0aGVyKCkpIHtcblx0XHRcdGpvaW5CdXR0b24gPSAoPGxpPjxidXR0b24gXG5cdFx0XHRcdFx0XHRcdG9uQ2xpY2s9e3RoaXMubGVhdmVHYXRoZXJ9IFxuXHRcdFx0XHRcdFx0XHRjbGFzc05hbWU9XCJidG4gYnRuLWRhbmdlclwiPkxlYXZlIEdhdGhlcjwvYnV0dG9uPjwvbGk+KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0am9pbkJ1dHRvbiA9ICg8bGk+PEpvaW5HYXRoZXJCdXR0b24gLz48L2xpPik7XG5cdFx0fVxuXHRcdHZhciBpbnZpdGVCdXR0b247XG5cdFx0aWYgKHRoaXMucHJvcHMuZ2F0aGVyLnN0YXRlID09PSAnZ2F0aGVyaW5nJykge1xuXHRcdFx0aW52aXRlQnV0dG9uID0gKDxsaT48YnV0dG9uXG5cdFx0XHRcdFx0XHRcdG9uQ2xpY2s9e3RoaXMuaW52aXRlVG9HYXRoZXJ9XG5cdFx0XHRcdFx0XHRcdGNsYXNzTmFtZT1cImJ0biBidG4tcHJpbWFyeVwiPkludml0ZSB0byBHYXRoZXI8L2J1dHRvbj48L2xpPik7XG5cdFx0fVxuXHRcdHJldHVybiAoXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsIHBhbmVsLWRlZmF1bHRcIj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1oZWFkaW5nXCI+XG5cdFx0XHRcdFx0PHN0cm9uZz5OUzIgR2F0aGVyIDwvc3Ryb25nPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cImJhZGdlIGFkZC1sZWZ0XCI+e3RoaXMucHJvcHMuZ2F0aGVyLmdhdGhlcmVycy5sZW5ndGh9PC9zcGFuPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PEdhdGhlcmVycyBnYXRoZXI9e3RoaXMucHJvcHMuZ2F0aGVyfSBjdXJyZW50R2F0aGVyZXI9e3RoaXMuY3VycmVudEdhdGhlcmVyKCl9IC8+XG5cdFx0XHRcdDxHYXRoZXJQcm9ncmVzcyBnYXRoZXI9e3RoaXMucHJvcHMuZ2F0aGVyfSAvPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsLWZvb3RlciB0ZXh0LXJpZ2h0XCI+XG5cdFx0XHRcdFx0PHVsIGNsYXNzTmFtZT1cImxpc3QtaW5saW5lXCI+XG5cdFx0XHRcdFx0XHR7aW52aXRlQnV0dG9ufVxuXHRcdFx0XHRcdFx0e2pvaW5CdXR0b259XG5cdFx0XHRcdFx0PC91bD5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHQ8L2Rpdj5cblx0XHQpO1xuXHR9XG59KTtcblxudmFyIEdhdGhlcmVycyA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHNlbGYgPSB0aGlzO1xuXHRcdHZhciBnYXRoZXJlcnMgPSB0aGlzLnByb3BzLmdhdGhlci5nYXRoZXJlcnMubWFwKGZ1bmN0aW9uIChnYXRoZXJlcikge1xuXHRcdFx0dmFyIGxpZmVmb3JtcyA9IChcblx0XHRcdFx0Z2F0aGVyZXIudXNlci5hYmlsaXR5LmxpZmVmb3Jtcy5tYXAoZnVuY3Rpb24gKGxpZmVmb3JtKSB7XG5cdFx0XHRcdFx0cmV0dXJuICg8c3BhbiBjbGFzc05hbWU9XCJsYWJlbCBsYWJlbC1kZWZhdWx0XCI+e2xpZmVmb3JtfTwvc3Bhbj4pO1xuXHRcdFx0XHR9KVxuXHRcdFx0KTtcblxuXHRcdFx0dmFyIGNvbW1CYWRnZTtcblx0XHRcdGlmIChnYXRoZXJlci51c2VyLmFiaWxpdHkuY29tbWFuZGVyKSB7XG5cdFx0XHRcdGNvbW1CYWRnZSA9ICg8aW1nIHNyYz1cIi9pbWFnZXMvY29tbWFuZGVyLnBuZ1wiIFxuXHRcdFx0XHRcdFx0XHRhbHQ9XCJDb21tYW5kZXJcIiBcblx0XHRcdFx0XHRcdFx0aGVpZ2h0PVwiMjBcIlxuXHRcdFx0XHRcdFx0XHR3aWR0aD1cIjIwXCIgLz4pO1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgZGl2aXNpb24gPSAoPHNwYW4gY2xhc3NOYW1lPVwibGFiZWwgbGFiZWwtcHJpbWFyeVwiPntnYXRoZXJlci51c2VyLmFiaWxpdHkuZGl2aXNpb259PC9zcGFuPik7XG5cdFx0XHR2YXIgYWN0aW9uID0gbGlmZWZvcm1zO1xuXHRcdFx0aWYgKHNlbGYucHJvcHMuZ2F0aGVyLnN0YXRlID09PSBcImVsZWN0aW9uXCIpIHtcblx0XHRcdFx0dmFyIHZvdGVzID0gc2VsZi5wcm9wcy5nYXRoZXIuZ2F0aGVyZXJzLnJlZHVjZShmdW5jdGlvbiAoYWNjLCB2b3Rlcikge1xuXHRcdFx0XHRcdGlmICh2b3Rlci5sZWFkZXJWb3RlID09PSBnYXRoZXJlci5pZCkgYWNjKys7XG5cdFx0XHRcdFx0cmV0dXJuIGFjYztcblx0XHRcdFx0fSwgMClcblx0XHRcdFx0YWN0aW9uID0gKFxuXHRcdFx0XHRcdDxzcGFuPlxuXHRcdFx0XHRcdFx0PHNtYWxsPnt2b3RlcyArIFwiIHZvdGVzXCJ9ICZuYnNwOzwvc21hbGw+XG5cdFx0XHRcdFx0XHQ8Vm90ZUJ1dHRvbiBjdXJyZW50R2F0aGVyZXI9e3NlbGYucHJvcHMuY3VycmVudEdhdGhlcmVyfSBjYW5kaWRhdGU9e2dhdGhlcmVyfSAvPlxuXHRcdFx0XHRcdDwvc3Bhbj5cblx0XHRcdFx0KTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0PHRyIGtleT17Z2F0aGVyZXIudXNlci5pZH0+XG5cdFx0XHRcdFx0PHRkIGNsYXNzTmFtZT1cImNvbC1tZC0xXCI+e2NvbW1CYWRnZX08L3RkPlxuXHRcdFx0XHRcdDx0ZCBjbGFzc05hbWU9XCJjb2wtbWQtNVwiPntnYXRoZXJlci51c2VyLnVzZXJuYW1lfTwvdGQ+XG5cdFx0XHRcdFx0PHRkIGNsYXNzTmFtZT1cImNvbC1tZC0zXCI+e2RpdmlzaW9ufSZuYnNwOzwvdGQ+XG5cdFx0XHRcdFx0PHRkIGNsYXNzTmFtZT1cImNvbC1tZC0yIHRleHQtcmlnaHRcIj57YWN0aW9ufSZuYnNwOzwvdGQ+XG5cdFx0XHRcdDwvdHI+XG5cdFx0XHQpO1xuXHRcdH0pXG5cdFx0aWYgKHRoaXMucHJvcHMuZ2F0aGVyLmdhdGhlcmVycy5sZW5ndGgpIHtcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwicGFuZWwtYm9keVwiPlxuXHRcdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwicGFuZWwgcGFuZWwtZGVmYXVsdFwiPlxuXHRcdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1oZWFkaW5nXCI+XG5cdFx0XHRcdFx0XHRcdDxoNSBjbGFzc05hbWU9XCJwYW5lbC10aXRsZVwiPlJvc3RlcjwvaDU+XG5cdFx0XHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0XHRcdDx0YWJsZSBjbGFzc05hbWU9XCJ0YWJsZSByb3N0ZXItdGFibGVcIj5cblx0XHRcdFx0XHRcdFx0PHRib2R5PlxuXHRcdFx0XHRcdFx0XHRcdHtnYXRoZXJlcnN9XG5cdFx0XHRcdFx0XHRcdDwvdGJvZHk+XG5cdFx0XHRcdFx0XHQ8L3RhYmxlPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiAoPGRpdiBjbGFzc05hbWU9XCJwYW5lbC1ib2R5IHRleHQtY2VudGVyXCI+PEpvaW5HYXRoZXJCdXR0b24gYnV0dG9uQ2xhc3M9XCJidG4tbGdcIiBidXR0b25OYW1lPVwiU3RhcnQgYSBHYXRoZXJcIiAvPjwvZGl2Pik7XG5cdFx0fVxuXHR9XG59KTtcblxuXG5cbiJdfQ== \ No newline at end of file diff --git a/public/js/init.js b/public/js/init.js new file mode 100644 index 0000000..b4f148b --- /dev/null +++ b/public/js/init.js @@ -0,0 +1,23 @@ +"use strict"; + +var socket; + +function initialiseComponents () { + var socketUrl = window.location.protocol + "//" + window.location.host; + socket = io(socketUrl) + .on("connect", function () { + console.log("Connected"); + }) + .on("reconnect", function () { + console.log("Reconnected"); + }) + .on("disconnect", function () { + console.log("Disconnected") + }); + + React.render(React.createElement(UserMenu, null), document.getElementById('side-menu')); + React.render(React.createElement(Chatroom, null), document.getElementById('chatroom')); + React.render(React.createElement(Gather, null), document.getElementById('gathers')); + React.render(React.createElement(CurrentUser, null), document.getElementById('currentuser')); +}; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtZWQuanMiLCJzb3VyY2VzIjpbbnVsbF0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVksQ0FBQzs7QUFFYixJQUFJLE1BQU0sQ0FBQzs7QUFFWCxTQUFTLG9CQUFvQixJQUFJO0NBQ2hDLElBQUksU0FBUyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsUUFBUSxHQUFHLElBQUksR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQztDQUN2RSxNQUFNLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQztHQUNwQixFQUFFLENBQUMsU0FBUyxFQUFFLFlBQVk7R0FDMUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQztHQUN6QixDQUFDO0dBQ0QsRUFBRSxDQUFDLFdBQVcsRUFBRSxZQUFZO0dBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUM7R0FDM0IsQ0FBQztHQUNELEVBQUUsQ0FBQyxZQUFZLEVBQUUsWUFBWTtHQUM3QixPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQztBQUM5QixHQUFHLENBQUMsQ0FBQzs7Q0FFSixLQUFLLENBQUMsTUFBTSxDQUFDLG9CQUFDLFFBQVEsRUFBQSxJQUFBLENBQUcsQ0FBQSxFQUFFLFFBQVEsQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQztDQUNqRSxLQUFLLENBQUMsTUFBTSxDQUFDLG9CQUFDLFFBQVEsRUFBQSxJQUFBLENBQUcsQ0FBQSxFQUFFLFFBQVEsQ0FBQyxjQUFjLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztDQUNoRSxLQUFLLENBQUMsTUFBTSxDQUFDLG9CQUFDLE1BQU0sRUFBQSxJQUFBLENBQUcsQ0FBQSxFQUFFLFFBQVEsQ0FBQyxjQUFjLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztDQUM3RCxLQUFLLENBQUMsTUFBTSxDQUFDLG9CQUFDLFdBQVcsRUFBQSxJQUFBLENBQUcsQ0FBQSxFQUFFLFFBQVEsQ0FBQyxjQUFjLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztDQUN0RSIsInNvdXJjZXNDb250ZW50IjpbIlwidXNlIHN0cmljdFwiO1xuXG52YXIgc29ja2V0O1xuXG5mdW5jdGlvbiBpbml0aWFsaXNlQ29tcG9uZW50cyAoKSB7XG5cdHZhciBzb2NrZXRVcmwgPSB3aW5kb3cubG9jYXRpb24ucHJvdG9jb2wgKyBcIi8vXCIgKyB3aW5kb3cubG9jYXRpb24uaG9zdDtcblx0c29ja2V0ID0gaW8oc29ja2V0VXJsKVxuXHRcdC5vbihcImNvbm5lY3RcIiwgZnVuY3Rpb24gKCkge1xuXHRcdFx0Y29uc29sZS5sb2coXCJDb25uZWN0ZWRcIik7XG5cdFx0fSlcblx0XHQub24oXCJyZWNvbm5lY3RcIiwgZnVuY3Rpb24gKCkge1xuXHRcdFx0Y29uc29sZS5sb2coXCJSZWNvbm5lY3RlZFwiKTtcblx0XHR9KVxuXHRcdC5vbihcImRpc2Nvbm5lY3RcIiwgZnVuY3Rpb24gKCkge1xuXHRcdFx0Y29uc29sZS5sb2coXCJEaXNjb25uZWN0ZWRcIilcblx0XHR9KTtcblxuXHRSZWFjdC5yZW5kZXIoPFVzZXJNZW51IC8+LCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnc2lkZS1tZW51JykpO1xuXHRSZWFjdC5yZW5kZXIoPENoYXRyb29tIC8+LCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnY2hhdHJvb20nKSk7XG5cdFJlYWN0LnJlbmRlcig8R2F0aGVyIC8+LCBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZ2F0aGVycycpKTtcblx0UmVhY3QucmVuZGVyKDxDdXJyZW50VXNlciAvPiwgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2N1cnJlbnR1c2VyJykpO1xufTsiXX0= \ No newline at end of file diff --git a/public/js/message.js b/public/js/message.js new file mode 100644 index 0000000..6fce96a --- /dev/null +++ b/public/js/message.js @@ -0,0 +1,148 @@ +"use strict"; + +var Chatroom = React.createClass({displayName: "Chatroom", + getDefaultProps: function () { + return { + history: [] + }; + }, + componentDidMount: function () { + var self = this; + var TIMER_INTERVAL = 60000; // Every minute + + socket.on("message:new", function (data) { + var history = self.props.history; + history.push(data); + self.setProps({ + history: history + }); + self.scrollToBottom(); + }); + + // Message History Retrieved + socket.on("message:refresh", function (data) { + self.setProps({ + history: data.chatHistory + }); + self.scrollToBottom(); + }); + + socket.emit("message:refresh", {}); + + self.timer = setInterval(function () { + if (self.refs.messages) self.refs.messages.refreshTime(); + }, TIMER_INTERVAL); + }, + + componentDidUnmount: function () { + clearInterval(this.timer); + }, + sendMessage: function (message) { + socket.emit("newMessage", {message: message}); + }, + scrollToBottom: function () { + var node = React.findDOMNode(this.refs.messageContainer); + node.scrollTop = node.scrollHeight; + }, + render: function () { + var messages = this.props.history.map(function (message) { + return ( + React.createElement(ChatMessage, { + avatar: message.author.avatar, + username: message.author.username, + content: message.content, + ref: "messages", + createdAt: message.createdAt}) + ); + }); + return ( + React.createElement("div", {className: "panel panel-default"}, + React.createElement("div", {className: "panel-heading"}, "Gather Chat"), + React.createElement("div", {className: "panel-body"}, + React.createElement("ul", {className: "chat", id: "chatmessages", ref: "messageContainer"}, + messages + ) + ), + React.createElement("div", {className: "panel-footer"}, + React.createElement(MessageBar, null) + ) + ) + ); + } +}); + +var ChatMessage = React.createClass({displayName: "ChatMessage", + getInitialState: function () { + return { + timeAgo: $.timeago(this.props.createdAt) + } + }, + refreshTime: function () { + var self = this; + self.setState({ + timeAgo: $.timeago(self.props.createdAt) + }); + }, + render: function () { + return ( + React.createElement("li", {className: "left clearfix"}, + React.createElement("span", {className: "chat-img pull-left"}, + React.createElement("img", { + src: this.props.avatar, + alt: "User Avatar", + height: "40", + width: "40", + className: "img-circle"}) + ), + React.createElement("div", {className: "chat-body clearfix"}, + React.createElement("div", {className: "header"}, + React.createElement("strong", {className: "primary-font"}, this.props.username), + React.createElement("small", {className: "pull-right text-muted"}, + React.createElement("i", {className: "fa fa-clock-o fa-fw"}), " ", this.state.timeAgo + ) + ), + React.createElement("p", null, this.props.content) + ) + ) + ); + } +}); + +var MessageBar = React.createClass({displayName: "MessageBar", + sendMessage: function (content) { + socket.emit("message:new", { + content: content + }); + }, + handleSubmit: function (e) { + e.preventDefault(); + var content = React.findDOMNode(this.refs.content).value.trim(); + if (!content) return; + React.findDOMNode(this.refs.content).value = ''; + this.sendMessage(content); + return; + }, + render: function () { + return ( + React.createElement("form", {onSubmit: this.handleSubmit}, + React.createElement("div", {className: "input-group"}, + React.createElement("input", { + id: "btn-input", + type: "text", + className: "form-control", + ref: "content", + placeholder: "Be polite please..."}), + React.createElement("span", {className: "input-group-btn"}, + React.createElement("input", { + type: "submit", + className: "btn btn-primary", + id: "btn-chat", + value: "Send"}) + ) + ) + ) + ); + } +}); + +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtZWQuanMiLCJzb3VyY2VzIjpbbnVsbF0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVksQ0FBQzs7QUFFYixJQUFJLDhCQUE4Qix3QkFBQTtDQUNqQyxlQUFlLEVBQUUsWUFBWTtFQUM1QixPQUFPO0dBQ04sT0FBTyxFQUFFLEVBQUU7R0FDWCxDQUFDO0VBQ0Y7Q0FDRCxpQkFBaUIsRUFBRSxZQUFZO0VBQzlCLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQztBQUNsQixFQUFFLElBQUksY0FBYyxHQUFHLEtBQUssQ0FBQzs7RUFFM0IsTUFBTSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsVUFBVSxJQUFJLEVBQUU7R0FDeEMsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUM7R0FDakMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztHQUNuQixJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ2IsT0FBTyxFQUFFLE9BQU87SUFDaEIsQ0FBQyxDQUFDO0dBQ0gsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBQ3pCLEdBQUcsQ0FBQyxDQUFDO0FBQ0w7O0VBRUUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxVQUFVLElBQUksRUFBRTtHQUM1QyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ2IsT0FBTyxFQUFFLElBQUksQ0FBQyxXQUFXO0lBQ3pCLENBQUMsQ0FBQztHQUNILElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztBQUN6QixHQUFHLENBQUMsQ0FBQzs7QUFFTCxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxDQUFDLENBQUM7O0VBRW5DLElBQUksQ0FBQyxLQUFLLEdBQUcsV0FBVyxDQUFDLFlBQVk7R0FDcEMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztHQUN6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b29tID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0aGlzdG9yeTogW11cblx0XHR9O1xuXHR9LFxuXHRjb21wb25lbnREaWRNb3VudDogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHR2YXIgVElNRVJfSU5URVJWQUwgPSA2MDAwMDsgLy8gRXZlcnkgbWludXRlXG5cblx0XHRzb2NrZXQub24oXCJtZXNzYWdlOm5ld1wiLCBmdW5jdGlvbiAoZGF0YSkge1xuXHRcdFx0dmFyIGhpc3RvcnkgPSBzZWxmLnByb3BzLmhpc3Rvcnk7XG5cdFx0XHRoaXN0b3J5LnB1c2goZGF0YSk7XG5cdFx0XHRzZWxmLnNldFByb3BzKHtcblx0XHRcdFx0aGlzdG9yeTogaGlzdG9yeVxuXHRcdFx0fSk7XG5cdFx0XHRzZWxmLnNjcm9sbFRvQm90dG9tKCk7XG5cdFx0fSk7XG5cblx0XHQvLyBNZXNzYWdlIEhpc3RvcnkgUmV0cmlldmVkXG5cdFx0c29ja2V0Lm9uKFwibWVzc2FnZTpyZWZyZXNoXCIsIGZ1bmN0aW9uIChkYXRhKSB7XG5cdFx0XHRzZWxmLnNldFByb3BzKHtcblx0XHRcdFx0aGlzdG9yeTogZGF0YS5jaGF0SGlzdG9yeVxuXHRcdFx0fSk7XG5cdFx0XHRzZWxmLnNjcm9sbFRvQm90dG9tKCk7XG5cdFx0fSk7XG5cblx0XHRzb2NrZXQuZW1pdChcIm1lc3NhZ2U6cmVmcmVzaFwiLCB7fSk7XG5cblx0XHRzZWxmLnRpbWVyID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkge1xuXHRcdFx0aWYgKHNlbGYucmVmcy5tZXNzYWdlcykgc2VsZi5yZWZzLm1lc3NhZ2VzLnJlZnJlc2hUaW1lKCk7XG5cdFx0fSwgVElNRVJfSU5URVJWQUwpO1xuXHR9LFxuXG5cdGNvbXBvbmVudERpZFVubW91bnQ6IGZ1bmN0aW9uICgpIHtcblx0XHRjbGVhckludGVydmFsKHRoaXMudGltZXIpO1xuXHR9LFxuXHRzZW5kTWVzc2FnZTogZnVuY3Rpb24gKG1lc3NhZ2UpIHtcblx0XHRzb2NrZXQuZW1pdChcIm5ld01lc3NhZ2VcIiwge21lc3NhZ2U6IG1lc3NhZ2V9KTtcblx0fSxcblx0c2Nyb2xsVG9Cb3R0b206IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgbm9kZSA9IFJlYWN0LmZpbmRET01Ob2RlKHRoaXMucmVmcy5tZXNzYWdlQ29udGFpbmVyKTtcblx0ICBub2RlLnNjcm9sbFRvcCA9IG5vZGUuc2Nyb2xsSGVpZ2h0O1xuXHR9LFxuXHRyZW5kZXI6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgbWVzc2FnZXMgPSB0aGlzLnByb3BzLmhpc3RvcnkubWFwKGZ1bmN0aW9uIChtZXNzYWdlKSB7XG5cdFx0XHRyZXR1cm4gKFxuXHRcdFx0XHQ8Q2hhdE1lc3NhZ2UgXG5cdFx0XHRcdFx0YXZhdGFyPXttZXNzYWdlLmF1dGhvci5hdmF0YXJ9IFxuXHRcdFx0XHRcdHVzZXJuYW1lPXttZXNzYWdlLmF1dGhvci51c2VybmFtZX1cblx0XHRcdFx0XHRjb250ZW50PXttZXNzYWdlLmNvbnRlbnR9XG5cdFx0XHRcdFx0cmVmPVwibWVzc2FnZXNcIlxuXHRcdFx0XHRcdGNyZWF0ZWRBdD17bWVzc2FnZS5jcmVhdGVkQXR9IC8+XG5cdFx0XHQpO1xuXHRcdH0pO1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cInBhbmVsIHBhbmVsLWRlZmF1bHRcIj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1oZWFkaW5nXCI+R2F0aGVyIENoYXQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1ib2R5XCI+XG5cdFx0XHRcdFx0PHVsIGNsYXNzTmFtZT1cImNoYXRcIiBpZD1cImNoYXRtZXNzYWdlc1wiIHJlZj1cIm1lc3NhZ2VDb250YWluZXJcIj5cblx0XHRcdFx0XHRcdHttZXNzYWdlc31cblx0XHRcdFx0XHQ8L3VsPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJwYW5lbC1mb290ZXJcIj5cblx0XHRcdFx0XHQ8TWVzc2FnZUJhciAvPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvZGl2PlxuXHRcdCk7XG5cdH1cbn0pO1xuXG52YXIgQ2hhdE1lc3NhZ2UgPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdGdldEluaXRpYWxTdGF0ZTogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiB7XG5cdFx0XHR0aW1lQWdvOiAkLnRpbWVhZ28odGhpcy5wcm9wcy5jcmVhdGVkQXQpXG5cdFx0fVxuXHR9LFxuXHRyZWZyZXNoVGltZTogZnVuY3Rpb24gKCkge1xuXHRcdHZhciBzZWxmID0gdGhpcztcblx0XHRzZWxmLnNldFN0YXRlKHtcblx0XHRcdHRpbWVBZ286ICQudGltZWFnbyhzZWxmLnByb3BzLmNyZWF0ZWRBdClcblx0XHR9KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdDxsaSBjbGFzc05hbWU9XCJsZWZ0IGNsZWFyZml4XCI+XG5cdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cImNoYXQtaW1nIHB1bGwtbGVmdFwiPlxuXHRcdFx0XHRcdFx0PGltZyBcblx0XHRcdFx0XHRcdFx0c3JjPXt0aGlzLnByb3BzLmF2YXRhcn0gXG5cdFx0XHRcdFx0XHRcdGFsdD1cIlVzZXIgQXZhdGFyXCIgXG5cdFx0XHRcdFx0XHRcdGhlaWdodD1cIjQwXCJcblx0XHRcdFx0XHRcdFx0d2lkdGg9XCI0MFwiXG5cdFx0XHRcdFx0XHRcdGNsYXNzTmFtZT1cImltZy1jaXJjbGVcIiAvPlxuXHRcdFx0XHQ8L3NwYW4+XG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwiY2hhdC1ib2R5IGNsZWFyZml4XCI+XG5cdFx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJoZWFkZXJcIj5cblx0XHRcdFx0XHRcdDxzdHJvbmcgY2xhc3NOYW1lPVwicHJpbWFyeS1mb250XCI+e3RoaXMucHJvcHMudXNlcm5hbWV9PC9zdHJvbmc+XG5cdFx0XHRcdFx0XHQ8c21hbGwgY2xhc3NOYW1lPVwicHVsbC1yaWdodCB0ZXh0LW11dGVkXCI+XG5cdFx0XHRcdFx0XHRcdDxpIGNsYXNzTmFtZT1cImZhIGZhLWNsb2NrLW8gZmEtZndcIj48L2k+IHt0aGlzLnN0YXRlLnRpbWVBZ299XG5cdFx0XHRcdFx0XHQ8L3NtYWxsPlxuXHRcdFx0XHRcdDwvZGl2PlxuXHRcdFx0XHRcdDxwPnt0aGlzLnByb3BzLmNvbnRlbnR9PC9wPlxuXHRcdFx0XHQ8L2Rpdj5cblx0XHRcdDwvbGk+XG5cdFx0KTtcblx0fVxufSk7XG5cbnZhciBNZXNzYWdlQmFyID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXHRzZW5kTWVzc2FnZTogZnVuY3Rpb24gKGNvbnRlbnQpIHtcblx0XHRzb2NrZXQuZW1pdChcIm1lc3NhZ2U6bmV3XCIsIHtcblx0XHRcdGNvbnRlbnQ6IGNvbnRlbnRcblx0XHR9KTtcblx0fSxcblx0aGFuZGxlU3VibWl0OiBmdW5jdGlvbiAoZSkge1xuXHRcdGUucHJldmVudERlZmF1bHQoKTtcblx0XHR2YXIgY29udGVudCA9IFJlYWN0LmZpbmRET01Ob2RlKHRoaXMucmVmcy5jb250ZW50KS52YWx1ZS50cmltKCk7XG5cdFx0aWYgKCFjb250ZW50KSByZXR1cm47XG5cdFx0UmVhY3QuZmluZERPTU5vZGUodGhpcy5yZWZzLmNvbnRlbnQpLnZhbHVlID0gJyc7XG5cdFx0dGhpcy5zZW5kTWVzc2FnZShjb250ZW50KTtcblx0XHRyZXR1cm47XG5cdH0sXG5cdHJlbmRlcjogZnVuY3Rpb24gKCkge1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8Zm9ybSBvblN1Ym1pdD17dGhpcy5oYW5kbGVTdWJtaXR9ID5cblx0XHRcdFx0PGRpdiBjbGFzc05hbWU9XCJpbnB1dC1ncm91cFwiPlxuXHRcdFx0XHRcdDxpbnB1dCBcblx0XHRcdFx0XHRcdGlkPVwiYnRuLWlucHV0XCIgXG5cdFx0XHRcdFx0XHR0eXBlPVwidGV4dFwiIFxuXHRcdFx0XHRcdFx0Y2xhc3NOYW1lPVwiZm9ybS1jb250cm9sXCIgXG5cdFx0XHRcdFx0XHRyZWY9XCJjb250ZW50XCJcblx0XHRcdFx0XHRcdHBsYWNlaG9sZGVyPVwiQmUgcG9saXRlIHBsZWFzZS4uLlwiIC8+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3NOYW1lPVwiaW5wdXQtZ3JvdXAtYnRuXCI+XG5cdFx0XHRcdFx0XHQ8aW5wdXQgXG5cdFx0XHRcdFx0XHRcdHR5cGU9XCJzdWJtaXRcIiBcblx0XHRcdFx0XHRcdFx0Y2xhc3NOYW1lPVwiYnRuIGJ0bi1wcmltYXJ5XCIgXG5cdFx0XHRcdFx0XHRcdGlkPVwiYnRuLWNoYXRcIiBcblx0XHRcdFx0XHRcdFx0dmFsdWU9XCJTZW5kXCIgLz5cblx0XHRcdFx0XHQ8L3NwYW4+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9mb3JtPlxuXHRcdCk7XG5cdH1cbn0pO1xuIl19 \ No newline at end of file diff --git a/public/js/user.js b/public/js/user.js new file mode 100644 index 0000000..4bea783 --- /dev/null +++ b/public/js/user.js @@ -0,0 +1,114 @@ +"use strict"; + +var UserCounter = React.createClass({displayName: "UserCounter", + render: function () { + return ( + React.createElement("li", null, + React.createElement("a", {href: "#"}, + React.createElement("i", {className: "fa fa-users fa-fw"}), " Online", + React.createElement("span", {className: "badge add-left"}, " ", this.props.count, " ") + ) + ) + ); + } +}); + +var UserLogin = React.createClass({displayName: "UserLogin", + authorizeId: function (id) { + id = parseInt(id, 10); + socket.emit("users:authorize", { + id: id + }); + }, + handleSubmit: function (e) { + e.preventDefault(); + var id = React.findDOMNode(this.refs.authorize_id).value.trim(); + if (!id) return; + React.findDOMNode(this.refs.authorize_id).value = ''; + this.authorizeId(id); + return; + }, + render: function () { + return ( + React.createElement("form", {onSubmit: this.handleSubmit}, + React.createElement("div", {className: "input-group signin"}, + React.createElement("input", { + id: "btn-input", + type: "text", + className: "form-control", + ref: "authorize_id", + placeholder: "Choose an ID..."}), + React.createElement("span", {className: "input-group-btn"}, + React.createElement("input", { + type: "submit", + className: "btn btn-primary", + id: "btn-chat", + value: "Login"}) + ) + ), + React.createElement("div", {className: "signin"}, + React.createElement("p", {className: "text-center"}, React.createElement("small", null, "Just a temporary measure until genuine authentication is implemented")) + ) + ) + ); + } +}) + +var UserMenu = React.createClass({displayName: "UserMenu", + getDefaultProps: function () { + return { + count: 0, + users: [] + }; + }, + componentDidMount: function () { + socket.on('users:update', this.updateUsers); + }, + updateUsers: function (data) { + this.setProps({ + count: data.count, + users: data.users + }); + }, + render: function () { + var users = this.props.users.map(function (user) { + return ( + React.createElement("li", {key: user.id}, React.createElement("a", {href: "#"}, user.username)) + ); + }); + return ( + React.createElement("ul", {className: "nav", id: "side-menu"}, + React.createElement(UserCounter, React.__spread({}, this.props)), + users, + React.createElement("li", null, React.createElement("br", null), React.createElement(UserLogin, null), React.createElement("br", null)) + ) + ); + } +}); + +var CurrentUser = React.createClass({displayName: "CurrentUser", + componentDidMount: function () { + var self = this; + socket.on("users:update", function (data) { + self.setProps({ + user: data.currentUser + }); + }); + socket.emit("users:refresh", {}); + }, + render: function () { + if (this.props.user) { + return ( + React.createElement("a", {href: "#"}, this.props.user.username, "  ", React.createElement("img", {src: this.props.user.avatar, + alt: "User Avatar", + height: "20", + width: "20"})) + ); + } else { + return false; + } + } +}); + +alert("foo") +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNmb3JtZWQuanMiLCJzb3VyY2VzIjpbbnVsbF0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVksQ0FBQzs7QUFFYixJQUFJLGlDQUFpQywyQkFBQTtDQUNwQyxNQUFNLEVBQUUsWUFBWTtFQUNuQjtHQUNDLG9CQUFBLElBQUcsRUFBQSxJQUFDLEVBQUE7SUFDSCxvQkFBQSxHQUFFLEVBQUEsQ0FBQSxDQUFDLElBQUEsRUFBSSxDQUFDLEdBQUksQ0FBQSxFQUFBO0tBQ1gsb0JBQUEsR0FBRSxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxtQkFBb0IsQ0FBSSxDQUFBLEVBQUEsU0FBQSxFQUFBLENBQUE7QUFBQSxLQUNyQyxvQkFBQSxNQUFLLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLGdCQUFpQixDQUFBLEVBQUEsR0FBQSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFDLEdBQVEsQ0FBQTtJQUN6RCxDQUFBO0dBQ0EsQ0FBQTtJQUNKO0VBQ0Y7QUFDRixDQUFDLENBQUMsQ0FBQzs7QUFFSCxJQUFJLCtCQUErQix5QkFBQTtDQUNsQyxXQUFXLEVBQUUsVUFBVSxFQUFFLEVBQUU7RUFDMUIsRUFBRSxHQUFHLFFBQVEsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7RUFDdEIsTUFBTSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtHQUM5QixFQUFFLEVBQUUsRUFBRTtHQUNOLENBQUMsQ0FBQztFQUNIO0NBQ0QsWUFBWSxFQUFFLFVBQVUsQ0FBQyxFQUFFO0VBQzFCLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztFQUNuQixJQUFJLEVBQUUsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0VBQ2hFLElBQUksQ0FBQyxFQUFFLEVBQUUsT0FBTztFQUNoQixLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztFQUNyRCxJQUFJLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0VBQ3JCLE9BQU87RUFDUDtDQUNELE1BQU0sRUFBRSxZQUFZO0VBQ25CO0dBQ0Msb0JBQUEsTUFBSyxFQUFBLENBQUEsQ0FBQyxRQUFBLEVBQVEsQ0FBRSxJQUFJLENBQUMsWUFBYSxDQUFFLENBQUEsRUFBQTtJQUNuQyxvQkFBQSxLQUFJLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLG9CQUFxQixDQUFBLEVBQUE7S0FDbkMsb0JBQUEsT0FBTSxFQUFBLENBQUE7TUFDTCxFQUFBLEVBQUUsQ0FBQyxXQUFBLEVBQVc7TUFDZCxJQUFBLEVBQUksQ0FBQyxNQUFBLEVBQU07TUFDWCxTQUFBLEVBQVMsQ0FBQyxjQUFBLEVBQWM7TUFDeEIsR0FBQSxFQUFHLENBQUMsY0FBQSxFQUFjO01BQ2xCLFdBQUEsRUFBVyxDQUFDLGlCQUFpQixDQUFBLENBQUcsQ0FBQSxFQUFBO0tBQ2pDLG9CQUFBLE1BQUssRUFBQSxDQUFBLENBQUMsU0FBQSxFQUFTLENBQUMsaUJBQWtCLENBQUEsRUFBQTtNQUNqQyxvQkFBQSxPQUFNLEVBQUEsQ0FBQTtPQUNMLElBQUEsRUFBSSxDQUFDLFFBQUEsRUFBUTtPQUNiLFNBQUEsRUFBUyxDQUFDLGlCQUFBLEVBQWlCO09BQzNCLEVBQUEsRUFBRSxDQUFDLFVBQUEsRUFBVTtPQUNiLEtBQUEsRUFBSyxDQUFDLE9BQU8sQ0FBQSxDQUFHLENBQUE7S0FDWCxDQUFBO0lBQ0YsQ0FBQSxFQUFBO0lBQ04sb0JBQUEsS0FBSSxFQUFBLENBQUEsQ0FBQyxTQUFBLEVBQVMsQ0FBQyxRQUFTLENBQUEsRUFBQTtJQUN4QixvQkFBQSxHQUFFLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLGFBQWMsQ0FBQSxFQUFBLG9CQUFBLE9BQU0sRUFBQSxJQUFDLEVBQUEsc0VBQTRFLENBQUksQ0FBQTtJQUM1RyxDQUFBO0dBQ0EsQ0FBQTtJQUNOO0VBQ0Y7QUFDRixDQUFDLENBQUM7O0FBRUYsSUFBSSw4QkFBOEIsd0JBQUE7Q0FDakMsZUFBZSxFQUFFLFlBQVk7RUFDNUIsT0FBTztHQUNOLEtBQUssRUFBRSxDQUFDO0dBQ1IsS0FBSyxFQUFFLEVBQUU7R0FDVCxDQUFDO0VBQ0Y7Q0FDRCxpQkFBaUIsRUFBRSxZQUFZO0VBQzlCLE1BQU0sQ0FBQyxFQUFFLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztFQUM1QztDQUNELFdBQVcsRUFBRSxVQUFVLElBQUksRUFBRTtFQUM1QixJQUFJLENBQUMsUUFBUSxDQUFDO0dBQ2IsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLO0dBQ2pCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztHQUNqQixDQUFDLENBQUM7RUFDSDtDQUNELE1BQU0sRUFBRSxZQUFZO0VBQ25CLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksRUFBRTtHQUNoRDtJQUNDLG9CQUFBLElBQUcsRUFBQSxDQUFBLENBQUMsR0FBQSxFQUFHLENBQUUsSUFBSSxDQUFDLEVBQUksQ0FBQSxFQUFBLG9CQUFBLEdBQUUsRUFBQSxDQUFBLENBQUMsSUFBQSxFQUFJLENBQUMsR0FBSSxDQUFBLEVBQUMsSUFBSSxDQUFDLFFBQWEsQ0FBSyxDQUFBO0tBQ3JEO0dBQ0YsQ0FBQyxDQUFDO0VBQ0g7R0FDQyxvQkFBQSxJQUFHLEVBQUEsQ0FBQSxDQUFDLFNBQUEsRUFBUyxDQUFDLEtBQUEsRUFBSyxDQUFDLEVBQUEsRUFBRSxDQUFDLFdBQVksQ0FBQSxFQUFBO0lBQ2xDLG9CQUFDLFdBQVcsRUFBQSxnQkFBQSxHQUFBLENBQUUsR0FBRyxJQUFJLENBQUMsS0FBTSxDQUFBLENBQUcsQ0FBQSxFQUFBO0lBQzlCLEtBQUssRUFBQztJQUNQLG9CQUFBLElBQUcsRUFBQSxJQUFDLEVBQUEsb0JBQUEsSUFBRyxFQUFBLElBQUEsQ0FBRyxDQUFBLEVBQUEsb0JBQUMsU0FBUyxFQUFBLElBQUEsQ0FBRyxDQUFBLEVBQUEsb0JBQUEsSUFBRyxFQUFBLElBQUEsQ0FBRyxDQUFLLENBQUE7R0FDOUIsQ0FBQTtJQUNKO0VBQ0Y7QUFDRixDQUFDLENBQUMsQ0FBQzs7QUFFSCxJQUFJLGlDQUFpQywyQkFBQTtDQUNwQyxpQkFBaUIsRUFBRSxZQUFZO0VBQzlCLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQztFQUNoQixNQUFNLENBQUMsRUFBRSxDQUFDLGNBQWMsRUFBRSxVQUFVLElBQUksRUFBRTtHQUN6QyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ2IsSUFBSSxFQUFFLElBQUksQ0FBQyxXQUFXO0lBQ3RCLENBQUMsQ0FBQztHQUNILENBQUMsQ0FBQztFQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0VBQ2pDO0NBQ0QsTUFBTSxFQUFFLFlBQVk7RUFDbkIsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRTtHQUNwQjtJQUNDLG9CQUFBLEdBQUUsRUFBQSxDQUFBLENBQUMsSUFBQSxFQUFJLENBQUMsR0FBSSxDQUFBLEVBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFDLElBQUEsRUFBTyxvQkFBQSxLQUFJLEVBQUEsQ0FBQSxDQUFDLEdBQUEsRUFBRyxDQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBQztLQUM3RSxHQUFBLEVBQUcsQ0FBQyxhQUFBLEVBQWE7S0FDakIsTUFBQSxFQUFNLENBQUMsSUFBQSxFQUFJO0tBQ1gsS0FBQSxFQUFLLENBQUMsSUFBSSxDQUFBLENBQUcsQ0FBSSxDQUFBO0tBQ2pCO0dBQ0YsTUFBTTtHQUNOLE9BQU8sS0FBSyxDQUFDO0dBQ2I7RUFDRDtBQUNGLENBQUMsQ0FBQyxDQUFDOztBQUVILEtBQUssQ0FBQyxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBVc2VyQ291bnRlciA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdDxsaT5cblx0XHRcdFx0PGEgaHJlZj1cIiNcIj5cblx0XHRcdFx0XHQ8aSBjbGFzc05hbWU9XCJmYSBmYS11c2VycyBmYS1md1wiPjwvaT4gT25saW5lIFxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cImJhZGdlIGFkZC1sZWZ0XCI+IHt0aGlzLnByb3BzLmNvdW50fSA8L3NwYW4+XG5cdFx0XHRcdDwvYT5cblx0XHRcdDwvbGk+XG5cdFx0KTtcblx0fVxufSk7XG5cbnZhciBVc2VyTG9naW4gPSBSZWFjdC5jcmVhdGVDbGFzcyh7XG5cdGF1dGhvcml6ZUlkOiBmdW5jdGlvbiAoaWQpIHtcblx0XHRpZCA9IHBhcnNlSW50KGlkLCAxMCk7XG5cdFx0c29ja2V0LmVtaXQoXCJ1c2VyczphdXRob3JpemVcIiwge1xuXHRcdFx0aWQ6IGlkXG5cdFx0fSk7XG5cdH0sXG5cdGhhbmRsZVN1Ym1pdDogZnVuY3Rpb24gKGUpIHtcblx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cdFx0dmFyIGlkID0gUmVhY3QuZmluZERPTU5vZGUodGhpcy5yZWZzLmF1dGhvcml6ZV9pZCkudmFsdWUudHJpbSgpO1xuXHRcdGlmICghaWQpIHJldHVybjtcblx0XHRSZWFjdC5maW5kRE9NTm9kZSh0aGlzLnJlZnMuYXV0aG9yaXplX2lkKS52YWx1ZSA9ICcnO1xuXHRcdHRoaXMuYXV0aG9yaXplSWQoaWQpO1xuXHRcdHJldHVybjtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdDxmb3JtIG9uU3VibWl0PXt0aGlzLmhhbmRsZVN1Ym1pdH0gPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzTmFtZT1cImlucHV0LWdyb3VwIHNpZ25pblwiPlxuXHRcdFx0XHRcdDxpbnB1dCBcblx0XHRcdFx0XHRcdGlkPVwiYnRuLWlucHV0XCIgXG5cdFx0XHRcdFx0XHR0eXBlPVwidGV4dFwiIFxuXHRcdFx0XHRcdFx0Y2xhc3NOYW1lPVwiZm9ybS1jb250cm9sXCIgXG5cdFx0XHRcdFx0XHRyZWY9XCJhdXRob3JpemVfaWRcIlxuXHRcdFx0XHRcdFx0cGxhY2Vob2xkZXI9XCJDaG9vc2UgYW4gSUQuLi5cIiAvPlxuXHRcdFx0XHRcdDxzcGFuIGNsYXNzTmFtZT1cImlucHV0LWdyb3VwLWJ0blwiPlxuXHRcdFx0XHRcdFx0PGlucHV0IFxuXHRcdFx0XHRcdFx0XHR0eXBlPVwic3VibWl0XCIgXG5cdFx0XHRcdFx0XHRcdGNsYXNzTmFtZT1cImJ0biBidG4tcHJpbWFyeVwiIFxuXHRcdFx0XHRcdFx0XHRpZD1cImJ0bi1jaGF0XCIgXG5cdFx0XHRcdFx0XHRcdHZhbHVlPVwiTG9naW5cIiAvPlxuXHRcdFx0XHRcdDwvc3Bhbj5cblx0XHRcdFx0PC9kaXY+XG5cdFx0XHRcdDxkaXYgY2xhc3NOYW1lPVwic2lnbmluXCI+XG5cdFx0XHRcdDxwIGNsYXNzTmFtZT1cInRleHQtY2VudGVyXCI+PHNtYWxsPkp1c3QgYSB0ZW1wb3JhcnkgbWVhc3VyZSB1bnRpbCBnZW51aW5lIGF1dGhlbnRpY2F0aW9uIGlzIGltcGxlbWVudGVkPC9zbWFsbD48L3A+XG5cdFx0XHRcdDwvZGl2PlxuXHRcdFx0PC9mb3JtPlxuXHRcdCk7XG5cdH1cbn0pXG5cbnZhciBVc2VyTWVudSA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0Z2V0RGVmYXVsdFByb3BzOiBmdW5jdGlvbiAoKSB7XG5cdFx0cmV0dXJuIHtcblx0XHRcdGNvdW50OiAwLFxuXHRcdFx0dXNlcnM6IFtdXG5cdFx0fTtcblx0fSxcblx0Y29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uICgpIHtcblx0XHRzb2NrZXQub24oJ3VzZXJzOnVwZGF0ZScsIHRoaXMudXBkYXRlVXNlcnMpO1xuXHR9LFxuXHR1cGRhdGVVc2VyczogZnVuY3Rpb24gKGRhdGEpIHtcblx0XHR0aGlzLnNldFByb3BzKHtcblx0XHRcdGNvdW50OiBkYXRhLmNvdW50LFxuXHRcdFx0dXNlcnM6IGRhdGEudXNlcnNcblx0XHR9KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0dmFyIHVzZXJzID0gdGhpcy5wcm9wcy51c2Vycy5tYXAoZnVuY3Rpb24gKHVzZXIpIHtcblx0XHRcdHJldHVybiAoXG5cdFx0XHRcdDxsaSBrZXk9e3VzZXIuaWR9PjxhIGhyZWY9XCIjXCI+e3VzZXIudXNlcm5hbWV9PC9hPjwvbGk+XG5cdFx0XHQpO1xuXHRcdH0pO1xuXHRcdHJldHVybiAoXG5cdFx0XHQ8dWwgY2xhc3NOYW1lPVwibmF2XCIgaWQ9XCJzaWRlLW1lbnVcIj5cblx0XHRcdFx0PFVzZXJDb3VudGVyIHsuLi50aGlzLnByb3BzfSAvPlxuXHRcdFx0XHR7dXNlcnN9XG5cdFx0XHRcdDxsaT48YnIgLz48VXNlckxvZ2luIC8+PGJyIC8+PC9saT5cblx0XHRcdDwvdWw+XG5cdFx0KTtcblx0fVxufSk7XG5cbnZhciBDdXJyZW50VXNlciA9IFJlYWN0LmNyZWF0ZUNsYXNzKHtcblx0Y29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uICgpIHtcblx0XHR2YXIgc2VsZiA9IHRoaXM7XG5cdFx0c29ja2V0Lm9uKFwidXNlcnM6dXBkYXRlXCIsIGZ1bmN0aW9uIChkYXRhKSB7XG5cdFx0XHRzZWxmLnNldFByb3BzKHtcblx0XHRcdFx0dXNlcjogZGF0YS5jdXJyZW50VXNlclxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdFx0c29ja2V0LmVtaXQoXCJ1c2VyczpyZWZyZXNoXCIsIHt9KTtcblx0fSxcblx0cmVuZGVyOiBmdW5jdGlvbiAoKSB7XG5cdFx0aWYgKHRoaXMucHJvcHMudXNlcikge1xuXHRcdFx0cmV0dXJuIChcblx0XHRcdFx0PGEgaHJlZj1cIiNcIj57dGhpcy5wcm9wcy51c2VyLnVzZXJuYW1lfSAmbmJzcDs8aW1nIHNyYz17dGhpcy5wcm9wcy51c2VyLmF2YXRhcn1cblx0XHRcdFx0XHRhbHQ9XCJVc2VyIEF2YXRhclwiIFxuXHRcdFx0XHRcdGhlaWdodD1cIjIwXCJcblx0XHRcdFx0XHR3aWR0aD1cIjIwXCIgLz48L2E+XG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXHR9XG59KTtcblxuYWxlcnQoXCJmb29cIikiXX0= \ No newline at end of file diff --git a/spec/gather.js b/spec/gather.js index 530b590..f27c7bd 100644 --- a/spec/gather.js +++ b/spec/gather.js @@ -147,6 +147,7 @@ describe("Gather Model:", function () { }); }); }); + describe("addUser", function () { it ("adds gatherer to lobby", function () { gather.addUser(user); @@ -159,6 +160,7 @@ describe("Gather Model:", function () { assert.equal(gather.gatherers.length, 1); }); }); + describe("removeUser", function () { it ("removes gatherer altogether", function () { gather.addUser(user); @@ -168,6 +170,7 @@ describe("Gather Model:", function () { assert.equal(gather.gatherers.length, 0); }); }); + describe("moveToMarine", function () { it ("moves a player to marine", function () { gather.addUser(user); @@ -183,6 +186,7 @@ describe("Gather Model:", function () { }); }); }); + describe("moveToAlien", function () { it ("moves a player to alien", function () { gather.addUser(user); @@ -198,6 +202,7 @@ describe("Gather Model:", function () { }); }); }); + describe("moveToLobby", function () { it ("moves a player to lobby", function () { gather.addUser(user); @@ -208,6 +213,7 @@ describe("Gather Model:", function () { assert.equal(gather.lobby()[0].id, user.id); }); }); + describe("aliens", function () { it ("returns all gatherers in aliens", function () { gather.addUser(user); @@ -215,6 +221,7 @@ describe("Gather Model:", function () { assert.equal(gather.aliens().length, 1); }); }); + describe("marines", function () { it ("returns all gatherers in marines", function () { gather.addUser(user); @@ -222,12 +229,14 @@ describe("Gather Model:", function () { assert.equal(gather.marines().length, 1); }); }); + describe("lobby", function () { it ("returns all gatherers in lobby", function () { gather.addUser(user); assert.equal(gather.lobby().length, 1); }); }); + describe("toJson", function () { it ("returns a json representation of the gather instance", function () { var output = gather.toJson(); @@ -235,6 +244,7 @@ describe("Gather Model:", function () { assert.isString(output.state); }); }); + describe("leaderVotes", function () { beforeEach(function () { gatherers.forEach(function (user) { @@ -261,6 +271,7 @@ describe("Gather Model:", function () { assert.equal(gather.leaderVotes().length, 0); }); }); + describe("voteForLeader", function () { beforeEach(function () { gatherers.forEach(function (user) { @@ -289,6 +300,7 @@ describe("Gather Model:", function () { assert.equal(votes[0], secondCandidate.id); }); }); + describe("alienLeader", function () { beforeEach(function () { gatherers.forEach(function (gatherer) { @@ -304,6 +316,7 @@ describe("Gather Model:", function () { assert.isUndefined(gather.alienLeader()); }); }); + describe("marineLeader", function () { beforeEach(function () { gatherers.forEach(function (gatherer) { @@ -319,6 +332,7 @@ describe("Gather Model:", function () { assert.isUndefined(gather.marineLeader()); }); }); + describe("assignMarineLeader", function () { it ("assigns a marine leader", function () { gather.addUser(user); @@ -327,6 +341,7 @@ describe("Gather Model:", function () { assert.equal(leader.id, user.id); }); }); + describe("assignAlienLeader", function () { it ("assigns an alien leader", function () { gather.addUser(user); @@ -335,6 +350,21 @@ describe("Gather Model:", function () { assert.equal(leader.id, user.id); }); }); + + describe("getGatherer", function () { + beforeEach(function () { + gather.addGatherer(user); + }); + it ("returns a gatherer given a user", function () { + var gatherer = gather.getGatherer(user); + assert.equal(gatherer.id, user.id); + }); + it ("returns null if user is not a gatherer", function () { + var gatherer = gather.getGatherer(gatherers[0]); + assert.isNull(gatherer); + }); + }); + describe("confirmTeam", function () { var leader; beforeEach(function () { diff --git a/views/partials/foot.hbs b/views/partials/foot.hbs index 13d57a5..806d4e9 100644 --- a/views/partials/foot.hbs +++ b/views/partials/foot.hbs @@ -1 +1,2 @@ - \ No newline at end of file + + \ No newline at end of file