<commit_before>const { Map, Set, fromJS } = require('immutable')
const Frontend = require('../frontend')
const Backend = require('../backend')

class WatchableDoc {
  constructor (doc) {
    if (!doc) throw new Error("doc argument is required")
    this.doc = doc
    this.handlers = Set()
  }

  get () {
    return this.doc
  }

  set (doc) {
    this.doc = doc
    this.handlers.forEach(handler => handler(doc))
  }

  applyChanges (changes) {
    const oldState = Frontend.getBackendState(this.doc)
    const [newState, patch] = Backend.applyChanges(oldState, changes)
    patch.state = newState
    const newDoc = Frontend.applyPatch(this.doc, patch)
    this.set(newDoc)
    return newDoc
  }

  registerHandler (handler) {
    this.handlers = this.handlers.add(handler)
  }

  unregisterHandler (handler) {
    this.handlers = this.handlers.remove(handler)
  }
}

module.exports = WatchableDoc
<commit_msg>Remove unreferenced imports in watchable_doc<commit_after>const { Set } = require('immutable')
const Frontend = require('../frontend')
const Backend = require('../backend')

class WatchableDoc {
  constructor (doc) {
    if (!doc) throw new Error("doc argument is required")
    this.doc = doc
    this.handlers = Set()
  }

  get () {
    return this.doc
  }

  set (doc) {
    this.doc = doc
    this.handlers.forEach(handler => handler(doc))
  }

  applyChanges (changes) {
    const oldState = Frontend.getBackendState(this.doc)
    const [newState, patch] = Backend.applyChanges(oldState, changes)
    patch.state = newState
    const newDoc = Frontend.applyPatch(this.doc, patch)
    this.set(newDoc)
    return newDoc
  }

  registerHandler (handler) {
    this.handlers = this.handlers.add(handler)
  }

  unregisterHandler (handler) {
    this.handlers = this.handlers.remove(handler)
  }
}

module.exports = WatchableDoc
<|endoftext|>


<commit_before>/** @babel */

import {GitRepositoryAsync, Point} from 'atom'
import path from 'path'
import fs from 'fs-plus'
import GitService from '../../lib/git/git-service'
import GitStore from '../../lib/git/git-store'
import CommitBoxViewModel, {SummaryPreferredLength} from '../../lib/git/commit-box/commit-box-view-model'
import {copyRepository} from './git-helpers'

async function stageFile (repoPath, filePath) {
  const repo = await GitRepositoryAsync.Git.Repository.open(repoPath)
  const index = await repo.index()
  await index.addByPath(filePath)
  return index.write()
}

describe('CommitBoxViewModel', () => {
  let viewModel
  let gitStore
  let gitService
  let repoPath

  beforeEach(async () => {
    repoPath = copyRepository()

    gitService = new GitService(GitRepositoryAsync.open(repoPath))
    gitStore = new GitStore(gitService)
    await gitStore.loadFromGit()

    viewModel = new CommitBoxViewModel(gitStore)
  })

  describe('::getBranchName', () => {
    it('returns the current branch', () => {
      expect(viewModel.getBranchName()).toBe('master')
    })
  })

  describe('::commit', () => {
    const newFileName = 'new-file.txt'

    beforeEach(async () => {
      const newFile = path.join(repoPath, newFileName)
      fs.writeFileSync(newFile, 'my fav file')

      let statuses = await gitService.getStatuses()
      expect(statuses[newFileName]).not.toBeUndefined()
    })

    it('commits the staged changes', async () => {
      await stageFile(repoPath, newFileName)
      await gitStore.loadFromGit()

      await viewModel.commit('hey there')

      const statuses = await gitService.getStatuses()
      expect(statuses[newFileName]).toBeUndefined()
    })

    it("throws an error if there's no commit message", async () => {
      let error = null
      try {
        await viewModel.commit('')
      } catch (e) {
        error = e
      }

      expect(error).not.toBe(null)
      expect(error.name).toBe(CommitBoxViewModel.NoMessageErrorName())
    })

    it('throws an error if there are no staged changes', async () => {
      let error = null
      try {
        await viewModel.commit('hey there')
      } catch (e) {
        error = e
      }

      expect(error).not.toBe(null)
      expect(error.name).toBe(CommitBoxViewModel.NoStagedFilesErrorName())
    })
  })

  describe('.calculateRemainingCharacters', () => {
    const summary = 'hey kids!'
    const description = 'Version control is good and good for you!'
    const msg = `${summary}\n\n${description}`

    describe('when the summary is being edited', () => {
      it('counts down from 50', () => {
        const remaining = viewModel.calculateRemainingCharacters(msg, new Point(0, 0))
        expect(remaining).toBe(SummaryPreferredLength - summary.length)
      })
    })

    describe('when the description is being edited', () => {
      it('is infinite', () => {
        const msg = 'hey kids!\n\nVersion control is good and good for you!'
        const remaining = viewModel.calculateRemainingCharacters(msg, new Point(3, 0))
        expect(isFinite(remaining)).toBe(false)
      })
    })
  })
})
<commit_msg>Fix specs<commit_after>/** @babel */

import {GitRepositoryAsync, Point} from 'atom'
import path from 'path'
import fs from 'fs-plus'
import GitService from '../../lib/git/git-service'
import GitStore from '../../lib/git/git-store'
import CommitBoxViewModel from '../../lib/git/commit-box/commit-box-view-model'
import {copyRepository} from './git-helpers'

async function stageFile (repoPath, filePath) {
  const repo = await GitRepositoryAsync.Git.Repository.open(repoPath)
  const index = await repo.index()
  await index.addByPath(filePath)
  return index.write()
}

describe('CommitBoxViewModel', () => {
  let viewModel
  let gitStore
  let gitService
  let repoPath

  beforeEach(async () => {
    repoPath = copyRepository()

    gitService = new GitService(GitRepositoryAsync.open(repoPath))
    gitStore = new GitStore(gitService)
    await gitStore.loadFromGit()

    viewModel = new CommitBoxViewModel(gitStore)
  })

  describe('::getBranchName', () => {
    it('returns the current branch', () => {
      expect(viewModel.getBranchName()).toBe('master')
    })
  })

  describe('::commit', () => {
    const newFileName = 'new-file.txt'

    beforeEach(async () => {
      const newFile = path.join(repoPath, newFileName)
      fs.writeFileSync(newFile, 'my fav file')

      let statuses = await gitService.getStatuses()
      expect(statuses[newFileName]).not.toBeUndefined()
    })

    it('commits the staged changes', async () => {
      await stageFile(repoPath, newFileName)
      await gitStore.loadFromGit()

      await viewModel.commit('hey there')

      const statuses = await gitService.getStatuses()
      expect(statuses[newFileName]).toBeUndefined()
    })

    it("throws an error if there's no commit message", async () => {
      let error = null
      try {
        await viewModel.commit('')
      } catch (e) {
        error = e
      }

      expect(error).not.toBe(null)
      expect(error.name).toBe(CommitBoxViewModel.NoMessageErrorName())
    })

    it('throws an error if there are no staged changes', async () => {
      let error = null
      try {
        await viewModel.commit('hey there')
      } catch (e) {
        error = e
      }

      expect(error).not.toBe(null)
      expect(error.name).toBe(CommitBoxViewModel.NoStagedFilesErrorName())
    })
  })

  describe('.calculateRemainingCharacters', () => {
    const summary = 'hey kids!'
    const description = 'Version control is good and good for you!'
    const msg = `${summary}\n\n${description}`

    describe('when the summary is being edited', () => {
      it('counts down from 50', () => {
        const remaining = viewModel.calculateRemainingCharacters(msg, new Point(0, 0))
        expect(remaining).toBe(viewModel.getSummaryPreferredLength() - summary.length)
      })
    })

    describe('when the description is being edited', () => {
      it('is infinite', () => {
        const msg = 'hey kids!\n\nVersion control is good and good for you!'
        const remaining = viewModel.calculateRemainingCharacters(msg, new Point(3, 0))
        expect(isFinite(remaining)).toBe(false)
      })
    })
  })
})
<|endoftext|>


