<commit_before>import template from './template.jade';
import View from '../view/view.js';
import dom from 'dom';
import Quill from 'quill';
import merge from 'merge';

var defaults = {
  toolbar: {
    fontFace: false,
    fontSize: false,
    fontWidth: true,
    image: true,
    video: true,
    link: true,
    bullet: true,
    list: true
  },
  theme: 'snow'
};

/**
 * Wraps an input element and converts it in a Quill WYSIWYG control
 * @param {String|HTMLInputElement} Selector or domified single element
 * @param {Object} Customization options
 *
 * Usage:
 *   var richtext = require('richtext');
 *   var input = dom('input#description');
 *   richtext(input);
 *
 */

export default class RichTextView extends View {

  constructor(el, options = {}) {
    super();

    // The original input or textarea element
    this.input = 'string' === typeof el ? dom(el) : el;

    // Settings merged with options provided by callee
    this.settings = merge(defaults, options, { inheritance: true });

    super(template, this.settings);

    // Set up Quill instance
    var modules = {
        'toolbar': { container: this.find('#toolbar')[0] },
    };

    if (this.settings.toolbar.link) modules['link-tooltip'] = true;
    if (this.settings.toolbar.image) modules['image-tooltip'] = true;
    if (this.settings.toolbar.video) modules['video-tooltip'] = true;

    // Create Quill object
    this.editor = new Quill(this.find('#editor')[0], {
      modules: modules,
      theme: this.settings.theme
    });

    // If original input element has value, set it to Quill object
    if (this.input.val()) this.editor.setHTML(this.input.val());

    this.render();
  }

  switchOn() {
    this.editor.on('text-change', this.bound('ontextchange'));
  }

  ontextchange() {
    var contents = this.editor.getHTML();
    this.input.val(contents);
  }

  render() {
    if (this.input) {
      this.input.addClass('hide');
      this.el.insertAfter(this.input);
    }

    return super.render();
  }
}
<commit_msg>[richtext] Add logging<commit_after>import template from './template.jade';
import View from '../view/view.js';
import dom from 'dom';
import Quill from 'quill';
import merge from 'merge';
import debug from 'debug';

let log = debug('democracyos:richtext');

var defaults = {
  toolbar: {
    fontFace: false,
    fontSize: false,
    fontWidth: true,
    image: true,
    video: true,
    link: true,
    bullet: true,
    list: true
  },
  theme: 'snow'
};

/**
 * Wraps an input element and converts it in a Quill WYSIWYG control
 * @param {String|HTMLInputElement} Selector or domified single element
 * @param {Object} Customization options
 *
 * Usage:
 *   var richtext = require('richtext');
 *   var input = dom('input#description');
 *   richtext(input);
 *
 */

export default class RichTextView extends View {

  constructor(el, options = {}) {
    super();

    // The original input or textarea element
    this.input = 'string' === typeof el ? dom(el) : el;

    // Settings merged with options provided by callee
    this.settings = merge(defaults, options, { inheritance: true });

    super(template, this.settings);

    // Set up Quill instance
    var modules = {
        'toolbar': { container: this.find('#toolbar')[0] },
    };

    if (this.settings.toolbar.link) modules['link-tooltip'] = true;
    if (this.settings.toolbar.image) modules['image-tooltip'] = true;
    if (this.settings.toolbar.video) modules['video-tooltip'] = true;

    // Create Quill object
    this.editor = new Quill(this.find('#editor')[0], {
      modules: modules,
      theme: this.settings.theme
    });

    // If original input element has value, set it to Quill object
    if (this.input.val()) this.editor.setHTML(this.input.val());

    this.render();
  }

  switchOn() {
    this.editor.on('text-change', this.bound('ontextchange'));
  }

  ontextchange() {
    var contents = this.editor.getHTML();
    log('Text has changed: %s', contents);
    this.input.val(contents);
  }

  render() {
    if (this.input) {
      this.input.addClass('hide');
      this.el.insertAfter(this.input);
    }

    return super.render();
  }
}
<|endoftext|>


<commit_before>import Promise from 'rsvp/promise';
import { ResolvedHandlerInfo } from './handler-info';
import { trigger, slice, log, promiseLabel } from './utils';

/**
  A Transition is a thennable (a promise-like object) that represents
  an attempt to transition to another route. It can be aborted, either
  explicitly via `abort` or by attempting another transition while a
  previous one is still underway. An aborted transition can also
  be `retry()`d later.

  @class Transition
  @constructor
  @param {Object} router
  @param {Object} intent
  @param {Object} state
  @param {Object} error
  @private
 */
function Transition(router, intent, state, error) {
  var transition = this;
  this.state = state || router.state;
  this.intent = intent;
  this.router = router;
  this.data = this.intent && this.intent.data || {};
  this.resolvedModels = {};
  this.queryParams = {};

  if (error) {
    this.promise = Promise.reject(error);
    this.error = error;
    return;
  }

  if (state) {
    this.params = state.params;
    this.queryParams = state.queryParams;
    this.handlerInfos = state.handlerInfos;

    var len = state.handlerInfos.length;
    if (len) {
      this.targetName = state.handlerInfos[len-1].name;
    }

    for (var i = 0; i < len; ++i) {
      var handlerInfo = state.handlerInfos[i];

      // TODO: this all seems hacky
      if (!handlerInfo.isResolved) { break; }
      this.pivotHandler = handlerInfo.handler;
    }

    this.sequence = Transition.currentSequence++;
    this.promise = state.resolve(checkForAbort, this)['catch'](function(result) {
      if (result.wasAborted || transition.isAborted) {
        return Promise.reject(logAbort(transition));
      } else {
        transition.trigger('error', result.error, transition, result.handlerWithError);
        transition.abort();
        return Promise.reject(result.error);
      }
    }, promiseLabel('Handle Abort'));
  } else {
    this.promise = Promise.resolve(this.state);
    this.params = {};
  }

  function checkForAbort() {
    if (transition.isAborted) {
      return Promise.reject(undefined, promiseLabel("Transition aborted - reject"));
    }
  }
}

Transition.currentSequence = 0;

Transition.prototype = {
  targetName: null,
  urlMethod: 'update',
  intent: null,
  params: null,
  pivotHandler: null,
  resolveIndex: 0,
  handlerInfos: null,
  resolvedModels: null,
  isActive: true,
  state: null,
  queryParamsOnly: false,

  isTransition: true,

  isExiting: function(handler) {
    var handlerInfos = this.handlerInfos;
    for (var i = 0, len = handlerInfos.length; i < len; ++i) {
      var handlerInfo = handlerInfos[i];
      if (handlerInfo.name === handler || handlerInfo.handler === handler) {
        return false;
      }
    }
    return true;
  },

  /**
    @property promise
    @type {Object}
    @public

    The Transition's internal promise. Calling `.then` on this property
    is that same as calling `.then` on the Transition object itself, but
    this property is exposed for when you want to pass around a
    Transition's promise, but not the Transition object itself, since
    Transition object can be externally `abort`ed, while the promise
    cannot.
   */
  promise: null,

  /**
    @property data
    @type {Object}
    @public

    Custom state can be stored on a Transition's `data` object.
    This can be useful for decorating a Transition within an earlier
    hook and shared with a later hook. Properties set on `data` will
    be copied to new transitions generated by calling `retry` on this
    transition.
   */
  data: null,

  /**
    A standard promise hook that resolves if the transition
    succeeds and rejects if it fails/redirects/aborts.

    Forwards to the internal `promise` property which you can
    use in situations where you want to pass around a thennable,
    but not the Transition itself.

    @method then
    @param {Function} onFulfilled
    @param {Function} onRejected
    @param {String} label optional string for labeling the promise.
    Useful for tooling.
    @return {Promise}
    @public
   */
  then: function(onFulfilled, onRejected, label) {
    return this.promise.then(onFulfilled, onRejected, label);
  },

  /**

    Forwards to the internal `promise` property which you can
    use in situations where you want to pass around a thennable,
    but not the Transition itself.

    @method catch
    @param {Function} onRejection
    @param {String} label optional string for labeling the promise.
    Useful for tooling.
    @return {Promise}
    @public
   */
  catch: function(onRejection, label) {
    return this.promise.catch(onRejection, label);
  },

  /**

    Forwards to the internal `promise` property which you can
    use in situations where you want to pass around a thennable,
    but not the Transition itself.

    @method finally
    @param {Function} callback
    @param {String} label optional string for labeling the promise.
    Useful for tooling.
    @return {Promise}
    @public
   */
  finally: function(callback, label) {
    return this.promise.finally(callback, label);
  },

  /**
    Aborts the Transition. Note you can also implicitly abort a transition
    by initiating another transition while a previous one is underway.

    @method abort
    @return {Transition} this transition
    @public
   */
  abort: function() {
    if (this.isAborted) { return this; }
    log(this.router, this.sequence, this.targetName + ": transition was aborted");
    this.intent.preTransitionState = this.router.state;
    this.isAborted = true;
    this.isActive = false;
    this.router.activeTransition = null;
    return this;
  },

  /**

    Retries a previously-aborted transition (making sure to abort the
    transition if it's still active). Returns a new transition that
    represents the new attempt to transition.

    @method retry
    @return {Transition} new transition
    @public
   */
  retry: function() {
    // TODO: add tests for merged state retry()s
    this.abort();
    return this.router.transitionByIntent(this.intent, false);
  },

  /**

    Sets the URL-changing method to be employed at the end of a
    successful transition. By default, a new Transition will just
    use `updateURL`, but passing 'replace' to this method will
    cause the URL to update using 'replaceWith' instead. Omitting
    a parameter will disable the URL change, allowing for transitions
    that don't update the URL at completion (this is also used for
    handleURL, since the URL has already changed before the
    transition took place).

    @method method
    @param {String} method the type of URL-changing method to use
      at the end of a transition. Accepted values are 'replace',
      falsy values, or any other non-falsy value (which is
      interpreted as an updateURL transition).

    @return {Transition} this transition
    @public
   */
  method: function(method) {
    this.urlMethod = method;
    return this;
  },

  /**

    Fires an event on the current list of resolved/resolving
    handlers within this transition. Useful for firing events
    on route hierarchies that haven't fully been entered yet.

    Note: This method is also aliased as `send`

    @method trigger
    @param {Boolean} [ignoreFailure=false] a boolean specifying whether unhandled events throw an error
    @param {String} name the name of the event to fire
    @public
   */
  trigger: function (ignoreFailure) {
    var args = slice.call(arguments);
    if (typeof ignoreFailure === 'boolean') {
      args.shift();
    } else {
      // Throw errors on unhandled trigger events by default
      ignoreFailure = false;
    }
    trigger(this.router, this.state.handlerInfos.slice(0, this.resolveIndex + 1), ignoreFailure, args);
  },

  /**
    Transitions are aborted and their promises rejected
    when redirects occur; this method returns a promise
    that will follow any redirects that occur and fulfill
    with the value fulfilled by any redirecting transitions
    that occur.

    @method followRedirects
    @return {Promise} a promise that fulfills with the same
      value that the final redirecting transition fulfills with
    @public
   */
  followRedirects: function() {
    var router = this.router;
    return this.promise['catch'](function(reason) {
      if (router.activeTransition) {
        return router.activeTransition.followRedirects();
      }
      return Promise.reject(reason);
    });
  },

  toString: function() {
    return "Transition (sequence " + this.sequence + ")";
  },

  /**
    @private
   */
  log: function(message) {
    log(this.router, this.sequence, message);
  }
};

