<commit_before>// for Google Publisher Tag ads
//
// required props:
//    - adId: eg, '/6355419/Travel/Europe/France/Paris'
//    - height: a css size in pixels
//    - width: ditto
//
// optional props:
//    - placement: only useful if the same `adId` is used more than once on a
//      page, use this to distinguish between them: call one "1" and the other
//      "2", or call them "top-left" and "bottom-right", etc
//    - refresh: number of seconds between refreshes
//    - shouldWatchViewport: turn off checks for ad in view
//    - tracing: verbose messages in console.log via Ember.Logger.log

import Ember from 'ember';
import {task, timeout} from 'ember-concurrency';
import InViewportMixin from 'ember-in-viewport';
import getViewportTolerance from '../utils/get-viewport-tolerance';

const {
    Component,
    assert,
    get, set, getProperties, setProperties,
    String: { htmlSafe },
    Logger: { log },
    inject: { service },
    run,
    run: { scheduleOnce }
} = Ember;

export default Component.extend(InViewportMixin, {
    classNames: ['google-publisher-tag'],
    attributeBindings: ['style'],

    adQueue: service(),

    placement: 0,
    refresh: 0,
    refreshCount: 0,
    refreshLimit: 0,
    tracing: false,
    shouldWatchViewport: true,

    didReceiveAttrs() {
        this._super(...arguments);

        let {adId, width, height, placement} = getProperties(this, 'adId', 'width', 'height', 'placement');

        // width and height are also passed into .defineSlot(), which will
        // silently fail unless they are actually numbers
        assert(`google-publisher-tag "${adId} (${placement})": width and height must be numbers`, typeof width === 'number' && typeof height === 'number');

        let style = `width:${width}px; height:${height}px;`;
        set(this, 'style', htmlSafe(style));
    },
    didInsertElement() {
        let {
          shouldWatchViewport,
          width,
          height
        } = getProperties(this,
          'shouldWatchViewport',
          'width',
          'height'
        );

        setProperties(this, {
          viewportEnabled: shouldWatchViewport,
          viewportSpy: true,
          viewportTolerance: getViewportTolerance(width, height, 0.5)
        });

        // we must set the properties above first before calling super
        // where the mixin consumes the properties
        this._super(...arguments);

        if (!shouldWatchViewport) {
          scheduleOnce('afterRender', () => {
            this.initAd();
          });
        } else {
          this.trace('watching viewport, waiting for event...');
        }
    },

    initAd() {
      if (!get(this, 'isAdInitialized')) {
        this.trace('initializing');
        get(this, 'adQueue').push(this);
        set(this, 'isAdInitialized', true);
      }
      this.waitForRefresh();
    },

    addTargeting(slot) { // jshint ignore:line
        // override this in child components, if needed, but an example is:
        // slot.setTargeting('placement', get(this, 'placement'));
        // slot.setTargeting('refresh_count', get(this, 'refreshCount'));
        // slot.setTargeting('planet', 'Earth');
    },
    waitForRefresh() {
        let duration = get(this, 'refresh');
        if (duration > 0) {
            this.trace(`will refresh in ${duration} seconds`);

            // give the tests a moment to release wait handlers
            setTimeout(() => {
              run(() => {
                get(this, 'refreshWaitTask').perform(duration);
              });
            });
        }
    },
    trace() {
        if (get(this, 'tracing')) {
            let {adId, placement} = getProperties(this, 'adId', 'placement');
            log(`${adId} (${placement}):`, ...arguments);
        }
    },

    refreshWaitTask: task(function * (duration) {
        yield timeout(duration * 1000);

        let {
          shouldWatchViewport,
          viewportEntered
        } = getProperties(this,
          'shouldWatchViewport',
          'viewportEntered'
        );

        if (shouldWatchViewport && !viewportEntered) {
          this.trace('ad not in view, skipped refresh');

          return set(this, 'isRefreshOverdue', true);
        }

        this.doRefresh();
    }).restartable(),

    doRefresh() {
        let {refreshLimit, refreshCount} = getProperties(this, 'refreshLimit', 'refreshCount');
        if (refreshLimit > 0 && refreshCount >= refreshLimit) {
          this.trace(`refreshCount has met refreshLimit: ${refreshLimit}`);
          return;
        }

        this.trace(`queuing a refresh: ${refreshCount}`);
        let googletag = window.googletag;
        googletag.cmd.push( () => {
          let slot = get(this, 'slot');
          this.trace('refreshing now');
          this.addTargeting(slot);
          googletag.pubads().refresh([slot]);
          this.incrementProperty('refreshCount');
          this.waitForRefresh();
        });
    },

    didEnterViewport() {
      this.trace('entered viewport');

      this.initAd();
      if (get(this, 'isRefreshOverdue')) {
        this.doRefresh();
        set(this, 'isRefreshOverdue', false);
      }
    }
});
<commit_msg>drop instead of restartable so you don't reset the timer before ever seeing the refresh<commit_after>// for Google Publisher Tag ads
//
// required props:
//    - adId: eg, '/6355419/Travel/Europe/France/Paris'
//    - height: a css size in pixels
//    - width: ditto
//
// optional props:
//    - placement: only useful if the same `adId` is used more than once on a
//      page, use this to distinguish between them: call one "1" and the other
//      "2", or call them "top-left" and "bottom-right", etc
//    - refresh: number of seconds between refreshes
//    - shouldWatchViewport: turn off checks for ad in view
//    - tracing: verbose messages in console.log via Ember.Logger.log

import Ember from 'ember';
import {task, timeout} from 'ember-concurrency';
import InViewportMixin from 'ember-in-viewport';
import getViewportTolerance from '../utils/get-viewport-tolerance';

const {
    Component,
    assert,
    get, set, getProperties, setProperties,
    String: { htmlSafe },
    Logger: { log },
    inject: { service },
    run,
    run: { scheduleOnce }
} = Ember;

export default Component.extend(InViewportMixin, {
    classNames: ['google-publisher-tag'],
    attributeBindings: ['style'],

    adQueue: service(),

    placement: 0,
    refresh: 0,
    refreshCount: 0,
    refreshLimit: 0,
    tracing: false,
    shouldWatchViewport: true,

    didReceiveAttrs() {
        this._super(...arguments);

        let {adId, width, height, placement} = getProperties(this, 'adId', 'width', 'height', 'placement');

        // width and height are also passed into .defineSlot(), which will
        // silently fail unless they are actually numbers
        assert(`google-publisher-tag "${adId} (${placement})": width and height must be numbers`, typeof width === 'number' && typeof height === 'number');

        let style = `width:${width}px; height:${height}px;`;
        set(this, 'style', htmlSafe(style));
    },
    didInsertElement() {
        let {
          shouldWatchViewport,
          width,
          height
        } = getProperties(this,
          'shouldWatchViewport',
          'width',
          'height'
        );

        setProperties(this, {
          viewportEnabled: shouldWatchViewport,
          viewportSpy: true,
          viewportTolerance: getViewportTolerance(width, height, 0.5)
        });

        // we must set the properties above first before calling super
        // where the mixin consumes the properties
        this._super(...arguments);

        if (!shouldWatchViewport) {
          scheduleOnce('afterRender', () => {
            this.initAd();
          });
        } else {
          this.trace('watching viewport, waiting for event...');
        }
    },

    initAd() {
      if (!get(this, 'isAdInitialized')) {
        this.trace('initializing');
        get(this, 'adQueue').push(this);
        set(this, 'isAdInitialized', true);
      }
      this.waitForRefresh();
    },

    addTargeting(slot) { // jshint ignore:line
        // override this in child components, if needed, but an example is:
        // slot.setTargeting('placement', get(this, 'placement'));
        // slot.setTargeting('refresh_count', get(this, 'refreshCount'));
        // slot.setTargeting('planet', 'Earth');
    },
    waitForRefresh() {
        let duration = get(this, 'refresh');
        if (duration > 0) {
            // give the tests a moment to release wait handlers
            setTimeout(() => {
              run(() => {
                get(this, 'refreshWaitTask').perform(duration);
              });
            });
        }
    },
    trace() {
        if (get(this, 'tracing')) {
            let {adId, placement} = getProperties(this, 'adId', 'placement');
            log(`${adId} (${placement}):`, ...arguments);
        }
    },

    refreshWaitTask: task(function * (duration) {
        this.trace(`will refresh in ${duration} seconds`);

        yield timeout(duration * 1000);

        let {
          shouldWatchViewport,
          viewportEntered
        } = getProperties(this,
          'shouldWatchViewport',
          'viewportEntered'
        );

        if (shouldWatchViewport && !viewportEntered) {
          this.trace('ad not in view, skipped refresh');

          return set(this, 'isRefreshOverdue', true);
        }

        this.doRefresh();
    }).drop(), // don't reset the timer if you scroll out and back in view before it finishes

    doRefresh() {
        let {refreshLimit, refreshCount} = getProperties(this, 'refreshLimit', 'refreshCount');
        if (refreshLimit > 0 && refreshCount >= refreshLimit) {
          this.trace(`refreshCount has met refreshLimit: ${refreshLimit}`);
          return;
        }

        this.trace(`queuing a refresh: ${refreshCount}`);
        let googletag = window.googletag;
        googletag.cmd.push( () => {
          let slot = get(this, 'slot');
          this.trace('refreshing now');
          this.addTargeting(slot);
          googletag.pubads().refresh([slot]);
          this.incrementProperty('refreshCount');
          this.waitForRefresh();
        });
    },

    didEnterViewport() {
      this.trace('entered viewport');

      this.initAd();
      if (get(this, 'isRefreshOverdue')) {
        this.doRefresh();
        set(this, 'isRefreshOverdue', false);
      }
    }
});
<|endoftext|>