<commit_before>window.WebKitServer = {
  nodes            : {},
  nextIndex        : 0,
  lastAttachedFile : "",

  invoke: function() {
    return this[WebKitServerInvocation.functionName].apply(this, WebKitServerInvocation.arguments);
  },

  find: function(selector) {
    return this.findRelativeTo(document, selector);
  },

  findWithin: function(index, selector) {
    return this.findRelativeTo(this.nodes[index], selector);
  },

  findRelativeTo: function(parent, selector) {
    var results  = [],
        elements = parent.querySelectorAll(selector);

    for (var index = 0, length = elements.length; index < length; index++) {
      this.nodes[results.push(++this.nextIndex)] = elements[index];
    }

    return results.join(",");
  },

  isAttached: function(index) {
    return document.evaluate("ancestor-or-self::html", this.nodes[index], null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue != null;
  },

  text: function(index) {
    var node = this.nodes[index],
        type = (node.type || node.tagName).toLowerCase();

    if (type == "textarea") {
      return node.innerHTML;
    } else {
      return node.innerText;
    }
  },

  attribute: function(index, name) {
    switch(name) {
      case "checked":  return this.nodes[index].checked;
      case "disabled": return this.nodes[index].disabled;
      default:         return this.nodes[index].getAttribute(name);
    }
  },

  tagName: function(index) {
    return this.nodes[index].tagName.toLowerCase();
  },

  click: function(index) {
    var clickEvent = document.createEvent("MouseEvents");
    clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    this.nodes[index].dispatchEvent(clickEvent);
  },

  trigger: function(index, eventName) {
    var eventObject = document.createEvent("HTMLEvents");
    eventObject.initEvent(eventName, true, true);
    this.nodes[index].dispatchEvent(eventObject);
  },

  keypress: function(index, altKey, ctrlKey, shiftKey, metaKey, keyCode, charCode) {
    var eventObject = document.createEvent("Events");
    eventObject.initEvent("keypress", true, true);
    eventObject.window = window;
    eventObject.altKey = altKey;
    eventObject.ctrlKey = ctrlKey;
    eventObject.shiftKey = shiftKey;
    eventObject.metaKey = metaKey;
    eventObject.keyCode = keyCode;
    eventObject.charCode = charCode;
    this.nodes[index].dispatchEvent(eventObject);
  },

  visible: function(index) {
    var element = this.nodes[index];

    while (element) {
      if (element.ownerDocument.defaultView.getComputedStyle(element, null).getPropertyValue("display") == "none") {
        return false;
      }

      element = element.parentElement;
    }

    return true;
  },

  selected: function(index) {
    return this.nodes[index].selected;
  },

  value: function(index) {
    return this.nodes[index].value;
  },

  set: function(index, value) {
    var node = this.nodes[index],
        type = (node.type || node.tagName).toLowerCase();

    if (type == "text" || type == "textarea" || type == "password") {
      this.trigger(index, "focus");

      node.value = "";

      var length    = value.length,
          maxLength = this.attribute(index, "maxlength");

      if (maxLength && value.length > maxLength) {
        length = maxLength;
      }

      for (var offset = 0; offset < length; offset++) {
        node.value += value[offset];

        this.trigger(index, "keydown");
        this.keypress(index, false, false, false, false, 0, value[offset]);
        this.trigger(index, "keyup");
      }

      this.trigger(index, "change");
      this.trigger(index, "blur");
    } else if(type == "checkbox" || type == "radio") {
      node.checked = (value == "true");

      this.trigger(index, "click");
      this.trigger(index, "change");
    } else if(type == "file") {
      this.lastAttachedFile = value;
      this.trigger(index, "click");
    } else {
      node.value = value;
    }
  },

  selectOption: function(index) {
    var node = this.nodes[index];

    node.selected = true;
    node.setAttribute("selected", "selected");
    this.trigger(index, "change");
  },

  unselectOption: function(index) {
    var node = this.nodes[index];

    node.selected = false;
    node.removeAttribute("selected");
    this.trigger(index, "change");
  },

  centerPostion: function(element) {
    this.reflow(element);

    var rect     = element.getBoundingClientRect(),
        position = {
          x: rect.width / 2,
          y: rect.height / 2
        };

    do {
      position.x += element.offsetLeft;
      position.y += element.offsetTop;
    } while ((element = element.offsetParent));

    position.x = Math.floor(position.x), position.y = Math.floor(position.y);

    return position;
  },

  reflow: function(element, force) {
    if (force || element.offsetWidth === 0) {
      var property,
          oldStyle = {},
        newStyle = {
          display    : "block",
          position   : "absolute",
          visibility : "hidden",
        };

      for (property in newStyle)  {
        oldStyle[property]      = element.style[property];
        element.style[property] = newStyle[property];
      }

      element.offsetWidth;
      element.offsetHeight;

      for (property in oldStyle) {
        element.style[property] = oldStyle[property];
      }
    }
  },

  dragTo: function(index, targetIndex) {
    var element  = this.nodes[index],
        target   = this.nodes[targetIndex],
        position = this.centerPostion(element),
        options  = {
          clientX: position.x,
          clientY: position.y
        },
        mouseTrigger = function(eventName, options) {
          var eventObject = document.createEvent("MouseEvents");
          eventObject.initMouseEvent(eventName, true, true, window, 0, 0, 0, options.clientX || 0, options.clientY || 0, false, false, false, false, 0, null);
          element.dispatchEvent(eventObject);
        };

    mouseTrigger("mousedown", options);

    options.clientX += 1;
    options.clientY += 1;

    mouseTrigger("mousemove", options);

    position = this.centerPostion(target),
    options  = {
      clientX: position.x,
      clientY: position.y
    };

    mouseTrigger("mousemove", options);
    mouseTrigger("mouseup", options);
  }
};
<commit_msg>Support "email", "search" and "url" as text input types.<commit_after>window.WebKitServer = {
  nodes            : {},
  nextIndex        : 0,
  lastAttachedFile : "",

  invoke: function() {
    return this[WebKitServerInvocation.functionName].apply(this, WebKitServerInvocation.arguments);
  },

  find: function(selector) {
    return this.findRelativeTo(document, selector);
  },

  findWithin: function(index, selector) {
    return this.findRelativeTo(this.nodes[index], selector);
  },

  findRelativeTo: function(parent, selector) {
    var results  = [],
        elements = parent.querySelectorAll(selector);

    for (var index = 0, length = elements.length; index < length; index++) {
      this.nodes[results.push(++this.nextIndex)] = elements[index];
    }

    return results.join(",");
  },

  isAttached: function(index) {
    return document.evaluate("ancestor-or-self::html", this.nodes[index], null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue != null;
  },

  text: function(index) {
    var node = this.nodes[index],
        type = (node.type || node.tagName).toLowerCase();

    if (type == "textarea") {
      return node.innerHTML;
    } else {
      return node.innerText;
    }
  },

  attribute: function(index, name) {
    switch(name) {
      case "checked":  return this.nodes[index].checked;
      case "disabled": return this.nodes[index].disabled;
      default:         return this.nodes[index].getAttribute(name);
    }
  },

  tagName: function(index) {
    return this.nodes[index].tagName.toLowerCase();
  },

  click: function(index) {
    var clickEvent = document.createEvent("MouseEvents");
    clickEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
    this.nodes[index].dispatchEvent(clickEvent);
  },

  trigger: function(index, eventName) {
    var eventObject = document.createEvent("HTMLEvents");
    eventObject.initEvent(eventName, true, true);
    this.nodes[index].dispatchEvent(eventObject);
  },

  keypress: function(index, altKey, ctrlKey, shiftKey, metaKey, keyCode, charCode) {
    var eventObject = document.createEvent("Events");
    eventObject.initEvent("keypress", true, true);
    eventObject.window = window;
    eventObject.altKey = altKey;
    eventObject.ctrlKey = ctrlKey;
    eventObject.shiftKey = shiftKey;
    eventObject.metaKey = metaKey;
    eventObject.keyCode = keyCode;
    eventObject.charCode = charCode;
    this.nodes[index].dispatchEvent(eventObject);
  },

  visible: function(index) {
    var element = this.nodes[index];

    while (element) {
      if (element.ownerDocument.defaultView.getComputedStyle(element, null).getPropertyValue("display") == "none") {
        return false;
      }

      element = element.parentElement;
    }

    return true;
  },

  selected: function(index) {
    return this.nodes[index].selected;
  },

  value: function(index) {
    return this.nodes[index].value;
  },

  set: function(index, value) {
    var node = this.nodes[index],
        type = (node.type || node.tagName).toLowerCase(),
        textTypes = ["email", "password", "search", "text", "textarea", "url"];

    if (textTypes.indexOf(type) !== -1) {
      this.trigger(index, "focus");

      node.value = "";

      var length    = value.length,
          maxLength = this.attribute(index, "maxlength");

      if (maxLength && value.length > maxLength) {
        length = maxLength;
      }

      for (var offset = 0; offset < length; offset++) {
        node.value += value[offset];

        this.trigger(index, "keydown");
        this.keypress(index, false, false, false, false, 0, value[offset]);
        this.trigger(index, "keyup");
      }

      this.trigger(index, "change");
      this.trigger(index, "blur");
    } else if (type == "checkbox" || type == "radio") {
      node.checked = (value == "true");

      this.trigger(index, "click");
      this.trigger(index, "change");
    } else if (type == "file") {
      this.lastAttachedFile = value;
      this.trigger(index, "click");
    } else {
      node.value = value;
    }
  },

  selectOption: function(index) {
    var node = this.nodes[index];

    node.selected = true;
    node.setAttribute("selected", "selected");
    this.trigger(index, "change");
  },

  unselectOption: function(index) {
    var node = this.nodes[index];

    node.selected = false;
    node.removeAttribute("selected");
    this.trigger(index, "change");
  },

  centerPostion: function(element) {
    this.reflow(element);

    var rect     = element.getBoundingClientRect(),
        position = {
          x: rect.width / 2,
          y: rect.height / 2
        };

    do {
      position.x += element.offsetLeft;
      position.y += element.offsetTop;
    } while ((element = element.offsetParent));

    position.x = Math.floor(position.x), position.y = Math.floor(position.y);

    return position;
  },

  reflow: function(element, force) {
    if (force || element.offsetWidth === 0) {
      var property,
          oldStyle = {},
        newStyle = {
          display    : "block",
          position   : "absolute",
          visibility : "hidden",
        };

      for (property in newStyle)  {
        oldStyle[property]      = element.style[property];
        element.style[property] = newStyle[property];
      }

      element.offsetWidth;
      element.offsetHeight;

      for (property in oldStyle) {
        element.style[property] = oldStyle[property];
      }
    }
  },

  dragTo: function(index, targetIndex) {
    var element  = this.nodes[index],
        target   = this.nodes[targetIndex],
        position = this.centerPostion(element),
        options  = {
          clientX: position.x,
          clientY: position.y
        },
        mouseTrigger = function(eventName, options) {
          var eventObject = document.createEvent("MouseEvents");
          eventObject.initMouseEvent(eventName, true, true, window, 0, 0, 0, options.clientX || 0, options.clientY || 0, false, false, false, false, 0, null);
          element.dispatchEvent(eventObject);
        };

    mouseTrigger("mousedown", options);

    options.clientX += 1;
    options.clientY += 1;

    mouseTrigger("mousemove", options);

    position = this.centerPostion(target),
    options  = {
      clientX: position.x,
      clientY: position.y
    };

    mouseTrigger("mousemove", options);
    mouseTrigger("mouseup", options);
  }
};
<|endoftext|>


<commit_before>import {FeatureLayers} from './featureLayers'
import {MapAreaMenu} from './mapAreaMenu'
import {SplitOverlay} from 'widget/split/splitOverlay'
import {compose} from 'compose'
import {selectFrom} from 'stateUtils'
import {withMapAreaContext} from './mapAreaContext'
import {withRecipe} from '../body/process/recipeContext'
import PropTypes from 'prop-types'
import React from 'react'

const mapRecipeToProps = recipe => ({
    areas: selectFrom(recipe, ['layers.areas'])
})

class _MapAreaLayout extends React.Component {
    render() {
        const {mapAreaContext: {area}, form, map, areas} = this.props
        return areas[area]
            ? (
                <React.Fragment>
                    <SplitOverlay area={area}>
                        <MapAreaMenu area={area} form={form}/>
                        <FeatureLayers selectedLayers={areas[area].featureLayers} map={map}/>
                    </SplitOverlay>
                </React.Fragment>
            )
            : null
    }

    componentDidUpdate() {
        const {layer, map} = this.props
        if (!map) {
            return
        }
        const imageLayerId = 'imageLayer'
        if (layer) {
            map.setLayer({id: imageLayerId, layer})
        } else {
            map.removeLayer(imageLayerId)
        }
    }

}

export const MapAreaLayout = compose(
    _MapAreaLayout,
    withMapAreaContext(),
    withRecipe(mapRecipeToProps),
)

MapAreaLayout.propTypes = {
    form: PropTypes.object,
    layer: PropTypes.object,
    map: PropTypes.object
}
<commit_msg>Fixed MapAreaLayout.<commit_after>import {FeatureLayers} from './featureLayers'
import {MapAreaMenu} from './mapAreaMenu'
import {SplitOverlay} from 'widget/split/splitOverlay'
import {compose} from 'compose'
import {selectFrom} from 'stateUtils'
import {withMapAreaContext} from './mapAreaContext'
import {withRecipe} from '../body/process/recipeContext'
import PropTypes from 'prop-types'
import React from 'react'

const mapRecipeToProps = recipe => ({
    areas: selectFrom(recipe, ['layers.areas'])
})

class _MapAreaLayout extends React.Component {
    render() {
        const {mapAreaContext: {area}, form, map, areas} = this.props
        return (
            <React.Fragment>
                <SplitOverlay area={area}>
                    <MapAreaMenu area={area} form={form}/>
                    <FeatureLayers selectedLayers={areas[area].featureLayers} map={map}/>
                </SplitOverlay>
            </React.Fragment>
        )
    }

    componentDidUpdate() {
        const {layer, map} = this.props
        if (!map) {
            return
        }
        const imageLayerId = 'imageLayer'
        if (layer) {
            map.setLayer({id: imageLayerId, layer})
        } else {
            map.removeLayer(imageLayerId)
        }
    }

}

export const MapAreaLayout = compose(
    _MapAreaLayout,
    withRecipe(mapRecipeToProps),
    withMapAreaContext(),
)

MapAreaLayout.propTypes = {
    form: PropTypes.object,
    layer: PropTypes.object,
    map: PropTypes.object
}
<|endoftext|>


<commit_before>goog.provide('gmf.BackgroundlayerselectorController');
goog.provide('gmf.backgroundlayerselectorDirective');

goog.require('gmf');
goog.require('gmf.Themes');
goog.require('ngeo.BackgroundEventType');
goog.require('ngeo.BackgroundLayerMgr');

gmf.module.value('gmfBackgroundlayerselectorTemplateUrl',
    /**
     * @param {angular.JQLite} element Element.
     * @param {angular.Attributes} attrs Attributes.
     * @return {string} Template URL.
     */
    function(element, attrs) {
      var templateUrl = attrs['gmfBackgroundlayerselectorTemplateurl'];
      return templateUrl !== undefined ? templateUrl :
          gmf.baseTemplateUrl + '/backgroundlayerselector.html';
    });

/**
 * Provide a "background layer selector" directive.
 *
 * Example:
 *
 *      <gmf-backgroundlayerselector
 *        gmf-backgroundlayerselector-map="::ctrl.map">
 *        gmf-backgroundlayerselector-select="onBackgroundSelected()">
 *      </gmf-backgroundlayerselector>
 *
 * Used UI metadata:
 *
 *  * thumbnail: The URL used for the icon.
 *
 * @htmlAttribute {ol.Map=} gmf-backgroundlayerselector-map The map.
 * @htmlAttribute {Function} gmf-backgroundlayerselector-select Function called
 *     when a layer was selected by the user.
 * @param {string} gmfBackgroundlayerselectorTemplateUrl Url to template.
 * @return {angular.Directive} The Directive Definition Object.
 * @ngInject
 * @ngdoc directive
 * @ngname gmfBackgroundlayerselector
 */
gmf.backgroundlayerselectorDirective = function(
    gmfBackgroundlayerselectorTemplateUrl) {

  return {
    restrict: 'E',
    scope: {
      'map': '=gmfBackgroundlayerselectorMap',
      'select': '&?gmfBackgroundlayerselectorSelect'
    },
    bindToController: true,
    controller: 'GmfBackgroundlayerselectorController',
    controllerAs: 'ctrl',
    templateUrl: gmfBackgroundlayerselectorTemplateUrl
  };
};

gmf.module.directive('gmfBackgroundlayerselector',
    gmf.backgroundlayerselectorDirective);

/**
 * @constructor
 * @param {ngeo.BackgroundLayerMgr} ngeoBackgroundLayerMgr Background layer
 *     manager.
 * @param {gmf.Themes} gmfThemes Themes service.
 * @export
 * @ngInject
 * @ngdoc controller
 * @ngname GmfBackgroundlayerselectorController
 */
gmf.BackgroundlayerselectorController = function(ngeoBackgroundLayerMgr, gmfThemes) {

  /**
   * @type {ol.Map}
   * @export
   */
  this.map;

  /**
   * Function called when a layer was selected by the user.
   * @type {Function}
   * @export
   */
  this.select;

  /**
   * @type {ol.layer.Base}
   * @export
   */
  this.bgLayer;

  /**
   * @type {Array.<ol.layer.Base>}
   * @export
   */
  this.bgLayers;

  gmfThemes.getBgLayers().then(function(layers) {
    this.bgLayers = layers;
  }.bind(this));

  /**
   * @type {ngeo.BackgroundLayerMgr}
   * @private
   */
  this.backgroundLayerMgr_ = ngeoBackgroundLayerMgr;

  ol.events.listen(
      this.backgroundLayerMgr_,
      ngeo.BackgroundEventType.CHANGE,
      function() {
        this.bgLayer = this.backgroundLayerMgr_.get(this.map);
      },
      this);

};

gmf.module.controller('GmfBackgroundlayerselectorController',
    gmf.BackgroundlayerselectorController);

/**
 * @param {ol.layer.Base} layer Layer.
 * @param {boolean=} opt_silent Do not notify listeners.
 * @export
 */
gmf.BackgroundlayerselectorController.prototype.setLayer = function(
    layer, opt_silent) {
  this.bgLayer = layer;
  this.backgroundLayerMgr_.set(this.map, layer);
  if (!opt_silent && this.select) {
    this.select();
  }
};
<commit_msg>Manage reloading of themes in background layer selector<commit_after>goog.provide('gmf.BackgroundlayerselectorController');
goog.provide('gmf.backgroundlayerselectorDirective');

goog.require('gmf');
goog.require('gmf.Themes');
goog.require('ngeo.BackgroundEventType');
goog.require('ngeo.BackgroundLayerMgr');

gmf.module.value('gmfBackgroundlayerselectorTemplateUrl',
    /**
     * @param {angular.JQLite} element Element.
     * @param {angular.Attributes} attrs Attributes.
     * @return {string} Template URL.
     */
    function(element, attrs) {
      var templateUrl = attrs['gmfBackgroundlayerselectorTemplateurl'];
      return templateUrl !== undefined ? templateUrl :
          gmf.baseTemplateUrl + '/backgroundlayerselector.html';
    });

/**
 * Provide a "background layer selector" directive.
 *
 * Example:
 *
 *      <gmf-backgroundlayerselector
 *        gmf-backgroundlayerselector-map="::ctrl.map">
 *        gmf-backgroundlayerselector-select="onBackgroundSelected()">
 *      </gmf-backgroundlayerselector>
 *
 * Used UI metadata:
 *
 *  * thumbnail: The URL used for the icon.
 *
 * @htmlAttribute {ol.Map=} gmf-backgroundlayerselector-map The map.
 * @htmlAttribute {Function} gmf-backgroundlayerselector-select Function called
 *     when a layer was selected by the user.
 * @param {string} gmfBackgroundlayerselectorTemplateUrl Url to template.
 * @return {angular.Directive} The Directive Definition Object.
 * @ngInject
 * @ngdoc directive
 * @ngname gmfBackgroundlayerselector
 */
gmf.backgroundlayerselectorDirective = function(
    gmfBackgroundlayerselectorTemplateUrl) {

  return {
    restrict: 'E',
    scope: {
      'map': '=gmfBackgroundlayerselectorMap',
      'select': '&?gmfBackgroundlayerselectorSelect'
    },
    bindToController: true,
    controller: 'GmfBackgroundlayerselectorController',
    controllerAs: 'ctrl',
    templateUrl: gmfBackgroundlayerselectorTemplateUrl
  };
};

gmf.module.directive('gmfBackgroundlayerselector',
    gmf.backgroundlayerselectorDirective);

/**
 * @constructor
 * @param {!angular.Scope} $scope Angular scope.
 * @param {ngeo.BackgroundLayerMgr} ngeoBackgroundLayerMgr Background layer
 *     manager.
 * @param {gmf.Themes} gmfThemes Themes service.
 * @export
 * @ngInject
 * @ngdoc controller
 * @ngname GmfBackgroundlayerselectorController
 */
gmf.BackgroundlayerselectorController = function($scope, ngeoBackgroundLayerMgr,
    gmfThemes) {

  /**
   * @type {ol.Map}
   * @export
   */
  this.map;

  /**
   * Function called when a layer was selected by the user.
   * @type {Function}
   * @export
   */
  this.select;

  /**
   * @type {ol.layer.Base}
   * @export
   */
  this.bgLayer;

  /**
   * @type {Array.<ol.layer.Base>}
   * @export
   */
  this.bgLayers;

  /**
   * @type {gmf.Themes}
   * @private
   */
  this.gmfThemes_ = gmfThemes;

  /**
   * @type {Array.<ol.EventsKey>}
   * @export
   */
  this.listenerKeys_ = [];

  this.listenerKeys_.push(ol.events.listen(gmfThemes,
    gmf.ThemesEventType.CHANGE, this.handleThemesChange_, this));

  /**
   * @type {ngeo.BackgroundLayerMgr}
   * @private
   */
  this.backgroundLayerMgr_ = ngeoBackgroundLayerMgr;

  this.listenerKeys_.push(ol.events.listen(
      this.backgroundLayerMgr_,
      ngeo.BackgroundEventType.CHANGE,
      function() {
        this.bgLayer = this.backgroundLayerMgr_.get(this.map);
      },
      this));

  $scope.$on('$destroy', this.handleDestroy_.bind(this));

};

gmf.module.controller('GmfBackgroundlayerselectorController',
    gmf.BackgroundlayerselectorController);

/**
 * Called when the themes changes. Set (or reset) the backround layers.
 * @private
 */
gmf.BackgroundlayerselectorController.prototype.handleThemesChange_ = function() {
  this.gmfThemes_.getBgLayers().then(function(layers) {
    this.bgLayers = layers;
  }.bind(this));
};

/**
 * @param {ol.layer.Base} layer Layer.
 * @param {boolean=} opt_silent Do not notify listeners.
 * @export
 */
gmf.BackgroundlayerselectorController.prototype.setLayer = function(
    layer, opt_silent) {
  this.bgLayer = layer;
  this.backgroundLayerMgr_.set(this.map, layer);
  if (!opt_silent && this.select) {
    this.select();
  }
};

/**
 * @private
 */
gmf.BackgroundlayerselectorController.prototype.handleDestroy_ = function() {
  this.listenerKeys_.forEach(ol.events.unlistenByKey);
  this.listenerKeys_.length = 0;
};
<|endoftext|>


<commit_before>const {ipcMain} = require('electron')
let previousURL
let currentURL
/**
 * @type {Electron.BrowserWindow}
 */
let window
/**
* Initialize windowManager
* @param {Electron.BrowserWindow} broswerWindow - window to manage
*/
function initialize (broswerWindow) {
	window = broswerWindow
}
/**
 * Opens provided url in main window
 * @param {url.URL} url - url to load
 */
function openURL (url) {
	previousURL = currentURL
	currentURL = url
	window.loadURL(url)
}

ipcMain.on('goBack', (event) => {
	if (previousURL !== undefined) {
		window.loadURL(previousURL)
		[currentURL, previousURL] = [previousURL, currentURL]
	}
})

module.exports = {
	initialize: initialize,
	openURL: openURL
}
<commit_msg>fixed back button<commit_after>const {ipcMain} = require('electron')
let history = []
/**
 * @type {Electron.BrowserWindow}
 */
let window
/**
* Initialize windowManager
* @param {Electron.BrowserWindow} broswerWindow - window to manage
*/
function initialize (broswerWindow) {
	window = broswerWindow
}
/**
 * Opens provided url in main window
 * @param {url.URL} url - url to load
 */
function openURL (url) {
	history.push(url)
	window.loadURL(url)
}

ipcMain.on('goBack', (event) => {
	if (history.length > 0) {
		history.pop()
		window.loadURL(history[history.length - 1])
	}
})

module.exports = {
	initialize: initialize,
	openURL: openURL
}
<|endoftext|>


<commit_before>/*jshint white: false, strict: false, plusplus: false, onevar: false,
  nomen: false */
/*global define: false, console: false, window: false, setTimeout: false */

define( function ( require ) {

    return function( engine ) {

        var math = engine.math;

        var Transform = function( options ) {

            option = options || {};

            var _position = math.Vector3( math.vector3.zero );
            Object.defineProperty( this, 'position', {
                get: function() {
                    return math.Vector3( _position );
                },
                set: function( value ) {
                    if( !math.vector3.equal( value, _position ) ) {
                        _position = value;
                        _valid = false;
                    }
                }
            });

            var _rotation = math.Vector3( math.vector3.zero );
            Object.defineProperty( this, 'rotation', {
                get: function() {
                    return math.Vector3( _rotation );
                },
                set: function( value ) {
                    if( !math.vector3.equal( value, _rotation ) ) {
                        _rotation = value;
                        _valid = false;
                    }
                }
            });

            var _scale = new math.Vector3( math.vector3.one );
            Object.defineProperty( this, 'scale', {
                get: function() {
                    return math.Vector3( _scale );
                },
                set: function( value ) {
                    if( !math.vector3.equal( value, _scale ) ) {
                        _scale = value;
                        _valid = false;
                    }
                }
            });

            // True if the cached transform is valid, false otherwise.
            var _valid = true;

            var _absolute = math.transform.fixed( _position, _rotation, _scale );
            var _relative = math.matrix4.inverse( _absolute );

            Object.defineProperty( this, 'absolute', {
                get: function() {
                    if( !_valid ) {
                        _absolute = math.transform.fixed( _position, _rotation, _scale );
                        _relative = math.matrix4.inverse( _absolute );
                        _valid = true;
                    }

                    return _absolute;
                }
            });

            Object.defineProperty( this, 'relative', {
                get: function() {
                    if( !_valid ) {
                        _absolute = math.transform.fixed( _position, _rotation, _scale );
                        _relative = math.matrix4.inverse( _absolute );
                        _valid = true;
                    }

                    return _relative;
                }
            });

        };
        Transform.prototype = new engine.Component({
            type: 'Transform'
        });
        Transform.prototype.constructor = Transform;

        return Transform;

    };

});
<commit_msg>Finished up Transform, for now. Math needs to be finished before I test this.<commit_after>/*jshint white: false, strict: false, plusplus: false, onevar: false,
  nomen: false */
/*global define: false, console: false, window: false, setTimeout: false */

define( function ( require ) {

    return function( engine ) {

        var math = engine.math;

        var Transform = function( options ) {

            option = options || {};
            var that = this;

            var _position = math.Vector3( math.vector3.zero );
            Object.defineProperty( this, 'position', {
                get: function() {
                    return math.Vector3( _position );
                },
                set: function( value ) {
                    if( !math.vector3.equal( value, _position ) ) {
                        _position = value;
                        _valid = false;
                    }
                }
            });

            var _rotation = math.Vector3( math.vector3.zero );
            Object.defineProperty( this, 'rotation', {
                get: function() {
                    return math.Vector3( _rotation );
                },
                set: function( value ) {
                    if( !math.vector3.equal( value, _rotation ) ) {
                        _rotation = value;
                        _valid = false;
                    }
                }
            });

            var _scale = new math.Vector3( math.vector3.one );
            Object.defineProperty( this, 'scale', {
                get: function() {
                    return math.Vector3( _scale );
                },
                set: function( value ) {
                    if( !math.vector3.equal( value, _scale ) ) {
                        _scale = value;
                        _valid = false;
                    }
                }
            });

            var _absolute = null;
            var _relative = null;

            Object.defineProperty( this, 'absolute', {
                get: function() {
                    if( !_absolute ) {
                        math.transform.fixed(   // Compute fixed transform
                                math.vector3.equal( _position, math.vector3.zero ) ? null : _position,
                                math.vector3.equal( _rotation, math.vector3.zero ) ? null : _rotation,
                                math.vector3.equal( _scale, math.vector3.one ) ? null : _scale,
                                _absolute
                        );
                        if( that.owner && that.owner.contains( that.type ) )
                            math.matrix4.multiply( that.owner.find( that.type ).absolute, _absolute, _absolute ); // Apply parent transform
                    }

                    return _absolute;
                }
            });

            Object.defineProperty( this, 'relative', {
                get: function() {
                    if( !_relative ) {
                        if( !_absolute ) {  // Relative transform is computed from the absolute transform, so check it now
                            math.transform.fixed(
                                    math.vector3.equal( _position, math.vector3.zero ) ? null : _position,
                                    math.vector3.equal( _rotation, math.vector3.zero ) ? null : _rotation,
                                    math.vector3.equal( _scale, math.vector3.one ) ? null : _scale,
                                    _absolute
                            );
                        }
                        if( that.owner && that.owner.contains( that.type ) )
                            math.matrix4.multiply( that.owner.find( that.type ).absolute, _absolute, _absolute ); // Apply parent transform
                        math.matrix4.inverse( _absolute, _relative );
                    }

                    return _relative;
                }
            });

            // Events

        };
        Transform.prototype = new engine.Component({
            type: 'Transform'
        });
        Transform.prototype.constructor = Transform;

        return Transform;

    };

});
<|endoftext|>


<commit_before>/**
 * Module dependencies
 */

var util = require('util');
var _ = require('lodash');
_.defaults = require('merge-defaults');

/**
 * humpback-model
 *
 * Usage:
 * `sails generate humpback-model`
 *
 * @description Generates a humpback-model
 * @help See http://links.sailsjs.org/docs/generators
 */

module.exports = {

  /**
   * `before()` is run before executing any of the `targets`
   * defined below.
   *
   * This is where we can validate user input, configure default
   * scope variables, get extra dependencies, and so on.
   *
   * @param  {Object} scope
   * @param  {Function} cb    [callback]
   */

  before: function (scope, cb) {

    // scope.args are the raw command line arguments.
    //
    // e.g. if someone runs:
    // $ sails generate humpback-model user find create update
    // then `scope.args` would be `['user', 'find', 'create', 'update']`

    if (!scope.args[0]) {
      return cb( new Error('Please provide a name for this sails-stripe.') );
    }

    // scope.rootPath is the base path for this generator
    //
    // e.g. if this generator specified the target:
    // './Foobar.md': { copy: 'Foobar.md' }
    //
    // And someone ran this generator from `/Users/dbowie/sailsStuff`,
    // then `/Users/dbowie/sailsStuff/Foobar.md` would be created.

    if (!scope.rootPath) {
      return cb( INVALID_SCOPE_VARIABLE('rootPath') );
    }

    // Attach defaults
    _.defaults(scope, {
      createdAt: new Date()
    });

    // Decide the output filename for use in targets below:
    scope.modelname = scope.args[0].toLowerCase();
    scope.Modelname = scope.args[0].charAt(0).toUpperCase() + scope.args[0].slice(1);
    scope.filename = scope.args[0].charAt(0).toUpperCase() + scope.args[0].slice(1) + '.js';
    // Add other stuff to the scope for use in our templates:
    scope.whatIsThis = 'humpback-model created at '+scope.createdAt;

    // When finished, we trigger a callback with no error
    // to begin generating files/folders as specified by
    // the `targets` below.
    cb();
  },

  /**
   * The files/folders to generate.
   * @type {Object}
   */

  targets: {

    // Usage:
    // './path/to/destination.foo': { someHelper: opts }

    // Creates a dynamically-named file relative to `scope.rootPath`
    // (defined by the `filename` scope variable).
    //
    // The `template` helper reads the specified template, making the
    // entire scope available to it (uses underscore/JST/ejs syntax).
    // Then the file is copied into the specified destination (on the left).
    './assets/app/model/:filename' : {template : 'model.template.js'}

  },

  /**
   * The absolute path to the `templates` for this generator
   * (for use with the `template` helper)
   *
   * @type {String}
   */
  templatesDirectory: require('path').resolve(__dirname, './templates')
};

/**
 * INVALID_SCOPE_VARIABLE()
 *
 * Helper method to put together a nice error about a missing or invalid
 * scope variable. We should always validate any required scope variables
 * to avoid inadvertently smashing someone's filesystem.
 *
 * @param {String} varname [the name of the missing/invalid scope variable]
 * @param {String} details [optional - additional details to display on the console]
 * @param {String} message [optional - override for the default message]
 * @return {Error}
 * @api private
 */

function INVALID_SCOPE_VARIABLE (varname, details, message) {
  var DEFAULT_MESSAGE =
  'Issue encountered in generator "humpback-model":\n'+
  'Missing required scope variable: `%s`"\n' +
  'If you are the author of `humpback-model`, please resolve this '+
  'issue and publish a new patch release.';

  message = (message || DEFAULT_MESSAGE) + (details ? '\n'+details : '');
  message = util.inspect(message, varname);

  return new Error(message);
}
<commit_msg>Update folder location<commit_after>/**
 * Module dependencies
 */

var util = require('util');
var _ = require('lodash');
_.defaults = require('merge-defaults');

/**
 * humpback-model
 *
 * Usage:
 * `sails generate humpback-model`
 *
 * @description Generates a humpback-model
 * @help See http://links.sailsjs.org/docs/generators
 */

module.exports = {

  /**
   * `before()` is run before executing any of the `targets`
   * defined below.
   *
   * This is where we can validate user input, configure default
   * scope variables, get extra dependencies, and so on.
   *
   * @param  {Object} scope
   * @param  {Function} cb    [callback]
   */

  before: function (scope, cb) {

    // scope.args are the raw command line arguments.
    //
    // e.g. if someone runs:
    // $ sails generate humpback-model user find create update
    // then `scope.args` would be `['user', 'find', 'create', 'update']`

    if (!scope.args[0]) {
      return cb( new Error('Please provide a name for this sails-stripe.') );
    }

    // scope.rootPath is the base path for this generator
    //
    // e.g. if this generator specified the target:
    // './Foobar.md': { copy: 'Foobar.md' }
    //
    // And someone ran this generator from `/Users/dbowie/sailsStuff`,
    // then `/Users/dbowie/sailsStuff/Foobar.md` would be created.

    if (!scope.rootPath) {
      return cb( INVALID_SCOPE_VARIABLE('rootPath') );
    }

    // Attach defaults
    _.defaults(scope, {
      createdAt: new Date()
    });

    // Decide the output filename for use in targets below:
    scope.modelname = scope.args[0].toLowerCase();
    scope.Modelname = scope.args[0].charAt(0).toUpperCase() + scope.args[0].slice(1);
    scope.filename = scope.args[0].charAt(0).toUpperCase() + scope.args[0].slice(1) + '.js';
    // Add other stuff to the scope for use in our templates:
    scope.whatIsThis = 'humpback-model created at '+scope.createdAt;

    // When finished, we trigger a callback with no error
    // to begin generating files/folders as specified by
    // the `targets` below.
    cb();
  },

  /**
   * The files/folders to generate.
   * @type {Object}
   */

  targets: {

    // Usage:
    // './path/to/destination.foo': { someHelper: opts }

    // Creates a dynamically-named file relative to `scope.rootPath`
    // (defined by the `filename` scope variable).
    //
    // The `template` helper reads the specified template, making the
    // entire scope available to it (uses underscore/JST/ejs syntax).
    // Then the file is copied into the specified destination (on the left).
    './assets/app/models/:filename' : {template : 'model.template.js'}

  },

  /**
   * The absolute path to the `templates` for this generator
   * (for use with the `template` helper)
   *
   * @type {String}
   */
  templatesDirectory: require('path').resolve(__dirname, './templates')
};

/**
 * INVALID_SCOPE_VARIABLE()
 *
 * Helper method to put together a nice error about a missing or invalid
 * scope variable. We should always validate any required scope variables
 * to avoid inadvertently smashing someone's filesystem.
 *
 * @param {String} varname [the name of the missing/invalid scope variable]
 * @param {String} details [optional - additional details to display on the console]
 * @param {String} message [optional - override for the default message]
 * @return {Error}
 * @api private
 */

function INVALID_SCOPE_VARIABLE (varname, details, message) {
  var DEFAULT_MESSAGE =
  'Issue encountered in generator "humpback-model":\n'+
  'Missing required scope variable: `%s`"\n' +
  'If you are the author of `humpback-model`, please resolve this '+
  'issue and publish a new patch release.';

  message = (message || DEFAULT_MESSAGE) + (details ? '\n'+details : '');
  message = util.inspect(message, varname);

  return new Error(message);
}
<|endoftext|>


<commit_before>import {MetricsPanelCtrl} from 'app/plugins/sdk';
import _ from 'lodash';
import TimeSeries from 'app/core/time_series2';
import kbn from 'app/core/utils/kbn';
import mapRenderer from './map_renderer';
import DataFormatter from './data_formatter';
import decodeGeoHash from './geohash';
import './css/worldmap-panel.css!';

const panelDefaults = {
  mapCenter: '(0°, 0°)',
  mapCenterLatitude: 0,
  mapCenterLongitude: 0,
  initialZoom: 1,
  valueName: 'total',
  circleMinSize: 2,
  circleMaxSize: 30,
  locationData: 'countries',
  thresholds: '0,10',
  colors: ['rgba(245, 54, 54, 0.9)', 'rgba(237, 129, 40, 0.89)', 'rgba(50, 172, 45, 0.97)'],
  unitSingle: '',
  unitPlural: '',
  showLegend: true,
  esMetric: 'Count',
  decimals: 0
};

const mapCenters = {
  '(0°, 0°)': {mapCenterLatitude: 0, mapCenterLongitude: 0},
  'North America': {mapCenterLatitude: 40, mapCenterLongitude: -100},
  'Europe': {mapCenterLatitude: 46, mapCenterLongitude: 14},
  'West Asia': {mapCenterLatitude: 26, mapCenterLongitude: 53},
  'SE Asia': {mapCenterLatitude: 10, mapCenterLongitude: 106}
};

export class WorldmapCtrl extends MetricsPanelCtrl {
  constructor($scope, $injector, contextSrv) {
    super($scope, $injector);

    this.setMapProvider(contextSrv);
    _.defaults(this.panel, panelDefaults);

    this.dataFormatter = new DataFormatter(this, kbn);

    this.events.on('init-edit-mode', this.onInitEditMode.bind(this));
    this.events.on('data-received', this.onDataReceived.bind(this));
    this.events.on('panel-teardown', this.onPanelTeardown.bind(this));
    this.events.on('data-snapshot-load', this.onDataSnapshotLoad.bind(this));

    this.loadLocationDataFromFile();
  }

  setMapProvider(contextSrv) {
    this.tileServer = contextSrv.user.lightTheme ? 'CartoDB Positron' : 'CartoDB Dark';
    this.setMapSaturationClass();
  }

  setMapSaturationClass() {
    if (this.tileServer === 'CartoDB Dark') {
      this.saturationClass = 'map-darken';
    } else {
      this.saturationClass = '';
    }
  }

  loadLocationDataFromFile() {
    if (this.map) return;

    if (this.panel.locationData === 'jsonp endpoint') {
      if (!this.panel.jsonpUrl || !this.panel.jsonpCallback) return;

      window.$.ajax({
        type: 'GET',
        url: this.panel.jsonpUrl + '?callback=?',
        contentType: 'application/json',
        jsonpCallback: this.panel.jsonpCallback,
        dataType: 'jsonp',
        success: (res) => {
          this.locations = res;
          this.render();
        }
      });
    } else if (this.panel.locationData === 'json endpoint') {
      if (!this.panel.jsonUrl) return;

      window.$.getJSON(this.panel.jsonUrl).then(res => {
        this.locations = res;
        this.render();
      });
    } else if (this.panel.locationData === 'influx') {
      //.. Do nothing
    } else if (this.panel.locationData !== 'geohash') {
      window.$.getJSON('public/plugins/grafana-worldmap-panel/data/' + this.panel.locationData + '.json').then(res => {
        this.locations = res;
        this.render();
      });
    }
  }

  onPanelTeardown() {
    if (this.map) this.map.remove();
  }

  onInitEditMode() {
    this.addEditorTab('Worldmap', 'public/plugins/grafana-worldmap-panel/editor.html', 2);
  }

  onDataReceived(dataList) {
    if (!dataList) return;

    console.log('datalist');
    console.log(dataList);
    const data = [];

    if (this.panel.locationData === 'geohash') {
      this.series = dataList.map(this.seriesHandler.bind(this));
      this.setGeohashValues(data);
    } else if (this.panel.locationData === 'influx') {
      this.series = dataList.map(this.tableHandler.bind(this));
      this.setTableValues(data);
    } else {
      this.dataFormatter.setValues(data);
    }

    this.data = data;
    this.updateThresholdData();
    this.render();
  }

  onDataSnapshotLoad(snapshotData) {
    this.onDataReceived(snapshotData);
  }

  setGeohashValues(data) {
    if (!this.panel.esGeoPoint || !this.panel.esMetric) return;

    if (this.series && this.series.length > 0) {
      let highestValue = 0;
      let lowestValue = Number.MAX_VALUE;

      this.series[0].datapoints.forEach(datapoint => {
        const encodedGeohash = datapoint[this.panel.esGeoPoint];
        const decodedGeohash = decodeGeoHash(encodedGeohash);

        const dataValue = {
          key: encodedGeohash,
          locationName: this.panel.esLocationName ? datapoint[this.panel.esLocationName] : encodedGeohash,
          locationLatitude: decodedGeohash.latitude,
          locationLongitude: decodedGeohash.longitude,
          value: datapoint[this.panel.esMetric],
          valueFormatted: datapoint[this.panel.esMetric],
          valueRounded: 0
        };

        if (dataValue.value > highestValue) highestValue = dataValue.value;
        if (dataValue.value < lowestValue) lowestValue = dataValue.value;

        dataValue.valueRounded = kbn.roundValue(dataValue.value, this.panel.decimals || 0);
        data.push(dataValue);
      });

      data.highestValue = highestValue;
      data.lowestValue = lowestValue;
      data.valueRange = highestValue - lowestValue;
    }
  }

  setTableValues(data) {
    if (!this.panel.influxMetric) return;

    if (this.series && this.series.length > 0) {
      let highestValue = 0;
      let lowestValue = Number.MAX_VALUE;

      this.series[0].datapoints.forEach(datapoint => {
        const encodedGeohash = datapoint['geohash'];
        const decodedGeohash = decodeGeoHash(encodedGeohash);

        const dataValue = {
          key: encodedGeohash,
          locationName: datapoint[this.panel.influxLabel] || 'n/a',
          locationLatitude: decodedGeohash.latitude,
          locationLongitude: decodedGeohash.longitude,
          value: datapoint['metric'],
          valueFormatted: datapoint['metric'],
          valueRounded: 0
        };

        if (dataValue.value > highestValue) highestValue = dataValue.value;
        if (dataValue.value < lowestValue) lowestValue = dataValue.value;

        dataValue.valueRounded = kbn.roundValue(dataValue.value, this.panel.decimals || 0);
        data.push(dataValue);
      });

      data.highestValue = highestValue;
      data.lowestValue = lowestValue;
      data.valueRange = highestValue - lowestValue;
    }
  }

  seriesHandler(seriesData) {
    const series = new TimeSeries({
      datapoints: seriesData.datapoints,
      alias: seriesData.target,
    });

    series.flotpairs = series.getFlotPairs(this.panel.nullPointMode);
    return series;
  }

  tableHandler(tableData) {
    const datapoints = [];
    const alias = null;

    console.log('tabel data');
    console.log(tableData);

    if (tableData.type === 'table') {
      const columnNames = {};

      tableData.columns.forEach((column, i) => {
        columnNames[i] = column.text;
      });

      console.log(columnNames);

      tableData.rows.forEach(row => {
        const datapoint = {};

        row.forEach((value, i) => {
          const key = columnNames[i];
          datapoint[key] = value;
        });

        datapoints.push(datapoint);
      });
    }

    console.log('datapoints');
    console.log(datapoints);

    const series = new TimeSeries({ datapoints, alias });
    series.flotpairs = series.getFlotPairs(this.panel.nullPointMode);
    return series;
  }

  setNewMapCenter() {
    if (this.panel.mapCenter !== 'custom') {
      this.panel.mapCenterLatitude = mapCenters[this.panel.mapCenter].mapCenterLatitude;
      this.panel.mapCenterLongitude = mapCenters[this.panel.mapCenter].mapCenterLongitude;
    }
    this.mapCenterMoved = true;
    this.render();
  }

  setZoom() {
    this.map.setZoom(this.panel.initialZoom);
  }

  toggleLegend() {
    if (!this.panel.showLegend) {
      this.map.removeLegend();
    }
    this.render();
  }

  changeThresholds() {
    this.updateThresholdData();
    this.map.legend.update();
    this.render();
  }

  updateThresholdData() {
    this.data.thresholds = this.panel.thresholds.split(',').map(strValue => {
      return Number(strValue.trim());
    });
  }

  changeLocationData() {
    this.loadLocationDataFromFile();

    if (this.panel.locationData === 'geohash') {
      this.render();
    }
  }

  link(scope, elem, attrs, ctrl) {
    mapRenderer(scope, elem, attrs, ctrl);
  }
}

WorldmapCtrl.templateUrl = 'module.html';
<commit_msg>Update worldmap_ctrl.js<commit_after>import {MetricsPanelCtrl} from 'app/plugins/sdk';
import _ from 'lodash';
import TimeSeries from 'app/core/time_series2';
import kbn from 'app/core/utils/kbn';
import mapRenderer from './map_renderer';
import DataFormatter from './data_formatter';
import decodeGeoHash from './geohash';
import './css/worldmap-panel.css!';

const panelDefaults = {
  mapCenter: '(0°, 0°)',
  mapCenterLatitude: 0,
  mapCenterLongitude: 0,
  initialZoom: 1,
  valueName: 'total',
  circleMinSize: 2,
  circleMaxSize: 30,
  locationData: 'countries',
  thresholds: '0,10',
  colors: ['rgba(245, 54, 54, 0.9)', 'rgba(237, 129, 40, 0.89)', 'rgba(50, 172, 45, 0.97)'],
  unitSingle: '',
  unitPlural: '',
  showLegend: true,
  esMetric: 'Count',
  decimals: 0
};

const mapCenters = {
  '(0°, 0°)': {mapCenterLatitude: 0, mapCenterLongitude: 0},
  'North America': {mapCenterLatitude: 40, mapCenterLongitude: -100},
  'Europe': {mapCenterLatitude: 46, mapCenterLongitude: 14},
  'West Asia': {mapCenterLatitude: 26, mapCenterLongitude: 53},
  'SE Asia': {mapCenterLatitude: 10, mapCenterLongitude: 106}
};

export class WorldmapCtrl extends MetricsPanelCtrl {
  constructor($scope, $injector, contextSrv) {
    super($scope, $injector);

    this.setMapProvider(contextSrv);
    _.defaults(this.panel, panelDefaults);

    this.dataFormatter = new DataFormatter(this, kbn);

    this.events.on('init-edit-mode', this.onInitEditMode.bind(this));
    this.events.on('data-received', this.onDataReceived.bind(this));
    this.events.on('panel-teardown', this.onPanelTeardown.bind(this));
    this.events.on('data-snapshot-load', this.onDataSnapshotLoad.bind(this));

    this.loadLocationDataFromFile();
  }

  setMapProvider(contextSrv) {
    this.tileServer = contextSrv.user.lightTheme ? 'CartoDB Positron' : 'CartoDB Dark';
    this.setMapSaturationClass();
  }

  setMapSaturationClass() {
    if (this.tileServer === 'CartoDB Dark') {
      this.saturationClass = 'map-darken';
    } else {
      this.saturationClass = '';
    }
  }

  loadLocationDataFromFile() {
    if (this.map) return;

    if (this.panel.locationData === 'jsonp endpoint') {
      if (!this.panel.jsonpUrl || !this.panel.jsonpCallback) return;

      window.$.ajax({
        type: 'GET',
        url: this.panel.jsonpUrl + '?callback=?',
        contentType: 'application/json',
        jsonpCallback: this.panel.jsonpCallback,
        dataType: 'jsonp',
        success: (res) => {
          this.locations = res;
          this.render();
        }
      });
    } else if (this.panel.locationData === 'json endpoint') {
      if (!this.panel.jsonUrl) return;

      window.$.getJSON(this.panel.jsonUrl).then(res => {
        this.locations = res;
        this.render();
      });
    } else if (this.panel.locationData === 'influx') {
      //.. Do nothing
    } else if (this.panel.locationData !== 'geohash') {
      window.$.getJSON('public/plugins/grafana-worldmap-panel/data/' + this.panel.locationData + '.json').then(res => {
        this.locations = res;
        this.render();
      });
    }
  }

  onPanelTeardown() {
    if (this.map) this.map.remove();
  }

  onInitEditMode() {
    this.addEditorTab('Worldmap', 'public/plugins/grafana-worldmap-panel/editor.html', 2);
  }

  onDataReceived(dataList) {
    if (!dataList) return;

    console.log('datalist');
    console.log(dataList);
    const data = [];

    if (this.panel.locationData === 'geohash') {
      this.series = dataList.map(this.seriesHandler.bind(this));
      this.setGeohashValues(data);
    } else if (this.panel.locationData === 'influx') {
      this.series = dataList.map(this.tableHandler.bind(this));
      this.setTableValues(data);
    } else {
      this.dataFormatter.setValues(data);
    }

    this.data = data;
    this.updateThresholdData();
    this.render();
  }

  onDataSnapshotLoad(snapshotData) {
    this.onDataReceived(snapshotData);
  }

  setGeohashValues(data) {
    if (!this.panel.esGeoPoint || !this.panel.esMetric) return;

    if (this.series && this.series.length > 0) {
      let highestValue = 0;
      let lowestValue = Number.MAX_VALUE;

      this.series[0].datapoints.forEach(datapoint => {
        const encodedGeohash = datapoint[this.panel.esGeoPoint];
        const decodedGeohash = decodeGeoHash(encodedGeohash);

        const dataValue = {
          key: encodedGeohash,
          locationName: this.panel.esLocationName ? datapoint[this.panel.esLocationName] : encodedGeohash,
          locationLatitude: decodedGeohash.latitude,
          locationLongitude: decodedGeohash.longitude,
          value: datapoint[this.panel.esMetric],
          valueFormatted: datapoint[this.panel.esMetric],
          valueRounded: 0
        };

        if (dataValue.value > highestValue) highestValue = dataValue.value;
        if (dataValue.value < lowestValue) lowestValue = dataValue.value;

        dataValue.valueRounded = kbn.roundValue(dataValue.value, this.panel.decimals || 0);
        data.push(dataValue);
      });

      data.highestValue = highestValue;
      data.lowestValue = lowestValue;
      data.valueRange = highestValue - lowestValue;
    }
  }

  setTableValues(data) {
    //if (!this.panel.influxMetric) return;

    if (this.series && this.series.length > 0) {
      let highestValue = 0;
      let lowestValue = Number.MAX_VALUE;

      this.series[0].datapoints.forEach(datapoint => {
        const encodedGeohash = datapoint['geohash'];
        const decodedGeohash = decodeGeoHash(encodedGeohash);

        const dataValue = {
          key: encodedGeohash,
          locationName: datapoint[this.panel.influxLabel] || 'n/a',
          locationLatitude: decodedGeohash.latitude,
          locationLongitude: decodedGeohash.longitude,
          value: datapoint['metric'],
          valueFormatted: datapoint['metric'],
          valueRounded: 0
        };

        if (dataValue.value > highestValue) highestValue = dataValue.value;
        if (dataValue.value < lowestValue) lowestValue = dataValue.value;

        dataValue.valueRounded = kbn.roundValue(dataValue.value, this.panel.decimals || 0);
        data.push(dataValue);
      });

      data.highestValue = highestValue;
      data.lowestValue = lowestValue;
      data.valueRange = highestValue - lowestValue;
    }
  }

  seriesHandler(seriesData) {
    const series = new TimeSeries({
      datapoints: seriesData.datapoints,
      alias: seriesData.target,
    });

    series.flotpairs = series.getFlotPairs(this.panel.nullPointMode);
    return series;
  }

  tableHandler(tableData) {
    const datapoints = [];
    const alias = null;

    console.log('tabel data');
    console.log(tableData);

    if (tableData.type === 'table') {
      const columnNames = {};

      tableData.columns.forEach((column, i) => {
        columnNames[i] = column.text;
      });

      console.log(columnNames);

      tableData.rows.forEach(row => {
        const datapoint = {};

        row.forEach((value, i) => {
          const key = columnNames[i];
          datapoint[key] = value;
        });

        datapoints.push(datapoint);
      });
    }

    console.log('datapoints');
    console.log(datapoints);

    const series = new TimeSeries({ datapoints, alias });
    series.flotpairs = series.getFlotPairs(this.panel.nullPointMode);
    return series;
  }

  setNewMapCenter() {
    if (this.panel.mapCenter !== 'custom') {
      this.panel.mapCenterLatitude = mapCenters[this.panel.mapCenter].mapCenterLatitude;
      this.panel.mapCenterLongitude = mapCenters[this.panel.mapCenter].mapCenterLongitude;
    }
    this.mapCenterMoved = true;
    this.render();
  }

  setZoom() {
    this.map.setZoom(this.panel.initialZoom);
  }

  toggleLegend() {
    if (!this.panel.showLegend) {
      this.map.removeLegend();
    }
    this.render();
  }

  changeThresholds() {
    this.updateThresholdData();
    this.map.legend.update();
    this.render();
  }

  updateThresholdData() {
    this.data.thresholds = this.panel.thresholds.split(',').map(strValue => {
      return Number(strValue.trim());
    });
  }

  changeLocationData() {
    this.loadLocationDataFromFile();

    if (this.panel.locationData === 'geohash') {
      this.render();
    }
  }

  link(scope, elem, attrs, ctrl) {
    mapRenderer(scope, elem, attrs, ctrl);
  }
}

WorldmapCtrl.templateUrl = 'module.html';
<|endoftext|>


<commit_before>var request = require('request');
var async = require('async');
var https = require('https');

var BASE_URL = 'https://news.ycombinator.com/';

module.exports = {

  aliases: ['hn', 'hackernews', 'hacker news'],

  pingAndSend: function (callback) {

    request('http://node-hnapi.herokuapp.com/news', function(err, response, items) {
      if (err || response.statusCode != 200) {
        callback(err);
      }

      items = JSON.parse(items);

      var botPayload = 'Current Hacker News homepage:\n'

      var index = 0;
      async.forEach(items, function(item, cb) {
        var url = item.url;
        if (item.url.startsWith('http')) {
          url = BASE_URL + item.url
        }

        botPayload += '<%url%|%rank%. %title%>\n'
                        .replace('%url%', url)
                        .replace('%rank%', index + 1)
                        .replace('%title%', item.title);
        index++;
        cb();
      }, function(err) {

        var payload = {
          text: botPayload,
          username: 'HackerNews'
        };

        callback(null, payload);
      });
    });

  }

}
<commit_msg>fix the fix<commit_after>var request = require('request');
var async = require('async');
var https = require('https');

var BASE_URL = 'https://news.ycombinator.com/';

module.exports = {

  aliases: ['hn', 'hackernews', 'hacker news'],

  pingAndSend: function (callback) {

    request('http://node-hnapi.herokuapp.com/news', function(err, response, items) {
      if (err || response.statusCode != 200) {
        callback(err);
      }

      items = JSON.parse(items);

      var botPayload = 'Current Hacker News homepage:\n'

      var index = 0;
      async.forEach(items, function(item, cb) {
        var url = item.url;
        if (item.url.indexOf('http') !== 0) {
          url = BASE_URL + item.url
        }

        botPayload += '<%url%|%rank%. %title%>\n'
                        .replace('%url%', url)
                        .replace('%rank%', index + 1)
                        .replace('%title%', item.title);
        index++;
        cb();
      }, function(err) {

        var payload = {
          text: botPayload,
          username: 'HackerNews'
        };

        callback(null, payload);
      });
    });

  }

}
<|endoftext|>


<commit_before>import { Material } from './Material.js';
import { cloneUniforms } from '../renderers/shaders/UniformsUtils.js';

/**
 * @author alteredq / http://alteredqualia.com/
 *
 * parameters = {
 *  defines: { "label" : "value" },
 *  uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } },
 *
 *  fragmentShader: <string>,
 *  vertexShader: <string>,
 *
 *  wireframe: <boolean>,
 *  wireframeLinewidth: <float>,
 *
 *  lights: <bool>,
 *
 *  skinning: <bool>,
 *  morphTargets: <bool>,
 *  morphNormals: <bool>
 * }
 */

function ShaderMaterial( parameters ) {

	Material.call( this );

	this.type = 'ShaderMaterial';

	this.defines = {};
	this.uniforms = {};

	this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}';
	this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}';

	this.linewidth = 1;

	this.wireframe = false;
	this.wireframeLinewidth = 1;

	this.fog = false; // set to use scene fog
	this.lights = false; // set to use scene lights
	this.clipping = false; // set to use user-defined clipping planes

	this.skinning = false; // set to use skinning attribute streams
	this.morphTargets = false; // set to use morph targets
	this.morphNormals = false; // set to use morph normals

	this.extensions = {
		derivatives: false, // set to use derivatives
		fragDepth: false, // set to use fragment depth values
		drawBuffers: false, // set to use draw buffers
		shaderTextureLOD: false // set to use shader texture LOD
	};

	// When rendered geometry doesn't include these attributes but the material does,
	// use these default values in WebGL. This avoids errors when buffer data is missing.
	this.defaultAttributeValues = {
		'color': [ 1, 1, 1 ],
		'uv': [ 0, 0 ],
		'uv2': [ 0, 0 ]
	};

	this.index0AttributeName = undefined;
	this.uniformsNeedUpdate = false;

	if ( parameters !== undefined ) {

		if ( parameters.attributes !== undefined ) {

			console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );

		}

		this.setValues( parameters );

	}

}

