<commit_before>/**
 * Created by youha on 4/12/2016.
 */
'use strict';
var React = require('react');
var ReactDOM = require('react-dom');
var Firebase = require('firebase');
var bs = require('react-bootstrap');
var Button = bs.Button;
var constant = require('./../common/config');
var LIST = require('./../common/customerList');
var ProjectList = LIST.ProjectList;

var StoryList = React.createClass({
    getInitialState: function () {
        this.curRelease = '';
        this.curProject = 4;
        return {
            items: [[], [], [], [], [], []]
        }
    },
    updateList: function (list, data) {
        if (list) {
            for (var i in list) {
                if (list[i].id == data.id) {
                    list.splice(i, 1);
                    break;
                }
            }
        }

    },
    loadData: function () {
        this.firebaseRef.once('value', function (snap) {
            this.state.items = [[], [], [], [], [], []];
            var dataList = snap.val();
            if (dataList) {
                for (var i in dataList) {
                    var data = dataList[i];
                    if (data && data.action && data.schedule.release.toString() == this.curRelease.toString()
                        && data.schedule.project.toString() == this.curProject.toString()) {
                        if (!data.bug) {
                            data.bug = [];
                        }
                        this.state.items[data.action - 1].push(data);
                    }
                }
            }
            this.setState({
                items: this.state.items
            });
        }.bind(this));
    },
    componentWillMount: function () {
        this.firebaseRef = new Firebase(constant.story);
        this.ref = new Firebase(constant.host);
        this.ref.child('index').child('releaseIndex').once('value', function (snap) {
            this.ref.child('release').child(snap.val() - 1).once('value', function (tt) {
                var value = tt.val();
                if (value) {
                    this.curRelease = value.id;
                    this.curReleaseName = value.name;
                }
                this.loadData();
            }.bind(this));
        }.bind(this));
    },
    componentWillUnmount: function () {
        this.firebaseRef.off();
        this.indexRef.off();
    },
    renderLi: function (item) {
        return (
            <StoryItem story={item} key={item.id} onLeft={this.onLeft} onRight={this.onRight}>
            </StoryItem>
        );
    },
    onLeft: function (data) {
        if (!data || data.action <= 1) {
            alert('ni shi dou bi me? ');
            return;
        }
        this.firebaseRef.child(data.storyId).child('action').set(data.action - 1, function (error) {
            if (!error) {
                this.loadData();
            }
        }.bind(this));
    },
    onRight: function (data) {
        if (!data || data.action >= 6) {
            alert('ni shi dou bi me? ');
            return;
        }
        this.firebaseRef.child(data.storyId).child('action').set(data.action + 1, function (error) {
            if (!error) {
                this.loadData();
            }
        }.bind(this));
    },
    projectChange: function (value) {
        this.curProject = value;
        this.loadData();
    },
    render: function () {
        return (

                        Current Release:
                        {this.curReleaseName}

                        Select Project:
                        <ProjectList value={this.curProject} onChange={this.projectChange}></ProjectList>

定义

                    {this.state.items[0].map(this.renderLi)}

开发中

                    {this.state.items[1].map(this.renderLi)}

开发完成

                    {this.state.items[2].map(this.renderLi)}

测试中

                    {this.state.items[3].map(this.renderLi)}

测试完成

                    {this.state.items[4].map(this.renderLi)}

上线

                    {this.state.items[5].map(this.renderLi)}

        )
    }
});

var StoryItem = React.createClass({
    goEditPage: function () {
        var data = this.props.story;
        if (data.storyId) {
            window.open("story.html?id=" + data.storyId, '_blank');
        }
    },
    clickLeft: function () {
        this.props.onLeft(this.props.story);
    },
    clickRight: function () {
        this.props.onRight(this.props.story);
    },
    renderBugItem: function (item) {
        return (

                1 ? 'fixed-bug' : 'open-bug'}> {item.name}

        )
    },
    render: function () {
        var style = {
            float: 'right'
        };
        return (

                            {this.props.story.storyId}--{this.props.story.basic.name}

                    Plan Est: {this.props.story.status.planEst}

                    Task Est: {this.props.story.status.taskEst}

                    Todo: {this.props.story.status.todo}

                    Bugs: {this.props.story.bug.length}

                    {this.props.story.bug.map(this.renderBugItem)}
                    <Button bsStyle="primary" onClick={this.clickLeft}><</Button>
                    <Button bsStyle="primary" style={style} onClick={this.clickRight}>></Button>

        )
    }
});

var el = document.getElementById('storyList');

if (el) {
    ReactDOM.render(React.createElement(StoryList, null), el);
}<commit_msg>add release filter<commit_after>/**
 * Created by youha on 4/12/2016.
 */
'use strict';
var React = require('react');
var ReactDOM = require('react-dom');
var Firebase = require('firebase');
var bs = require('react-bootstrap');
var Button = bs.Button;
var constant = require('./../common/config');
var LIST = require('./../common/customerList');
var ProjectList = LIST.ProjectList;
var ReleaseSelect = LIST.ReleaseSelect;

var StoryList = React.createClass({
    getInitialState: function () {
        this.curRelease = '';
        this.curProject = 4;
        return {
            items: [[], [], [], [], [], []]
        }
    },
    loadData: function () {
        this.firebaseRef.once('value', function (snap) {
            this.state.items = [[], [], [], [], [], []];
            var dataList = snap.val();
            if (dataList) {
                for (var i in dataList) {
                    var data = dataList[i];
                    if (data && data.action && data.schedule.release.toString() == this.curRelease.toString()
                        && data.schedule.project.toString() == this.curProject.toString()) {
                        if (!data.bug) {
                            data.bug = [];
                        }
                        this.state.items[data.action - 1].push(data);
                    }
                }
            }
            this.setState({
                items: this.state.items
            });
        }.bind(this));
    },
    componentWillMount: function () {
        this.firebaseRef = new Firebase(constant.story);
        this.ref = new Firebase(constant.host);
        this.ref.child('index').child('releaseIndex').once('value', function (snap) {
            this.ref.child('release').child(snap.val() - 1).once('value', function (tt) {
                var value = tt.val();
                if (value) {
                    this.curRelease = value.id;
                    this.curReleaseName = value.name;
                }
                this.loadData();
            }.bind(this));
        }.bind(this));
    },
    componentWillUnmount: function () {
        this.firebaseRef.off();
        this.indexRef.off();
    },
    renderLi: function (item) {
        return (
            <StoryItem story={item} key={item.id} onLeft={this.onLeft} onRight={this.onRight}>
            </StoryItem>
        );
    },
    onLeft: function (data) {
        if (!data || data.action <= 1) {
            alert('ni shi dou bi me? ');
            return;
        }
        this.firebaseRef.child(data.storyId).child('action').set(data.action - 1, function (error) {
            if (!error) {
                this.loadData();
            }
        }.bind(this));
    },
    onRight: function (data) {
        if (!data || data.action >= 6) {
            alert('ni shi dou bi me? ');
            return;
        }
        this.firebaseRef.child(data.storyId).child('action').set(data.action + 1, function (error) {
            if (!error) {
                this.loadData();
            }
        }.bind(this));
    },
    projectChange: function (value) {
        this.curProject = value;
        this.loadData();
    },
    releaseChange: function (value) {
        this.curRelease = value;
        this.loadData();
    },
    render: function () {
        return (

                        <ProjectList value={this.curProject} onChange={this.projectChange}
                                     floatingLabelText="Project"/>
                        <ReleaseSelect value={this.curRelease} onChange={this.releaseChange}
                                       floatingLabelText="Release"/>

定义

                    {this.state.items[0].map(this.renderLi)}

开发中

                    {this.state.items[1].map(this.renderLi)}

开发完成

                    {this.state.items[2].map(this.renderLi)}

测试中

                    {this.state.items[3].map(this.renderLi)}

测试完成

                    {this.state.items[4].map(this.renderLi)}

上线

                    {this.state.items[5].map(this.renderLi)}

        )
    }
});

var StoryItem = React.createClass({
    goEditPage: function () {
        var data = this.props.story;
        if (data.storyId) {
            window.open("story.html?id=" + data.storyId, '_blank');
        }
    },
    clickLeft: function () {
        this.props.onLeft(this.props.story);
    },
    clickRight: function () {
        this.props.onRight(this.props.story);
    },
    renderBugItem: function (item) {
        return (

                1 ? 'fixed-bug' : 'open-bug'}> {item.name}

        )
    },
    render: function () {
        var style = {
            float: 'right'
        };
        return (

                            {this.props.story.storyId}--{this.props.story.basic.name}

                    Plan Est: {this.props.story.status.planEst}

                    Task Est: {this.props.story.status.taskEst}

                    Todo: {this.props.story.status.todo}

                    Bugs: {this.props.story.bug.length}

                    {this.props.story.bug.map(this.renderBugItem)}
                    <Button bsStyle="primary" onClick={this.clickLeft}><</Button>
                    <Button bsStyle="primary" style={style} onClick={this.clickRight}>></Button>

        )
    }
});

var el = document.getElementById('storyList');

if (el) {
    ReactDOM.render(React.createElement(StoryList, null), el);
}<|endoftext|>


<commit_before>// browser globals
if (typeof biojs === 'undefined') {
  biojs = {};
}
if (typeof biojs.vis === 'undefined') {
  biojs.vis = {};
}
// use two namespaces
window.msa = biojs.vis.msa = module.exports = require('./index');

// TODO: how should this be bundled

if (typeof biojs.io === 'undefined') {
  biojs.io = {};
}

// just bundle the two parsers
window.biojs.io.fasta = require("biojs-io-fasta");
window.biojs.io.clustal = require("biojs-io-clustal");
window.biojs.xhr = require("nets");

module.exports = require("./src/index");

require('./css/msa.css');
<commit_msg>FIX: require src/index<commit_after>// browser globals
if (typeof biojs === 'undefined') {
  biojs = {};
}
if (typeof biojs.vis === 'undefined') {
  biojs.vis = {};
}
// use two namespaces
window.msa = biojs.vis.msa = module.exports = require('./src/index');

// TODO: how should this be bundled

if (typeof biojs.io === 'undefined') {
  biojs.io = {};
}

// just bundle the two parsers
window.biojs.io.fasta = require("biojs-io-fasta");
window.biojs.io.clustal = require("biojs-io-clustal");
window.biojs.xhr = require("nets");

module.exports = require("./src/index");

require('./css/msa.css');
<|endoftext|>


<commit_before>'use strict';

var EventEmitter = require('eventemitter3')
  , loads = require('loads')
  , AXO = require('axo');

/**
 * RequestS(tream).
 *
 * @constructor
 * @param {String} url The URL we want to request.
 * @param {String} method HTTP method to use.
 * @api public
 */
function Requests(url, options) {
  if (!(this instanceof Requests)) return new Requests(url, options);
  options = options || {};

  this.id = Requests.requested++;
  this.streaming = options.streaming || false;
  this.socket = Requests[Requests.mode](options);
  this.socket.open(url, options.method.toUppercase(), true);

  //
  // Register this as an active HTTP request.
  //
  Requests.active[this.id] = this;
  this.initialize();
}

Requests.prototype = new EventEmitter();
Requests.prototype.constructor = Requests;
Requests.prototype.emits = require('emits');

/**
 * Initialize and start requesting the supplied resource.
 *
 * @param {Object} options Passed in defaults.
 * @api private
 */