<commit_before>(function () {

var Path = require('fire-path');

Editor.registerPanel( 'package-manager.panel', {
    is: 'package-manager',

    properties: {
    },

    ready: function () {
        Editor.Package.query(function ( results ) {
            var packages = results.map( function (item) {
                return { name: item.info.name, enabled: item.enabled, builtin: item.builtin, info: item.info };
            });
            this.set( 'packages', packages );
        }.bind(this));
    },

    attached: function () {
        EditorUI.update( this, 'packages' );
    },

    _onReload: function (event) {
        event.stopPropagation();

        var item = this.$.list.itemForElement(event.target);
        Editor.Package.reload(item.name);
    },

    returnEnabled: function (enabled) {
        if (enabled) {
            return 'Disabled';
        }
        else {
            return 'Enbled';
        }
    },
});

})();
<commit_msg>修正拼写错误<commit_after>(function () {

var Path = require('fire-path');

Editor.registerPanel( 'package-manager.panel', {
    is: 'package-manager',

    properties: {
    },

    ready: function () {
        Editor.Package.query(function ( results ) {
            var packages = results.map( function (item) {
                return { name: item.info.name, enabled: item.enabled, builtin: item.builtin, info: item.info };
            });
            this.set( 'packages', packages );
        }.bind(this));
    },

    attached: function () {
        EditorUI.update( this, 'packages' );
    },

    _onReload: function (event) {
        event.stopPropagation();

        var item = this.$.list.itemForElement(event.target);
        Editor.Package.reload(item.name);
    },

    returnEnabled: function (enabled) {
        if (enabled) {
            return 'Disabled';
        }
        else {
            return 'Enabled';
        }
    },
});

})();
<|endoftext|>


<commit_before>/* global createGridDriver, System */

/* Config for galen tests to use
 * Usage
 *  @@ import galen.sauce.config.test
 *  @@ Parameterized using browsers
 *  Open simple.html in ${browserName}
 *    ${browserFactory} ${endpoint} ${browserArgs}
 * System Properties
 * USERNAME          sauce username
 * ACCESS_KEY        sauce access key
 * TUNNEL_IDENTIFIER sauce connect tunnel_identifier
 * NAME              sauce test name
 * BUILD             sauce build number
 */

this.endpoint = 'http://localhost:8080/components/d2l-table/demo/simple.html';

function factory(settings, url) {
	settings = settings || {};
	settings.desiredCapabilities = settings.desiredCapabilities || {};
	settings.desiredCapabilities.tunnelIdentifier = System.getProperty('TUNNEL_IDENTIFIER');
	settings.desiredCapabilities.build = System.getProperty('BUILD');
	settings.desiredCapabilities.tags = 'galen';

	var USERNAME = System.getProperty('USERNAME');
	var ACCESS_KEY = System.getProperty('ACCESS_KEY');
	var driver = createGridDriver('http://' + USERNAME + ':' + ACCESS_KEY + '@ondemand.saucelabs.com:80/wd/hub', settings);
	driver.get(url);
	return driver;
}

this.reportStatus = function reportStatus(driver, status) {
	driver.executeScript('sauce:job-result=' + (status ? 'passed' : 'failed'));
};

this.browsers = {
	chromeWindows: {
		browserName: 'chrome-windows',
		browserFactory: factory.bind(this, {
			browser: 'Chrome',
			platform: 'WIN10',
			size: '1400x900'
		})
	},
	firefoxWindows: {
		browserName: 'firefox-windows',
		browserFactory: factory.bind(this, {
			browser: 'Firefox',
			platform: 'WIN10',
			size: '1400x900'
		})
	},
	ie11Windows: {
		browserName: 'ie11-windows',
		browserFactory: factory.bind(this, {
			browser: 'internet explorer',
			version: '11',
			platform: 'WIN10',
			size: '1400x900'
		})
	},
	ie10Windows: {
		browserName: 'ie10-windows',
		browserFactory: factory.bind(this, {
			browser: 'internet explorer',
			version: '10',
			platform: 'WIN8',
			size: '1400x900'
		})
	},
	edgeWindows: {
		browserName: 'edge-windows',
		browserFactory: factory.bind(this, {
			browser: 'microsoftedge',
			platform: 'WIN10',
			size: '1400x900'
		})
	},
	chromeMac: {
		browserName: 'chrome-mac',
		browserFactory: factory.bind(this, {
			browser: 'Chrome',
			platform: 'EL_CAPITAN',
			size: '1400x900'
		})
	},
	safariMac: {
		browserName: 'safari-mac',
		browserFactory: factory.bind(this, {
			browser: 'Safari',
			platform: 'EL_CAPITAN',
			size: '1400x900'
		})
	},
	firefoxMac: {
		browserName: 'firefox-mac',
		browserFactory: factory.bind(this, {
			browser: 'Firefox',
			platform: 'EL_CAPITAN',
			size: '1400x900'
		})
	}
};
<commit_msg>Add missing NAME system property<commit_after>/* global createGridDriver, System */

/* Config for galen tests to use
 * Usage
 *  @@ import galen.sauce.config.test
 *  @@ Parameterized using browsers
 *  Open simple.html in ${browserName}
 *    ${browserFactory} ${endpoint} ${browserArgs}
 * System Properties
 * USERNAME          sauce username
 * ACCESS_KEY        sauce access key
 * TUNNEL_IDENTIFIER sauce connect tunnel_identifier
 * NAME              sauce test name
 * BUILD             sauce build number
 */

this.endpoint = 'http://localhost:8080/components/d2l-table/demo/simple.html';

function factory(settings, url) {
	settings = settings || {};
	settings.desiredCapabilities = settings.desiredCapabilities || {};
	settings.desiredCapabilities.tunnelIdentifier = System.getProperty('TUNNEL_IDENTIFIER');
	settings.desiredCapabilities.name = System.getProperty('NAME');
	settings.desiredCapabilities.build = System.getProperty('BUILD');
	settings.desiredCapabilities.tags = 'galen';

	var USERNAME = System.getProperty('USERNAME');
	var ACCESS_KEY = System.getProperty('ACCESS_KEY');
	var driver = createGridDriver('http://' + USERNAME + ':' + ACCESS_KEY + '@ondemand.saucelabs.com:80/wd/hub', settings);
	driver.get(url);
	return driver;
}

this.reportStatus = function reportStatus(driver, status) {
	driver.executeScript('sauce:job-result=' + (status ? 'passed' : 'failed'));
};

this.browsers = {
	chromeWindows: {
		browserName: 'chrome-windows',
		browserFactory: factory.bind(this, {
			browser: 'Chrome',
			platform: 'WIN10',
			size: '1400x900'
		})
	},
	firefoxWindows: {
		browserName: 'firefox-windows',
		browserFactory: factory.bind(this, {
			browser: 'Firefox',
			platform: 'WIN10',
			size: '1400x900'
		})
	},
	ie11Windows: {
		browserName: 'ie11-windows',
		browserFactory: factory.bind(this, {
			browser: 'internet explorer',
			version: '11',
			platform: 'WIN10',
			size: '1400x900'
		})
	},
	ie10Windows: {
		browserName: 'ie10-windows',
		browserFactory: factory.bind(this, {
			browser: 'internet explorer',
			version: '10',
			platform: 'WIN8',
			size: '1400x900'
		})
	},
	edgeWindows: {
		browserName: 'edge-windows',
		browserFactory: factory.bind(this, {
			browser: 'microsoftedge',
			platform: 'WIN10',
			size: '1400x900'
		})
	},
	chromeMac: {
		browserName: 'chrome-mac',
		browserFactory: factory.bind(this, {
			browser: 'Chrome',
			platform: 'EL_CAPITAN',
			size: '1400x900'
		})
	},
	safariMac: {
		browserName: 'safari-mac',
		browserFactory: factory.bind(this, {
			browser: 'Safari',
			platform: 'EL_CAPITAN',
			size: '1400x900'
		})
	},
	firefoxMac: {
		browserName: 'firefox-mac',
		browserFactory: factory.bind(this, {
			browser: 'Firefox',
			platform: 'EL_CAPITAN',
			size: '1400x900'
		})
	}
};
<|endoftext|>


<commit_before>'use strict';
var GameDataCreator = require('../gamedatacreator');
var PointView = require('../prefabs/pointview');
var MapView = require('../prefabs/mapview');
var FileInputHandler = require('../fileinputhandler');

function Editor() {}
Editor.prototype = {
  create: function() {
    this.game.add.image(0, 0, 'frame');
    this.mapView = new MapView(this.game, this.removePoint, this);
    this.game.add.existing(this.mapView);
    this.buttonGroup = this.game.add.group();
    this.addButtons();
    var parentDiv = document.getElementById('lukuinto-spring-2015-editor');
    this.fileInputHandler = new FileInputHandler(25, 50, parentDiv);
    this.fileInputHandler.addFileInputListener(this.mapView.displayImage, this.game.data);
  },
  update: function() {
  },
  shutdown: function() {
    this.fileInputHandler.remove();
  },
  addButtons: function() {
    var addStartPointButton = this.game.add.button(154, 646, 'add-startpoint', this.changeAction, this, 1, 0);
    this.buttonGroup.add(addStartPointButton);
    var addEndPointButton = this.game.add.button(334, 646, 'add-startpoint', this.changeAction, this, 1, 0);
    this.buttonGroup.add(addEndPointButton);
    var addPointsButton = this.game.add.button(514, 646, 'add-point', this.changeAction, this, 1, 0);
    this.buttonGroup.add(addPointsButton);
    var removePointsButton = this.game.add.button(694, 646, 'remove-point', this.changeAction, this, 1, 0);
    this.buttonGroup.add(removePointsButton);
    this.game.add.button(891, 641, 'next-state', this.moveToNextState, this, 1, 0, 2, 0);
  },
  changeAction: function(button) {
    this.buttonGroup.setAll('frame', 0);
    this.buttonGroup.setAll('freezeFrames', false);
    button.freezeFrames = true;
    button.frame = 1;
    this.mapView.toggleInputOnPointViews(false);

    this.mapView.events.onInputDown.removeAll();
    var buttonIndex = this.buttonGroup.getChildIndex(button);

    switch (buttonIndex) {
      case 0:
        this.mapView.events.onInputDown.add(this.addStartPoint, this);
        break;
      case 1:
        this.mapView.events.onInputDown.add(this.addEndPoint, this);
        break;
      case 2:
        this.mapView.events.onInputDown.add(this.addPoint, this);
        break;
      case 3:
        this.mapView.toggleInputOnPointViews(true);
        break;
      default:
        console.log('Invalid button index encountered, how the heck did that happen?');
    }
  },
  addPoint: function(sprite, pointer) {
    var x = this.scaleUp(pointer.x - this.mapView.x);
    var y = this.scaleUp(pointer.y - this.mapView.y);
    var newPoint = new GameDataCreator.GamePoint(x, y, 'unvisited');
    if (this.game.data.points.length === 0) {
      newPoint.state = 'next';
    }
    this.game.data.points.push(newPoint);
    var pointSprite = new PointView(this.game, newPoint, this.game.data.points, this.removePoint, this);
    this.mapView.addPointView(pointSprite);
    this.updatePreviewText();
  },
  removePoint: function(pointView) {
    var indexToRemove = this.game.data.points.indexOf(pointView.pointData);
    this.game.data.points.splice(indexToRemove, 1);
    pointView.destroy();
    this.mapView.updatePointViews();
    this.updatePreviewText();
  },
  addStartPoint: function(sprite, pointer) {
    this.game.data.startPoint.x = this.scaleUp(pointer.x - this.mapView.x);
    this.game.data.startPoint.y = this.scaleUp(pointer.y - this.mapView.y);
    this.mapView.updateStartPoint();
    this.updatePreviewText();
  },
  addEndPoint: function(sprite, pointer) {
    this.game.data.endPoint.x = this.scaleUp(pointer.x - this.mapView.x);
    this.game.data.endPoint.y = this.scaleUp(pointer.y - this.mapView.y);
    this.mapView.updateEndPoint();
    this.updatePreviewText();
  },
  updatePreviewText: function() {
    var textArea = window.document.getElementById('outputJSON');
    textArea.value = JSON.stringify(this.game.data, null, 2);
  },
  //Scales up point related numbers from the 0.75 scale of the displayed game area
  //to the correct game area size used in the game
  scaleUp: function(number) {
    var scaleCorrectedNumber = (number / 3) * 4;
    return Math.floor(scaleCorrectedNumber);
  },
  // addFileInputListener: function() {
  //   var sprite = this.mapView;
  //   var gameData = this.game.data;
  //   this.fileInputHandler.fileInput.addEventListener('change', function handleFiles(files) {
  //     var image = new Image();
  //     image.onload = function addImageToSprite() {
  //       sprite.displayImage.loadTexture(new PIXI.Texture(new PIXI.BaseTexture(image, PIXI.scaleModes.DEFAULT)));
  //       console.log('Image loaded');
  //       sprite.displayImage.width = 1024;
  //       sprite.displayImage.height = 768;
  //       // URL.revokeObjectURL(image.src);
  //       gameData.image = image.src;
  //     };
  //     image.src = URL.createObjectURL(files.target.files[0]);
  //   }, false);
  // },
  moveToNextState: function() {
    this.game.state.start('phase2');
  }
};

