<commit_before>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Utility function that allows modes to be combined. The mode given
// as the base argument takes care of most of the normal mode
// functionality, but a second (typically simple) mode is used, which
// can override the style of text. Both modes get to parse all of the
// text, but when both assign a non-null style to a piece of code, the
// overlay wins, unless the combine argument was true and not overridden,
// or state.overlay.combineTokens was true, in which case the styles are
// combined.

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.overlayMode = function(base, overlay, combine) {
  return {
    startState: function() {
      return {
        base: CodeMirror.startState(base),
        overlay: CodeMirror.startState(overlay),
        basePos: 0, baseCur: null,
        overlayPos: 0, overlayCur: null,
        lineSeen: null
      };
    },
    copyState: function(state) {
      return {
        base: CodeMirror.copyState(base, state.base),
        overlay: CodeMirror.copyState(overlay, state.overlay),
        basePos: state.basePos, baseCur: null,
        overlayPos: state.overlayPos, overlayCur: null
      };
    },

    token: function(stream, state) {
      if (stream.sol() || stream.string != state.lineSeen ||
          Math.min(state.basePos, state.overlayPos) < stream.start) {
        state.lineSeen = stream.string;
        state.basePos = state.overlayPos = stream.start;
      }

      if (stream.start == state.basePos) {
        state.baseCur = base.token(stream, state.base);
        state.basePos = stream.pos;
      }
      if (stream.start == state.overlayPos) {
        stream.pos = stream.start;
        state.overlayCur = overlay.token(stream, state.overlay);
        state.overlayPos = stream.pos;
      }
      stream.pos = Math.min(state.basePos, state.overlayPos);

      // state.overlay.combineTokens always takes precedence over combine,
      // unless set to null
      if (state.overlayCur == null) return state.baseCur;
      else if (state.baseCur != null &&
               state.overlay.combineTokens ||
               combine && state.overlay.combineTokens == null)
        return state.baseCur + " " + state.overlayCur;
      else return state.overlayCur;
    },

    indent: base.indent && function(state, textAfter) {
      return base.indent(state.base, textAfter);
    },
    electricChars: base.electricChars,

    innerMode: function(state) { return {state: state.base, mode: base}; },

    blankLine: function(state) {
      if (base.blankLine) base.blankLine(state.base);
      if (overlay.blankLine) overlay.blankLine(state.overlay);
    }
  };
};

});
<commit_msg>[overlay addon] Fix bad synchronization that was breaking gfm mode<commit_after>// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE

// Utility function that allows modes to be combined. The mode given
// as the base argument takes care of most of the normal mode
// functionality, but a second (typically simple) mode is used, which
// can override the style of text. Both modes get to parse all of the
// text, but when both assign a non-null style to a piece of code, the
// overlay wins, unless the combine argument was true and not overridden,
// or state.overlay.combineTokens was true, in which case the styles are
// combined.

(function(mod) {
  if (typeof exports == "object" && typeof module == "object") // CommonJS
    mod(require("../../lib/codemirror"));
  else if (typeof define == "function" && define.amd) // AMD
    define(["../../lib/codemirror"], mod);
  else // Plain browser env
    mod(CodeMirror);
})(function(CodeMirror) {
"use strict";

CodeMirror.overlayMode = function(base, overlay, combine) {
  return {
    startState: function() {
      return {
        base: CodeMirror.startState(base),
        overlay: CodeMirror.startState(overlay),
        basePos: 0, baseCur: null,
        overlayPos: 0, overlayCur: null,
        streamSeen: null
      };
    },
    copyState: function(state) {
      return {
        base: CodeMirror.copyState(base, state.base),
        overlay: CodeMirror.copyState(overlay, state.overlay),
        basePos: state.basePos, baseCur: null,
        overlayPos: state.overlayPos, overlayCur: null
      };
    },

    token: function(stream, state) {
      if (stream != state.streamSeen ||
          Math.min(state.basePos, state.overlayPos) < stream.start) {
        state.streamSeen = stream;
        state.basePos = state.overlayPos = stream.start;
      }

      if (stream.start == state.basePos) {
        state.baseCur = base.token(stream, state.base);
        state.basePos = stream.pos;
      }
      if (stream.start == state.overlayPos) {
        stream.pos = stream.start;
        state.overlayCur = overlay.token(stream, state.overlay);
        state.overlayPos = stream.pos;
      }
      stream.pos = Math.min(state.basePos, state.overlayPos);

      // state.overlay.combineTokens always takes precedence over combine,
      // unless set to null
      if (state.overlayCur == null) return state.baseCur;
      else if (state.baseCur != null &&
               state.overlay.combineTokens ||
               combine && state.overlay.combineTokens == null)
        return state.baseCur + " " + state.overlayCur;
      else return state.overlayCur;
    },

    indent: base.indent && function(state, textAfter) {
      return base.indent(state.base, textAfter);
    },
    electricChars: base.electricChars,

    innerMode: function(state) { return {state: state.base, mode: base}; },

    blankLine: function(state) {
      if (base.blankLine) base.blankLine(state.base);
      if (overlay.blankLine) overlay.blankLine(state.overlay);
    }
  };
};

});
<|endoftext|>