Requests.prototype.initialize = function initialize(options) {
  this.on('stream', function stream() {
    if (this.socket.multipart) return this.emit('data', this.socket.responseText);

    var chunk = this.socket.responseText.slice(this.offset);
    this.offset = this.socket.responseText.length;

    this.emit('data', chunk);
  });

  if (options.timeout) {
    // @TODO use setTimeout here for older webkits
    this.socket.timeout = +options.time;
    this.socket.ontimeout = this.emits('timeout');
  }

  if ('cors' === options.mode.toLowerCase() && 'withCredentials' in this.socket) {
    this.socket.withCredentials = true;
  }

  //
  // We want to prevent pre-flight requests by default for CORS requests so we
  // need to force the content-type to text/plain.
  //
  this.header('Content-Type', 'text/plain');
  for (var key in options.headers) {
    this.header(key, options.headers[key]);
  }

  loads(this.socket, this.emits('data'), this.emits('streaming'));
  this.socket.send(options.body);
};

/**
 * Safely set a request header.
 *
 * @param {String} key Name of the header.
 * @param {String} value Value of the header.
 * @returns {Requests}
 * @api public
 */
Requests.prototype.header = function header(key, value) {
  //
  // ActiveXObject will throw an `Type Mismatch` exception when setting the to
  // an null-value and to be consistent with all XHR implementations we're going
  // to cast the value to a string.
  //
  // While we don't technically support the XDomainRequest of IE, we do want to
  // double check that the setRequestHeader is available before adding headers.
  //
  if (value !== undefined && this.socket.setRequestHeader) {
    this.socket.setRequestHeader(key, value +'');
  }

  return this;
};

/**
 * Register a timeout handler.
 *
 * @param {Number} time Maximum duration a request can take.
 * @returns {Requests}
 * @api public
 */
Requests.prototype.timeout = function timeout(time) {
  this.socket.timeout = +time;
  this.socket.ontimeout = this.emits('timeout');

  return this;
};

/**
 * Create a new XMLHttpRequest.
 *
 * @returns {XMLHttpRequest}
 * @api private
 */
Requests.XHR = function create() {
  try { return new XMLHttpRequest(); }
  catch (e) {}
};

/**
 * Create a new ActiveXObject which can be used for XHR.
 *
 * @returns {ActiveXObject}
 * @api private
 */
Requests.AXO = function create() {
  var ids = ['MSXML2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.3.0', 'Microsoft.XMLHTTP']
    , id;

  while (ids.length) {
    id = ids.shift();

    try { return new AXO(id); }
    catch (e) {}
  }
};

/**
 * Requests that are currently running.
 *
 * @type {Object}
 * @private
 */
Requests.active = {};

/**
 * Unique id and also an indication on how many XHR requests we've made using
 * this library.
 *
 * @type {Number}
 * @private
 */
Requests.requested = 0;

/**
 * The type of technology we are using to establish a working Ajax connection.
 * This can either be:
 *
 * - XHR: XMLHttpRequest
 * - AXO: ActiveXObject
 *
 * This is also used as internal optimization so we can easily get the correct
 * constructor as we've already feature detected it.
 *
 * @type {String}
 * @public
 */
Requests.mode = !!Requests.XHR() ? 'XHR' : (!!Requests.AXO() ? 'AXO' : '');

/**
 * Boolean indicating
 *
 * @type {Boolean}
 * @public
 */
Requests.supported = !!Requests.mode;

/**
 * The different type of `responseType` parsers that are supported in this XHR
 * implementation.
 *
 * @type {Object}
 * @public
 */
Requests.type = 'XHR' === Requests.mode ? (function detect() {
  var types = 'arraybuffer,blob,document,json,text,moz-blob,moz-chunked-text,moz-chunked-arraybuffer,ms-stream'.split(',')
    , supported = {}
    , type, xhr, prop;

  while (types.length) {
    type = types.pop();

    xhr = Requests.XHR();
    xhr.open('get', '/', true);
    prop = type.replace('-', '');

    //
    // We can only set the `responseType` after we've opened the connection or
    // FireFox will throw an error and according to the spec only async requests
    // can use this, which is fine as we force that by default.
    //
    try {
      xhr.responseType = type;
      supported[prop] = 'response' in xhr && xhr.responseType === type;
    } catch (e) {
      supported[prop] = false;
    }

    xhr = null;
  }

  return supported;
}()) : {};

/**
 * Do we support streaming response parsing.
 *
 * @type {Boolean}
 * @private
 */
Requests.streaming = 'XHR' === Requests.mode && (
     'multipart' in XMLHttpRequest.prototype
  || Requests.type.mozchunkedarraybuffer
  || Requests.type.mozchunkedtext
  || Requests.type.msstream
  || Requests.type.mozblob
);

//
// Expose the Requests library.
//
module.exports = Requests;
<commit_msg>[rm] Why was this even here =/<commit_after><|endoftext|>


<commit_before>"use strict"
const colors = require('colors');
const walk = require('walk');
const fs = require("fs");
const ytdl = require('ytdl-core');

class MusicManager{
  constructor(options){
    this.options = options;
    this.disnode = options.disnode;

    this.following = [];

    this.defaultConfig = {
      commands:[
        {
		      "cmd": "skip",
		      "context": "MusicManager",
		      "run": "cmdSkip",
		      "desc": "Displays list of Audio Files.",
		      "usage": "list [page]",
		    },
				{
		      "cmd": "stream",
		      "context": "MusicManager",
		      "run": "cmdStream",
		      "desc": "Plays an audio file.",
		      "usage": "play [url] [volume]",
		    },
        {
		      "cmd": "clearqueue",
		      "context": "MusicManager",
		      "run": "cmdClearQueue",
		      "desc": "Stopps and Clears all URLS's in Queue",
		      "usage": "clearqueue",
		    },
		    {
		      "cmd": "resume",
		      "context": "MusicManager",
		      "run": "cmdResume",
		      "desc": "Resumes Connection",
		      "usage": "resume",
		    },
        {
		      "cmd": "pause",
		      "context": "MusicManager",
		      "run": "cmdPause",
		      "desc": "Pauses Connection",
		      "usage": "resume",
		    },
				{
          "cmd": "jv",
          "context": "MusicManager",
          "run": "cmdJoinVoice",
          "desc": "Joins the voice channel you are connected to.",
          "usage": "jv"
        },
        {
          "cmd": "lv",
          "context": "MusicManager",
          "run": "cmdLeaveVoice",
          "desc": "Leaves the voice channel you are connected to.",
          "usage": "lv",
        },
        {
          "cmd": "follow",
          "context": "MusicManager",
          "run": "cmdFollowUser",
          "desc": "Test Command that lists all params.",
          "usage": "follow [User]",
        },
        {
          "cmd": "unfollow",
          "context": "MusicManager",
          "run": "cmdUnFollowUser",
          "desc": "Test Command that lists all params.",
          "usage": "unfollow [parms]",
        }
			],
			songs: [],
      maxVolume: 3,
      defaultVolume: 0.8,
			resNoName : "```Please Enter a name for this song!```",
			resNoUrl : "```Please Enter a Youtube URL for this song!```",
			resSongAdded : "```[Song] Added!```",
      resFollow : "**Following: ** [Sender]",
      resUnFollow : "**Stop Following: ** [Sender]",
      resJoiningServer: "**Joining Server: ** [Server]",
      resNotInServer: "**Can't Join You! Try Joining a Channel First!**",
      resMaxVolume: "**Max Volume([MaxVolume]) Reached! Playing at: [DefaultVolume].**",
      resResume: "**Resuming the queue!**",
      resPause: "**Pausing the queue!**",
      resClearQueue: "**Clearing the queue!**"
    };

    this.config = this.disnode.config.MusicManager || this.defaultConfig;

    if(options.voiceEvents == true){
       options.disnode.bot.on("voiceJoin", (c,u)=>this.OnVoiceJoin(c,u));
       options.disnode.bot.on("voiceLeave", (c,u)=>this.OnVoiceLeave(c,u));
    }
  }

  OnVoiceJoin(channel,user){
    if(this.following.includes(user.username)){
        this.JoinServer(channel);
    }
  }

  OnVoiceLeave(channel,user){
    if(this.following.includes(user.username)){
      this.LeaveServer(channel);
    }
  }

  playStream(connection, vol){
    var self = this;
    connection.playRunning = true;
    connection.setVolume(vol);
    connection.ytStream = ytdl(connection.queue[0], {audioonly: true});
    connection.ytStream.on('end', function(){
      if(connection.queue.length == 0){
        connection.playRunning = false;

      }else{
        connection.queue.splice(0,1);
        self.playStream(connection);
        //connection.ytStream.destory();
      }
    });
		connection.playRawStream(connection.ytStream);
  }
  addUrl(url,connection, vol){
    var bot = this.disnode.bot;

    if(!connection.queue){connection.queue = [];}
    connection.queue.push(url);
    if(!connection.playRunning){
      this.playStream(connection,vol);
    }
  }

  JoinServer(channel){
    var self = this;
    this.disnode.bot.joinVoiceChannel(channel, function(err, connnection){
      if(err){
        console.log(err);
        return;
      }
    });
  }

  LeaveServer(channel){
    var self = this;
    this.disnode.bot.leaveVoiceChannel(channel, function(err, connnection){
      if(err){
        console.log(err);
        return;
      }
    });
  }

  cmdPause(parsedMsg){
    var connection = GetVoiceConnectionViaMsg(parsedMsg.msg, this.disnode.bot.voiceConnections);

    if(connection){
      connection.pause();
      this.disnode.sendResponse(parsedMsg, this.config.resPause);
    }else{
      this.disnode.sendResponse(parsedMsg, this.config.resNotInServer);
    }
  }

  cmdResume(parsedMsg){
    var connection = GetVoiceConnectionViaMsg(parsedMsg.msg, this.disnode.bot.voiceConnections);

    if(connection){
      connection.resume();
      this.disnode.sendResponse(parsedMsg, this.config.resResume,{parse: true});
    }else{
      this.disnode.sendResponse(parsedMsg, this.config.resNotInServer,{parse: true});
    }
  }

  cmdStream(parsedMsg){
    var self = this;
    var url = parsedMsg.params[0];
    var vol = this.config.defaultConfig || .8;
    if(parsedMsg.params[1]){
      if(parseFloat(parsedMsg.params[1]) != 'NaN'){
        vol = parseFloat(parsedMsg.params[1]);
      }
    }
    GetVolume(vol, this.config, function(err, res){
      if(!err){
        vol = res;

      }
      if(err == "MAX"){
        var shortcuts = [
          {shortcut: "[DefaultVolume]", data: self.config.defaultVolume},
          {shortcut: "[MaxVolume]", data: self.config.maxVolume},
          {shortcut: "[RequestedVolume]", data: vol}];
        self.disnode.sendResponse(parsedMsg, self.config.resMaxVolume, {parse: true, shortcuts: shortcuts})
      }
    });
    var channel = GetVoiceConnectionViaMsg(parsedMsg.msg, this.disnode.bot.voiceConnections);

    if(channel){
      this.addUrl(url,channel,vol);
    }
    else{
      this.disnode.sendResponse(parsedMsg, "Not In Server!");
    }
  }

  cmdJoinVoice(parsedMsg){
    var self = this;
    var channel = parsedMsg.msg.author.voiceChannel;
    var shortcuts = [{
      shortcut: "[Server]",
      data: channel.name
    }];
    if(channel){
      this.JoinServer(channel);
      this.disnode.sendResponse(parsedMsg, this.config.resJoiningServer,{parse: true, shortcuts: shortcuts});
    }else{
      this.disnode.sendResponse(parsedMsg, this.config.resNotInServer,{parse: true});
    }
  }

