<commit_before>'use strict';

var $ = require('jquery'),
    TimePickerComponent = require('./TimePickerComponent');

require('../libs/pikaday/plugins/pikaday.jquery');
require('../libs/select2/dist/js/select2.min');
require('../libs/spectrum/spectrum');

function PulsarFormComponent(html) {
    this.$html = html;
    this.timePickerComponent = new TimePickerComponent();
}

PulsarFormComponent.prototype.init = function () {
    var component = this;

    // Colour picker
    component.initColourpickers();

    // Date picker
    component.initDatePickers();

    // Choice block
    component.initSelectionButtons();

    // Select2
    component.initSelect2(component.$html.find('.js-select2:not([data-init="false"])'));

    // Time picker
    component.initTimePickers();

    // reinitialise select2 items in a tab when the tab is focused to fix widths
    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
        var $target = $($(e.target).attr('href')),
            $select2 = $target.find('.js-select2:not([data-init="false"])');

        $.each($select2, function() {
            component.initSelect2($(this));
        });
    });

    // reinitialise select2 items when opening a modal to fix widths
    $('[data-toggle="modal"]').on('click', function (e) {
        var $target = $($(e.target).attr('href')),
            $select2 = $target.find('.js-select2:not([data-init="false"])');

        $target.on('shown.bs.modal', function() {
            $.each($select2, function() {
                component.initSelect2($(this));
            });
        });
    });
}

/**
 * Re-initialise the Form Component Services
 * I've intentionally left out Select2 here, as programmatic
 * control often requires more custom behaviour than simply re-init'ing
 */
PulsarFormComponent.prototype.refresh = function () {
    // Colour picker
    this.initColourpickers();

    // Date picker
    this.initDatePickers();

    // Choice block
    this.initSelectionButtons();

    // Time picker
    this.initTimePickers();
}

/**
 * Initiate a time picker on data-timepicker fields
 */
PulsarFormComponent.prototype.initTimePickers = function () {
    this.timePickerComponent.init(this.$html.find('[data-timepicker=true]'));
}

/**
 * Initiate a date picker on data-datepicker fields using pickaday
 */
PulsarFormComponent.prototype.initDatePickers = function () {
    const datepickers = this.$html.find('[data-datepicker="true"]');
    let defaultDateFormat = 'DD/MM/YYYY';

    datepickers.each((index, element) => {
        const dateFormat = element.getAttribute('data-format');

        // Add missing data-format to hardcoded examples and initialize pikaday
        if (!dateFormat) {
            element.setAttribute('data-format', 'default');
        } else {
            switch (dateFormat) {
                case 'US':
                    defaultDateFormat = 'MM/DD/YYYY';
                    break;
                case 'reverse':
                    defaultDateFormat = 'YYYY/MM/DD';
                    break;
            }
        }

        // Initialize pikaday with the correct date format
        $(element).pikaday({ format: defaultDateFormat });
    });
}

/**
 * Initiate colour pickers
 */
PulsarFormComponent.prototype.initColourpickers = function () {
    var component = this,
        pickers = component.$html.find('.js-colorpicker');

    pickers.each(function() {

        var $this = $(this),
            $input = $this.find('.form__control'),
            $pickerInput = $('<input type="hidden" data-colour-picker-input>'),
            disabledAttr = $input.attr('disabled'),
            isDisabled = false,
            existingPicker = $input.next('[data-colour-picker-input]');

        if (typeof disabledAttr !== typeof undefined && disabledAttr !== false) {
            isDisabled = true;
        }

        if (existingPicker.length) {
            // Remove existing colour picker elements,
            // frustratingly invoking the spectrum 'destroy'
            // method does not remove the sp-replacer
            $pickerInput.spectrum('destroy');
            existingPicker.remove();
            $input.siblings('.sp-replacer').remove();
        }

        $pickerInput.insertAfter($input);

        // changing the picker should update the input
        $pickerInput.spectrum({
            color: '#' + $input.val(),
            disabled: isDisabled,
            showInput: false,
            preferredFormat: 'hex',
            replacerClassName: 'btn',
            change: function (color) {
                if (!$input.attr('disabled')) {
                    $input.val(('' + color).substring(1));
                    $input.trigger('change');
                }
            }
        });

        // changing the input should update the picker
        $input.on('change', function () {
            $pickerInput.spectrum('set', '#' + $input.val());
        });
    });
}

/**
 * Update colour pickers within a scope
 * @param $root
 */
PulsarFormComponent.prototype.updateColourPicker = function ($root) {
    const $input = $root.find('.js-colorpicker .form__control');

    $input.each((index, element) => {
        const $input = $(element);
        const $picker = $input.next();

        $picker.spectrum('set', `#${$input.val()}`);
    });
}

/**
 * Initiate Selection Buttons
 */
PulsarFormComponent.prototype.initSelectionButtons = function () {
    const choiceblock = this.$html.find('.choice--block');

    choiceblock
        .find('input[type="checkbox"]:checked, input[type="radio"]:checked')
        .closest('.control__label')
        .addClass('is-selected');

    choiceblock
        .on('change', '.controls input[type="checkbox"], .controls input[type="radio"]', this.selectionButtons);
}

/**
 * Selection Button className logic
 */
PulsarFormComponent.prototype.selectionButtons = function () {
    var $target = $(this),
        $controls = $target.closest('.controls');

    $controls.find('input[type="checkbox"]:not(:checked), input[type="radio"]:not(:checked)')
        .closest('.control__label')
        .removeClass('is-selected');

    if ($target.is(':checked')) {
        $target.closest('.control__label').addClass('is-selected');
    } else {
        $target.closest('.control__label').removeClass('is-selected');
    }
}

/**
 * Initiate Select2
 * @param target
 */
PulsarFormComponent.prototype.initSelect2 = function (target) {
    var $target = target;

    $target.each(function() {
        var $this = $(this),
            config = {};

        function formatOption(data) {
            return $('' + data.text + '');
        }

        if ($this.data('html')) {
            config.templateResult = formatOption;
            config.templateSelection = formatOption;
        }

        $this.select2(config);
        $this.parent().find('.select2-container').removeAttr('style');
    });
}

module.exports = PulsarFormComponent;
<commit_msg>Restore default switch case<commit_after>'use strict';

var $ = require('jquery'),
    TimePickerComponent = require('./TimePickerComponent');

require('../libs/pikaday/plugins/pikaday.jquery');
require('../libs/select2/dist/js/select2.min');
require('../libs/spectrum/spectrum');

function PulsarFormComponent(html) {
    this.$html = html;
    this.timePickerComponent = new TimePickerComponent();
}

PulsarFormComponent.prototype.init = function () {
    var component = this;

    // Colour picker
    component.initColourpickers();

    // Date picker
    component.initDatePickers();

    // Choice block
    component.initSelectionButtons();

    // Select2
    component.initSelect2(component.$html.find('.js-select2:not([data-init="false"])'));

    // Time picker
    component.initTimePickers();

    // reinitialise select2 items in a tab when the tab is focused to fix widths
    $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
        var $target = $($(e.target).attr('href')),
            $select2 = $target.find('.js-select2:not([data-init="false"])');

        $.each($select2, function() {
            component.initSelect2($(this));
        });
    });

    // reinitialise select2 items when opening a modal to fix widths
    $('[data-toggle="modal"]').on('click', function (e) {
        var $target = $($(e.target).attr('href')),
            $select2 = $target.find('.js-select2:not([data-init="false"])');

        $target.on('shown.bs.modal', function() {
            $.each($select2, function() {
                component.initSelect2($(this));
            });
        });
    });
}

/**
 * Re-initialise the Form Component Services
 * I've intentionally left out Select2 here, as programmatic
 * control often requires more custom behaviour than simply re-init'ing
 */
PulsarFormComponent.prototype.refresh = function () {
    // Colour picker
    this.initColourpickers();

    // Date picker
    this.initDatePickers();

    // Choice block
    this.initSelectionButtons();

    // Time picker
    this.initTimePickers();
}

/**
 * Initiate a time picker on data-timepicker fields
 */
PulsarFormComponent.prototype.initTimePickers = function () {
    this.timePickerComponent.init(this.$html.find('[data-timepicker=true]'));
}

/**
 * Initiate a date picker on data-datepicker fields using pickaday
 */
PulsarFormComponent.prototype.initDatePickers = function () {
    const datepickers = this.$html.find('[data-datepicker="true"]');
    let defaultDateFormat = 'DD/MM/YYYY';

    datepickers.each((index, element) => {
        const dateFormat = element.getAttribute('data-format');

        // Add missing data-format to hardcoded examples
        if (!dateFormat) {
            element.setAttribute('data-format', 'default');
        } else {
            switch (dateFormat) {
                case 'US':
                    defaultDateFormat = 'MM/DD/YYYY';
                    break;
                case 'reverse':
                    defaultDateFormat = 'YYYY/MM/DD';
                    break;
                default:
                    defaultDateFormat = 'DD/MM/YYYY';
            }
        }

        // Initialize pikaday with the correct date format
        $(element).pikaday({ format: defaultDateFormat });
    });
}

/**
 * Initiate colour pickers
 */
PulsarFormComponent.prototype.initColourpickers = function () {
    var component = this,
        pickers = component.$html.find('.js-colorpicker');

    pickers.each(function() {

        var $this = $(this),
            $input = $this.find('.form__control'),
            $pickerInput = $('<input type="hidden" data-colour-picker-input>'),
            disabledAttr = $input.attr('disabled'),
            isDisabled = false,
            existingPicker = $input.next('[data-colour-picker-input]');

        if (typeof disabledAttr !== typeof undefined && disabledAttr !== false) {
            isDisabled = true;
        }

        if (existingPicker.length) {
            // Remove existing colour picker elements,
            // frustratingly invoking the spectrum 'destroy'
            // method does not remove the sp-replacer
            $pickerInput.spectrum('destroy');
            existingPicker.remove();
            $input.siblings('.sp-replacer').remove();
        }

        $pickerInput.insertAfter($input);

        // changing the picker should update the input
        $pickerInput.spectrum({
            color: '#' + $input.val(),
            disabled: isDisabled,
            showInput: false,
            preferredFormat: 'hex',
            replacerClassName: 'btn',
            change: function (color) {
                if (!$input.attr('disabled')) {
                    $input.val(('' + color).substring(1));
                    $input.trigger('change');
                }
            }
        });

        // changing the input should update the picker
        $input.on('change', function () {
            $pickerInput.spectrum('set', '#' + $input.val());
        });
    });
}

/**
 * Update colour pickers within a scope
 * @param $root
 */
PulsarFormComponent.prototype.updateColourPicker = function ($root) {
    const $input = $root.find('.js-colorpicker .form__control');

    $input.each((index, element) => {
        const $input = $(element);
        const $picker = $input.next();

        $picker.spectrum('set', `#${$input.val()}`);
    });
}

/**
 * Initiate Selection Buttons
 */
PulsarFormComponent.prototype.initSelectionButtons = function () {
    const choiceblock = this.$html.find('.choice--block');

    choiceblock
        .find('input[type="checkbox"]:checked, input[type="radio"]:checked')
        .closest('.control__label')
        .addClass('is-selected');

    choiceblock
        .on('change', '.controls input[type="checkbox"], .controls input[type="radio"]', this.selectionButtons);
}

/**
 * Selection Button className logic
 */