// Alias 'trigger' as 'send'
Transition.prototype.send = Transition.prototype.trigger;

/**
  @private

  Logs and returns a TransitionAborted error.
 */
function logAbort(transition) {
  log(transition.router, transition.sequence, "detected abort.");
  return new TransitionAborted();
}

function TransitionAborted(message) {
  this.message = (message || "TransitionAborted");
  this.name = "TransitionAborted";
}

export { Transition, logAbort, TransitionAborted };
<commit_msg>Move property descriptors below descriptions<commit_after>import Promise from 'rsvp/promise';
import { ResolvedHandlerInfo } from './handler-info';
import { trigger, slice, log, promiseLabel } from './utils';

/**
  A Transition is a thennable (a promise-like object) that represents
  an attempt to transition to another route. It can be aborted, either
  explicitly via `abort` or by attempting another transition while a
  previous one is still underway. An aborted transition can also
  be `retry()`d later.

  @class Transition
  @constructor
  @param {Object} router
  @param {Object} intent
  @param {Object} state
  @param {Object} error
  @private
 */
function Transition(router, intent, state, error) {
  var transition = this;
  this.state = state || router.state;
  this.intent = intent;
  this.router = router;
  this.data = this.intent && this.intent.data || {};
  this.resolvedModels = {};
  this.queryParams = {};

  if (error) {
    this.promise = Promise.reject(error);
    this.error = error;
    return;
  }

  if (state) {
    this.params = state.params;
    this.queryParams = state.queryParams;
    this.handlerInfos = state.handlerInfos;

    var len = state.handlerInfos.length;
    if (len) {
      this.targetName = state.handlerInfos[len-1].name;
    }

    for (var i = 0; i < len; ++i) {
      var handlerInfo = state.handlerInfos[i];

      // TODO: this all seems hacky
      if (!handlerInfo.isResolved) { break; }
      this.pivotHandler = handlerInfo.handler;
    }

    this.sequence = Transition.currentSequence++;
    this.promise = state.resolve(checkForAbort, this)['catch'](function(result) {
      if (result.wasAborted || transition.isAborted) {
        return Promise.reject(logAbort(transition));
      } else {
        transition.trigger('error', result.error, transition, result.handlerWithError);
        transition.abort();
        return Promise.reject(result.error);
      }
    }, promiseLabel('Handle Abort'));
  } else {
    this.promise = Promise.resolve(this.state);
    this.params = {};
  }

  function checkForAbort() {
    if (transition.isAborted) {
      return Promise.reject(undefined, promiseLabel("Transition aborted - reject"));
    }
  }
}

Transition.currentSequence = 0;

Transition.prototype = {
  targetName: null,
  urlMethod: 'update',
  intent: null,
  params: null,
  pivotHandler: null,
  resolveIndex: 0,
  handlerInfos: null,
  resolvedModels: null,
  isActive: true,
  state: null,
  queryParamsOnly: false,

  isTransition: true,

  isExiting: function(handler) {
    var handlerInfos = this.handlerInfos;
    for (var i = 0, len = handlerInfos.length; i < len; ++i) {
      var handlerInfo = handlerInfos[i];
      if (handlerInfo.name === handler || handlerInfo.handler === handler) {
        return false;
      }
    }
    return true;
  },

  /**
    The Transition's internal promise. Calling `.then` on this property
    is that same as calling `.then` on the Transition object itself, but
    this property is exposed for when you want to pass around a
    Transition's promise, but not the Transition object itself, since
    Transition object can be externally `abort`ed, while the promise
    cannot.

    @property promise
    @type {Object}
    @public
   */
  promise: null,

  /**
    Custom state can be stored on a Transition's `data` object.
    This can be useful for decorating a Transition within an earlier
    hook and shared with a later hook. Properties set on `data` will
    be copied to new transitions generated by calling `retry` on this
    transition.

    @property data
    @type {Object}
    @public
   */
  data: null,

  /**
    A standard promise hook that resolves if the transition
    succeeds and rejects if it fails/redirects/aborts.

    Forwards to the internal `promise` property which you can
    use in situations where you want to pass around a thennable,
    but not the Transition itself.

    @method then
    @param {Function} onFulfilled
    @param {Function} onRejected
    @param {String} label optional string for labeling the promise.
    Useful for tooling.
    @return {Promise}
    @public
   */
  then: function(onFulfilled, onRejected, label) {
    return this.promise.then(onFulfilled, onRejected, label);
  },

  /**

    Forwards to the internal `promise` property which you can
    use in situations where you want to pass around a thennable,
    but not the Transition itself.

    @method catch
    @param {Function} onRejection
    @param {String} label optional string for labeling the promise.
    Useful for tooling.
    @return {Promise}
    @public
   */
  catch: function(onRejection, label) {
    return this.promise.catch(onRejection, label);
  },

  /**

    Forwards to the internal `promise` property which you can
    use in situations where you want to pass around a thennable,
    but not the Transition itself.

    @method finally
    @param {Function} callback
    @param {String} label optional string for labeling the promise.
    Useful for tooling.
    @return {Promise}
    @public
   */
  finally: function(callback, label) {
    return this.promise.finally(callback, label);
  },

  /**
    Aborts the Transition. Note you can also implicitly abort a transition
    by initiating another transition while a previous one is underway.

    @method abort
    @return {Transition} this transition
    @public
   */
  abort: function() {
    if (this.isAborted) { return this; }
    log(this.router, this.sequence, this.targetName + ": transition was aborted");
    this.intent.preTransitionState = this.router.state;
    this.isAborted = true;
    this.isActive = false;
    this.router.activeTransition = null;
    return this;
  },

  /**

    Retries a previously-aborted transition (making sure to abort the
    transition if it's still active). Returns a new transition that
    represents the new attempt to transition.

    @method retry
    @return {Transition} new transition
    @public
   */
  retry: function() {
    // TODO: add tests for merged state retry()s
    this.abort();
    return this.router.transitionByIntent(this.intent, false);
  },

  /**

    Sets the URL-changing method to be employed at the end of a
    successful transition. By default, a new Transition will just
    use `updateURL`, but passing 'replace' to this method will
    cause the URL to update using 'replaceWith' instead. Omitting
    a parameter will disable the URL change, allowing for transitions
    that don't update the URL at completion (this is also used for
    handleURL, since the URL has already changed before the
    transition took place).

    @method method
    @param {String} method the type of URL-changing method to use
      at the end of a transition. Accepted values are 'replace',
      falsy values, or any other non-falsy value (which is
      interpreted as an updateURL transition).

    @return {Transition} this transition
    @public
   */
  method: function(method) {
    this.urlMethod = method;
    return this;
  },

  /**

    Fires an event on the current list of resolved/resolving
    handlers within this transition. Useful for firing events
    on route hierarchies that haven't fully been entered yet.

    Note: This method is also aliased as `send`

    @method trigger
    @param {Boolean} [ignoreFailure=false] a boolean specifying whether unhandled events throw an error
    @param {String} name the name of the event to fire
    @public
   */
  trigger: function (ignoreFailure) {
    var args = slice.call(arguments);
    if (typeof ignoreFailure === 'boolean') {
      args.shift();
    } else {
      // Throw errors on unhandled trigger events by default
      ignoreFailure = false;
    }
    trigger(this.router, this.state.handlerInfos.slice(0, this.resolveIndex + 1), ignoreFailure, args);
  },

  /**
    Transitions are aborted and their promises rejected
    when redirects occur; this method returns a promise
    that will follow any redirects that occur and fulfill
    with the value fulfilled by any redirecting transitions
    that occur.

    @method followRedirects
    @return {Promise} a promise that fulfills with the same
      value that the final redirecting transition fulfills with
    @public
   */
  followRedirects: function() {
    var router = this.router;
    return this.promise['catch'](function(reason) {
      if (router.activeTransition) {
        return router.activeTransition.followRedirects();
      }
      return Promise.reject(reason);
    });
  },

  toString: function() {
    return "Transition (sequence " + this.sequence + ")";
  },

  /**
    @private
   */
  log: function(message) {
    log(this.router, this.sequence, message);
  }
};

// Alias 'trigger' as 'send'
Transition.prototype.send = Transition.prototype.trigger;

/**
  @private

  Logs and returns a TransitionAborted error.
 */
function logAbort(transition) {
  log(transition.router, transition.sequence, "detected abort.");
  return new TransitionAborted();
}

function TransitionAborted(message) {
  this.message = (message || "TransitionAborted");
  this.name = "TransitionAborted";
}