module.exports = Editor;
<commit_msg>Remove commented code related to previous commit.<commit_after>'use strict';
var GameDataCreator = require('../gamedatacreator');
var PointView = require('../prefabs/pointview');
var MapView = require('../prefabs/mapview');
var FileInputHandler = require('../fileinputhandler');

function Editor() {}
Editor.prototype = {
  create: function() {
    this.game.add.image(0, 0, 'frame');
    this.mapView = new MapView(this.game, this.removePoint, this);
    this.game.add.existing(this.mapView);
    this.buttonGroup = this.game.add.group();
    this.addButtons();
    var parentDiv = document.getElementById('lukuinto-spring-2015-editor');
    this.fileInputHandler = new FileInputHandler(25, 50, parentDiv);
    this.fileInputHandler.addFileInputListener(this.mapView.displayImage, this.game.data);
  },
  update: function() {
  },
  shutdown: function() {
    this.fileInputHandler.remove();
  },
  addButtons: function() {
    var addStartPointButton = this.game.add.button(154, 646, 'add-startpoint', this.changeAction, this, 1, 0);
    this.buttonGroup.add(addStartPointButton);
    var addEndPointButton = this.game.add.button(334, 646, 'add-startpoint', this.changeAction, this, 1, 0);
    this.buttonGroup.add(addEndPointButton);
    var addPointsButton = this.game.add.button(514, 646, 'add-point', this.changeAction, this, 1, 0);
    this.buttonGroup.add(addPointsButton);
    var removePointsButton = this.game.add.button(694, 646, 'remove-point', this.changeAction, this, 1, 0);
    this.buttonGroup.add(removePointsButton);
    this.game.add.button(891, 641, 'next-state', this.moveToNextState, this, 1, 0, 2, 0);
  },
  changeAction: function(button) {
    this.buttonGroup.setAll('frame', 0);
    this.buttonGroup.setAll('freezeFrames', false);
    button.freezeFrames = true;
    button.frame = 1;
    this.mapView.toggleInputOnPointViews(false);

    this.mapView.events.onInputDown.removeAll();
    var buttonIndex = this.buttonGroup.getChildIndex(button);

    switch (buttonIndex) {
      case 0:
        this.mapView.events.onInputDown.add(this.addStartPoint, this);
        break;
      case 1:
        this.mapView.events.onInputDown.add(this.addEndPoint, this);
        break;
      case 2:
        this.mapView.events.onInputDown.add(this.addPoint, this);
        break;
      case 3:
        this.mapView.toggleInputOnPointViews(true);
        break;
      default:
        console.log('Invalid button index encountered, how the heck did that happen?');
    }
  },
  addPoint: function(sprite, pointer) {
    var x = this.scaleUp(pointer.x - this.mapView.x);
    var y = this.scaleUp(pointer.y - this.mapView.y);
    var newPoint = new GameDataCreator.GamePoint(x, y, 'unvisited');
    if (this.game.data.points.length === 0) {
      newPoint.state = 'next';
    }
    this.game.data.points.push(newPoint);
    var pointSprite = new PointView(this.game, newPoint, this.game.data.points, this.removePoint, this);
    this.mapView.addPointView(pointSprite);
    this.updatePreviewText();
  },
  removePoint: function(pointView) {
    var indexToRemove = this.game.data.points.indexOf(pointView.pointData);
    this.game.data.points.splice(indexToRemove, 1);
    pointView.destroy();
    this.mapView.updatePointViews();
    this.updatePreviewText();
  },
  addStartPoint: function(sprite, pointer) {
    this.game.data.startPoint.x = this.scaleUp(pointer.x - this.mapView.x);
    this.game.data.startPoint.y = this.scaleUp(pointer.y - this.mapView.y);
    this.mapView.updateStartPoint();
    this.updatePreviewText();
  },
  addEndPoint: function(sprite, pointer) {
    this.game.data.endPoint.x = this.scaleUp(pointer.x - this.mapView.x);
    this.game.data.endPoint.y = this.scaleUp(pointer.y - this.mapView.y);
    this.mapView.updateEndPoint();
    this.updatePreviewText();
  },
  updatePreviewText: function() {
    var textArea = window.document.getElementById('outputJSON');
    textArea.value = JSON.stringify(this.game.data, null, 2);
  },
  //Scales up point related numbers from the 0.75 scale of the displayed game area
  //to the correct game area size used in the game
  scaleUp: function(number) {
    var scaleCorrectedNumber = (number / 3) * 4;
    return Math.floor(scaleCorrectedNumber);
  },
  moveToNextState: function() {
    this.game.state.start('phase2');
  }
};

module.exports = Editor;
<|endoftext|>


<commit_before>// Globals.
var GM_config = GM_getConfig();
var GM_uninstallQueue = {};
var GM_stringBundle = Components
    .classes["@mozilla.org/intl/stringbundle;1"]
    .getService(Components.interfaces.nsIStringBundleService)
    .createBundle("chrome://greasemonkey/locale/gm-manage.properties");
function GM_string(key) { return GM_stringBundle.GetStringFromName(key); }

(function() {
// Override some built-in functions, with a closure reference to the original
// function, to either handle or delegate the call.
var _origShowView = showView;
showView = function(aView) {
  if ('userscripts' == aView) {
    greasemonkeyAddons.showView();
  } else {
    _origShowView(aView);
  }
};

var _origBuildContextMenu = buildContextMenu;
buildContextMenu = function(aEvent) {
  if ('userscripts' == gView) {
    greasemonkeyAddons.buildContextMenu(aEvent);
  } else {
    _origBuildContextMenu(aEvent);
  }
};

// Set up an "observer" on the config, to keep the displayed items up to date
// with their actual state.
var config = GM_config;
window.addEventListener("load", function() {
  config.addObserver(observer);
}, false);
window.addEventListener("unload", function() {
  config.removeObserver(observer);
}, false);

var observer = {
  notifyEvent: function(script, event, data) {
    // if the currently open tab is not the userscripts tab, then ignore event.
    if (gView != 'userscripts') return;

    if (event == "install") {
      var item = greasemonkeyAddons.addScriptToList(script);
      gExtensionsView.selectedItem = item;
      return;
    }

    // find the script's node in the listbox
    var listbox = gExtensionsView;
    var node;
    for (var i = 0; node = listbox.childNodes[i]; i++) {
      if (node.getAttribute('addonId') == script.id) {
        break;
      }
    }
    if (!node) return;

    switch (event) {
      case "edit-enabled":
        node.setAttribute('isDisabled', !data);
        break;
      case "uninstall":
        listbox.removeChild(node);
        break;
      case "move":
        listbox.removeChild(node);
        listbox.insertBefore(node, listbox.childNodes[data]);
        break;
      case "modified":
        var item = greasemonkeyAddons.listitemForScript(script);
        gExtensionsView.replaceChild(item, node);
        break;
    }
  }
};
})();

// Set event listeners.
window.addEventListener('load', function() {
  greasemonkeyAddons.onAddonSelect();
  gExtensionsView.addEventListener(
      'select', greasemonkeyAddons.onAddonSelect, false);

  // Work-around for Stylish compatibility, which does not update gView in
  // its overridden showView() function.
  var stylishRadio = document.getElementById('userstyles-view');
  if (stylishRadio) {
    stylishRadio.addEventListener(
        'command',
        function() { gView = 'userstyles' },
        false);
  }
}, false);

window.addEventListener('unload', function() {
  for (var id in GM_uninstallQueue) {
    GM_config.uninstall(GM_uninstallQueue[id]);
    delete(GM_uninstallQueue[id]);
  }
}, false);

