<commit_before>// Copyright 2016-2019, University of Colorado Boulder

// Note: This file is a mashup of two ported Java files: Carousel and
// EnergySystemElementCarousel. Carousel.java was not ported to avoid confusion
// with the PhET Sun Carousel.js UI component.

/**
 * This type implements a model-based carousel for positionable model elements. Model elements are positioned based
 * on the current selection, and an API is provided that allows clients to change those selection. Changes to the
 * selected element are animated.
 *
 * @author John Blanco
 * @author Andrew Adare
 * @author Jesse Greenberg
 */
define( require => {
  'use strict';

  // modules
  const BooleanProperty = require( 'AXON/BooleanProperty' );
  const Easing = require( 'TWIXT/Easing' );
  const energyFormsAndChanges = require( 'ENERGY_FORMS_AND_CHANGES/energyFormsAndChanges' );
  const NumberProperty = require( 'AXON/NumberProperty' );
  const Range = require( 'DOT/Range' );
  const Util = require( 'DOT/Util' );
  const Vector2 = require( 'DOT/Vector2' );

  // constants
  const TRANSITION_DURATION = 0.75; // in seconds

  class EnergySystemElementCarousel {

    /**
     * @param {EnergySystemElement[]} - array of elements to add to this carousel
     * @param {Vector2} selectedElementPosition - location where the selected model element should be
     * @param {Vector2} offsetBetweenElements - offset between elements in the carousel
     * @param {Tandem} tandem
     */
    constructor( elements, selectedElementPosition, offsetBetweenElements, tandem ) {

      // @public (read-only) {Vector2} - the position in model space where the currently selected element should be
      this.selectedElementPosition = selectedElementPosition;

      // @private {Vector2} - the offset between elements whose position is managed by this carousel
      this.offsetBetweenElements = offsetBetweenElements;

      // @public (read-only) {EnergySystemElement[]} - list of the elements whose position is managed by this carousel
      this.managedElements = [];

      // add each element to the array of managed elements
      elements.forEach( element => this.add( element ) );

      // @public (read-only) {NumberProperty} - indicates which element on the carousel is currently selected
      this.targetIndexProperty = new NumberProperty( 0, {
        range: new Range( 0, this.managedElements.length - 1 ),
        tandem: tandem.createTandem( 'targetIndexProperty' )
      } );

      // @public (read-only) {BooleanProperty} - a flag indicating whether or not an animation from one carousel position
      // to another is in progress
      this.animationInProgressProperty = new BooleanProperty( false, {
        tandem: tandem.createTandem( 'animationInProgressProperty' )
      } );

      // @private - variables needed to manage carousel transitions
      this.elapsedTransitionTime = 0; // in seconds
      this.currentCarouselOffset = new Vector2( 0, 0 ); // in meters
      this.initialCarouselOffset = new Vector2( 0, 0 ); // in meters

      // set up the variables needed for animation each time the target changes
      this.targetIndexProperty.lazyLink( () => {

        // set vars for the transition
        this.elapsedTransitionTime = 0;
        this.initialCarouselOffset = this.currentCarouselOffset;
        this.animationInProgressProperty.set( true );
      } );

      // activate and deactivate energy system elements as they come into the center location
      this.animationInProgressProperty.lazyLink( animationInProgress => {
        if ( animationInProgress ) {
          this.managedElements.forEach( element => {
            element.deactivate();
          } );
        }
        else {
          this.getElement( this.targetIndexProperty.value ).activate();
        }
      } );
    }

    /**
     * add element to list of managed elements
     * @param {EnergySystemElement} element - energy system element to be added to carousel
     * @private
     */
    add( element ) {

      // set the element's position to be at the end of the carousel
      if ( this.managedElements.length === 0 ) {
        element.positionProperty.set( this.selectedElementPosition );
      }
      else {
        const lastElement = this.managedElements[ this.managedElements.length - 1 ];
        element.positionProperty.set( lastElement.positionProperty.value.plus( this.offsetBetweenElements ) );
      }

      // add element to the list of managed elements
      this.managedElements.push( element );

      // update opacities
      this.updateManagedElementOpacities();
    }

    /**
     * get an element from carousel by index
     * @param  {number} index Requested position in array of EnergySystemElements
     * @returns {EnergySystemElement}
     * @public
     */
    getElement( index ) {
      assert && assert( index < this.managedElements.length, `carousel index out of range: ${index}` );
      return this.managedElements[ index ];
    }

    /**
     * get the currently selected element from carousel
     * @returns {EnergySystemElement|null}
     * @public
     */
    getSelectedElement() {
      const i = this.targetIndexProperty.get();
      if ( i < this.managedElements.length ) {
        return this.managedElements[ i ];
      }
      return null;
    }

    /**
     * step this model element
     * @param {number} dt - time step, in seconds
     * @public
     */
    step( dt ) {
      if ( !this.atTargetPosition() ) {
        this.elapsedTransitionTime += dt;
        const targetCarouselOffset = this.offsetBetweenElements.times( -this.targetIndexProperty.get() );
        const totalTravelVector = targetCarouselOffset.minus( this.initialCarouselOffset );
        const transitionProportion = Util.clamp( this.elapsedTransitionTime / TRANSITION_DURATION, 0, 1 );
        this.currentCarouselOffset =
          this.initialCarouselOffset.plus( totalTravelVector.times( Easing.CUBIC_IN_OUT.value( transitionProportion ) ) );
        this.updateManagedElementPositions();

        if ( transitionProportion === 1 ) {
          this.currentCarouselOffset = targetCarouselOffset;
        }

        if ( this.currentCarouselOffset === targetCarouselOffset ) {
          this.animationInProgressProperty.set( false );
        }
        this.updateManagedElementOpacities();
      }
    }

    /**
     * sets the position in model space of each element based on the state of the carousel
     * @private
     */
    updateManagedElementPositions() {
      for ( let i = 0; i < this.managedElements.length; i++ ) {
        let position = this.selectedElementPosition.plus( this.offsetBetweenElements.times( i ) );
        position = position.plus( this.currentCarouselOffset );
        this.managedElements[ i ].positionProperty.set( position );
      }
    }

    /**
     * sets the opacity of each element based on the state of the carousel. elements fade out as they get farther from
     * the active, selected position
     * @private
     */
    updateManagedElementOpacities() {
      this.managedElements.forEach( managedElement => {
        const distanceToSelection = managedElement.positionProperty.value.distance( this.selectedElementPosition );
        const opacity = Util.clamp( 1 - ( distanceToSelection / this.offsetBetweenElements.magnitude ), 0, 1 );
        managedElement.opacityProperty.set( opacity );
      } );
    }

    /**
     * whether the current selected element is in its destination spot
     * @private
     * @returns {boolean}
     */
    atTargetPosition() {
      const targetCarouselOffset = this.offsetBetweenElements.times( -this.targetIndexProperty.value );
      return this.currentCarouselOffset.equals( targetCarouselOffset );
    }
  }

  return energyFormsAndChanges.register( 'EnergySystemElementCarousel', EnergySystemElementCarousel );
} );
<commit_msg>Refactor targetIndexProperty validation as validValues, see https://github.com/phetsims/energy-forms-and-changes/issues/216<commit_after>// Copyright 2016-2019, University of Colorado Boulder

// Note: This file is a mashup of two ported Java files: Carousel and
// EnergySystemElementCarousel. Carousel.java was not ported to avoid confusion
// with the PhET Sun Carousel.js UI component.

/**
 * This type implements a model-based carousel for positionable model elements. Model elements are positioned based
 * on the current selection, and an API is provided that allows clients to change those selection. Changes to the
 * selected element are animated.
 *
 * @author John Blanco
 * @author Andrew Adare
 * @author Jesse Greenberg
 */