PulsarFormComponent.prototype.selectionButtons = function () {
    var $target = $(this),
        $controls = $target.closest('.controls');

    $controls.find('input[type="checkbox"]:not(:checked), input[type="radio"]:not(:checked)')
        .closest('.control__label')
        .removeClass('is-selected');

    if ($target.is(':checked')) {
        $target.closest('.control__label').addClass('is-selected');
    } else {
        $target.closest('.control__label').removeClass('is-selected');
    }
}

/**
 * Initiate Select2
 * @param target
 */
PulsarFormComponent.prototype.initSelect2 = function (target) {
    var $target = target;

    $target.each(function() {
        var $this = $(this),
            config = {};

        function formatOption(data) {
            return $('' + data.text + '');
        }

        if ($this.data('html')) {
            config.templateResult = formatOption;
            config.templateSelection = formatOption;
        }

        $this.select2(config);
        $this.parent().find('.select2-container').removeAttr('style');
    });
}

module.exports = PulsarFormComponent;
<|endoftext|>


<commit_before>/**
 * context menu
 */

define([
    'jquery',
    'app/ccp'
], function($, CCP) {

    'use strict';

    $.fn.contextMenu = function (settings) {

        // animation
        var animationInType = CCP.isInGameBrowser() ? 'fadeIn' : 'transition.flipXIn';
        var animationInDuration = CCP.isInGameBrowser() ? 0 : 150;
        var animationOutType = CCP.isInGameBrowser() ? 'fadeOut' : 'transition.flipXOut';
        var animationOutDuration = CCP.isInGameBrowser() ? 0 : 150;

        return this.each(function () {

            // Open context menu
            $(this).off('pf:openContextMenu').on('pf:openContextMenu', function (e, originalEvent, component, hiddenOptions, activeOptions) {

                // hide all other open context menus
               $('#pf-dialog-wrapper > .dropdown-menu').hide();

                var contextMenu = $(settings.menuSelector);

                var menuLiElements = contextMenu.find('li');

                // show all menu entries
                menuLiElements.show();

                // disable specific menu entries
                for(var i = 0; i < hiddenOptions.length; i++){
                    contextMenu.find('li[data-action="' + hiddenOptions[i] + '"]').hide();
                }

                // deactivate all menu entries
                menuLiElements.removeClass('active');

                //set active specific menu entries
                for(var j = 0; j < activeOptions.length; j++){
                    contextMenu.find('li[data-action="' + activeOptions[j] + '"]').addClass('active');
                }

                //open menu
                contextMenu.css({
                    position: 'absolute',
                    left: getLeftLocation(originalEvent),
                    top: getTopLocation(originalEvent)
                }).velocity(animationInType, {
                    duration: animationInDuration,
                    complete: function(){
                        // set context menu "click" observer
                        $(this).off('click').one('click', {component: component, position:{x: getLeftLocation(originalEvent), y: getTopLocation(originalEvent)}}, function (e) {
                            // hide contextmenu
                            $(this).hide();

                            var params = {
                                selectedMenu: $(e.target),
                                component: e.data.component,
                                position: e.data.position
                            };

                            settings.menuSelected.call(this, params);
                        });
                    }
                });

                //make sure menu closes on any click
                $(document).one('click.closeContextmenu', function () {
                    $('.dropdown-menu[role="menu"]').velocity(animationOutType, {
                        duration: animationOutDuration
                    });
                });

                return false;
            });

        });

        function getLeftLocation(e) {
            var mouseWidth = e.pageX;
            var pageWidth = $(window).width();
            var menuWidth = $(settings.menuSelector).width();

            // opening menu would pass the side of the page
            if (mouseWidth + menuWidth > pageWidth &&
                menuWidth < mouseWidth) {
                return mouseWidth - menuWidth;
            }
            return mouseWidth;
        }

        function getTopLocation(e) {
            var mouseHeight = e.pageY;
            var pageHeight = $(window).height();
            var menuHeight = $(settings.menuSelector).height();

            // opening menu would pass the bottom of the page
            if (mouseHeight + menuHeight > pageHeight &&
                menuHeight < mouseHeight) {
                return mouseHeight - menuHeight;
            }
            return mouseHeight;
        }

    };
});<commit_msg>fixed position for "new system" according to current mouse cursor position<commit_after>/**
 * context menu
 */

define([
    'jquery',
    'app/ccp'
], function($, CCP) {

    'use strict';

    $.fn.contextMenu = function (settings) {

        // animation
        var animationInType = CCP.isInGameBrowser() ? 'fadeIn' : 'transition.flipXIn';
        var animationInDuration = CCP.isInGameBrowser() ? 0 : 150;
        var animationOutType = CCP.isInGameBrowser() ? 'fadeOut' : 'transition.flipXOut';
        var animationOutDuration = CCP.isInGameBrowser() ? 0 : 150;

        return this.each(function () {

            // Open context menu
            $(this).off('pf:openContextMenu').on('pf:openContextMenu', function (e, originalEvent, component, hiddenOptions, activeOptions) {

                // hide all other open context menus
               $('#pf-dialog-wrapper > .dropdown-menu').hide();

                var contextMenu = $(settings.menuSelector);

                var menuLiElements = contextMenu.find('li');

                // show all menu entries
                menuLiElements.show();

                // disable specific menu entries
                for(var i = 0; i < hiddenOptions.length; i++){
                    contextMenu.find('li[data-action="' + hiddenOptions[i] + '"]').hide();
                }

                // deactivate all menu entries
                menuLiElements.removeClass('active');

                //set active specific menu entries
                for(var j = 0; j < activeOptions.length; j++){
                    contextMenu.find('li[data-action="' + activeOptions[j] + '"]').addClass('active');
                }

                //open menu
                contextMenu.css({
                    position: 'absolute',
                    left: getLeftLocation(originalEvent),
                    top: getTopLocation(originalEvent)
                }).velocity(animationInType, {
                    duration: animationInDuration,
                    complete: function(){
                        // set context menu "click" observer
                        $(this).off('click').one('click', {component: component, position:{x: originalEvent.offsetX, y: originalEvent.offsetY}}, function (e) {
                            // hide contextmenu
                            $(this).hide();

                            var params = {
                                selectedMenu: $(e.target),
                                component: e.data.component,
                                position: e.data.position
                            };

                            settings.menuSelected.call(this, params);
                        });
                    }
                });

                //make sure menu closes on any click
                $(document).one('click.closeContextmenu', function () {
                    $('.dropdown-menu[role="menu"]').velocity(animationOutType, {
                        duration: animationOutDuration
                    });
                });

                return false;
            });

        });

        function getLeftLocation(e) {
            var mouseWidth = e.pageX;
            var pageWidth = $(window).width();
            var menuWidth = $(settings.menuSelector).width();

            // opening menu would pass the side of the page
            if (mouseWidth + menuWidth > pageWidth &&
                menuWidth < mouseWidth) {
                return mouseWidth - menuWidth;
            }
            return mouseWidth;
        }

        function getTopLocation(e) {
            var mouseHeight = e.pageY;
            var pageHeight = $(window).height();
            var menuHeight = $(settings.menuSelector).height();

            // opening menu would pass the bottom of the page
            if (mouseHeight + menuHeight > pageHeight &&
                menuHeight < mouseHeight) {
                return mouseHeight - menuHeight;
            }
            return mouseHeight;
        }

    };
});<|endoftext|>


<commit_before>// Copyright 2014-2017, University of Colorado Boulder

/**
 * Base class for button models, which describe the behavior of buttons when users interact with them.  Property values
 * are set by an associated listener, see ButtonListener for details.
 */
define( function( require ) {
  'use strict';

  // modules
  var BooleanProperty = require( 'AXON/BooleanProperty' );
  var inherit = require( 'PHET_CORE/inherit' );
  var PressListener = require( 'SCENERY/listeners/PressListener' );
  var Property = require( 'AXON/Property' );
  var sun = require( 'SUN/sun' );
  var Tandem = require( 'TANDEM/Tandem' );

  /**
   * @param {Object} [options]
   * @constructor
   */
  function ButtonModel( options ) {

    options = _.extend( {
      // {function} called on pointer down
      startCallback: function() {},
      // {function} called on pointer up, @param {boolean} over - indicates whether the pointer was released over the button
      endCallback: function( over ) {},
      // {boolean} is the button enabled?
      enabled: true,

      tandem: Tandem.required,

      // a11y
      fireOnHoldInterval: 100 // fire continuously at this interval in ms when holding down button with keyboard
    }, options );

    var self = this;

    // model properties
    this.overProperty = new Property( false ); // @public - Is the pointer over the button?
    this.downProperty = new Property( false ); // @public - Is the pointer down?

    // @public - Is the button enabled?
    this.enabledProperty = new BooleanProperty( options.enabled, {
      tandem: options.tandem.createTandem( 'enabledProperty' ),
      phetioInstanceDocumentation: 'When disabled, the button is grayed out and cannot be pressed'
    } );

    // @private - keep track of and store all listeners this model creates
    this.listeners = [];

    // @private {number}
    this._fireOnHoldInterval = options.fireOnHoldInterval;

    // startCallback on pointer down, endCallback on pointer up. lazyLink so they aren't called immediately.
    this.downProperty.lazyLink( function( down ) {
      if ( down ) {
        options.startCallback();
      }
      else {
        options.endCallback( self.overProperty.get() );
      }
    } );

    // interrupt listeners when enabled is set to false
    this.enabledProperty.link( function( enabled ) {
      if ( !enabled ) {
        for ( var i = 0; i < self.listeners.length; i++ ) {
          var listener = self.listeners[ i ];
          listener.interrupt && listener.interrupt();
        }
      }
    } );

    // @private
    this.disposeButtonModel = function() {

      // This will unlink all listeners, causing potential issues if listeners try to unlink properties afterwards
      this.overProperty.dispose();
      this.downProperty.dispose();
      this.enabledProperty.dispose();
      this.listeners = [];
    };
  }

  sun.register( 'ButtonModel', ButtonModel );

  return inherit( Object, ButtonModel, {

    /**
     * @public
     */
    dispose: function() {
      this.disposeButtonModel();
    },

    /**
     * Click the button by pressing the button down and then releasing after a timeout. When assistive technology is
     * used, the browser does not receive 'down' or 'up' events on buttons - only a single 'click' event. For a11y we
     * need to toggle the pressed state every 'click' event.
     * @param {function} [endListener] - optional function to be called once the button has been released after
     *                                   accessibility related interaction.
     * @public
     */
    a11yClick: function( endListener ) {
      if ( !this.downProperty.get() && this.enabledProperty.get() ) {

        // ensure that button is 'over' so listener can be called while button is down
        this.overProperty.set( true );
        this.downProperty.set( true );

        var self = this;
        // Timer.setTimeout( function() {

        // no longer down, don't reset 'over' so button can be styled as long as it has focus
        self.downProperty.set( false );

        endListener && endListener();
        // }, self._fireOnHoldInterval );
      }
    },

    /**
     * Button is no longer considered over on blur, unless blur was initiated by a 'down' event.
     *
     * @public
     */
    a11yBlur: function() {
      if ( !this.downProperty.get() ) {
        this.overProperty.value = false;
      }
    },

    /**
     * Creates a standard button listener that can be added to a node and that will trigger the changes to this model.
     * @param {Object} [options]
     * @returns {PressListener}
     * @public
     */
    createListener: function( options ) {
      var self = this;

      options = _.extend( {
        phetioInstanceDocumentation: 'Indicates when the button has been pressed or released',
        isPressedProperty: this.downProperty,
        isOverProperty: this.overProperty,
        canStartPress: function() {
          return self.enabledProperty.value;
        }
      }, options );

      var pressListener = new PressListener( options );
      this.listeners.push( pressListener );
      return pressListener;
    }
  } );
} );<commit_msg>Pass through value for phetioState in ButtonModel, see https://github.com/phetsims/sun/issues/374<commit_after>// Copyright 2014-2017, University of Colorado Boulder