ShaderMaterial.prototype = Object.create( Material.prototype );
ShaderMaterial.prototype.constructor = ShaderMaterial;

ShaderMaterial.prototype.isShaderMaterial = true;

ShaderMaterial.prototype.copy = function ( source ) {

	Material.prototype.copy.call( this, source );

	this.fragmentShader = source.fragmentShader;
	this.vertexShader = source.vertexShader;

	this.uniforms = cloneUniforms( source.uniforms );

	this.defines = Object.assign( {}, source.defines );

	this.wireframe = source.wireframe;
	this.wireframeLinewidth = source.wireframeLinewidth;

	this.lights = source.lights;
	this.clipping = source.clipping;

	this.skinning = source.skinning;

	this.morphTargets = source.morphTargets;
	this.morphNormals = source.morphNormals;

	this.extensions = source.extensions;

	return this;

};

ShaderMaterial.prototype.toJSON = function ( meta ) {

	var data = Material.prototype.toJSON.call( this, meta );

	data.uniforms = {};

	for ( var name in this.uniforms ) {

		var uniform = this.uniforms[ name ];
		var value = uniform.value;

		if ( value.isTexture ) {

			data.uniforms[ name ] = {
				type: 't',
				value: value.toJSON( meta ).uuid
			};

		} else if ( value.isColor ) {

			data.uniforms[ name ] = {
				type: 'c',
				value: value.getHex()
			};

		} else if ( value.isVector2 ) {

			data.uniforms[ name ] = {
				type: 'v2',
				value: value.toArray()
			};

		} else if ( value.isVector3 ) {

			data.uniforms[ name ] = {
				type: 'v3',
				value: value.toArray()
			};

		} else if ( value.isVector4 ) {

			data.uniforms[ name ] = {
				type: 'v4',
				value: value.toArray()
			};

		} else if ( value.isMatrix4 ) {

			data.uniforms[ name ] = {
				type: 'm4',
				value: value.toArray()
			};

		} else {

			data.uniforms[ name ] = {
				value: value
			};

			// note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far

		}

	}

	if ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines;

	data.vertexShader = this.vertexShader;
	data.fragmentShader = this.fragmentShader;

	return data;

};