define( require => {
  'use strict';

  // modules
  const BooleanProperty = require( 'AXON/BooleanProperty' );
  const Easing = require( 'TWIXT/Easing' );
  const energyFormsAndChanges = require( 'ENERGY_FORMS_AND_CHANGES/energyFormsAndChanges' );
  const NumberProperty = require( 'AXON/NumberProperty' );
  const Util = require( 'DOT/Util' );
  const Vector2 = require( 'DOT/Vector2' );

  // constants
  const TRANSITION_DURATION = 0.75; // in seconds

  class EnergySystemElementCarousel {

    /**
     * @param {EnergySystemElement[]} - array of elements to add to this carousel
     * @param {Vector2} selectedElementPosition - location where the selected model element should be
     * @param {Vector2} offsetBetweenElements - offset between elements in the carousel
     * @param {Tandem} tandem
     */
    constructor( elements, selectedElementPosition, offsetBetweenElements, tandem ) {

      // @public (read-only) {Vector2} - the position in model space where the currently selected element should be
      this.selectedElementPosition = selectedElementPosition;

      // @private {Vector2} - the offset between elements whose position is managed by this carousel
      this.offsetBetweenElements = offsetBetweenElements;

      // @public (read-only) {EnergySystemElement[]} - list of the elements whose position is managed by this carousel
      this.managedElements = [];

      // add each element to the array of managed elements
      elements.forEach( element => this.add( element ) );

      /**
       * calculates the valid target indices for this carousel
       *
       * @param {number} numberOfElements
       * @returns {number[]}
       */
      const getValidTargetIndices = numberOfElements => {
        const validTargetIndices = [];
        _.times( numberOfElements, index => {
          validTargetIndices.push( index );
        } );
        return validTargetIndices;
      };

      // @public (read-only) {NumberProperty} - indicates which element on the carousel is currently selected
      this.targetIndexProperty = new NumberProperty( 0, {
        validValues: getValidTargetIndices( this.managedElements.length ),
        tandem: tandem.createTandem( 'targetIndexProperty' )
      } );

      // @public (read-only) {BooleanProperty} - a flag indicating whether or not an animation from one carousel position
      // to another is in progress
      this.animationInProgressProperty = new BooleanProperty( false, {
        tandem: tandem.createTandem( 'animationInProgressProperty' )
      } );

      // @private - variables needed to manage carousel transitions
      this.elapsedTransitionTime = 0; // in seconds
      this.currentCarouselOffset = new Vector2( 0, 0 ); // in meters
      this.initialCarouselOffset = new Vector2( 0, 0 ); // in meters

      // set up the variables needed for animation each time the target changes
      this.targetIndexProperty.lazyLink( () => {

        // set vars for the transition
        this.elapsedTransitionTime = 0;
        this.initialCarouselOffset = this.currentCarouselOffset;
        this.animationInProgressProperty.set( true );
      } );

      // activate and deactivate energy system elements as they come into the center location
      this.animationInProgressProperty.lazyLink( animationInProgress => {
        if ( animationInProgress ) {
          this.managedElements.forEach( element => {
            element.deactivate();
          } );
        }
        else {
          this.getElement( this.targetIndexProperty.value ).activate();
        }
      } );
    }

    /**
     * add element to list of managed elements
     * @param {EnergySystemElement} element - energy system element to be added to carousel
     * @private
     */
    add( element ) {

      // set the element's position to be at the end of the carousel
      if ( this.managedElements.length === 0 ) {
        element.positionProperty.set( this.selectedElementPosition );
      }
      else {
        const lastElement = this.managedElements[ this.managedElements.length - 1 ];
        element.positionProperty.set( lastElement.positionProperty.value.plus( this.offsetBetweenElements ) );
      }

      // add element to the list of managed elements
      this.managedElements.push( element );

      // update opacities
      this.updateManagedElementOpacities();
    }

    /**
     * get an element from carousel by index
     * @param  {number} index Requested position in array of EnergySystemElements
     * @returns {EnergySystemElement}
     * @public
     */
    getElement( index ) {
      assert && assert( index < this.managedElements.length, `carousel index out of range: ${index}` );
      return this.managedElements[ index ];
    }

    /**
     * get the currently selected element from carousel
     * @returns {EnergySystemElement|null}
     * @public
     */
    getSelectedElement() {
      const i = this.targetIndexProperty.get();
      if ( i < this.managedElements.length ) {
        return this.managedElements[ i ];
      }
      return null;
    }

    /**
     * step this model element
     * @param {number} dt - time step, in seconds
     * @public
     */
    step( dt ) {
      if ( !this.atTargetPosition() ) {
        this.elapsedTransitionTime += dt;
        const targetCarouselOffset = this.offsetBetweenElements.times( -this.targetIndexProperty.get() );
        const totalTravelVector = targetCarouselOffset.minus( this.initialCarouselOffset );
        const transitionProportion = Util.clamp( this.elapsedTransitionTime / TRANSITION_DURATION, 0, 1 );
        this.currentCarouselOffset =
          this.initialCarouselOffset.plus( totalTravelVector.times( Easing.CUBIC_IN_OUT.value( transitionProportion ) ) );
        this.updateManagedElementPositions();

        if ( transitionProportion === 1 ) {
          this.currentCarouselOffset = targetCarouselOffset;
        }

        if ( this.currentCarouselOffset === targetCarouselOffset ) {
          this.animationInProgressProperty.set( false );
        }
        this.updateManagedElementOpacities();
      }
    }

    /**
     * sets the position in model space of each element based on the state of the carousel
     * @private
     */
    updateManagedElementPositions() {
      for ( let i = 0; i < this.managedElements.length; i++ ) {
        let position = this.selectedElementPosition.plus( this.offsetBetweenElements.times( i ) );
        position = position.plus( this.currentCarouselOffset );
        this.managedElements[ i ].positionProperty.set( position );
      }
    }

    /**
     * sets the opacity of each element based on the state of the carousel. elements fade out as they get farther from
     * the active, selected position
     * @private
     */
    updateManagedElementOpacities() {
      this.managedElements.forEach( managedElement => {
        const distanceToSelection = managedElement.positionProperty.value.distance( this.selectedElementPosition );
        const opacity = Util.clamp( 1 - ( distanceToSelection / this.offsetBetweenElements.magnitude ), 0, 1 );
        managedElement.opacityProperty.set( opacity );
      } );
    }

    /**
     * whether the current selected element is in its destination spot
     * @private
     * @returns {boolean}
     */
    atTargetPosition() {
      const targetCarouselOffset = this.offsetBetweenElements.times( -this.targetIndexProperty.value );
      return this.currentCarouselOffset.equals( targetCarouselOffset );
    }
  }

  return energyFormsAndChanges.register( 'EnergySystemElementCarousel', EnergySystemElementCarousel );
} );
<|endoftext|>


<commit_before><commit_msg>First experiments<commit_after>/**
 * Strings
 */
var text = '你好吗？';

console.log(text);

var helloWorld = 'Hello, World!';
console.log(helloWorld.startsWith('H'));

var a = 'Jo';
console.log(a.endsWith('O')); // case sensitive

// search for text
var gangstaIpsum = 'Lorizzle ipsum dolizzle sizzle dawg, we gonna chung owned elizzle.';
console.log(gangstaIpsum.includes('ipsum'));

// repeat
var theWord = 'secret';
console.log(theWord.repeat(2));

// The variable value is declared using let instead of var. That means the declaration is not hoisted to the top,
for (let i = 3;i>=1;i--) {
  console.log('Loop ' + i);
}

// constants are also block-level declarations,
const theAnswer = 42;
console.log(theAnswer);

/**
 * Functions
 */
function doGreeting(greeting = 'Hoi') {
  console.log(greeting);
}

doGreeting();
doGreeting('Hallo');

// spread
let numbers = [1, 2, 3];
console.log(Math.max(...numbers));

// arrow functions
var sayIt = it => console.log(it);
sayIt('Yo');

var sayMultipleThings = (so, many, ...things) => console.log(so, many, ...things);
var alphabet = ['c', 'd', 'e'];
sayMultipleThings('a', 'b', ...alphabet);

// generators
function *alphabetGenerator() {
  yield 'A';
  yield 'B';
  yield 'C';
}

var alphabet = alphabetGenerator();

console.log(alphabet.next().value);
console.log(alphabet.next().value);
console.log(alphabet.next().value);
console.log(alphabet.next().value);

// multiline comments
let comment = `this
is
a
comment`;
console.log(comment);

// string substitutions (usage of backticks required)
let hi = 'hi';
let dummyText = `I just wanted to say ${hi}`;
console.log(dummyText);

var saySum = (a, b) =>
              `sum of ${a} and ${b} is ${a + b}`

console.log(saySum(2, 3));
<|endoftext|>


<commit_before>var config = {
  server: "162.243.157.40:443",
  secure: false,
  masterServer: false,
  skins: "./skins/",
  logging: true
};<commit_msg>More config options<commit_after>var config = {
  server: "162.243.157.40:443",
  secure: false,
  masterServer: false,
  skins: "./skins/",
  logging: true,
  colorLine: '#faa',
  colorGrid: '#000',
  colorBack: '#f1f1f1',
};<|endoftext|>


<commit_before>(function (jskom) {
  // The MembershipListHandler regularly polls the server for any
  // new unread texts/memberships and upates the membership
  // list. The handling parts include updating the list of
  // memberships with what texts are unread and how many unread
  // there are.
  function MembershipListHandler($log, $q, $timeout, membershipsService, conn, membershipList) {
    this._$log = $log;
    this._$q = $q;
    this._$timeout = $timeout;
    this._membershipsService = membershipsService;

    this._conn = conn;
    this._membershipList = membershipList;
    this._logPrefix = "MembershipListHandler - ";

    this._initializePromise = null;

    this._refreshIntervalSeconds = 2*60;
    this._autoRefreshPromise = null;
  };

  _.extend(MembershipListHandler.prototype, {
    _initialize: function () {
      if (this._initializePromise == null) {
        var p1 = this._fetchUnreadMemberships();
        var p2 = this._fetchMembershipUnreads();
        var self = this;
        // The returned promise will be resolved when the unread
        // have been fetched, not when all memberships have been
        // fetched.
        this._initializePromise = this._$q.all([ p1, p2 ]).then(
          function () {
            // When we have fetched both the unread memberships and
            // the membershipUnreads, then we fetch the full membership list.
            self._registerEvents();
            self._fetchAllMemberships();
            self.enableAutoRefresh();
            self._$log.log(self._logPrefix + "initialize() - success");
          },
          function () {
            // if the initialize fails, remove the stored promise.
            self._$log.log(self._logPrefix + "initialize() - error");
            self._initializePromise = null;
            return self._$q.reject();
          });
      }
      return this._initializePromise;
    },

    _registerEvents : function () {
      var conn = this._conn;
      var self = this;
      conn.on('jskom:session:created', function ($event) {
        self._$log.log(self._logPrefix + 'on(jskom:session:created)');
        self.reset();
      });

      conn.on('jskom:session:changed', function ($event) {
        self._$log.log(self._logPrefix + 'on(jskom:session:changed)');
        self.reset();
      });

      conn.on('jskom:session:deleted', function ($event) {
        self._$log.log(self._logPrefix + 'on(jskom:session:deleted)');
        self.reset();
      });

      conn.on('jskom:readMarking:created', function ($event, text) {
        self._$log.log(self._logPrefix + 'on(jskom:readMarking:created)');
        var recipientConfNos = _.map(text.recipient_list, function (r) {
          return r.recpt.conf_no;
        });
        self._membershipList.markTextAsRead(text.text_no, recipientConfNos);
      });

      conn.on('jskom:readMarking:deleted', function ($event, text) {
        self._$log.log(self._logPrefix + 'on(jskom:readMarking:deleted)');
        var recipientConfNos = _.map(text.recipient_list, function (r) {
          return r.recpt.conf_no;
        });
        self._membershipList.markTextAsUnread(text.text_no, recipientConfNos);
      });

      conn.on('jskom:membership:created', function ($event, confNo) {
        self._$log.log(self._logPrefix + 'on(jskom:membership:created, ' + confNo + ')');
        self._fetchMembership(confNo);
        self._fetchMembershipUnread(confNo);
      });

      conn.on('jskom:membership:deleted', function ($event, confNo) {
        self._$log.log(self._logPrefix + 'on(jskom:membership:deleted, ' + confNo + ')');
        self._membershipList.deleteMembership(confNo);
      });

      conn.on('jskom:membership:changed', function ($event, confNo) {
        self._$log.log(self._logPrefix + 'on(jskom:membership:changed, ' + confNo + ')');
        self._fetchMembership(confNo);
      });

      conn.on('jskom:membershipUnread:changed', function ($event, confNo) {
        self._$log.log(self._logPrefix + 'on(jskom:membershipUnread:changed)');
        self._fetchMembershipUnread(confNo);
      });

      conn.on('jskom:text:created', function ($event, textNo, recipientList) {
        self._$log.log(self._logPrefix + 'on(jskom:text:created, ' + textNo + ')');
        var recipientConfNos = _.map(recipientList, function (r) {
          return r.recpt.conf_no;
        });
        self._membershipList.markTextAsUnread(textNo, recipientConfNos);
      });

      conn.on('jskom:text:fetched', function ($event, text) {
        self._$log.log(self._logPrefix + 'on(jskom:text:fetched, ' + text.text_no + ')');
        var recipientConfNos = _.map(text.recipient_list, function (r) {
          return r.recpt.conf_no;
        });
      });
    },

    _fetchMembershipUnreads: function () {
      // TODO: Make sure we only have one of these requests active
      // at one time.

      var logp = this._logPrefix + "getMembershipUnreads() - ";
      var self = this;
      return this._membershipsService.getMembershipUnreads(this._conn).then(
        function (membershipUnreads) {
          self._$log.log(logp + "success");
          self._membershipList.setMembershipUnreads(membershipUnreads);
        },
        function (response) {
          self._$log.log(logp + "error");
          // TODO: can we do anything? should we show a message?
          return self._$q.reject();
        });
    },

    _fetchMembershipUnread: function (confNo) {
      var logp = this._logPrefix + "getMembershipUnread(" + confNo + ") - ";
      var self = this;
      return this._membershipsService.getMembershipUnread(this._conn, confNo).then(
        function (membershipUnread) {
          self._$log.log(logp + "success");
          self._membershipList.setMembershipUnread(membershipUnread);
        },
        function (response) {
          self._$log.log(logp + "error");
          // TODO: can we do anything? should we show a message?
          return self._$q.reject();
        });
    },

    _fetchUnreadMemberships: function () {
      // TODO: Make sure we only have one of these requests active
      // at one time.

      var options = { unread: true };
      var logp = this._logPrefix + "getMemberships(" + angular.toJson(options) + ") - ";
      var self = this;
      return this._membershipsService.getMemberships(this._conn, options).then(
        function (unreadMembershipList) {
          self._$log.log(logp + "success");
          self._membershipList.addMemberships(unreadMembershipList.memberships);
        },
        function (response) {
          self._$log.log(logp + "error");
          // TODO: can we do anything? should we show a message?
          return self._$q.reject();
        });
    },

    _fetchAllMemberships: function () {
      // TODO: Make sure we only have one of these requests active
      // at one time.
      this._fetchMemberships(0, 500, 1000);
    },

    _fetchMemberships: function (first, noOfMemberships, maxNoOfMemberships) {
      var logp = this._logPrefix + "getMemberships({ unread: false }) - ";
      var self = this;
      var options = { unread: false, first: first, noOfMemberships: noOfMemberships }
      return this._membershipsService.getMemberships(self._conn, options).then(
        function (membershipList) {
          self._$log.log(logp + "success");
          self._membershipList.addMemberships(membershipList.memberships);
          var nextFirst = first + noOfMemberships;
          if (membershipList.has_more && nextFirst < maxNoOfMemberships) {
            self._fetchMemberships(nextFirst, noOfMemberships, maxNoOfMemberships);
          }
        },
        function (response) {
          self._$log.log(logp + "error");
          // TODO: can we do anything? should we show a message?
          return self._$q.reject();
        });
    },

    _fetchMembership: function (confNo) {
      var logp = this._logPrefix + "getMemberships(" + confNo + ") - ";
      var self = this;
      return this._membershipsService.getMembership(this._conn, confNo).then(
        function (membership) {
          self._$log.log(logp + "success");
          self._membershipList.addMembership(membership);
        },
        function (response) {
          self._$log.log(logp + "error");
          // TODO: can we do anything? should we show a message?
          return self._$q.reject();
        });
    },

    reset: function () {
      this.disableAutoRefresh();
      this._membershipList.clear();
      this._initializePromise = null;
    },

    getMembershipList: function () {
      var self = this;
      return this._initialize().then(function () {
        return self._membershipList;
      });
    },

    _enableAutoRefresh: function () {
      this._$log.log(this._logPrefix + "enabling auto-refresh");
      var self = this;
      function scheduleReload() {
        self._autoRefreshPromise = self._$timeout(function() {
          self.refreshUnread().then(
            function() {
              scheduleReload();
            },
            function() {
              self.disableAutoRefresh();
            });
        }, self._refreshIntervalSeconds * 1000);
      }
      scheduleReload();
    },

    enableAutoRefresh: function () {
      var self = this;
      return this._initialize().then(function () {
        self._enableAutoRefresh();
      });
    },

    disableAutoRefresh: function () {
      if (this._autoRefreshPromise != null) {
        this._$log.log(this._logPrefix + "disabling auto-refresh");
        this._$timeout.cancel(this._autoRefreshPromise);
        this._autoRefreshPromise = null;
      }
    },

    refreshUnread: function () {
      var self = this;
      return this._initialize().then(function () {
        return self._fetchMembershipUnreads();
      });
    }
  });

  jskom.MembershipListHandler = MembershipListHandler;

})(window.jskom);
<commit_msg>Better unread refresh. No longer disables auto refresh of unreads on failure, but instead delays the next attempt a bit longer.<commit_after>// Copyright (C) 2012-2014 Oskar Skoog.