export { Transition, logAbort, TransitionAborted };
<|endoftext|>


<commit_before>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

(function (context) {
    // Replace navigator before any modules are required(), to ensure it happens as soon as possible.
    // We replace it so that properties that can't be clobbered can instead be overridden.
    function replaceNavigator(origNavigator) {
        var CordovaNavigator = function() {};
        CordovaNavigator.prototype = origNavigator;
        var newNavigator = new CordovaNavigator();
        // This work-around really only applies to new APIs that are newer than Function.bind.
        // Without it, APIs such as getGamepads() break.
        if (CordovaNavigator.bind) {
            for (var key in origNavigator) {
                if (typeof origNavigator[key] == 'function') {
                    newNavigator[key] = origNavigator[key].bind(origNavigator);
                }
            }
        }
        return newNavigator;
    }
    if (context.navigator) {
        context.navigator = replaceNavigator(context.navigator);
    }

    var channel = require("cordova/channel");

    // _nativeReady is global variable that the native side can set
    // to signify that the native code is ready. It is a global since
    // it may be called before any cordova JS is ready.
    if (window._nativeReady) {
        channel.onNativeReady.fire();
    }

    /**
     * Create all cordova objects once page has fully loaded and native side is ready.
     */
    channel.join(function() {
        var platform = require('cordova/platform');

        // Call the platform-specific initialization
        platform.initialize();

        // Fire event to notify that all objects are created
        channel.onCordovaReady.fire();

        // Fire onDeviceReady event once all constructors have run and
        // cordova info has been received from native side.
        channel.join(function() {
            require('cordova').fireDocumentEvent('deviceready');
        }, channel.deviceReadyChannelsArray);

    }, [ channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady ]);

}(window));
<commit_msg>[all] CB-3044 log an error if start-up channels fail to fire.<commit_after>/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
*/

(function (context) {
    var channel = require('cordova/channel');
    var platfromInitChannels = [channel.onDOMContentLoaded, channel.onNativeReady, channel.onPluginsReady];

    function logUnfiredChannels(arr) {
        for (var i = 0; i < arr.length; ++i) {
            if (arr[i].state != 2) {
                console.log('Channel not fired: ' + arr[i].type);
            }
        }
    }

    window.setTimeout(function() {
        if (channel.onDeviceReady.state != 2) {
            console.log('deviceready has not fired after 5 seconds.');
            logUnfiredChannels(platfromInitChannels);
            logUnfiredChannels(channel.deviceReadyChannelsArray);
        }
    }, 5000);

    // Replace navigator before any modules are required(), to ensure it happens as soon as possible.
    // We replace it so that properties that can't be clobbered can instead be overridden.
    function replaceNavigator(origNavigator) {
        var CordovaNavigator = function() {};
        CordovaNavigator.prototype = origNavigator;
        var newNavigator = new CordovaNavigator();
        // This work-around really only applies to new APIs that are newer than Function.bind.
        // Without it, APIs such as getGamepads() break.
        if (CordovaNavigator.bind) {
            for (var key in origNavigator) {
                if (typeof origNavigator[key] == 'function') {
                    newNavigator[key] = origNavigator[key].bind(origNavigator);
                }
            }
        }
        return newNavigator;
    }
    if (context.navigator) {
        context.navigator = replaceNavigator(context.navigator);
    }

    // _nativeReady is global variable that the native side can set
    // to signify that the native code is ready. It is a global since
    // it may be called before any cordova JS is ready.
    if (window._nativeReady) {
        channel.onNativeReady.fire();
    }

    /**
     * Create all cordova objects once page has fully loaded and native side is ready.
     */
    channel.join(function() {
        var platform = require('cordova/platform');

        // Call the platform-specific initialization
        platform.initialize();

        // Fire event to notify that all objects are created
        channel.onCordovaReady.fire();

        // Fire onDeviceReady event once all constructors have run and
        // cordova info has been received from native side.
        channel.join(function() {
            require('cordova').fireDocumentEvent('deviceready');
        }, channel.deviceReadyChannelsArray);

    }, platfromInitChannels);

}(window));
<|endoftext|>


<commit_before>var fs = require('fs'),
    path = require('path'),
    util = require("util"),
    events = require("events"),
    Logger = require('../logger.js'),
    Protocol = require('./protocol.js');

function addElementCommand(protocolCommand, extraArgs) {
  var defaultUsing = 'css selector';
  var self = this;
  extraArgs = extraArgs || 0;
  var expectedArgs = 3 + extraArgs;
  return function() {
    var noopFn = function() {};
    var args  = Array.prototype.slice.call(arguments, 0);
    if (typeof args[args.length-1] != "function") {
      args.push(noopFn);
    }

    if (expectedArgs - args.length === 1) {
      args.unshift(defaultUsing);
    }

    if (args.length < expectedArgs - 1 || args.length > expectedArgs) {
      console.log(args, expectedArgs)
      throw new Error(protocolCommand + ' method expects ' + (expectedArgs - 1) + ' or ' + expectedArgs + ' arguments - ' + args.length + ' given.');
    }

    var using = args.shift(), value = args.shift();
    var callback = args.pop();

    function CommandAction() {
      events.EventEmitter.call(this);

      var $this = this;

      var el = Protocol.actions.element.call(self, using, value, function(result) {
        if (result.status !== 0) {
          callback.call(self, result);
          var errorMessage = 'Unable to locate element: "' + value + '" using: ' + using;
          self.results.errors++;
          self.errors.push(errorMessage);
          console.log(Logger.colors.red("ERROR:"), errorMessage);
          $this.emit('complete', el, $this);
        } else {
          result = result.value.ELEMENT;
          args.push(function(r) {
            callback.call(self, r);
          });
          args.unshift(result);

          var c = Protocol.actions[protocolCommand].apply(self, args).once('complete', function() {
            $this.emit('complete', c, $this);
          });
        }
      });
    };

    util.inherits(CommandAction, events.EventEmitter);

    return new CommandAction();
  }
};

module.exports = {
  addCommands : function() {
    var specs = {
      'click' : addElementCommand.call(this, 'elementIdClick'),
      'getAttribute' : addElementCommand.call(this, 'elementIdAttribute', 1),
      'getCssProperty' : addElementCommand.call(this, 'elementIdCssProperty', 1),
      'getElementSize' : addElementCommand.call(this, 'elementIdSize'),
      'getLocation' : addElementCommand.call(this, 'elementIdLocation'),
      'getLocationInView' : addElementCommand.call(this, 'elementIdLocationInView'),
      'getTagName' : addElementCommand.call(this, 'elementIdName'),
      'getText' : addElementCommand.call(this, 'elementIdText'),
      'getValue' : addElementCommand.call(this, 'elementIdValue'),
      'isVisible' : addElementCommand.call(this, 'elementIdDisplayed'),
      'setValue' : addElementCommand.call(this, 'elementIdValue', 1),
      'moveToElement' : addElementCommand.call(this, 'moveTo', 2),
      'submitForm' : addElementCommand.call(this, 'submit')
    };

    for (commandName in specs) {
      this.addCommand(commandName, specs[commandName], this);
    }

    var relativePath = '/commands/';
    var commandFiles = fs.readdirSync(__dirname + relativePath);
    for (var i = 0, len = commandFiles.length; i < len; i++) {
      if (path.extname(commandFiles[i]) == ".js") {
        var commandName = path.basename(commandFiles[i], '.js');
        var Module = require(__dirname + relativePath + commandFiles[i]);
        if (typeof Module == 'object' && Module.command) {
          var command = Module.command;
          var context = this;
        } else {
          var m = new Module();
          m.client = this;
          command = m.command;
          context = m;
        }
        this.addCommand(commandName, command, context);
      }
    }
  }
}
<commit_msg>minor refactoring<commit_after>var fs = require('fs'),
    path = require('path'),
    util = require("util"),
    events = require("events"),
    Logger = require('../logger.js'),
    Protocol = require('./protocol.js');

function addElementCommand(protocolCommand, extraArgs) {
  var defaultUsing = 'css selector';
  var self = this;
  extraArgs = extraArgs || 0;
  var expectedArgs = 3 + extraArgs;
  return function() {
    var noopFn = function() {};
    var args  = Array.prototype.slice.call(arguments, 0);
    if (typeof args[args.length-1] != "function") {
      args.push(noopFn);
    }

    if (expectedArgs - args.length === 1) {
      args.unshift(defaultUsing);
    }

    if (args.length < expectedArgs - 1 || args.length > expectedArgs) {
      throw new Error(protocolCommand + ' method expects ' + (expectedArgs - 1) + ' or ' + expectedArgs + ' arguments - ' + args.length + ' given.');
    }

    var using = args.shift(), value = args.shift();
    var callback = args.pop();

    function CommandAction() {
      events.EventEmitter.call(this);

      var $this = this;

      var el = Protocol.actions.element.call(self, using, value, function(result) {
        if (result.status !== 0) {
          callback.call(self, result);
          var errorMessage = 'Unable to locate element: "' + value + '" using: ' + using;
          self.results.errors++;
          self.errors.push(errorMessage);
          console.log(Logger.colors.red("ERROR:"), errorMessage);
          $this.emit('complete', el, $this);
        } else {
          result = result.value.ELEMENT;

          args.push(function(r) {
            callback.call(self, r);
          });

          args.unshift(result);

          var c = Protocol.actions[protocolCommand].apply(self, args).once('complete', function() {
            $this.emit('complete', c, $this);
          });
        }
      });
    };

    util.inherits(CommandAction, events.EventEmitter);

    return new CommandAction();
  }
};