export { ShaderMaterial };
<commit_msg>Null uniform value serialization.<commit_after>import { Material } from './Material.js';
import { cloneUniforms } from '../renderers/shaders/UniformsUtils.js';

/**
 * @author alteredq / http://alteredqualia.com/
 *
 * parameters = {
 *  defines: { "label" : "value" },
 *  uniforms: { "parameter1": { value: 1.0 }, "parameter2": { value2: 2 } },
 *
 *  fragmentShader: <string>,
 *  vertexShader: <string>,
 *
 *  wireframe: <boolean>,
 *  wireframeLinewidth: <float>,
 *
 *  lights: <bool>,
 *
 *  skinning: <bool>,
 *  morphTargets: <bool>,
 *  morphNormals: <bool>
 * }
 */

function ShaderMaterial( parameters ) {

	Material.call( this );

	this.type = 'ShaderMaterial';

	this.defines = {};
	this.uniforms = {};

	this.vertexShader = 'void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}';
	this.fragmentShader = 'void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}';

	this.linewidth = 1;

	this.wireframe = false;
	this.wireframeLinewidth = 1;

	this.fog = false; // set to use scene fog
	this.lights = false; // set to use scene lights
	this.clipping = false; // set to use user-defined clipping planes

	this.skinning = false; // set to use skinning attribute streams
	this.morphTargets = false; // set to use morph targets
	this.morphNormals = false; // set to use morph normals

	this.extensions = {
		derivatives: false, // set to use derivatives
		fragDepth: false, // set to use fragment depth values
		drawBuffers: false, // set to use draw buffers
		shaderTextureLOD: false // set to use shader texture LOD
	};

	// When rendered geometry doesn't include these attributes but the material does,
	// use these default values in WebGL. This avoids errors when buffer data is missing.
	this.defaultAttributeValues = {
		'color': [ 1, 1, 1 ],
		'uv': [ 0, 0 ],
		'uv2': [ 0, 0 ]
	};

	this.index0AttributeName = undefined;
	this.uniformsNeedUpdate = false;

	if ( parameters !== undefined ) {

		if ( parameters.attributes !== undefined ) {

			console.error( 'THREE.ShaderMaterial: attributes should now be defined in THREE.BufferGeometry instead.' );

		}

		this.setValues( parameters );

	}

}