'use strict';

(function (jskom) {
  // The MembershipListHandler regularly polls the server for any
  // new unread texts/memberships and upates the membership
  // list. The handling parts include updating the list of
  // memberships with what texts are unread and how many unread
  // there are.
  function MembershipListHandler($log, $q, $timeout, membershipsService, conn, membershipList) {
    this._$log = $log;
    this._$q = $q;
    this._$timeout = $timeout;
    this._membershipsService = membershipsService;

    this._conn = conn;
    this._membershipList = membershipList;
    this._logPrefix = "MembershipListHandler - ";

    this._initializePromise = null;

    this._refreshIntervalSeconds = 2*60;
    this._autoRefreshPromise = null;
  };

  _.extend(MembershipListHandler.prototype, {
    initialize: function () {
      return this._initialize();
    },

    _initialize: function () {
      // only initialize once
      if (this._initializePromise == null) {
        var p1 = this._fetchUnreadMemberships();
        var p2 = this._fetchMembershipUnreads();
        var self = this;
        // The returned promise will be resolved when the unread
        // have been fetched, not when all memberships have been
        // fetched.
        this._initializePromise = this._$q.all([ p1, p2 ]).then(
          function () {
            // When we have fetched both the unread memberships and
            // the membershipUnreads, then we fetch the full membership list.
            self._registerEvents();
            self._fetchAllMemberships();
            self.enableAutoRefresh();
            self._$log.log(self._logPrefix + "initialize() - success");
          },
          function () {
            // if the initialize fails, remove the stored promise.
            self._$log.log(self._logPrefix + "initialize() - error");
            self._initializePromise = null;
            return self._$q.reject();
          });
      }
      return this._initializePromise;
    },

    _registerEvents : function () {
      var conn = this._conn;
      var self = this;
      conn.on('jskom:session:created', function ($event) {
        self._$log.log(self._logPrefix + 'on(jskom:session:created)');
        self.reset();
      });

      conn.on('jskom:session:changed', function ($event) {
        self._$log.log(self._logPrefix + 'on(jskom:session:changed)');
        self.reset();
      });

      conn.on('jskom:session:deleted', function ($event) {
        self._$log.log(self._logPrefix + 'on(jskom:session:deleted)');
        self.reset();
      });

      conn.on('jskom:readMarking:created', function ($event, text) {
        self._$log.log(self._logPrefix + 'on(jskom:readMarking:created)');
        var recipientConfNos = _.map(text.recipient_list, function (r) {
          return r.recpt.conf_no;
        });
        self._membershipList.markTextAsRead(text.text_no, recipientConfNos);
      });

      conn.on('jskom:readMarking:deleted', function ($event, text) {
        self._$log.log(self._logPrefix + 'on(jskom:readMarking:deleted)');
        var recipientConfNos = _.map(text.recipient_list, function (r) {
          return r.recpt.conf_no;
        });
        self._membershipList.markTextAsUnread(text.text_no, recipientConfNos);
      });

      conn.on('jskom:membership:created', function ($event, confNo) {
        self._$log.log(self._logPrefix + 'on(jskom:membership:created, ' + confNo + ')');
        self._fetchMembership(confNo);
        self._fetchMembershipUnread(confNo);
      });

      conn.on('jskom:membership:deleted', function ($event, confNo) {
        self._$log.log(self._logPrefix + 'on(jskom:membership:deleted, ' + confNo + ')');
        self._membershipList.deleteMembership(confNo);
      });

      conn.on('jskom:membership:changed', function ($event, confNo) {
        self._$log.log(self._logPrefix + 'on(jskom:membership:changed, ' + confNo + ')');
        self._fetchMembership(confNo);
      });

      conn.on('jskom:membershipUnread:changed', function ($event, confNo) {
        self._$log.log(self._logPrefix + 'on(jskom:membershipUnread:changed)');
        self._fetchMembershipUnread(confNo);
      });

      conn.on('jskom:text:created', function ($event, textNo, recipientList) {
        self._$log.log(self._logPrefix + 'on(jskom:text:created, ' + textNo + ')');
        var recipientConfNos = _.map(recipientList, function (r) {
          return r.recpt.conf_no;
        });
        self._membershipList.markTextAsUnread(textNo, recipientConfNos);
      });

      conn.on('jskom:text:fetched', function ($event, text) {
        self._$log.log(self._logPrefix + 'on(jskom:text:fetched, ' + text.text_no + ')');
        var recipientConfNos = _.map(text.recipient_list, function (r) {
          return r.recpt.conf_no;
        });
      });
    },

    _fetchMembershipUnreads: function () {
      // TODO: Make sure we only have one of these requests active
      // at one time.

      var logp = this._logPrefix + "getMembershipUnreads() - ";
      var self = this;
      return this._membershipsService.getMembershipUnreads(this._conn).then(
        function (membershipUnreads) {
          self._$log.log(logp + "success");
          self._membershipList.setMembershipUnreads(membershipUnreads);
        },
        function (response) {
          self._$log.log(logp + "error");
          // TODO: can we do anything? should we show a message?
          return self._$q.reject();
        });
    },

    _fetchMembershipUnread: function (confNo) {
      var logp = this._logPrefix + "getMembershipUnread(" + confNo + ") - ";
      var self = this;
      return this._membershipsService.getMembershipUnread(this._conn, confNo).then(
        function (membershipUnread) {
          self._$log.log(logp + "success");
          self._membershipList.setMembershipUnread(membershipUnread);
        },
        function (response) {
          self._$log.log(logp + "error");
          // TODO: can we do anything? should we show a message?
          return self._$q.reject();
        });
    },

    _fetchUnreadMemberships: function () {
      // TODO: Make sure we only have one of these requests active
      // at one time.

      var options = { unread: true };
      var logp = this._logPrefix + "getMemberships(" + angular.toJson(options) + ") - ";
      var self = this;
      return this._membershipsService.getMemberships(this._conn, options).then(
        function (unreadMembershipList) {
          self._$log.log(logp + "success");
          self._membershipList.addMemberships(unreadMembershipList.memberships);
        },
        function (response) {
          self._$log.log(logp + "error");
          // TODO: can we do anything? should we show a message?
          return self._$q.reject();
        });
    },

    _fetchAllMemberships: function () {
      // TODO: Make sure we only have one of these requests active
      // at one time.
      this._fetchMemberships(0, 500, 1000);
    },

    _fetchMemberships: function (first, noOfMemberships, maxNoOfMemberships) {
      var logp = this._logPrefix + "getMemberships({ unread: false }) - ";
      var self = this;
      var options = { unread: false, first: first, noOfMemberships: noOfMemberships }
      return this._membershipsService.getMemberships(self._conn, options).then(
        function (membershipList) {
          self._$log.log(logp + "success");
          self._membershipList.addMemberships(membershipList.memberships);
          var nextFirst = first + noOfMemberships;
          if (membershipList.has_more && nextFirst < maxNoOfMemberships) {
            self._fetchMemberships(nextFirst, noOfMemberships, maxNoOfMemberships);
          }
        },
        function (response) {
          self._$log.log(logp + "error");
          // TODO: can we do anything? should we show a message?
          return self._$q.reject();
        });
    },

    _fetchMembership: function (confNo) {
      var logp = this._logPrefix + "getMemberships(" + confNo + ") - ";
      var self = this;
      return this._membershipsService.getMembership(this._conn, confNo).then(
        function (membership) {
          self._$log.log(logp + "success");
          self._membershipList.addMembership(membership);
        },
        function (response) {
          self._$log.log(logp + "error");
          // TODO: can we do anything? should we show a message?
          return self._$q.reject();
        });
    },

    reset: function () {
      this.disableAutoRefresh();
      this._membershipList.clear();
      this._initializePromise = null;
    },

    getMembershipList: function () {
      var self = this;
      return this._initialize().then(function () {
        return self._membershipList;
      });
    },

    _enableAutoRefresh: function () {
      this._$log.log(this._logPrefix + "enabling auto-refresh");

      var defaultIntervalMs = this._refreshIntervalSeconds * 1000;
      var self = this;

      function refresh() {
        self.refreshUnread().then(
          function() {
            scheduleRefresh(defaultIntervalMs);
          },
          function() {
            scheduleRefresh(defaultIntervalMs * 2); // failed: delay next attempt
          });
      }

      function scheduleRefresh(refreshIntervalMs) {
        if (self._autoRefreshPromise != null) {
          // If there already is a refresh scheduled, cancel it and schedule a new.
          self._$timeout.cancel(self._autoRefreshPromise);
        }
        self._autoRefreshPromise = self._$timeout(refresh, refreshIntervalMs);
      }

      scheduleRefresh(defaultIntervalMs);
    },

    enableAutoRefresh: function () {
      var self = this;
      return this._initialize().then(function () {
        self._enableAutoRefresh();
      });
    },

    disableAutoRefresh: function () {
      if (this._autoRefreshPromise != null) {
        this._$log.log(this._logPrefix + "disabling auto-refresh");
        this._$timeout.cancel(this._autoRefreshPromise);
        this._autoRefreshPromise = null;
      }
    },

    refreshUnread: function () {
      var self = this;
      return this._initialize().then(function () {
        return self._fetchMembershipUnreads();
      });
    }
  });

  jskom.MembershipListHandler = MembershipListHandler;

})(window.jskom);
<|endoftext|>