module.exports = {
  addCommands : function() {
    var specs = {
      'click' : addElementCommand.call(this, 'elementIdClick'),
      'getAttribute' : addElementCommand.call(this, 'elementIdAttribute', 1),
      'getCssProperty' : addElementCommand.call(this, 'elementIdCssProperty', 1),
      'getElementSize' : addElementCommand.call(this, 'elementIdSize'),
      'getLocation' : addElementCommand.call(this, 'elementIdLocation'),
      'getLocationInView' : addElementCommand.call(this, 'elementIdLocationInView'),
      'getTagName' : addElementCommand.call(this, 'elementIdName'),
      'getText' : addElementCommand.call(this, 'elementIdText'),
      'getValue' : addElementCommand.call(this, 'elementIdValue'),
      'isVisible' : addElementCommand.call(this, 'elementIdDisplayed'),
      'moveToElement' : addElementCommand.call(this, 'moveTo', 2),
      'setValue' : addElementCommand.call(this, 'elementIdValue', 1),
      'submitForm' : addElementCommand.call(this, 'submit')
    };

    for (commandName in specs) {
      this.addCommand(commandName, specs[commandName], this);
    }

    var relativePath = '/commands/';
    var commandFiles = fs.readdirSync(__dirname + relativePath);
    for (var i = 0, len = commandFiles.length; i < len; i++) {
      if (path.extname(commandFiles[i]) == ".js") {
        var commandName = path.basename(commandFiles[i], '.js');
        var Module = require(__dirname + relativePath + commandFiles[i]);
        if (typeof Module == 'object' && Module.command) {
          var command = Module.command;
          var context = this;
        } else {
          var m = new Module();
          m.client = this;
          command = m.command;
          context = m;
        }
        this.addCommand(commandName, command, context);
      }
    }
  }
}
<|endoftext|>


<commit_before>'use strict';

var q = require('q'),
    fs = require('fs'),
    _ = require('lodash'),
    path = require('path'),
    output = require('../utils/output'),
    logger = require('../utils/logger');

module.exports = function(config){
    var deferred = q.defer(),
        progress = output.progress({label: 'Making directories'}),
        directories = [
            makeDir('tmp'),
            makeDir('app'),
            makeDir('app/lib'),
            makeDir('app/views'),
            makeDir('app/routes'),
            makeDir('app/public'),
            makeDir('app/public/vendor'),
            makeDir('app/public/admin'),
            makeDir('app/public/assets')
        ];

    logger.statement('');
    logger.statement('Creating project scaffolding...');

    progress.start();

    deleteFolderRecursive('tmp');
    deleteFolderRecursive('app');

    directories.reduce(q.when, q({})).then(
        function(){
            progress.complete();
            deferred.resolve(config);
        },
        function(err){
            progress.complete();
            logger.error('');
            logger.error(err.message);
            deferred.reject(err);
        }
    );

    return deferred.promise;

    function makeDir(newDir) {
        return function(){
            var deferred = q.defer();

            fs.mkdir(path.join(config.project.home, newDir), '775', function(err){
                if(err){
                    deferred.reject(err);
                }

                deferred.resolve();
            });

            return deferred.promise;
        }
    }

    function deleteFolderRecursive(path) {
        var files = [];
        if( fs.existsSync(path) ) {
            files = fs.readdirSync(path);
            files.forEach(function(file,index){
                var curPath = path + "/" + file;
                if(fs.lstatSync(curPath).isDirectory()) { // recurse
                    deleteFolderRecursive(curPath);
                } else { // delete file
                    fs.unlinkSync(curPath);
                }
            });
            fs.rmdirSync(path);
        }
    }
};<commit_msg>Moved files needed to start server.<commit_after>'use strict';

var q = require('q'),
    fs = require('fs'),
    _ = require('lodash'),
    path = require('path'),
    output = require('../utils/output'),
    logger = require('../utils/logger');

module.exports = function(config){
    var deferred = q.defer(),
        progress = output.progress({label: 'Making directories'}),
        directories = [
            makeDir('tmp'),
            makeDir('app'),
            makeDir('app/lib'),
            makeDir('app/views'),
            makeDir('app/routes'),
            makeDir('app/public'),
            makeDir('app/public/vendor'),
            makeDir('app/public/admin'),
            makeDir('app/public/assets'),
            copyFile('app/lib/grasshopper.js'),
            copyFile('app/routes/main.js'),
            copyFile('app/views/layout.jade'),
            copyFile('app/index.js')
        ];

    logger.statement('');
    logger.statement('Creating project scaffolding...');

    progress.start();

    deleteFolderRecursive('tmp');
    deleteFolderRecursive('app');

    directories.reduce(q.when, q({})).then(
        function(){
            progress.complete();
            deferred.resolve(config);
        },
        function(err){
            progress.complete();
            logger.error('');
            logger.error(err.message);
            deferred.reject(err);
        }
    );

    return deferred.promise;

    function makeDir(newDir) {
        return function(){
            var deferred = q.defer();

            fs.mkdir(path.join(config.project.home, newDir), '775', function(err){
                if(err){
                    deferred.reject(err);
                }

                deferred.resolve();
            });

            return deferred.promise;
        }
    }

    function copyFile(relativeSrc){
        var deferred = q.defer();

        return function(){
            fs.link(path.join(__dirname, '../../templates/sample', relativeSrc), path.join(config.project.home, relativeSrc), function(err){
                if(err){
                    deferred.reject(err);
                }

                deferred.resolve();
            });
        }
        return deferred.promise;
    }

    function deleteFolderRecursive(path) {
        var files = [];
        if( fs.existsSync(path) ) {
            files = fs.readdirSync(path);
            files.forEach(function(file,index){
                var curPath = path + "/" + file;
                if(fs.lstatSync(curPath).isDirectory()) { // recurse
                    deleteFolderRecursive(curPath);
                } else { // delete file
                    fs.unlinkSync(curPath);
                }
            });
            fs.rmdirSync(path);
        }
    }
};<|endoftext|>


<commit_before>"use strict";

const Base = require("./Base");
const Permission = require("./Permission");
const Permissions = require("../Constants").Permissions;
const VoiceState = require("./VoiceState");

/**
* Represents a server member
* @prop {String} id The ID of the member
* @prop {String} mention A string that mentions the member
* @prop {Guild} guild The guild the member is in
* @prop {Number} joinedAt Timestamp of when the member joined the guild
* @prop {String} status The member's status. Either "online", "idle", or "offline"
* @prop {Object?} game The active game the member is playing
* @prop {String} game.name The name of the active game
* @prop {Number} game.type The type of the active game (0 is default, 1 is Twitch, 2 is YouTube)
* @prop {String?} game.url The url of the active game
* @prop {VoiceState} voiceState The voice state of the member
* @prop {String?} nick The server nickname of the member
* @prop {String[]} roles An array of role IDs this member is a part of
* @prop {User} user The user object of the member
* @prop {Permission} permission The guild-wide permissions of the member
* @prop {String} defaultAvatar The hash for the default avatar of a user if there is no avatar set
* @prop {Number} createdAt Timestamp of user creation
* @prop {Boolean} bot Whether the user is an OAuth bot or not
* @prop {String} username The username of the user
* @prop {String} discriminator The discriminator of the user
* @prop {String?} avatar The hash of the user's avatar, or null if no avatar
* @prop {String} defaultAvatarURL The URL of the user's default avatar
* @prop {String} avatarURL The URL of the user's avatar which can be either a JPG or GIF
* @prop {String} staticAvatarURL The URL of the user's avatar (always a JPG)
*/
class Member extends Base {
    constructor(data, guild) {
        super(data.id);
        this.guild = guild;
        this.user = guild && guild.shard.client.users.get(data.id);
        if(!this.user && guild && data.user) {
            this.user = guild.shard.client.users.add(data.user, guild.shard.client);
        }
        if(!this.user) {
            throw new Error("User associated with Member not found: " + data.id);
        }
        this.voiceState = new VoiceState(data);
        this.update(data);
    }

    update(data) {
        this.status = data.status !== undefined ? data.status : this.status || "offline";
        this.game = data.game !== undefined ? data.game : this.game || null;
        this.joinedAt = data.joined_at !== undefined ? Date.parse(data.joined_at) : this.joinedAt;

        if(data.mute !== undefined) {
            this.voiceState.update(data);
        }

        this.nick = data.nick !== undefined ? data.nick : this.nick || null;
        if(data.roles !== undefined) {
            this.roles = data.roles;
        }
    }

    get permission() {
        if(this.id === this.guild.ownerID) {
            return new Permission(Permissions.all);
        } else {
            var permissions = this.guild.roles.get(this.guild.id).permissions.allow;
            for(var role of this.roles) {
                role = this.guild.roles.get(role);
                if(!role) {
                    continue;
                }

                var perm = role.permissions.allow;
                if(perm & Permissions.administrator) {
                    permissions = Permissions.all;
                    break;
                } else {
                    permissions |= perm;
                }
            }
            return new Permission(permissions);
        }
    }

    get username() {
        return this.user.username;
    }

    get discriminator() {
        return this.user.discriminator;
    }

    get avatar() {
        return this.user.avatar;
    }

    get bot() {
        return this.user.bot;
    }

    get createdAt() {
        return this.user.createdAt;
    }

    get defaultAvatar() {
        return this.user.defaultAvatar;
    }

    get defaultAvatarURL() {
        return this.user.defaultAvatarURL;
    }

    get staticAvatarURL(){
        return this.user.staticAvatarURL;
    }

    get avatarURL() {
        return this.user.avatarURL;
    }

    get mention() {
        return `<@!${this.id}>`;
    }

    /**
    * Edit the guild member
    * @arg {Object} options The properties to edit
    * @arg {String[]} [options.roles] The array of role IDs the user should have
    * @arg {String} [options.nick] Set the user's server nickname, "" to remove
    * @arg {Boolean} [options.mute] Server mute the user
    * @arg {Boolean} [options.deaf] Server deafen the user
    * @arg {String} [options.channelID] The ID of the voice channel to move the user to (must be in voice)
    * @returns {Promise}
    */
    edit(options) {
        return this.guild.shard.client.editGuildMember.call(this.guild.shard.client, this.guild.id, this.id, options);
    }