<commit_before>CodeMirror.defineMode("elm", function() {

  function switchState(source, setState, f) {
    setState(f);
    return f(source, setState);
  }

  // These should all be Unicode extended, as per the Haskell 2010 report
  var smallRE = /[a-z_]/;
  var largeRE = /[A-Z]/;
  var digitRE = /[0-9]/;
  var hexitRE = /[0-9A-Fa-f]/;
  var octitRE = /[0-7]/;
  var idRE = /[a-z_A-Z0-9\']/;
  var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/;
  var specialRE = /[(),;[\]`{}]/;
  var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer

  function normal(interpolate) {
    return function (source, setState) {
      if (source.eatWhile(whiteCharRE)) {
        return null;
      }

      var ch = source.next();
      if (specialRE.test(ch)) {
        if (ch == '{' && source.eat('-')) {
          var t = "comment";
          if (source.eat('#')) {
            t = "meta";
          }
          return switchState(source, setState, ncomment(t, 1));
        }
        if (interpolate && ch == '}' && source.eat('}')) {
          return switchState(source, setState, markdown);
        }
        if (ch == '['  &&
            source.eat('m') && source.eat('a') && source.eat('r') && source.eat('k') &&
            source.eat('d') && source.eat('o') && source.eat('w') && source.eat('n') &&
            source.eat('|')) {
          setState(markdown);
          return null;
        }
        return null;
      }

      if (ch == '\'') {
        if (source.eat('\\')) {
          source.next();  // should handle other escapes here
        }
        else {
          source.next();
        }
        if (source.eat('\'')) {
          return "string";
        }
        return "error";
      }

      if (ch == '"') {
        return switchState(source, setState, stringLiteral);
      }

      if (largeRE.test(ch)) {
        source.eatWhile(idRE);
        if (source.eat('.')) {
          return "qualifier";
        }
        return "variable-2";
      }

      if (smallRE.test(ch)) {
        var isDef = source.pos === 1;
        source.eatWhile(idRE);
        return isDef ? "variable-3" : "variable";
      }

      if (digitRE.test(ch)) {
        if (ch == '0') {
          if (source.eat(/[xX]/)) {
            source.eatWhile(hexitRE); // should require at least 1
            return "integer";
          }
          if (source.eat(/[oO]/)) {
            source.eatWhile(octitRE); // should require at least 1
            return "number";
          }
        }
        source.eatWhile(digitRE);
        var t = "number";
        if (source.eat('.')) {
          t = "number";
          source.eatWhile(digitRE); // should require at least 1
        }
        if (source.eat(/[eE]/)) {
          t = "number";
          source.eat(/[-+]/);
          source.eatWhile(digitRE); // should require at least 1
        }
        return t;
      }

      if (symbolRE.test(ch)) {
        if (ch == '-' && source.eat(/-/)) {
          source.eatWhile(/-/);
          if (!source.eat(symbolRE)) {
            source.skipToEnd();
            return "comment";
          }
        }
        source.eatWhile(symbolRE);
        return "builtin";
      }

      return "error";
    }
  }

  function ncomment(type, nest) {
    if (nest == 0) {
      return normal(false);
    }
    return function(source, setState) {
      var currNest = nest;
      while (!source.eol()) {
        var ch = source.next();
        if (ch == '{' && source.eat('-')) {
          ++currNest;
        }
        else if (ch == '-' && source.eat('}')) {
          --currNest;
          if (currNest == 0) {
            setState(normal(false));
            return type;
          }
        }
      }
      setState(ncomment(type, currNest));
      return type;
    }
  }

  function markdown(source, setState) {
    while (!source.eol()) {
      var ch = source.next();
      if (ch == '{' && source.eat('{')) {
        setState(normal(true));
        return "string";
      }
      if (ch == '|' && source.eat(']')) {
        setState(normal(false));
	return null;
      }
    }
    setState(markdown);
    return "string";
  }

  function stringLiteral(source, setState) {
    while (!source.eol()) {
      var ch = source.next();
      if (ch == '"') {
        setState(normal(false));
        return "string";
      }
      if (ch == '\\') {
        if (source.eol() || source.eat(whiteCharRE)) {
          setState(stringGap);
          return "string";
        }
        if (source.eat('&')) {
        }
        else {
          source.next(); // should handle other escapes here
        }
      }
    }
    setState(normal(false));
    return "error";
  }

  function stringGap(source, setState) {
    if (source.eat('\\')) {
      return switchState(source, setState, stringLiteral);
    }
    source.next();
    setState(normal(false));
    return "error";
  }

  var wellKnownWords = (function() {
      var wkw = {};

      var keywords = [
          "as", "case", "class", "data", "default", "deriving", "do", "else", "export", "foreign",
          "hiding", "jsevent", "if", "import", "in", "infix", "infixl", "infixr", "instance", "let",
          "module", "newtype", "of", "open", "then", "type", "where", "_",
          "..", "|", ":", "=", "\\", "\"", "->", "<-", "\u2192", "\u03BB"
      ];

      for (var i = keywords.length; i--;) {
          wkw[keywords[i]] = "keyword";
      }

      return wkw;
  })();

  return {
    startState: function ()  { return { f: normal(false) }; },
    copyState:  function (s) { return { f: s.f }; },

    token: function(stream, state) {
      var t = state.f(stream, function(s) { state.f = s; });
      var w = stream.current();
      return (wellKnownWords.hasOwnProperty(w)) ? wellKnownWords[w] : t;
    }
  };

});
<commit_msg>Add "port" as a reserved word<commit_after>CodeMirror.defineMode("elm", function() {

  function switchState(source, setState, f) {
    setState(f);
    return f(source, setState);
  }

  // These should all be Unicode extended, as per the Haskell 2010 report
  var smallRE = /[a-z_]/;
  var largeRE = /[A-Z]/;
  var digitRE = /[0-9]/;
  var hexitRE = /[0-9A-Fa-f]/;
  var octitRE = /[0-7]/;
  var idRE = /[a-z_A-Z0-9\']/;
  var symbolRE = /[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/;
  var specialRE = /[(),;[\]`{}]/;
  var whiteCharRE = /[ \t\v\f]/; // newlines are handled in tokenizer

  function normal(interpolate) {
    return function (source, setState) {
      if (source.eatWhile(whiteCharRE)) {
        return null;
      }

      var ch = source.next();
      if (specialRE.test(ch)) {
        if (ch == '{' && source.eat('-')) {
          var t = "comment";
          if (source.eat('#')) {
            t = "meta";
          }
          return switchState(source, setState, ncomment(t, 1));
        }
        if (interpolate && ch == '}' && source.eat('}')) {
          return switchState(source, setState, markdown);
        }
        if (ch == '['  &&
            source.eat('m') && source.eat('a') && source.eat('r') && source.eat('k') &&
            source.eat('d') && source.eat('o') && source.eat('w') && source.eat('n') &&
            source.eat('|')) {
          setState(markdown);
          return null;
        }
        return null;
      }

      if (ch == '\'') {
        if (source.eat('\\')) {
          source.next();  // should handle other escapes here
        }
        else {
          source.next();
        }
        if (source.eat('\'')) {
          return "string";
        }
        return "error";
      }

      if (ch == '"') {
        return switchState(source, setState, stringLiteral);
      }

      if (largeRE.test(ch)) {
        source.eatWhile(idRE);
        if (source.eat('.')) {
          return "qualifier";
        }
        return "variable-2";
      }

      if (smallRE.test(ch)) {
        var isDef = source.pos === 1;
        source.eatWhile(idRE);
        return isDef ? "variable-3" : "variable";
      }

      if (digitRE.test(ch)) {
        if (ch == '0') {
          if (source.eat(/[xX]/)) {
            source.eatWhile(hexitRE); // should require at least 1
            return "integer";
          }
          if (source.eat(/[oO]/)) {
            source.eatWhile(octitRE); // should require at least 1
            return "number";
          }
        }
        source.eatWhile(digitRE);
        var t = "number";
        if (source.eat('.')) {
          t = "number";
          source.eatWhile(digitRE); // should require at least 1
        }
        if (source.eat(/[eE]/)) {
          t = "number";
          source.eat(/[-+]/);
          source.eatWhile(digitRE); // should require at least 1
        }
        return t;
      }

      if (symbolRE.test(ch)) {
        if (ch == '-' && source.eat(/-/)) {
          source.eatWhile(/-/);
          if (!source.eat(symbolRE)) {
            source.skipToEnd();
            return "comment";
          }
        }
        source.eatWhile(symbolRE);
        return "builtin";
      }

      return "error";
    }
  }

  function ncomment(type, nest) {
    if (nest == 0) {
      return normal(false);
    }
    return function(source, setState) {
      var currNest = nest;
      while (!source.eol()) {
        var ch = source.next();
        if (ch == '{' && source.eat('-')) {
          ++currNest;
        }
        else if (ch == '-' && source.eat('}')) {
          --currNest;
          if (currNest == 0) {
            setState(normal(false));
            return type;
          }
        }
      }
      setState(ncomment(type, currNest));
      return type;
    }
  }

  function markdown(source, setState) {
    while (!source.eol()) {
      var ch = source.next();
      if (ch == '{' && source.eat('{')) {
        setState(normal(true));
        return "string";
      }
      if (ch == '|' && source.eat(']')) {
        setState(normal(false));
	return null;
      }
    }
    setState(markdown);
    return "string";
  }

  function stringLiteral(source, setState) {
    while (!source.eol()) {
      var ch = source.next();
      if (ch == '"') {
        setState(normal(false));
        return "string";
      }
      if (ch == '\\') {
        if (source.eol() || source.eat(whiteCharRE)) {
          setState(stringGap);
          return "string";
        }
        if (source.eat('&')) {
        }
        else {
          source.next(); // should handle other escapes here
        }
      }
    }
    setState(normal(false));
    return "error";
  }

  function stringGap(source, setState) {
    if (source.eat('\\')) {
      return switchState(source, setState, stringLiteral);
    }
    source.next();
    setState(normal(false));
    return "error";
  }

  var wellKnownWords = (function() {
      var wkw = {};

      var keywords = [
          "as", "case", "class", "data", "default", "deriving", "do", "else", "export", "foreign",
          "hiding", "jsevent", "if", "import", "in", "infix", "infixl", "infixr", "instance", "let",
          "module", "newtype", "of", "open", "then", "type", "where", "_",
          "..", "|", ":", "=", "\\", "\"", "->", "<-", "\u2192", "\u03BB", "port"
      ];

      for (var i = keywords.length; i--;) {
          wkw[keywords[i]] = "keyword";
      }

      return wkw;
  })();

  return {
    startState: function ()  { return { f: normal(false) }; },
    copyState:  function (s) { return { f: s.f }; },

    token: function(stream, state) {
      var t = state.f(stream, function(s) { state.f = s; });
      var w = stream.current();
      return (wellKnownWords.hasOwnProperty(w)) ? wellKnownWords[w] : t;
    }
  };

});
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import RoomLink from 'components/RoomLink'
import {styles} from './styles.module.scss'
import Cookie from 'js-cookie';
import T from 'components/T'

class Settings extends Component {

  handleSoundToggle() {
    this.props.toggleSoundEnabled(!this.props.soundIsEnabled)
  }

  handleLanguageChange(evt) {
    const language = evt.target.value;
    Cookie.set('language', language);
    this.props.setLanguage(language);
  }

  render() {
    return (

<T path='sound'/>

          <form>

                <input id="sound-control" onChange={this.handleSoundToggle.bind(this)} className="form-check-input" type="checkbox" checked={this.props.soundIsEnabled} />
                <T path='sound'/>

          </form>

<T path='copyRoomHeader'/>

          <RoomLink roomId={this.props.roomId} translations={this.props.translations} />

<T path='languageDropdownHeader'/>

Help us translate Darkwire!

            <select value={this.props.language} className="form-control" onChange={this.handleLanguageChange.bind(this)}>
              <option value="en">English</option>
              {/*<option value="fr">Français</option>*/}
            </select>

<T path='roomOwnerHeader'/>

<T path='roomOwnerText'/>

<T path='lockRoomHeader'/>

<T path='lockRoomText'/>

<T path='slashCommandsHeader'/>

<T path='slashCommandsText'/>

/nick [username] <T path='slashCommandsBullets.0'/>

/me [action] <T path='slashCommandsBullets.1'/>

/clear <T path='slashCommandsBullets.2'/>

/help <T path='slashCommandsBullets.3'/>

    )
  }
}

Settings.propTypes = {
  soundIsEnabled: PropTypes.bool.isRequired,
  toggleSoundEnabled: PropTypes.func.isRequired,
  roomId: PropTypes.string.isRequired,
  setLanguage: PropTypes.func.isRequired,
  translations: PropTypes.object.isRequired,
}

export default Settings
<commit_msg>Add French to language dropdown (#88)<commit_after>import React, { Component } from 'react'
import PropTypes from 'prop-types'
import RoomLink from 'components/RoomLink'
import {styles} from './styles.module.scss'
import Cookie from 'js-cookie';
import T from 'components/T'

class Settings extends Component {

  handleSoundToggle() {
    this.props.toggleSoundEnabled(!this.props.soundIsEnabled)
  }

  handleLanguageChange(evt) {
    const language = evt.target.value;
    Cookie.set('language', language);
    this.props.setLanguage(language);
  }

  render() {
    return (

<T path='sound'/>

          <form>

                <input id="sound-control" onChange={this.handleSoundToggle.bind(this)} className="form-check-input" type="checkbox" checked={this.props.soundIsEnabled} />
                <T path='sound'/>

          </form>

<T path='copyRoomHeader'/>

          <RoomLink roomId={this.props.roomId} translations={this.props.translations} />

<T path='languageDropdownHeader'/>

Help us translate Darkwire!

            <select value={this.props.language} className="form-control" onChange={this.handleLanguageChange.bind(this)}>
              <option value="en">English</option>
              <option value="fr">Français</option>
            </select>

<T path='roomOwnerHeader'/>

<T path='roomOwnerText'/>

<T path='lockRoomHeader'/>

<T path='lockRoomText'/>

<T path='slashCommandsHeader'/>

<T path='slashCommandsText'/>

/nick [username] <T path='slashCommandsBullets.0'/>

/me [action] <T path='slashCommandsBullets.1'/>

/clear <T path='slashCommandsBullets.2'/>

/help <T path='slashCommandsBullets.3'/>

    )
  }
}

Settings.propTypes = {
  soundIsEnabled: PropTypes.bool.isRequired,
  toggleSoundEnabled: PropTypes.func.isRequired,
  roomId: PropTypes.string.isRequired,
  setLanguage: PropTypes.func.isRequired,
  translations: PropTypes.object.isRequired,
}

export default Settings
<|endoftext|>


<commit_before>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var EventEmitter = require("../lib/event_emitter").EventEmitter;
var config = require("../config");

var WorkerClient = function(topLevelNamespaces, mod, classname) {
    this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
    this.changeListener = this.changeListener.bind(this);
    this.onMessage = this.onMessage.bind(this);

    // nameToUrl is renamed to toUrl in requirejs 2
    if (require.nameToUrl && !require.toUrl)
        require.toUrl = require.nameToUrl;

    var workerUrl;
    if (config.get("packaged") || !require.toUrl) {
        workerUrl = config.moduleUrl(mod, "worker");
    } else {
        var normalizePath = this.$normalizePath;
        workerUrl = normalizePath(require.toUrl("ace/worker/worker.js", null, "_"));

        var tlns = {};
        topLevelNamespaces.forEach(function(ns) {
            tlns[ns] = normalizePath(require.toUrl(ns, null, "_").replace(/(\.js)?(\?.*)?$/, ""));
        });
    }

    this.$worker = new Worker(workerUrl);
    this.$worker.postMessage({
        init : true,
        tlns: tlns,
        module: mod,
        classname: classname
    });

    this.callbackId = 1;
    this.callbacks = {};

    this.$worker.onmessage = this.onMessage;
};

(function(){

    oop.implement(this, EventEmitter);

    this.onMessage = function(e) {
        var msg = e.data;
        switch(msg.type) {
            case "log":
                window.console && console.log && console.log.apply(console, msg.data);
                break;

            case "event":
                this._emit(msg.name, {data: msg.data});
                break;

            case "call":
                var callback = this.callbacks[msg.id];
                if (callback) {
                    callback(msg.data);
                    delete this.callbacks[msg.id];
                }
                break;
        }
    };

    this.$normalizePath = function(path) {
        if (!location.host) // needed for file:// protocol
            return path;
        path = path.replace(/^[a-z]+:\/\/[^\/]+/, ""); // Remove domain name and rebuild it
        path = location.protocol + "//" + location.host
            // paths starting with a slash are relative to the root (host)
            + (path.charAt(0) == "/" ? "" : location.pathname.replace(/\/[^\/]*$/, ""))
            + "/" + path.replace(/^[\/]+/, "");
        return path;
    };

    this.terminate = function() {
        this._emit("terminate", {});
        this.deltaQueue = null;
        this.$worker.terminate();
        this.$worker = null;
        this.$doc.removeEventListener("change", this.changeListener);
        this.$doc = null;
    };

    this.send = function(cmd, args) {
        this.$worker.postMessage({command: cmd, args: args});
    };

    this.call = function(cmd, args, callback) {
        if (callback) {
            var id = this.callbackId++;
            this.callbacks[id] = callback;
            args.push(id);
        }
        this.send(cmd, args);
    };

    this.emit = function(event, data) {
        try {
            // firefox refuses to clone objects which have function properties
            // TODO: cleanup event
            this.$worker.postMessage({event: event, data: {data: data.data}});
        }
        catch(ex) {}
    };

    this.attachToDocument = function(doc) {
        if(this.$doc)
            this.terminate();

        this.$doc = doc;
        this.call("setValue", [doc.getValue()]);
        doc.on("change", this.changeListener);
    };

    this.changeListener = function(e) {
        if (!this.deltaQueue) {
            this.deltaQueue = [e.data];
            setTimeout(this.$sendDeltaQueue, 0);
        } else
            this.deltaQueue.push(e.data);
    };

    this.$sendDeltaQueue = function() {
        var q = this.deltaQueue;
        if (!q) return;
        this.deltaQueue = null;
        if (q.length > 20 && q.length > this.$doc.getLength() >> 1) {
            this.call("setValue", [this.$doc.getValue()]);
        } else
            this.emit("change", {data: q});
    }

}).call(WorkerClient.prototype);

var UIWorkerClient = function(topLevelNamespaces, mod, classname) {
    this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
    this.changeListener = this.changeListener.bind(this);
    this.callbackId = 1;
    this.callbacks = {};
    this.messageBuffer = [];

    var main = null;
    var sender = Object.create(EventEmitter);
    var _self = this;

    this.$worker = {};
    this.$worker.terminate = function() {};
    this.$worker.postMessage = function(e) {
        _self.messageBuffer.push(e);
        main && setTimeout(processNext);
    };

    var processNext = function() {
        var msg = _self.messageBuffer.shift();
        if (msg.command)
            main[msg.command].apply(main, msg.args);
        else if (msg.event)
            sender._emit(msg.event, msg.data);
    };

    sender.postMessage = function(msg) {
        _self.onMessage({data: msg});
    };
    sender.callback = function(data, callbackId) {
        this.postMessage({type: "call", id: callbackId, data: data});
    };
    sender.emit = function(name, data) {
        this.postMessage({type: "event", name: name, data: data});
    };

    config.loadModule(["worker", mod], function(Main) {
        main = new Main[classname](sender);
        while (_self.messageBuffer.length)
            processNext();
    });
};

UIWorkerClient.prototype = WorkerClient.prototype;

exports.UIWorkerClient = UIWorkerClient;
exports.WorkerClient = WorkerClient;

});
<commit_msg>Use shim blob with importScripts to use CORS for Worker<commit_after>/* ***** BEGIN LICENSE BLOCK *****
 * Distributed under the BSD license:
 *
 * Copyright (c) 2010, Ajax.org B.V.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of Ajax.org B.V. nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * ***** END LICENSE BLOCK ***** */