/**
 * Base class for button models, which describe the behavior of buttons when users interact with them.  Property values
 * are set by an associated listener, see ButtonListener for details.
 */
define( function( require ) {
  'use strict';

  // modules
  var BooleanProperty = require( 'AXON/BooleanProperty' );
  var inherit = require( 'PHET_CORE/inherit' );
  var PhetioObject = require( 'TANDEM/PhetioObject' );
  var PressListener = require( 'SCENERY/listeners/PressListener' );
  var Property = require( 'AXON/Property' );
  var sun = require( 'SUN/sun' );
  var Tandem = require( 'TANDEM/Tandem' );

  /**
   * @param {Object} [options]
   * @constructor
   */
  function ButtonModel( options ) {

    options = _.extend( {
      // {function} called on pointer down
      startCallback: function() {},
      // {function} called on pointer up, @param {boolean} over - indicates whether the pointer was released over the button
      endCallback: function( over ) {},
      // {boolean} is the button enabled?
      enabled: true,

      tandem: Tandem.required,
      phetioState: PhetioObject.DEFAULT_OPTIONS.phetioState, // to support properly passing this to children, see https://github.com/phetsims/tandem/issues/60

      // a11y
      fireOnHoldInterval: 100 // fire continuously at this interval in ms when holding down button with keyboard
    }, options );

    var self = this;

    // model properties
    this.overProperty = new Property( false ); // @public - Is the pointer over the button?
    this.downProperty = new Property( false ); // @public - Is the pointer down?

    // @public - Is the button enabled?
    this.enabledProperty = new BooleanProperty( options.enabled, {
      phetioState: options.phetioState,
      tandem: options.tandem.createTandem( 'enabledProperty' ),
      phetioInstanceDocumentation: 'When disabled, the button is grayed out and cannot be pressed'
    } );

    // @private - keep track of and store all listeners this model creates
    this.listeners = [];

    // @private {number}
    this._fireOnHoldInterval = options.fireOnHoldInterval;

    // startCallback on pointer down, endCallback on pointer up. lazyLink so they aren't called immediately.
    this.downProperty.lazyLink( function( down ) {
      if ( down ) {
        options.startCallback();
      }
      else {
        options.endCallback( self.overProperty.get() );
      }
    } );

    // interrupt listeners when enabled is set to false
    this.enabledProperty.link( function( enabled ) {
      if ( !enabled ) {
        for ( var i = 0; i < self.listeners.length; i++ ) {
          var listener = self.listeners[ i ];
          listener.interrupt && listener.interrupt();
        }
      }
    } );

    // @private
    this.disposeButtonModel = function() {

      // This will unlink all listeners, causing potential issues if listeners try to unlink properties afterwards
      this.overProperty.dispose();
      this.downProperty.dispose();
      this.enabledProperty.dispose();
      this.listeners = [];
    };
  }

  sun.register( 'ButtonModel', ButtonModel );

  return inherit( Object, ButtonModel, {

    /**
     * @public
     */
    dispose: function() {
      this.disposeButtonModel();
    },

    /**
     * Click the button by pressing the button down and then releasing after a timeout. When assistive technology is
     * used, the browser does not receive 'down' or 'up' events on buttons - only a single 'click' event. For a11y we
     * need to toggle the pressed state every 'click' event.
     * @param {function} [endListener] - optional function to be called once the button has been released after
     *                                   accessibility related interaction.
     * @public
     */
    a11yClick: function( endListener ) {
      if ( !this.downProperty.get() && this.enabledProperty.get() ) {

        // ensure that button is 'over' so listener can be called while button is down
        this.overProperty.set( true );
        this.downProperty.set( true );

        var self = this;
        // Timer.setTimeout( function() {

        // no longer down, don't reset 'over' so button can be styled as long as it has focus
        self.downProperty.set( false );

        endListener && endListener();
        // }, self._fireOnHoldInterval );
      }
    },

    /**
     * Button is no longer considered over on blur, unless blur was initiated by a 'down' event.
     *
     * @public
     */
    a11yBlur: function() {
      if ( !this.downProperty.get() ) {
        this.overProperty.value = false;
      }
    },

    /**
     * Creates a standard button listener that can be added to a node and that will trigger the changes to this model.
     * @param {Object} [options]
     * @returns {PressListener}
     * @public
     */
    createListener: function( options ) {
      var self = this;

      options = _.extend( {
        phetioInstanceDocumentation: 'Indicates when the button has been pressed or released',
        isPressedProperty: this.downProperty,
        isOverProperty: this.overProperty,
        canStartPress: function() {
          return self.enabledProperty.value;
        }
      }, options );

      var pressListener = new PressListener( options );
      this.listeners.push( pressListener );
      return pressListener;
    }
  } );
} );<|endoftext|>


<commit_before>var Query   = require("./query")
  , Utils   = require("../../utils")

module.exports = (function() {
  var ConnectorManager = function(sequelize, config) {
    var pgModule = config.dialectModulePath || 'pg'

    this.sequelize = sequelize
    this.client         = null
    this.config         = config || {}
    this.config.port    = this.config.port || 5432
    this.pooling        = (!!this.config.pool && (this.config.pool.maxConnections > 0))
    this.pg             = this.config.native ? require(pgModule).native : require(pgModule)
    this.poolIdentifier = null

    // Better support for BigInts
    // https://github.com/brianc/node-postgres/issues/166#issuecomment-9514935
    this.pg.types.setTypeParser(20, String);

    // set pooling parameters if specified
    if (this.pooling) {
      this.pg.defaults.poolSize        = this.config.pool.maxConnections
      this.pg.defaults.poolIdleTimeout = this.config.pool.maxIdleTime
    }

    this.disconnectTimeoutId = null
    this.pendingQueries = 0
    this.maxConcurrentQueries = (this.config.maxConcurrentQueries || 50)

    process.on('exit', function() {
      this.disconnect()
    }.bind(this))
  }
  Utils._.extend(ConnectorManager.prototype, require("../connector-manager").prototype)

  ConnectorManager.prototype.endQuery = function() {
    var self = this

    self.pendingQueries--

    if (!self.pooling && self.pendingQueries === 0) {
      setTimeout(function() {
        self.pendingQueries === 0 && self.disconnect.call(self)
      }, 100)
    }
  }

  ConnectorManager.prototype.query = function(sql, callee, options) {
    var self = this

    self.pendingQueries++

    return new Utils.CustomEventEmitter(function(emitter) {
      self.connect()
      .on('error', function(err) {
        emitter.emit('error', err)
      })
      .on('success', function(done) {
        var query = new Query(self.client, self.sequelize, callee, options || {})
        done = done || null

        return query.run(sql, done)
          .success(function(results) { self.endQuery.call(self) })
          .error(function(err) { self.endQuery.call(self) })
          .proxy(emitter)
      })
    }).run()
  }

  ConnectorManager.prototype.connect = function(callback) {
    var self = this
    var emitter = new (require('events').EventEmitter)()

    // in case database is slow to connect, prevent orphaning the client
    if (this.isConnecting && !this.pooling) {
      emitter.emit('success')
      return emitter
    }

    this.isConnecting = true
    this.isConnected  = false

    var uri = this.sequelize.getQueryInterface().QueryGenerator.databaseConnectionUri(this.config)

    var connectCallback = function(err, client, done) {
      self.isConnecting = false

      if (!!err) {
        // release the pool immediately, very important.
        done && done(err)

        if (err.code) {
          switch(err.code) {
          case 'ECONNREFUSED':
            emitter.emit('error', new Error("Failed to authenticate for PostgresSQL. Please double check your settings."))
            break
          case 'ENOTFOUND':
          case 'EHOSTUNREACH':
          case 'EINVAL':
            emitter.emit('error', new Error("Failed to find PostgresSQL server. Please double check your settings."))
            break
          default:
            emitter.emit('error', err)
            break
          }
        }
      } else if (client) {
        client.query("SET TIME ZONE 'UTC'").on('end', function() {
            self.isConnected = true
            self.client = client
            emitter.emit('success', done)
          })
      } else {
        self.client = null
        emitter.emit('success', done)
      }
    }

    if (this.pooling) {
      // acquire client from pool
      this.poolIdentifier = this.pg.pools.getOrCreate(this.sequelize.config)
      this.poolIdentifier.connect(connectCallback)
    } else {
      //create one-off client
      this.client = new this.pg.Client(uri)
      this.client.connect(connectCallback)
    }

    return emitter
  }

  ConnectorManager.prototype.disconnect = function() {
    if (this.poolIdentifier) {
      this.poolIdentifier.destroyAllNow()
    }

    if (this.client) {
      this.client.end()
    }

    this.client = null
    this.isConnecting = false
    this.isConnected  = false
  }

  return ConnectorManager
})()<commit_msg>Fixed up one off connection clients for Sequelize (if client is already defined simply callback rather than connecting again).<commit_after>var Query   = require("./query")
  , Utils   = require("../../utils")

module.exports = (function() {
  var ConnectorManager = function(sequelize, config) {
    var pgModule = config.dialectModulePath || 'pg'

    this.sequelize = sequelize
    this.client         = null
    this.config         = config || {}
    this.config.port    = this.config.port || 5432
    this.pooling        = (!!this.config.pool && (this.config.pool.maxConnections > 0))
    this.pg             = this.config.native ? require(pgModule).native : require(pgModule)
    this.poolIdentifier = null

    // Better support for BigInts
    // https://github.com/brianc/node-postgres/issues/166#issuecomment-9514935
    this.pg.types.setTypeParser(20, String);

    // set pooling parameters if specified
    if (this.pooling) {
      this.pg.defaults.poolSize        = this.config.pool.maxConnections
      this.pg.defaults.poolIdleTimeout = this.config.pool.maxIdleTime
    }

    this.disconnectTimeoutId = null
    this.pendingQueries = 0
    this.maxConcurrentQueries = (this.config.maxConcurrentQueries || 50)

    process.on('exit', function() {
      this.disconnect()
    }.bind(this))
  }
  Utils._.extend(ConnectorManager.prototype, require("../connector-manager").prototype)

  ConnectorManager.prototype.endQuery = function() {
    var self = this

    self.pendingQueries--

    if (!self.pooling && self.pendingQueries === 0) {
      setTimeout(function() {
        self.pendingQueries === 0 && self.disconnect.call(self)
      }, 100)
    }
  }

  ConnectorManager.prototype.query = function(sql, callee, options) {
    var self = this

    self.pendingQueries++

    return new Utils.CustomEventEmitter(function(emitter) {
      self.connect()
      .on('error', function(err) {
        emitter.emit('error', err)
      })
      .on('success', function(done) {
        var query = new Query(self.client, self.sequelize, callee, options || {})
        done = done || null

        return query.run(sql, done)
          .success(function(results) { self.endQuery.call(self) })
          .error(function(err) { self.endQuery.call(self) })
          .proxy(emitter)
      })
    }).run()
  }

  ConnectorManager.prototype.connect = function(callback) {
    var self = this
    var emitter = new (require('events').EventEmitter)()

    // in case database is slow to connect, prevent orphaning the client
    if (this.isConnecting && !this.pooling) {
      emitter.emit('success')
      return emitter
    }

    this.isConnecting = true
    this.isConnected  = false

    var uri = this.sequelize.getQueryInterface().QueryGenerator.databaseConnectionUri(this.config)

    var connectCallback = function(err, client, done) {
      self.isConnecting = false

      if (!!err) {
        // release the pool immediately, very important.
        done && done(err)

        if (err.code) {
          switch(err.code) {
          case 'ECONNREFUSED':
            emitter.emit('error', new Error("Failed to authenticate for PostgresSQL. Please double check your settings."))
            break
          case 'ENOTFOUND':
          case 'EHOSTUNREACH':
          case 'EINVAL':
            emitter.emit('error', new Error("Failed to find PostgresSQL server. Please double check your settings."))
            break
          default:
            emitter.emit('error', err)
            break
          }
        }
      } else if (client) {
        client.query("SET TIME ZONE 'UTC'").on('end', function() {
          self.isConnected = true
          self.client = client
          emitter.emit('success', done)
        })
      } else {
        self.client = null
        emitter.emit('success', done)
      }
    }

    if (this.pooling) {
      // acquire client from pool
      this.poolIdentifier = this.pg.pools.getOrCreate(this.sequelize.config)
      this.poolIdentifier.connect(connectCallback)
    } else {
      if (!!this.client) {
        connectCallback(null, this.client);
      } else {
        //create one-off client
        this.client = new this.pg.Client(uri)
        this.client.connect(connectCallback)
      }
    }

    return emitter
  }

  ConnectorManager.prototype.disconnect = function() {
    if (this.poolIdentifier) {
      this.poolIdentifier.destroyAllNow()
    }

    if (this.client) {
      this.client.end()
    }

    this.client = null
    this.isConnecting = false
    this.isConnected  = false
  }

  return ConnectorManager
})()<|endoftext|>