    /**
    * Add a role to the guild member
    * @arg {String} roleID The ID of the role
    * @returns {Promise}
    */
    addRole(roleID) {
        return this.guild.shard.client.addGuildMemberRole.call(this.guild.shard.client, this.guild.id, this.id, roleID);
    }

    /**
    * Remve a role from the guild member
    * @arg {String} roleID The ID of the role
    * @returns {Promise}
    */
    removeRole(roleID) {
        return this.guild.shard.client.removeGuildMemberRole.call(this.guild.shard.client, this.guild.id, this.id, roleID);
    }

    /**
    * Kick the member from the guild
    * @returns {Promise}
    */
    kick() {
        return this.guild.shard.client.kickGuildMember.call(this.guild.shard.client, this.guild.id, this.id);
    }

    /**
    * Ban the user from the guild
    * @arg {Number} [deleteMessageDays=0] Number of days to delete messages for
    * @returns {Promise}
    */
    ban(deleteMessageDays) {
        return this.guild.shard.client.banGuildMember.call(this.guild.shard.client, this.guild.id, this.id, deleteMessageDays);
    }

    /**
    * Unban the user from the guild
    * @returns {Promise}
    */
    unban() {
        return this.guild.shard.client.unbanGuildMember.call(this.guild.shard.client, this.guild.id, this.id);
    }
}

module.exports = Member;
<commit_msg>Fix getRESTGuildMember()<commit_after>"use strict";

const Base = require("./Base");
const Permission = require("./Permission");
const Permissions = require("../Constants").Permissions;
const VoiceState = require("./VoiceState");

/**
* Represents a server member
* @prop {String} id The ID of the member
* @prop {String} mention A string that mentions the member
* @prop {Guild} guild The guild the member is in
* @prop {Number} joinedAt Timestamp of when the member joined the guild
* @prop {String} status The member's status. Either "online", "idle", or "offline"
* @prop {Object?} game The active game the member is playing
* @prop {String} game.name The name of the active game
* @prop {Number} game.type The type of the active game (0 is default, 1 is Twitch, 2 is YouTube)
* @prop {String?} game.url The url of the active game
* @prop {VoiceState} voiceState The voice state of the member
* @prop {String?} nick The server nickname of the member
* @prop {String[]} roles An array of role IDs this member is a part of
* @prop {User} user The user object of the member
* @prop {Permission} permission The guild-wide permissions of the member
* @prop {String} defaultAvatar The hash for the default avatar of a user if there is no avatar set
* @prop {Number} createdAt Timestamp of user creation
* @prop {Boolean} bot Whether the user is an OAuth bot or not
* @prop {String} username The username of the user
* @prop {String} discriminator The discriminator of the user
* @prop {String?} avatar The hash of the user's avatar, or null if no avatar
* @prop {String} defaultAvatarURL The URL of the user's default avatar
* @prop {String} avatarURL The URL of the user's avatar which can be either a JPG or GIF
* @prop {String} staticAvatarURL The URL of the user's avatar (always a JPG)
*/
class Member extends Base {
    constructor(data, guild) {
        super(data.id);
        if((this.guild = guild)) {
            this.user = guild.shard.client.users.get(data.id);
            if(!this.user && data.user) {
                this.user = guild.shard.client.users.add(data.user, guild.shard.client);
            }
            if(!this.user) {
                throw new Error("User associated with Member not found: " + data.id);
            }
        } else {
            this.user = null;
        }
        this.voiceState = new VoiceState(data);
        this.update(data);
    }

    update(data) {
        this.status = data.status !== undefined ? data.status : this.status || "offline";
        this.game = data.game !== undefined ? data.game : this.game || null;
        this.joinedAt = data.joined_at !== undefined ? Date.parse(data.joined_at) : this.joinedAt;

        if(data.mute !== undefined) {
            this.voiceState.update(data);
        }

        this.nick = data.nick !== undefined ? data.nick : this.nick || null;
        if(data.roles !== undefined) {
            this.roles = data.roles;
        }
    }

    get permission() {
        if(this.id === this.guild.ownerID) {
            return new Permission(Permissions.all);
        } else {
            var permissions = this.guild.roles.get(this.guild.id).permissions.allow;
            for(var role of this.roles) {
                role = this.guild.roles.get(role);
                if(!role) {
                    continue;
                }

                var perm = role.permissions.allow;
                if(perm & Permissions.administrator) {
                    permissions = Permissions.all;
                    break;
                } else {
                    permissions |= perm;
                }
            }
            return new Permission(permissions);
        }
    }

    get username() {
        return this.user.username;
    }

    get discriminator() {
        return this.user.discriminator;
    }

    get avatar() {
        return this.user.avatar;
    }

    get bot() {
        return this.user.bot;
    }

    get createdAt() {
        return this.user.createdAt;
    }

    get defaultAvatar() {
        return this.user.defaultAvatar;
    }

    get defaultAvatarURL() {
        return this.user.defaultAvatarURL;
    }

    get staticAvatarURL(){
        return this.user.staticAvatarURL;
    }

    get avatarURL() {
        return this.user.avatarURL;
    }

    get mention() {
        return `<@!${this.id}>`;
    }

    /**
    * Edit the guild member
    * @arg {Object} options The properties to edit
    * @arg {String[]} [options.roles] The array of role IDs the user should have
    * @arg {String} [options.nick] Set the user's server nickname, "" to remove
    * @arg {Boolean} [options.mute] Server mute the user
    * @arg {Boolean} [options.deaf] Server deafen the user
    * @arg {String} [options.channelID] The ID of the voice channel to move the user to (must be in voice)
    * @returns {Promise}
    */
    edit(options) {
        return this.guild.shard.client.editGuildMember.call(this.guild.shard.client, this.guild.id, this.id, options);
    }

    /**
    * Add a role to the guild member
    * @arg {String} roleID The ID of the role
    * @returns {Promise}
    */
    addRole(roleID) {
        return this.guild.shard.client.addGuildMemberRole.call(this.guild.shard.client, this.guild.id, this.id, roleID);
    }

    /**
    * Remve a role from the guild member
    * @arg {String} roleID The ID of the role
    * @returns {Promise}
    */
    removeRole(roleID) {
        return this.guild.shard.client.removeGuildMemberRole.call(this.guild.shard.client, this.guild.id, this.id, roleID);
    }

    /**
    * Kick the member from the guild
    * @returns {Promise}
    */
    kick() {
        return this.guild.shard.client.kickGuildMember.call(this.guild.shard.client, this.guild.id, this.id);
    }

    /**
    * Ban the user from the guild
    * @arg {Number} [deleteMessageDays=0] Number of days to delete messages for
    * @returns {Promise}
    */
    ban(deleteMessageDays) {
        return this.guild.shard.client.banGuildMember.call(this.guild.shard.client, this.guild.id, this.id, deleteMessageDays);
    }

    /**
    * Unban the user from the guild
    * @returns {Promise}
    */
    unban() {
        return this.guild.shard.client.unbanGuildMember.call(this.guild.shard.client, this.guild.id, this.id);
    }
}

module.exports = Member;
<|endoftext|>


<commit_before>'use strict';

/**
 * svg-sprite is a Node.js module for creating SVG sprites
 *
 * @see https://github.com/jkphl/svg-sprite
 *
 * @author Joschi Kuphal <joschi@kuphal.net> (https://github.com/jkphl)
 * @copyright © 2018 Joschi Kuphal
 * @license MIT https://raw.github.com/jkphl/svg-sprite/master/LICENSE
 */

var _ = require('lodash'),
    path = require('path'),
    yaml = require('js-yaml'),
    fs = require('fs'),
    winston = require('winston'),
    /**
     * Sprite types
     *
     * @type {Array}
     */
    spriteTypes = ['css', 'view', 'defs', 'symbol', 'stack'],
    /**
     * List of default shape transformations
     *
     * @type {Array}
     */
    defaultShapeTransform = ['svgo'],
    /**
     * Default SVG configuration
     *
     * @type {Object}
     */
    defaultSVGConfig = {
        /**
         * Add a DOCTYPE declaration to SVG documents
         *
         * @type {Boolean
		 */
        doctypeDeclaration: true,
        /**
         * Add an XML declaration to SVG documents
         *
         * @type {Boolean}
         */
        xmlDeclaration: true,
        /**
         * Namespace IDs in SVG documents to avoid ID clashes
         *
         * @type {Boolean}
         */
        namespaceIDs: true,
        /**
         * Prefix the usual alphabetical Namespace IDs with a custom string
         *
         * @type {Boolean}
         */
        namespaceIDPrefix: '',
        /**
         * Namespace CSS class names in SVG documents to avoid CSS clashes
         *
         * @type {Boolean}
         */
        namespaceClassnames: true,
        /**
         * Add width and height attributes to the sprite SVG
         *
         * @type {Boolean}
         */
        dimensionAttributes: true,
        /**
         * Additional root attributes for the outermost <svg> element
         *
         * @type {Boolean}
         */
        rootAttributes: {},
        /**
         * Floating point precision for CSS positioning values
         *
         * @type {Number}
         */
        precision: -1
    };

/**
 * SVGSpriter configuration
 *
 * @param {Object} config                Configuration
 */