  cmdLeaveVoice(parsedMsg){
    var channel = GetVoiceConnectionViaMsg(parsedMsg.msg, this.disnode.bot.voiceConnections).voiceChannel;
    this.LeaveServer(channel);
  }

  cmdSkip(parsedMsg){
    var connection = GetVoiceConnectionViaMsg(parsedMsg.msg, this.disnode.bot.voiceConnections);

    if(connection){
      connection.queue.splice(0,1);
      this.playLoop();
    }
  }

  cmdFollowUser(parsedMsg){
    var self = this;
    this.following.push(parsedMsg.msg.author.username);
    console.log(this.following);
    this.disnode.sendResponse(parsedMsg, this.config.resFollow,{parse: true});
  }

  cmdUnFollowUser(parsedMsg){
    var index = this.following.indexOf(parsedMsg.msg.author.username);

    this.following.splice(index,1);

    this.disnode.sendResponse(parsedMsg, this.config.resUnFollow,{parse: true});
  }

  cmdClearQueue(parsedMsg){
    var connection = GetVoiceConnectionViaMsg(parsedMsg.msg, this.disnode.bot.voiceConnections);

    if(connection){
      connection.queue = [];
      connection.stopPlaying();
      this.disnode.sendResponse(parsedMsg, this.config.resClearQueue);
    }else{
      this.disnode.sendResponse(parsedMsg, this.config.resNotInServer);
    }
  }

}

function GetVoiceConnectionViaMsg(msg, voiceConnections){
  var connection;

  var serverChannels = msg.server.channels;

  for (var i = 0; i < voiceConnections.length; i++) {
    var channel = voiceConnections[i].voiceChannel;

    if(serverChannels.includes(channel)){
      connection = voiceConnections[i];
    }
  }

  return connection;
}

function GetVolume(requestedVol, config, cb){
  var defaultVol = config.defaultVolume || 0.8;
  var maxVol = config.maxVolume || 1;

  if(requestedVol <= maxVol){

    cb(null,requestedVol) ;
  }else{
    cb("MAX", defaultVol);
  }
}

module.exports = MusicManager;
<commit_msg>bug fixes<commit_after>"use strict"
const colors = require('colors');
const walk = require('walk');
const fs = require("fs");
const ytdl = require('ytdl-core');

class MusicManager{
  constructor(options){
    this.options = options;
    this.disnode = options.disnode;

    this.following = [];

    this.defaultConfig = {
      commands:[
        {
		      "cmd": "skip",
		      "context": "MusicManager",
		      "run": "cmdSkip",
		      "desc": "Displays list of Audio Files.",
		      "usage": "list [page]",
		    },
				{
		      "cmd": "stream",
		      "context": "MusicManager",
		      "run": "cmdStream",
		      "desc": "Plays an audio file.",
		      "usage": "play [url] [volume]",
		    },
        {
		      "cmd": "clearqueue",
		      "context": "MusicManager",
		      "run": "cmdClearQueue",
		      "desc": "Stopps and Clears all URLS's in Queue",
		      "usage": "clearqueue",
		    },
		    {
		      "cmd": "resume",
		      "context": "MusicManager",
		      "run": "cmdResume",
		      "desc": "Resumes Connection",
		      "usage": "resume",
		    },
        {
		      "cmd": "pause",
		      "context": "MusicManager",
		      "run": "cmdPause",
		      "desc": "Pauses Connection",
		      "usage": "resume",
		    },
				{
          "cmd": "jv",
          "context": "MusicManager",
          "run": "cmdJoinVoice",
          "desc": "Joins the voice channel you are connected to.",
          "usage": "jv"
        },
        {
          "cmd": "lv",
          "context": "MusicManager",
          "run": "cmdLeaveVoice",
          "desc": "Leaves the voice channel you are connected to.",
          "usage": "lv",
        },
        {
          "cmd": "follow",
          "context": "MusicManager",
          "run": "cmdFollowUser",
          "desc": "Test Command that lists all params.",
          "usage": "follow [User]",
        },
        {
          "cmd": "unfollow",
          "context": "MusicManager",
          "run": "cmdUnFollowUser",
          "desc": "Test Command that lists all params.",
          "usage": "unfollow [parms]",
        }
			],
			songs: [],
      maxVolume: 3,
      defaultVolume: 0.8,
			resNoName : "```Please Enter a name for this song!```",
			resNoUrl : "```Please Enter a Youtube URL for this song!```",
			resSongAdded : "```[Song] Added!```",
      resFollow : "**Following: ** [Sender]",
      resUnFollow : "**Stop Following: ** [Sender]",
      resJoiningServer: "**Joining Server: ** [Server]",
      resNotInServer: "**Can't Join You! Try Joining a Channel First!**",
      resMaxVolume: "**Max Volume([MaxVolume]) Reached! Playing at: [DefaultVolume].**",
      resResume: "**Resuming the queue!**",
      resPause: "**Pausing the queue!**",
      resClearQueue: "**Clearing the queue!**"
    };

    this.config = this.disnode.config.MusicManager || this.defaultConfig;

    if(options.voiceEvents == true){
       options.disnode.bot.on("voiceJoin", (c,u)=>this.OnVoiceJoin(c,u));
       options.disnode.bot.on("voiceLeave", (c,u)=>this.OnVoiceLeave(c,u));
    }
  }

  OnVoiceJoin(channel,user){
    if(this.following.includes(user.username)){
        this.JoinServer(channel);
    }
  }

  OnVoiceLeave(channel,user){
    if(this.following.includes(user.username)){
      this.LeaveServer(channel);
    }
  }

  playStream(connection, vol){
    var self = this;
    connection.playRunning = true;
    connection.setVolume(vol);
    connection.ytStream = ytdl(connection.queue[0], {audioonly: true});
    connection.ytStream.on('end', function(){
      if(connection.queue.length == 0){
        connection.playRunning = false;

      }else{
        connection.queue.splice(0,1);
        self.playStream(connection);
        //connection.ytStream.destory();
      }
    });
		connection.playRawStream(connection.ytStream);
  }
  addUrl(url,connection, vol){
    var bot = this.disnode.bot;

    if(!connection.queue){connection.queue = [];}
    connection.queue.push(url);
    if(!connection.playRunning){
      this.playStream(connection,vol);
    }
  }

  JoinServer(channel){
    var self = this;
    this.disnode.bot.joinVoiceChannel(channel, function(err, connnection){
      if(err){
        console.log(err);
        return;
      }
    });
  }

  LeaveServer(channel){
    var self = this;
    this.disnode.bot.leaveVoiceChannel(channel, function(err, connnection){
      if(err){
        console.log(err);
        return;
      }
    });
  }

  cmdPause(parsedMsg){
    var connection = GetVoiceConnectionViaMsg(parsedMsg.msg, this.disnode.bot.voiceConnections);

    if(connection){
      connection.pause();
      this.disnode.sendResponse(parsedMsg, this.config.resPause);
    }else{
      this.disnode.sendResponse(parsedMsg, this.config.resNotInServer);
    }
  }

  cmdResume(parsedMsg){
    var connection = GetVoiceConnectionViaMsg(parsedMsg.msg, this.disnode.bot.voiceConnections);

    if(connection){
      connection.resume();
      this.disnode.sendResponse(parsedMsg, this.config.resResume,{parse: true});
    }else{
      this.disnode.sendResponse(parsedMsg, this.config.resNotInServer,{parse: true});
    }
  }

  cmdStream(parsedMsg){
    var self = this;
    var url = parsedMsg.params[0];
    var vol = this.config.defaultConfig || .8;
    if(parsedMsg.params[1]){
      if(parseFloat(parsedMsg.params[1]) != 'NaN'){
        vol = parseFloat(parsedMsg.params[1]);
      }
    }
    GetVolume(vol, this.config, function(err, res){
      if(!err){
        vol = res;

      }
      if(err == "MAX"){
        var shortcuts = [
          {shortcut: "[DefaultVolume]", data: self.config.defaultVolume},
          {shortcut: "[MaxVolume]", data: self.config.maxVolume},
          {shortcut: "[RequestedVolume]", data: vol}];
        self.disnode.sendResponse(parsedMsg, self.config.resMaxVolume, {parse: true, shortcuts: shortcuts})
      }
    });
    var channel = GetVoiceConnectionViaMsg(parsedMsg.msg, this.disnode.bot.voiceConnections);

    if(channel){
      this.addUrl(url,channel,vol);
    }
    else{
      this.disnode.sendResponse(parsedMsg, "Not In Server!");
    }
  }

  cmdJoinVoice(parsedMsg){
    var self = this;
    var channel = parsedMsg.msg.author.voiceChannel;
    var shortcuts = [{
      shortcut: "[Server]",
      data: channel.name
    }];
    if(channel){
      this.JoinServer(channel);
      this.disnode.sendResponse(parsedMsg, this.config.resJoiningServer,{parse: true, shortcuts: shortcuts});
    }else{
      this.disnode.sendResponse(parsedMsg, this.config.resNotInServer,{parse: true});
    }
  }

  cmdLeaveVoice(parsedMsg){
    var channel = GetVoiceConnectionViaMsg(parsedMsg.msg, this.disnode.bot.voiceConnections).voiceChannel;
    this.LeaveServer(channel);
  }

  cmdSkip(parsedMsg){
    var connection = GetVoiceConnectionViaMsg(parsedMsg.msg, this.disnode.bot.voiceConnections);

    if(connection){
      connection.queue.splice(0,1);
      this.playStream();
    }
  }

  cmdFollowUser(parsedMsg){
    var self = this;
    this.following.push(parsedMsg.msg.author.username);
    console.log(this.following);
    this.disnode.sendResponse(parsedMsg, this.config.resFollow,{parse: true});
  }

  cmdUnFollowUser(parsedMsg){
    var index = this.following.indexOf(parsedMsg.msg.author.username);

    this.following.splice(index,1);

    this.disnode.sendResponse(parsedMsg, this.config.resUnFollow,{parse: true});
  }

  cmdClearQueue(parsedMsg){
    var connection = GetVoiceConnectionViaMsg(parsedMsg.msg, this.disnode.bot.voiceConnections);

    if(connection){
      connection.queue = [];
      connection.stopPlaying();
      this.disnode.sendResponse(parsedMsg, this.config.resClearQueue);
    }else{
      this.disnode.sendResponse(parsedMsg, this.config.resNotInServer);
    }
  }

}

function GetVoiceConnectionViaMsg(msg, voiceConnections){
  var connection;

  var serverChannels = msg.server.channels;

  for (var i = 0; i < voiceConnections.length; i++) {
    var channel = voiceConnections[i].voiceChannel;

    if(serverChannels.includes(channel)){
      connection = voiceConnections[i];
    }
  }

  return connection;
}

function GetVolume(requestedVol, config, cb){
  var defaultVol = config.defaultVolume || 0.8;
  var maxVol = config.maxVolume || 1;

  if(requestedVol <= maxVol){

    cb(null,requestedVol) ;
  }else{
    cb("MAX", defaultVol);
  }
}

module.exports = MusicManager;
<|endoftext|>


<commit_before>// N-gram full text search client module
// https://github.com/sukuba/js-py-ngram-full-text-search

/*############
require JQuery
############*/

/* enable this when you wish to run within Node.js ...
define(function(){
*/