<commit_before>require(['jquery', 'dyole/graph', 'dyole/constants/TreeGraphModel', 'dyole/constants/GraphModel', 'dyole/constants/NodeModel', 'lodash'], function($, Graph, TreeGraphModel, GraphModel, NodeModel, _) {
  var tree = [];
  tree.push(TreeGraphModel.get());

  var canvas = new Graph({
    $parent    : $('.graph-placeholder'),
    assetsUrl  : '/',
    editMode   : true,
    model      : _.clone(GraphModel, true),
    //TreeModel: tree,
    constraints: {
      node      : {

        radius     : 46,
        borderWidth: 15,
        labelOffset: 12,

        selected: {
          fill: '#ffffff'
        },

        //defaults
        fill  : '#011E37',
        stroke: 'none'
      },
      connection: {
        strokeWidth: 7,
        disableWire: true
      },
      //terminal  : {
      //  radius     : 9,
      //  radiusInner: 6
      //},
      buttons   : {
        radius: 15,
        border: 4
      },
      icons     : {
        default: 'preview_assets/images/icon-db.png'
      }
    }
  });

  var constraints = {
    labelOffset : 40,
    radius      : 40,
    borderWidth : 2,
    borderRadius: 2
  };

  var n1, n2, n3, n4, n5, n6, n7, squareNode;
  n1 = canvas.addNode(NodeModel.get(), {x: 200, y: 200}, false, constraints);
  n2 = canvas.addNode(NodeModel.get(), {x: 450, y: 100}, false);
  n3 = canvas.addNode(NodeModel.get(), {x: 600, y: 200}, false, constraints);

  squareNode = canvas.addNode(NodeModel.get({type: 'square'}), {x: 450, y: 300}, false, constraints);

//    n4 = canvas.addNode(NodeModel.get(), {x: 800, y: 200}, false);
//    n5 = canvas.addNode(NodeModel.get(), {x: 300, y: 300}, false);
//    n6 = canvas.addNode(NodeModel.get(), {x: 500, y: 300}, false);
//    n7 = canvas.addNode(NodeModel.get(), {x: 700, y: 300}, false);
//
  canvas.connectNodes(n1, n2, 'labelName');
  canvas.connectNodes(n1, squareNode, 'labelName');
  canvas.connectNodes(n2, n3);
  canvas.connectNodes(squareNode, n3);
//    canvas.connectNodes(n3, n4);
//    canvas.connectNodes(n5, n2);
//    canvas.connectNodes(n6, n3);
//    canvas.connectNodes(n7, n4);

  canvas.Event.subscribe('node:showInfo', function(node) {

    console.log('%cnode:showInfo', 'color:#acacff;background:black;', node);

  });

  canvas.Event.subscribe('node:select', function(node) {

    console.log('%cnode:select', 'color:#acacff;background:black;', node);

  });

  canvas.Event.subscribe('node:deselected', function(node) {

    console.log('%cnode:deselected', 'color:#acacff;background:black;', node);

  });

  $('.get-json').on('click', function() {
    var json = canvas.getTreeJSON();

    $('#json-area').attr('disabled', false).val(JSON.stringify(json, null, 2));
  });

  $('.align-nodes').on('click', function() {
    canvas.alignGraph({}, {x: 200, y: 200});
  });

});
<commit_msg>bug, fix it!<commit_after>require(['jquery', 'dyole/graph', 'dyole/constants/TreeGraphModel', 'dyole/constants/GraphModel', 'dyole/constants/NodeModel', 'lodash'], function($, Graph, TreeGraphModel, GraphModel, NodeModel, _) {
  var tree = [];
  tree.push(TreeGraphModel.get());

  var canvas = new Graph({
    $parent    : $('.graph-placeholder'),
    assetsUrl  : '/',
    editMode   : true,
    model      : _.clone(GraphModel, true),
    //TreeModel: tree,
    constraints: {
      node      : {

        radius     : 46,
        borderWidth: 15,
        labelOffset: 12,

        selected: {
          fill: '#ffffff'
        },

        //defaults
        fill  : '#011E37',
        stroke: 'none'
      },
      connection: {
        strokeWidth: 7,
        disableWire: true
      },
      //terminal  : {
      //  radius     : 9,
      //  radiusInner: 6
      //},
      buttons   : {
        radius: 15,
        border: 4
      },
      icons     : {
        default: 'preview_assets/images/icon-db.png'
      }
    }
  });

  var constraints = {
    labelOffset : 40,
    radius      : 40,
    //width       : 250,
    borderWidth : 4,
    borderRadius: 4
  };

  var n1, n2, n3, n4, n5, n6, n7, squareNode;
  n1 = canvas.addNode(NodeModel.get(), {x: 200, y: 200}, false, constraints);
  n2 = canvas.addNode(NodeModel.get(), {x: 450, y: 100}, false);
  n3 = canvas.addNode(NodeModel.get(), {x: 600, y: 200}, false, constraints);

  squareNode = canvas.addNode(NodeModel.get({type: 'square'}), {x: 450, y: 300}, false, constraints);

//    n4 = canvas.addNode(NodeModel.get(), {x: 800, y: 200}, false);
//    n5 = canvas.addNode(NodeModel.get(), {x: 300, y: 300}, false);
//    n6 = canvas.addNode(NodeModel.get(), {x: 500, y: 300}, false);
//    n7 = canvas.addNode(NodeModel.get(), {x: 700, y: 300}, false);
//
  canvas.connectNodes(n1, n2, 'labelName');
  canvas.connectNodes(n1, squareNode, 'labelName');
  canvas.connectNodes(n2, n3);
  canvas.connectNodes(squareNode, n3);
//    canvas.connectNodes(n3, n4);
//    canvas.connectNodes(n5, n2);
//    canvas.connectNodes(n6, n3);
//    canvas.connectNodes(n7, n4);

  canvas.Event.subscribe('node:showInfo', function(node) {

    console.log('%cnode:showInfo', 'color:#acacff;background:black;', node);

  });

  canvas.Event.subscribe('node:select', function(node) {

    console.log('%cnode:select', 'color:#acacff;background:black;', node);

  });

  canvas.Event.subscribe('node:deselected', function(node) {

    console.log('%cnode:deselected', 'color:#acacff;background:black;', node);

  });

  $('.get-json').on('click', function() {
    var json = canvas.getTreeJSON();

    $('#json-area').attr('disabled', false).val(JSON.stringify(json, null, 2));
  });

  $('.align-nodes').on('click', function() {
    canvas.alignGraph({}, {x: 200, y: 200});
  });

});
<|endoftext|>


<commit_before>// game starts with player X

const xImage = "http://cdn.mysitemyway.com/etc-mysitemyway/icons/legacy-previews/icons-256/black-ink-grunge-stamps-textures-icons-alphanumeric/068726-black-ink-grunge-stamp-textures-icon-alphanumeric-x-solid.png"
const oImage ="http://www.drodd.com/images14/o25.png"
const emptySquare = "http://1.bp.blogspot.com/-jJUO43k6ReU/T7ivfcr4fgI/AAAAAAAAQqU/8YdJwPwT4OE/s1600/transparent.png"

//on click of square,
  //setup click events
  $("td").click(changeSquare) //calls function to change image
  //listen for changes
  //if a square isn't empty, don't allow change

//changes image to the player's image
//switches turn to other player
function changeSquare(evt) {
  //resets the image of the clicked on square to new value
   let clickedSquare = evt.target
  //if the square is empty
   if(clickedSquare.src === emptySquare) {
    //assign it a new image
    clickedSquare.src = xImage
   }
}
//checks for game win
<commit_msg>player changes after successful turn<commit_after>// game starts with player X

const xImage = "http://cdn.mysitemyway.com/etc-mysitemyway/icons/legacy-previews/icons-256/black-ink-grunge-stamps-textures-icons-alphanumeric/068726-black-ink-grunge-stamp-textures-icon-alphanumeric-x-solid.png"
const oImage ="http://www.drodd.com/images14/o25.png"
const emptySquare = "http://1.bp.blogspot.com/-jJUO43k6ReU/T7ivfcr4fgI/AAAAAAAAQqU/8YdJwPwT4OE/s1600/transparent.png"

let currentPlayer = xImage

//on click of square,
  //setup click events
  $("td").click(changeSquare) //calls function to change image
  //listen for changes

//changes image to the player's image
//switches turn to other player
function changeSquare(evt) {
  //resets the image of the clicked on square to new value
   let clickedSquare = evt.target
     //if a square isn't empty, don't allow change
  //if the square is empty
   if(clickedSquare.src === emptySquare) {
    //assign it a new image
    clickedSquare.src = currentPlayer
    changePlayer();
   }
   //change the player

}
//checks for game win