ShaderMaterial.prototype = Object.create( Material.prototype );
ShaderMaterial.prototype.constructor = ShaderMaterial;

ShaderMaterial.prototype.isShaderMaterial = true;

ShaderMaterial.prototype.copy = function ( source ) {

	Material.prototype.copy.call( this, source );

	this.fragmentShader = source.fragmentShader;
	this.vertexShader = source.vertexShader;

	this.uniforms = cloneUniforms( source.uniforms );

	this.defines = Object.assign( {}, source.defines );

	this.wireframe = source.wireframe;
	this.wireframeLinewidth = source.wireframeLinewidth;

	this.lights = source.lights;
	this.clipping = source.clipping;

	this.skinning = source.skinning;

	this.morphTargets = source.morphTargets;
	this.morphNormals = source.morphNormals;

	this.extensions = source.extensions;

	return this;

};

ShaderMaterial.prototype.toJSON = function ( meta ) {

	var data = Material.prototype.toJSON.call( this, meta );

	data.uniforms = {};

	for ( var name in this.uniforms ) {

		var uniform = this.uniforms[ name ];
		var value = uniform.value;

		if ( value && value.isTexture ) {

			data.uniforms[ name ] = {
				type: 't',
				value: value.toJSON( meta ).uuid
			};

		} else if ( value && value.isColor ) {

			data.uniforms[ name ] = {
				type: 'c',
				value: value.getHex()
			};

		} else if ( value && value.isVector2 ) {

			data.uniforms[ name ] = {
				type: 'v2',
				value: value.toArray()
			};

		} else if ( value && value.isVector3 ) {

			data.uniforms[ name ] = {
				type: 'v3',
				value: value.toArray()
			};

		} else if ( value && value.isVector4 ) {

			data.uniforms[ name ] = {
				type: 'v4',
				value: value.toArray()
			};

		} else if ( value && value.isMatrix4 ) {

			data.uniforms[ name ] = {
				type: 'm4',
				value: value.toArray()
			};

		} else {

			data.uniforms[ name ] = {
				value: value
			};

			// note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far

		}

	}

	if ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines;

	data.vertexShader = this.vertexShader;
	data.fragmentShader = this.fragmentShader;

	return data;

};