/*############
Namespace: JsNgram
  without Node.js, this will create a global entry point JsNgram.
############*/

var JsNgram = new function(){

  /*############
  Properties:
    size: size of N-gram.
    indexBase: base url to refer N-gram index files.
    textBase: base url to refer text files.
    keySeparator: '/' for subdirectory keys, '-' for flat file keys.
    keyExt: file ext, such as '.json'.
    resultSelector: JQuery selector pointing result wrapper.
    errorSelector: JQuery selector pointing error message box.
    ajaxJson: JQuery ajax settings for json.
    ajaxText: JQuery ajax settings for text.
    work: structured data shared between callbacks while searching.
    verbose: level of verbosity to show debug information on console.
  ############*/

  var _verbose;

  Object.defineProperties(this, {
    "size": { value: 2, writable: true, configurable: true },
    "indexBase": { value: 'idx/', writable: true, configurable: true },
    "textBase": { value: 'txt/', writable: true, configurable: true },
    "keySeparator": { value: '/', writable: true, configurable: true },
    "keyExt": { value: '.json', writable: true, configurable: true },
    "resultSelector": { value: undefined, writable: true, configurable: true },
    "errorSelector": { value: undefined, writable: true, configurable: true },
    "ajaxJson": { value: {
                    dataType: 'json',
                    mimeType: 'text/plain; charset=utf8'
                  },
                  writable: true, configurable: true },
    "ajaxText": { value: {
                    dataType: 'text',
                    mimeType: 'text/plain; charset=utf8'
                  },
                  writable: true, configurable: true },
    "work": { value: {}, writable: true, configurable: true },
    "verbose": { get: function(){ return _verbose; },
                 set: function(verbose){
                   if(!(verbose in [0,1,2,3])) {
                     throw "verbose value is out of range.";
                   }
                   if(_verbose == verbose) { return; }
                   _verbose = verbose;
                   this.log = new Log(verbose);
                 },
                 configurable: true }
  });

  /*############
  inner Class: Log
    console logger with verbosity.
  ############*/

  function Log(verbose){
    function nop(){}
    function log(msg){ console.log.apply(null, arguments); }
    this.v0 = log;
    this.v1 = (verbose < 1) ? nop : log;
    this.v2 = (verbose < 2) ? nop : log;
    this.v3 = (verbose < 3) ? nop : log;
  }

  /*############
  kickup default logger (this.log) with verbose = 0
  ############*/
  this.verbose = 0;

  /*############
  Method: search(text)
    perform search on text and insert results in html.
  ############*/

  function search(text) {
    if(text == '') {
      this.log.v1('blank query text is ignored.');
      return;
    }
    this.clearErrorMessage();
    this.clearSearchResult();
    this.appendSearchResult(text);
  }
  this.search = search;

  /*############
  Method: showErrorMessage(msg)
    replace content of error box with msg.
  ############*/

  function showErrorMessage(msg) {
    this.errorSelector.text(msg);
  }
  this.showErrorMessage = showErrorMessage;

  /*############
  Method: clearErrorMessage()
    clear content of error box.
  ############*/

  function clearErrorMessage() {
    this.showErrorMessage('');
  }
  this.clearErrorMessage = clearErrorMessage;

  /*############
  Method: clearSearchResult()
    clear content of result wrapper.
  ############*/

  function clearSearchResult() {
    this.resultSelector.html('');
  }
  this.clearSearchResult = clearSearchResult;

  /*############
  Method: makeResultHtml(result)
    generate html for result.
  ############*/

  function makeResultHtml(result) {
    var tr = [];
    tr.push('
');
    tr.push(result.join('	'));
    tr.push('
');
    return(tr.join(''));
  }
  this.makeResultHtml = makeResultHtml;

  /*############
  Method: failMessageHandler(xhr, ajaxOptions, thrownError)
    handle the failure of ajax and show error message.
  ############*/

  function failMessageHandler(xhr, ajaxOptions, thrownError) {
    var msg =xhr.status + ' / ' + thrownError;
    var msg2 = this.url + ' / ' + msg;
    JsNgram.log.v0(msg2);
    JsNgram.showErrorMessage(msg2);
  }
  this.failMessageHandler = failMessageHandler;

  /*############
  Method: encodeKey(text)
    convert text into hex byte string array of unicode.
  ############*/

  function encodeKey(text) {
    return(
      this.cutString2by2(this.toUnicodeArray(text).join('')).join(this.keySeparator)
    );
  }
  this.encodeKey = encodeKey;

  /*############
  Method: toUnicodeArray(text)
    convert text into strictly 4 digit hex string array of unicode.
  ############*/

  function toUnicodeArray(text) {
    var encodedArr = [];
    for(var i = 0; i < text.length; i++) {
      var twoByte = ('0000' + text.charCodeAt(i).toString(16)).slice(-4);
      encodedArr.push(twoByte);
    }
    return(encodedArr);
  }
  this.toUnicodeArray = toUnicodeArray;

  /*############
  Method: cutString2by2(text)
    convert text into two by two character array.
  ############*/

  function cutString2by2(text) {
    var twoByTwo = [];
    for(var i = 0; i < text.length; i+=2) {
      twoByTwo.push(text.substr(i, 2));
    }
    return(twoByTwo);
  }
  this.cutString2by2 = cutString2by2;

  /*############
  Method: indexFileName(text)
    get json file name of index to find text.
  ############*/

  function indexFileName(text) {
    return(this.indexBase + this.encodeKey(text) + this.keyExt);
  }
  this.indexFileName = indexFileName;

  /*############
  Method: loadIndexFile(text)
    load index json file to find text.
  ############*/

  function loadIndexFile(text) {
    return($.ajax(this.indexFileName(text), this.ajaxJson).fail(this.failMessageHandler));
  }
  this.loadIndexFile = loadIndexFile;

  /*############
  Method: findPerfection(x, n)
    pick up perfect match from sorted result of N-gram partial matches.
    x: sorted result of match (by document)
    n: required count for perfect match
  ############*/

  function findPerfection(x, n) {
    var bag = [];
    var ids = Object.keys(x);
    for(var i = 0; i < ids.length; i++) { // loop by document
      var xx = x[ids[i]];
      var seqs = Object.keys(xx);  // N-gram keys in the current document
      if(seqs.length < n) { continue; }  // at least, should have all keys.

      // find a key that has minimum occurrences.
      // this will help performance.
      var mini = -1;
      var miniLength = Number.MAX_SAFE_INTEGER;
      for(var j = 0; j < n; j++) {
        if(xx[j].length < miniLength) {
          miniLength = xx[j].length;
          mini = j;
        }
      }

      // loop by occurence at mini.
      var xxx = xx[mini];
      for(var k = 0; k < xxx.length; k++) {
        var p = xxx[k] - mini;  // valid sequences have same p values.
        for(var j = 0; j < n; j++) {
          if(j == mini) { continue; }
          var q = xx[j].indexOf(p + j);
          if(q == -1) { break; }  // not valid
        }
        if(j == n) { // valid
          bag.push([ids[i], p]);
        }
      }
    }
    return(bag);
  }
  this.findPerfection = findPerfection;

  /*############
  Method: startWork(what)
    start up with the property work.
  ############*/

  function startWork(what) {
    //clearWork();
    var work = {};
    work['what'] = what;
    work['nWhat'] = what.length;
    work['nGram'] = this.size;
    work['nIter'] = work['nWhat'] - work['nGram'] + 1;
    work['texts'] = this.generateTexts(work);
    work['nText'] = work['texts'].length;
    work['deferred'] = this.generateDeferred(work);
    // the last one submits multiple ajax requests.
    return(work);
  }
  this.startWork = startWork;

  /*############
  Method: clearWork()
    clear the property work.
  ############*/

  function clearWork() {
    this.work = {};
  }
  this.clearWork = clearWork;

  /*############
  Method: generateTexts(work)
    generate N-gram splitted keyword texts as array.
  ############*/

  function generateTexts(work) {
    var texts = [];
    // single character (or shoter than N-gram size) text
    // will not go into this loop.
    for(var i = 0; i < work['nIter']; i++) {
      texts.push(work['what'].substr(i, work['nGram']));
    }

    // for a short word
    if(work['nWhat'] < work['nGram']) {
      texts.push(work['what']);
      this.log.v1('adjusted: ', texts);
    }
    return(texts);
  }
  this.generateTexts = generateTexts;

  /*############
  Method: generateDeferred(work)
    generate ajax request array for each N-gram keyword after submit.
  ############*/

  function generateDeferred(work) {
    var deferred = [];
    for(var i = 0; i < work['nText']; i++) {
      deferred.push(this.loadIndexFile(work['texts'][i]));
    }
    return(deferred);
  }
  this.generateDeferred = generateDeferred;

  /*############
  Method: whenSearchRequestDone(useArgumentsToGetAllAsArray)
    integrate multiple ajax results of N-gram search.
  ############*/

  function whenSearchRequestDone(useArgumentsToGetAllAsArray) {
      var results = arguments;
      var work = JsNgram['work'];
      var log = JsNgram.log;

      if(work['deferred'].length == 1) { // adjust nesting level
        results = [results];
      }
      log.v1('whole: ', results.length, results);
      found = {}; // gather results by location.
      $.each(results, function(j, result){
        log.v1('j=', j, result);
        if(result == undefined) {
          log.v0('result is undefined. means ajax success with empty result.');
          return(true);
        }
        // result is [data, status_text, jqXHR_object]
        $.each(result[0], function(i, val){
          log.v1('i=', i, val);

          var docId = val[0];
          var pos = val[1];
          if(!(docId in found)) {
            found[docId] = {};
          }
          if(!(j in found[docId])) {
            found[docId][j] = [];
          }
          found[docId][j].push(pos);

          strVal = JSON.stringify(val);
          log.v1(val[0]);
          var x = cheat[val[0]];
          var xx = [x.substr(0, val[1]), '', x.substr(val[1], work['nGram']), '', x.substring(val[1] + work['nGram'], x.length)];
          $('#result').append(JsNgram.makeResultHtml([work['what'], strVal, xx.join('')]));
        });
      });

      log.v1(JSON.stringify(found));
      var perfection = JsNgram.findPerfection(found, work['nText']);
      log.v1(JSON.stringify(perfection));

      for(var k = 0; k < perfection.length; k++) {
        var val = perfection[k];
        var x = cheat[val[0]];
        var xx = [x.substr(0, val[1]), '', x.substr(val[1], work['nWhat']), '', x.substring(val[1] + work['nWhat'], x.length)];
        JsNgram.resultSelector.append(JsNgram.makeResultHtml(['*', JSON.stringify(val), xx.join('')]));
      }

  }
  this.whenSearchRequestDone = whenSearchRequestDone;

/**/
  var cheat = {
    '/a': "私たちは、もっとも始めに、この文書 a を追加してみます。",
    '/b': '2つ目はもっともっとおもしろいよ、ね。'
  };
/**/
  /*############
  Method: appendSearchResult(what)
    perform search and show result.
  ############*/

  function appendSearchResult(what) {
    this['work'] = this.startWork(what);
    // wait until all ajax requests done.
    $.when.apply($, this['work']['deferred']).done(whenSearchRequestDone);
  }
  this.appendSearchResult = appendSearchResult;

};

/* enable this when you wish to run within Node.js ...
return(JsNgram);
});
*/
<commit_msg>improve result processor<commit_after>// N-gram full text search client module
// https://github.com/sukuba/js-py-ngram-full-text-search

/*############
require JQuery
############*/

/* enable this when you wish to run within Node.js ...
define(function(){
*/

/*############
Namespace: JsNgram
  without Node.js, this will create a global entry point JsNgram.
############*/

var JsNgram = new function(){

  /*############
  Properties:
    size: size of N-gram.
    indexBase: base url to refer N-gram index files.
    textBase: base url to refer text files.
    keySeparator: '/' for subdirectory keys, '-' for flat file keys.
    keyExt: file ext, such as '.json'.
    resultSelector: JQuery selector pointing result wrapper.
    errorSelector: JQuery selector pointing error message box.
    ajaxJson: JQuery ajax settings for json.
    ajaxText: JQuery ajax settings for text.
    work: structured data shared between callbacks while searching.
    verbose: level of verbosity to show debug information on console.
  ############*/

  var _verbose;

  Object.defineProperties(this, {
    "size": { value: 2, writable: true, configurable: true },
    "indexBase": { value: 'idx/', writable: true, configurable: true },
    "textBase": { value: 'txt/', writable: true, configurable: true },
    "keySeparator": { value: '/', writable: true, configurable: true },
    "keyExt": { value: '.json', writable: true, configurable: true },
    "resultSelector": { value: undefined, writable: true, configurable: true },
    "errorSelector": { value: undefined, writable: true, configurable: true },
    "ajaxJson": { value: {
                    dataType: 'json',
                    mimeType: 'text/plain; charset=utf8'
                  },
                  writable: true, configurable: true },
    "ajaxText": { value: {
                    dataType: 'text',
                    mimeType: 'text/plain; charset=utf8'
                  },
                  writable: true, configurable: true },
    "work": { value: {}, writable: true, configurable: true },
    "verbose": { get: function(){ return _verbose; },
                 set: function(verbose){
                   if(!(verbose in [0,1,2,3])) {
                     throw "verbose value is out of range.";
                   }
                   if(_verbose == verbose) { return; }
                   _verbose = verbose;
                   this.log = new Log(verbose);
                 },
                 configurable: true }
  });

  /*############
  inner Class: Log
    console logger with verbosity.
  ############*/

  function Log(verbose){
    function nop(){}
    function log(msg){ console.log.apply(null, arguments); }
    this.v0 = log;
    this.v1 = (verbose < 1) ? nop : log;
    this.v2 = (verbose < 2) ? nop : log;
    this.v3 = (verbose < 3) ? nop : log;
  }

  /*############
  kickup default logger (this.log) with verbose = 0
  ############*/
  this.verbose = 0;

  /*############
  Method: search(text)
    perform search on text and insert results in html.
  ############*/

  function search(text) {
    if(text == '') {
      this.log.v1('blank query text is ignored.');
      return;
    }
    this.clearErrorMessage();
    this.clearSearchResult();
    this.appendSearchResult(text);
  }
  this.search = search;

  /*############
  Method: showErrorMessage(msg)
    replace content of error box with msg.
  ############*/

  function showErrorMessage(msg) {
    this.errorSelector.text(msg);
  }
  this.showErrorMessage = showErrorMessage;

  /*############
  Method: clearErrorMessage()
    clear content of error box.
  ############*/

  function clearErrorMessage() {
    this.showErrorMessage('');
  }
  this.clearErrorMessage = clearErrorMessage;

  /*############
  Method: clearSearchResult()
    clear content of result wrapper.
  ############*/

  function clearSearchResult() {
    this.resultSelector.html('');
  }
  this.clearSearchResult = clearSearchResult;

  /*############
  Method: makeResultHtml(result)
    generate html for result.
  ############*/

  function makeResultHtml(result) {
    var tr = [];
    tr.push('
');
    tr.push(result.join('	'));
    tr.push('
');
    return(tr.join(''));
  }
  this.makeResultHtml = makeResultHtml;

  /*############
  Method: makeTextHilighted(text, at, hiLen, outLen)
    generate html with text hilighted.
  ############*/

  function makeTextHilighted(text, at, hiLen, outLen) {
    var outLen = typeof outLen !== 'undefined' ? outLen : 100;
    // ES6 can default value with 'outLen=100', but be conservative.

    var start = at - Math.floor((outLen - hiLen) / 2);
    if(start < 0) { start = 0; }
    var x = text.substr(start, outLen);
    var pos = at - start;
    var xx = [x.substr(0, pos), '', x.substr(pos, hiLen), '', x.substring(pos + hiLen, outLen)];
    return(xx.join(''));
  }
  this.makeTextHilighted = makeTextHilighted;

  /*############
  Method: failMessageHandler(xhr, ajaxOptions, thrownError)
    handle the failure of ajax and show error message.
  ############*/

  function failMessageHandler(xhr, ajaxOptions, thrownError) {
    var msg =xhr.status + ' / ' + thrownError;
    var msg2 = this.url + ' / ' + msg;
    JsNgram.log.v0(msg2);
    JsNgram.showErrorMessage(msg2);
  }
  this.failMessageHandler = failMessageHandler;

  /*############
  Method: encodeKey(text)
    convert text into hex byte string array of unicode.
  ############*/

  function encodeKey(text) {
    return(
      this.cutString2by2(this.toUnicodeArray(text).join('')).join(this.keySeparator)
    );
  }
  this.encodeKey = encodeKey;

  /*############
  Method: toUnicodeArray(text)
    convert text into strictly 4 digit hex string array of unicode.
  ############*/

  function toUnicodeArray(text) {
    var encodedArr = [];
    for(var i = 0; i < text.length; i++) {
      var twoByte = ('0000' + text.charCodeAt(i).toString(16)).slice(-4);
      encodedArr.push(twoByte);
    }
    return(encodedArr);
  }
  this.toUnicodeArray = toUnicodeArray;

  /*############
  Method: cutString2by2(text)
    convert text into two by two character array.
  ############*/

  function cutString2by2(text) {
    var twoByTwo = [];
    for(var i = 0; i < text.length; i+=2) {
      twoByTwo.push(text.substr(i, 2));
    }
    return(twoByTwo);
  }
  this.cutString2by2 = cutString2by2;

  /*############
  Method: indexFileName(text)
    get json file name of index to find text.
  ############*/

  function indexFileName(text) {
    return(this.indexBase + this.encodeKey(text) + this.keyExt);
  }
  this.indexFileName = indexFileName;

  /*############
  Method: loadIndexFile(text)
    load index json file to find text.
  ############*/

  function loadIndexFile(text) {
    return($.ajax(this.indexFileName(text), this.ajaxJson).fail(this.failMessageHandler));
  }
  this.loadIndexFile = loadIndexFile;

  /*############
  Method: findPerfection(x, n)
    pick up perfect match from sorted result of N-gram partial matches.
    x: sorted result of match (by document)
    n: required count for perfect match
  ############*/

  function findPerfection(x, n) {
    var bag = [];
    var ids = Object.keys(x);
    for(var i = 0; i < ids.length; i++) { // loop by document
      var xx = x[ids[i]];
      var seqs = Object.keys(xx);  // N-gram keys in the current document
      if(seqs.length < n) { continue; }  // at least, should have all keys.

      // find a key that has minimum occurrences.
      // this will help performance.
      var mini = -1;
      var miniLength = Number.MAX_SAFE_INTEGER;
      for(var j = 0; j < n; j++) {
        if(xx[j].length < miniLength) {
          miniLength = xx[j].length;
          mini = j;
        }
      }

      // loop by occurence at mini.
      var xxx = xx[mini];
      for(var k = 0; k < xxx.length; k++) {
        var p = xxx[k] - mini;  // valid sequences have same p values.
        for(var j = 0; j < n; j++) {
          if(j == mini) { continue; }
          var q = xx[j].indexOf(p + j);
          if(q == -1) { break; }  // not valid
        }
        if(j == n) { // valid
          bag.push([ids[i], p]);
        }
      }
    }
    return(bag);
  }
  this.findPerfection = findPerfection;

  /*############
  Method: startWork(what)
    start up with the property work.
  ############*/

  function startWork(what) {
    //clearWork();
    var work = {};
    work['what'] = what;
    work['nWhat'] = what.length;
    work['nGram'] = this.size;
    work['nIter'] = work['nWhat'] - work['nGram'] + 1;
    work['texts'] = this.generateTexts(work);
    work['nText'] = work['texts'].length;
    work['deferred'] = this.generateDeferred(work);
    // the last one submits multiple ajax requests.
    return(work);
  }
  this.startWork = startWork;

  /*############
  Method: clearWork()
    clear the property work.
  ############*/

  function clearWork() {
    this.work = {};
  }
  this.clearWork = clearWork;

  /*############
  Method: generateTexts(work)
    generate N-gram splitted keyword texts as array.
  ############*/

  function generateTexts(work) {
    var texts = [];
    // single character (or shoter than N-gram size) text
    // will not go into this loop.
    for(var i = 0; i < work['nIter']; i++) {
      texts.push(work['what'].substr(i, work['nGram']));
    }

    // for a short word
    if(work['nWhat'] < work['nGram']) {
      texts.push(work['what']);
      this.log.v1('adjusted: ', texts);
    }
    return(texts);
  }
  this.generateTexts = generateTexts;

  /*############
  Method: generateDeferred(work)
    generate ajax request array for each N-gram keyword after submit.
  ############*/

  function generateDeferred(work) {
    var deferred = [];
    for(var i = 0; i < work['nText']; i++) {
      deferred.push(this.loadIndexFile(work['texts'][i]));
    }
    return(deferred);
  }
  this.generateDeferred = generateDeferred;

  /*############
  Method: loadFullText(id)
    load full text at id (url).
  ############*/

  function loadFullText(id) {
/**/
  var cheat = {
    '/a': "私たちは、もっとも始めに、この文書 a を追加してみます。",
    '/b': '2つ目はもっともっとおもしろいよ、ね。'
  };
/**/
    var text;
    text = cheat[id];
    return(text);
  }
  this.loadFullText = loadFullText;

  /*############
  Method: whenSearchRequestDone(useArgumentsToGetAllAsArray)
    integrate multiple ajax results of N-gram search.
  ############*/

  function whenSearchRequestDone(useArgumentsToGetAllAsArray) {
      var results = arguments;
      var work = JsNgram['work'];
      var log = JsNgram.log;

      if(work['deferred'].length == 1) { // adjust nesting level
        results = [results];
      }
      log.v1('whole: ', results.length, results);
      found = {}; // gather results by location.
      $.each(results, function(j, result){
        log.v1('j=', j, result);
        if(result == undefined) {
          log.v0('result is undefined. means ajax success with empty result.');
          return(true);
        }
        // result is [data, status_text, jqXHR_object]
        $.each(result[0], function(i, val){
          log.v1('i=', i, val);

          var docId = val[0];
          var pos = val[1];
          if(!(docId in found)) {
            found[docId] = {};
          }
          if(!(j in found[docId])) {
            found[docId][j] = [];
          }
          found[docId][j].push(pos);

          strVal = JSON.stringify(val);
          log.v1(val[0]);
          var x = JsNgram.loadFullText(val[0]);
          //var xx = [x.substr(0, val[1]), '', x.substr(val[1], work['nGram']), '', x.substring(val[1] + work['nGram'], x.length)];
          var xx = JsNgram.makeTextHilighted(x, val[1], work['nGram']);
          $('#result').append(JsNgram.makeResultHtml([work['what'], strVal, xx]));
        });
      });

      log.v1(JSON.stringify(found));
      var perfection = JsNgram.findPerfection(found, work['nText']);
      log.v1(JSON.stringify(perfection));

      for(var k = 0; k < perfection.length; k++) {
        var val = perfection[k];
        var x = JsNgram.loadFullText(val[0]);
        //var xx = [x.substr(0, val[1]), '', x.substr(val[1], work['nWhat']), '', x.substring(val[1] + work['nWhat'], x.length)];
        var xx = JsNgram.makeTextHilighted(x, val[1], work['nWhat']);
        JsNgram.resultSelector.append(JsNgram.makeResultHtml(['*', JSON.stringify(val), xx]));
      }

  }
  this.whenSearchRequestDone = whenSearchRequestDone;

  /*############
  Method: appendSearchResult(what)
    perform search and show result.
  ############*/

  function appendSearchResult(what) {
    this['work'] = this.startWork(what);
    // wait until all ajax requests done.
    $.when.apply($, this['work']['deferred']).done(whenSearchRequestDone);
  }
  this.appendSearchResult = appendSearchResult;

};

/* enable this when you wish to run within Node.js ...
return(JsNgram);
});
*/
<|endoftext|>


<commit_before>#!/usr/bin/env node
const { MONGODB: DB, ES } = process.env
const child_process = require('child_process')
const fs = require('fs')
const mongoose = require('mongoose')
mongoose.Promise = global.Promise
const elasticsearch = require('elasticsearch')
let es = new elasticsearch.Client({
  host: ES
})
let db = mongoose.createConnection(DB)

db.on('error', err => {
  console.error(err)
  process.exit(1)
})
db.on('open', () => {
  require('./lib/dbModel.js')(db, es).then(({PastPaperDoc, PastPaperPaperBlob}) => {
    PastPaperDoc.find({}).cursor().eachAsync(async function (doc) {
      try {
        console.log('Processing ' + doc._id)
        let pdfBlob = await doc.getFileBlob()
        let newBlob = null
        newBlob = await doOptimize(pdfBlob)
        doc.fileBlob = null
        await PastPaperPaperBlob.remove({docId: doc._id})
        let chunkSize = 10 * 1024 * 1024
        for (let off = 0; off < newBlob.length; off += chunkSize) {
          let slice = newBlob.slice(off, off + chunkSize)
          let dbBlobFrag = new PastPaperPaperBlob({
            docId: doc._id,
            offset: off,
            data: slice
          })
          await dbBlobFrag.save()
        }
        await doc.save()
      } catch (e) {
        process.stderr.write(`Error when processing ${doc._id}: ${e.toString()}\n`)
        return
      }
    }).then(() => {
      process.exit()
    })
  }, err => {
    console.error(err)
    process.exit(1)
  })
})

function doOptimize (pdfBlob) {
  return new Promise((resolve, reject) => {
    // For some reason if we want gs to write to any file in /dev/fd, it segfaults.
    // let cp = child_process.spawn('gs',
    //                              ['-sDEVICE=pdfwrite', '-dFastWebView', '-dNOPAUSE', '-dBATCH', '-sOutputFile=| cat - >&3', '-'],
    //                              {
    //                                cwd: '/tmp/',
    //                                stdio: [
    //                                  'pipe', // input from stdin
    //                                  'inherit', // stdout
    //                                  'inherit', // stderr
    //                                  'pipe' // fd=3 as pipe
    //                                ]
    //                              })
    // let [sI, _, _2, sO] = cp.stdio
    // let receivedBytes = 0
    // let outBuffer = Buffer.allocUnsafe(1000)
    // sO.on('data', data => {
    //   if (receivedBytes + data.length <= outBuffer.length) {
    //     let len = data.copy(outBuffer, receivedBytes)
    //     receivedBytes += len
    //   } else {
    //     let allocNewSize = Math.max(outBuffer.length * 2, receivedBytes + data.length)
    //     let newBuffer = Buffer.allocUnsafe(allocNewSize)
    //     outBuffer.copy(newBuffer, 0, 0, receivedBytes)
    //     delete outBuffer
    //     outBuffer = newBuffer
    //     let len = data.copy(outBuffer, receivedBytes)
    //     receivedBytes += len
    //   }
    // })
    // let exitCode = null
    // let readDone = false
    // let done = false
    // sO.on('end', () => {
    //   if (exitCode !== null) {
    //     finish()
    //   } else {
    //     readDone = true
    //   }
    // })
    let cp = child_process.spawn('gs',
                                 ['-sDEVICE=pdfwrite', '-dFastWebView', '-dNOPAUSE', '-dBATCH', '-sOutputFile=/tmp/optimize_pdfjs_tmpout.pdf', '-'],
                                 {
                                   cwd: '/tmp/',
                                   stdio: [
                                     'pipe', 'inherit', 'inherit'
                                   ]
                                })
    let sI = cp.stdin
    let done = false
    cp.on('exit', (code, sig) => {
      if (done) return
      if (code === null && sig !== null) {
        done = true
        reject(new Error(`Process killed because ${sig}`))
      }
      if (code !== null && code !== 0) {
        done = true
        reject(new Error(`Process exited with code ${code}`))
      }
      finish()
    })
    cp.on('error', err => {
      if (done) return
      done = true
      reject(err)
    })
    sI.on('error', err => {
      if (done) return
      done = true
      reject(err)
    })
    sI.end(pdfBlob)
    function finish () {
      if (done) return
      done = true
      fs.readFile('/tmp/optimize_pdfjs_tmpout.pdf', {encoding: null, flag: 'r'}, (err, data) => {
        if (err) {
          reject(err)
        } else {
          resolve(data)
        }
      })
    }
  })
}
<commit_msg>Check if doc already optimized<commit_after>#!/usr/bin/env node
const { MONGODB: DB, ES } = process.env
const child_process = require('child_process')
const fs = require('fs')
const mongoose = require('mongoose')
mongoose.Promise = global.Promise
const elasticsearch = require('elasticsearch')
let es = new elasticsearch.Client({
  host: ES
})
let db = mongoose.createConnection(DB)

db.on('error', err => {
  console.error(err)
  process.exit(1)
})
db.on('open', () => {
  require('./lib/dbModel.js')(db, es).then(({PastPaperDoc, PastPaperPaperBlob}) => {
    PastPaperDoc.find({}).cursor().eachAsync(async function (doc) {
      try {
        console.log('Processing ' + doc._id)
        if (doc.gs_optimized) {
          return
        }
        let pdfBlob = await doc.getFileBlob()
        let newBlob = null
        newBlob = await doOptimize(pdfBlob)
        doc.fileBlob = null
        await PastPaperPaperBlob.remove({docId: doc._id})
        let chunkSize = 10 * 1024 * 1024
        for (let off = 0; off < newBlob.length; off += chunkSize) {
          let slice = newBlob.slice(off, off + chunkSize)
          let dbBlobFrag = new PastPaperPaperBlob({
            docId: doc._id,
            offset: off,
            data: slice
          })
          await dbBlobFrag.save()
        }
        doc.set('gs_optimized', true)
        await doc.save()
      } catch (e) {
        process.stderr.write(`Error when processing ${doc._id}: ${e.toString()}\n`)
        return
      }
    }).then(() => {
      process.exit()
    })
  }, err => {
    console.error(err)
    process.exit(1)
  })
})

function doOptimize (pdfBlob) {
  return new Promise((resolve, reject) => {
    // For some reason if we want gs to write to any file in /dev/fd, it segfaults.
    // let cp = child_process.spawn('gs',
    //                              ['-sDEVICE=pdfwrite', '-dFastWebView', '-dNOPAUSE', '-dBATCH', '-sOutputFile=| cat - >&3', '-'],
    //                              {
    //                                cwd: '/tmp/',
    //                                stdio: [
    //                                  'pipe', // input from stdin
    //                                  'inherit', // stdout
    //                                  'inherit', // stderr
    //                                  'pipe' // fd=3 as pipe
    //                                ]
    //                              })
    // let [sI, _, _2, sO] = cp.stdio
    // let receivedBytes = 0
    // let outBuffer = Buffer.allocUnsafe(1000)
    // sO.on('data', data => {
    //   if (receivedBytes + data.length <= outBuffer.length) {
    //     let len = data.copy(outBuffer, receivedBytes)
    //     receivedBytes += len
    //   } else {
    //     let allocNewSize = Math.max(outBuffer.length * 2, receivedBytes + data.length)
    //     let newBuffer = Buffer.allocUnsafe(allocNewSize)
    //     outBuffer.copy(newBuffer, 0, 0, receivedBytes)
    //     delete outBuffer
    //     outBuffer = newBuffer
    //     let len = data.copy(outBuffer, receivedBytes)
    //     receivedBytes += len
    //   }
    // })
    // let exitCode = null
    // let readDone = false
    // let done = false
    // sO.on('end', () => {
    //   if (exitCode !== null) {
    //     finish()
    //   } else {
    //     readDone = true
    //   }
    // })
    let cp = child_process.spawn('gs',
                                 ['-sDEVICE=pdfwrite', '-dFastWebView', '-dNOPAUSE', '-dBATCH', '-sOutputFile=/tmp/optimize_pdfjs_tmpout.pdf', '-'],
                                 {
                                   cwd: '/tmp/',
                                   stdio: [
                                     'pipe', 'inherit', 'inherit'
                                   ]
                                })
    let sI = cp.stdin
    let done = false
    cp.on('exit', (code, sig) => {
      if (done) return
      if (code === null && sig !== null) {
        done = true
        reject(new Error(`Process killed because ${sig}`))
      }
      if (code !== null && code !== 0) {
        done = true
        reject(new Error(`Process exited with code ${code}`))
      }
      finish()
    })
    cp.on('error', err => {
      if (done) return
      done = true
      reject(err)
    })
    sI.on('error', err => {
      if (done) return
      done = true
      reject(err)
    })
    sI.end(pdfBlob)
    function finish () {
      if (done) return
      done = true
      fs.readFile('/tmp/optimize_pdfjs_tmpout.pdf', {encoding: null, flag: 'r'}, (err, data) => {
        if (err) {
          reject(err)
        } else {
          resolve(data)
        }
      })
    }
  })
}
<|endoftext|>


<commit_before>/**
 * @class CM_Form_Abstract
 * @extends CM_View_Abstract
 */
var CM_Form_Abstract = CM_View_Abstract.extend({
  _class: 'CM_Form_Abstract',

  /** @type Object **/
  _fields: {},

  /** @type Object **/
  _actions: {},

  /** @type Boolean **/
  _stopErrorPropagation: false,

  initialize: function() {
    CM_View_Abstract.prototype.initialize.call(this);

    this._fields = {};
    this._actions = {};
  },

  events: {
    'reset': function() {
      _.each(this._fields, function(field) {
        field.reset();
      });
      this.resetErrors();
    }
  },

  ready: function() {
  },

  _ready: function() {
    var handler = this;

    _.each(this._actions, function(action, name) {
      var $btn = $('#' + this.getAutoId() + '-' + name + '-button');
      var event = $btn.data('event');
      if (!event) {
        event = 'click';
      }
      $btn.on(event, {action: name}, function(event) {
        event.preventDefault();
        event.stopPropagation();
        return handler.submit(event.data.action).catch(CM_Exception_FormFieldValidation, function(error) {
          // this error type is already handled and displayed in `submit`
        });
      });
    }, this);

    this.$el.on('submit', function() {
      handler.$el.find('input[type="submit"], button[type="submit"]').first().click();
      return false;
    });

    CM_View_Abstract.prototype._ready.call(this);
  },

  /**
   * @param {CM_FormField_Abstract} field
   */
  registerField: function(field) {
    this._fields[field.getName()] = field;

    field.on('change', function() {
      this.trigger('change');
    }, this);
  },

  /**
   * @param {String} name
   * @param {Object} presentation
   */
  registerAction: function(name, presentation) {
    this._actions[name] = presentation;
  },

  /**
   * @return CM_FormField_Abstract
   */
  getField: function(name) {
    if (!this._fields[name]) {
      throw new CM_Exception(this.getClass() + ' cannot find form field `' + name + '`');
    }
    return this._fields[name];
  },

  /**
   * @return Boolean
   */
  hasField: function(name) {
    return !!this._fields[name];
  },

  /**
   * @return jQuery
   */
  $: function(selector) {
    if (!selector) {
      return this.$el;
    }
    selector = selector.replace('#', '#' + this.getAutoId() + '-');
    return $(selector, this.el);
  },

  /**
   * @returns {String[]}
   */
  getFieldNames: function() {
    return _.keys(this._fields);
  },

  /**
   * @returns {CM_FormField_Abstract[]}
   */
  getFields: function() {
    return _.values(this._fields);
  },

  /**
   * @returns {{}}
   */
  getData: function() {
    var data = {};
    _.each(this._fields, function(field) {
      if (field.getEnabled()) {
        data[field.getName()] = field.getValue();
      }
    });
    return data;
  },

  /**
   * @param {String} actionName
   * @returns {{}}
   */
  getActionData: function(actionName) {
    var action = this._getAction(actionName);
    var data = {};

    _.each(action.fields, function(isRequired, fieldName) {
      if (this.hasField(fieldName)) {
        var field = this.getField(fieldName);
        if (field.getEnabled()) {
          data[field.getName()] = field.getValue();
        }
      }
    }, this);

    return data;
  },

  /**
   * @param {String} [actionName]
   * @param {Object} [options]
   * @return Promise
   */
  submit: function(actionName, options) {
    options = _.defaults(options || {}, {
      handleErrors: true,
      disableUI: true
    });
    var action = this._getAction(actionName);
    var data = this.getActionData(action.name);
    var errorList = this._getErrorList(action.name, data);

    if (options.handleErrors) {
      _.each(this._fields, function(field, fieldName) {
        if (errorList[fieldName]) {
          field.error(errorList[fieldName]);
        } else {
          field.error(null);
        }
      }, this);
    }

    if (_.size(errorList)) {
      return Promise.reject(new CM_Exception_FormFieldValidation(errorList));
    } else {
      if (options.disableUI) {
        this.disable();
      }
      this.trigger('submit', [data]);

      var handler = this;
      return cm.ajax('form', {viewInfoList: this.getViewInfoList(), actionName: action.name, data: data})
        .then(function(response) {
          if (response.errors) {
            if (options.handleErrors) {
              for (var i = response.errors.length - 1, error; error = response.errors[i]; i--) {
                if (_.isArray(error)) {
                  handler.getField(error[1]).error(error[0]);
                } else {
                  handler.error(error);
                }
              }
            }

            throw new CM_Exception_FormFieldValidation(response.errors);
          }

          if (response.exec) {
            handler.evaluation = new Function(response.exec);
            handler.evaluation();
          }

          if (response.messages) {
            for (var i = 0, msg; msg = response.messages[i]; i++) {
              handler.message(msg);
            }
          }

          handler.trigger('success success.' + action.name, response.data);
          return response.data;
        })
        .catch(CM_Exception_FormFieldValidation, function(error) {
          handler._stopErrorPropagation = false;
          handler.trigger('error error.' + action.name, error.message, error.name, error.isPublic);
          if (!handler._stopErrorPropagation) {
            throw error;
          }
        })
        .finally(function() {
          if (options.disableUI) {
            handler.enable();
          }
          handler.trigger('complete');
        });
    }
  },

  stopErrorPropagation: function() {
    this._stopErrorPropagation = true;
  },

  reset: function() {
    this.el.reset();
  },

  disable: function() {
    this.$().disable();
  },

  enable: function() {
    this.$().enable();
  },

  /**
   * @param {String} message
   */
  error: function(message) {
    cm.window.hint(message);
  },

  /**
   * @param {String} message
   */
  message: function(message) {
    cm.window.hint(message);
  },

  resetErrors: function() {
    _.each(this._fields, function(field) {
      field.error(null);
    });
  },

  /**
   * @param {String} actionName
   * @returns {Object}
   */
  _getAction: function(actionName) {
    var action = this._actions[actionName];
    if (!action) {
      throw new CM_Exception('Form `' + this.getClass() + '` has no action `' + actionName + '`.');
    }
    action.name = actionName;
    return action;
  },

  /**
   * @param {String} actionName
   * @param {Object} data
   * @returns {Object}
   */
  _getErrorList: function(actionName, data) {
    var action = this._getAction(actionName);
    var errorList = {};

    _.each(action.fields, function(isRequired, fieldName) {
      if (isRequired) {
        var field = this.getField(fieldName);
        if (field.isEmpty(data[fieldName])) {
          var label = this._getFieldLabel(field);
          if (label) {
            errorList[fieldName] = cm.language.get('{$label} is required.', {label: label});
          } else {
            errorList[fieldName] = cm.language.get('Required');
          }
        }
      }
    }, this);

    return errorList;
  },

  /**
   * @param {CM_FormField_Abstract} field
   * @returns {String|null}
   * @private
   */
  _getFieldLabel: function(field) {
    var $labels = this.$('label[for="' + field.getAutoId() + '-input"]');
    if ($labels.length) {
      return $labels.first().text();
    }
    if (field.getInput().attr('placeholder')) {
      return field.getInput().attr('placeholder');
    }
    return null;
  }
});
<commit_msg>Trigger "reset" event on forms<commit_after>/**
 * @class CM_Form_Abstract
 * @extends CM_View_Abstract
 */
var CM_Form_Abstract = CM_View_Abstract.extend({
  _class: 'CM_Form_Abstract',

  /** @type Object **/
  _fields: {},

  /** @type Object **/
  _actions: {},

  /** @type Boolean **/
  _stopErrorPropagation: false,

  initialize: function() {
    CM_View_Abstract.prototype.initialize.call(this);

    this._fields = {};
    this._actions = {};
  },

  events: {
    'reset': function() {
      _.each(this._fields, function(field) {
        field.reset();
      });
      this.resetErrors();
    }
  },

  ready: function() {
  },

  _ready: function() {
    var handler = this;

    _.each(this._actions, function(action, name) {
      var $btn = $('#' + this.getAutoId() + '-' + name + '-button');
      var event = $btn.data('event');
      if (!event) {
        event = 'click';
      }
      $btn.on(event, {action: name}, function(event) {
        event.preventDefault();
        event.stopPropagation();
        return handler.submit(event.data.action).catch(CM_Exception_FormFieldValidation, function(error) {
          // this error type is already handled and displayed in `submit`
        });
      });
    }, this);

    this.$el.on('submit', function() {
      handler.$el.find('input[type="submit"], button[type="submit"]').first().click();
      return false;
    });

    this.$el.on('reset', function() {
      _.defer(function() {
        handler.trigger('reset');
      });
    });

    CM_View_Abstract.prototype._ready.call(this);
  },

  /**
   * @param {CM_FormField_Abstract} field
   */
  registerField: function(field) {
    this._fields[field.getName()] = field;

    field.on('change', function() {
      this.trigger('change');
    }, this);
  },

  /**
   * @param {String} name
   * @param {Object} presentation
   */
  registerAction: function(name, presentation) {
    this._actions[name] = presentation;
  },

  /**
   * @return CM_FormField_Abstract
   */
  getField: function(name) {
    if (!this._fields[name]) {
      throw new CM_Exception(this.getClass() + ' cannot find form field `' + name + '`');
    }
    return this._fields[name];
  },

  /**
   * @return Boolean
   */
  hasField: function(name) {
    return !!this._fields[name];
  },

  /**
   * @return jQuery
   */
  $: function(selector) {
    if (!selector) {
      return this.$el;
    }
    selector = selector.replace('#', '#' + this.getAutoId() + '-');
    return $(selector, this.el);
  },

  /**
   * @returns {String[]}
   */
  getFieldNames: function() {
    return _.keys(this._fields);
  },

  /**
   * @returns {CM_FormField_Abstract[]}
   */
  getFields: function() {
    return _.values(this._fields);
  },

  /**
   * @returns {{}}
   */
  getData: function() {
    var data = {};
    _.each(this._fields, function(field) {
      if (field.getEnabled()) {
        data[field.getName()] = field.getValue();
      }
    });
    return data;
  },

  /**
   * @param {String} actionName
   * @returns {{}}
   */
  getActionData: function(actionName) {
    var action = this._getAction(actionName);
    var data = {};

    _.each(action.fields, function(isRequired, fieldName) {
      if (this.hasField(fieldName)) {
        var field = this.getField(fieldName);
        if (field.getEnabled()) {
          data[field.getName()] = field.getValue();
        }
      }
    }, this);

    return data;
  },

  /**
   * @param {String} [actionName]
   * @param {Object} [options]
   * @return Promise
   */
  submit: function(actionName, options) {
    options = _.defaults(options || {}, {
      handleErrors: true,
      disableUI: true
    });
    var action = this._getAction(actionName);
    var data = this.getActionData(action.name);
    var errorList = this._getErrorList(action.name, data);

    if (options.handleErrors) {
      _.each(this._fields, function(field, fieldName) {
        if (errorList[fieldName]) {
          field.error(errorList[fieldName]);
        } else {
          field.error(null);
        }
      }, this);
    }

    if (_.size(errorList)) {
      return Promise.reject(new CM_Exception_FormFieldValidation(errorList));
    } else {
      if (options.disableUI) {
        this.disable();
      }
      this.trigger('submit', [data]);

      var handler = this;
      return cm.ajax('form', {viewInfoList: this.getViewInfoList(), actionName: action.name, data: data})
        .then(function(response) {
          if (response.errors) {
            if (options.handleErrors) {
              for (var i = response.errors.length - 1, error; error = response.errors[i]; i--) {
                if (_.isArray(error)) {
                  handler.getField(error[1]).error(error[0]);
                } else {
                  handler.error(error);
                }
              }
            }

            throw new CM_Exception_FormFieldValidation(response.errors);
          }

          if (response.exec) {
            handler.evaluation = new Function(response.exec);
            handler.evaluation();
          }

          if (response.messages) {
            for (var i = 0, msg; msg = response.messages[i]; i++) {
              handler.message(msg);
            }
          }

          handler.trigger('success success.' + action.name, response.data);
          return response.data;
        })
        .catch(CM_Exception_FormFieldValidation, function(error) {
          handler._stopErrorPropagation = false;
          handler.trigger('error error.' + action.name, error.message, error.name, error.isPublic);
          if (!handler._stopErrorPropagation) {
            throw error;
          }
        })
        .finally(function() {
          if (options.disableUI) {
            handler.enable();
          }
          handler.trigger('complete');
        });
    }
  },

  stopErrorPropagation: function() {
    this._stopErrorPropagation = true;
  },

  reset: function() {
    this.el.reset();
  },

  disable: function() {
    this.$().disable();
  },

  enable: function() {
    this.$().enable();
  },

  /**
   * @param {String} message
   */
  error: function(message) {
    cm.window.hint(message);
  },

  /**
   * @param {String} message
   */
  message: function(message) {
    cm.window.hint(message);
  },

  resetErrors: function() {
    _.each(this._fields, function(field) {
      field.error(null);
    });
  },

  /**
   * @param {String} actionName
   * @returns {Object}
   */
  _getAction: function(actionName) {
    var action = this._actions[actionName];
    if (!action) {
      throw new CM_Exception('Form `' + this.getClass() + '` has no action `' + actionName + '`.');
    }
    action.name = actionName;
    return action;
  },

  /**
   * @param {String} actionName
   * @param {Object} data
   * @returns {Object}
   */
  _getErrorList: function(actionName, data) {
    var action = this._getAction(actionName);
    var errorList = {};

    _.each(action.fields, function(isRequired, fieldName) {
      if (isRequired) {
        var field = this.getField(fieldName);
        if (field.isEmpty(data[fieldName])) {
          var label = this._getFieldLabel(field);
          if (label) {
            errorList[fieldName] = cm.language.get('{$label} is required.', {label: label});
          } else {
            errorList[fieldName] = cm.language.get('Required');
          }
        }
      }
    }, this);

    return errorList;
  },

  /**
   * @param {CM_FormField_Abstract} field
   * @returns {String|null}
   * @private
   */
  _getFieldLabel: function(field) {
    var $labels = this.$('label[for="' + field.getAutoId() + '-input"]');
    if ($labels.length) {
      return $labels.first().text();
    }
    if (field.getInput().attr('placeholder')) {
      return field.getInput().attr('placeholder');
    }
    return null;
  }
});
<|endoftext|>


<commit_before>'use strict';

var map;
var destinationMarker;
var driverMarker;
var activeWayPointId;

function orderUpdateCb(order) {
  console.log('orderUpdateCb: ' + JSON.stringify(order));
  addToLogContainer('Order Updated: see console for more info');
  var wayPoint = _.find(order.way_points, {id: activeWayPointId});
  var destination = new google.maps.LatLng(wayPoint.lat, wayPoint.lng);

  if(destinationMarker){
    destinationMarker.setPosition(destination);
  }else{
    destinationMarker = new google.maps.Marker({
      position: destination,
      map: map,
      icon: 'pin_destination.png'
    });
  }

  resizeMapByMarkers();
}

function locationUpdateCb(location) {
  addToLogContainer('Location Updated: ' + JSON.stringify(location));
  console.log('locationUpdateCb: ' + JSON.stringify(location));
  if (location.lat() && location.lng() && map) {
    // do something with location here
    var driverPosition = new google.maps.LatLng(location.lat(), location.lng());

    //move the marker
    if (driverMarker) {
      driverMarker.setPosition(driverPosition);
    } else {
      driverMarker = new google.maps.Marker({
        position: driverPosition,
        map: map,
        icon: 'pin_delivery.png'
      });
    }
    resizeMapByMarkers();
  }
}

function etaUpdateCb(eta) {
  console.log('etaUpdateCb: ' + eta);
  addToLogContainer('ETA Updated: ' + eta);
  // can do something with eta here
}

function onTaskRatedCb() {
  console.log('onTaskRatedCb');
  addToLogContainer('Task Rated');
  // task rated successfully!
  // we can call BringgSDK.disconnect() for example.
}

function onTaskEndedCb() {
  console.log('onTaskEndedCb');
  addToLogContainer('Task Ended');
  // task ended
  // we can call BringgSDK.disconnect() if we are not using a rating screen for example.
}

// example of watch order with order_uuid and share_uuid
function onConnectByOrderUuidAndAccessToken() {
  console.log('onConnect');
  addToLogContainer('Connected');
  BringgSDK.watchOrder({
    order_uuid: DemoConfig.order_uuid,
    access_token: DemoConfig.customer_access_token
  }, function (result) {
    console.log('watch order result: ' + JSON.stringify(result));
  });
}

function initMap() {
  // init ui
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: -34.397, lng: 150.644},
    zoom: 8
  });
}

function addToLogContainer(value) {
  $('#logsContainer').append('
' + value + '
');
}

function onLoad() {
  $('#requestPhone').click(function () {
    var order_uuid = $('#order_uuid').val();
    var share_uuid = $('#share_uuid').val();

    if (!order_uuid || !share_uuid) {
      alert('please fill connectiont params')
      return;
    }

    BringgSDK.getDriverPhone(share_uuid, function (result) {
      if (result.status === 'ok') {
        addToLogContainer('Driver Phone Received: ' + result.phone_number);
      } else {
        addToLogContainer('FAILED Getting Driver Phone Received: ' + result.message);
      }
    });
  });

  $('#connectButton').click(function () {
    // example for setting callbacks directly
    BringgSDK.setLocationUpdateCb(locationUpdateCb);
    BringgSDK.setETAUpdateCb(etaUpdateCb);
    BringgSDK.setOrderUpdateCb(orderUpdateCb);

    // example for setting callbacks implicitly
    BringgSDK.setEventCallback({
      'taskRatedCb': onTaskRatedCb,
      'taskEndedCb': onTaskEndedCb
    });

    // customer_access_token may be null or undefined.
    var accessToken = $('#customer_access_token').val();

    // can use any combination of 2 from the following.
    // i.e for example can uncomment the access_token and comment out the share uuid or order uuid.
    var watchOrderParams = {
      order_uuid: $('#order_uuid').val(),
      share_uuid: $('#share_uuid').val()
    };

    if (accessToken) {
      watchOrderParams.access_token = accessToken;
    }

    BringgSDK.connect(accessToken, function () {
      console.log('onConnect');
      addToLogContainer('Connected');
      BringgSDK.watchOrder(watchOrderParams, function (result) {
        console.log('watch order result: ' + JSON.stringify(result));
        if (result.success === true) {
          addToLogContainer('WatchOrderSuccess');
          activeWayPointId = parseInt(result.shared_location.way_point_id);
        } else {
          addToLogContainer('Failed to watch order reason: ' + result.error);
        }
      });
    }, function () {
      console.log('onDisconnect');
      addToLogContainer('Disconnected');
    });
  })
}

function resizeMapByMarkers() {
  if(!map){
    return;
  }

  var latlngbounds = new google.maps.LatLngBounds();
  if(driverMarker){
    latlngbounds.extend(driverMarker.getPosition());
  }

  if (destinationMarker) {
    latlngbounds.extend(destinationMarker.getPosition());
  }

  if(driverMarker && destinationMarker){
    map.fitBounds(latlngbounds);
    map.setZoom(map.getZoom() - 1);
  }

  map.setCenter(latlngbounds.getCenter());
}<commit_msg>Customer sdk demo: Fix active way point id error<commit_after>"use strict";

var map;
var destinationMarker;
var driverMarker;

function orderUpdateCb(order) {
  console.log("orderUpdateCb: ", order);
  addToLogContainer("Order Updated: see console for more info");

  var wayPoint = _.last(order.way_points);
  var destination = new google.maps.LatLng(wayPoint.lat, wayPoint.lng);

  if (destinationMarker) {
    destinationMarker.setPosition(destination);
  } else {
    destinationMarker = new google.maps.Marker({
      position: destination,
      map: map,
      icon: "pin_destination.png",
    });
  }

  resizeMapByMarkers();
}

function locationUpdateCb(location) {
  addToLogContainer("Location Updated: " + JSON.stringify(location));
  console.log("locationUpdateCb: " + JSON.stringify(location));
  if (location.lat() && location.lng() && map) {
    // do something with location here
    var driverPosition = new google.maps.LatLng(location.lat(), location.lng());

    //move the marker
    if (driverMarker) {
      driverMarker.setPosition(driverPosition);
    } else {
      driverMarker = new google.maps.Marker({
        position: driverPosition,
        map: map,
        icon: "pin_delivery.png",
      });
    }
    resizeMapByMarkers();
  }
}

function etaUpdateCb(eta) {
  console.log("etaUpdateCb: " + eta);
  addToLogContainer("ETA Updated: " + eta);
  // can do something with eta here
}

function onTaskRatedCb() {
  console.log("onTaskRatedCb");
  addToLogContainer("Task Rated");
  // task rated successfully!
  // we can call BringgSDK.disconnect() for example.
}

function onTaskEndedCb() {
  console.log("onTaskEndedCb");
  addToLogContainer("Task Ended");
  // task ended
  // we can call BringgSDK.disconnect() if we are not using a rating screen for example.
}

// example of watch order with order_uuid and share_uuid
function onConnectByOrderUuidAndAccessToken() {
  console.log("onConnect");
  addToLogContainer("Connected");
  BringgSDK.watchOrder(
    {
      order_uuid: DemoConfig.order_uuid,
      access_token: DemoConfig.customer_access_token,
    },
    function (result) {
      console.log("watch order result: " + JSON.stringify(result));
    }
  );
}

function initMap() {
  // init ui
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: -34.397, lng: 150.644 },
    zoom: 8,
  });
}