define(function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var EventEmitter = require("../lib/event_emitter").EventEmitter;
var config = require("../config");

var WorkerClient = function(topLevelNamespaces, mod, classname) {
    this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
    this.changeListener = this.changeListener.bind(this);
    this.onMessage = this.onMessage.bind(this);

    // nameToUrl is renamed to toUrl in requirejs 2
    if (require.nameToUrl && !require.toUrl)
        require.toUrl = require.nameToUrl;

    var workerUrl;
    if (config.get("packaged") || !require.toUrl) {
        workerUrl = config.moduleUrl(mod, "worker");
    } else {
        var normalizePath = this.$normalizePath;
        workerUrl = normalizePath(require.toUrl("ace/worker/worker.js", null, "_"));

        var tlns = {};
        topLevelNamespaces.forEach(function(ns) {
            tlns[ns] = normalizePath(require.toUrl(ns, null, "_").replace(/(\.js)?(\?.*)?$/, ""));
        });
    }

    try {
        this.$worker = new Worker(workerUrl);
    } catch ( e ) {
        if ( e instanceof DOMException ) {
            // Likely same origin problem. Use importScripts from a shim Worker
            var blob = this.blobWorker(workerUrl),
                URL = URL || webkitURL,
                blobURL = URL.createObjectURL(blob);

            this.$worker = new Worker(blobURL);
            URL.revokeObjectURL(blobURL);
        } else {
            throw e;
        }
    }
    this.$worker.postMessage({
        init : true,
        tlns: tlns,
        module: mod,
        classname: classname
    });

    this.callbackId = 1;
    this.callbacks = {};

    this.$worker.onmessage = this.onMessage;
};

(function(){

    oop.implement(this, EventEmitter);

    this.onMessage = function(e) {
        var msg = e.data;
        switch(msg.type) {
            case "log":
                window.console && console.log && console.log.apply(console, msg.data);
                break;

            case "event":
                this._emit(msg.name, {data: msg.data});
                break;

            case "call":
                var callback = this.callbacks[msg.id];
                if (callback) {
                    callback(msg.data);
                    delete this.callbacks[msg.id];
                }
                break;
        }
    };

    this.$normalizePath = function(path) {
        if (!location.host) // needed for file:// protocol
            return path;
        path = path.replace(/^[a-z]+:\/\/[^\/]+/, ""); // Remove domain name and rebuild it
        path = location.protocol + "//" + location.host
            // paths starting with a slash are relative to the root (host)
            + (path.charAt(0) == "/" ? "" : location.pathname.replace(/\/[^\/]*$/, ""))
            + "/" + path.replace(/^[\/]+/, "");
        return path;
    };

    this.terminate = function() {
        this._emit("terminate", {});
        this.deltaQueue = null;
        this.$worker.terminate();
        this.$worker = null;
        this.$doc.removeEventListener("change", this.changeListener);
        this.$doc = null;
    };

    this.send = function(cmd, args) {
        this.$worker.postMessage({command: cmd, args: args});
    };

    this.call = function(cmd, args, callback) {
        if (callback) {
            var id = this.callbackId++;
            this.callbacks[id] = callback;
            args.push(id);
        }
        this.send(cmd, args);
    };

    this.emit = function(event, data) {
        try {
            // firefox refuses to clone objects which have function properties
            // TODO: cleanup event
            this.$worker.postMessage({event: event, data: {data: data.data}});
        }
        catch(ex) {}
    };

    this.attachToDocument = function(doc) {
        if(this.$doc)
            this.terminate();

        this.$doc = doc;
        this.call("setValue", [doc.getValue()]);
        doc.on("change", this.changeListener);
    };

    this.changeListener = function(e) {
        if (!this.deltaQueue) {
            this.deltaQueue = [e.data];
            setTimeout(this.$sendDeltaQueue, 0);
        } else
            this.deltaQueue.push(e.data);
    };

    this.$sendDeltaQueue = function() {
        var q = this.deltaQueue;
        if (!q) return;
        this.deltaQueue = null;
        if (q.length > 20 && q.length > this.$doc.getLength() >> 1) {
            this.call("setValue", [this.$doc.getValue()]);
        } else
            this.emit("change", {data: q});
    };

    this.blobWorker = function(workerUrl) {
        var script = 'importScripts("' + workerUrl + '");',
            blob;
        try {
            blob = new Blob(
                [script],
                { 'type' : 'application/javascript' }
            );
        } catch (e) { // Backwards-compatibility
            var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder,
                blobBuilder = new BlobBuilder();
            blobBuilder.append(script);
            blob = blobBuilder.getBlob('application/javascript');
        }
        return blob;
    };

}).call(WorkerClient.prototype);

var UIWorkerClient = function(topLevelNamespaces, mod, classname) {
    this.$sendDeltaQueue = this.$sendDeltaQueue.bind(this);
    this.changeListener = this.changeListener.bind(this);
    this.callbackId = 1;
    this.callbacks = {};
    this.messageBuffer = [];

    var main = null;
    var sender = Object.create(EventEmitter);
    var _self = this;

    this.$worker = {};
    this.$worker.terminate = function() {};
    this.$worker.postMessage = function(e) {
        _self.messageBuffer.push(e);
        main && setTimeout(processNext);
    };

    var processNext = function() {
        var msg = _self.messageBuffer.shift();
        if (msg.command)
            main[msg.command].apply(main, msg.args);
        else if (msg.event)
            sender._emit(msg.event, msg.data);
    };

    sender.postMessage = function(msg) {
        _self.onMessage({data: msg});
    };
    sender.callback = function(data, callbackId) {
        this.postMessage({type: "call", id: callbackId, data: data});
    };
    sender.emit = function(name, data) {
        this.postMessage({type: "event", name: name, data: data});
    };

    config.loadModule(["worker", mod], function(Main) {
        main = new Main[classname](sender);
        while (_self.messageBuffer.length)
            processNext();
    });
};

UIWorkerClient.prototype = WorkerClient.prototype;

exports.UIWorkerClient = UIWorkerClient;
exports.WorkerClient = WorkerClient;

});
<|endoftext|>