var greasemonkeyAddons = {
  showView: function() {
    if ('userscripts' == gView) return;
    updateLastSelected('userscripts');
    gView='userscripts';

    // Update any possibly modified scripts.
    GM_config.updateModifiedScripts();

    // Hide the native controls that don't work in the user scripts view.
    function $(id) { return document.getElementById(id); }
    function hide(el) { el=$(el); el && (el.hidden=true); }
    var elementIds=[
      'searchPanel', 'installFileButton', 'checkUpdatesAllButton',
      'skipDialogButton', 'themePreviewArea', 'themeSplitter',
      'showUpdateInfoButton', 'hideUpdateInfoButton',
      'installUpdatesAllButton',
      // Stylish injects these elements.
      'copy-style-info', 'new-style'];
    elementIds.forEach(hide);

    var getMore = document.getElementById('getMore');
    getMore.setAttribute('getMoreURL', 'http://userscripts.org/');
    getMore.hidden = false;
    getMore.value = 'Get User Scripts';

    greasemonkeyAddons.fillList();
    gExtensionsView.selectedItem = gExtensionsView.children[0];
    // The setTimeout() here is for timing, to make sure the selection above
    // has really happened.
    setTimeout(greasemonkeyAddons.onAddonSelect, 0);
  },

  fillList: function() {
    var config = GM_config;
    var listbox = gExtensionsView;

    // Remove any pre-existing contents.
    while (listbox.firstChild) {
      listbox.removeChild(listbox.firstChild);
    }

    // Add a list item for each script.
    for (var i = 0, script = null; script = config.scripts[i]; i++) {
      greasemonkeyAddons.addScriptToList(script);
    }
  },

  listitemForScript: function(script) {
    var item = document.createElement('richlistitem');
    item.setAttribute('class', 'userscript');
    // Fake this for now.
    // Setting these attributes inherits the values into the same place they
    // would go for extensions.
    item.setAttribute('addonId', script.id);
    item.setAttribute('name', script.name);
    item.setAttribute('description', script.description);
    item.setAttribute('version', script.version);
    item.setAttribute('id', 'urn:greasemonkey:item:'+script.id);
    item.setAttribute('isDisabled', !script.enabled);
    // These hide extension-specific bits we don't want to display.
    item.setAttribute('blocklisted', 'false');
    item.setAttribute('blocklistedsoft', 'false');
    item.setAttribute('compatible', 'true');
    item.setAttribute('locked', 'false');
    item.setAttribute('providesUpdatesSecurely', 'true');
    item.setAttribute('satisfiesDependencies', 'true');
    item.setAttribute('type', nsIUpdateItem.TYPE_EXTENSION);
    return item;
  },

  addScriptToList: function(script, beforeNode) {
    var item = greasemonkeyAddons.listitemForScript(script);
    gExtensionsView.insertBefore(item, beforeNode || null);
    return item;
  },

  findSelectedScript: function() {
    if (!gExtensionsView.selectedItem) return null;
    var scripts = GM_config.scripts;
    var selectedScriptId = gExtensionsView.selectedItem.getAttribute('addonId');
    for (var i = 0, script = null; script = scripts[i]; i++) {
      if (selectedScriptId == script.id) {
        return script;
      }
    }
    return null;
  },

  onAddonSelect: function(aEvent) {
    // We do all this work here, because the elements we want to change do
    // not exist until the item is selected.

    if (!gExtensionsView.selectedItem) return;
    if ('userscripts' != gView) return;
    var script = greasemonkeyAddons.findSelectedScript();

    // Remove/change the anonymous nodes we don't want.
    var item = gExtensionsView.selectedItem;
    var button;

    // Replace 'preferences' with 'edit'.
    button = item.ownerDocument.getAnonymousElementByAttribute(
        item, 'command', 'cmd_options');
    if (!button) return;
    button.setAttribute('label', GM_string('Edit'));
    button.setAttribute('accesskey', GM_string('Edit.accesskey'));
    button.setAttribute('tooltiptext', GM_string('Edit.tooltip'));
    button.setAttribute('command', 'cmd_userscript_edit');
    button.setAttribute('disabled', 'false');

    // Rewire enable, disable, uninstall.
    button = item.ownerDocument.getAnonymousElementByAttribute(
        item, 'command', 'cmd_enable');
    if (!button) return;
    button.setAttribute('tooltiptext', GM_string('Enable.tooltip'));
    button.setAttribute('command', 'cmd_userscript_enable');
    button.setAttribute('disabled', 'false');

    button = item.ownerDocument.getAnonymousElementByAttribute(
        item, 'command', 'cmd_disable');
    if (!button) return;
    button.setAttribute('tooltiptext', GM_string('Disable.tooltip'));
    button.setAttribute('command', 'cmd_userscript_disable');
    button.setAttribute('disabled', 'false');

    button = item.ownerDocument.getAnonymousElementByAttribute(
        item, 'command', 'cmd_uninstall');
    if (!button) return;
    button.setAttribute('tooltiptext', GM_string('Uninstall.tooltip'));
    button.setAttribute('command', 'cmd_userscript_uninstall');
    button.setAttribute('disabled', 'false');

    button = item.ownerDocument.getAnonymousElementByAttribute(
        item, 'command', 'cmd_cancelUninstall');
    if (!button) return;
    button.setAttribute('tooltiptext', GM_string('UninstallCancel.tooltip'));
    button.setAttribute('command', 'cmd_userscript_uninstall_cancel');
    button.setAttribute('disabled', 'false');
  },

  doCommand: function(command) {
    var script = greasemonkeyAddons.findSelectedScript();
    if (!script) {
      dump("greasemonkeyAddons.doCommand() could not find selected script.\n");
      return;
    }

    var selectedListitem = gExtensionsView.selectedItem;
    switch (command) {
    case 'cmd_userscript_edit':
      GM_openInEditor(script);
      break;
    case 'cmd_userscript_enable':
      script.enabled = true;
      break;
    case 'cmd_userscript_disable':
      script.enabled = false;
      break;
    case 'cmd_userscript_move_down':
      GM_config.move(script, 1);
      break;
    case 'cmd_userscript_move_bottom':
      GM_config.move(script, GM_config.scripts.length);
      break;
    case 'cmd_userscript_move_up':
      GM_config.move(script, -1);
      break;
    case 'cmd_userscript_move_top':
      GM_config.move(script, -1 * GM_config.scripts.length);
      break;
    case 'cmd_userscript_sort':
      function scriptCmp(a, b) { return a.name < b.name ? -1 : 1; }
      GM_config._scripts.sort(scriptCmp);
      GM_config._save();
      greasemonkeyAddons.fillList();
      break;
    case 'cmd_userscript_uninstall':
      GM_uninstallQueue[script.id] = script;
      selectedListitem.setAttribute('opType', 'needs-uninstall');
      // This setTimeout puts this after the opType set has taken effect, and
      // the element is created.
      // Todo: is there a way to do this sooner, that's still not too late?
      setTimeout(function() {
        var labelBox = selectedListitem.ownerDocument
            .getAnonymousElementByAttribute(
                selectedListitem, 'anonid', 'addonOpType');
        var label = labelBox.ownerDocument.getAnonymousNodes(labelBox)[0];
        label.setAttribute('value', GM_string('UninstallCancel'));
      }, 0);

      break;
    case 'cmd_userscript_uninstall_cancel':
      delete(GM_uninstallQueue[script.id]);
      selectedListitem.removeAttribute('opType');
      break;
    case 'cmd_userscript_uninstall_now':
      GM_config.uninstall(script);
      break;
    }
  },

  buildContextMenu: function(aEvent) {
    var script = greasemonkeyAddons.findSelectedScript();
    if (!script) {
      dump("greasemonkeyAddons.buildContextMenu() could not find selected script.\n");
      return;
    }

    var selectedItem = gExtensionsView.selectedItem;
    var popup = document.getElementById('addonContextMenu');
    while (popup.hasChildNodes()) {
      popup.removeChild(popup.firstChild);
    }

    function forceDisabled(aEvent) {
      if ('disabled' != aEvent.attrName) return;
      if ('true' == aEvent.newValue) return;
      aEvent.target.setAttribute('disabled', 'true');
    }
    function addMenuItem(label, command, enabled) {
      var menuitem = document.createElement('menuitem');
      menuitem.setAttribute('label', GM_string(label));
      menuitem.setAttribute('accesskey', GM_string(label+'.accesskey'));
      menuitem.setAttribute('command', command);

      if ('undefined' == typeof enabled) enabled = true;
      if (!enabled) {
        menuitem.setAttribute('disabled', 'true');
        // Something is un-setting the disabled attribute.  Work around that,
        // this way for now.
        menuitem.addEventListener('DOMAttrModified', forceDisabled, true);
      }

      popup.appendChild(menuitem);
    }

    addMenuItem('Edit', 'cmd_userscript_edit');
    if (script.enabled) {
      addMenuItem('Disable', 'cmd_userscript_disable');
    } else {
      addMenuItem('Enable', 'cmd_userscript_enable');
    }

    if ('needs-uninstall' == selectedItem.getAttribute('opType')) {
      addMenuItem('UninstallNow', 'cmd_userscript_uninstall_now');
    } else {
      addMenuItem('Uninstall', 'cmd_userscript_uninstall');
    }

    popup.appendChild(document.createElement('menuseparator'));

    addMenuItem('Move Up', 'cmd_userscript_move_up',
        !!selectedItem.previousSibling);
    addMenuItem('Move Down', 'cmd_userscript_move_down',
        !!selectedItem.nextSibling);
    addMenuItem('Move To Top', 'cmd_userscript_move_top',
        !!selectedItem.previousSibling);
    addMenuItem('Move To Bottom', 'cmd_userscript_move_bottom',
        !!selectedItem.nextSibling);

    popup.appendChild(document.createElement('menuseparator'));

    addMenuItem('Sort Scripts', 'cmd_userscript_sort',
        gExtensionsView.itemCount > 1);
  }
};
<commit_msg>Change the todo comment to make sense.<commit_after>// Globals.
var GM_config = GM_getConfig();
var GM_uninstallQueue = {};
var GM_stringBundle = Components
    .classes["@mozilla.org/intl/stringbundle;1"]
    .getService(Components.interfaces.nsIStringBundleService)
    .createBundle("chrome://greasemonkey/locale/gm-manage.properties");
function GM_string(key) { return GM_stringBundle.GetStringFromName(key); }