function addToLogContainer(value) {
  $("#logsContainer").append('
' + value + "
");
}

function onLoad() {
  $("#requestPhone").click(function () {
    var order_uuid = $("#order_uuid").val();
    var share_uuid = $("#share_uuid").val();

    if (!order_uuid || !share_uuid) {
      alert("please fill connectiont params");
      return;
    }

    BringgSDK.getDriverPhone(share_uuid, function (result) {
      if (result.status === "ok") {
        addToLogContainer("Driver Phone Received: " + result.phone_number);
      } else {
        addToLogContainer(
          "FAILED Getting Driver Phone Received: " + result.message
        );
      }
    });
  });

  $("#connectButton").click(function () {
    // example for setting callbacks directly
    BringgSDK.setLocationUpdateCb(locationUpdateCb);
    BringgSDK.setETAUpdateCb(etaUpdateCb);
    BringgSDK.setOrderUpdateCb(orderUpdateCb);

    // example for setting callbacks implicitly
    BringgSDK.setEventCallback({
      taskRatedCb: onTaskRatedCb,
      taskEndedCb: onTaskEndedCb,
    });

    // customer_access_token may be null or undefined.
    var accessToken = $("#customer_access_token").val();

    // can use any combination of 2 from the following.
    // i.e for example can uncomment the access_token and comment out the share uuid or order uuid.
    var watchOrderParams = {
      order_uuid: $("#order_uuid").val(),
      share_uuid: $("#share_uuid").val(),
    };

    if (accessToken) {
      watchOrderParams.access_token = accessToken;
    }

    BringgSDK.connect(
      accessToken,
      function () {
        console.log("onConnect");
        addToLogContainer("Connected");
        BringgSDK.watchOrder(watchOrderParams, function (result) {
          console.log("watch order result: ", result);
          if (result.success === true) {
            addToLogContainer("WatchOrderSuccess");
          } else {
            addToLogContainer("Failed to watch order reason: " + result.error);
          }
        });
      },
      function () {
        console.log("onDisconnect");
        addToLogContainer("Disconnected");
      }
    );
  });
}

function resizeMapByMarkers() {
  if (!map) {
    return;
  }

  var latlngbounds = new google.maps.LatLngBounds();
  if (driverMarker) {
    latlngbounds.extend(driverMarker.getPosition());
  }

  if (destinationMarker) {
    latlngbounds.extend(destinationMarker.getPosition());
  }

  if (driverMarker && destinationMarker) {
    map.fitBounds(latlngbounds);
    map.setZoom(map.getZoom() - 1);
  }

  map.setCenter(latlngbounds.getCenter());
}

<|endoftext|>