<commit_before>var util = require('util');

module.exports = function(options)
{
	this.options = options;
	this.servers = {};

	this.lc =
	{
		urgent: process.stdout,
		out: process.stdout,
		err: process.stderr,
		verbose: null,
	};

	this.start = function()
	{
		for(var kServer in this.servers)
		{
			this.servers[kServer].connect();
		}
	}

	this.run = this.start;

	this.log = function(logChannel, message)
	{
		message = util.inspect(message);
		this.logUnsafe(logChannel, message);
	}

	this.logUnsafe = function(logChannel, message)
	{
		var d = new Date();
		var t = '[' + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds() + ']';

		if(typeof this.lc[logChannel] !== 'undefined' && this.lc[logChannel] !== null)
		{
			this.lc[logChannel].write(t + ' ' + message + '\n');
		}
	}

	this.loadModule = function(name, server)
	{
		var path;

		try
		{
			if(typeof this.options !== 'undefined') this.options = {};
			if(typeof this.options.modulesPath === 'undefined') this.options.modulesPath = process.cwd() + '/modules';
			path = this.options.modulesPath + '/' + name;
			if(typeof require.cache[path] !== 'undefined') delete require.cache[path];
			require.resolve(path);
		}
		catch(e)
		{
			try
			{
				path = './modules/' + name;
				require.resolve(path);
			}
			catch(e2)
			{
				this.log('urgent', e.message);
				this.log('urgent', e2.message);
				return e.message + ' | ' + e2.message;
			}
		}

		try
		{
			if(typeof require.cache[require.resolve(path)] !== 'undefined')
			{
				delete require.cache[require.resolve(path)];
			}

			var module = require(path);
			var mod = new module.mod(this);

			if(typeof server === 'undefined' || server === null)
			{
				for(var kServer in this.servers)
				{
					this.servers[kServer].modules[name] = mod;
				}
			}
			else
			{
				server.modules[name] = mod;
			}

			this.log('out', 'Loaded module: ' + name);
			return '';
		}
		catch(e)
		{
			this.log('out', 'Failed to load module: ' + name);
			this.logUnsafe('urgent', e.stack);
			return e.message;
		}
	}

	this.unloadModule = function(name, server)
	{
		if(server === null)
		{
			for(var kServer in this.servers)
			{
				this.servers[kServer].modules[name] = null;
				delete this.servers[kServer].modules[name];
			}
		}
		else
		{
			server.modules[name] = null;
			delete server.modules[name];
		}

		this.log('out', 'Unloaded module: ' + name);
	}
}
<commit_msg>Fixed module loading bug again.<commit_after>var util = require('util');

module.exports = function(options)
{
	this.options = options;
	this.servers = {};

	this.lc =
	{
		urgent: process.stdout,
		out: process.stdout,
		err: process.stderr,
		verbose: null,
	};

	this.start = function()
	{
		for(var kServer in this.servers)
		{
			this.servers[kServer].connect();
		}
	}

	this.run = this.start;

	this.log = function(logChannel, message)
	{
		message = util.inspect(message);
		this.logUnsafe(logChannel, message);
	}

	this.logUnsafe = function(logChannel, message)
	{
		var d = new Date();
		var t = '[' + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds() + ']';

		if(typeof this.lc[logChannel] !== 'undefined' && this.lc[logChannel] !== null)
		{
			this.lc[logChannel].write(t + ' ' + message + '\n');
		}
	}

	this.loadModule = function(name, server)
	{
		var path;

		try
		{
			if(typeof this.options === 'undefined') this.options = {};
			if(typeof this.options.modulesPath === 'undefined') this.options.modulesPath = process.cwd() + '/modules';
			path = this.options.modulesPath + '/' + name;
			if(typeof require.cache[path] !== 'undefined') delete require.cache[path];
			require.resolve(path);
		}
		catch(e)
		{
			try
			{
				path = './modules/' + name;
				require.resolve(path);
			}
			catch(e2)
			{
				this.log('urgent', e.message);
				this.log('urgent', e2.message);
				return e.message + ' | ' + e2.message;
			}
		}

		try
		{
			if(typeof require.cache[require.resolve(path)] !== 'undefined')
			{
				delete require.cache[require.resolve(path)];
			}

			var module = require(path);
			var mod = new module.mod(this);

			if(typeof server === 'undefined' || server === null)
			{
				for(var kServer in this.servers)
				{
					this.servers[kServer].modules[name] = mod;
				}
			}
			else
			{
				server.modules[name] = mod;
			}

			this.log('out', 'Loaded module: ' + name);
			return '';
		}
		catch(e)
		{
			this.log('out', 'Failed to load module: ' + name);
			this.logUnsafe('urgent', e.stack);
			return e.message;
		}
	}

	this.unloadModule = function(name, server)
	{
		if(server === null)
		{
			for(var kServer in this.servers)
			{
				this.servers[kServer].modules[name] = null;
				delete this.servers[kServer].modules[name];
			}
		}
		else
		{
			server.modules[name] = null;
			delete server.modules[name];
		}

		this.log('out', 'Unloaded module: ' + name);
	}
}
<|endoftext|>


<commit_before>// Fetches tweets from Twitters streaming service, which uses keyword search.
'use strict';

var Twit = require('twit');
var ContentService = require('../content-service');
var config = require('../../../config/secrets');
var util = require('util');
var _ = require('lodash');
var tweetMatches = require('tweet-matches');

function TwitterContentService() {
  this._twit = new Twit(_.clone(config.get().twitter));
  this._connectedSources = {};
  this._compiledQueries = {};
  this.fetchType = 'subscribe';
  this._isStreaming = false;
  this._streamName = 'statuses/filter';
}

util.inherits(TwitterContentService, ContentService);

TwitterContentService.prototype.subscribe = function(id, info) {
  this._connectedSources[id] = info;
  this._compiledQueries[id] = tweetMatches.compile(info.keywords);
  this._keywords = getQuery(this._connectedSources);
  if (this._isStreaming) this._stop();
  this._start();
  return 'tweet:' + id;
};

TwitterContentService.prototype.unsubscribe = function(id) {
  delete this._connectedSources[id];
  delete this._compiledQueries[id];
  this._keywords = getQuery(this._connectedSources);
  this._stop();
  if (_.keys(this._connectedSources).length > 0) this._start();
};

function getQuery(sources) {
  return _.map(_.values(sources), 'keywords').join(',');
}

// Start/resume streaming of filtered data
TwitterContentService.prototype._start = function() {
  if (this._isStreaming) return;
  this._stream = this._getStream();
  this._addListeners();
  this._isStreaming = true;
};

// Stop the stream
TwitterContentService.prototype._stop = function() {
  if (this._stream) {
    this._stream.stop();
    delete this._stream;
  }
  this._isStreaming = false;
};

// Wrapper for stream event listener
TwitterContentService.prototype._addListeners = function() {
  if (this._stream) {
    // Avoid re-adding the same listeners
    var listeners = this._stream.listeners('tweet');
    if (listeners.length !== 0) return;
  } else {
    // Bail if stream has not been started
    return;
  }
  var self = this;
  this._stream.on('tweet', function(tweet) {
    self._makeReport(tweet);
  });
  this._stream.on('limit', function(message) {
    self.emit('warning', new Error('Twitter sent rate limitation: ' + JSON.stringify(message.limit)));
  });
  this._stream.on('disconnect', function(message) {
    self.emit('warning', new Error('Twitter sent disconnect: ' + JSON.stringify(message.disconnect)));
  });
  this._stream.on('reconnect', function(request, response, connectInterval) {
    self.emit('warning', new Error('Reconnecting to Twitter in ' + connectInterval / 1000 + ' seconds'));
  });
  this._stream.on('warning', function(message) {
    self.emit('warning', new Error('Twitter sent warning: ' + JSON.stringify(message.warning)));
  });
};