function SVGSpriterConfig(config) {

    // Logging
    this.log = '';
    if ('log' in config) {
        if ((config.log instanceof winston.Logger) || (_.isObject(config.log) && !_.isUndefined(config.log.level) && _.isObject(config.log.transports) && _.isFunction(config.log.log))) {
            this.log = config.log;
        } else {
            this.log = (_.isString(config.log) && (['info', 'verbose', 'debug'].indexOf(config.log) >= 0)) ? config.log : (config.log ? 'info' : '');
        }
    }
    if (_.isString(this.log)) {
        this.log = winston.createLogger({
            transports: [new winston.transports.Console({
                level: this.log || 'info',
                silent: !this.log.length,
                format: winston.format.combine(
                    winston.format.colorize(),
                    winston.format.timestamp({
                        format: 'YYYY-MM-DD HH:MM:ss'
                    }),
                    winston.format.splat(),
                    winston.format.printf(function (info) {
                        return info.timestamp + ' - ' + info.level + ': ' + info.message;
                    })
                )
            })]
        });
    }

    this.log.debug('Started logging');

    this.dest = path.resolve(config.dest || '.');

    this.log.debug('Prepared general options');

    this.shape = ('shape' in config) ? _.assign({}, config.shape || {}) : {};

    var stat, t, transforms = null;

    // Parse meta data (if configured)
    if (('meta' in this.shape) && !_.isPlainObject(this.shape.meta)) {
        var meta = _.isString(this.shape.meta) ? path.resolve(this.shape.meta) : null,
            metaFile = meta;
        stat = meta ? fs.lstatSync(meta) : null;
        this.shape.meta = {};
        if (stat) {
            if (stat.isSymbolicLink()) {
                meta = fs.readlinkSync(meta);
                stat = fs.statSync(meta);
            }
            meta = stat.isFile() ? fs.readFileSync(meta, 'utf8') : null;
            meta = meta ? yaml.safeLoad(meta) : {};
            for (var m in meta) {
                if (_.isPlainObject(meta[m])) {
                    this.shape.meta[path.join(path.dirname(m), path.basename(m, '.svg'))] = _.pick(meta[m], ['title', 'description']);
                }
            }
            this.log.debug('Processed meta data file "%s"', path.basename(metaFile));
        }
    } else {
        this.shape.meta = {};
    }

    // Parse alignment data (if configured)
    if (('align' in this.shape) && !_.isPlainObject(this.shape.align)) {
        var align = _.isString(this.shape.align) ? path.resolve(this.shape.align) : null,
            alignFile = align;
        stat = align ? fs.lstatSync(align) : null;
        this.shape.align = { '*': { '%s': 0 } };
        if (stat) {
            if (stat.isSymbolicLink()) {
                align = fs.readlinkSync(align);
                stat = fs.statSync(align);
            }
            align = stat.isFile() ? fs.readFileSync(align, 'utf8') : null;
            align = align ? yaml.safeLoad(align) : {};
            for (var a in align) {
                if (_.isPlainObject(align[a]) && Object.keys(align[a]).length) {
                    this.shape.align[a] = this.shape.align[a] || {};
                    for (var tmpl in align[a]) {
                        var template = tmpl.length ? ((tmpl.indexOf('%s') >= 0) ? tmpl : ('%s' + tmpl)) : '%s';
                        this.shape.align[path.join(path.dirname(a), path.basename(a, '.svg'))][template] = Math.max(0, Math.min(1, parseFloat(align[a][tmpl], 10)));
                    }
                }
            }
            this.log.debug('Processed alignment data file "%s"', path.basename(alignFile));
        }
    } else {
        this.shape.align = { '*': { '%s': 0 } };
    }

    // Register a sorting callback for shape names
    if (!('sort' in this.shape) || !_.isFunction(this.shape.sort)) {
        this.shape.sort = function (shape1, shape2) {
            return (shape1.id === shape2.id) ? 0 : ((shape1.id > shape2.id) ? 1 : -1);
        };
    }

    // Intermediate SVG destination
    this.shape.dest = ('dest' in this.shape) ? ('' + this.shape.dest).trim() : '';
    this.shape.dest = this.shape.dest.length ? path.resolve(this.dest, this.shape.dest) : null;

    // Expand spacing options to arrays
    this.shape.spacing = ('spacing' in this.shape) ? (this.shape.spacing || {}) : {};
    ['padding'].forEach(function (property) {
        var spacing;

        if (!_.isArray(this.spacing[property])) {
            spacing = Math.max(0, parseInt(this.spacing[property] || 0, 10));
            this.spacing[property] = { top: spacing, right: spacing, bottom: spacing, left: spacing };
        } else {
            spacing = this.spacing[property].map(function (n) {
                return Math.max(0, n);
            });
            switch (spacing.length) {
                case 1:
                    spacing = { top: spacing[0], right: spacing[0], bottom: spacing[0], left: spacing[0] };
                    break;
                case 2:
                    spacing = { top: spacing[0], right: spacing[1], bottom: spacing[0], left: spacing[1] };
                    break;
                case 3:
                    spacing = { top: spacing[0], right: spacing[1], bottom: spacing[2], left: spacing[1] };
                    break;
                default:
                    spacing = { top: spacing[0], right: spacing[1], bottom: spacing[2], left: spacing[3] };
                    break;
            }
            this.spacing[property] = spacing;
        }
    }, this.shape);

    // Prepare shape transforms
    if (('transform' in this.shape) && _.isArray(this.shape.transform)) {
        transforms = this.shape.transform;
    }

    // Alternatively use deprecated top-level transforms
    // TODO: Remove in future version
    if ('transform' in config) {
        this.log.warn('The top-level `transform` option is deprecated and will be removed in a future version. Please use `shape.transform` instead.');

        if ((transforms === null) && _.isArray(config.transform)) {
            transforms = config.transform;
        }
    }

    // Fallback: Use default transformations
    if (transforms === null) {
        transforms = defaultShapeTransform;
    }

    this.shape.transform = [];
    if (_.isArray(transforms)) {
        transformers: for (t = 0; t < transforms.length; ++t) {
            if (_.isString(transforms[t])) {
                transforms[t] = JSON.parse('{"' + transforms[t] + '":true}');
            } else if (_.isFunction(transforms[t])) {
                var custom = {};
                custom.custom = transforms[t];
                transforms[t] = custom;
            }
            if (_.isObject(transforms[t])) {
                for (var transformer in transforms[t]) {
                    var tconfig = transforms[t][transformer];
                    if ((tconfig === true) || _.isObject(tconfig) || _.isFunction(tconfig)) {
                        this.shape.transform.push([transformer, (tconfig === true) ? {} : tconfig]);
                        continue transformers;
                    }
                }
            }
        }
    }

    this.log.debug('Prepared `shape` options');

    this.svg = _.clone(defaultSVGConfig);
    this.svg = ('svg' in config) ? _.assign(this.svg, config.svg || {}) : this.svg;
    this.svg.xmlDeclaration = this.svg.xmlDeclaration || false;
    this.svg.doctypeDeclaration = this.svg.doctypeDeclaration || false;
    this.svg.dimensionAttributes = this.svg.dimensionAttributes || false;
    this.svg.rootAttributes = this.svg.rootAttributes || {};
    this.svg.precision = Math.max(-1, parseInt(this.svg.precision || -1));

    // Prepare post-processing transforms
    transforms = [];
    if ('transform' in this.svg) {
        if (_.isFunction(this.svg.transform)) {
            transforms.push(this.svg.transform);
        } else if (_.isArray(this.svg.transform)) {
            for (t = 0; t < this.svg.transform.length; ++t) {
                if (_.isFunction(this.svg.transform[t])) {
                    transforms.push(this.svg.transform[t]);
                }
            }
        }
    }
    this.svg.transform = transforms;

    this.log.debug('Prepared `svg` options');

    this.mode = this.filter(config.mode);

    this.log.debug('Prepared `mode` options');

    this.variables = _.extend({}, config.variables);

    this.log.debug('Prepared `variables` options');

    this.log.verbose('Initialized spriter configuration');
}

/**
 * Pick out the relevant mode options out of a configuration object
 *
 * @param {Object} config                Configuration object
 * @return {Object}                        Mode relevant options
 */
SVGSpriterConfig.prototype.filter = function (config) {
    var filtered = {};
    config = config || {};
    for (var m in config) {
        var modeConfig = _.isPlainObject(config[m]) ? config[m] : ((config[m] === true) ? {} : null);
        if ((modeConfig !== null) && (spriteTypes.indexOf(modeConfig.mode || m) >= 0)) {
            filtered[m] = modeConfig;
            filtered[m].mode = modeConfig.mode || m;
        }
    }
    return filtered;
};

/**
 * Module export (constructor wrapper)
 *
 * @param {Object} config                Configuration
 * @return {SVGSpriterConfig}            SVGSpriter configuration
 */
module.exports = function (config) {
    return new SVGSpriterConfig(config || {});
};
<commit_msg>config: add missing bracket in jsDoc type<commit_after>'use strict';

/**
 * svg-sprite is a Node.js module for creating SVG sprites
 *
 * @see https://github.com/jkphl/svg-sprite
 *
 * @author Joschi Kuphal <joschi@kuphal.net> (https://github.com/jkphl)
 * @copyright © 2018 Joschi Kuphal
 * @license MIT https://raw.github.com/jkphl/svg-sprite/master/LICENSE
 */

var _ = require('lodash'),
    path = require('path'),
    yaml = require('js-yaml'),
    fs = require('fs'),
    winston = require('winston'),
    /**
     * Sprite types
     *
     * @type {Array}
     */
    spriteTypes = ['css', 'view', 'defs', 'symbol', 'stack'],
    /**
     * List of default shape transformations
     *
     * @type {Array}
     */
    defaultShapeTransform = ['svgo'],
    /**
     * Default SVG configuration
     *
     * @type {Object}
     */
    defaultSVGConfig = {
        /**
         * Add a DOCTYPE declaration to SVG documents
         *
         * @type {Boolean}
		 */
        doctypeDeclaration: true,
        /**
         * Add an XML declaration to SVG documents
         *
         * @type {Boolean}
         */
        xmlDeclaration: true,
        /**
         * Namespace IDs in SVG documents to avoid ID clashes
         *
         * @type {Boolean}
         */
        namespaceIDs: true,
        /**
         * Prefix the usual alphabetical Namespace IDs with a custom string
         *
         * @type {Boolean}
         */
        namespaceIDPrefix: '',
        /**
         * Namespace CSS class names in SVG documents to avoid CSS clashes
         *
         * @type {Boolean}
         */
        namespaceClassnames: true,
        /**
         * Add width and height attributes to the sprite SVG
         *
         * @type {Boolean}
         */
        dimensionAttributes: true,
        /**
         * Additional root attributes for the outermost <svg> element
         *
         * @type {Boolean}
         */
        rootAttributes: {},
        /**
         * Floating point precision for CSS positioning values
         *
         * @type {Number}
         */
        precision: -1
    };