export { ShaderMaterial };
<|endoftext|>


<commit_before>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var Utils = require('../../renderer/webgl/Utils');

/**
 * Renders this Game Object with the WebGL Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method Phaser.GameObjects.RenderTexture#renderWebGL
 * @since 3.2.0
 * @private
 *
 * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active Canvas renderer.
 * @param {Phaser.GameObjects.RenderTexture} src - The Game Object being rendered in this call.
 * @param {number} interpolationPercentage - Reserved for future use and custom pipelines.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
 */
var RenderTextureWebGLRenderer = function (renderer, src, interpolationPercentage, camera, parentMatrix)
{
    var getTint = Utils.getTintAppendFloatAlpha;

    this.pipeline.batchTexture(
        src,
        src.texture,
        src.texture.width, src.texture.height,
        src.x, src.y,
        src.width, src.height,
        src.scaleX, src.scaleY,
        src.rotation,
        src.flipX, !src.flipY,
        src.scrollFactorX, src.scrollFactorY,
        src.displayOriginX, src.displayOriginY,
        0, 0, src.texture.width, src.texture.height,
        getTint(src._tintTL, camera.alpha * src._alphaTL),
        getTint(src._tintTR, camera.alpha * src._alphaTR),
        getTint(src._tintBL, camera.alpha * src._alphaBL),
        getTint(src._tintBR, camera.alpha * src._alphaBR),
        (src._isTinted && src.tintFill),
        0, 0,
        camera,
        parentMatrix
    );
};