// Determine which subscribed bots match this report, and send it to one of them
// If we send it to all that match, it will be duplicated!
TwitterContentService.prototype._makeReport = function(tweet) {
  var self = this;
  var matchingBots = _.pickBy(this._connectedSources, function(ignore, botId) {
    var compiled = self._compiledQueries[botId];
    var b = tweetMatches(tweet, compiled);
    return b;
  });
  tweet._sources = _.values(_.mapValues(matchingBots, 'sourceId'));
  tweet._sourceNicknames = _.values(_.mapValues(matchingBots, 'sourceName'));
  var botIds = _.keys(matchingBots);
  if (botIds.length === 0) {
    throw new Error('tweet-matches failed with keywords ' + this._keywords);
  }
  this.emit('tweet:' + botIds[0], this._parse(tweet));
};

// Gets a Twit stream object
TwitterContentService.prototype._getStream = function() {
  return this._twit.stream(this._streamName, { track: this._keywords });
};

TwitterContentService.prototype._parse = function(data) {
  var author = data.user ? data.user.screen_name : null;
  var metadata = {
    tweetID: data.id ? data.id : null,
    retweet: data.retweeted_status ? true : false,
    replyTo: data.in_reply_to_status_id_str ? data.in_reply_to_status_id_str : '',
    location: data.user.location ? data.user.location : '',
    verified: data.user.verified ? data.user.verified : false,
    followerCount: data.user.followers_count ? data.user.followers_count : 0,
    friendCount: data.user.friends_count ? data.user.friends_count : 0,
    geoEnabled: data.user.geo_enabled ? data.user.geo_enabled : false,
    latitude: data.coordinates ? data.coordinates[0] : 0,
    longitude: data.coordinates ? data.coordinates[1] : 0,
    retweetCount: data.retweet_count ? data.retweet_count : 0,
    favouriteCount: data.favorite_count ? data.favorite_count : 0
  };
  return {
    authoredAt: new Date(data.created_at),
    fetchedAt: new Date(),
    content: data.text,
    author: author,
    metadata: metadata,
    url: author ? 'https://twitter.com/' + author + '/status/' + data.id_str : null,
    _sources: data._sources,
    _sourceNicknames: data._sourceNicknames
  };
};

TwitterContentService.prototype.reloadSettings = function() {
  this._stop();
  delete this._stream;
  delete this._twit;

  this._twit = new Twit(_.clone(config.get().twitter));
  this._start();
};

module.exports = new TwitterContentService();
<commit_msg>Better tweet-matches failure log<commit_after>// Fetches tweets from Twitters streaming service, which uses keyword search.
'use strict';

var Twit = require('twit');
var ContentService = require('../content-service');
var config = require('../../../config/secrets');
var util = require('util');
var _ = require('lodash');
var tweetMatches = require('tweet-matches');

function TwitterContentService() {
  this._twit = new Twit(_.clone(config.get().twitter));
  this._connectedSources = {};
  this._compiledQueries = {};
  this.fetchType = 'subscribe';
  this._isStreaming = false;
  this._streamName = 'statuses/filter';
}

util.inherits(TwitterContentService, ContentService);

TwitterContentService.prototype.subscribe = function(id, info) {
  this._connectedSources[id] = info;
  this._compiledQueries[id] = tweetMatches.compile(info.keywords);
  this._keywords = getQuery(this._connectedSources);
  if (this._isStreaming) this._stop();
  this._start();
  return 'tweet:' + id;
};

TwitterContentService.prototype.unsubscribe = function(id) {
  delete this._connectedSources[id];
  delete this._compiledQueries[id];
  this._keywords = getQuery(this._connectedSources);
  this._stop();
  if (_.keys(this._connectedSources).length > 0) this._start();
};

function getQuery(sources) {
  return _.map(_.values(sources), 'keywords').join(',');
}

// Start/resume streaming of filtered data
TwitterContentService.prototype._start = function() {
  if (this._isStreaming) return;
  this._stream = this._getStream();
  this._addListeners();
  this._isStreaming = true;
};

// Stop the stream
TwitterContentService.prototype._stop = function() {
  if (this._stream) {
    this._stream.stop();
    delete this._stream;
  }
  this._isStreaming = false;
};

// Wrapper for stream event listener
TwitterContentService.prototype._addListeners = function() {
  if (this._stream) {
    // Avoid re-adding the same listeners
    var listeners = this._stream.listeners('tweet');
    if (listeners.length !== 0) return;
  } else {
    // Bail if stream has not been started
    return;
  }
  var self = this;
  this._stream.on('tweet', function(tweet) {
    self._makeReport(tweet);
  });
  this._stream.on('limit', function(message) {
    self.emit('warning', new Error('Twitter sent rate limitation: ' + JSON.stringify(message.limit)));
  });
  this._stream.on('disconnect', function(message) {
    self.emit('warning', new Error('Twitter sent disconnect: ' + JSON.stringify(message.disconnect)));
  });
  this._stream.on('reconnect', function(request, response, connectInterval) {
    self.emit('warning', new Error('Reconnecting to Twitter in ' + connectInterval / 1000 + ' seconds'));
  });
  this._stream.on('warning', function(message) {
    self.emit('warning', new Error('Twitter sent warning: ' + JSON.stringify(message.warning)));
  });
};

// Determine which subscribed bots match this report, and send it to one of them
// If we send it to all that match, it will be duplicated!
TwitterContentService.prototype._makeReport = function(tweet) {
  var self = this;
  var matchingBots = _.pickBy(this._connectedSources, function(ignore, botId) {
    var compiled = self._compiledQueries[botId];
    var b = tweetMatches(tweet, compiled);
    return b;
  });
  tweet._sources = _.values(_.mapValues(matchingBots, 'sourceId'));
  tweet._sourceNicknames = _.values(_.mapValues(matchingBots, 'sourceName'));
  var botIds = _.keys(matchingBots);
  if (botIds.length === 0) {
    throw new Error('tweet-matches failed with keywords ' + this._keywords + ' on tweet http://twitter.com/' + (tweet.user && tweet.user.name) + '/status/' + tweet.id_str);
  }
  this.emit('tweet:' + botIds[0], this._parse(tweet));
};

// Gets a Twit stream object
TwitterContentService.prototype._getStream = function() {
  return this._twit.stream(this._streamName, { track: this._keywords });
};

TwitterContentService.prototype._parse = function(data) {
  var author = data.user ? data.user.screen_name : null;
  var metadata = {
    tweetID: data.id ? data.id : null,
    retweet: data.retweeted_status ? true : false,
    replyTo: data.in_reply_to_status_id_str ? data.in_reply_to_status_id_str : '',
    location: data.user.location ? data.user.location : '',
    verified: data.user.verified ? data.user.verified : false,
    followerCount: data.user.followers_count ? data.user.followers_count : 0,
    friendCount: data.user.friends_count ? data.user.friends_count : 0,
    geoEnabled: data.user.geo_enabled ? data.user.geo_enabled : false,
    latitude: data.coordinates ? data.coordinates[0] : 0,
    longitude: data.coordinates ? data.coordinates[1] : 0,
    retweetCount: data.retweet_count ? data.retweet_count : 0,
    favouriteCount: data.favorite_count ? data.favorite_count : 0
  };
  return {
    authoredAt: new Date(data.created_at),
    fetchedAt: new Date(),
    content: data.text,
    author: author,
    metadata: metadata,
    url: author ? 'https://twitter.com/' + author + '/status/' + data.id_str : null,
    _sources: data._sources,
    _sourceNicknames: data._sourceNicknames
  };
};

TwitterContentService.prototype.reloadSettings = function() {
  this._stop();
  delete this._stream;
  delete this._twit;

  this._twit = new Twit(_.clone(config.get().twitter));
  this._start();
};

module.exports = new TwitterContentService();
<|endoftext|>


<commit_before>import {createStore, applyMiddleware} from 'redux'
import createLogger from 'redux-logger'
import reduxPromise from 'redux-promise'
import reduxThunk from 'redux-thunk'
import {AsyncStorage} from 'react-native'
import {allViewNames as defaultViewOrder} from '../views/views'
import difference from 'lodash/difference'
import {tracker} from '../analytics'

export const SAVE_HOMESCREEN_ORDER = 'SAVE_HOMESCREEN_ORDER'

export const updateViewOrder = (currentOrder, defaultOrder=defaultViewOrder) => {
  currentOrder = currentOrder || []

  // lodash/difference: Creates an array of array values _not included_ in the
  // other given arrays.

  // In case new screens have been added, get a list of the new screens
  let addedScreens = difference(defaultOrder, currentOrder)
  // check for removed screens
  let removedScreens = difference(currentOrder, defaultOrder)

  // add the new screens to the list
  currentOrder = currentOrder.concat(addedScreens)

  // now we remove the screens that were removed
  currentOrder = difference(currentOrder, removedScreens)

  return currentOrder
}

export const loadHomescreenOrder = async () => {
  // get the saved list from AsyncStorage
  let savedOrder = JSON.parse(await AsyncStorage.getItem('homescreen:view-order'))

  // update the order, in case new views have been added/removed
  let order = updateViewOrder(savedOrder, defaultViewOrder)

  // return an action to save it to AsyncStorage
  return saveHomescreenOrder(order, {noTrack: true})
}

export const saveHomescreenOrder = (order, options={}) => {
  options.noTrack || tracker.trackEventWithCustomDimensionValues('homescreen', 'reorder', {}, {order})
  AsyncStorage.setItem('homescreen:view-order', JSON.stringify(order))
  return {type: SAVE_HOMESCREEN_ORDER, payload: order}
}