(function() {
// Override some built-in functions, with a closure reference to the original
// function, to either handle or delegate the call.
var _origShowView = showView;
showView = function(aView) {
  if ('userscripts' == aView) {
    greasemonkeyAddons.showView();
  } else {
    _origShowView(aView);
  }
};

var _origBuildContextMenu = buildContextMenu;
buildContextMenu = function(aEvent) {
  if ('userscripts' == gView) {
    greasemonkeyAddons.buildContextMenu(aEvent);
  } else {
    _origBuildContextMenu(aEvent);
  }
};

// Set up an "observer" on the config, to keep the displayed items up to date
// with their actual state.
var config = GM_config;
window.addEventListener("load", function() {
  config.addObserver(observer);
}, false);
window.addEventListener("unload", function() {
  config.removeObserver(observer);
}, false);

var observer = {
  notifyEvent: function(script, event, data) {
    // if the currently open tab is not the userscripts tab, then ignore event.
    if (gView != 'userscripts') return;

    if (event == "install") {
      var item = greasemonkeyAddons.addScriptToList(script);
      gExtensionsView.selectedItem = item;
      return;
    }

    // find the script's node in the listbox
    var listbox = gExtensionsView;
    var node;
    for (var i = 0; node = listbox.childNodes[i]; i++) {
      if (node.getAttribute('addonId') == script.id) {
        break;
      }
    }
    if (!node) return;

    switch (event) {
      case "edit-enabled":
        node.setAttribute('isDisabled', !data);
        break;
      case "uninstall":
        listbox.removeChild(node);
        break;
      case "move":
        listbox.removeChild(node);
        listbox.insertBefore(node, listbox.childNodes[data]);
        break;
      case "modified":
        var item = greasemonkeyAddons.listitemForScript(script);
        gExtensionsView.replaceChild(item, node);
        break;
    }
  }
};
})();

// Set event listeners.
window.addEventListener('load', function() {
  greasemonkeyAddons.onAddonSelect();
  gExtensionsView.addEventListener(
      'select', greasemonkeyAddons.onAddonSelect, false);

  // Work-around for Stylish compatibility, which does not update gView in
  // its overridden showView() function.
  var stylishRadio = document.getElementById('userstyles-view');
  if (stylishRadio) {
    stylishRadio.addEventListener(
        'command',
        function() { gView = 'userstyles' },
        false);
  }
}, false);

window.addEventListener('unload', function() {
  for (var id in GM_uninstallQueue) {
    GM_config.uninstall(GM_uninstallQueue[id]);
    delete(GM_uninstallQueue[id]);
  }
}, false);

var greasemonkeyAddons = {
  showView: function() {
    if ('userscripts' == gView) return;
    updateLastSelected('userscripts');
    gView='userscripts';

    // Update any possibly modified scripts.
    GM_config.updateModifiedScripts();

    // Hide the native controls that don't work in the user scripts view.
    function $(id) { return document.getElementById(id); }
    function hide(el) { el=$(el); el && (el.hidden=true); }
    var elementIds=[
      'searchPanel', 'installFileButton', 'checkUpdatesAllButton',
      'skipDialogButton', 'themePreviewArea', 'themeSplitter',
      'showUpdateInfoButton', 'hideUpdateInfoButton',
      'installUpdatesAllButton',
      // Stylish injects these elements.
      'copy-style-info', 'new-style'];
    elementIds.forEach(hide);

    var getMore = document.getElementById('getMore');
    getMore.setAttribute('getMoreURL', 'http://userscripts.org/');
    getMore.hidden = false;
    getMore.value = 'Get User Scripts';

    greasemonkeyAddons.fillList();
    gExtensionsView.selectedItem = gExtensionsView.children[0];
    // The setTimeout() here is for timing, to make sure the selection above
    // has really happened.
    setTimeout(greasemonkeyAddons.onAddonSelect, 0);
  },

  fillList: function() {
    var config = GM_config;
    var listbox = gExtensionsView;

    // Remove any pre-existing contents.
    while (listbox.firstChild) {
      listbox.removeChild(listbox.firstChild);
    }

    // Add a list item for each script.
    for (var i = 0, script = null; script = config.scripts[i]; i++) {
      greasemonkeyAddons.addScriptToList(script);
    }
  },

  listitemForScript: function(script) {
    var item = document.createElement('richlistitem');
    item.setAttribute('class', 'userscript');
    // Fake this for now.
    // Setting these attributes inherits the values into the same place they
    // would go for extensions.
    item.setAttribute('addonId', script.id);
    item.setAttribute('name', script.name);
    item.setAttribute('description', script.description);
    item.setAttribute('version', script.version);
    item.setAttribute('id', 'urn:greasemonkey:item:'+script.id);
    item.setAttribute('isDisabled', !script.enabled);
    // These hide extension-specific bits we don't want to display.
    item.setAttribute('blocklisted', 'false');
    item.setAttribute('blocklistedsoft', 'false');
    item.setAttribute('compatible', 'true');
    item.setAttribute('locked', 'false');
    item.setAttribute('providesUpdatesSecurely', 'true');
    item.setAttribute('satisfiesDependencies', 'true');
    item.setAttribute('type', nsIUpdateItem.TYPE_EXTENSION);
    return item;
  },

  addScriptToList: function(script, beforeNode) {
    var item = greasemonkeyAddons.listitemForScript(script);
    gExtensionsView.insertBefore(item, beforeNode || null);
    return item;
  },

  findSelectedScript: function() {
    if (!gExtensionsView.selectedItem) return null;
    var scripts = GM_config.scripts;
    var selectedScriptId = gExtensionsView.selectedItem.getAttribute('addonId');
    for (var i = 0, script = null; script = scripts[i]; i++) {
      if (selectedScriptId == script.id) {
        return script;
      }
    }
    return null;
  },

  onAddonSelect: function(aEvent) {
    // We do all this work here, because the elements we want to change do
    // not exist until the item is selected.

    if (!gExtensionsView.selectedItem) return;
    if ('userscripts' != gView) return;
    var script = greasemonkeyAddons.findSelectedScript();

    // Remove/change the anonymous nodes we don't want.
    var item = gExtensionsView.selectedItem;
    var button;

    // Replace 'preferences' with 'edit'.
    button = item.ownerDocument.getAnonymousElementByAttribute(
        item, 'command', 'cmd_options');
    if (!button) return;
    button.setAttribute('label', GM_string('Edit'));
    button.setAttribute('accesskey', GM_string('Edit.accesskey'));
    button.setAttribute('tooltiptext', GM_string('Edit.tooltip'));
    button.setAttribute('command', 'cmd_userscript_edit');
    button.setAttribute('disabled', 'false');

    // Rewire enable, disable, uninstall.
    button = item.ownerDocument.getAnonymousElementByAttribute(
        item, 'command', 'cmd_enable');
    if (!button) return;
    button.setAttribute('tooltiptext', GM_string('Enable.tooltip'));
    button.setAttribute('command', 'cmd_userscript_enable');
    button.setAttribute('disabled', 'false');

    button = item.ownerDocument.getAnonymousElementByAttribute(
        item, 'command', 'cmd_disable');
    if (!button) return;
    button.setAttribute('tooltiptext', GM_string('Disable.tooltip'));
    button.setAttribute('command', 'cmd_userscript_disable');
    button.setAttribute('disabled', 'false');

    button = item.ownerDocument.getAnonymousElementByAttribute(
        item, 'command', 'cmd_uninstall');
    if (!button) return;
    button.setAttribute('tooltiptext', GM_string('Uninstall.tooltip'));
    button.setAttribute('command', 'cmd_userscript_uninstall');
    button.setAttribute('disabled', 'false');

    button = item.ownerDocument.getAnonymousElementByAttribute(
        item, 'command', 'cmd_cancelUninstall');
    if (!button) return;
    button.setAttribute('tooltiptext', GM_string('UninstallCancel.tooltip'));
    button.setAttribute('command', 'cmd_userscript_uninstall_cancel');
    button.setAttribute('disabled', 'false');
  },

  doCommand: function(command) {
    var script = greasemonkeyAddons.findSelectedScript();
    if (!script) {
      dump("greasemonkeyAddons.doCommand() could not find selected script.\n");
      return;
    }

    var selectedListitem = gExtensionsView.selectedItem;
    switch (command) {
    case 'cmd_userscript_edit':
      GM_openInEditor(script);
      break;
    case 'cmd_userscript_enable':
      script.enabled = true;
      break;
    case 'cmd_userscript_disable':
      script.enabled = false;
      break;
    case 'cmd_userscript_move_down':
      GM_config.move(script, 1);
      break;
    case 'cmd_userscript_move_bottom':
      GM_config.move(script, GM_config.scripts.length);
      break;
    case 'cmd_userscript_move_up':
      GM_config.move(script, -1);
      break;
    case 'cmd_userscript_move_top':
      GM_config.move(script, -1 * GM_config.scripts.length);
      break;
    case 'cmd_userscript_sort':
      function scriptCmp(a, b) { return a.name < b.name ? -1 : 1; }
      GM_config._scripts.sort(scriptCmp);
      GM_config._save();
      greasemonkeyAddons.fillList();
      break;
    case 'cmd_userscript_uninstall':
      GM_uninstallQueue[script.id] = script;
      selectedListitem.setAttribute('opType', 'needs-uninstall');
      // This setTimeout puts this after the opType set has taken effect, and
      // the element is created.
      // Todo: is there a way to do this sooner/simpler?
      setTimeout(function() {
        var labelBox = selectedListitem.ownerDocument
            .getAnonymousElementByAttribute(
                selectedListitem, 'anonid', 'addonOpType');
        var label = labelBox.ownerDocument.getAnonymousNodes(labelBox)[0];
        label.setAttribute('value', GM_string('UninstallCancel'));
      }, 0);

      break;
    case 'cmd_userscript_uninstall_cancel':
      delete(GM_uninstallQueue[script.id]);
      selectedListitem.removeAttribute('opType');
      break;
    case 'cmd_userscript_uninstall_now':
      GM_config.uninstall(script);
      break;
    }
  },

  buildContextMenu: function(aEvent) {
    var script = greasemonkeyAddons.findSelectedScript();
    if (!script) {
      dump("greasemonkeyAddons.buildContextMenu() could not find selected script.\n");
      return;
    }

    var selectedItem = gExtensionsView.selectedItem;
    var popup = document.getElementById('addonContextMenu');
    while (popup.hasChildNodes()) {
      popup.removeChild(popup.firstChild);
    }

    function forceDisabled(aEvent) {
      if ('disabled' != aEvent.attrName) return;
      if ('true' == aEvent.newValue) return;
      aEvent.target.setAttribute('disabled', 'true');
    }
    function addMenuItem(label, command, enabled) {
      var menuitem = document.createElement('menuitem');
      menuitem.setAttribute('label', GM_string(label));
      menuitem.setAttribute('accesskey', GM_string(label+'.accesskey'));
      menuitem.setAttribute('command', command);

      if ('undefined' == typeof enabled) enabled = true;
      if (!enabled) {
        menuitem.setAttribute('disabled', 'true');
        // Something is un-setting the disabled attribute.  Work around that,
        // this way for now.
        menuitem.addEventListener('DOMAttrModified', forceDisabled, true);
      }

      popup.appendChild(menuitem);
    }

    addMenuItem('Edit', 'cmd_userscript_edit');
    if (script.enabled) {
      addMenuItem('Disable', 'cmd_userscript_disable');
    } else {
      addMenuItem('Enable', 'cmd_userscript_enable');
    }

    if ('needs-uninstall' == selectedItem.getAttribute('opType')) {
      addMenuItem('UninstallNow', 'cmd_userscript_uninstall_now');
    } else {
      addMenuItem('Uninstall', 'cmd_userscript_uninstall');
    }

    popup.appendChild(document.createElement('menuseparator'));

    addMenuItem('Move Up', 'cmd_userscript_move_up',
        !!selectedItem.previousSibling);
    addMenuItem('Move Down', 'cmd_userscript_move_down',
        !!selectedItem.nextSibling);
    addMenuItem('Move To Top', 'cmd_userscript_move_top',
        !!selectedItem.previousSibling);
    addMenuItem('Move To Bottom', 'cmd_userscript_move_bottom',
        !!selectedItem.nextSibling);

    popup.appendChild(document.createElement('menuseparator'));

    addMenuItem('Sort Scripts', 'cmd_userscript_sort',
        gExtensionsView.itemCount > 1);
  }
};
<|endoftext|>


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