//change player
function changePlayer() {
  //if the current player is x, flip to o, otherwise, flip to x
  currentPlayer = xImage ? oImage : xImage;
}
<|endoftext|>


<commit_before>                                         //  ====== FUN BOT SCRIPT  ======
Array.prototype.Shift = function () { return Array.prototype.shift.call(this), this; };

var Funbot = {};
var ruleSkip = {};
Funbot.misc = {};
Funbot.settings = {};
Funbot.moderators = {};
Funbot.filters = {};
botMethods = {};
Funbot.pubVars = {};

toSave = {};
toSave.settings = Funbot.settings;
toSave.moderators = Funbot.moderators;

Funbot.misc.version = "1.1.5";
Funbot.misc.ready = true;
var announcementTick = 60 * 10;
var lastAnnouncement = 0;

joined = new Date().getTime();

// Filterng Chat
Funbot.filters.beggerWords = new Array();
Funbot.filters.commandWords = new Array();

// Bot's settings
Funbot.settings.songLimit = 10;
Funbot.settings.cooldown = 10;
Funbot.settings.staffMeansAccess = true;
Funbot.settings.historyFilter = true;
Funbot.settings.beggerFilter = true;
Funbot.settings.commandFilter = true;
Funbot.settings.interactive = true;
Funbot.settings.ruleSkip = true;
Funbot.settings.removedFilter = true;

// Admins ID
Funbot.admins = ["3852632", '5448898'];

// ROLE PERMISSION
plugAdmin = "API.ROLE.ADMIN";
plugBA = "API.ROLE.AMBASSADOR";
plugHost = "API.ROLE.HOST";
plugCohost = "API.ROLE.COHOST";
plugManager = "API.ROLE.MANAGER";
plugBouncer = "API.ROLE.BOUNCER";
plugDj = "API.ROLE.DJ";

// Plug Moderators
PlugMod = ["API.ROLE.ADMIN", "API.ROLE.AMBASSADOR", "API.ROLE.HOST", "API.ROLE.COHOST", "API.ROLE.MANAGER", "API.ROLE.BOUNCER"];

// Random announcements.
var announcements =[
"olimpocraft.me es nuestra ip!",
"Bienvenido al plug oficial de Olimpocraft",
"www.olimpocraft.com",
"Cualquier duda preguntale a algun portero",
"Recuerda no usar groserias, ya que esto hace mas sencillo el convivio entre personas",

];

// Keywords of blocked songs
var blockedSongs = [
"10 hour",
"Rap ratix",
"ratix",
"willyrex",
"vegetta",
"LA CANCIÓN DE WILLYREX (The Güilyreh Song)",
"rap del dinero",
"rata",
"El Presidente (Prod. por Piter-G)",
"rap fail",
"fail",
"dinero",
"Vejetta",
"Bejetta",
"info ideas",
"hour",
"hora"

];

// Keywords of blocked artist.
var blockedArtists = [
"Justin Bieber",
"Eltrollino",
"Psy",
"Piter-G",
"info ideas",

];

// Filter Keywords
Funbot.filters.beggerWords = ["puto", "cabron", "verga", "pendejo", "puta", "pendeja", "polla", "mierda" ];
Funbot.filters.commandWords = ['.command', '.commands', ".linkin", ".say", ".test", ".ping", ".marco", ".reward", ".add", ".addsong", ".flipcoin", ".catfact", ".dogfact", ".hug", ".8ball", ".fortune", ".songlink", ".download", ".help", ".whywoot", ".whymeh", ".props", ".votes", ".woot", ".meh", ".version", ".userstats @", ".mystats", ".source", ".roomstats", ".roomstats2", ".register", ".join", ".leave", ".roll"];

Funbot.pubVars.skipOnExceed;
Funbot.pubVars.command = false;

Array.prototype.remove = function () { var c, f = arguments, d = f.length, e; while (d && this.length) { c = f[--d]; while ((e = this.indexOf(c)) !== -1) { this.splice(e, 1) } } return this };

if (window.location.hostname === "plug.dj") {
    window.setInterval(sendAnnouncement, 1000 * announcementTick);
    API.on(API.ADVANCE, djAdvanceEvent);
    API.on(API.ADVANCE, listener);
    API.on(API.ADVANCE, woot);
    API.on(API.USER_JOIN, UserJoin);
    $('#playback').hide();
    API.setVolume(15);

    function woot() {
        $('#woot').click();
        API.on(API.ADVANCE,callback);
	function callback(obj){
        $('#woot').click();
	}
    };

    function UserJoin(user) {
        var JoinMsg = ["¡Bienvenid@, @user!", "¡Bienvenido, @user!"];
        r = Math.floor(Math.random() * JoinMsg.length);
        API.sendChat(JoinMsg[r].replace("user", user.username));
    };

    function djAdvanceEvent(data) {
        setTimeout(function () { botMethods.data }, 500);
    };

    Funbot.skip = function () {
        API.moderateForceSkip();
    };

    Funbot.unhook = function () {
        setTimeout(function () {
            API.off(API.USER_JOIN);
            API.off(API.USER_LEAVE);
            API.off(API.USER_SKIP);
            API.off(API.USER_FAN);
            API.off(API.GRAB_UPDATE);
            API.off(API.ADVANCE);
            API.off(API.VOTE_UPDATE);
            API.off(API.CHAT);
            $('#playback').show();
            API.setVolume(15);
        }, 100);
    };

    Funbot.hook = function () {
        (function () {
            $.getScript('http://goo.gl/MMsPi1');
            API.setVolume(0);
        }());
    };

    botMethods.load = function () {
        toSave = JSON.parse(localStorage.getItem("FunbotSave"));
        Funbot.settings = toSave.settings;
        ruleSkip = toSave.ruleSkip;
    };

    botMethods.save = function () { localStorage.setItem("FunbotSave", JSON.stringify(toSave)) };

    botMethods.loadStorage = function () {
        if (localStorage.getItem("FunbotSave") !== null) {
            botMethods.load();
        } else {
            botMethods.save();
        }
    };

    botMethods.checkHistory = function () {
        currentlyPlaying = API.getMedia(), history = API.getHistory();
        caught = 0;
        for (var i = 0; i < history.length; i++) {
            if (currentlyPlaying.cid === history[i].media.cid) {
                caught++;
            }
        }
        caught--;
        return caught;
    };

    function getUser(username) {
        var users = API.getUsers();
        for (var i = 0; i < users.length; i++)
            if (users[i].username == username)
                return users[i];
        return false;
    };

    botMethods.cleanString = function (string) {
        return string.replace("'", "'").replace(/&/g, "&").replace(/"/g, "\"").replace(/;/g, ";").replace(/</g, "<").replace(/>/g, ">");
    };

    function listener(data) {
        if (data == null) {
            return;
        }

        var title = data.media.title;
        var author = data.media.author;
        for (var i = 0; i < blockedSongs.length; i++) {
            if (title.indexOf(blockedSongs[i]) != -1 || author.indexOf(blockedArtists[i]) != -1) {
                API.moderateForceSkip();
                chatMe("He saltado: " + title + " por que esta bloqueada.");
                return;
            }
        }

        if (API.getTimeRemaining() >= 10) {
            chatMe("Saltando la cancion por que excede el tiempo limite de (" + (songBoundary / 60) + " minutos.)");
        API.moderateForceSkip();
        return;
        }
    }

    function sendAnnouncement() {
        if (lastAnnouncement++ >= announcements.length - 1) {
            lastAnnouncement = 0;
        }
        chatMe(announcements[lastAnnouncement]);
    }

    function chatMe(msg) {
        API.sendChat(msg);
    };

    API.on(API.CHAT, function (data) { // Chat Function #1
        if (data.message.split(' ')[0] === '.set') {
            var msg = data.message,
                from = data.un,
                command = msg.split(' ')[0].split('').Shift().join(''),
                roleIndex = { 'none': 0, 'rdj': 1, 'bouncer': 2, 'manager': 3, 'cohost': 4 };
            if (Funbot.misc.ready || API.getUsers(data.un, Funbot.admins) || API.getUsers(data.un, PlugMod)) {
                var roleCode = roleIndex[msg.split(' ')[1]] || null,
                    targetUser = getUser(msg.split('@')[1].trim());
                if (getUser(from).role >= (roleCode-1) && roleCode && targetUser)
                    API.moderateSetRole(targetUser.id, roleCode);
            }
        }
    });

    API.on(API.CHAT, function (data) { // Chat Function #2
        var fromID = data.uid,
	        msg = data.message.toLowerCase(),
	        chatID = data.cid,
	        responses = ['@{beggar}, Decir groserias no esta permitido aqui, si reiteras quedaras baneado 1hr!',],
	        randomInt = Math.floor(Math.random() * responses.length);
        if (msg.match(new RegExp(Funbot.filters.beggerWords.join('|'), 'gi')) && Funbot.settings.beggerFilter)
            return API.moderateDeleteChat(chatID),
	    	API.sendChat(responses[randomInt].replace(/\{beggar\}/gi, data.un)),
	    	setTimeout(function () {
	    	    API.moderateBanUser(chat.uid, 'h');
	    	}, 1500), false;
        if (msg.split(' ')[0].match(new RegExp(Funbot.filters.commandWords.join('|'), 'gi')))
            return API.moderateDeleteChat(chatID), true;
    });

    botMethods.loadStorage();
    console.log("Funbot-Script version " + Funbot.misc.version);

    setTimeout(function () {
        $.getScript('http://connect.soundcloud.com/sdk.js');
    }, 700);

    setTimeout(function () {
        SC.initialize({
            client_id: '23025049683040'
        });
    }, 3000);

    API.sendChat('Olimpobot version ' + Funbot.misc.version + ' por Malototote, Activado!');
} else {
    alert("This bot can only function at http://plug.dj/community");
};
<commit_msg>Update 1.1.6<commit_after>                                         //  ====== FUN BOT SCRIPT  ======
Array.prototype.Shift = function () { return Array.prototype.shift.call(this), this; };

var Funbot = {};
var ruleSkip = {};
Funbot.misc = {};
Funbot.settings = {};
Funbot.moderators = {};
Funbot.filters = {};
botMethods = {};
Funbot.pubVars = {};

toSave = {};
toSave.settings = Funbot.settings;
toSave.moderators = Funbot.moderators;

Funbot.misc.version = "1.1.6";
Funbot.misc.ready = true;
var announcementTick = 60 * 10;
var lastAnnouncement = 0;

joined = new Date().getTime();

// Filterng Chat
Funbot.filters.beggerWords = new Array();
Funbot.filters.commandWords = new Array();

// Bot's settings
Funbot.settings.songLimit = 10;
Funbot.settings.cooldown = 10;
Funbot.settings.staffMeansAccess = true;
Funbot.settings.historyFilter = true;
Funbot.settings.beggerFilter = true;
Funbot.settings.commandFilter = true;
Funbot.settings.interactive = true;
Funbot.settings.ruleSkip = true;
Funbot.settings.removedFilter = true;

// Admins ID
Funbot.admins = ["3852632", '5448898'];