/**
 * SVGSpriter configuration
 *
 * @param {Object} config                Configuration
 */
function SVGSpriterConfig(config) {

    // Logging
    this.log = '';
    if ('log' in config) {
        if ((config.log instanceof winston.Logger) || (_.isObject(config.log) && !_.isUndefined(config.log.level) && _.isObject(config.log.transports) && _.isFunction(config.log.log))) {
            this.log = config.log;
        } else {
            this.log = (_.isString(config.log) && (['info', 'verbose', 'debug'].indexOf(config.log) >= 0)) ? config.log : (config.log ? 'info' : '');
        }
    }
    if (_.isString(this.log)) {
        this.log = winston.createLogger({
            transports: [new winston.transports.Console({
                level: this.log || 'info',
                silent: !this.log.length,
                format: winston.format.combine(
                    winston.format.colorize(),
                    winston.format.timestamp({
                        format: 'YYYY-MM-DD HH:MM:ss'
                    }),
                    winston.format.splat(),
                    winston.format.printf(function (info) {
                        return info.timestamp + ' - ' + info.level + ': ' + info.message;
                    })
                )
            })]
        });
    }

    this.log.debug('Started logging');

    this.dest = path.resolve(config.dest || '.');

    this.log.debug('Prepared general options');

    this.shape = ('shape' in config) ? _.assign({}, config.shape || {}) : {};

    var stat, t, transforms = null;

    // Parse meta data (if configured)
    if (('meta' in this.shape) && !_.isPlainObject(this.shape.meta)) {
        var meta = _.isString(this.shape.meta) ? path.resolve(this.shape.meta) : null,
            metaFile = meta;
        stat = meta ? fs.lstatSync(meta) : null;
        this.shape.meta = {};
        if (stat) {
            if (stat.isSymbolicLink()) {
                meta = fs.readlinkSync(meta);
                stat = fs.statSync(meta);
            }
            meta = stat.isFile() ? fs.readFileSync(meta, 'utf8') : null;
            meta = meta ? yaml.safeLoad(meta) : {};
            for (var m in meta) {
                if (_.isPlainObject(meta[m])) {
                    this.shape.meta[path.join(path.dirname(m), path.basename(m, '.svg'))] = _.pick(meta[m], ['title', 'description']);
                }
            }
            this.log.debug('Processed meta data file "%s"', path.basename(metaFile));
        }
    } else {
        this.shape.meta = {};
    }

    // Parse alignment data (if configured)
    if (('align' in this.shape) && !_.isPlainObject(this.shape.align)) {
        var align = _.isString(this.shape.align) ? path.resolve(this.shape.align) : null,
            alignFile = align;
        stat = align ? fs.lstatSync(align) : null;
        this.shape.align = { '*': { '%s': 0 } };
        if (stat) {
            if (stat.isSymbolicLink()) {
                align = fs.readlinkSync(align);
                stat = fs.statSync(align);
            }
            align = stat.isFile() ? fs.readFileSync(align, 'utf8') : null;
            align = align ? yaml.safeLoad(align) : {};
            for (var a in align) {
                if (_.isPlainObject(align[a]) && Object.keys(align[a]).length) {
                    this.shape.align[a] = this.shape.align[a] || {};
                    for (var tmpl in align[a]) {
                        var template = tmpl.length ? ((tmpl.indexOf('%s') >= 0) ? tmpl : ('%s' + tmpl)) : '%s';
                        this.shape.align[path.join(path.dirname(a), path.basename(a, '.svg'))][template] = Math.max(0, Math.min(1, parseFloat(align[a][tmpl], 10)));
                    }
                }
            }
            this.log.debug('Processed alignment data file "%s"', path.basename(alignFile));
        }
    } else {
        this.shape.align = { '*': { '%s': 0 } };
    }

    // Register a sorting callback for shape names
    if (!('sort' in this.shape) || !_.isFunction(this.shape.sort)) {
        this.shape.sort = function (shape1, shape2) {
            return (shape1.id === shape2.id) ? 0 : ((shape1.id > shape2.id) ? 1 : -1);
        };
    }

    // Intermediate SVG destination
    this.shape.dest = ('dest' in this.shape) ? ('' + this.shape.dest).trim() : '';
    this.shape.dest = this.shape.dest.length ? path.resolve(this.dest, this.shape.dest) : null;

    // Expand spacing options to arrays
    this.shape.spacing = ('spacing' in this.shape) ? (this.shape.spacing || {}) : {};
    ['padding'].forEach(function (property) {
        var spacing;

        if (!_.isArray(this.spacing[property])) {
            spacing = Math.max(0, parseInt(this.spacing[property] || 0, 10));
            this.spacing[property] = { top: spacing, right: spacing, bottom: spacing, left: spacing };
        } else {
            spacing = this.spacing[property].map(function (n) {
                return Math.max(0, n);
            });
            switch (spacing.length) {
                case 1:
                    spacing = { top: spacing[0], right: spacing[0], bottom: spacing[0], left: spacing[0] };
                    break;
                case 2:
                    spacing = { top: spacing[0], right: spacing[1], bottom: spacing[0], left: spacing[1] };
                    break;
                case 3:
                    spacing = { top: spacing[0], right: spacing[1], bottom: spacing[2], left: spacing[1] };
                    break;
                default:
                    spacing = { top: spacing[0], right: spacing[1], bottom: spacing[2], left: spacing[3] };
                    break;
            }
            this.spacing[property] = spacing;
        }
    }, this.shape);

    // Prepare shape transforms
    if (('transform' in this.shape) && _.isArray(this.shape.transform)) {
        transforms = this.shape.transform;
    }

    // Alternatively use deprecated top-level transforms
    // TODO: Remove in future version
    if ('transform' in config) {
        this.log.warn('The top-level `transform` option is deprecated and will be removed in a future version. Please use `shape.transform` instead.');

        if ((transforms === null) && _.isArray(config.transform)) {
            transforms = config.transform;
        }
    }

    // Fallback: Use default transformations
    if (transforms === null) {
        transforms = defaultShapeTransform;
    }

    this.shape.transform = [];
    if (_.isArray(transforms)) {
        transformers: for (t = 0; t < transforms.length; ++t) {
            if (_.isString(transforms[t])) {
                transforms[t] = JSON.parse('{"' + transforms[t] + '":true}');
            } else if (_.isFunction(transforms[t])) {
                var custom = {};
                custom.custom = transforms[t];
                transforms[t] = custom;
            }
            if (_.isObject(transforms[t])) {
                for (var transformer in transforms[t]) {
                    var tconfig = transforms[t][transformer];
                    if ((tconfig === true) || _.isObject(tconfig) || _.isFunction(tconfig)) {
                        this.shape.transform.push([transformer, (tconfig === true) ? {} : tconfig]);
                        continue transformers;
                    }
                }
            }
        }
    }

    this.log.debug('Prepared `shape` options');

    this.svg = _.clone(defaultSVGConfig);
    this.svg = ('svg' in config) ? _.assign(this.svg, config.svg || {}) : this.svg;
    this.svg.xmlDeclaration = this.svg.xmlDeclaration || false;
    this.svg.doctypeDeclaration = this.svg.doctypeDeclaration || false;
    this.svg.dimensionAttributes = this.svg.dimensionAttributes || false;
    this.svg.rootAttributes = this.svg.rootAttributes || {};
    this.svg.precision = Math.max(-1, parseInt(this.svg.precision || -1));

    // Prepare post-processing transforms
    transforms = [];
    if ('transform' in this.svg) {
        if (_.isFunction(this.svg.transform)) {
            transforms.push(this.svg.transform);
        } else if (_.isArray(this.svg.transform)) {
            for (t = 0; t < this.svg.transform.length; ++t) {
                if (_.isFunction(this.svg.transform[t])) {
                    transforms.push(this.svg.transform[t]);
                }
            }
        }
    }
    this.svg.transform = transforms;

    this.log.debug('Prepared `svg` options');

    this.mode = this.filter(config.mode);

    this.log.debug('Prepared `mode` options');

    this.variables = _.extend({}, config.variables);

    this.log.debug('Prepared `variables` options');

    this.log.verbose('Initialized spriter configuration');
}

/**
 * Pick out the relevant mode options out of a configuration object
 *
 * @param {Object} config                Configuration object
 * @return {Object}                        Mode relevant options
 */
SVGSpriterConfig.prototype.filter = function (config) {
    var filtered = {};
    config = config || {};
    for (var m in config) {
        var modeConfig = _.isPlainObject(config[m]) ? config[m] : ((config[m] === true) ? {} : null);
        if ((modeConfig !== null) && (spriteTypes.indexOf(modeConfig.mode || m) >= 0)) {
            filtered[m] = modeConfig;
            filtered[m].mode = modeConfig.mode || m;
        }
    }
    return filtered;
};

/**
 * Module export (constructor wrapper)
 *
 * @param {Object} config                Configuration
 * @return {SVGSpriterConfig}            SVGSpriter configuration
 */
module.exports = function (config) {
    return new SVGSpriterConfig(config || {});
};
<|endoftext|>


<commit_before>var winston = require('winston');
var moment = require('moment');
var getSecret = require('./docker-secrets').getDockerSecret;

function getLogger(nconf) {
  var log_level = nconf.get('loglevel');
  var logger = new (winston.Logger)({
    transports: [
      new (winston.transports.Console)({
        "level": log_level,
        "json": nconf.get('json'),
        "timestamp": function() {
          return moment();
        }
      })
    ]
  });
  var logzio_token_file = nconf.get("LOGZIO_TOKEN_FILE");
  if (logzio_token_file) {
    getSecret(logzio_token_file, (line) => {
      var logzioWinstonTransport = require('winston-logzio');
      var loggerOptions = {
          token: line.trim(),
          host: 'listener.logz.io',
      };
      logger.add(logzioWinstonTransport, loggerOptions);
    })
  }
  return logger
}
module.exports.getLogger = getLogger;
<commit_msg>Yet another reference to docker-secrets that needs to go<commit_after>var winston = require('winston');
var moment = require('moment');
let fs = require('fs')