// namespace:
this.createjs = this.createjs||{};

(function() {

/**
 * A Shape allows you to display vector art in the display list. It composites a Graphics instance which exposes all of the vector
 * drawing methods. The Graphics instance can be shared between multiple Shape instances to display the same vector graphics with different
 * positions or transforms. If the vector art will not change between draws, you may want to use the cache() method to reduce the rendering cost.
 * @class ButtonHelper
 * @constructor
 * @param {MovieClip | BitmapAnimation} target The MovieClip or BitmapAnimation to add button functionality to.
 * @param {String | Number} outLabel Optional. The label name or frame number to display when the user mouses over the target. Defaults to "out".
 * @param {String | Number} overLabel Optional. The label name or frame number to display when the user mouses out of the target. Defaults to "over".
 * @param {String | Number} pressLabel Optional. The label name or frame number to display when the user presses (clicks and holds) on the target. Defaults to "press".
 * @param {Boolean} play Optional. If true, then ButtonHelper will call gotoAndPlay, if false, it will use gotoAndStop. Default is false.
 * @param {DisplayObject} hitArea Optional. If specified, this sets the hitArea property on the target.
 * @param {String | Number} hitLabel Optional. If specified, this will set actionsEnabled to false and advance the hitArea to the specified label or frame number. Equivalent to calling hitArea.gotoAndStop(hitLabel).
 **/
var ButtonHelper = function(target, outLabel, overLabel, pressLabel, play, hitArea, hitLabel) {
	this.initialize(target, outLabel, overLabel, pressLabel, play, hitArea, hitLabel);
}
var p = ButtonHelper.prototype;

// public properties:
	/**
	 * Read-only. The target for this button helper.
	 * @property target
	 * @type MovieClip | BitmapAnimation
	 **/
	p.target = null;

	/**
	 * The label name or frame number to display when the user mouses out of the target. Defaults to "over".
	 * @property overLabel
	 * @type String | Number
	 **/
	p.overLabel = null;

	/**
	 * The label name or frame number to display when the user mouses over the target. Defaults to "out".
	 * @property outLabel
	 * @type String | Number
	 **/
	p.outLabel = null;

	/**
	 * The label name or frame number to display when the user presses (clicks and holds) on the target. Defaults to "press".
	 * @property pressLabel
	 * @type String | Number
	 **/
	p.pressLabel = null;

	/**
	 * If true, then ButtonHelper will call gotoAndPlay, if false, it will use gotoAndStop. Default is false.
	 * @property play
	 * @default false
	 * @type Boolean
	 **/
	p.play = false;

//  private properties
	/**
	 * @property _isPressed
	 * @type Boolean
	 * @protected
	 **/
	p._isPressed = false;

// constructor:
	/**
	 * Initialization method.
	 * @method initialize
	 * @protected
	 **/
	p.initialize = function(target, outLabel, overLabel, pressLabel, play, hitArea, hitLabel) {
		this.target = target;
		this.overLabel = overLabel == null ? "over" : overLabel;
		this.outLabel = outLabel == null ? "out" : outLabel;
		this.pressLabel = pressLabel == null ? "press" : pressLabel;
		this.play = play;
		target.cursor = "pointer";
		this.setEnabled(true);
		this._handleEvt({});
		if (hitArea) {
			if (hitLabel) {
				hitArea.actionsEnabled = false;
				hitArea.gotoAndStop(hitLabel);
			}
			target.hitArea = hitArea;
		}
	};

// public methods:
	/**
	 * Enables or disables the button functionality on the target.
	 * @method setEnabled
	 * @param {Boolean} value
	 **/
	p.setEnabled = function(value) {
		var o = this.target;
		var _this = this;
		if (o.addEventListener) {
			var f = _this._handleEvt;
			if (value) {
				o.addEventListener("mouseOver", f, _this);
				o.addEventListener("mouseOut", f, _this);
				o.addEventListener("press", f, _this);
				o.addEventListener("click", f, _this);
			} else {
				o.removeEventListener("mouseOver", f, _this);
				o.removeEventListener("mouseOut", f, _this);
				o.removeEventListener("press", f, _this);
				o.removeEventListener("click", f, _this);
			}
		} else {
			o.onMouseOver = o.onMouseOut = value ? function(e) { _this._handleEvt(e); } : null;
		}
	};

	/**
	 * Returns a string representation of this object.
	 * @method toString
	 * @return {String} a string representation of the instance.
	 **/
	p.toString = function() {
		return "[ButtonHelper]";
	};

// protected methods:
	/**
	 * @method _handleEvt
	 * @protected
	 **/
	p._handleEvt = function(evt) {
		var label = (evt.type == "mouseOver" && !this._isPressed) || evt.type == "click" ? this.overLabel :
				  		(evt.type == "mouseOver" && this._isPressed) || evt.type == "press" ? this.pressLabel :
						this.outLabel;

		if (evt.type == "press") {
			var _this = this;
			this._isPressed = true;
			if (evt.addEventListener) {
				evt.addEventListener("mouseUp", _this._handleEvt, _this);
			} else {
				evt.onMouseMove = function(e) { _this._handleEvt(e); };
			}
		} else if (evt.type == "mouseUp") {
			this._isPressed = false;
			return;
		}

		if (this.play) {
			this.target.gotoAndPlay(label);
		} else {
			this.target.gotoAndStop(label);
		}
	};

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

// namespace:
this.createjs = this.createjs||{};

(function() {

/**
 * A Shape allows you to display vector art in the display list. It composites a Graphics instance which exposes all of the vector
 * drawing methods. The Graphics instance can be shared between multiple Shape instances to display the same vector graphics with different
 * positions or transforms. If the vector art will not change between draws, you may want to use the cache() method to reduce the rendering cost.
 * @class ButtonHelper
 * @constructor
 * @param {MovieClip | BitmapAnimation} target The MovieClip or BitmapAnimation to add button functionality to.
 * @param {String | Number} outLabel Optional. The label name or frame number to display when the user mouses over the target. Defaults to "out".
 * @param {String | Number} overLabel Optional. The label name or frame number to display when the user mouses out of the target. Defaults to "over".
 * @param {String | Number} pressLabel Optional. The label name or frame number to display when the user presses (clicks and holds) on the target. Defaults to "press".
 * @param {Boolean} play Optional. If true, then ButtonHelper will call gotoAndPlay, if false, it will use gotoAndStop. Default is false.
 * @param {DisplayObject} hitArea Optional. If specified, this sets the hitArea property on the target.
 * @param {String | Number} hitLabel Optional. If specified, this will set actionsEnabled to false and advance the hitArea to the specified label or frame number. Equivalent to calling hitArea.gotoAndStop(hitLabel).
 **/
var ButtonHelper = function(target, outLabel, overLabel, pressLabel, play, hitArea, hitLabel) {
	this.initialize(target, outLabel, overLabel, pressLabel, play, hitArea, hitLabel);
}
var p = ButtonHelper.prototype;

// public properties:
	/**
	 * Read-only. The target for this button helper.
	 * @property target
	 * @type MovieClip | BitmapAnimation
	 **/
	p.target = null;

	/**
	 * The label name or frame number to display when the user mouses out of the target. Defaults to "over".
	 * @property overLabel
	 * @type String | Number
	 **/
	p.overLabel = null;

	/**
	 * The label name or frame number to display when the user mouses over the target. Defaults to "out".
	 * @property outLabel
	 * @type String | Number
	 **/
	p.outLabel = null;

	/**
	 * The label name or frame number to display when the user presses (clicks and holds) on the target. Defaults to "press".
	 * @property pressLabel
	 * @type String | Number
	 **/
	p.pressLabel = null;

	/**
	 * If true, then ButtonHelper will call gotoAndPlay, if false, it will use gotoAndStop. Default is false.
	 * @property play
	 * @default false
	 * @type Boolean
	 **/
	p.play = false;

//  private properties
	/**
	 * @property _isPressed
	 * @type Boolean
	 * @protected
	 **/
	p._isPressed = false;

// constructor:
	/**
	 * Initialization method.
	 * @method initialize
	 * @protected
	 **/
	p.initialize = function(target, outLabel, overLabel, pressLabel, play, hitArea, hitLabel) {
		if (!target.addEventListener) { return; }
		this.target = target;
		this.overLabel = overLabel == null ? "over" : overLabel;
		this.outLabel = outLabel == null ? "out" : outLabel;
		this.pressLabel = pressLabel == null ? "press" : pressLabel;
		this.play = play;
		target.cursor = "pointer";
		this.setEnabled(true);
		this._handleEvt({});
		if (hitArea) {
			if (hitLabel) {
				hitArea.actionsEnabled = false;
				hitArea.gotoAndStop(hitLabel);
			}
			target.hitArea = hitArea;
		}
	};

// public methods:
	/**
	 * Enables or disables the button functionality on the target.
	 * @method setEnabled
	 * @param {Boolean} value
	 **/
	p.setEnabled = function(value) {
		var o = this.target;
		var _this = this;
		if (o.addEventListener) {
			var f = _this._handleEvt;
			if (value) {
				o.addEventListener("mouseOver", f, _this);
				o.addEventListener("mouseOut", f, _this);
				o.addEventListener("press", f, _this);
				o.addEventListener("click", f, _this);
			} else {
				o.removeEventListener("mouseOver", f, _this);
				o.removeEventListener("mouseOut", f, _this);
				o.removeEventListener("press", f, _this);
				o.removeEventListener("click", f, _this);
			}
		}
	};

	/**
	 * Returns a string representation of this object.
	 * @method toString
	 * @return {String} a string representation of the instance.
	 **/
	p.toString = function() {
		return "[ButtonHelper]";
	};

// protected methods:
	/**
	 * @method _handleEvt
	 * @protected
	 **/
	p._handleEvt = function(evt) {
		var label = (evt.type == "mouseOver" && !this._isPressed) || evt.type == "click" ? this.overLabel :
				  		(evt.type == "mouseOver" && this._isPressed) || evt.type == "press" ? this.pressLabel :
						this.outLabel;

		if (evt.type == "press") {
			var _this = this;
			this._isPressed = true;
			evt.addEventListener("mouseUp", _this._handleEvt, _this);
		} else if (evt.type == "mouseUp") {
			this._isPressed = false;
			return;
		}

		if (this.play) {
			this.target.gotoAndPlay(label);
		} else {
			this.target.gotoAndStop(label);
		}
	};

createjs.ButtonHelper = ButtonHelper;
}());<|endoftext|>


<commit_before>module.exports = writeStats;

function writeStats(emitter, options) {
    var clientName = options.clientName;
    var statsd = options.statsd;

    emitter.on('makeRequest', onMakeRequest);
    emitter.on('requestTime', onRequestTime);
    emitter.on('statusCode', onStatusCode);
    emitter.on('totalTime', onTotalTime);

    function onMakeRequest(resource) {
        statsd.increment([
            'typed-request-client',
            clientName,
            resource,
            'request'
        ]);
    }

    function onRequestTime(resource, delta) {
        statsd.timing([
            'typed-request-client',
            clientName,
            resource,
            'request-time'
        ], delta);
    }

    function onStatusCode(resource, statusCode) {
        statsd.increment([
            'typed-request-client',
            clientName,
            resource,
            'statusCode',
            statusCode
        ]);
    }

    function onTotalTime(resource, delta) {
        statsd.timing([
            'typed-request-client',
            clientName,
            resource,
            'total-time'
        ]);
    }
}
<commit_msg>pass delta to statsd<commit_after>module.exports = writeStats;

function writeStats(emitter, options) {
    var clientName = options.clientName;
    var statsd = options.statsd;

    emitter.on('makeRequest', onMakeRequest);
    emitter.on('requestTime', onRequestTime);
    emitter.on('statusCode', onStatusCode);
    emitter.on('totalTime', onTotalTime);

    function onMakeRequest(resource) {
        statsd.increment([
            'typed-request-client',
            clientName,
            resource,
            'request'
        ]);
    }

    function onRequestTime(resource, delta) {
        statsd.timing([
            'typed-request-client',
            clientName,
            resource,
            'request-time'
        ], delta);
    }

    function onStatusCode(resource, statusCode) {
        statsd.increment([
            'typed-request-client',
            clientName,
            resource,
            'statusCode',
            statusCode
        ]);
    }

    function onTotalTime(resource, delta) {
        statsd.timing([
            'typed-request-client',
            clientName,
            resource,
            'total-time'
        ], delta);
    }
}
<|endoftext|>


<commit_before> // @todo Build containers automatically at calculated dropoff spots.

var utilities = require('utilities');

StructureKeeperLair.prototype.isDangerous = function () {
    return !this.ticksToSpawn || this.ticksToSpawn < 20;
};

StructureTower.prototype.runLogic = function () {
    var tower = this;

    // Emergency repairs.
    /*var closestDamagedStructure = tower.pos.findClosestByRange(FIND_STRUCTURES, {
        filter: (structure) => {
            if (structure.structureType == STRUCTURE_WALL) {
                return ((structure.pos.getRangeTo(tower) <= 5 && structure.hits < 10000) || structure.hits < 1000) && tower.energy > tower.energyCapacity * 0.7;
            }
            if (structure.structureType == STRUCTURE_RAMPART) {
                return ((structure.pos.getRangeTo(tower) <= 5 && structure.hits < 10000) || structure.hits < 1000) && tower.energy > tower.energyCapacity * 0.7 || structure.hits < 500;
            }
            return (structure.hits < structure.hitsMax - TOWER_POWER_REPAIR) && (structure.hits < structure.hitsMax * 0.2);
        }
    });
    if (closestDamagedStructure) {
        tower.repair(closestDamagedStructure);
    }//*/

    // Attack enemies.
    var closestHostileHealer = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {
        filter: (creep) => {
            for (var i in creep.body) {
                if (creep.body[i].type == HEAL && creep.body[i].hits > 0) {
                    return true;
                }
            }
            return false;
        }
    });
    var closestHostile = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {
        filter: (creep) => creep.isDangerous()
    });
    if (closestHostileHealer) {
        tower.attack(closestHostileHealer);
    }
    else if (closestHostile) {
        tower.attack(closestHostile);
    }

    // Heal friendlies.
    var damaged = tower.pos.findClosestByRange(FIND_MY_CREEPS, {
        filter: (creep) => creep.hits < creep.hitsMax
    });
    if (damaged) {
        tower.heal(damaged);
    }
};