<commit_before>import React from "react";
import { storiesOf } from "dextrose/storiesOfOverloader";
import { decorateAction } from "@storybook/addon-actions";
import { AuthorProfileProvider } from "@times-components/provider";
import { MockedProvider } from "@times-components/utils/graphql";
import storybookReporter from "@times-components/tealium/storybook";
import AuthorProfile from "./author-profile";
import AuthorProfileContent from "./author-profile-content";
import {
  makeAuthor,
  makeArticleMocks,
  makeBrokenMocks,
  makeMocksWithAuthorError,
  makeMocksWithPageError
} from "./fixtures/fixture-generator";

const preventDefaultedAction = decorateAction([
  ([e, ...args]) => {
    e.preventDefault();
    return ["[SyntheticEvent (storybook prevented default)]", ...args];
  }
]);

const slug = "deborah-haynes";
const pageSize = 5;

storiesOf("AuthorProfile", module)
  .add("Default with images", () => {
    const props = {
      slug,
      author: makeAuthor({ withImages: true }),
      articleImageRatio: "3:2",
      isLoading: false,
      page: 2,
      pageSize,
      onTwitterLinkPress: preventDefaultedAction("onTwitterLinkPress"),
      onArticlePress: preventDefaultedAction("onArticlePress"),
      analyticsStream: storybookReporter
    };

    return (
      <MockedProvider
        mocks={makeArticleMocks({ withImages: true, slug, pageSize })}
      >
        <AuthorProfile {...props} />
      </MockedProvider>
    );
  })
  .add("Default without images", () => {
    const props = {
      slug: "deborah-haynes",
      author: makeAuthor(),
      articleImageRatio: "3:2",
      isLoading: false,
      page: 2,
      pageSize,
      onTwitterLinkPress: preventDefaultedAction("onTwitterLinkPress"),
      onArticlePress: preventDefaultedAction("onArticlePress"),
      analyticsStream: storybookReporter
    };

    return (
      <MockedProvider mocks={makeArticleMocks({ pageSize })}>
        <AuthorProfile {...props} />
      </MockedProvider>
    );
  })
  .add("Loading", () => {
    const props = {
      isLoading: true,
      articlesLoading: true,
      pageSize,
      onTwitterLinkPress: preventDefaultedAction("onTwitterLinkPress"),
      onArticlePress: preventDefaultedAction("onArticlePress"),
      analyticsStream: storybookReporter,
      refetch: () => {}
    };

    return <AuthorProfileContent {...props} />;
  })
  .add("With an error getting author", () => (
    <MockedProvider
      mocks={makeMocksWithAuthorError({ slug, pageSize, withImages: true })}
    >
      <AuthorProfileProvider slug={slug}>
        {({ author, isLoading, error, refetch }) => (
          <AuthorProfile
            author={author}
            page={1}
            refetch={refetch}
            pageSize={pageSize}
            slug={slug}
            isLoading={isLoading}
            error={error}
            onTwitterLinkPress={preventDefaultedAction("onTwitterLinkPress")}
            onArticlePress={preventDefaultedAction("onArticlePress")}
            analyticsStream={storybookReporter}
          />
        )}
      </AuthorProfileProvider>
    </MockedProvider>
  ))
  .add("With an error getting articles", () => {
    const props = {
      slug,
      author: makeAuthor({ withImages: true }),
      isLoading: false,
      page: 1,
      pageSize,
      onTwitterLinkPress: preventDefaultedAction("onTwitterLinkPress"),
      onArticlePress: preventDefaultedAction("onArticlePress"),
      analyticsStream: storybookReporter
    };

    return (
      <MockedProvider
        mocks={makeMocksWithPageError({ withImages: true, pageSize })}
      >
        <AuthorProfile {...props} />
      </MockedProvider>
    );
  })
  .add("With an error rendering a card", () => {
    const props = {
      slug,
      author: makeAuthor({ withImages: true }),
      articleImageRatio: "3:2",
      isLoading: false,
      page: 1,
      pageSize,
      onTwitterLinkPress: preventDefaultedAction("onTwitterLinkPress"),
      onArticlePress: preventDefaultedAction("onArticlePress"),
      analyticsStream: storybookReporter
    };

    return (
      <MockedProvider mocks={makeBrokenMocks({ withImages: true, pageSize })}>
        <AuthorProfile {...props} />
      </MockedProvider>
    );
  })
  .add("With Provider and Tracking", () => {
    const props = {
      slug,
      page: 2,
      pageSize,
      onTwitterLinkPress: preventDefaultedAction("onTwitterLinkPress"),
      onArticlePress: preventDefaultedAction("onArticlePress"),
      analyticsStream: storybookReporter
    };

    return (
      <MockedProvider mocks={makeArticleMocks({ withImages: true, pageSize })}>
        <AuthorProfileProvider slug={slug}>
          {({ author, isLoading, error }) => (
            <AuthorProfile
              author={author}
              isLoading={isLoading}
              error={error}
              {...props}
            />
          )}
        </AuthorProfileProvider>
      </MockedProvider>
    );
  });