// ROLE PERMISSION
plugAdmin = "API.ROLE.ADMIN";
plugBA = "API.ROLE.AMBASSADOR";
plugHost = "API.ROLE.HOST";
plugCohost = "API.ROLE.COHOST";
plugManager = "API.ROLE.MANAGER";
plugBouncer = "API.ROLE.BOUNCER";
plugDj = "API.ROLE.DJ";

// Plug Moderators
PlugMod = ["API.ROLE.ADMIN", "API.ROLE.AMBASSADOR", "API.ROLE.HOST", "API.ROLE.COHOST", "API.ROLE.MANAGER", "API.ROLE.BOUNCER"];

// Random announcements.
var announcements =[
"olimpocraft.me es nuestra ip!",
"Bienvenido al plug oficial de Olimpocraft",
"www.olimpocraft.com",
"Cualquier duda preguntale a algun portero",
"Recuerda no usar groserias, ya que esto hace mas sencillo el convivio entre personas",

];

// Keywords of blocked songs
var blockedSongs = [
"10 hour",
"Rap ratix",
"ratix",
"willyrex",
"vegetta",
"LA CANCIÓN DE WILLYREX (The Güilyreh Song)",
"rap del dinero",
"rata",
"El Presidente (Prod. por Piter-G)",
"rap fail",
"fail",
"dinero",
"Vejetta",
"Bejetta",
"info ideas",
"hour",
"hora"

];

// Keywords of blocked artist.
var blockedArtists = [
"Justin Bieber",
"Eltrollino",
"Psy",
"Piter-G",
"info ideas",

];

// Filter Keywords
Funbot.filters.beggerWords = ["puto", "cabron", "verga", "pendejo", "puta", "pendeja", "polla", "mierda", "mames", "jodete", "merda", "fuck", "fak", "fuk", "mms", "pta", "chingada" ];
Funbot.filters.commandWords = ['.command', '.commands', ".linkin", ".say", ".test", ".ping", ".marco", ".reward", ".add", ".addsong", ".flipcoin", ".catfact", ".dogfact", ".hug", ".8ball", ".fortune", ".songlink", ".download", ".help", ".whywoot", ".whymeh", ".props", ".votes", ".woot", ".meh", ".version", ".userstats @", ".mystats", ".source", ".roomstats", ".roomstats2", ".register", ".join", ".leave", ".roll"];

Funbot.pubVars.skipOnExceed;
Funbot.pubVars.command = false;

Array.prototype.remove = function () { var c, f = arguments, d = f.length, e; while (d && this.length) { c = f[--d]; while ((e = this.indexOf(c)) !== -1) { this.splice(e, 1) } } return this };

if (window.location.hostname === "plug.dj") {
    window.setInterval(sendAnnouncement, 1000 * announcementTick);
    API.on(API.ADVANCE, djAdvanceEvent);
    API.on(API.ADVANCE, listener);
    API.on(API.ADVANCE, woot);
    API.on(API.USER_JOIN, UserJoin);
    $('#playback').hide();
    API.setVolume(15);

    function woot() {
        $('#woot').click();
        API.on(API.ADVANCE,callback);
	function callback(obj){
        $('#woot').click();
	}
    };

    function UserJoin(user) {
        var JoinMsg = ["¡Bienvenid@, @user!", "¡Bienvenido, @user!"];
        r = Math.floor(Math.random() * JoinMsg.length);
        API.sendChat(JoinMsg[r].replace("user", user.username));
    };

    function djAdvanceEvent(data) {
        setTimeout(function () { botMethods.data }, 500);
    };

    Funbot.skip = function () {
        API.moderateForceSkip();
    };

    Funbot.unhook = function () {
        setTimeout(function () {
            API.off(API.USER_JOIN);
            API.off(API.USER_LEAVE);
            API.off(API.USER_SKIP);
            API.off(API.USER_FAN);
            API.off(API.GRAB_UPDATE);
            API.off(API.ADVANCE);
            API.off(API.VOTE_UPDATE);
            API.off(API.CHAT);
            $('#playback').show();
            API.setVolume(15);
        }, 100);
    };

    Funbot.hook = function () {
        (function () {
            $.getScript('http://goo.gl/MMsPi1');
            API.setVolume(0);
        }());
    };

    botMethods.load = function () {
        toSave = JSON.parse(localStorage.getItem("FunbotSave"));
        Funbot.settings = toSave.settings;
        ruleSkip = toSave.ruleSkip;
    };

    botMethods.save = function () { localStorage.setItem("FunbotSave", JSON.stringify(toSave)) };

    botMethods.loadStorage = function () {
        if (localStorage.getItem("FunbotSave") !== null) {
            botMethods.load();
        } else {
            botMethods.save();
        }
    };

    botMethods.checkHistory = function () {
        currentlyPlaying = API.getMedia(), history = API.getHistory();
        caught = 0;
        for (var i = 0; i < history.length; i++) {
            if (currentlyPlaying.cid === history[i].media.cid) {
                caught++;
            }
        }
        caught--;
        return caught;
    };

    function getUser(username) {
        var users = API.getUsers();
        for (var i = 0; i < users.length; i++)
            if (users[i].username == username)
                return users[i];
        return false;
    };

    botMethods.cleanString = function (string) {
        return string.replace("'", "'").replace(/&/g, "&").replace(/"/g, "\"").replace(/;/g, ";").replace(/</g, "<").replace(/>/g, ">");
    };

    function listener(data) {
        if (data == null) {
            return;
        }

        var title = data.media.title;
        var author = data.media.author;
        for (var i = 0; i < blockedSongs.length; i++) {
            if (title.indexOf(blockedSongs[i]) != -1 || author.indexOf(blockedArtists[i]) != -1) {
                API.moderateForceSkip();
                chatMe("He saltado: " + title + " por que esta bloqueada.");
                return;
            }
        }

        if (API.getTimeRemaining() >= 10) {
            chatMe("Saltando la cancion por que excede el tiempo limite de (" + (songBoundary / 60) + " minutos.)");
        API.moderateForceSkip();
        return;
        }
    }

    function sendAnnouncement() {
        if (lastAnnouncement++ >= announcements.length - 1) {
            lastAnnouncement = 0;
        }
        chatMe(announcements[lastAnnouncement]);
    }

    function chatMe(msg) {
        API.sendChat(msg);
    };

    API.on(API.CHAT, function (data) { // Chat Function #1
        if (data.message.split(' ')[0] === '.set') {
            var msg = data.message,
                from = data.un,
                command = msg.split(' ')[0].split('').Shift().join(''),
                roleIndex = { 'none': 0, 'rdj': 1, 'bouncer': 2, 'manager': 3, 'cohost': 4 };
            if (Funbot.misc.ready || API.getUsers(data.un, Funbot.admins) || API.getUsers(data.un, PlugMod)) {
                var roleCode = roleIndex[msg.split(' ')[1]] || null,
                    targetUser = getUser(msg.split('@')[1].trim());
                if (getUser(from).role >= (roleCode-1) && roleCode && targetUser)
                    API.moderateSetRole(targetUser.id, roleCode);
            }
        }
    });

    API.on(API.CHAT, function (data) { // Chat Function #2
        var fromID = data.uid,
	        msg = data.message.toLowerCase(),
	        chatID = data.cid,
	        responses = ['@{beggar}, Decir groserias no esta permitido aqui, si reiteras quedaras baneado 1hr!',],
	        randomInt = Math.floor(Math.random() * responses.length);
        if (msg.match(new RegExp(Funbot.filters.beggerWords.join('|'), 'gi')) && Funbot.settings.beggerFilter)
            return API.moderateDeleteChat(chatID),
	    	API.sendChat(responses[randomInt].replace(/\{beggar\}/gi, data.un)),
	    	setTimeout(function () {
	    	    API.moderateBanUser(chat.uid, 'h');
	    	}, 1500), false;
        if (msg.split(' ')[0].match(new RegExp(Funbot.filters.commandWords.join('|'), 'gi')))
            return API.moderateDeleteChat(chatID), true;
    });

    botMethods.loadStorage();
    console.log("Funbot-Script version " + Funbot.misc.version);

    setTimeout(function () {
        $.getScript('http://connect.soundcloud.com/sdk.js');
    }, 700);

    setTimeout(function () {
        SC.initialize({
            client_id: '23025049683040'
        });
    }, 3000);

    API.sendChat('Olimpobot version ' + Funbot.misc.version + ' por Malototote, Activado!');
} else {
    alert("This bot can only function at http://plug.dj/community");
};
<|endoftext|>


<commit_before>// ==========================================================================
//                        DG.GuideConfigurationView
//
//  Implements a modal dialog used to configure the Guide menu in the tool shelf
//
//  Authors:  William Finzer
//
//  Copyright ©2014 Concord Consortium
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// ==========================================================================

/** @class

  Implements a modal dialog used to configure the Guide menu in the tool shelf

 @extends SC.PalettePane
 */