Room.prototype.manageLabs = function () {
    if (this.controller && this.controller.my && this.memory.canPerformReactions && this.memory.currentReaction) {
        var source1 = Game.getObjectById(this.memory.labs.source1);
        var source2 = Game.getObjectById(this.memory.labs.source2);

        var labs = this.memory.labs.reactor;
        if (!labs) return;
        if (typeof labs == 'string') {
            labs = [labs];
            this.memory.labs.reactor = labs;
        }
        for (let i in labs) {
            var reactor = Game.getObjectById(labs[i]);

            if (source1 && source2 && reactor) {
                if (reactor.cooldown <= 0 && source1.mineralType == this.memory.currentReaction[0] && source2.mineralType == this.memory.currentReaction[1]) {
                    reactor.runReaction(source1, source2);
                }
            }
        }
    }
};

var structureManager = {

    /**
     * Determines the amount of available resources in each room.
     */
    getRoomResourceStates: function () {
        var rooms = {};

        for (let roomId in Game.rooms) {
            let room = Game.rooms[roomId];

            let storage = room.storage;
            let terminal = room.terminal;

            if (!room.controller || !room.controller.my || !terminal || !storage) {
                continue;
            }

            let roomData = {
                totalResources: {},
                state: {},
            };

            for (let resourceType in storage.store) {
                roomData.totalResources[resourceType] = storage.store[resourceType];
            }
            for (let resourceType in terminal.store) {
                if (!roomData.totalResources[resourceType]) {
                    roomData.totalResources[resourceType] = 0;
                }
                roomData.totalResources[resourceType] += terminal.store[resourceType];
            }

            for (let resourceType in roomData.totalResources) {
                let amount = roomData.totalResources[resourceType];
                if (resourceType == RESOURCE_ENERGY) {
                    amount /= 2.5;
                }

                if (amount >= 220000) {
                    roomData.state[resourceType] = 'excessive';
                }
                else if (amount >= 30000) {
                    roomData.state[resourceType] = 'high';
                }
                else if (amount >= 10000) {
                    roomData.state[resourceType] = 'medium';
                }
                else {
                    roomData.state[resourceType] = 'low';
                }
            }

            rooms[room.name] = roomData;
        }

        return rooms;
    },

    /**
     * Determines when it makes sense to transport resources between rooms.
     */
    getAvailableTransportRoutes: function (rooms) {
        var options = [];

        for (var roomName in rooms) {
            var roomState = rooms[roomName];

            // Do not try transferring from a room that is already preparing a transfer.
            if (Game.rooms[roomName].memory.fillTerminal) continue;

            for (var resourceType in roomState.state) {
                if (roomState.state[resourceType] == 'high' || roomState.state[resourceType] == 'excessive') {
                    // Look for other rooms that are low on this resource.
                    for (var roomName2 in rooms) {
                        if (!rooms[roomName2].state[resourceType] || rooms[roomName2].state[resourceType] == 'low' || (roomState.state[resourceType] == 'excessive' && (rooms[roomName2].state[resourceType] == 'medium' || rooms[roomName2].state[resourceType] == 'high'))) {
                            // Make sure target has space left.
                            if (_.sum(Game.rooms[roomName2].terminal.store) > Game.rooms[roomName2].terminal.storeCapacity - 5000) {
                                continue;
                            }

                            var option = {
                                priority: 5,
                                weight: (roomState.totalResources[resourceType] - rooms[roomName2].totalResources[resourceType]) / 100000 - Game.map.getRoomLinearDistance(roomName, roomName2),
                                resourceType: resourceType,
                                source: roomName,
                                target: roomName2,
                            };

                            if (rooms[roomName2].state[resourceType] == 'medium') {
                                option.priority--;
                            }

                            //option.priority -= Game.map.getRoomLinearDistance(roomName, roomName2) * 0.5;

                            options.push(option);
                        }
                    }
                }
            }
        }

        return options;
    },

    /**
     * Sets appropriate reactions for each room depending on available resources.
     */
    chooseReactions: function (rooms) {
        for (let roomName in rooms) {
            let room = Game.rooms[roomName];
            let roomData = rooms[roomName];

            if (room.memory.canPerformReactions) {
                // Try to find possible reactions where we have a good amount of resources.
                var bestReaction = null;
                var mostResources = null;
                for (var resourceType in roomData.totalResources) {
                    if (roomData.totalResources[resourceType] > 0 && REACTIONS[resourceType]) {
                        for (var resourceType2 in REACTIONS[resourceType]) {
                            let targetType = REACTIONS[resourceType][resourceType2];
                            if (roomData.totalResources[targetType] > 10000) continue;

                            if (roomData.totalResources[resourceType2] && roomData.totalResources[resourceType2] > 0) {
                                //console.log(resourceType, '+', resourceType2, '=', REACTIONS[resourceType][resourceType2]);
                                var resourceAmount = Math.min(roomData.totalResources[resourceType], roomData.totalResources[resourceType2]);

                                // Also prioritize reactions whose product we don't have much of.
                                resourceAmount -= (roomData.totalResources[targetType] || 0);

                                if (!mostResources || mostResources < resourceAmount) {
                                    mostResources = resourceAmount;
                                    bestReaction = [resourceType, resourceType2];
                                }
                            }
                        }
                    }
                }

                room.memory.currentReaction = bestReaction;
                if (bestReaction) {
                    new Game.logger('labs', roomName).log('now producing', REACTIONS[bestReaction[0]][bestReaction[1]]);
                }
            }
        }
    },

    /**
     * Manages all rooms' resources.
     */
    manageResources: function () {
        let rooms = structureManager.getRoomResourceStates();
        let best = utilities.getBestOption(structureManager.getAvailableTransportRoutes(rooms));

        if (best) {
            let terminal = Game.rooms[best.source].terminal;
            if (terminal.store[best.resourceType] && terminal.store[best.resourceType] > 5000) {
                let result = terminal.send(best.resourceType, 5000, best.target, "Resource equalizing");
                console.log("sending", best.resourceType, "from", best.source, "to", best.target, ":", result);
            }
            else {
                console.log("Preparing 5000", best.resourceType, 'for transport from', best.source, 'to', best.target);
                Game.rooms[best.source].memory.fillTerminal = best.resourceType;
            }
        }

        if (Game.time % 1500 == 981) {
            structureManager.chooseReactions(rooms);
        }
    },

};