function getLogger(nconf) {
  var log_level = nconf.get('loglevel');
  var logger = new (winston.Logger)({
    transports: [
      new (winston.transports.Console)({
        "level": log_level,
        "json": nconf.get('json'),
        "timestamp": function() {
          return moment();
        }
      })
    ]
  });
  var logzioTokenFile = nconf.get("LOGZIO_TOKEN_FILE");
  if (logzioTokenFile) {
    let logzioToken = fs.readFileSync(logzioTokenFile, 'utf8').trim()
    var logzioWinstonTransport = require('winston-logzio');
    var loggerOptions = {
        token: logzioToken,
        host: 'listener.logz.io',
    };
    logger.add(logzioWinstonTransport, loggerOptions);
  }
  return logger
}
module.exports.getLogger = getLogger;
<|endoftext|>


<commit_before>var selectorName = '(-?[_a-z]+[_\\w-]*)';
var selectorSuffix = '((?=[\\s:#\\.\\{,\\>\\~+\\[\\]]))(?=.*{)';

/**
 * Some awesome expressions that I'll explain in a bit.
 * Test these dope boats live on http://scriptular.com/ to make your life easier.
 */
module.exports = {
	/**
	 * Selector name extracts valid selector names from selectors. Basically we use the selector
	 * expression to find the selectors, then use this to extract the actual name which need to be
	 * shortened.
	 *
	 * Should match:
	 * - selector
	 * - -selector
	 * - _selector
	 * - selector0
	 *
	 * Shouldn't match:
	 * - 3selector
	 * - :selector
	 */
	selectorName: new RegExp(selectorName, 'g'),
	/**
	 * Selectors should match any classes and ids defined in a stylesheet.
	 *
	 * NOTE: This will also match hex values but will capture the close ; or } so that it can be
	 * ignored later.
	 *
	 * Should match:
	 * - #selector
	 * - .selector
	 * - #e6e6e6;
	 *
	 * Shouldn't match:
	 * - body
	 * - #666
	 * - :pseudo
	 * - url('foobar.classname')
	 * - other stupid stuff...I dunno check the tests
	 */
	classSelector: new RegExp('(\\.|\\[class[\\^\\$\\|\\*]?=)' + selectorName + selectorSuffix, 'gsi'),
	idSelector: new RegExp('(#|\\[id[\\^\\$\\|\\*]?=)' + selectorName + selectorSuffix, 'gsi'),
	/**
	 * Matches HTML class, id, and for attributes. I think those are the only ones we care about...
	 *
	 * NOTE: This expression should also match attributes with spaces between the assignment, e.g.
	 *
	 * Should match:
	 * - class="selector"
	 * - class="selector selector"
	 * - id="selector"
	 * - for="selector"
	 *
	 * Shouldn't match:
	 * - name="selector"
	 * - href="selector"
	 */
	elementAttribute: /(class|id|for)\s*=\s*["'](-?[_a-zA-Z]+[_\w-\s]*)["']/g,
	/**
	 * Matches ID Values
	 *
	 * All values can be single values or lists and lists can be either comma separated (each val is surrounded by single or double quotes OR a space separated list with not internal quotes (only quotes at beginning and end).
	 * .getElementById
	 * .id
	 * $ Only matches values with "#"
	 * jQuery Only matches values with "#"
	 * .attr This has a known bug. There is no way to differentiate the leading "class" from "id" in attr without look-behind, which javascript does not support. Therefore, all matches using this regex need to be filtered to remove results which are lists that have "class" as the first value.
	 */
	idList: /(?:\$|jQuery|(?:\.(?:getElementById|id|jQuery|attr)))\s*[\(=]{1}\s*(["']{1}#?-?[_a-zA-Z]+[_\w-]*(?:(?:(?:["']{1}\s*,\s*["']{1})|\s+){1}#?-?[_a-zA-Z]+[_\w-]*)*["']{1})/,
	/**
	 * Matches Class Values
	 *
	 * All values can be single values or lists and lists can be either comma separated (each val is surrounded by single or double quotes OR a space separated list with not internal quotes (only quotes at beginning and end).
	 * .getElementsByClassName
	 * .classList.add
	 * .classList.remove
	 * .className
	 * $ Only matches values with "."
	 * jQuery Only matches values with "."
	 * .addClass
	 * .toggleClass
	 * .removeClass
	 * .attr This has a known bug. There is no way to differentiate the leading "class" from "id" in attr without look-behind, which javascript does not support. Therefore, all matches using this regex need to be filtered to remove results which are lists that have "id" as the first value.
	 * .hasClass
	 */
	classList: /(?:\$|jQuery|(?:\.(?:getElementsByClassName|classList\.add|classList\.remove|className|jQuery|addClass|toggleClass|removeClass|attr|hasClass)))\s*[\(=]{1}\s*(["']{1}\.?-?[_a-zA-Z]+[_\w-]*(?:(?:(?:["']{1}\s*,\s*["']{1})|\s+){1}\.?-?[_a-zA-Z]+[_\w-]*)*["']{1})/,
	/**
	 * Builds a regular expression which will match a quoted string.
	 *
	 * @param name String of selector name
	 * @returns {RegExp}
	 */
	jsString: function(name) {
		return new RegExp('[\'|"]' + name + '[\'|"]', 'g');
	}
};
<commit_msg>Drop single line modifier from css selectors<commit_after>var selectorName = '(-?[_a-z]+[_\\w-]*)';
var selectorSuffix = '((?=[\\s:#\\.\\{,\\>\\~+\\[\\]]))(?=(?:.|\n|\r)*{)';

/**
 * Some awesome expressions that I'll explain in a bit.
 * Test these dope boats live on http://scriptular.com/ to make your life easier.
 */
module.exports = {
	/**
	 * Selector name extracts valid selector names from selectors. Basically we use the selector
	 * expression to find the selectors, then use this to extract the actual name which need to be
	 * shortened.
	 *
	 * Should match:
	 * - selector
	 * - -selector
	 * - _selector
	 * - selector0
	 *
	 * Shouldn't match:
	 * - 3selector
	 * - :selector
	 */
	selectorName: new RegExp(selectorName, 'g'),
	/**
	 * Selectors should match any classes and ids defined in a stylesheet.
	 *
	 * NOTE: This will also match hex values but will capture the close ; or } so that it can be
	 * ignored later.
	 *
	 * Should match:
	 * - #selector
	 * - .selector
	 * - #e6e6e6;
	 *
	 * Shouldn't match:
	 * - body
	 * - #666
	 * - :pseudo
	 * - url('foobar.classname')
	 * - other stupid stuff...I dunno check the tests
	 */
	classSelector: new RegExp('(\\.|\\[class[\\^\\$\\|\\*]?=)' + selectorName + selectorSuffix, 'gi'),
	idSelector: new RegExp('(#|\\[id[\\^\\$\\|\\*]?=)' + selectorName + selectorSuffix, 'gi'),
	/**
	 * Matches HTML class, id, and for attributes. I think those are the only ones we care about...
	 *
	 * NOTE: This expression should also match attributes with spaces between the assignment, e.g.
	 *
	 * Should match:
	 * - class="selector"
	 * - class="selector selector"
	 * - id="selector"
	 * - for="selector"
	 *
	 * Shouldn't match:
	 * - name="selector"
	 * - href="selector"
	 */
	elementAttribute: /(class|id|for)\s*=\s*["'](-?[_a-zA-Z]+[_\w-\s]*)["']/g,
	/**
	 * Matches ID Values
	 *
	 * All values can be single values or lists and lists can be either comma separated (each val is surrounded by single or double quotes OR a space separated list with not internal quotes (only quotes at beginning and end).
	 * .getElementById
	 * .id
	 * $ Only matches values with "#"
	 * jQuery Only matches values with "#"
	 * .attr This has a known bug. There is no way to differentiate the leading "class" from "id" in attr without look-behind, which javascript does not support. Therefore, all matches using this regex need to be filtered to remove results which are lists that have "class" as the first value.
	 */
	idList: /(?:\$|jQuery|(?:\.(?:getElementById|id|jQuery|attr)))\s*[\(=]{1}\s*(["']{1}#?-?[_a-zA-Z]+[_\w-]*(?:(?:(?:["']{1}\s*,\s*["']{1})|\s+){1}#?-?[_a-zA-Z]+[_\w-]*)*["']{1})/,
	/**
	 * Matches Class Values
	 *
	 * All values can be single values or lists and lists can be either comma separated (each val is surrounded by single or double quotes OR a space separated list with not internal quotes (only quotes at beginning and end).
	 * .getElementsByClassName
	 * .classList.add
	 * .classList.remove
	 * .className
	 * $ Only matches values with "."
	 * jQuery Only matches values with "."
	 * .addClass
	 * .toggleClass
	 * .removeClass
	 * .attr This has a known bug. There is no way to differentiate the leading "class" from "id" in attr without look-behind, which javascript does not support. Therefore, all matches using this regex need to be filtered to remove results which are lists that have "id" as the first value.
	 * .hasClass
	 */
	classList: /(?:\$|jQuery|(?:\.(?:getElementsByClassName|classList\.add|classList\.remove|className|jQuery|addClass|toggleClass|removeClass|attr|hasClass)))\s*[\(=]{1}\s*(["']{1}\.?-?[_a-zA-Z]+[_\w-]*(?:(?:(?:["']{1}\s*,\s*["']{1})|\s+){1}\.?-?[_a-zA-Z]+[_\w-]*)*["']{1})/,
	/**
	 * Builds a regular expression which will match a quoted string.
	 *
	 * @param name String of selector name
	 * @returns {RegExp}
	 */
	jsString: function(name) {
		return new RegExp('[\'|"]' + name + '[\'|"]', 'g');
	}
};
<|endoftext|>