<commit_msg>chore: use component for story (#493)<commit_after>import React from "react";
import { storiesOf } from "dextrose/storiesOfOverloader";
import { decorateAction } from "@storybook/addon-actions";
import { AuthorProfileProvider } from "@times-components/provider";
import { MockedProvider } from "@times-components/utils/graphql";
import storybookReporter from "@times-components/tealium/storybook";
import AuthorProfile from "./author-profile";
import {
  makeAuthor,
  makeArticleMocks,
  makeBrokenMocks,
  makeMocksWithAuthorError,
  makeMocksWithPageError
} from "./fixtures/fixture-generator";

const preventDefaultedAction = decorateAction([
  ([e, ...args]) => {
    e.preventDefault();
    return ["[SyntheticEvent (storybook prevented default)]", ...args];
  }
]);

const slug = "deborah-haynes";
const pageSize = 5;

storiesOf("AuthorProfile", module)
  .add("Default with images", () => {
    const props = {
      slug,
      author: makeAuthor({ withImages: true }),
      articleImageRatio: "3:2",
      isLoading: false,
      page: 2,
      pageSize,
      onTwitterLinkPress: preventDefaultedAction("onTwitterLinkPress"),
      onArticlePress: preventDefaultedAction("onArticlePress"),
      analyticsStream: storybookReporter
    };

    return (
      <MockedProvider
        mocks={makeArticleMocks({ withImages: true, slug, pageSize })}
      >
        <AuthorProfile {...props} />
      </MockedProvider>
    );
  })
  .add("Default without images", () => {
    const props = {
      slug: "deborah-haynes",
      author: makeAuthor(),
      articleImageRatio: "3:2",
      isLoading: false,
      page: 2,
      pageSize,
      onTwitterLinkPress: preventDefaultedAction("onTwitterLinkPress"),
      onArticlePress: preventDefaultedAction("onArticlePress"),
      analyticsStream: storybookReporter
    };

    return (
      <MockedProvider mocks={makeArticleMocks({ pageSize })}>
        <AuthorProfile {...props} />
      </MockedProvider>
    );
  })
  .add("Loading", () => {
    const props = {
      slug: "deborah-haynes",
      isLoading: true,
      pageSize,
      onTwitterLinkPress: preventDefaultedAction("onTwitterLinkPress"),
      onArticlePress: preventDefaultedAction("onArticlePress"),
      analyticsStream: storybookReporter
    };

    return <AuthorProfile {...props} />;
  })
  .add("With an error getting author", () => (
    <MockedProvider
      mocks={makeMocksWithAuthorError({ slug, pageSize, withImages: true })}
    >
      <AuthorProfileProvider slug={slug}>
        {({ author, isLoading, error, refetch }) => (
          <AuthorProfile
            author={author}
            page={1}
            refetch={refetch}
            pageSize={pageSize}
            slug={slug}
            isLoading={isLoading}
            error={error}
            onTwitterLinkPress={preventDefaultedAction("onTwitterLinkPress")}
            onArticlePress={preventDefaultedAction("onArticlePress")}
            analyticsStream={storybookReporter}
          />
        )}
      </AuthorProfileProvider>
    </MockedProvider>
  ))
  .add("With an error getting articles", () => {
    const props = {
      slug,
      author: makeAuthor({ withImages: true }),
      isLoading: false,
      page: 1,
      pageSize,
      onTwitterLinkPress: preventDefaultedAction("onTwitterLinkPress"),
      onArticlePress: preventDefaultedAction("onArticlePress"),
      analyticsStream: storybookReporter
    };

    return (
      <MockedProvider
        mocks={makeMocksWithPageError({ withImages: true, pageSize })}
      >
        <AuthorProfile {...props} />
      </MockedProvider>
    );
  })
  .add("With an error rendering a card", () => {
    const props = {
      slug,
      author: makeAuthor({ withImages: true }),
      articleImageRatio: "3:2",
      isLoading: false,
      page: 1,
      pageSize,
      onTwitterLinkPress: preventDefaultedAction("onTwitterLinkPress"),
      onArticlePress: preventDefaultedAction("onArticlePress"),
      analyticsStream: storybookReporter
    };

    return (
      <MockedProvider mocks={makeBrokenMocks({ withImages: true, pageSize })}>
        <AuthorProfile {...props} />
      </MockedProvider>
    );
  })
  .add("With Provider and Tracking", () => {
    const props = {
      slug,
      page: 2,
      pageSize,
      onTwitterLinkPress: preventDefaultedAction("onTwitterLinkPress"),
      onArticlePress: preventDefaultedAction("onArticlePress"),
      analyticsStream: storybookReporter
    };

    return (
      <MockedProvider mocks={makeArticleMocks({ withImages: true, pageSize })}>
        <AuthorProfileProvider slug={slug}>
          {({ author, isLoading, error }) => (
            <AuthorProfile
              author={author}
              isLoading={isLoading}
              error={error}
              {...props}
            />
          )}
        </AuthorProfileProvider>
      </MockedProvider>
    );
  });
<|endoftext|>


<commit_before>(function() {

  if (phantom.version.major >= 2) {
    var system = require('system');
    var url = system.args[1];
    var showConsoleLog = system.args[2] === 'true';
    var configScript = system.args[3];
  }
  else {
    var url = phantom.args[0];
    var showConsoleLog = phantom.args[1] === 'true';
    var configScript = phantom.args[2];
  }

  var page = require('webpage').create();
  configScript = configScript.replace(/['"]{2}/,"");

  if (configScript !== '') {
    try {
      require(configScript).configure(page);
    } catch(e) {
      console.error('Failed to configure phantom');
      console.error(e.stack);
      phantom.exit(1);
    }
  }

  var specTimingStart = Date.now(); // First spec timing might be inaccurate

  page.onCallback = function(data) {
    if(data.state === 'specDone') {
      var specDt = Date.now() - specTimingStart;
      if (specDt > 10) {
        console.log('');
        console.log('Slow spec runtime: ', specDt, ' milliseconds');
        console.log(data.results.fullName);
        console.log('');
      }

      var results = {
        description: data.results.description,
        failedExpectations: [], // data.results.failedExpectations,
        fullName: data.results.fullName,
        id: data.results.id,
        passedExpectations: [], // data.results.passedExpectations,
        pendingReason: data.results.pendingReason,
        status: data.results.status
      };

      var stringifyStartTime0 = Date.now();
      console.log('jasmine_spec_result' + JSON.stringify([].concat(results)));
      var stringifyDt = Date.now() - stringifyStartTime0;

      if(stringifyDt > 5) {
        console.log('');
        console.log('Slow spec serialization: ', stringifyDt, ' milliseconds');
        console.log(data.results.fullName);
        console.log('');
      }

      specTimingStart = Date.now();
    } else if (data.state === 'suiteDone') {
      var suiteDt = Date.now() - specTimingStart;
      if (suiteDt > 10) {
        console.log('');
        console.log('Slow suite runtime: ', suiteDt, ' milliseconds');
        console.log(data.results.fullName);
        console.log('');
      }

      var results = {
        description: data.results.description,
        failedExpectations: [], // data.results.failedExpectations,
        fullName: data.results.fullName,
        id: data.results.id,
        status: data.results.status
      };

      var stringifyStartTime0 = Date.now();
      console.log('jasmine_suite_result' + JSON.stringify([].concat(results)));
      var stringifyDt = Date.now() - stringifyStartTime0;

      if(stringifyDt > 5) {
        console.log('');
        console.log('Slow suite serialization : ', stringifyDt, ' milliseconds');
        console.log(data.results.fullName);
        console.log('');
      }

      specTimingStart = Date.now();
    } else {
      console.log('jasmine_done' + JSON.stringify(data.details));
      phantom.exit(0);
    }
  };

  if (showConsoleLog) {
    page.onConsoleMessage = function(message) {
      console.log(message);
    };
  }

  page.open(url, function(status) {
    if (status !== "success") {
      phantom.exit(1);
    }
  });
}).call(this);
<commit_msg>Bump threshold for slowness detection<commit_after>(function() {

  if (phantom.version.major >= 2) {
    var system = require('system');
    var url = system.args[1];
    var showConsoleLog = system.args[2] === 'true';
    var configScript = system.args[3];
  }
  else {
    var url = phantom.args[0];
    var showConsoleLog = phantom.args[1] === 'true';
    var configScript = phantom.args[2];
  }

  var page = require('webpage').create();
  configScript = configScript.replace(/['"]{2}/,"");

  if (configScript !== '') {
    try {
      require(configScript).configure(page);
    } catch(e) {
      console.error('Failed to configure phantom');
      console.error(e.stack);
      phantom.exit(1);
    }
  }

  var specTimingStart = Date.now(); // First spec timing might be inaccurate

  page.onCallback = function(data) {
    if(data.state === 'specDone') {
      var specDt = Date.now() - specTimingStart;
      if (specDt > 1000) {
        console.log('');
        console.log('Slow spec runtime: ', specDt, ' milliseconds');
        console.log(data.results.fullName);
        console.log('');
      }

      var stringifyStartTime0 = Date.now();
      console.log('jasmine_spec_result' + JSON.stringify([].concat(data.results)));
      var stringifyDt = Date.now() - stringifyStartTime0;

      if(stringifyDt > 5) {
        console.log('');
        console.log('Slow spec serialization: ', stringifyDt, ' milliseconds');
        console.log(data.results.fullName);
        console.log('');
      }

      specTimingStart = Date.now();
    } else if (data.state === 'suiteDone') {
      var suiteDt = Date.now() - specTimingStart;
      if (suiteDt > 1000) {
        console.log('');
        console.log('Slow suite runtime: ', suiteDt, ' milliseconds');
        console.log(data.results.fullName);
        console.log('');
      }

      var stringifyStartTime0 = Date.now();
      console.log('jasmine_suite_result' + JSON.stringify([].concat(data.results)));
      var stringifyDt = Date.now() - stringifyStartTime0;

      if(stringifyDt > 5) {
        console.log('');
        console.log('Slow suite serialization : ', stringifyDt, ' milliseconds');
        console.log(data.results.fullName);
        console.log('');
      }

      specTimingStart = Date.now();
    } else {
      console.log('done son!')

      var stringifyStartTime0 = Date.now();
      console.log('jasmine_done' + JSON.stringify(data.details));
      var stringifyDt = Date.now() - stringifyStartTime0;

      if(stringifyDt > 5) {
        console.log('');
        console.log('Slow done serialization : ', stringifyDt, ' milliseconds');
        console.log(Object.keys(data.details));
        console.log('');
      }

      phantom.exit(0);
    }
  };

  if (showConsoleLog) {
    page.onConsoleMessage = function(message) {
      console.log(message);
    };
  }

  page.open(url, function(status) {
    if (status !== "success") {
      phantom.exit(1);
    }
  });
}).call(this);
<|endoftext|>


<commit_before>export default {
  setupState(lastState, env, scope, params, hash) {
    let state = {
      componentPath: env.hooks.getValue(params[0]),
      manager: lastState && lastState.manager,
      isComponentHelper: true
    };

    return state;
  },

  render(morph, env, scope, params, hash, template, inverse, visitor) {
    // Force the component hook to treat this as a first-time render,
    // because normal components (`<foo-bar>`) cannot change at runtime,
    // but the `{{component}}` helper can.
    morph.state.manager = null;

    let componentPath = morph.state.componentPath;

    // If the value passed to the {{component}} helper is undefined or null,
    // don't create a new ComponentNode.
    if (componentPath === undefined || componentPath === null) {
      return;
    }

    env.hooks.component(morph, env, scope, componentPath, params, hash, template, visitor);
  }
};
<commit_msg>Dynamic {{component}} re-renders when attrs change<commit_after>import { assign } from "ember-metal/merge";

export default {
  setupState(lastState, env, scope, params, hash) {
    let componentPath = env.hooks.getValue(params[0]);
    return assign({}, lastState, { componentPath, isComponentHelper: true });
  },

  render(morph, ...rest) {
    // Force the component hook to treat this as a first-time render,
    // because normal components (`<foo-bar>`) cannot change at runtime,
    // but the `{{component}}` helper can.
    morph.state.manager = null;

    render(morph, ...rest);
  },

  rerender: render
};

function render(morph, env, scope, params, hash, template, inverse, visitor) {
  let componentPath = morph.state.componentPath;

  // If the value passed to the {{component}} helper is undefined or null,
  // don't create a new ComponentNode.
  if (componentPath === undefined || componentPath === null) {
    return;
  }

  env.hooks.component(morph, env, scope, componentPath, params, hash, template, visitor);
}
<|endoftext|>


<commit_before>'use strict';

class Terminal {
    constructor(host) {
        this.element = host
        this.interactive = false

        const node = (tag, cssClass, parent) => {
            const node = document.createElement(tag)
            if (cssClass) node.classList.add(cssClass)
            if (parent) parent.appendChild(node)
            return node
        }

        this.background = node('div', 'terminal-background', host)
        this.input = node('input', null, this.background)
        this.scrollContainer = node('div', 'terminal-scroll', this.background)
        this.outputArea = node('p', 'terminal-output-area', this.scrollContainer)
        this.inputArea = node('p', 'terminal-input-area')
        this.userPrompt = node('span', null, this.inputArea)
        this.userInput = node('span', null, this.inputArea)
        this.inputCaret = node('span', 'terminal-caret', this.inputArea)

        this.input.setAttribute('type','text')
        this.inputCaret.textContent = 'C'

        this.background.addEventListener('click', (event) => { if(this.inputArea.parentNode) this.input.focus() })
        this.input.addEventListener('input', (event) => this.userInput.textContent = this.input.value)
        this.input.addEventListener('blur', (event) => this.inputCaret.classList.remove('blink'))
        this.input.addEventListener('focus', (event) => this.inputCaret.classList.add('blink'))
    }

    write(text) {
        if (!text) return
        const div = document.createElement('div')
        div.textContent = text
        this.outputArea.appendChild(div)
    }

    finishInput(echoInput) {
        this.scrollContainer.removeChild(this.inputArea)

        if (echoInput) {
            this.write(this.userPrompt.textContent + this.input.value)
        }

        const userInput = this.input.value
        this.input.value = ''
        this.userInput.textContent = ''
        this.userPrompt.textContent = ''

        this.scrollToBottom()

        return userInput
    }

    get echoHandler() {
        return (text) => {
            this.write(text)
        }
    }

    startInteractive(handler, echoInput) {
        this.interactive = true
        const loop = () => {
            this.prompt(echoInput)
            .then(handler)
            .then(() => { if (this.interactive) loop() })
        }
        loop()
    }

    stopInteractive() {
        this.finishInput()
        this.interactive = false
    }

    scrollToBottom() {
        this.background.scrollTop = this.scrollContainer.scrollHeight
    }

    prompt(echoInput) {
        if(echoInput == undefined) {
            echoInput = true
        }
        this.scrollContainer.appendChild(this.inputArea)
        this.userPrompt.textContent = '>>> '

        this.scrollToBottom()

        return new Promise((resolve, reject) => {
            const listener = (event) => {
                if (event.keyCode == 13) {
                    this.input.removeEventListener('keydown', listener)
                    resolve(this.finishInput(echoInput))
                }
            }
            this.input.addEventListener('keydown', listener)
        })
    }
}
<commit_msg>added keyboard interrupt<commit_after>'use strict';

class Terminal {
    constructor(host) {
        this.element = host
        this.interactive = false

        const node = (tag, cssClass, parent) => {
            const node = document.createElement(tag)
            if (cssClass) node.classList.add(cssClass)
            if (parent) parent.appendChild(node)
            return node
        }

        this.background = node('div', 'terminal-background', host)
        this.input = node('input', null, this.background)
        this.scrollContainer = node('div', 'terminal-scroll', this.background)
        this.outputArea = node('p', 'terminal-output-area', this.scrollContainer)
        this.inputArea = node('p', 'terminal-input-area')
        this.userPrompt = node('span', null, this.inputArea)
        this.userInput = node('span', null, this.inputArea)
        this.inputCaret = node('span', 'terminal-caret', this.inputArea)

        this.input.setAttribute('type','text')
        this.inputCaret.textContent = 'C'

        this.background.addEventListener('click', (event) => { if(this.inputArea.parentNode) this.input.focus() })
        this.input.addEventListener('input', (event) => this.userInput.textContent = this.input.value)
        this.input.addEventListener('blur', (event) => this.inputCaret.classList.remove('blink'))
        this.input.addEventListener('focus', (event) => this.inputCaret.classList.add('blink'))
    }

    write(text) {
        if (!text) return
        const div = document.createElement('div')
        div.textContent = text
        this.outputArea.appendChild(div)
    }

    finishInput(echoInput) {
        this.scrollContainer.removeChild(this.inputArea)

        if (echoInput) {
            this.write(this.userPrompt.textContent + this.input.value)
        }

        const userInput = this.input.value
        this.input.value = ''
        this.userInput.textContent = ''
        this.userPrompt.textContent = ''

        this.scrollToBottom()

        return userInput
    }

    get echoHandler() {
        return (text) => {
            this.write(text)
        }
    }

    startInteractive(handler, echoInput) {
        this.interactive = true
        const loop = () => {
            this.prompt(echoInput)
            .then(handler)
            .then(() => { if (this.interactive) loop() })
        }
        loop()
    }

    stopInteractive() {
        this.finishInput()
        this.interactive = false
    }

    scrollToBottom() {
        this.background.scrollTop = this.scrollContainer.scrollHeight
    }

    prompt(echoInput) {
        if(echoInput == undefined) {
            echoInput = true
        }
        this.scrollContainer.appendChild(this.inputArea)
        this.userPrompt.textContent = '>>> '

        this.scrollToBottom()

        return new Promise((resolve, reject) => {
            const listener = (event) => {
                if (event.keyCode == 67 && event.ctrlKey) {
                    this.input.removeEventListener('keydown', listener)
                    this.finishInput(false)
                    reject("Keyboard Interrupt")
                }
                if (event.keyCode == 13) {
                    this.input.removeEventListener('keydown', listener)
                    resolve(this.finishInput(echoInput))
                }
            }
            this.input.addEventListener('keydown', listener)
        })
    }
}
<|endoftext|>


<commit_before>exports.names = ['.callmod'];
exports.hidden = false;
exports.enabled = true;
exports.matchStart = true;
exports.handler = function (data) {

    var message = data.message.split(' ').slice(1).join(' ').trim();

    if (config.slack.webhookUrl === '') {
        bot.sendChat('Need help? Ask a mod! No mods around? Contact a Brand Ambassador: http://plug.dj/support - Hours: http://blog.plug.dj/brand-ambassadors/');
    }
    else if(message === '') {
        bot.sendChat('Need help? Type .callmod with the nature of your request - for example `.callmod Someone is spinning dubstep!`');
    }
    else {

        var formPayload = {
            text: '@channel - ' + data.from.username + ' requested help in https://plug.dj/' + config.roomName + " \n`" + message + "`",
            username: bot.getUser().username,
            channel: config.slack.default.channel,
            icon_url: config.slack.default.icon_url
        }

        formPayload = JSON.stringify(formPayload);

        request.post(config.slack.webhook_url, {form: {payload: formPayload}}, function (error, response, body) {

            if (!error && response.statusCode == 200) {
                if (body == 'ok') {
                    bot.sendChat('A mod has been contacted and will be on the way if available, @' + data.from.username + '. You can also contact a Brand Ambassador: http://plug.dj/support - Hours: http://blog.plug.dj/brand-ambassadors/');
                }
                else {
                    bot.sendChat('There was an error sending your request.  In the meantime, please contact a Brand Ambassador: http://plug.dj/support');
                }
            }
        });
    }
}<commit_msg>Use formatting instructions from https://api.slack.com/docs/formatting to make the .callmod request a tiny bit nicer.  We can probably set this up to use attachments in the future so it's really nice :D<commit_after>exports.names = ['.callmod'];
exports.hidden = false;
exports.enabled = true;
exports.matchStart = true;
exports.handler = function (data) {

    var message = data.message.split(' ').slice(1).join(' ').trim();

    if (config.slack.webhookUrl === '') {
        bot.sendChat('Need help? Ask a mod! No mods around? Contact a Brand Ambassador: http://plug.dj/support - Hours: http://blog.plug.dj/brand-ambassadors/');
    }
    else if(message === '') {
        bot.sendChat('Need help? Type .callmod with the nature of your request - for example `.callmod Someone is spinning dubstep!`');
    }
    else {

        var formPayload = {
            text: '@channel - ' + data.from.username + ' requested help in https://plug.dj/' + config.roomName + " \n`" + message + "`",
            username: bot.getUser().username,
            link_names: 1,
            channel: config.slack.default.channel,
            icon_url: config.slack.default.icon_url
        }

        formPayload = JSON.stringify(formPayload);

        request.post(config.slack.webhook_url, {form: {payload: formPayload}}, function (error, response, body) {

            if (!error && response.statusCode == 200) {
                if (body == 'ok') {
                    bot.sendChat('A mod has been contacted and will be on the way if available, @' + data.from.username + '. You can also contact a Brand Ambassador: http://plug.dj/support - Hours: http://blog.plug.dj/brand-ambassadors/');
                }
                else {
                    bot.sendChat('There was an error sending your request.  In the meantime, please contact a Brand Ambassador: http://plug.dj/support');
                }
            }
        });
    }
}<|endoftext|>


<commit_before><commit_msg>Changing theme code to fit gulp requierments.<commit_after>class DCFSlideshowTheme {
  constructor(slideshows, openCaption, closeCaption) {
    this.slideshows = slideshows;
    this.openCaption = openCaption;
    this.closeCaption = closeCaption;
  }

  initialize() {
    const keyframesClose1 = [
      {
        transform: 'rotate(45deg)',
        transformOrigin: '50% 50%'
      },
      {
        transform: 'rotate(0deg)',
        transformOrigin: '50% 50%'
      }
    ];
    const keyframesClose2 = [
      {
        transform: 'rotate(-45deg)',
        transformOrigin: '50% 50%'
      },
      {
        transform: 'rotate(0deg)',
        transformOrigin: '50% 50%'
      }
    ];
    const keyframesOpen1 = [
      {
        transform: 'rotate(0deg)',
        transformOrigin: '50% 50%'
      },
      {
        transform: 'rotate(45deg)',
        transformOrigin: '50% 50%'
      }
    ];
    const keyframesOpen2 = [
      {
        transform: 'rotate(0deg)',
        transformOrigin: '50% 50%'
      },
      {
        transform: 'rotate(-45deg)',
        transformOrigin: '50% 50%'
      }
    ];
    const options = {
      duration: 250,
      fill: 'forwards'
    };

    Array.prototype.forEach.call(this.slideshows, (slideshow) => {
      // Slideshow Controls
      let ctrlGroup = slideshow.querySelector('[aria-label = "slideshow controls"]'); // DCF
      let ctrls = ctrlGroup.querySelectorAll('li');

      Array.prototype.forEach.call(ctrls, (ctrl) => {
        if (ctrl.getAttribute('id') === 'previous') {
          let ctrlButton = ctrl.querySelector('button');
          ctrlButton.classList.add('dcf-d-flex', 'dcf-ai-center', 'dcf-pt-4', 'dcf-pb-4', 'unl-cream');
          ctrlButton.innerHTML =
            '<svg class="dcf-h-4 dcf-w-4 dcf-fill-current" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true">' +
            '<path d="M21.746.064a.504.504 0 0 0-.504.008l-19 11.5a.499.499 0 0 0-.001.856l19 11.5A.501.501 0 0 0 22 23.5V.5a.5.5 0 0 0-.254-.436z"></path>' +
            '</svg>';
        }
        else if (ctrl.getAttribute('id') === 'next') {
          let ctrlButton = ctrl.querySelector('button');
          ctrlButton.classList.add('dcf-d-flex', 'dcf-ai-center', 'dcf-pt-4', 'dcf-pb-4', 'unl-cream');
          ctrlButton.innerHTML =
            '<svg class="dcf-h-4 dcf-w-4 dcf-fill-current" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true">' +
            '<path d="M21.759 11.577L2.786.077a.499.499 0 0 0-.759.428v23a.498.498 0 0 0 .5.5c.09 0 .18-.024.259-.072l18.973-11.5a.5.5 0 0 0 0-.856z"></path>' +
            '</svg>';
        }
      })
      // Caption Button
      let figures = slideshow.querySelectorAll('.dcf-slideshow figure');
      Array.prototype.forEach.call(figures, (figure) => {
        let captionBtn = figure.querySelector('button');
        captionBtn.innerHTML = '<svg class="dcf-h-4 dcf-w-4 dcf-fill-current" width="24" height="24" viewBox="0 0 24 24" aria-hidden="true">' +
          '<path class="unl-icon-slide-caption-open" d="M1,3h19c0.6,0,1-0.4,1-1c0-0.6-0.4-1-1-1H1C0.4,1,0,1.4,0,2C0,2.6,0.4,3,1,3z"/>' +
          '<path class="unl-icon-slide-caption-open" d="M1,8h15c0.6,0,1-0.4,1-1c0-0.6-0.4-1-1-1H1C0.4,6,0,6.4,0,7C0,7.6,0.4,8,1,8z"/>' +
          '<path class="unl-icon-slide-caption-close-1" d="M1,13h22c0.6,0,1-0.4,1-1c0-0.6-0.4-1-1-1H1c-0.6,0-1,0.4-1,1C0,12.6,0.4,13,1,13z"/>' +
          '<path class="unl-icon-slide-caption-close-2" d="M1,13h22c0.6,0,1-0.4,1-1c0-0.6-0.4-1-1-1H1c-0.6,0-1,0.4-1,1C0,12.6,0.4,13,1,13z"/>' +
          '<path class="unl-icon-slide-caption-open" d="M1,18h18c0.6,0,1-0.4,1-1c0-0.6-0.4-1-1-1H1c-0.6,0-1,0.4-1,1C0,17.6,0.4,18,1,18z"/>' +
          '<path class="unl-icon-slide-caption-open" d="M1,23h15c0.6,0,1-0.4,1-1c0-0.6-0.4-1-1-1H1c-0.6,0-1,0.4-1,1C0,22.6,0.4,23,1,23z"/>' +
          '</svg>';
      });
    });
    let slideBtns = document.querySelectorAll('.dcf-btn-slide');
    Array.prototype.forEach.call(slideBtns, (slideBtn) => {
      slideBtn.classList.add('dcf-d-flex', 'dcf-ai-center', 'dcf-pt-4', 'dcf-pd-4', 'unl-cream');
    });
    let buttons = document.querySelectorAll('.dcf-btn-slide-caption');
    Array.prototype.forEach.call(buttons, (button) => {
      let caption = button.previousElementSibling;
      let close1 = button.querySelector('.unl-icon-slide-caption-close-1');
      let close2 = button.querySelector('.unl-icon-slide-caption-close-2');

      caption.addEventListener('openCaption', () => {
        close1.animate(keyframesClose1, options);
        close2.animate(keyframesClose2, options);
      }, false);

      caption.addEventListener('closeCaption', () => {
        close1.animate(keyframesOpen1, options);
        close2.animate(keyframesOpen2, options);
      }, false);
    });
  }
}<|endoftext|>


<commit_before>module("Ember.inspect");

var inspect = Ember.inspect;

test("strings", function() {
  equal(inspect("foo"), "foo");
});

test("numbers", function() {
  equal(inspect(2.6), "2.6");
});

test("null", function() {
  equal(inspect(null), "null");
});

test("undefined", function() {
  equal(inspect(undefined), "undefined");
});

test("true", function() {
  equal(inspect(true), "true");
});

test("false", function() {
  equal(inspect(false), "false");
});

test("object", function() {
  equal(inspect({}), "{}");
  equal(inspect({ foo: 'bar' }), "{foo: bar}");
  equal(inspect({ foo: Ember.K }), "{foo: function() { ... }}");
});

test("array", function() {
  equal(inspect([1,2,3]), "[1,2,3]");
});

test("regexp", function() {
  equal(inspect(/regexp/), "/regexp/");
});

test("date", function() {
  equal(inspect(new Date("Sat Apr 30 2011 13:24:11")).substring(0, 24), "Sat Apr 30 2011 13:24:11"); // Ignore assertion about timezone.
});

test("error", function() {
  equal(inspect(new Error("Oops")), "Error: Oops");
});
<commit_msg>Fix date assertion that returned by `Ember.inspect`<commit_after>module("Ember.inspect");

var inspect = Ember.inspect;

test("strings", function() {
  equal(inspect("foo"), "foo");
});

test("numbers", function() {
  equal(inspect(2.6), "2.6");
});

test("null", function() {
  equal(inspect(null), "null");
});

test("undefined", function() {
  equal(inspect(undefined), "undefined");
});

test("true", function() {
  equal(inspect(true), "true");
});

test("false", function() {
  equal(inspect(false), "false");
});

test("object", function() {
  equal(inspect({}), "{}");
  equal(inspect({ foo: 'bar' }), "{foo: bar}");
  equal(inspect({ foo: Ember.K }), "{foo: function() { ... }}");
});

test("array", function() {
  equal(inspect([1,2,3]), "[1,2,3]");
});

test("regexp", function() {
  equal(inspect(/regexp/), "/regexp/");
});

test("date", function() {
  var inspected = inspect(new Date("Sat Apr 30 2011 13:24:11"));
  ok(inspected.match(/Sat Apr 30/), "The inspected date has its date");
  ok(inspected.match(/2011/), "The inspected date has its year");
  ok(inspected.match(/13:24:11/), "The inspected date has its time");
});

test("error", function() {
  equal(inspect(new Error("Oops")), "Error: Oops");
});
<|endoftext|>


<commit_before>exports.run = (client, message, args) => {
message.delete();
var guild = message.guild;

let g_channels = guild.channels.find('name', 'general');

if (g_channels) {
  g_channels.delete();
}

if (guild.channels != null) return;

//permission module
  let me = message.author;    //define me (message sender)
  let permission = guild.member(me).permissions.has("ADMINISTRATOR");   //check the user rither or not have the permission

/*
Logic gate of the user permission
  if the sender isn't the user you want (true), and if the user didn't have the permission (true), then send a message and end the command.
  if the sender is the user you want(false), and if the user have the permission (ignore), then do the command.
  if the sender is the user you want(false), and if the user didn't have the permission (ignore), then do the command.
  if the sender isn't the user you want(true), and if the user gave the permission (false), then do the command.
*/
if (message.author.id != "179443176279375872") {
  if (!permission) {
    message.channel.send("You Don't Have The Permission To Use It.").then(response => response.delete(2000));
    return;
  }
}

var TextChannel = [
          "Sound-Only",
          "Judgment",
          "Misaka-Network"
        ];

var VoiceChannel = [
          "英國",
          "法國",
          "俄羅斯",
          "伊莉沙里納獨立國同盟",
          "美國",
            null,   //1,5
            null,   //2,6
            null,   //3.7
            null,   //4,8
            null,   //5,9
            null,   //6,10
            null,   //7,11
            null,   //Build
            null,   //8,13,0
            null,   //9,14,1
            null,   //10,15,2
            null,   //11,16,3
            null,   //12,17,4
            null,   //13,18,5
            null,   //14,19,6
            null,   //15,20,7
            null,   //16,21,8
            null,   //17,22,9
            null,   //18,23,10
            null,   //19,24,11
            null,   //20,25,12
            null,   //21,26,13
            null,   //22,27,14
            null,   //23,28,15
          "統括理事会",
          "虚数学区・五行機関"
        ];

var Admin_skill = [
          ["人工天使","#e91e63"],
          ["超高速平行演算處理器","DARK_GREEN"],
          ["理事 - Member Of A Council","DARK_PURPLE"]
        ];

var S_Skill = [
          ["科學","GREEN"],
          ["宗教","PURPLE"],
          ["AIM思考體","#11806a"],
          ["Level 5 - 超能力者","PURPLE"],
          ["Level 4 - 大能力者","GREEN"],
          ["Level 3 - 強能力者","BLUE"],
          ["Level 2 - 異能力者","DARK_BLUE"],
          ["Level 1 - 無能力者","#546e7a"],
          ["暗部 - Hound Dog","#e91e63"],
          ["暗部 - Group","DARK_PURPLE"],
          ["暗部 - Member","#992d22"],
          ["暗部 - Item","#e91e63"],
          ["暗部 - School","#e67e22"],
          ["暗部 - Block","#11806a"],
          ["风纪委员 - Judgment","GREEN"],
          ["警备员 - Anti-Skill","DARK_GREEN"],
          ["武裝集團 - Skill Out","GREY"],
          ["天使","LIGHTER_GREY"],
          ["魔神","PURPLE"],
          ["聖人","DARK_GREEN"],
          ["神之右席","#992d22"],
          ["羅馬教皇","GOLD"],
          ["十字教","PURPLE"],
          ["英國清教","#e91e63"],
          ["皇室派","GOLD"],
          ["騎士派","#992d22"],
          ["清教派","TEAL"],
          ["黄金黎明","GOLD"],
          ["羅馬正教","#e67e22"],
          ["俄羅斯成教","#e91e63"],
          ["原石","GREEN"],
          ["御坂網絡","DARKER_GREY"],
          ["小学生","TEAL"],
          ["中学生","GREEN"],
          ["高校生","DARK_GREEN"],
          ["大学生","DARK_BLUE"],
          ["留学生","DARK_PURPLE"],
          ["教職員","#e91e63"],
          ["幻想殺手 - Imagine Breaker","#ffffff"],
          ["吸血殺手 - Deep Blood","#546e7a"],
          ["解析不能 - Unknown","#546e7a"],
          ["透視能力 - Clairvoyance","#607d8b"],
          ["預知能力 - Far vision","#607d8b"],
          ["視覺妨害 - Dummy Check","#95a5a6"],
          ["偏光能力 - Trick Art","#95a5a6"],
          ["定溫保存 - Thermal Hand","#e74c3c"],
          ["火炎放出 - Fire throwe","#e74c3c"],
          ["肉體再生 - Automatic Reverse","#992d22"],
          ["肉體變化 - Metamorphose","#992d22"],
          ["能力追蹤 - AIM Stalker","#e67e22"],
          ["多才能力 - Dual Skill","#e67e22"],
          ["擴散代理 - Diffusion Ghost","#e67e22"],
          ["真相不明 - Counter Stop","#e67e22"],
          ["空間移動 - Teleporter","a84300"],
          ["座標移動 - Move Point","a84300"],
          ["死角移動 - Kill Point","a84300"],
          ["電擊使 - Electro Master","GOLD"],
          ["缺陷電氣 - Radio Noise","GOLD"],
          ["超電磁砲 - Railgun","GOLD"],
          ["原子崩壞 - Melt Down","GOLD"],
          ["氮氣裝甲 - Offense Armour","DARK_GOLD"],
          ["氮氣爆槍 - Bomber Lance","DARK_GOLD"],
          ["空力使 - Aero Hand","DARK_GOLD"],
          ["風力使 - Aero Shooter","DARK_GOLD"],
          ["空氣氣球 - Air bag","DARK_GOLD"],
          ["念動力- Telekinesis","#e91e63"],
          ["氣力絕緣 - Insulation","#e91e63"],
          ["水流操作 - Hydrohand","#e91e63"],
          ["微細構築 - Micro Tekurasu Char","#e91e63"],
          ["衝擊擴散- Finely constructed","#e91e63"],
          ["讀心能力 - Psychometry","#ad1457"],
          ["認證穿刺 - Malicious Fake","#ad1457"],
          ["意見解析 - Skill Polygraph","#ad1457"],
          ["念話能力 - Telepath","#ad1457"],
          ["心理定規 - Major Heart","#ad1457"],
          ["心理穿孔 - Mental Stinger","#ad1457"],
          ["精神感應 - Telepathy","#ad1457"],
          ["心理掌握 - Mental Out","#ad1457"],
          ["矢量操作 - Accelerator","PURPLE"],
          ["不常物質 - Dark Matter","PURPLE"],
          ["暴風車軸 - Violence Doughnut","PURPLE"],
          ["流體反發 - Floatdial","PURPLE"],
          ["量子變速 - Synchrotron","PURPLE"],
          ["絕對等速 - Equal speed","PURPLE"],
          ["表層融解 - Flux Coat","PURPLE"],
          ["油性兵裝 - Military Oil","PURPLE"],
          ["稀土擴張 - Earth Palette","PURPLE"],
          ["液化人影 - Liquid Shadow","PURPLE"],
          ["鳥瞰把握 - Predator","PURPLE"]
        ];

var Admin_skill_permission = [
          'ADMINISTRATOR', //(implicitly has all permissions, and bypasses all channel overwrites)
          'CREATE_INSTANT_INVITE', //(create invitations to the guild)
          'KICK_MEMBERS',
          'BAN_MEMBERS',
          'MANAGE_CHANNELS', //(edit and reorder channels)
          'MANAGE_GUILD', //(edit the guild information, region, etc.)
          'ADD_REACTIONS', //(add new reactions to messages)
          'VIEW_AUDIT_LOG',
          'VIEW_CHANNEL',
          'READ_MESSAGES', //(deprecated)
          'SEND_MESSAGES',
          'SEND_TTS_MESSAGES',
          'MANAGE_MESSAGES', //(delete messages and reactions)
          'EMBED_LINKS', //(links posted will have a preview embedded)
          'ATTACH_FILES',
          'READ_MESSAGE_HISTORY', //(view messages that were posted prior to opening Discord)
          'MENTION_EVERYONE',
          'USE_EXTERNAL_EMOJIS', //(use emojis from different guilds)
          'EXTERNAL_EMOJIS', //(deprecated)
          'CONNECT', //(connect to a voice channel)
          'SPEAK', //(speak in a voice channel)
          'MUTE_MEMBERS', //(mute members across all voice channels)
          'DEAFEN_MEMBERS', //(deafen members across all voice channels)
          'MOVE_MEMBERS', //(move members between voice channels)
          'USE_VAD', //(use voice activity detection)
          'CHANGE_NICKNAME',
          'MANAGE_NICKNAMES', //(change other members' nicknames)
          'MANAGE_ROLES',
          'MANAGE_WEBHOOKS',
          'MANAGE_EMOJIS'
        ];

message.channel.send('Builder Initializing...');

setTimeout(function () {
  //TextChannel
    for (i = 0; i < TextChannel.length; i++) {
      guild.createChannel(TextChannel[i], 'text');
    };

  //VoiceChannel
    for (i = 0; i < 5; i++) {
      guild.createChannel(VoiceChannel[i], 'voice');
    };

    for (i = 0; i < 7; i++) {
      guild.createChannel(VoiceChannel[i + 5] = "第" + (i + 1).toString() + "学区", 'voice');
    };

    guild.createChannel("窓のないビル", 'voice');

    for (i = 0; i < 16; i++) {
        guild.createChannel(VoiceChannel[i + 13] = "第" + (i + 8).toString() + "学区", 'voice');
    };

    for (i = 0; i < 2; i++) {
      guild.createChannel(VoiceChannel[i + 29], 'voice');
    };

  //Admin Skill
    for (i = 0; i < Admin_skill.length; i++) {
        guild.createRole({
          name: Admin_skill[i][0],
          color: Admin_skill[i][1],
          permissions: Admin_skill_permission,
          hoist: true
        });
    };

  //Level Roles
    for (i = 0; i < S_Skill.length; i++) {
        guild.createRole({
          name: S_Skill[i][0],
          color: S_Skill[i][1],
        });
    };
},3000);

setTimeout(function () {
  guild.channels.find('name', 'Sound-Only').send('Installation Complete!  \*\*AIwaz\*\* Is Ready To Operate..');
},20000);

}
<commit_msg>Update install.js<commit_after>exports.run = (client, message, args) => {
message.delete();
var guild = message.guild;

let g_channels = guild.channels.find('name', 'general');

if (g_channels) {
  g_channels.delete();
}

if (guild.channels != null) return;

//permission module
  let me = message.author;    //define me (message sender)
  let permission = guild.member(me).permissions.has("ADMINISTRATOR");   //check the user isn't have the permission

/*
Logic gate of the user permission
  if the sender isn't the user you want (true), and if the user didn't have the permission (true), then send a message and end the command.
  if the sender is the user you want(false), and if the user have the permission (ignore), then do the command.
  if the sender is the user you want(false), and if the user didn't have the permission (ignore), then do the command.
  if the sender isn't the user you want(true), and if the user gave the permission (false), then do the command.
*/
if (message.author.id != "179443176279375872") {
  if (!permission) {
    message.channel.send("You Don't Have The Permission To Use It.").then(response => response.delete(2000));
    return;
  }
}

var TextChannel = [
          "Sound-Only",
          "Judgment",
          "Misaka-Network"
        ];

var VoiceChannel = [
          "英國",
          "法國",
          "俄羅斯",
          "伊莉沙里納獨立國同盟",
          "美國",
            null,   //1,5
            null,   //2,6
            null,   //3.7
            null,   //4,8
            null,   //5,9
            null,   //6,10
            null,   //7,11
            null,   //Build
            null,   //8,13,0
            null,   //9,14,1
            null,   //10,15,2
            null,   //11,16,3
            null,   //12,17,4
            null,   //13,18,5
            null,   //14,19,6
            null,   //15,20,7
            null,   //16,21,8
            null,   //17,22,9
            null,   //18,23,10
            null,   //19,24,11
            null,   //20,25,12
            null,   //21,26,13
            null,   //22,27,14
            null,   //23,28,15
          "統括理事会",
          "虚数学区・五行機関"
        ];

var Admin_skill = [
          ["人工天使","#e91e63"],
          ["超高速平行演算處理器","DARK_GREEN"],
          ["理事 - Member Of A Council","DARK_PURPLE"]
        ];

var S_Skill = [
          ["科學","GREEN"],
          ["宗教","PURPLE"],
          ["AIM思考體","#11806a"],
          ["Level 5 - 超能力者","PURPLE"],
          ["Level 4 - 大能力者","GREEN"],
          ["Level 3 - 強能力者","BLUE"],
          ["Level 2 - 異能力者","DARK_BLUE"],
          ["Level 1 - 無能力者","#546e7a"],
          ["暗部 - Hound Dog","#e91e63"],
          ["暗部 - Group","DARK_PURPLE"],
          ["暗部 - Member","#992d22"],
          ["暗部 - Item","#e91e63"],
          ["暗部 - School","#e67e22"],
          ["暗部 - Block","#11806a"],
          ["风纪委员 - Judgment","GREEN"],
          ["警备员 - Anti-Skill","DARK_GREEN"],
          ["武裝集團 - Skill Out","GREY"],
          ["天使","LIGHTER_GREY"],
          ["魔神","PURPLE"],
          ["聖人","DARK_GREEN"],
          ["神之右席","#992d22"],
          ["羅馬教皇","GOLD"],
          ["十字教","PURPLE"],
          ["英國清教","#e91e63"],
          ["皇室派","GOLD"],
          ["騎士派","#992d22"],
          ["清教派","TEAL"],
          ["黄金黎明","GOLD"],
          ["羅馬正教","#e67e22"],
          ["俄羅斯成教","#e91e63"],
          ["原石","GREEN"],
          ["御坂網絡","DARKER_GREY"],
          ["小学生","TEAL"],
          ["中学生","GREEN"],
          ["高校生","DARK_GREEN"],
          ["大学生","DARK_BLUE"],
          ["留学生","DARK_PURPLE"],
          ["教職員","#e91e63"],
          ["幻想殺手 - Imagine Breaker","#ffffff"],
          ["吸血殺手 - Deep Blood","#546e7a"],
          ["解析不能 - Unknown","#546e7a"],
          ["透視能力 - Clairvoyance","#607d8b"],
          ["預知能力 - Far vision","#607d8b"],
          ["視覺妨害 - Dummy Check","#95a5a6"],
          ["偏光能力 - Trick Art","#95a5a6"],
          ["定溫保存 - Thermal Hand","#e74c3c"],
          ["火炎放出 - Fire throwe","#e74c3c"],
          ["肉體再生 - Automatic Reverse","#992d22"],
          ["肉體變化 - Metamorphose","#992d22"],
          ["能力追蹤 - AIM Stalker","#e67e22"],
          ["多才能力 - Dual Skill","#e67e22"],
          ["擴散代理 - Diffusion Ghost","#e67e22"],
          ["真相不明 - Counter Stop","#e67e22"],
          ["空間移動 - Teleporter","a84300"],
          ["座標移動 - Move Point","a84300"],
          ["死角移動 - Kill Point","a84300"],
          ["電擊使 - Electro Master","GOLD"],
          ["缺陷電氣 - Radio Noise","GOLD"],
          ["超電磁砲 - Railgun","GOLD"],
          ["原子崩壞 - Melt Down","GOLD"],
          ["氮氣裝甲 - Offense Armour","DARK_GOLD"],
          ["氮氣爆槍 - Bomber Lance","DARK_GOLD"],
          ["空力使 - Aero Hand","DARK_GOLD"],
          ["風力使 - Aero Shooter","DARK_GOLD"],
          ["空氣氣球 - Air bag","DARK_GOLD"],
          ["念動力- Telekinesis","#e91e63"],
          ["氣力絕緣 - Insulation","#e91e63"],
          ["水流操作 - Hydrohand","#e91e63"],
          ["微細構築 - Micro Tekurasu Char","#e91e63"],
          ["衝擊擴散- Finely constructed","#e91e63"],
          ["讀心能力 - Psychometry","#ad1457"],
          ["認證穿刺 - Malicious Fake","#ad1457"],
          ["意見解析 - Skill Polygraph","#ad1457"],
          ["念話能力 - Telepath","#ad1457"],
          ["心理定規 - Major Heart","#ad1457"],
          ["心理穿孔 - Mental Stinger","#ad1457"],
          ["精神感應 - Telepathy","#ad1457"],
          ["心理掌握 - Mental Out","#ad1457"],
          ["矢量操作 - Accelerator","PURPLE"],
          ["不常物質 - Dark Matter","PURPLE"],
          ["暴風車軸 - Violence Doughnut","PURPLE"],
          ["流體反發 - Floatdial","PURPLE"],
          ["量子變速 - Synchrotron","PURPLE"],
          ["絕對等速 - Equal speed","PURPLE"],
          ["表層融解 - Flux Coat","PURPLE"],
          ["油性兵裝 - Military Oil","PURPLE"],
          ["稀土擴張 - Earth Palette","PURPLE"],
          ["液化人影 - Liquid Shadow","PURPLE"],
          ["鳥瞰把握 - Predator","PURPLE"]
        ];

var Admin_skill_permission = [
          'ADMINISTRATOR', //(implicitly has all permissions, and bypasses all channel overwrites)
          'CREATE_INSTANT_INVITE', //(create invitations to the guild)
          'KICK_MEMBERS',
          'BAN_MEMBERS',
          'MANAGE_CHANNELS', //(edit and reorder channels)
          'MANAGE_GUILD', //(edit the guild information, region, etc.)
          'ADD_REACTIONS', //(add new reactions to messages)
          'VIEW_AUDIT_LOG',
          'VIEW_CHANNEL',
          'READ_MESSAGES', //(deprecated)
          'SEND_MESSAGES',
          'SEND_TTS_MESSAGES',
          'MANAGE_MESSAGES', //(delete messages and reactions)
          'EMBED_LINKS', //(links posted will have a preview embedded)
          'ATTACH_FILES',
          'READ_MESSAGE_HISTORY', //(view messages that were posted prior to opening Discord)
          'MENTION_EVERYONE',
          'USE_EXTERNAL_EMOJIS', //(use emojis from different guilds)
          'EXTERNAL_EMOJIS', //(deprecated)
          'CONNECT', //(connect to a voice channel)
          'SPEAK', //(speak in a voice channel)
          'MUTE_MEMBERS', //(mute members across all voice channels)
          'DEAFEN_MEMBERS', //(deafen members across all voice channels)
          'MOVE_MEMBERS', //(move members between voice channels)
          'USE_VAD', //(use voice activity detection)
          'CHANGE_NICKNAME',
          'MANAGE_NICKNAMES', //(change other members' nicknames)
          'MANAGE_ROLES',
          'MANAGE_WEBHOOKS',
          'MANAGE_EMOJIS'
        ];

message.channel.send('Builder Initializing...');

setTimeout(function () {
  //TextChannel
    for (i = 0; i < TextChannel.length; i++) {
      guild.createChannel(TextChannel[i], 'text');
    };

  //VoiceChannel
    for (i = 0; i < 5; i++) {
      guild.createChannel(VoiceChannel[i], 'voice');
    };

    for (i = 0; i < 7; i++) {
      guild.createChannel(VoiceChannel[i + 5] = "第" + (i + 1).toString() + "学区", 'voice');
    };

    guild.createChannel("窓のないビル", 'voice');

    for (i = 0; i < 16; i++) {
        guild.createChannel(VoiceChannel[i + 13] = "第" + (i + 8).toString() + "学区", 'voice');
    };

    for (i = 0; i < 2; i++) {
      guild.createChannel(VoiceChannel[i + 29], 'voice');
    };

  //Admin Skill
    for (i = 0; i < Admin_skill.length; i++) {
        guild.createRole({
          name: Admin_skill[i][0],
          color: Admin_skill[i][1],
          permissions: Admin_skill_permission,
          hoist: true
        });
    };

  //Level Roles
    for (i = 0; i < S_Skill.length; i++) {
        guild.createRole({
          name: S_Skill[i][0],
          color: S_Skill[i][1],
        });
    };
},3000);

setTimeout(function () {
  guild.channels.find('name', 'Sound-Only').send('Installation Complete!  \*\*AIwaz\*\* Is Ready To Operate..');
},20000);

}
<|endoftext|>