module.exports = structureManager;
<commit_msg>include rooms without a storage or terminal in getRoomResourceStates<commit_after> // @todo Build containers automatically at calculated dropoff spots.

var utilities = require('utilities');

StructureKeeperLair.prototype.isDangerous = function () {
    return !this.ticksToSpawn || this.ticksToSpawn < 20;
};

StructureTower.prototype.runLogic = function () {
    var tower = this;

    // Emergency repairs.
    /*var closestDamagedStructure = tower.pos.findClosestByRange(FIND_STRUCTURES, {
        filter: (structure) => {
            if (structure.structureType == STRUCTURE_WALL) {
                return ((structure.pos.getRangeTo(tower) <= 5 && structure.hits < 10000) || structure.hits < 1000) && tower.energy > tower.energyCapacity * 0.7;
            }
            if (structure.structureType == STRUCTURE_RAMPART) {
                return ((structure.pos.getRangeTo(tower) <= 5 && structure.hits < 10000) || structure.hits < 1000) && tower.energy > tower.energyCapacity * 0.7 || structure.hits < 500;
            }
            return (structure.hits < structure.hitsMax - TOWER_POWER_REPAIR) && (structure.hits < structure.hitsMax * 0.2);
        }
    });
    if (closestDamagedStructure) {
        tower.repair(closestDamagedStructure);
    }//*/

    // Attack enemies.
    var closestHostileHealer = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {
        filter: (creep) => {
            for (var i in creep.body) {
                if (creep.body[i].type == HEAL && creep.body[i].hits > 0) {
                    return true;
                }
            }
            return false;
        }
    });
    var closestHostile = tower.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {
        filter: (creep) => creep.isDangerous()
    });
    if (closestHostileHealer) {
        tower.attack(closestHostileHealer);
    }
    else if (closestHostile) {
        tower.attack(closestHostile);
    }

    // Heal friendlies.
    var damaged = tower.pos.findClosestByRange(FIND_MY_CREEPS, {
        filter: (creep) => creep.hits < creep.hitsMax
    });
    if (damaged) {
        tower.heal(damaged);
    }
};

Room.prototype.manageLabs = function () {
    if (this.controller && this.controller.my && this.memory.canPerformReactions && this.memory.currentReaction) {
        var source1 = Game.getObjectById(this.memory.labs.source1);
        var source2 = Game.getObjectById(this.memory.labs.source2);

        var labs = this.memory.labs.reactor;
        if (!labs) return;
        if (typeof labs == 'string') {
            labs = [labs];
            this.memory.labs.reactor = labs;
        }
        for (let i in labs) {
            var reactor = Game.getObjectById(labs[i]);

            if (source1 && source2 && reactor) {
                if (reactor.cooldown <= 0 && source1.mineralType == this.memory.currentReaction[0] && source2.mineralType == this.memory.currentReaction[1]) {
                    reactor.runReaction(source1, source2);
                }
            }
        }
    }
};

var structureManager = {

    /**
     * Determines the amount of available resources in each room.
     */
    getRoomResourceStates: function () {
        var rooms = {};

        for (let roomId in Game.rooms) {
            let room = Game.rooms[roomId];

            let storage = room.storage;
            let terminal = room.terminal;

            if (!room.controller || !room.controller.my) {
                continue;
            }

            let roomData = {
                totalResources: {},
                state: {},
                canTrade: false,
            };
            if (storage && terminal) {
                roomData.canTrade = true;
            }

            if (storage) {
                for (let resourceType in storage.store) {
                    roomData.totalResources[resourceType] = storage.store[resourceType];
                }
            }
            if (terminal) {
                for (let resourceType in terminal.store) {
                    if (!roomData.totalResources[resourceType]) {
                        roomData.totalResources[resourceType] = 0;
                    }
                    roomData.totalResources[resourceType] += terminal.store[resourceType];
                }
            }

            for (let resourceType in roomData.totalResources) {
                let amount = roomData.totalResources[resourceType];
                if (resourceType == RESOURCE_ENERGY) {
                    amount /= 2.5;
                }

                if (amount >= 220000) {
                    roomData.state[resourceType] = 'excessive';
                }
                else if (amount >= 30000) {
                    roomData.state[resourceType] = 'high';
                }
                else if (amount >= 10000) {
                    roomData.state[resourceType] = 'medium';
                }
                else {
                    roomData.state[resourceType] = 'low';
                }
            }

            rooms[room.name] = roomData;
        }

        return rooms;
    },

    /**
     * Determines when it makes sense to transport resources between rooms.
     */
    getAvailableTransportRoutes: function (rooms) {
        var options = [];

        for (var roomName in rooms) {
            var roomState = rooms[roomName];
            if (!roomState.canTrade) continue;

            // Do not try transferring from a room that is already preparing a transfer.
            if (Game.rooms[roomName].memory.fillTerminal) continue;

            for (var resourceType in roomState.state) {
                if (roomState.state[resourceType] == 'high' || roomState.state[resourceType] == 'excessive') {
                    // Look for other rooms that are low on this resource.
                    for (var roomName2 in rooms) {
                        if (!rooms[roomName2].canTrade) continue;

                        if (!rooms[roomName2].state[resourceType] || rooms[roomName2].state[resourceType] == 'low' || (roomState.state[resourceType] == 'excessive' && (rooms[roomName2].state[resourceType] == 'medium' || rooms[roomName2].state[resourceType] == 'high'))) {
                            // Make sure target has space left.
                            if (_.sum(Game.rooms[roomName2].terminal.store) > Game.rooms[roomName2].terminal.storeCapacity - 5000) {
                                continue;
                            }

                            var option = {
                                priority: 5,
                                weight: (roomState.totalResources[resourceType] - rooms[roomName2].totalResources[resourceType]) / 100000 - Game.map.getRoomLinearDistance(roomName, roomName2),
                                resourceType: resourceType,
                                source: roomName,
                                target: roomName2,
                            };

                            if (rooms[roomName2].state[resourceType] == 'medium') {
                                option.priority--;
                            }

                            //option.priority -= Game.map.getRoomLinearDistance(roomName, roomName2) * 0.5;

                            options.push(option);
                        }
                    }
                }
            }
        }

        return options;
    },

    /**
     * Sets appropriate reactions for each room depending on available resources.
     */
    chooseReactions: function (rooms) {
        for (let roomName in rooms) {
            let room = Game.rooms[roomName];
            let roomData = rooms[roomName];

            if (room.memory.canPerformReactions) {
                // Try to find possible reactions where we have a good amount of resources.
                var bestReaction = null;
                var mostResources = null;
                for (var resourceType in roomData.totalResources) {
                    if (roomData.totalResources[resourceType] > 0 && REACTIONS[resourceType]) {
                        for (var resourceType2 in REACTIONS[resourceType]) {
                            let targetType = REACTIONS[resourceType][resourceType2];
                            if (roomData.totalResources[targetType] > 10000) continue;

                            if (roomData.totalResources[resourceType2] && roomData.totalResources[resourceType2] > 0) {
                                //console.log(resourceType, '+', resourceType2, '=', REACTIONS[resourceType][resourceType2]);
                                var resourceAmount = Math.min(roomData.totalResources[resourceType], roomData.totalResources[resourceType2]);

                                // Also prioritize reactions whose product we don't have much of.
                                resourceAmount -= (roomData.totalResources[targetType] || 0);

                                if (!mostResources || mostResources < resourceAmount) {
                                    mostResources = resourceAmount;
                                    bestReaction = [resourceType, resourceType2];
                                }
                            }
                        }
                    }
                }

                room.memory.currentReaction = bestReaction;
                if (bestReaction) {
                    new Game.logger('labs', roomName).log('now producing', REACTIONS[bestReaction[0]][bestReaction[1]]);
                }
            }
        }
    },

    /**
     * Manages all rooms' resources.
     */
    manageResources: function () {
        let rooms = structureManager.getRoomResourceStates();
        let best = utilities.getBestOption(structureManager.getAvailableTransportRoutes(rooms));

        if (best) {
            let terminal = Game.rooms[best.source].terminal;
            if (terminal.store[best.resourceType] && terminal.store[best.resourceType] > 5000) {
                let result = terminal.send(best.resourceType, 5000, best.target, "Resource equalizing");
                new Game.logger('trade').log("sending", best.resourceType, "from", best.source, "to", best.target, ":", result);
            }
            else {
                new Game.logger('trade').log("Preparing 5000", best.resourceType, 'for transport from', best.source, 'to', best.target);
                Game.rooms[best.source].memory.fillTerminal = best.resourceType;
            }
        }

        if (Game.time % 1500 == 981) {
            structureManager.chooseReactions(rooms);
        }
    },

};

module.exports = structureManager;
<|endoftext|>