const initialHomescreenState = {
  order: [],
}
function homescreen(state=initialHomescreenState, action) {
  let {type, payload} = action
  switch (type) {
    case SAVE_HOMESCREEN_ORDER: {
      return {...state, order: payload}
    }
    default:
      return state
  }
}

export const UPDATE_MENU_FILTERS = 'menus/UPDATE_MENU_FILTERS'

export const updateMenuFilters = (menuName: string, filters: any[]) => {
  tracker.trackEventWithCustomDimensionValues('menus', 'filter', {label: menuName}, {filters})
  return {type: UPDATE_MENU_FILTERS, payload: {menuName, filters}}
}

const initialMenusState = {}
function menus(state=initialMenusState, action) {
  let {type, payload} = action
  switch (type) {
    case UPDATE_MENU_FILTERS:
      return {...state, [payload.menuName]: payload.filters}
    default:
      return state
  }
}

export function aao(state={}, action) {
  return {
    homescreen: homescreen(state.homescreen, action),
    menus: menus(state.menus, action),
  }
}

const logger = createLogger()
export const store = createStore(
  aao,
  applyMiddleware(
    reduxPromise,
    reduxThunk,
    logger
  )
)

store.dispatch(loadHomescreenOrder())
<commit_msg>custom dimensions must be strings<commit_after>import {createStore, applyMiddleware} from 'redux'
import createLogger from 'redux-logger'
import reduxPromise from 'redux-promise'
import reduxThunk from 'redux-thunk'
import {AsyncStorage} from 'react-native'
import {allViewNames as defaultViewOrder} from '../views/views'
import difference from 'lodash/difference'
import {tracker} from '../analytics'

export const SAVE_HOMESCREEN_ORDER = 'SAVE_HOMESCREEN_ORDER'

export const updateViewOrder = (currentOrder, defaultOrder=defaultViewOrder) => {
  currentOrder = currentOrder || []

  // lodash/difference: Creates an array of array values _not included_ in the
  // other given arrays.

  // In case new screens have been added, get a list of the new screens
  let addedScreens = difference(defaultOrder, currentOrder)
  // check for removed screens
  let removedScreens = difference(currentOrder, defaultOrder)

  // add the new screens to the list
  currentOrder = currentOrder.concat(addedScreens)

  // now we remove the screens that were removed
  currentOrder = difference(currentOrder, removedScreens)

  return currentOrder
}

export const loadHomescreenOrder = async () => {
  // get the saved list from AsyncStorage
  let savedOrder = JSON.parse(await AsyncStorage.getItem('homescreen:view-order'))

  // update the order, in case new views have been added/removed
  let order = updateViewOrder(savedOrder, defaultViewOrder)

  // return an action to save it to AsyncStorage
  return saveHomescreenOrder(order, {noTrack: true})
}

export const saveHomescreenOrder = (order, options={}) => {
  options.noTrack || tracker.trackEventWithCustomDimensionValues('homescreen', 'reorder', {}, {order: order.join(', ')})
  AsyncStorage.setItem('homescreen:view-order', JSON.stringify(order))
  return {type: SAVE_HOMESCREEN_ORDER, payload: order}
}

const initialHomescreenState = {
  order: [],
}
function homescreen(state=initialHomescreenState, action) {
  let {type, payload} = action
  switch (type) {
    case SAVE_HOMESCREEN_ORDER: {
      return {...state, order: payload}
    }
    default:
      return state
  }
}

export const UPDATE_MENU_FILTERS = 'menus/UPDATE_MENU_FILTERS'

export const updateMenuFilters = (menuName: string, filters: any[]) => {
  tracker.trackEventWithCustomDimensionValues('menus', 'filter', {label: menuName}, {filters: JSON.stringify(filters)})
  return {type: UPDATE_MENU_FILTERS, payload: {menuName, filters}}
}

const initialMenusState = {}
function menus(state=initialMenusState, action) {
  let {type, payload} = action
  switch (type) {
    case UPDATE_MENU_FILTERS:
      return {...state, [payload.menuName]: payload.filters}
    default:
      return state
  }
}

export function aao(state={}, action) {
  return {
    homescreen: homescreen(state.homescreen, action),
    menus: menus(state.menus, action),
  }
}

const logger = createLogger()
export const store = createStore(
  aao,
  applyMiddleware(
    reduxPromise,
    reduxThunk,
    logger
  )
)

store.dispatch(loadHomescreenOrder())
<|endoftext|>


<commit_before>import HandsImage from './images/hands.jpg';
import HandsImageRetina from './images/hands@2x.jpg';
import isRetina from 'is-retina';

var backgroundImage = isRetina()? 'url('+HandsImageRetina+')': 'url('+HandsImage+')';

export default {

  base: {
    color: '#fff',
    backgroundImage: backgroundImage,
    backgroundSize: 'cover',
    backgroundColor: 'rgba(0,0,0,.5)'
  },

  content: {
    display: 'flex',
    justifyContent: 'space-between',
    backgroundColor: 'rgba(0,0,0,.5)',
    padding: '4rem',
  },

  title: {
    fontWeight: 'normal',
    marginBottom: '2rem'
  },

  teamList: {
    listStyle: 'none',
    marginTop: '5rem'
  },

  profile: {
    width: '50%'
  },

  profileImage: {
    border: '4px solid #fff',
    marginBottom: '2rem',
    width: '100%',
    height: 'auto'
  }

};
<commit_msg>Style<commit_after>import HandsImage from './images/hands.jpg';
import HandsImageRetina from './images/hands@2x.jpg';
import isRetina from 'is-retina';

var backgroundImage = isRetina()? 'url('+HandsImageRetina+')': 'url('+HandsImage+')';

export default {

  base: {
    color: '#fff',
    backgroundImage: backgroundImage,
    backgroundSize: 'cover',
    backgroundPosition: 'center'
  },

  content: {
    display: 'flex',
    justifyContent: 'space-between',
    backgroundColor: 'rgba(0,0,0,.5)',
    padding: '4rem',
  },

  title: {
    fontWeight: 'normal',
    marginBottom: '2rem'
  },

  teamList: {
    listStyle: 'none',
    marginTop: '5rem'
  },

  profile: {
    width: '50%'
  },

  profileImage: {
    border: '4px solid #fff',
    marginBottom: '2rem',
    width: '100%',
    height: 'auto'
  }

};
<|endoftext|>