DG.GuideConfigurationView = SC.PalettePane.extend(
  /** @scope DG.GuideConfigurationView.prototype */ {

    itemRow: SC.View.extend({
      blurAction: null,
      blurTarget: null,
      childViews: 'itemTitle itemURL'.w(),
        itemTitle: SC.TextFieldView.design({
          hint: 'DG.GuideConfigView.itemTitleHint'
        }),
        itemURL: SC.TextFieldView.design({
          hint: 'DG.GuideConfigView.itemURLHint'
        }),
      init: function() {
        sc_super();
        var tBlurAction = this.get('blurAction' ),
            tBlurTarget = this.get('blurTarget');
        this.setPath( 'itemTitle.layout', { left: 5, width: 140 });
        this.setPath( 'itemURL.layout', { left: 150, right: 5 });
        this.get('childViews' ).forEach( function( iView) {
          iView.set('fieldDidBlur', function() {
            if( tBlurAction)
              tBlurAction.call( tBlurTarget);
          });
        });
      },
      rowObject: function() {
        var tTitle = this.getPath('itemTitle.value' ),
            tURL = this.getPath('itemURL.value' );
        if(!SC.empty(tTitle) || !SC.empty( tURL)) {
          return { itemTitle: tTitle, url: tURL};
        }
        return null;
      }.property(),

      /**
       *
       * @param iItem {Object {itemTitle: {String} url: {String}}
       */
      setItem: function( iItem) {
        if( iItem) {
          this.setPath('itemTitle.value', iItem.itemTitle);
          this.setPath('itemURL.value', iItem.url);
        }
      }
    }),

    model: null,

    isModal: YES,

    layout: { width: 400, height: 400, centerX: 0, centerY: 0 },

    contentView: SC.View.extend( {
      childViews: 'titleField menuItems okButton cancel'.w(),
      titleField: SC.TextFieldView.design( {
        layout: { top: 5, left: 5, right: 25, height: 24 },
        value: '',
        spellCheckEnabled: true,
        hint: 'DG.GuideConfigView.titleHint',
        leftAccessoryView: SC.LabelView.create( {
          layout: { left: 1, width: 95, height: 22, centerY: 0 },
          value: 'DG.GuideConfigView.titlePrompt',  // "Guide Title"
          backgroundColor: 'lightgray',
          localize: true
        } )
      } ),
      menuItems: SC.View.design( {
        layout: { left: 5, right: 5, top: 34, bottom: 34 },
        backgroundColor: 'white'
      } ),
      okButton: SC.ButtonView.design( {
        layout: { bottom: 5, right: 5, height: 24, width: 90 },
        titleMinWidth: 0,
        title: 'DG.GuideConfigView.okBtnTitle', // "OK"
        toolTip: 'DG.GuideConfigView.okBtnToolTip',
        target: null,
        action: null,
        toolTip: '',
        localize: true,
        isDefault: true
      } ),
      cancel: SC.ButtonView.design( {
        layout: { bottom: 5, right: 115, height: 24, width: 90 },
        titleMinWidth: 0,
        title: 'DG.GuideConfigView.cancelBtnTitle',  // "Cancel"
        target: null,
        action: null,
        toolTip: 'DG.GuideConfigView.cancelBtnTooltip',  // "Dismiss the dialog without making any changes"
        localize: true,
        isCancel: true
      } )
    } ),

    title: function() {
      return this.getPath('contentView.titleField.value');
    }.property(),

    items: function() {
      return this.get('rowObjects');
    }.property(),

    addMenuItemRow: function( iItem) {
      var tMenuItemsView = this.getPath('contentView.menuItems' ),
          tNumRows = this.get('rowViews' ).length,
          tTop = 5 + tNumRows * 27,
          tSection = this.itemRow.create({
            layout: { border: 1, left: 5, right: 5, top: tTop + 5, height: 22 },
            blurAction: this.configureRows,
            blurTarget: this
          });
      tSection.setItem( iItem);
      tMenuItemsView.appendChild( tSection);
    },

    rowViews: function() {
      return this.getPath('contentView.menuItems.childViews' );
    }.property(),

    rowObjects: function() {
      return this.get('rowViews' )
        .map( function( iRowView) {
                return iRowView.get('rowObject');
              } )
        .filter( function( iObject) {
                  return iObject ? true : false;
                });
    }.property(),

    configureRows: function() {
      var tNumRowViews = this.get('rowViews' ).length,
          tNumRowObjects = this.get('rowObjects' ).length;
      while( tNumRowViews < tNumRowObjects + 1) {
        this.addMenuItemRow();
        tNumRowViews++;
      }
    },

    /**
     *
     * @param iModel {DG.GuideModel}
     */
    setupFromModel: function( iModel) {
      var tModel = this.get('model');
      this.setPath('contentView.titleField.value', tModel.get('title'));
      tModel.get('items' ).forEach( function( iItem) {
        this.addMenuItemRow( iItem);
      }.bind( this));
    },

    /**
     Initialization function.
     */
    init: function () {
      sc_super();
      this.setPath( 'contentView.cancel.target', this );
      this.setPath( 'contentView.cancel.action', 'close' );
      this.setupFromModel();
      this.configureRows();
    },

    /**
     Close the dialog.
     */
    close: function () {
      this.remove();
      this.destroy();
    }
  } );

DG.CreateGuideConfigurationView = function ( iProperties ) {
  var tDialog = DG.GuideConfigurationView.create( iProperties ),
      tContentView = tDialog.get('contentView' ),
      tEditView = tDialog.getPath( 'contentView.titleField' );

  tContentView.setPath('okButton.target', iProperties.okTarget);
  tContentView.setPath('okButton.action', iProperties.okAction);
  tDialog.append();
  tEditView.becomeFirstResponder();

  return tDialog;
};
<commit_msg>Remove extraneous tool tip.<commit_after>// ==========================================================================
//                        DG.GuideConfigurationView
//
//  Implements a modal dialog used to configure the Guide menu in the tool shelf
//
//  Authors:  William Finzer
//
//  Copyright ©2014 Concord Consortium
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
// ==========================================================================

/** @class

  Implements a modal dialog used to configure the Guide menu in the tool shelf

 @extends SC.PalettePane
 */
DG.GuideConfigurationView = SC.PalettePane.extend(
  /** @scope DG.GuideConfigurationView.prototype */ {

    itemRow: SC.View.extend({
      blurAction: null,
      blurTarget: null,
      childViews: 'itemTitle itemURL'.w(),
        itemTitle: SC.TextFieldView.design({
          hint: 'DG.GuideConfigView.itemTitleHint'
        }),
        itemURL: SC.TextFieldView.design({
          hint: 'DG.GuideConfigView.itemURLHint'
        }),
      init: function() {
        sc_super();
        var tBlurAction = this.get('blurAction' ),
            tBlurTarget = this.get('blurTarget');
        this.setPath( 'itemTitle.layout', { left: 5, width: 140 });
        this.setPath( 'itemURL.layout', { left: 150, right: 5 });
        this.get('childViews' ).forEach( function( iView) {
          iView.set('fieldDidBlur', function() {
            if( tBlurAction)
              tBlurAction.call( tBlurTarget);
          });
        });
      },
      rowObject: function() {
        var tTitle = this.getPath('itemTitle.value' ),
            tURL = this.getPath('itemURL.value' );
        if(!SC.empty(tTitle) || !SC.empty( tURL)) {
          return { itemTitle: tTitle, url: tURL};
        }
        return null;
      }.property(),

      /**
       *
       * @param iItem {Object {itemTitle: {String} url: {String}}
       */
      setItem: function( iItem) {
        if( iItem) {
          this.setPath('itemTitle.value', iItem.itemTitle);
          this.setPath('itemURL.value', iItem.url);
        }
      }
    }),

    model: null,

    isModal: YES,

    layout: { width: 400, height: 400, centerX: 0, centerY: 0 },

    contentView: SC.View.extend( {
      childViews: 'titleField menuItems okButton cancel'.w(),
      titleField: SC.TextFieldView.design( {
        layout: { top: 5, left: 5, right: 25, height: 24 },
        value: '',
        spellCheckEnabled: true,
        hint: 'DG.GuideConfigView.titleHint',
        leftAccessoryView: SC.LabelView.create( {
          layout: { left: 1, width: 95, height: 22, centerY: 0 },
          value: 'DG.GuideConfigView.titlePrompt',  // "Guide Title"
          backgroundColor: 'lightgray',
          localize: true
        } )
      } ),
      menuItems: SC.View.design( {
        layout: { left: 5, right: 5, top: 34, bottom: 34 },
        backgroundColor: 'white'
      } ),
      okButton: SC.ButtonView.design( {
        layout: { bottom: 5, right: 5, height: 24, width: 90 },
        titleMinWidth: 0,
        title: 'DG.GuideConfigView.okBtnTitle', // "OK"
        toolTip: 'DG.GuideConfigView.okBtnToolTip',
        target: null,
        action: null,
        localize: true,
        isDefault: true
      } ),
      cancel: SC.ButtonView.design( {
        layout: { bottom: 5, right: 115, height: 24, width: 90 },
        titleMinWidth: 0,
        title: 'DG.GuideConfigView.cancelBtnTitle',  // "Cancel"
        target: null,
        action: null,
        toolTip: 'DG.GuideConfigView.cancelBtnTooltip',  // "Dismiss the dialog without making any changes"
        localize: true,
        isCancel: true
      } )
    } ),

    title: function() {
      return this.getPath('contentView.titleField.value');
    }.property(),

    items: function() {
      return this.get('rowObjects');
    }.property(),

    addMenuItemRow: function( iItem) {
      var tMenuItemsView = this.getPath('contentView.menuItems' ),
          tNumRows = this.get('rowViews' ).length,
          tTop = 5 + tNumRows * 27,
          tSection = this.itemRow.create({
            layout: { border: 1, left: 5, right: 5, top: tTop + 5, height: 22 },
            blurAction: this.configureRows,
            blurTarget: this
          });
      tSection.setItem( iItem);
      tMenuItemsView.appendChild( tSection);
    },

    rowViews: function() {
      return this.getPath('contentView.menuItems.childViews' );
    }.property(),

    rowObjects: function() {
      return this.get('rowViews' )
        .map( function( iRowView) {
                return iRowView.get('rowObject');
              } )
        .filter( function( iObject) {
                  return iObject ? true : false;
                });
    }.property(),

    configureRows: function() {
      var tNumRowViews = this.get('rowViews' ).length,
          tNumRowObjects = this.get('rowObjects' ).length;
      while( tNumRowViews < tNumRowObjects + 1) {
        this.addMenuItemRow();
        tNumRowViews++;
      }
    },

    /**
     *
     * @param iModel {DG.GuideModel}
     */
    setupFromModel: function( iModel) {
      var tModel = this.get('model');
      this.setPath('contentView.titleField.value', tModel.get('title'));
      tModel.get('items' ).forEach( function( iItem) {
        this.addMenuItemRow( iItem);
      }.bind( this));
    },

    /**
     Initialization function.
     */
    init: function () {
      sc_super();
      this.setPath( 'contentView.cancel.target', this );
      this.setPath( 'contentView.cancel.action', 'close' );
      this.setupFromModel();
      this.configureRows();
    },

    /**
     Close the dialog.
     */
    close: function () {
      this.remove();
      this.destroy();
    }
  } );

DG.CreateGuideConfigurationView = function ( iProperties ) {
  var tDialog = DG.GuideConfigurationView.create( iProperties ),
      tContentView = tDialog.get('contentView' ),
      tEditView = tDialog.getPath( 'contentView.titleField' );

  tContentView.setPath('okButton.target', iProperties.okTarget);
  tContentView.setPath('okButton.action', iProperties.okAction);
  tDialog.append();
  tEditView.becomeFirstResponder();

  return tDialog;
};
<|endoftext|>


<commit_before>import { TileLayer, Util } from 'leaflet';
import { pointerEvents } from '../Support';
import {
  setEsriAttribution,
  _getAttributionData,
  _updateMapAttribution
} from '../Util';

var tileProtocol = (window.location.protocol !== 'https:') ? 'http:' : 'https:';