module.exports = RenderTextureWebGLRenderer;
<commit_msg>Blank the texture after drawing<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var Utils = require('../../renderer/webgl/Utils');

/**
 * Renders this Game Object with the WebGL Renderer to the given Camera.
 * The object will not render if any of its renderFlags are set or it is being actively filtered out by the Camera.
 * This method should not be called directly. It is a utility function of the Render module.
 *
 * @method Phaser.GameObjects.RenderTexture#renderWebGL
 * @since 3.2.0
 * @private
 *
 * @param {Phaser.Renderer.WebGL.WebGLRenderer} renderer - A reference to the current active Canvas renderer.
 * @param {Phaser.GameObjects.RenderTexture} src - The Game Object being rendered in this call.
 * @param {number} interpolationPercentage - Reserved for future use and custom pipelines.
 * @param {Phaser.Cameras.Scene2D.Camera} camera - The Camera that is rendering the Game Object.
 * @param {Phaser.GameObjects.Components.TransformMatrix} parentMatrix - This transform matrix is defined if the game object is nested
 */
var RenderTextureWebGLRenderer = function (renderer, src, interpolationPercentage, camera, parentMatrix)
{
    var getTint = Utils.getTintAppendFloatAlpha;

    this.pipeline.batchTexture(
        src,
        src.texture,
        src.texture.width, src.texture.height,
        src.x, src.y,
        src.width, src.height,
        src.scaleX, src.scaleY,
        src.rotation,
        src.flipX, !src.flipY,
        src.scrollFactorX, src.scrollFactorY,
        src.displayOriginX, src.displayOriginY,
        0, 0, src.texture.width, src.texture.height,
        getTint(src._tintTL, camera.alpha * src._alphaTL),
        getTint(src._tintTR, camera.alpha * src._alphaTR),
        getTint(src._tintBL, camera.alpha * src._alphaBL),
        getTint(src._tintBR, camera.alpha * src._alphaBR),
        (src._isTinted && src.tintFill),
        0, 0,
        camera,
        parentMatrix
    );

    //  Force clear the current texture so that items next in the batch (like Graphics) don't try and use it
    renderer.setBlankTexture(true);
};

module.exports = RenderTextureWebGLRenderer;
<|endoftext|>