<commit_before>UE.plugins['background'] = function(){
    var me = this;
    me.addListener("getAllHtml",function(type,headHtml){
        var body = this.body,
            su = domUtils.getComputedStyle(body,"background-image"),
            url="";
        if(su.indexOf(me.options.imagePath)>0){
            url =  su.substring(su.indexOf(me.options.imagePath),su.length-1).replace(/"|\(|\)/ig,"");
        }else{
            url =  su!="none" ? su.replace(/url\("?|"?\)/ig,""):"";
        }
        headHtml.html += '<style type="text/css">body{';
        var bgObj = {
            "background-color" : domUtils.getComputedStyle(body,"background-color")||"#ffffff",
            'background-image' : url ? 'url('+url+')' : '',
            'background-repeat':domUtils.getComputedStyle(body,"background-repeat")||"",
            'background-position': browser.ie?(domUtils.getComputedStyle(body,"background-position-x")+" "+domUtils.getComputedStyle(body,"background-position-y")):domUtils.getComputedStyle(body,"background-position"),
            'height':domUtils.getComputedStyle(body,"height")
        };
        for ( var name in bgObj ) {
            if ( bgObj.hasOwnProperty( name ) ) {
                headHtml.html += name+":"+bgObj[name]+";";
            }
        }
        headHtml.html += '}</style> ';
    });
}<commit_msg>by zhanyi<commit_after>UE.plugins['background'] = function(){
    var me = this;
    me.addListener("getAllHtml",function(type,headHtml){
        var body = this.body,
            su = domUtils.getComputedStyle(body,"background-image"),
            url="";
        if(su.indexOf(me.options.imagePath)>0){
            url =  su.substring(su.indexOf(me.options.imagePath),su.length-1).replace(/"|\(|\)/ig,"");
        }else{
            url =  su!="none" ? su.replace(/url\("?|"?\)/ig,""):"";
        }
        var html = '<style type="text/css">body{';
        var bgObj = {
            "background-color" : domUtils.getComputedStyle(body,"background-color")||"#ffffff",
            'background-image' : url ? 'url('+url+')' : '',
            'background-repeat':domUtils.getComputedStyle(body,"background-repeat")||"",
            'background-position': browser.ie?(domUtils.getComputedStyle(body,"background-position-x")+" "+domUtils.getComputedStyle(body,"background-position-y")):domUtils.getComputedStyle(body,"background-position"),
            'height':domUtils.getComputedStyle(body,"height")
        };
        for ( var name in bgObj ) {
            if ( bgObj.hasOwnProperty( name ) ) {
                html += name+":"+bgObj[name]+";";
            }
        }
        html += '}</style> ';
        headHtml.push(html);
    });
}<|endoftext|>


<commit_before>import mongoose from 'mongoose';
import register from './register';
import {
  getSession, authorizedForDomainOrSelf, requireSession,
  requireDomainAdministratorOrUser,
} from './auth';
import { unsetDomainIfNeeded } from './domains';
import { catcher, getPostData } from './utils';

mongoose.Promise = global.Promise;

// /api/payments

const updateForms = (payment, formIds) => {
  // update forms to record payment
  const Form = mongoose.model('Form');
  const promises = [];
  (formIds || []).forEach((formId) => {
    promises.push(Form.findOne({ _id: formId }).exec()
    .then((form) => {
      form.paymentIds.push(payment._id);
      return form.save();
    }));
  });
  return Promise.all(promises);
};

const deletePaymentRelated = (doc) => {
  const Form = mongoose.model('Form');
  Form.update(
    { paymentIds: doc._id },
    { $pull: { formIds: doc._id } },
  ).exec()
  .then(() => doc);
};

const canAdmin = (session, payment = {}) => (
  session.userId.administrator || (payment.domainId &&
    payment.domainId.equals(session.userId.administratorDomainId))
);

export default function (router) {
  register(router, {
    category: 'payments',
    modelName: 'Payment',
    omit: ['get', 'post', 'put', 'delete'], // special handling below
    index: {
      filterAuthorized: authorizedForDomainOrSelf,
      populate: [
        { path: 'userId', select: 'name' },
      ],
    },
  });

  router.get('/payments/:id', (req, res) => {
    getSession(req)
    .then(requireSession)
    // get payment
    .then((session) => {
      const id = req.params.id;
      const Payment = mongoose.model('Payment');
      return Payment.findOne({ _id: id })
      .populate({ path: 'userId', select: 'name' })
      .exec()
      .then(payment => ({ payment, session }));
    })
    // authorize
    .then((context) => {
      const { payment } = context;
      return requireDomainAdministratorOrUser(
        context, payment.domainId, payment.userId);
    })
    .then(context => res.status(200).json(context.payment))
    .catch(error => catcher(error, res));
  });

  router.post('/payments', (req, res) => {
    getSession(req)
    .then(requireSession)
    .then(session => getPostData(req).then(data => ({ session, data })))
    // .then((context) => {
    //   const { data } = context;
    //   const FormTemplate = mongoose.model('FormTemplate');
    //   return FormTemplate.findOne({ _id: data.formTemplateId }).exec()
    //   .then(formTemplate => ({ formTemplate, ...context }));
    // })
    .then((context) => {
      const { data, session } = context;
      if (canAdmin(session) && data.userId) {
        const User = mongoose.model('User');
        return User.findOne({ _id: data.userId }).exec()
        .then(user => ({ user, ...context }));
      }
      return context;
    })
    .then((context) => {
      const { data, session, user } = context;
      const Payment = mongoose.model('Payment');
      data.created = new Date();
      data.modified = data.created;
      if (!data.sent) {
        data.sent = data.created;
      }
      // Allow an administrator to set the userId. Otherwise, set it to
      // the current session user
      if (!data.userId || !canAdmin(session)) {
        data.userId = session.userId;
      }
      const useUser = user || session.userId;
      data.name = useUser.name || useUser.email;
      const payment = new Payment(data);
      return payment.save().then(doc => ({ doc, ...context }));
    })
    .then(context => updateForms(context.doc, context.data.formIds)
      .then(() => context.doc))
    .then(doc => res.status(200).send(doc))
    .catch(error => catcher(error, res));
  });

  router.put('/payments/:id', (req, res) => {
    const Payment = mongoose.model('Payment');
    getSession(req)
    .then(requireSession)
    .then(session => getPostData(req).then(data => ({ session, data })))
    // get prior payment
    .then((context) => {
      const id = req.params.id;
      return Payment.findOne({ _id: id }).exec()
      .then(payment => ({ payment, ...context }));
    })
    // authorize
    .then((context) => {
      const { payment } = context;
      return requireDomainAdministratorOrUser(
        context, payment.domainId, payment.userId);
    })
    .then((context) => {
      const { data, payment, session } = context;
      if (canAdmin(session, payment) && data.userId) {
        const User = mongoose.model('User');
        return User.findOne({ _id: data.userId }).exec()
        .then(user => ({ user, ...context }));
      }
      return context;
    })
    .then((context) => {
      const { data, session, payment, user } = context;
      // Allow an administrator to set the userId. Otherwise, set it to
      // the current session user
      if (!data.userId || !canAdmin(session, payment)) {
        data.userId = session.userId;
      }
      const useUser = user || session.userId;
      data.name = useUser.name || useUser.email;
      data.modified = new Date();
      // Have to use update in case non-admin edits something, don't want
      // to overwrite admin fields.
      return payment.update(unsetDomainIfNeeded(data, session))
      .then(() => Payment.findOne({ _id: req.params.id })
        .exec()
        .then(doc => ({ doc, data })));
    })
    .then(context => updateForms(context.doc, context.data.formIds)
      .then(() => context.doc))
    .then(doc => res.status(200).json(doc))
    .catch(error => catcher(error, res));
  });

  router.delete('/payments/:id', (req, res) => {
    getSession(req)
    .then(requireSession)
    // get prior payment
    .then((session) => {
      const id = req.params.id;
      const Payment = mongoose.model('Payment');
      return Payment.findOne({ _id: id }).exec()
      .then(payment => ({ payment, session }));
    })
    // authorize
    .then((context) => {
      const { payment } = context;
      return requireDomainAdministratorOrUser(
        context, payment.domainId, payment.userId);
    })
    // remove payment
    .then(context => context.payment.remove())
    .then(deletePaymentRelated)
    // respond
    .then(() => res.status(200).send())
    .catch(error => catcher(error, res));
  });
}
<commit_msg>Set domainId from form when posting payments.<commit_after>import mongoose from 'mongoose';
import register from './register';
import {
  getSession, authorizedForDomainOrSelf, requireSession,
  requireDomainAdministratorOrUser,
} from './auth';
import { unsetDomainIfNeeded } from './domains';
import { catcher, getPostData } from './utils';

mongoose.Promise = global.Promise;

// /api/payments

const loadPaymentForms = (context) => {
  const { data } = context;
  if (data.formIds && data.formIds.length > 0) {
    const Form = mongoose.model('Form');
    return Form.find({ _id: { $in: data.formIds } }).exec()
    .then(forms => ({ ...context, forms }));
  }
  return context;
};

const updateForms = (context) => {
  // update forms to record payment
  const { doc, forms } = context;
  forms.forEach((form) => {
    form.paymentIds.push(doc._id);
    form.save();
  });
  return context;
};

const deletePaymentRelated = (doc) => {
  const Form = mongoose.model('Form');
  Form.update(
    { paymentIds: doc._id },
    { $pull: { formIds: doc._id } },
  ).exec()
  .then(() => doc);
};

const canAdmin = (session, payment = {}) => (
  session.userId.administrator || (payment.domainId &&
    payment.domainId.equals(session.userId.administratorDomainId))
);

export default function (router) {
  register(router, {
    category: 'payments',
    modelName: 'Payment',
    omit: ['get', 'post', 'put', 'delete'], // special handling below
    index: {
      filterAuthorized: authorizedForDomainOrSelf,
      populate: [
        { path: 'userId', select: 'name' },
      ],
    },
  });

  router.get('/payments/:id', (req, res) => {
    getSession(req)
    .then(requireSession)
    // get payment
    .then((session) => {
      const id = req.params.id;
      const Payment = mongoose.model('Payment');
      return Payment.findOne({ _id: id })
      .populate({ path: 'userId', select: 'name' })
      .exec()
      .then(payment => ({ payment, session }));
    })
    // authorize
    .then((context) => {
      const { payment } = context;
      return requireDomainAdministratorOrUser(
        context, payment.domainId, payment.userId);
    })
    .then(context => res.status(200).json(context.payment))
    .catch(error => catcher(error, res));
  });

  router.post('/payments', (req, res) => {
    getSession(req)
    .then(requireSession)
    .then(session => getPostData(req).then(data => ({ session, data })))
    // .then((context) => {
    //   const { data } = context;
    //   const FormTemplate = mongoose.model('FormTemplate');
    //   return FormTemplate.findOne({ _id: data.formTemplateId }).exec()
    //   .then(formTemplate => ({ formTemplate, ...context }));
    // })
    .then((context) => {
      const { data, session } = context;
      if (canAdmin(session) && data.userId) {
        const User = mongoose.model('User');
        return User.findOne({ _id: data.userId }).exec()
        .then(user => ({ user, ...context }));
      }
      return context;
    })
    .then(loadPaymentForms)
    .then((context) => {
      const { data, forms, session, user } = context;
      const Payment = mongoose.model('Payment');
      data.created = new Date();
      data.modified = data.created;
      if (!data.sent) {
        data.sent = data.created;
      }
      // Allow an administrator to set the userId. Otherwise, set it to
      // the current session user
      if (!data.userId || !canAdmin(session)) {
        data.userId = session.userId;
      }
      const useUser = user || session.userId;
      data.name = useUser.name || useUser.email;
      if (forms && forms.length > 0) {
        data.domainId = forms[0].domainId;
      }
      const payment = new Payment(data);
      return payment.save().then(doc => ({ doc, ...context }));
    })
    .then(updateForms)
    .then(context => res.status(200).send(context.doc))
    .catch(error => catcher(error, res));
  });

  router.put('/payments/:id', (req, res) => {
    const Payment = mongoose.model('Payment');
    getSession(req)
    .then(requireSession)
    .then(session => getPostData(req).then(data => ({ session, data })))
    // get prior payment
    .then((context) => {
      const id = req.params.id;
      return Payment.findOne({ _id: id }).exec()
      .then(payment => ({ payment, ...context }));
    })
    // authorize
    .then((context) => {
      const { payment } = context;
      return requireDomainAdministratorOrUser(
        context, payment.domainId, payment.userId);
    })
    .then((context) => {
      const { data, payment, session } = context;
      if (canAdmin(session, payment) && data.userId) {
        const User = mongoose.model('User');
        return User.findOne({ _id: data.userId }).exec()
        .then(user => ({ user, ...context }));
      }
      return context;
    })
    .then(loadPaymentForms)
    .then((context) => {
      const { data, session, payment, user } = context;
      // Allow an administrator to set the userId. Otherwise, set it to
      // the current session user
      if (!data.userId || !canAdmin(session, payment)) {
        data.userId = session.userId;
      }
      const useUser = user || session.userId;
      data.name = useUser.name || useUser.email;
      data.modified = new Date();
      // Have to use update in case non-admin edits something, don't want
      // to overwrite admin fields.
      return payment.update(unsetDomainIfNeeded(data, session))
      .then(() => Payment.findOne({ _id: req.params.id })
        .exec()
        .then(doc => ({ doc, data })));
    })
    .then(updateForms)
    .then(context => res.status(200).json(context.doc))
    .catch(error => catcher(error, res));
  });

  router.delete('/payments/:id', (req, res) => {
    getSession(req)
    .then(requireSession)
    // get prior payment
    .then((session) => {
      const id = req.params.id;
      const Payment = mongoose.model('Payment');
      return Payment.findOne({ _id: id }).exec()
      .then(payment => ({ payment, session }));
    })
    // authorize
    .then((context) => {
      const { payment } = context;
      return requireDomainAdministratorOrUser(
        context, payment.domainId, payment.userId);
    })
    // remove payment
    .then(context => context.payment.remove())
    .then(deletePaymentRelated)
    // respond
    .then(() => res.status(200).send())
    .catch(error => catcher(error, res));
  });
}
<|endoftext|>


<commit_before>Ext.ns('Kwf.Maintenance');
Kwf.Maintenance.UpdateDownloader = Ext.extend(Ext.Panel, {
    border: false,
    initComponent: function() {
        this.libraryUrl = new Ext.form.TextField({
            name: 'libraryUrl',
            fieldLabel: 'Library Url',
            value: this.defaultLibraryUrl,
            width: 600
        });
        this.kwfUrl = new Ext.form.TextField({
            name: 'kwfUrl',
            fieldLabel: 'Kwf Url',
            value: this.defaultKwfUrl,
            width: 600
        });
        this.appUrl = new Ext.form.TextField({
            name: 'appUrl',
            fieldLabel: 'App Url',
            value: this.defaultAppUrl,
            width: 600
        });
        this.layout = 'form',
        this.items = [
            this.libraryUrl,
            this.kwfUrl,
            this.appUrl
        ];
        this.buttons = [{
            text: trlKwf('Download Updates'),
            handler: function() {
                Kwf.application.assetsVersion = null; //unset to avoid checking (which is problematic during update)
                Kwf.Utils.BackgroundProcess.request({
                    url: '/kwf/maintenance/update-downloader/json-download-updates',
                    params: {
                        libraryUrl: this.libraryUrl.getValue(),
                        kwfUrl: this.kwfUrl.getValue(),
                        appUrl: this.appUrl.getValue()
                    },
                    progress: true,
                    scope: this,
                    timeout: 10*60*1000,
                    success: function() {
                        //after download finished execute updates
                        Kwf.Utils.BackgroundProcess.request({
                            url: '/kwf/maintenance/update-downloader/json-execute-updates',
                            progress: true,
                            scope: this,
                            timeout: 10*60*1000,
                            success: function(response, options, r) {
                                if (r.errMsg) {
                                    Ext.Msg.alert(trlKwf('Update Error'), r.message+"
"+r.errMsg.replace("\n", "
"));
                                } else if (r.message) {
                                    Ext.Msg.alert(trlKwf('Updates Finished'), r.message, function() {
                                        locaiton.href = '/kwf/welcome';
                                    }, scope);
                                }
                            }
                        });
                    }
                });
            },
            scope: this
        }];
        Kwf.Maintenance.UpdateDownloader.superclass.initComponent.call(this);
    }
});
Ext.reg('kwf.maintenance.updateDownloader', Kwf.Maintenance.UpdateDownloader);
<commit_msg>fix redirect to welcome after update-downloader finished<commit_after>Ext.ns('Kwf.Maintenance');
Kwf.Maintenance.UpdateDownloader = Ext.extend(Ext.Panel, {
    border: false,
    initComponent: function() {
        this.libraryUrl = new Ext.form.TextField({
            name: 'libraryUrl',
            fieldLabel: 'Library Url',
            value: this.defaultLibraryUrl,
            width: 600
        });
        this.kwfUrl = new Ext.form.TextField({
            name: 'kwfUrl',
            fieldLabel: 'Kwf Url',
            value: this.defaultKwfUrl,
            width: 600
        });
        this.appUrl = new Ext.form.TextField({
            name: 'appUrl',
            fieldLabel: 'App Url',
            value: this.defaultAppUrl,
            width: 600
        });
        this.layout = 'form',
        this.items = [
            this.libraryUrl,
            this.kwfUrl,
            this.appUrl
        ];
        this.buttons = [{
            text: trlKwf('Download Updates'),
            handler: function() {
                Kwf.application.assetsVersion = null; //unset to avoid checking (which is problematic during update)
                Kwf.Utils.BackgroundProcess.request({
                    url: '/kwf/maintenance/update-downloader/json-download-updates',
                    params: {
                        libraryUrl: this.libraryUrl.getValue(),
                        kwfUrl: this.kwfUrl.getValue(),
                        appUrl: this.appUrl.getValue()
                    },
                    progress: true,
                    scope: this,
                    timeout: 10*60*1000,
                    success: function() {
                        //after download finished execute updates
                        Kwf.Utils.BackgroundProcess.request({
                            url: '/kwf/maintenance/update-downloader/json-execute-updates',
                            progress: true,
                            scope: this,
                            timeout: 10*60*1000,
                            success: function(response, options, r) {
                                if (r.errMsg) {
                                    Ext.Msg.alert(trlKwf('Update Error'), r.message+"
"+r.errMsg.replace("\n", "
"));
                                } else if (r.message) {
                                    Ext.Msg.alert(trlKwf('Updates Finished'), r.message, function() {
                                        location.href = '/kwf/welcome';
                                    }, scope);
                                }
                            }
                        });
                    }
                });
            },
            scope: this
        }];
        Kwf.Maintenance.UpdateDownloader.superclass.initComponent.call(this);
    }
});
Ext.reg('kwf.maintenance.updateDownloader', Kwf.Maintenance.UpdateDownloader);
<|endoftext|>


<commit_before>//
//  Grid Forms
//  Copyright (c) 2013 Kumail Hunaid
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

$(function() {
	var GridForms = {
		el: {
			fieldsContainers: $('[data-field-span]'),
			focusableFields: $('input, textarea, select', '[data-field-span]')
		},
		init: function() {
			this.focusField(this.el.focusableFields.filter(':focus'));
			this.events();
			this.fitGrid();
		},
		focusField: function(currentField) {
			currentField.closest('[data-field-span]').addClass('focus');
		},
		removeFieldFocus: function() {
			this.el.fieldsContainers.removeClass('focus');
		},
		events: function() {
			var that = this;
			that.el.fieldsContainers.click(function() {
				$(this).find('input, textarea, select').focus();
			});
			that.el.focusableFields.focus(function() {
				that.focusField($(this));
			});
			that.el.focusableFields.blur(function() {
				that.removeFieldFocus();
			});
			$(window).resize(function() {
				that.fitGrid();
			});

		},

		/* fixes the 'border-gap' problem which occurs
		 * when one field is taller than the other
		 */
		fitGrid: function() {
			//reset any forced sizing for the resize event
			$('[data-field-span]').css("height", "");

			//if the document is smaller than the breakpoint, don't resize them
			if($(document).width() >= 700) {
				//for each row...
				var $rows = $('[data-row-span]');
				$rows.each(function(i) {
					//get the height of the row (thus the tallest element)
					var $row = $(this);
					var rowHeight = $row.height();

					//for each field within the row...
					var $fields = $row.find('[data-field-span]');
					$fields.each(function(j) {

						//set the field's height to a uniform height
						var $field = $(this);
						$field.css("height", rowHeight.toString());
					});
				});
			}
		}
	};

	GridForms.init();
});
<commit_msg>Refactoring code fixing bugs when resizing<commit_after>//
//  Grid Forms
//  Copyright (c) 2013 Kumail Hunaid
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

$(function() {
	var GridForms = {
		el: {
			fieldsRows : $('[data-row-span]'),
			fieldsContainers: $('[data-field-span]'),
			focusableFields: $('input, textarea, select', '[data-field-span]')
		},
		init: function() {
			this.focusField(this.el.focusableFields.filter(':focus'));
			this.events();
		},
		focusField: function(currentField) {
			currentField.closest('[data-field-span]').addClass('focus');
		},
		removeFieldFocus: function() {
			this.el.fieldsContainers.removeClass('focus');
		},
		events: function() {
			var that = this;
			that.equalizeFieldHeights();
			that.el.fieldsContainers.click(function() {
				$(this).find('input, textarea, select').focus();
			});
			that.el.focusableFields.focus(function() {
				that.focusField($(this));
			});
			that.el.focusableFields.blur(function() {
				that.removeFieldFocus();
			});
			$(window).resize(function() {
				that.equalizeFieldHeights();
			});

		},
		equalizeFieldHeights: function() {
			//reset any forced sizing for the resize event
			this.el.fieldsContainers.css("height", "auto");

			//get the rows
			var rows = this.el.fieldsRows;
			var fields = this.el.fieldsContainers;

			//make sure that the fields aren't stacked
			if(this.getTotalFieldsWidth(rows) <= rows.first().width()) {
				rows.each(function() {
					//get the height of the row (thus the tallest element's height)
					var row = $(this);
					var rowHeight = row.height();

					//set the height for each field in the row...
					row.find(fields).height(rowHeight);
				});
			}
		},

		getTotalFieldsWidth : function(rows) {
			//get the first row
			//which does not only contain one field
			var firstRow = rows
				.filter(function() {
					return $(this).attr("data-row-span") !== "1";
				})
				.first();

			//get to the total width
			//of each field witin the row
			var totalWidth = 0;
			firstRow.children().each(function() {
				totalWidth += $(this).width();
			});
			return totalWidth;

		}
	};

	GridForms.init();
});
<|endoftext|>