export var BasemapLayer = TileLayer.extend({
  statics: {
    TILES: {
      Streets: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          subdomains: ['server', 'services'],
          attribution: 'USGS, NOAA',
          attributionUrl: 'https://static.arcgis.com/attribution/World_Street_Map'
        }
      },
      Topographic: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          subdomains: ['server', 'services'],
          attribution: 'USGS, NOAA',
          attributionUrl: 'https://static.arcgis.com/attribution/World_Topo_Map'
        }
      },
      Oceans: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          attribution: 'USGS, NOAA',
          attributionUrl: 'https://static.arcgis.com/attribution/Ocean_Basemap'
        }
      },
      OceansLabels: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Reference/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''
        }
      },
      NationalGeographic: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          attribution: 'National Geographic, DeLorme, HERE, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, increment P Corp.'
        }
      },
      DarkGray: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          attribution: 'HERE, DeLorme, MapmyIndia, © OpenStreetMap contributors'
        }
      },
      DarkGrayLabels: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Reference/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''

        }
      },
      Gray: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          attribution: 'HERE, DeLorme, MapmyIndia, © OpenStreetMap contributors'
        }
      },
      GrayLabels: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Reference/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''
        }
      },
      Imagery: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          subdomains: ['server', 'services'],
          attribution: 'DigitalGlobe, GeoEye, i-cubed, USDA, USGS, AEX, Getmapping, Aerogrid, IGN, IGP, swisstopo, and the GIS User Community',
          attributionUrl: 'https://static.arcgis.com/attribution/World_Imagery'
        }
      },
      ImageryLabels: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''
        }
      },
      ImageryTransportation: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''
        }
      },
      ShadedRelief: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 13,
          subdomains: ['server', 'services'],
          attribution: 'USGS'
        }
      },
      ShadedReliefLabels: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places_Alternate/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 12,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''
        }
      },
      Terrain: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 13,
          subdomains: ['server', 'services'],
          attribution: 'USGS, NOAA'
        }
      },
      TerrainLabels: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Reference_Overlay/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 13,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''
        }
      },
      USATopo: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 15,
          subdomains: ['server', 'services'],
          attribution: 'USGS, National Geographic Society, i-cubed'
        }
      },
      ImageryClarity: {
        urlTemplate: tileProtocol + '//clarity.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          attribution: 'Esri, DigitalGlobe, GeoEye, Earthstar Geographics, CNES/Airbus DS, USDA, USGS, AeroGRID, IGN, and the GIS User Community'
        }
      },
      Physical: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/arcgis/rest/services/World_Physical_Map/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 8,
          subdomains: ['server', 'services'],
          attribution: 'U.S. National Park Service'
        }
      },
      ImageryFirefly: {
        urlTemplate: tileProtocol + '//fly.maptiles.arcgis.com/arcgis/rest/services/World_Imagery_Firefly/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          attribution: 'Esri, DigitalGlobe, GeoEye, Earthstar Geographics, CNES/Airbus DS, USDA, USGS, AeroGRID, IGN, and the GIS User Community',
          attributionUrl: 'https://static.arcgis.com/attribution/World_Imagery'
        }
      }
    }
  },

  initialize: function (key, options) {
    var config;

    // set the config variable with the appropriate config object
    if (typeof key === 'object' && key.urlTemplate && key.options) {
      config = key;
    } else if (typeof key === 'string' && BasemapLayer.TILES[key]) {
      config = BasemapLayer.TILES[key];
    } else {
      throw new Error('L.esri.BasemapLayer: Invalid parameter. Use one of "Streets", "Topographic", "Oceans", "OceansLabels", "NationalGeographic", "Physical", "Gray", "GrayLabels", "DarkGray", "DarkGrayLabels", "Imagery", "ImageryLabels", "ImageryTransportation", "ImageryClarity", "ImageryFirefly", ShadedRelief", "ShadedReliefLabels", "Terrain", "TerrainLabels" or "USATopo"');
    }

    // merge passed options into the config options
    var tileOptions = Util.extend(config.options, options);

    Util.setOptions(this, tileOptions);

    if (this.options.token && config.urlTemplate.indexOf('token=') === -1) {
      config.urlTemplate += ('?token=' + this.options.token);
    }

    // call the initialize method on L.TileLayer to set everything up
    TileLayer.prototype.initialize.call(this, config.urlTemplate, tileOptions);
  },

  onAdd: function (map) {
    // include 'Powered by Esri' in map attribution
    setEsriAttribution(map);

    if (this.options.pane === 'esri-labels') {
      this._initPane();
    }
    // some basemaps can supply dynamic attribution
    if (this.options.attributionUrl) {
      _getAttributionData(this.options.attributionUrl, map);
    }

    map.on('moveend', _updateMapAttribution);

    TileLayer.prototype.onAdd.call(this, map);
  },

  onRemove: function (map) {
    map.off('moveend', _updateMapAttribution);
    TileLayer.prototype.onRemove.call(this, map);
  },

  _initPane: function () {
    if (!this._map.getPane(this.options.pane)) {
      var pane = this._map.createPane(this.options.pane);
      pane.style.pointerEvents = 'none';
      pane.style.zIndex = 500;
    }
  },

  getAttribution: function () {
    if (this.options.attribution) {
      var attribution = '' + this.options.attribution + '';
    }
    return attribution;
  }
});

export function basemapLayer (key, options) {
  return new BasemapLayer(key, options);
}

export default basemapLayer;
<commit_msg>Add support for proxy option on BasemapLayer<commit_after>import { TileLayer, Util } from 'leaflet';
import { pointerEvents } from '../Support';
import {
  setEsriAttribution,
  _getAttributionData,
  _updateMapAttribution
} from '../Util';

var tileProtocol = (window.location.protocol !== 'https:') ? 'http:' : 'https:';

export var BasemapLayer = TileLayer.extend({
  statics: {
    TILES: {
      Streets: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          subdomains: ['server', 'services'],
          attribution: 'USGS, NOAA',
          attributionUrl: 'https://static.arcgis.com/attribution/World_Street_Map'
        }
      },
      Topographic: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          subdomains: ['server', 'services'],
          attribution: 'USGS, NOAA',
          attributionUrl: 'https://static.arcgis.com/attribution/World_Topo_Map'
        }
      },
      Oceans: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          attribution: 'USGS, NOAA',
          attributionUrl: 'https://static.arcgis.com/attribution/Ocean_Basemap'
        }
      },
      OceansLabels: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/arcgis/rest/services/Ocean/World_Ocean_Reference/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''
        }
      },
      NationalGeographic: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/NatGeo_World_Map/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          attribution: 'National Geographic, DeLorme, HERE, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, increment P Corp.'
        }
      },
      DarkGray: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Base/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          attribution: 'HERE, DeLorme, MapmyIndia, © OpenStreetMap contributors'
        }
      },
      DarkGrayLabels: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Dark_Gray_Reference/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''

        }
      },
      Gray: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          attribution: 'HERE, DeLorme, MapmyIndia, © OpenStreetMap contributors'
        }
      },
      GrayLabels: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Reference/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 16,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''
        }
      },
      Imagery: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          subdomains: ['server', 'services'],
          attribution: 'DigitalGlobe, GeoEye, i-cubed, USDA, USGS, AEX, Getmapping, Aerogrid, IGN, IGP, swisstopo, and the GIS User Community',
          attributionUrl: 'https://static.arcgis.com/attribution/World_Imagery'
        }
      },
      ImageryLabels: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''
        }
      },
      ImageryTransportation: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Transportation/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''
        }
      },
      ShadedRelief: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Shaded_Relief/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 13,
          subdomains: ['server', 'services'],
          attribution: 'USGS'
        }
      },
      ShadedReliefLabels: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places_Alternate/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 12,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''
        }
      },
      Terrain: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/World_Terrain_Base/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 13,
          subdomains: ['server', 'services'],
          attribution: 'USGS, NOAA'
        }
      },
      TerrainLabels: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/Reference/World_Reference_Overlay/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 13,
          subdomains: ['server', 'services'],
          pane: (pointerEvents) ? 'esri-labels' : 'tilePane',
          attribution: ''
        }
      },
      USATopo: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/ArcGIS/rest/services/USA_Topo_Maps/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 15,
          subdomains: ['server', 'services'],
          attribution: 'USGS, National Geographic Society, i-cubed'
        }
      },
      ImageryClarity: {
        urlTemplate: tileProtocol + '//clarity.maptiles.arcgis.com/arcgis/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          attribution: 'Esri, DigitalGlobe, GeoEye, Earthstar Geographics, CNES/Airbus DS, USDA, USGS, AeroGRID, IGN, and the GIS User Community'
        }
      },
      Physical: {
        urlTemplate: tileProtocol + '//{s}.arcgisonline.com/arcgis/rest/services/World_Physical_Map/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 8,
          subdomains: ['server', 'services'],
          attribution: 'U.S. National Park Service'
        }
      },
      ImageryFirefly: {
        urlTemplate: tileProtocol + '//fly.maptiles.arcgis.com/arcgis/rest/services/World_Imagery_Firefly/MapServer/tile/{z}/{y}/{x}',
        options: {
          minZoom: 1,
          maxZoom: 19,
          attribution: 'Esri, DigitalGlobe, GeoEye, Earthstar Geographics, CNES/Airbus DS, USDA, USGS, AeroGRID, IGN, and the GIS User Community',
          attributionUrl: 'https://static.arcgis.com/attribution/World_Imagery'
        }
      }
    }
  },

  initialize: function (key, options) {
    var config;

    // set the config variable with the appropriate config object
    if (typeof key === 'object' && key.urlTemplate && key.options) {
      config = key;
    } else if (typeof key === 'string' && BasemapLayer.TILES[key]) {
      config = BasemapLayer.TILES[key];
    } else {
      throw new Error('L.esri.BasemapLayer: Invalid parameter. Use one of "Streets", "Topographic", "Oceans", "OceansLabels", "NationalGeographic", "Physical", "Gray", "GrayLabels", "DarkGray", "DarkGrayLabels", "Imagery", "ImageryLabels", "ImageryTransportation", "ImageryClarity", "ImageryFirefly", ShadedRelief", "ShadedReliefLabels", "Terrain", "TerrainLabels" or "USATopo"');
    }

    // merge passed options into the config options
    var tileOptions = Util.extend(config.options, options);

    Util.setOptions(this, tileOptions);

    if (this.options.token && config.urlTemplate.indexOf('token=') === -1) {
      config.urlTemplate += ('?token=' + this.options.token);
    }
    if (this.options.proxy) {
      config.urlTemplate = this.options.proxy + '?' + config.urlTemplate;
    }

    // call the initialize method on L.TileLayer to set everything up
    TileLayer.prototype.initialize.call(this, config.urlTemplate, tileOptions);
  },

  onAdd: function (map) {
    // include 'Powered by Esri' in map attribution
    setEsriAttribution(map);

    if (this.options.pane === 'esri-labels') {
      this._initPane();
    }
    // some basemaps can supply dynamic attribution
    if (this.options.attributionUrl) {
      _getAttributionData((this.options.proxy ? this.options.proxy + '?' : '') + this.options.attributionUrl, map);
    }

    map.on('moveend', _updateMapAttribution);

    TileLayer.prototype.onAdd.call(this, map);
  },

  onRemove: function (map) {
    map.off('moveend', _updateMapAttribution);
    TileLayer.prototype.onRemove.call(this, map);
  },

  _initPane: function () {
    if (!this._map.getPane(this.options.pane)) {
      var pane = this._map.createPane(this.options.pane);
      pane.style.pointerEvents = 'none';
      pane.style.zIndex = 500;
    }
  },

  getAttribution: function () {
    if (this.options.attribution) {
      var attribution = '' + this.options.attribution + '';
    }
    return attribution;
  }
});

export function basemapLayer (key, options) {
  return new BasemapLayer(key, options);
}

export default basemapLayer;
<|endoftext|>