<commit_before>/**
 * controller.js
 * @flow
 */

import $ from "jquery";
import _ from "lodash";
import app from "app";
import Utils from "libs/utils";
import Backbone from "backbone";
import Stats from "stats.js";
import { InputKeyboardNoLoop } from "libs/input";
import Toast from "libs/toast";
import Model from "oxalis/model";
import Store from "oxalis/store";
import PlaneController from "oxalis/controller/viewmodes/plane_controller";
import SkeletonTracingController from "oxalis/controller/annotations/skeletontracing_controller";
import VolumeTracingController from "oxalis/controller/annotations/volumetracing_controller";
import SkeletonTracingArbitraryController from "oxalis/controller/combinations/skeletontracing_arbitrary_controller";
import SkeletonTracingPlaneController from "oxalis/controller/combinations/skeletontracing_plane_controller";
import VolumeTracingPlaneController from "oxalis/controller/combinations/volumetracing_plane_controller";
import ArbitraryController from "oxalis/controller/viewmodes/arbitrary_controller";
import MinimalSkeletonTracingArbitraryController from "oxalis/controller/combinations/minimal_skeletontracing_arbitrary_controller";
import SceneController from "oxalis/controller/scene_controller";
import UrlManager from "oxalis/controller/url_manager";
import View from "oxalis/view";
import SkeletonTracingView from "oxalis/view/skeletontracing_view";
import VolumeTracingView from "oxalis/view/volumetracing_view";
import constants from "oxalis/constants";
import Request from "libs/request";
import { wkReadyAction } from "oxalis/model/actions/actions";
import { saveNowAction } from "oxalis/model/actions/save_actions";
import messages from "messages";

import type { ToastType } from "libs/toast";
import type { ModeType } from "oxalis/constants";

class Controller {

  model: Model;
  urlManager: UrlManager;
  sceneController: SceneController;
  view: View;
  annotationController: SkeletonTracingController | VolumeTracingController;
  planeController: PlaneController;
  arbitraryController: ArbitraryController;
  zoomStepWarningToast: ToastType;
  keyboardNoLoop: InputKeyboardNoLoop;

  // Copied from backbone events (TODO: handle this better)
  listenTo: Function;

  // Main controller, responsible for setting modes and everything
  // that has to be controlled in any mode.
  //
  // We have a matrix of modes like this:
  //
  //   Annotation Mode \ View mode    Plane       Arbitrary
  //              Skeleton Tracing      X             X
  //                Volume Tracing      X             /
  //
  // In order to maximize code reuse, there is - besides the main
  // controller - a controller for each row, each column and each
  // cross in this matrix.

  constructor(options: Object) {
    this.model = options.model;

    _.extend(this, Backbone.Events);

    this.urlManager = new UrlManager(this.model);
    this.model.set("state", this.urlManager.initialState);

    this.model.fetch()
        .then(() => this.modelFetchDone());
        // .catch((error) => {
        //   // Don't throw errors for errors already handled by the model.
        //   if (error !== this.model.HANDLED_ERROR) {
        //     throw error;
        //   }
        // },
        // );
  }

  modelFetchDone() {
    if (!this.model.tracing.restrictions.allowAccess) {
      Toast.Error("You are not allowed to access this tracing");
      return;
    }

    app.router.on("beforeunload", () => {
      if (this.model.get("controlMode") === constants.CONTROL_MODE_TRACE) {
        if (this.model.volumeTracing != null) {
          const { stateLogger } = this.model.annotationModel;
          if (!stateLogger.stateSaved() && stateLogger.allowUpdate) {
            stateLogger.pushNow();
            return messages["save.leave_page_unfinished"];
          }
        } else {
          const state = Store.getState();
          const stateSaved = !state.save.isBusy && state.save.queue.length === 0;
          if (!stateSaved && state.skeletonTracing.restrictions.allowUpdate) {
            Store.dispatch(saveNowAction());
            return messages["save.leave_page_unfinished"];
          }
        }
      }
      return null;
    });

    this.urlManager.startUrlUpdater();

    this.sceneController = new SceneController(this.model);

    // TODO: Replace with skeletonTracing from Store (which is non-null currently)
    if (this.model.get("controlMode") === constants.CONTROL_MODE_TRACE) {
      if (this.model.volumeTracing != null) {
        // VOLUME MODE
        this.view = new VolumeTracingView(this.model);
        this.annotationController = new VolumeTracingController(
          this.model, this.view, this.sceneController);
        this.planeController = new VolumeTracingPlaneController(
          this.model, this.view, this.sceneController, this.annotationController);
      } else {
        // SKELETONRACING MODE
        this.view = new SkeletonTracingView(this.model);
        this.annotationController = new SkeletonTracingController(
          this.model, this.view, this.sceneController);
        this.planeController = new SkeletonTracingPlaneController(
          this.model, this.view, this.sceneController, this.annotationController);

        const ArbitraryControllerClass = this.model.tracing.content.settings.advancedOptionsAllowed ? SkeletonTracingArbitraryController : MinimalSkeletonTracingArbitraryController;
        this.arbitraryController = new ArbitraryControllerClass(
          this.model, this.view, this.sceneController, this.annotationController);
      }
    } else {
      // VIEW MODE
      this.view = new View(this.model);
      this.planeController = new PlaneController(
        this.model, this.view, this.sceneController);
    }

    // FPS stats
    const stats = new Stats();
    $("body").append(stats.domElement);
    if (this.arbitraryController) { this.listenTo(this.arbitraryController.arbitraryView, "render", () => stats.update()); }
    this.listenTo(this.planeController.planeView, "render", () => stats.update());

    this.initKeyboard();
    this.initTimeLimit();
    this.initTaskScript();

    for (const binaryName of Object.keys(this.model.binary)) {
      this.listenTo(this.model.binary[binaryName].cube, "bucketLoaded", () => app.vent.trigger("rerender"));
    }

    this.listenTo(this.model, "change:mode", this.loadMode);
    this.loadMode(this.model.get("mode"));

    // Zoom step warning
    this.zoomStepWarningToast = null;
    let lastZoomStep = Store.getState().flycam.zoomStep;
    Store.subscribe(() => {
      const { zoomStep } = Store.getState().flycam;
      if (lastZoomStep !== zoomStep) {
        this.onZoomStepChange();
        lastZoomStep = zoomStep;
      }
    });
    this.onZoomStepChange();

    app.vent.trigger("webknossos:ready");
    Store.dispatch(wkReadyAction());
  }

  initTaskScript() {
    // Loads a Gist from GitHub with a user script if there is a
    // script assigned to the task
    if (this.model.tracing.task && this.model.tracing.task.script) {
      const script = this.model.tracing.task.script;
      const gistId = _.last(script.gist.split("/"));

      Request.receiveJSON(`https://api.github.com/gists/${gistId}`).then((gist) => {
        const firstFile = gist.files[Object.keys(gist.files)[0]];

        if (firstFile && firstFile.content) {
          try {
            // eslint-disable-next-line no-eval
            eval(firstFile.content);
          } catch (error) {
            console.error(error);
            Toast.error(`Error executing the task script "${script.name}". See console for more information.`);
          }
        } else {
          Toast.error(`Unable to retrieve script ${script.name}`);
        }
      });
    }
  }

  initKeyboard() {
    // avoid scrolling while pressing space
    $(document).keydown((event) => {
      if ((event.which === 32 || event.which === 18 || event.which >= 37 && event.which <= 40) && !$(":focus").length) { event.preventDefault(); }
    });

    const keyboardControls = {};

    if (this.model.get("controlMode") === constants.CONTROL_MODE_TRACE) {
      _.extend(keyboardControls, {
        // Set Mode, outcomment for release
        "shift + 1": () => this.model.setMode(constants.MODE_PLANE_TRACING),
        "shift + 2": () => this.model.setMode(constants.MODE_ARBITRARY),
        "shift + 3": () => this.model.setMode(constants.MODE_ARBITRARY_PLANE),

        t: () => this.view.toggleTheme(),

        m: () => {
          // rotate allowed modes
          const index = (this.model.allowedModes.indexOf(this.model.get("mode")) + 1) % this.model.allowedModes.length;
          this.model.setMode(this.model.allowedModes[index]);
        },

        "super + s": (event) => {
          event.preventDefault();
          event.stopPropagation();
          this.model.save();
        },

        "ctrl + s": (event) => {
          event.preventDefault();
          event.stopPropagation();
          this.model.save();
        },

      });
    }

    this.keyboardNoLoop = new InputKeyboardNoLoop(keyboardControls);
  }

  loadMode(newMode: ModeType, force: boolean = false) {
    if ((newMode === constants.MODE_ARBITRARY || newMode === constants.MODE_ARBITRARY_PLANE) && (this.model.allowedModes.includes(newMode) || force)) {
      Utils.__guard__(this.planeController, x => x.stop());
      this.arbitraryController.start(newMode);
    } else if ((newMode === constants.MODE_PLANE_TRACING || newMode === constants.MODE_VOLUME) && (this.model.allowedModes.includes(newMode) || force)) {
      Utils.__guard__(this.arbitraryController, x1 => x1.stop());
      this.planeController.start(newMode);
    }
  }

  initTimeLimit() {
    // only enable hard time limit for anonymous users so far
    let model;
    if (!this.model.tracing.task || !this.model.tracing.user.isAnonymous) {
      return;
    }

    // TODO move that somehwere else
    const finishTracing = () => {
      // save the progress
      model = this.model;

      const tracingType = model.volumeTracing;
      tracingType.stateLogger.pushNow().then(() => {
        const url = `/annotations/${model.tracingType}/${model.tracingId}/finishAndRedirect`;
        app.router.loadURL(url);
      });
    };

    // parse hard time limit and convert from min to ms
    const { expectedTime } = this.model.tracing.task.type;
    let timeLimit = (expectedTime.maxHard * 60 * 1000) || 0;

    // setTimeout uses signed 32-bit integers, an overflow would cause immediate timeout execution
    if (timeLimit >= Math.pow(2, 32) / 2) {
      Toast.error("Time limit was reduced as it cannot be bigger than 35791 minutes.");
      timeLimit = (Math.pow(2, 32) / 2) - 1;
    }
    console.log(`TimeLimit is ${timeLimit / 60 / 1000} min`);

    if (timeLimit) {
      setTimeout(() => {
        window.alert("Time limit is reached, thanks for tracing!");
        finishTracing();
      }
      , timeLimit);
    }
  }

  onZoomStepChange() {
    const shouldWarn = !this.model.canDisplaySegmentationData();
    if (shouldWarn && (this.zoomStepWarningToast == null)) {
      const toastType = (this.model.volumeTracing != null) ? "danger" : "info";
      this.zoomStepWarningToast = Toast.message(toastType,
        "Segmentation data and volume tracing is only fully supported at a smaller zoom level.", true);
    } else if (!shouldWarn && (this.zoomStepWarningToast != null)) {
      this.zoomStepWarningToast.remove();
      this.zoomStepWarningToast = null;
    }
  }
}

export default Controller;
<commit_msg>show loading spinners during tracing initialization<commit_after>/**
 * controller.js
 * @flow
 */

import $ from "jquery";
import _ from "lodash";
import app from "app";
import Utils from "libs/utils";
import Backbone from "backbone";
import Stats from "stats.js";
import { InputKeyboardNoLoop } from "libs/input";
import Toast from "libs/toast";
import Model from "oxalis/model";
import Store from "oxalis/store";
import PlaneController from "oxalis/controller/viewmodes/plane_controller";
import SkeletonTracingController from "oxalis/controller/annotations/skeletontracing_controller";
import VolumeTracingController from "oxalis/controller/annotations/volumetracing_controller";
import SkeletonTracingArbitraryController from "oxalis/controller/combinations/skeletontracing_arbitrary_controller";
import SkeletonTracingPlaneController from "oxalis/controller/combinations/skeletontracing_plane_controller";
import VolumeTracingPlaneController from "oxalis/controller/combinations/volumetracing_plane_controller";
import ArbitraryController from "oxalis/controller/viewmodes/arbitrary_controller";
import MinimalSkeletonTracingArbitraryController from "oxalis/controller/combinations/minimal_skeletontracing_arbitrary_controller";
import SceneController from "oxalis/controller/scene_controller";
import UrlManager from "oxalis/controller/url_manager";
import View from "oxalis/view";
import SkeletonTracingView from "oxalis/view/skeletontracing_view";
import VolumeTracingView from "oxalis/view/volumetracing_view";
import constants from "oxalis/constants";
import Request from "libs/request";
import { wkReadyAction } from "oxalis/model/actions/actions";
import { saveNowAction } from "oxalis/model/actions/save_actions";
import messages from "messages";

import type { ToastType } from "libs/toast";
import type { ModeType } from "oxalis/constants";

class Controller {

  model: Model;
  urlManager: UrlManager;
  sceneController: SceneController;
  view: View;
  annotationController: SkeletonTracingController | VolumeTracingController;
  planeController: PlaneController;
  arbitraryController: ArbitraryController;
  zoomStepWarningToast: ToastType;
  keyboardNoLoop: InputKeyboardNoLoop;

  // Copied from backbone events (TODO: handle this better)
  listenTo: Function;

  // Main controller, responsible for setting modes and everything
  // that has to be controlled in any mode.
  //
  // We have a matrix of modes like this:
  //
  //   Annotation Mode \ View mode    Plane       Arbitrary
  //              Skeleton Tracing      X             X
  //                Volume Tracing      X             /
  //
  // In order to maximize code reuse, there is - besides the main
  // controller - a controller for each row, each column and each
  // cross in this matrix.

  constructor(options: Object) {
    app.router.showLoadingSpinner();
    this.model = options.model;

    _.extend(this, Backbone.Events);

    this.urlManager = new UrlManager(this.model);
    this.model.set("state", this.urlManager.initialState);

    this.model.fetch()
        .then(() => this.modelFetchDone());
        // .catch((error) => {
        //   // Don't throw errors for errors already handled by the model.
        //   if (error !== this.model.HANDLED_ERROR) {
        //     throw error;
        //   }
        // },
        // );
  }

  modelFetchDone() {
    if (!this.model.tracing.restrictions.allowAccess) {
      Toast.Error("You are not allowed to access this tracing");
      return;
    }

    app.router.on("beforeunload", () => {
      if (this.model.get("controlMode") === constants.CONTROL_MODE_TRACE) {
        if (this.model.volumeTracing != null) {
          const { stateLogger } = this.model.annotationModel;
          if (!stateLogger.stateSaved() && stateLogger.allowUpdate) {
            stateLogger.pushNow();
            return messages["save.leave_page_unfinished"];
          }
        } else {
          const state = Store.getState();
          const stateSaved = !state.save.isBusy && state.save.queue.length === 0;
          if (!stateSaved && state.skeletonTracing.restrictions.allowUpdate) {
            Store.dispatch(saveNowAction());
            return messages["save.leave_page_unfinished"];
          }
        }
      }
      return null;
    });

    this.urlManager.startUrlUpdater();

    this.sceneController = new SceneController(this.model);

    // TODO: Replace with skeletonTracing from Store (which is non-null currently)
    if (this.model.get("controlMode") === constants.CONTROL_MODE_TRACE) {
      if (this.model.volumeTracing != null) {
        // VOLUME MODE
        this.view = new VolumeTracingView(this.model);
        this.annotationController = new VolumeTracingController(
          this.model, this.view, this.sceneController);
        this.planeController = new VolumeTracingPlaneController(
          this.model, this.view, this.sceneController, this.annotationController);
      } else {
        // SKELETONRACING MODE
        this.view = new SkeletonTracingView(this.model);
        this.annotationController = new SkeletonTracingController(
          this.model, this.view, this.sceneController);
        this.planeController = new SkeletonTracingPlaneController(
          this.model, this.view, this.sceneController, this.annotationController);

        const ArbitraryControllerClass = this.model.tracing.content.settings.advancedOptionsAllowed ? SkeletonTracingArbitraryController : MinimalSkeletonTracingArbitraryController;
        this.arbitraryController = new ArbitraryControllerClass(
          this.model, this.view, this.sceneController, this.annotationController);
      }
    } else {
      // VIEW MODE
      this.view = new View(this.model);
      this.planeController = new PlaneController(
        this.model, this.view, this.sceneController);
    }

    // FPS stats
    const stats = new Stats();
    $("body").append(stats.domElement);
    if (this.arbitraryController) { this.listenTo(this.arbitraryController.arbitraryView, "render", () => stats.update()); }
    this.listenTo(this.planeController.planeView, "render", () => stats.update());

    this.initKeyboard();
    this.initTimeLimit();
    this.initTaskScript();

    for (const binaryName of Object.keys(this.model.binary)) {
      this.listenTo(this.model.binary[binaryName].cube, "bucketLoaded", () => app.vent.trigger("rerender"));
    }

    this.listenTo(this.model, "change:mode", this.loadMode);
    this.loadMode(this.model.get("mode"));

    // Zoom step warning
    this.zoomStepWarningToast = null;
    let lastZoomStep = Store.getState().flycam.zoomStep;
    Store.subscribe(() => {
      const { zoomStep } = Store.getState().flycam;
      if (lastZoomStep !== zoomStep) {
        this.onZoomStepChange();
        lastZoomStep = zoomStep;
      }
    });
    this.onZoomStepChange();

    app.router.hideLoadingSpinner();
    app.vent.trigger("webknossos:ready");
    Store.dispatch(wkReadyAction());
  }

  initTaskScript() {
    // Loads a Gist from GitHub with a user script if there is a
    // script assigned to the task
    if (this.model.tracing.task && this.model.tracing.task.script) {
      const script = this.model.tracing.task.script;
      const gistId = _.last(script.gist.split("/"));

      Request.receiveJSON(`https://api.github.com/gists/${gistId}`).then((gist) => {
        const firstFile = gist.files[Object.keys(gist.files)[0]];

        if (firstFile && firstFile.content) {
          try {
            // eslint-disable-next-line no-eval
            eval(firstFile.content);
          } catch (error) {
            console.error(error);
            Toast.error(`Error executing the task script "${script.name}". See console for more information.`);
          }
        } else {
          Toast.error(`Unable to retrieve script ${script.name}`);
        }
      });
    }
  }

  initKeyboard() {
    // avoid scrolling while pressing space
    $(document).keydown((event) => {
      if ((event.which === 32 || event.which === 18 || event.which >= 37 && event.which <= 40) && !$(":focus").length) { event.preventDefault(); }
    });

    const keyboardControls = {};

    if (this.model.get("controlMode") === constants.CONTROL_MODE_TRACE) {
      _.extend(keyboardControls, {
        // Set Mode, outcomment for release
        "shift + 1": () => this.model.setMode(constants.MODE_PLANE_TRACING),
        "shift + 2": () => this.model.setMode(constants.MODE_ARBITRARY),
        "shift + 3": () => this.model.setMode(constants.MODE_ARBITRARY_PLANE),

        t: () => this.view.toggleTheme(),

        m: () => {
          // rotate allowed modes
          const index = (this.model.allowedModes.indexOf(this.model.get("mode")) + 1) % this.model.allowedModes.length;
          this.model.setMode(this.model.allowedModes[index]);
        },

        "super + s": (event) => {
          event.preventDefault();
          event.stopPropagation();
          this.model.save();
        },

        "ctrl + s": (event) => {
          event.preventDefault();
          event.stopPropagation();
          this.model.save();
        },

      });
    }

    this.keyboardNoLoop = new InputKeyboardNoLoop(keyboardControls);
  }

  loadMode(newMode: ModeType, force: boolean = false) {
    if ((newMode === constants.MODE_ARBITRARY || newMode === constants.MODE_ARBITRARY_PLANE) && (this.model.allowedModes.includes(newMode) || force)) {
      Utils.__guard__(this.planeController, x => x.stop());
      this.arbitraryController.start(newMode);
    } else if ((newMode === constants.MODE_PLANE_TRACING || newMode === constants.MODE_VOLUME) && (this.model.allowedModes.includes(newMode) || force)) {
      Utils.__guard__(this.arbitraryController, x1 => x1.stop());
      this.planeController.start(newMode);
    }
  }

  initTimeLimit() {
    // only enable hard time limit for anonymous users so far
    let model;
    if (!this.model.tracing.task || !this.model.tracing.user.isAnonymous) {
      return;
    }

    // TODO move that somehwere else
    const finishTracing = () => {
      // save the progress
      model = this.model;

      const tracingType = model.volumeTracing;
      tracingType.stateLogger.pushNow().then(() => {
        const url = `/annotations/${model.tracingType}/${model.tracingId}/finishAndRedirect`;
        app.router.loadURL(url);
      });
    };

    // parse hard time limit and convert from min to ms
    const { expectedTime } = this.model.tracing.task.type;
    let timeLimit = (expectedTime.maxHard * 60 * 1000) || 0;

    // setTimeout uses signed 32-bit integers, an overflow would cause immediate timeout execution
    if (timeLimit >= Math.pow(2, 32) / 2) {
      Toast.error("Time limit was reduced as it cannot be bigger than 35791 minutes.");
      timeLimit = (Math.pow(2, 32) / 2) - 1;
    }
    console.log(`TimeLimit is ${timeLimit / 60 / 1000} min`);

    if (timeLimit) {
      setTimeout(() => {
        window.alert("Time limit is reached, thanks for tracing!");
        finishTracing();
      }
      , timeLimit);
    }
  }

  onZoomStepChange() {
    const shouldWarn = !this.model.canDisplaySegmentationData();
    if (shouldWarn && (this.zoomStepWarningToast == null)) {
      const toastType = (this.model.volumeTracing != null) ? "danger" : "info";
      this.zoomStepWarningToast = Toast.message(toastType,
        "Segmentation data and volume tracing is only fully supported at a smaller zoom level.", true);
    } else if (!shouldWarn && (this.zoomStepWarningToast != null)) {
      this.zoomStepWarningToast.remove();
      this.zoomStepWarningToast = null;
    }
  }
}

export default Controller;
<|endoftext|>


<commit_before>/**
 * plugin.js
 *
 * Copyright, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

/*global tinymce:true, console:true */

/**
 * This plugin adds missing events form the 4.x API back. Not every event is
 * properly supported but most things should work.
 *
 * Unsupported things:
 *  - No editor.onEvent
 *  - Can't cancel execCommands with beforeExecCommand
 */
(function(tinymce) {
	var reported;

	function Dispatcher(target, newEventName, argsMap, defaultScope) {
		target = target || this;

		this.add = function(callback, scope) {
			if (!reported && window && window.console) {
				reported = true;
				console.log('Deprecated TinyMCE API call: <target>.on' + newEventName + ".add(..)");
			}

			// Convert callback({arg1:x, arg2:x}) -> callback(arg1, arg2)
			function patchedEventCallback(e) {
				var callbackArgs = [];

				if (typeof argsMap == "string") {
					argsMap = argsMap.split(" ");
				}

				if (argsMap && typeof argsMap != "function") {
					for (var i = 0; i < argsMap.length; i++) {
						callbackArgs.push(e[argsMap[i]]);
					}
				}

				if (typeof argsMap == "function") {
					callbackArgs = argsMap(newEventName, e, target);
					if (!callbackArgs) {
						return;
					}
				}

				if (!argsMap) {
					callbackArgs = [e];
				}

				callbackArgs.unshift(defaultScope || target);

				if (callback.apply(scope || defaultScope || target, callbackArgs) === false) {
					e.stopImmediatePropagation();
				}
			}

			target.on(newEventName, patchedEventCallback);

			return patchedEventCallback;
		};

		// Not supported to just use add
		this.addToTop = this.add;

		this.remove = function(callback) {
			return target.off(newEventName, callback);
		};

		this.dispatch = function() {
			target.fire(newEventName);

			return true;
		};
	}

	tinymce.onBeforeUnload = new Dispatcher(tinymce, "BeforeUnload");
	tinymce.onAddEditor = new Dispatcher(tinymce, "AddEditor", "editor");
	tinymce.onRemoveEditor = new Dispatcher(tinymce, "RemoveEditor", "editor");

	tinymce.PluginManager.add("compat3x", function(editor) {
		function patchEditorEvents(oldEventNames, argsMap) {
			tinymce.each(oldEventNames.split(" "), function(oldName) {
				editor["on" + oldName] = new Dispatcher(editor, oldName, argsMap);
			});
		}

		function convertUndoEventArgs(type, event, target) {
			return [
				event.level,
				target
			];
		}

		function filterSelectionEvents(needsSelection) {
			return function(type, e) {
				if ((!e.selection && !needsSelection) || e.selection == needsSelection) {
					return [e];
				}
			};
		}

		editor.controlManager = {
			buttons: {},

			setDisabled: function(name, state) {
				if (this.buttons[name]) {
					this.buttons[name].disabled(state);
				}
			},

			setActive: function(name, state) {
				if (this.buttons[name]) {
					this.buttons[name].active(state);
				}
			},
		};

		patchEditorEvents("PreInit BeforeRenderUI PostRender Load Init Remove Activate Deactivate", "editor");
		patchEditorEvents("Click MouseUp MouseDown DblClick KeyDown KeyUp KeyPress ContextMenu Paste Submit Reset");
		patchEditorEvents("BeforeExecCommand ExecCommand", "command ui value args"); // args.terminate not supported
		patchEditorEvents("PreProcess PostProcess LoadContent SaveContent Change");
		patchEditorEvents("BeforeSetContent BeforeGetContent SetContent GetContent", filterSelectionEvents(false));
		patchEditorEvents("SetProgressState", "state time");
		patchEditorEvents("VisualAid", "element hasVisual");
		patchEditorEvents("Undo Redo", convertUndoEventArgs);

		patchEditorEvents("NodeChange", function(type, e) {
			return [
				editor.controlManager,
				e.element,
				editor.selection.isCollapsed(),
				e
			];
		});

		var originalAddButton = editor.addButton;
		editor.addButton = function(name, settings) {
			var originalOnPostRender;

			function patchedPostRender() {
				editor.controlManager.buttons[name] = this;

				if (originalOnPostRender) {
					return originalOnPostRender.call(this);
				}
			}

			for (var key in settings) {
				if (key.toLowerCase() === "onpostrender") {
					originalOnPostRender = settings[key];
					settings.onPostRender = patchedPostRender;
				}
			}

			if (!originalOnPostRender) {
				settings.onPostRender = patchedPostRender;
			}

			return originalAddButton.call(this, name, settings);
		};

		editor.on('init', function() {
			var undoManager = editor.undoManager, selection = editor.selection;

			undoManager.onUndo = new Dispatcher(editor, "Undo", convertUndoEventArgs, null, undoManager);
			undoManager.onRedo = new Dispatcher(editor, "Redo", convertUndoEventArgs, null, undoManager);
			undoManager.onBeforeAdd = new Dispatcher(editor, "BeforeAddUndo", null, undoManager);
			undoManager.onAdd = new Dispatcher(editor, "AddUndo", null, undoManager);

			selection.onBeforeGetContent = new Dispatcher(editor, "BeforeGetContent", filterSelectionEvents(true), selection);
			selection.onGetContent = new Dispatcher(editor, "GetContent", filterSelectionEvents(true), selection);
			selection.onBeforeSetContent = new Dispatcher(editor, "BeforeSetContent", filterSelectionEvents(true), selection);
			selection.onSetContent = new Dispatcher(editor, "SetContent", filterSelectionEvents(true), selection);

			editor.windowManager.createInstance = function(className, a, b, c, d, e) {
				var constr = tinymce.resolve(className);

				return new constr(a, b, c, d, e);
			};
		});
	});

	tinymce.addI18n = function(prefix, o) {
		var I18n = tinymce.util.I18n, each = tinymce.each;

		if (typeof(prefix) == "string" && prefix.indexOf('.') === -1) {
			I18n.add(prefix, o);
			return;
		}

		if (!tinymce.is(prefix, 'string')) {
			each(prefix, function(o, lc) {
				each(o, function(o, g) {
					each(o, function(o, k) {
						if (g === 'common') {
							I18n.data[lc + '.' + k] = o;
						} else {
							I18n.data[lc + '.' + g + '.' + k] = o;
						}
					});
				});
			});
		} else {
			each(o, function(o, k) {
				I18n.data[prefix + '.' + k] = o;
			});
		}
	};
})(tinymce);
<commit_msg>Worked more on the compat3x plugin.<commit_after>/**
 * plugin.js
 *
 * Copyright, Moxiecode Systems AB
 * Released under LGPL License.
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

/*global tinymce:true, console:true */

/**
 * This plugin adds missing events form the 4.x API back. Not every event is
 * properly supported but most things should work.
 *
 * Unsupported things:
 *  - No editor.onEvent
 *  - Can't cancel execCommands with beforeExecCommand
 */
(function(tinymce) {
	var reported;

	function log(apiCall) {
		if (!reported && window && window.console) {
			reported = true;
			console.log("Deprecated TinyMCE API call: " + apiCall);
		}
	}

	function Dispatcher(target, newEventName, argsMap, defaultScope) {
		target = target || this;

		this.add = function(callback, scope) {
			log('<target>.on' + newEventName + ".add(..)");

			// Convert callback({arg1:x, arg2:x}) -> callback(arg1, arg2)
			function patchedEventCallback(e) {
				var callbackArgs = [];

				if (typeof argsMap == "string") {
					argsMap = argsMap.split(" ");
				}

				if (argsMap && typeof argsMap != "function") {
					for (var i = 0; i < argsMap.length; i++) {
						callbackArgs.push(e[argsMap[i]]);
					}
				}

				if (typeof argsMap == "function") {
					callbackArgs = argsMap(newEventName, e, target);
					if (!callbackArgs) {
						return;
					}
				}

				if (!argsMap) {
					callbackArgs = [e];
				}

				callbackArgs.unshift(defaultScope || target);

				if (callback.apply(scope || defaultScope || target, callbackArgs) === false) {
					e.stopImmediatePropagation();
				}
			}

			target.on(newEventName, patchedEventCallback);

			return patchedEventCallback;
		};

		// Not supported to just use add
		this.addToTop = this.add;

		this.remove = function(callback) {
			return target.off(newEventName, callback);
		};

		this.dispatch = function() {
			target.fire(newEventName);

			return true;
		};
	}

	tinymce.onBeforeUnload = new Dispatcher(tinymce, "BeforeUnload");
	tinymce.onAddEditor = new Dispatcher(tinymce, "AddEditor", "editor");
	tinymce.onRemoveEditor = new Dispatcher(tinymce, "RemoveEditor", "editor");

	function patchEditor(editor) {
		function patchEditorEvents(oldEventNames, argsMap) {
			tinymce.each(oldEventNames.split(" "), function(oldName) {
				editor["on" + oldName] = new Dispatcher(editor, oldName, argsMap);
			});
		}

		function convertUndoEventArgs(type, event, target) {
			return [
				event.level,
				target
			];
		}

		function filterSelectionEvents(needsSelection) {
			return function(type, e) {
				if ((!e.selection && !needsSelection) || e.selection == needsSelection) {
					return [e];
				}
			};
		}

		if (editor.controlManager) {
			return;
		}

		editor.controlManager = {
			buttons: {},

			setDisabled: function(name, state) {
				log("controlManager.setDisabled(..)");

				if (this.buttons[name]) {
					this.buttons[name].disabled(state);
				}
			},

			setActive: function(name, state) {
				log("controlManager.setActive(..)");

				if (this.buttons[name]) {
					this.buttons[name].active(state);
				}
			},
		};

		patchEditorEvents("PreInit BeforeRenderUI PostRender Load Init Remove Activate Deactivate", "editor");
		patchEditorEvents("Click MouseUp MouseDown DblClick KeyDown KeyUp KeyPress ContextMenu Paste Submit Reset");
		patchEditorEvents("BeforeExecCommand ExecCommand", "command ui value args"); // args.terminate not supported
		patchEditorEvents("PreProcess PostProcess LoadContent SaveContent Change");
		patchEditorEvents("BeforeSetContent BeforeGetContent SetContent GetContent", filterSelectionEvents(false));
		patchEditorEvents("SetProgressState", "state time");
		patchEditorEvents("VisualAid", "element hasVisual");
		patchEditorEvents("Undo Redo", convertUndoEventArgs);

		patchEditorEvents("NodeChange", function(type, e) {
			return [
				editor.controlManager,
				e.element,
				editor.selection.isCollapsed(),
				e
			];
		});

		var originalAddButton = editor.addButton;
		editor.addButton = function(name, settings) {
			var originalOnPostRender;

			function patchedPostRender() {
				editor.controlManager.buttons[name] = this;

				if (originalOnPostRender) {
					return originalOnPostRender.call(this);
				}
			}

			for (var key in settings) {
				if (key.toLowerCase() === "onpostrender") {
					originalOnPostRender = settings[key];
					settings.onPostRender = patchedPostRender;
				}
			}

			if (!originalOnPostRender) {
				settings.onPostRender = patchedPostRender;
			}

			settings.title = tinymce.i18n.translate((editor.settings.language || "en") + "." + settings.title);

			return originalAddButton.call(this, name, settings);
		};

		editor.on('init', function() {
			var undoManager = editor.undoManager, selection = editor.selection;

			undoManager.onUndo = new Dispatcher(editor, "Undo", convertUndoEventArgs, null, undoManager);
			undoManager.onRedo = new Dispatcher(editor, "Redo", convertUndoEventArgs, null, undoManager);
			undoManager.onBeforeAdd = new Dispatcher(editor, "BeforeAddUndo", null, undoManager);
			undoManager.onAdd = new Dispatcher(editor, "AddUndo", null, undoManager);

			selection.onBeforeGetContent = new Dispatcher(editor, "BeforeGetContent", filterSelectionEvents(true), selection);
			selection.onGetContent = new Dispatcher(editor, "GetContent", filterSelectionEvents(true), selection);
			selection.onBeforeSetContent = new Dispatcher(editor, "BeforeSetContent", filterSelectionEvents(true), selection);
			selection.onSetContent = new Dispatcher(editor, "SetContent", filterSelectionEvents(true), selection);

			editor.windowManager.createInstance = function(className, a, b, c, d, e) {
				log("windowManager.createInstance(..)");

				var constr = tinymce.resolve(className);
				return new constr(a, b, c, d, e);
			};
		});
	}

	tinymce.on('SetupEditor', patchEditor);
	tinymce.PluginManager.add("compat3x", patchEditor);

	tinymce.addI18n = function(prefix, o) {
		var I18n = tinymce.util.I18n, each = tinymce.each;

		if (typeof(prefix) == "string" && prefix.indexOf('.') === -1) {
			I18n.add(prefix, o);
			return;
		}

		if (!tinymce.is(prefix, 'string')) {
			each(prefix, function(o, lc) {
				each(o, function(o, g) {
					each(o, function(o, k) {
						if (g === 'common') {
							I18n.data[lc + '.' + k] = o;
						} else {
							I18n.data[lc + '.' + g + '.' + k] = o;
						}
					});
				});
			});
		} else {
			each(o, function(o, k) {
				I18n.data[prefix + '.' + k] = o;
			});
		}
	};
})(tinymce);
<|endoftext|>


<commit_before>var distance = require('turf-distance');
var point = require('turf-point');
var linestring = require('turf-linestring');
var bearing = require('turf-bearing');
var destination = require('turf-destination');

/**
 * Takes a Point and a LineString and calculates the closest Point on the LineString
 *
 * @module turf/point-on-line
 * @category misc
 * @param {LineString} Line to snap to
 * @param {Point} Point to snap from
 * @return {Point} Closest Point on the Line
 * @example
 * var line = {
 *   "type": "Feature",
 *   "properties": {},
 *   "geometry": {
 *     "type": "LineString",
 *     "coordinates": [
 *       [-77.031669, 38.878605],
 *       [-77.029609, 38.881946],
 *       [-77.020339, 38.884084],
 *       [-77.025661, 38.885821],
 *       [-77.021884, 38.889563],
 *       [-77.019824, 38.892368]
 *     ]
 *   }
 * };
 * var pt = {
 *   "type": "Feature",
 *   "properties": {},
 *   "geometry": {
 *     "type": "Point",
 *     "coordinates": [-77.037076, 38.884017]
 *   }
 * };
 *
 * var snapped = turf.pointOnLine(line, pt);
 * snapped.properties['marker-color'] = '#00f'
 *
 * var result = {
 *   "type": "FeatureCollection",
 *   "features": [line, pt, snapped]
 * };
 *
 * //=result
 */

module.exports = function (line, pt) {
  var coords;
  if(line.type === 'Feature') coords = line.geometry.coordinates;
  else if(line.type === 'LineString') coords = line.geometry.coordinates;
  else throw new Error('input must be a LineString Feature or Geometry');

  return pointOnLine(pt, coords);
};

function pointOnLine (pt, coords) {
  var units = 'miles'
  var closestPt = point([Infinity, Infinity], {dist: Infinity});
  for(var i = 0; i < coords.length - 1; i++) {
    var start = point(coords[i])
    var stop = point(coords[i+1])
    //start
    start.properties.dist = distance(pt, start, units);
    //stop
    stop.properties.dist = distance(pt, stop, units);
    //perpendicular
    var direction = bearing(start, stop)
    var perpendicularPt = destination(pt, 1000 , direction + 90, units) // 1000 = gross
    var intersect = lineIntersects(
      pt.geometry.coordinates[0],
      pt.geometry.coordinates[1],
      perpendicularPt.geometry.coordinates[0],
      perpendicularPt.geometry.coordinates[1],
      start.geometry.coordinates[0],
      start.geometry.coordinates[1],
      stop.geometry.coordinates[0],
      stop.geometry.coordinates[1]
      );
    if(!intersect) {
      perpendicularPt = destination(pt, 1000 , direction - 90, units) // 1000 = gross
      intersect = lineIntersects(
        pt.geometry.coordinates[0],
        pt.geometry.coordinates[1],
        perpendicularPt.geometry.coordinates[0],
        perpendicularPt.geometry.coordinates[1],
        start.geometry.coordinates[0],
        start.geometry.coordinates[1],
        stop.geometry.coordinates[0],
        stop.geometry.coordinates[1]
        );
    }
    perpendicularPt.properties.dist = Infinity;
    var intersectPt;
    if(intersect) {
      var intersectPt = point(intersect);
      intersectPt.properties.dist = distance(pt, intersectPt, units);
    }

    if(start.properties.dist < closestPt.properties.dist) {
      closestPt = start;
      closestPt.properties.index = i;
    }
    if(stop.properties.dist < closestPt.properties.dist) {
     closestPt = stop;
     closestPt.properties.index = i;
    }
    if(intersectPt && intersectPt.properties.dist < closestPt.properties.dist){
      closestPt = intersectPt;
      closestPt.properties.index = i;
    }
  }

  return closestPt;
}

// modified from http://jsfiddle.net/justin_c_rounds/Gd2S2/light/
function lineIntersects(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) {
  // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point
  var denominator, a, b, numerator1, numerator2, result = {
    x: null,
    y: null,
    onLine1: false,
    onLine2: false
  };
  denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY));
  if (denominator === 0) {
    if(result.x !== null && result.y !== null) {
      return result;
    } else {
      return false;
    }
  }
  a = line1StartY - line2StartY;
  b = line1StartX - line2StartX;
  numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b);
  numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b);
  a = numerator1 / denominator;
  b = numerator2 / denominator;

  // if we cast these lines infinitely in both directions, they intersect here:
  result.x = line1StartX + (a * (line1EndX - line1StartX));
  result.y = line1StartY + (a * (line1EndY - line1StartY));

  // if line1 is a segment and line2 is infinite, they intersect if:
  if (a > 0 && a < 1) {
    result.onLine1 = true;
  }
  // if line2 is a segment and line1 is infinite, they intersect if:
  if (b > 0 && b < 1) {
    result.onLine2 = true;
  }
  // if line1 and line2 are segments, they intersect if both of the above are true
  if(result.onLine1 && result.onLine2){
    return [result.x, result.y];
  }
  else {
    return false;
  }
}
<commit_msg>Autoreformat<commit_after>var distance = require('turf-distance');
var point = require('turf-point');
var linestring = require('turf-linestring');
var bearing = require('turf-bearing');
var destination = require('turf-destination');

/**
 * Takes a Point and a LineString and calculates the closest Point on the LineString
 *
 * @module turf/point-on-line
 * @category misc
 * @param {LineString} Line to snap to
 * @param {Point} Point to snap from
 * @return {Point} Closest Point on the Line
 * @example
 * var line = {
 *   "type": "Feature",
 *   "properties": {},
 *   "geometry": {
 *     "type": "LineString",
 *     "coordinates": [
 *       [-77.031669, 38.878605],
 *       [-77.029609, 38.881946],
 *       [-77.020339, 38.884084],
 *       [-77.025661, 38.885821],
 *       [-77.021884, 38.889563],
 *       [-77.019824, 38.892368]
 *     ]
 *   }
 * };
 * var pt = {
 *   "type": "Feature",
 *   "properties": {},
 *   "geometry": {
 *     "type": "Point",
 *     "coordinates": [-77.037076, 38.884017]
 *   }
 * };
 *
 * var snapped = turf.pointOnLine(line, pt);
 * snapped.properties['marker-color'] = '#00f'
 *
 * var result = {
 *   "type": "FeatureCollection",
 *   "features": [line, pt, snapped]
 * };
 *
 * //=result
 */

module.exports = function(line, pt) {
  var coords;
  if (line.type === 'Feature') {
    coords = line.geometry.coordinates;
  } else if (line.type === 'LineString') {
    coords = line.geometry.coordinates;
  } else {
    throw new Error('input must be a LineString Feature or Geometry');
  }

  return pointOnLine(pt, coords);
};

function pointOnLine(pt, coords) {
  var units = 'miles';
  var closestPt = point([Infinity, Infinity], {
    dist: Infinity
  });
  for (var i = 0; i < coords.length - 1; i++) {
    var start = point(coords[i]);
    var stop = point(coords[i + 1]);
    //start
    start.properties.dist = distance(pt, start, units);
    //stop
    stop.properties.dist = distance(pt, stop, units);
    //perpendicular
    var direction = bearing(start, stop);
    var perpendicularPt = destination(pt, 1000, direction + 90, units); // 1000 = gross
    var intersect = lineIntersects(
      pt.geometry.coordinates[0],
      pt.geometry.coordinates[1],
      perpendicularPt.geometry.coordinates[0],
      perpendicularPt.geometry.coordinates[1],
      start.geometry.coordinates[0],
      start.geometry.coordinates[1],
      stop.geometry.coordinates[0],
      stop.geometry.coordinates[1]
    );
    if (!intersect) {
      perpendicularPt = destination(pt, 1000, direction - 90, units); // 1000 = gross
      intersect = lineIntersects(
        pt.geometry.coordinates[0],
        pt.geometry.coordinates[1],
        perpendicularPt.geometry.coordinates[0],
        perpendicularPt.geometry.coordinates[1],
        start.geometry.coordinates[0],
        start.geometry.coordinates[1],
        stop.geometry.coordinates[0],
        stop.geometry.coordinates[1]
      );
    }
    perpendicularPt.properties.dist = Infinity;
    var intersectPt;
    if (intersect) {
      var intersectPt = point(intersect);
      intersectPt.properties.dist = distance(pt, intersectPt, units);
    }

    if (start.properties.dist < closestPt.properties.dist) {
      closestPt = start;
      closestPt.properties.index = i;
    }
    if (stop.properties.dist < closestPt.properties.dist) {
      closestPt = stop;
      closestPt.properties.index = i;
    }
    if (intersectPt && intersectPt.properties.dist < closestPt.properties.dist) {
      closestPt = intersectPt;
      closestPt.properties.index = i;
    }
  }

  return closestPt;
}

// modified from http://jsfiddle.net/justin_c_rounds/Gd2S2/light/
function lineIntersects(line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) {
  // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point
  var denominator, a, b, numerator1, numerator2,
    result = {
      x: null,
      y: null,
      onLine1: false,
      onLine2: false
    };
  denominator = ((line2EndY - line2StartY) * (line1EndX - line1StartX)) - ((line2EndX - line2StartX) * (line1EndY - line1StartY));
  if (denominator === 0) {
    if (result.x !== null && result.y !== null) {
      return result;
    } else {
      return false;
    }
  }
  a = line1StartY - line2StartY;
  b = line1StartX - line2StartX;
  numerator1 = ((line2EndX - line2StartX) * a) - ((line2EndY - line2StartY) * b);
  numerator2 = ((line1EndX - line1StartX) * a) - ((line1EndY - line1StartY) * b);
  a = numerator1 / denominator;
  b = numerator2 / denominator;

  // if we cast these lines infinitely in both directions, they intersect here:
  result.x = line1StartX + (a * (line1EndX - line1StartX));
  result.y = line1StartY + (a * (line1EndY - line1StartY));

  // if line1 is a segment and line2 is infinite, they intersect if:
  if (a > 0 && a < 1) {
    result.onLine1 = true;
  }
  // if line2 is a segment and line1 is infinite, they intersect if:
  if (b > 0 && b < 1) {
    result.onLine2 = true;
  }
  // if line1 and line2 are segments, they intersect if both of the above are true
  if (result.onLine1 && result.onLine2) {
    return [result.x, result.y];
  } else {
    return false;
  }
}
<|endoftext|>


<commit_before>var pkg = require('./package.json')

module.exports = {
  root: "./docs",
  title: "Botpress Official Documentation",
  plugins: ["noembed", "sitemap"],
  variables: {
    version: pkg.version
  },
  pluginsConfig: {
    sitemap: {
      hostname: "https://docs.botpress.io/"
    }
  }
}
<commit_msg>Added a few plugins<commit_after>var pkg = require('./package.json')

module.exports = {
  root: "./docs",
  title: "Botpress Official Documentation",
  plugins: ["noembed", "sitemap", "expandable-chapters", "alerts"],
  variables: {
    version: pkg.version
  },
  pluginsConfig: {
    sitemap: {
      hostname: "https://docs.botpress.io/"
    }
  }
}
<|endoftext|>


<commit_before>function applyErrorPrototype(errorType) {
    errorType.prototype = Object.create(Error.prototype, {
        constructor: {
        value: Error,
        enumerable: false,
        writable: true,
        configurable: true
        }
    });

    if (Object.setPrototypeOf) {
        Object.setPrototypeOf(errorType, Error);
    } else {
        // eslint-disable-next-line
        InvalidModelError.__proto__ = Error;
    }
}

module.exports = applyErrorPrototype;
<commit_msg>Fixing syntax error<commit_after>function applyErrorPrototype(errorType) {
    errorType.prototype = Object.create(Error.prototype, {
        constructor: {
        value: Error,
        enumerable: false,
        writable: true,
        configurable: true
        }
    });

    if (Object.setPrototypeOf) {
        Object.setPrototypeOf(errorType, Error);
    } else {
        // eslint-disable-next-line
        errorType.__proto__ = Error;
    }
}

module.exports = applyErrorPrototype;
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import reactDom from 'react-dom'

class Text extends Component {

    render() {

        return (
            //
{this.props.text}

Debugging

strategies when stuff breaks :

read the error

console.log

add a bunch with strings

"what did you expect, what did you get, how do you know you got that"

put in comments to confirm where you've reached in the code

configuration env which helps you debug: e.g. watchify .... --dv

read your tooling docs for sweet trick, talk with friends

write down your error messages

helps you when you see it again

fix your indentation

google

collect keywords

iterate

"rubber ducking"

talking someone through your thinking reveals assumptions

timeboxing

walk away / give it some time

get some fresh eyes on a thing

reinstall your node_modules

try something / break it some more

keep deleting code until something works

whittle back till you're solving one problem

add things in slowly

save points when code is working

git checkout . - you can wipe away all changes since the last commit (doesn't include new files)

pull from master after every commit

        )
    }
}

export default Text
<commit_msg>text file remedy<commit_after>import React, { Component } from 'react'
import reactDom from 'react-dom'

class Text extends Component {

    render() {

        return (
            //
{this.props.text}

Debugging

strategies when stuff breaks :

read the error

console.log

add a bunch with strings

"what did you expect, what did you get, how do you know you got that"

put in comments to confirm where you've reached in the code

configuration env which helps you debug: e.g. watchify .... --dv

read your tooling docs for sweet trick, talk with friends

write down your error messages

helps you when you see it again

fix your indentation

google

collect keywords

iterate

"rubber ducking"

talking someone through your thinking reveals assumptions

timeboxing

walk away / give it some time

get some fresh eyes on a thing

reinstall your node_modules

try something / break it some more

keep deleting code until something works

whittle back till you're solving one problem

add things in slowly

save points when code is working

git checkout . - you can wipe away all changes since the last commit (doesn't include new files)

pull from master after every commit

        )
    }
}

export default Text
<|endoftext|>


<commit_before>import Player from '../Player.js'

const GAMESTATES = {
	INPUT: 'input',
	INFLIGHT: 'inflight',
	BETWEENTURN: 'betweenturn'
};

const DIFFICULTY_WIND_MULTIPLIER = 50;

const DEBUG = true;

export default class Stage extends Phaser.State {

	init() {
		this.gamestate = GAMESTATES.INPUT;

		this.background = null;
		this.bullet = null;
		// this.cannon = null;
		this.land = null;
		this.arrow = null;

		this.blastRadius = 50;

		// Player shooting Power and angle bounds
		this.minPower = 250;
		this.maxPower = 1000;
		this.minAngle = 10;
		this.maxAngle = 170;

		// disable texture filtering
		this.game.renderer.renderSession.roundPixels = true;

		// TODO: Hardcoded values need to be changed to values received from server
		this.distanceFromSide = 200;
		this.distanceFromBottom = 300;
		this.players = []
		this.playerTurn = 0;
		this.currentPlayer;

		this.manager = CastleCrush.GameManager;
		this.options = {
			difficulty: this.manager.difficulty,
			players: [this.manager.player1, this.manager.player2]
		};
		console.log("Game started with options: \n", this.options);
		this.maxWindPower = Math.abs(this.options.difficulty) * DIFFICULTY_WIND_MULTIPLIER;

		// set Arcade physics
		this.physics.startSystem(Phaser.Physics.ARCADE);
		this.physics.arcade.gravity.y = 300;
		this.physics.arcade.gravity.x = this.rnd.integerInRange(-this.maxWindPower, this.maxWindPower);
	}

	preload() {

		// preload assets
		this.load.image('background', 'public/assets/background_sky.png');
		this.load.image('tank', 'public/assets/tanks_tankGrey_body5.png');
		this.load.image('castle_blue', 'public/assets/BurgBlau.png');
		this.load.image('castle_red', 'public/assets/BurgRot.png');
		this.load.image('turret', 'public/assets/Kanone.png');
		this.load.image('bullet', 'public/assets/tank_bullet2.png');
		this.load.image('land', 'public/assets/land.png');
		this.load.image('landscape', 'public/assets/landscape.png');
		this.load.image('arrow', 'public/assets/tank_arrowFull.png');
		this.load.image('wheel', 'public/assets/Rad.png');
	}

	create() {
		console.log("Stage loaded.");

		// set background image and scale it to the screensize
		this.background = this.add.image(0,0,'landscape');
		this.background.height = this.world.height;
		this.background.width = this.world.width;

		// create a bullet and add physics to it.
		// bullet does not exist in game when created. Shooting the bullet will
		// set it to exist.
		this.bullet = this.add.sprite(this.world.centerX,this.world.centerY,
			'bullet');
		this.bullet.exists = false;
		this.bullet.anchor.setTo(1,0.5);
		this.physics.arcade.enable(this.bullet);

		// DEBUG Create a FPS Counter in the top left corner
		this.fpsText = this.add.text(8, 8, '', { font: "30px Arial",
			fill: "#000000" });
		this.windText = this.add.text(8, 46, '', { font: "30px Arial",
			fill: "#000000" });
		this.debugText = this.add.text(8, 84, '', { font: "30px Arial",
			fill: "#000000" });

		// Creates land bitmap data, scales it relative to the world size and
		// draws it on screen
		this.land = this.add.bitmapData(1920, 1080);
		this.land.draw('land');
		this.land.update();
		this.landScaling = this.world.width/ this.land.width; // assumes 16:9

		// Convert to sprite to enable collision detection
		this.landSprite = this.add.sprite(0,0, this.land);
		this.landSprite.scale.setTo(this.landScaling);
		// this.physics.arcade.enable(this.landSprite);
		// this.landSprite.body.allowGravity = false;
		console.log("Added land with scaling: ", this.landScaling);

		// Indicator arrow
		this.arrow = this.add.image(0,10, 'arrow')
		this.arrow.anchor.setTo(1,0.5);
		this.arrow.scale.setTo(this.landScaling);
		// this.arrow.width = 0.5 * this.arrow.width;
		// this.arrow.height = 0.5 * this.arrow.height;
		this.arrow.angle = -90;
		this.arrow.exists = false;

		// ShotIndicator
		this.g = this.add.graphics(100, 100);
		this.g.lineStyle(3, 0xAA0000, 1);
		this.g.lineTo(150, 0);

		// Create the players and put them into position
		this.players = [
			new Player(
				this.game,
				this.options.players[0],
				this.distanceFromSide,
				this.world.height - this.distanceFromBottom
			),
			new Player(
				this.game,
				this.options.players[1],
				this.world.width - this.distanceFromSide,
				this.world.height - this.distanceFromBottom, false
			)
		];
		this.players.forEach((player) => {
			player.scale.setTo(0.6 * this.landScaling);
			this.physics.arcade.enable(player);
			this.add.existing(player);
			player.body.allowGravity = false;
		})

		this.currentPlayer = this.players[0];

		// line display for touch controls
		this.lastState = false;
		this.pLine = new Phaser.Line();
		this.gLine = this.add.graphics(0,0);
		this.gLine.lineStyle(3, 0x0000ff, 1);
	}

	testFunc(x,y) {
		console.log(x,y)
	}

	update() {
		if (DEBUG) {
			this.updateDebugText();
			// this.game.debug.body(this.players[0]);
			// this.game.debug.body(this.players[1]);
			// this.game.debug.body(this.bullet);
		}

		if (this.gamestate === GAMESTATES.INPUT) {
			this.playerInput();
			this.updateShotIndicator();
		}
		else if (this.gamestate === GAMESTATES.INFLIGHT) {
			this.bulletVsLand();
			this.physics.arcade.overlap(this.bullet, this.players[0], this.testFunc, null, this);
		}
		else if (this.gamestate === GAMESTATES.BETWEENTURN) {
			// recalculate wind check gameoverstate
			this.physics.arcade.gravity.x = this.rnd.integerInRange(-this.maxWindPower, this.maxWindPower);
			this.playerTurn = (this.playerTurn + 1) % this.players.length;
			console.log('Next Player: ' + this.playerTurn);
			this.currentPlayer = this.players[this.playerTurn];

			this.gamestate = GAMESTATES.INPUT;
		}
	}

	playerInput() {
		var pointer = this.input.activePointer;

		if (pointer.isDown && !this.lastState) // Pointer went down
		{
			// set pointer start to current pointer position
			this.pLine.start = new Phaser.Point(pointer.x, pointer.y);
			console.log("Pointer just went down");

		}
		else if (pointer.isDown && this.lastState) // Pointer is down
		{
			this.pLine.end = new Phaser.Point(pointer.x, pointer.y);
			console.log("Pointer pressed");
			this.gLine.clear();
			this.gLine.lineStyle(3, 0x0000ff, 1);
			this.gLine.moveTo(this.pLine.start.x, this.pLine.start.y);
			this.gLine.lineTo(this.pLine.end.x, this.pLine.end.y);
			this.currentPlayer.shotAngle = this.pLine.angle;
			this.currentPlayer.shotPower = this.pLine.length;
		}
		else if(!pointer.isDown && this.lastState) // Pointer went up
		{
			this.gLine.clear();
			console.log("Pointer just went up");
			console.info(this.pLine.start, this.pLine.end, this.pLine.angle, this.pLine.length);
			this.shooting();
			this.gamestate = GAMESTATES.INFLIGHT;
		}
		this.lastState = pointer.isDown;

		if (this.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR)) {
			this.shooting();
			this.gamestate = GAMESTATES.INFLIGHT;
		}
	}
	updateDebugText() {
		var fps = Math.round(1000 / this.time.elapsedMS);
		this.fpsText.text = 'FPS: ' + fps;

		this.windText.text = 'Wind: ' + this.physics.arcade.gravity.x;
		this.debugText.text = 'PLAYER DEBUG INFO:\n' + this.currentPlayer.toString();
	}

	shooting() {

		// return if a bullet exists. Ensures that only a single bullet can exist.
		if (this.bullet.exists) {
			return;
		}
		this.bullet.reset(this.currentPlayer.x, this.currentPlayer.y-50);
		this.bullet.exists = true;

		console.log(this.currentPlayer.height);
		var p = new Phaser.Point(this.currentPlayer.x, this.currentPlayer.y-this.currentPlayer.height);

		// FIXME: direction
		var rotation = this.currentPlayer.shotAngle;
		console.log(this.currentPlayer.leftSide, 'rotation: ' + rotation);
		p.rotate(p.x, p.y, rotation, false, 0); // FIXME

		// Add a force to the bullet
		this.physics.arcade.velocityFromRotation(rotation, this.currentPlayer.shotPower,
			this.bullet.body.velocity);

		// And rotate the bullet towards its current velocity vector
		this.bullet.rotation = this.bullet.body.angle;
	}

	bulletVsLand() {
		// if bullet flies offscreen destroy it and return out of this function
		if (this.bullet.x < 0 || this.bullet.x > this.game.world.width
			|| this.bullet.y > this.game.height)
		{
   		this.removeBullet();
    		return;
		} // unless it flies above the sky show arrow to indicate horizontal position
		else if (this.bullet.y < -10) {
			this.arrow.exists = true;
			this.arrow.x = this.bullet.x;
		} // remove the indicator when the bullet reenters the screen
		else if (this.arrow.exists) this.arrow.exists = false;

		// Turn bullet towards its velocity's vector
		this.bullet.rotation = this.bullet.body.angle;

		// Get the rgba value of the land at the bullets current position
		var x = Math.floor(this.bullet.x / this.landScaling);
		var y = Math.floor(this.bullet.y / this.landScaling);
		var alpha = this.land.getPixel(x,y).a;

		if (alpha > 0) {
			// land is visible

			// Carve out a circular shape with set radius
			this.land.blendDestinationOut();
			this.land.circle(x,y, this.blastRadius / this.landScaling, 'rgba(0,0,0,255)');
			this.land.blendReset();
			this.land.update();
			this.land.dirty = true;

			this.explode();
			this.removeBullet();
		}
	}

	explode() {
		let p = new Phaser.Point(this.bullet.x, this.bullet.y);
		console.log("Land was hit at: ", p);
	}
	removeBullet() {
		console.log('bullet removed');
		this.bullet.exists = false;
		this.arrow.exists = false;
		this.gamestate = GAMESTATES.BETWEENTURN;
	}

	updateShotIndicator() {
		this.g.x = this.currentPlayer.x
		this.g.y = this.currentPlayer.y - this.currentPlayer.height;
    	this.g.rotation = this.currentPlayer.shotAngle;
	}

}<commit_msg>Repositioned bullet spawn<commit_after>import Player from '../Player.js'

const GAMESTATES = {
	INPUT: 'input',
	INFLIGHT: 'inflight',
	BETWEENTURN: 'betweenturn'
};

const DIFFICULTY_WIND_MULTIPLIER = 50;

const DEBUG = true;

export default class Stage extends Phaser.State {

	init() {
		this.gamestate = GAMESTATES.INPUT;

		this.background = null;
		this.bullet = null;
		// this.cannon = null;
		this.land = null;
		this.arrow = null;

		this.blastRadius = 50;

		// Player shooting Power and angle bounds
		this.minPower = 250;
		this.maxPower = 1000;
		this.minAngle = 10;
		this.maxAngle = 170;

		// disable texture filtering
		this.game.renderer.renderSession.roundPixels = true;

		// TODO: Hardcoded values need to be changed to values received from server
		this.distanceFromSide = 200;
		this.distanceFromBottom = 300;
		this.players = []
		this.playerTurn = 0;
		this.currentPlayer;

		this.manager = CastleCrush.GameManager;
		this.options = {
			difficulty: this.manager.difficulty,
			players: [this.manager.player1, this.manager.player2]
		};
		console.log("Game started with options: \n", this.options);
		this.maxWindPower = Math.abs(this.options.difficulty) * DIFFICULTY_WIND_MULTIPLIER;

		// set Arcade physics
		this.physics.startSystem(Phaser.Physics.ARCADE);
		this.physics.arcade.gravity.y = 300;
		this.physics.arcade.gravity.x = this.rnd.integerInRange(-this.maxWindPower, this.maxWindPower);
	}

	preload() {

		// preload assets
		this.load.image('background', 'public/assets/background_sky.png');
		this.load.image('tank', 'public/assets/tanks_tankGrey_body5.png');
		this.load.image('castle_blue', 'public/assets/BurgBlau.png');
		this.load.image('castle_red', 'public/assets/BurgRot.png');
		this.load.image('turret', 'public/assets/Kanone.png');
		this.load.image('bullet', 'public/assets/tank_bullet2.png');
		this.load.image('land', 'public/assets/land.png');
		this.load.image('landscape', 'public/assets/landscape.png');
		this.load.image('arrow', 'public/assets/tank_arrowFull.png');
		this.load.image('wheel', 'public/assets/Rad.png');
	}

	create() {
		console.log("Stage loaded.");

		// set background image and scale it to the screensize
		this.background = this.add.image(0,0,'landscape');
		this.background.height = this.world.height;
		this.background.width = this.world.width;

		// create a bullet and add physics to it.
		// bullet does not exist in game when created. Shooting the bullet will
		// set it to exist.
		this.bullet = this.add.sprite(this.world.centerX,this.world.centerY,
			'bullet');
		this.bullet.exists = false;
		this.bullet.anchor.setTo(1,0.5);
		this.physics.arcade.enable(this.bullet);

		// DEBUG Create a FPS Counter in the top left corner
		this.fpsText = this.add.text(8, 8, '', { font: "30px Arial",
			fill: "#000000" });
		this.windText = this.add.text(8, 46, '', { font: "30px Arial",
			fill: "#000000" });
		this.debugText = this.add.text(8, 84, '', { font: "30px Arial",
			fill: "#000000" });

		// Creates land bitmap data, scales it relative to the world size and
		// draws it on screen
		this.land = this.add.bitmapData(1920, 1080);
		this.land.draw('land');
		this.land.update();
		this.landScaling = this.world.width/ this.land.width; // assumes 16:9

		// Convert to sprite to enable collision detection
		this.landSprite = this.add.sprite(0,0, this.land);
		this.landSprite.scale.setTo(this.landScaling);
		// this.physics.arcade.enable(this.landSprite);
		// this.landSprite.body.allowGravity = false;
		console.log("Added land with scaling: ", this.landScaling);

		// Indicator arrow
		this.arrow = this.add.image(0,10, 'arrow')
		this.arrow.anchor.setTo(1,0.5);
		this.arrow.scale.setTo(this.landScaling);
		// this.arrow.width = 0.5 * this.arrow.width;
		// this.arrow.height = 0.5 * this.arrow.height;
		this.arrow.angle = -90;
		this.arrow.exists = false;

		// ShotIndicator
		this.g = this.add.graphics(100, 100);
		this.g.lineStyle(3, 0xAA0000, 1);
		this.g.lineTo(150, 0);

		// Create the players and put them into position
		this.players = [
			new Player(
				this.game,
				this.options.players[0],
				this.distanceFromSide,
				this.world.height - this.distanceFromBottom
			),
			new Player(
				this.game,
				this.options.players[1],
				this.world.width - this.distanceFromSide,
				this.world.height - this.distanceFromBottom, false
			)
		];
		this.players.forEach((player) => {
			player.scale.setTo(0.6 * this.landScaling);
			this.physics.arcade.enable(player);
			this.add.existing(player);
			player.body.allowGravity = false;
		})

		this.currentPlayer = this.players[0];

		// line display for touch controls
		this.lastState = false;
		this.pLine = new Phaser.Line();
		this.gLine = this.add.graphics(0,0);
		this.gLine.lineStyle(3, 0x0000ff, 1);
	}

	testFunc(x,y) {
		console.log("A direct hit! " + (y.leftSide ? "Left" : "Right") + " Player was hit!");
	}

	update() {
		if (DEBUG) {
			this.updateDebugText();
			// this.game.debug.body(this.players[0]);
			// this.game.debug.body(this.players[1]);
			// this.game.debug.body(this.bullet);
		}

		if (this.gamestate === GAMESTATES.INPUT) {
			this.playerInput();
			this.updateShotIndicator();
		}
		else if (this.gamestate === GAMESTATES.INFLIGHT) {
			this.bulletVsLand();
			this.physics.arcade.overlap(this.bullet, this.players, this.testFunc, null, this);
		}
		else if (this.gamestate === GAMESTATES.BETWEENTURN) {
			// recalculate wind check gameoverstate
			this.physics.arcade.gravity.x = this.rnd.integerInRange(-this.maxWindPower, this.maxWindPower);
			this.playerTurn = (this.playerTurn + 1) % this.players.length;
			console.log('Next Player: ' + this.playerTurn);
			this.currentPlayer = this.players[this.playerTurn];

			this.gamestate = GAMESTATES.INPUT;
		}
	}

	playerInput() {
		var pointer = this.input.activePointer;

		if (pointer.isDown && !this.lastState) // Pointer went down
		{
			// set pointer start to current pointer position
			this.pLine.start = new Phaser.Point(pointer.x, pointer.y);
			console.log("Pointer just went down");

		}
		else if (pointer.isDown && this.lastState) // Pointer is down
		{
			this.pLine.end = new Phaser.Point(pointer.x, pointer.y);
			console.log("Pointer pressed");
			this.gLine.clear();
			this.gLine.lineStyle(6, 0x0000ff, 1);
			this.gLine.moveTo(this.pLine.start.x, this.pLine.start.y);
			this.gLine.lineTo(this.pLine.end.x, this.pLine.end.y);
			this.currentPlayer.shotAngle = this.pLine.angle;
			this.currentPlayer.shotPower = this.pLine.length;
		}
		else if(!pointer.isDown && this.lastState) // Pointer went up
		{
			this.gLine.clear();
			console.log("Pointer just went up");
			console.info(this.pLine.start, this.pLine.end, this.pLine.angle, this.pLine.length);
			this.shooting();
			this.gamestate = GAMESTATES.INFLIGHT;
		}
		this.lastState = pointer.isDown;

		if (this.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR)) {
			this.shooting();
			this.gamestate = GAMESTATES.INFLIGHT;
		}
	}
	updateDebugText() {
		var fps = Math.round(1000 / this.time.elapsedMS);
		this.fpsText.text = 'FPS: ' + fps;

		this.windText.text = 'Wind: ' + this.physics.arcade.gravity.x;
		this.debugText.text = 'PLAYER DEBUG INFO:\n' + this.currentPlayer.toString();
	}

	shooting() {

		// return if a bullet exists. Ensures that only a single bullet can exist.
		if (this.bullet.exists) {
			return;
		}
		this.bullet.reset(this.currentPlayer.turret.worldPosition.x, this.currentPlayer.turret.worldPosition.y-50);
		this.bullet.exists = true;

		console.log(this.currentPlayer.height);
		var p = new Phaser.Point(this.currentPlayer.x, this.currentPlayer.y-this.currentPlayer.height);

		// FIXME: direction
		var rotation = this.currentPlayer.shotAngle;
		console.log(this.currentPlayer.leftSide, 'rotation: ' + rotation);
		p.rotate(p.x, p.y, rotation, false, 0); // FIXME

		// Add a force to the bullet
		this.physics.arcade.velocityFromRotation(rotation, this.currentPlayer.shotPower,
			this.bullet.body.velocity);

		// And rotate the bullet towards its current velocity vector
		this.bullet.rotation = this.bullet.body.angle;
	}

	bulletVsLand() {
		// if bullet flies offscreen destroy it and return out of this function
		if (this.bullet.x < 0 || this.bullet.x > this.game.world.width
			|| this.bullet.y > this.game.height)
		{
   		this.removeBullet();
    		return;
		} // unless it flies above the sky show arrow to indicate horizontal position
		else if (this.bullet.y < -10) {
			this.arrow.exists = true;
			this.arrow.x = this.bullet.x;
		} // remove the indicator when the bullet reenters the screen
		else if (this.arrow.exists) this.arrow.exists = false;

		// Turn bullet towards its velocity's vector
		this.bullet.rotation = this.bullet.body.angle;

		// Get the rgba value of the land at the bullets current position
		var x = Math.floor(this.bullet.x / this.landScaling);
		var y = Math.floor(this.bullet.y / this.landScaling);
		var alpha = this.land.getPixel(x,y).a;

		if (alpha > 0) {
			// land is visible

			// Carve out a circular shape with set radius
			this.land.blendDestinationOut();
			this.land.circle(x,y, this.blastRadius / this.landScaling, 'rgba(0,0,0,255)');
			this.land.blendReset();
			this.land.update();
			this.land.dirty = true;

			this.explode();
			this.removeBullet();
		}
	}

	explode() {
		let p = new Phaser.Point(this.bullet.x, this.bullet.y);
		console.log("Land was hit at: ", p);
	}
	removeBullet() {
		console.log('bullet removed');
		this.bullet.exists = false;
		this.arrow.exists = false;
		this.gamestate = GAMESTATES.BETWEENTURN;
	}

	updateShotIndicator() {
		this.g.x = this.currentPlayer.x
		this.g.y = this.currentPlayer.y - this.currentPlayer.height;
    	this.g.rotation = this.currentPlayer.shotAngle;
	}

}<|endoftext|>


<commit_before>"use strict";

window.cls || (window.cls = {});

/**
 * @constructor
 * @extends ViewBase
 */
cls.ResourceTreeView = function(id, name, container_class, html, default_handler, resource_inspector)
{
  //	const
  var THROTTLE_DELAY = 250;
  var GROUP_ORDER = [
    ui_strings.S_HTTP_LABEL_FILTER_MARKUP,
    ui_strings.S_HTTP_LABEL_FILTER_STYLESHEETS,
    ui_strings.S_HTTP_LABEL_FILTER_SCRIPTS,
    ui_strings.S_HTTP_LABEL_FILTER_IMAGES,
    ui_strings.S_HTTP_LABEL_FILTER_FONTS,
    ui_strings.S_HTTP_LABEL_FILTER_OTHER
  ];

  this._resource_inspector = resource_inspector;
  this.required_services = ["resource-manager", "document-manager"];

  this.get_group_order = function()
  {
    return GROUP_ORDER;
  };

  // throttle the update
  this.update = this.update.bind(this).throttle(THROTTLE_DELAY);

  this.createView = function(container)
  {
    var tpl;
    var ctx = this._resource_inspector.get_resource_context();
    var target = container.firstElementChild;

    if (ctx)
    {
      ctx.search_term = this.search_term || "";
      tpl = templates.resource_tree.update(ctx);
    }
    else
    {
      tpl = (
        ["div",
         ["span",
          "class", "container-button ui-button reload-window",
          "handler", "reload-window",
          "tabindex", "1"],
         ["p", ui_strings.S_RESOURCE_CLICK_BUTTON_TO_FETCH_RESOURCES],
         "class", "info-box"
        ]
      );
    }

    //  Exit if the template has not changed since last time ( using its JSON representation as hash )
    var tpl_JSON = JSON.stringify(tpl);
    if (tpl_JSON == this.tpl_JSON)
      return;

    this.tpl_JSON = tpl_JSON;

    var scroll_top = target ? target.scrollTop : 0;
    var scroll_left = target ? target.scrollLeft : 0;

    container.clearAndRender(tpl);

    target = container.firstElementChild;
    if (target)
    {
      target.scrollTop = scroll_top;
      target.scrollLeft = scroll_left;
    }
	};

  this.ondestroy = function(container)
  {
    delete this.tpl_JSON;
  };

  this.create_disabled_view = function(container)
  {
    container.clearAndRender(window.templates.disabled_view());
  };

  this._init = function()
  {
    this.id = id;

    var messages = window.messages;
    messages.add_listener("debug-context-selected", this.update);

    var doc_service = window.services["document-manager"];
    doc_service.add_listener("abouttoloaddocument", this.update);
    doc_service.add_listener("documentloaded", this.update);

    ActionHandlerInterface.apply(this);
    this._handlers = {
      "select-next-entry": this._resource_inspector.highlight_next_resource_bound,
      "select-previous-entry": this._resource_inspector.highlight_previous_resource_bound
    };
    ActionBroker.get_instance().register_handler(this);

    this.init(id, name, container_class, html, default_handler);
  };

  this._init(id, name, container_class, html, default_handler);
};

cls.ResourceTreeView.create_ui_widgets = function()
{
  new ToolbarConfig(
  {
    view: "resource_tree_view",
    groups:
    [
      {
        type: UI.TYPE_INPUT,
        items:
        [
          {
            handler: "resource-tree-text-search",
            shortcuts: "resource-tree-text-search",
            title: ui_strings.S_SEARCH_INPUT_TOOLTIP,
            label: ui_strings.S_INPUT_DEFAULT_TEXT_FILTER,
            type: "filter"
          }
        ]
      }
    ]
  });

  var text_search = window.views.resource_tree_view.text_search = new TextSearch();

  text_search.add_listener("onbeforesearch", (function(msg)
  {
    var view = window.views.resource_tree_view;
    if (view.search_term != msg.search_term)
    {
      view.search_term = msg.search_term;
      view.update();
    }
  }).bind(text_search));

  window.event_handlers.input["resource-tree-text-search"] = function(event, target)
  {
    text_search.searchDelayed(target.value);
  };

  ActionBroker.get_instance().get_global_handler().register_shortcut_listener(
    "resource-tree-text-search",
    cls.Helpers.shortcut_search_cb.bind(text_search)
  );

  var on_view_created = function(msg)
  {
    if (msg.id == "resource_tree_view")
    {
      if (msg.container)
      {
        text_search.setContainer(msg.container);
        text_search.set_query_selector(".resource-tree-resource-label");
        text_search.setFormInput(
          views.resource_tree_view.getToolbarControl(msg.container, "resource-tree-text-search")
        );
        window.views.resource_tree_view.search_term = "";
      }
    }
  };

  var on_view_destroyed = function(msg)
  {
    if (msg.id == "resource_tree_view")
    {
      text_search.cleanup();
      window.views.resource_tree_view.search_term = "";
    }
  };

  window.messages.add_listener("view-created", on_view_created);
  window.messages.add_listener("view-destroyed", on_view_destroyed);
}

cls.ResourceTreeView.prototype = ViewBase;
<commit_msg>Fixed infinite search-createView loop and cleaned up the throttling<commit_after>"use strict";

window.cls || (window.cls = {});

/**
 * @constructor
 * @extends ViewBase
 */
cls.ResourceTreeView = function(id, name, container_class, html, default_handler, resource_inspector)
{
  //	const
  var THROTTLE_DELAY = 250;
  var GROUP_ORDER = [
    ui_strings.S_HTTP_LABEL_FILTER_MARKUP,
    ui_strings.S_HTTP_LABEL_FILTER_STYLESHEETS,
    ui_strings.S_HTTP_LABEL_FILTER_SCRIPTS,
    ui_strings.S_HTTP_LABEL_FILTER_IMAGES,
    ui_strings.S_HTTP_LABEL_FILTER_FONTS,
    ui_strings.S_HTTP_LABEL_FILTER_OTHER
  ];

  this._next_render_time = 0;
  this._resource_inspector = resource_inspector;
  this.required_services = ["resource-manager", "document-manager"];

  this.get_group_order = function()
  {
    return GROUP_ORDER;
  };

  this.instant_update = function()
  {
    // Reset the _next_render_time to force an immediate render
    this._next_render_time = 0;
    this.update();
  };

  this.update_bound = this.update.bind(this);

  this.createView = function(container)
  {
    var now = Date.now();
    if (now >= this._next_render_time)
    {
      if (this._bounced_update)
        this._bounced_update = clearTimeout(this._bounced_update);

      this._render_view(container);
      this._next_render_time = now + THROTTLE_DELAY;
    }
    else if (!this._bounced_update)
      this._bounced_update = setTimeout(this.update_bound, THROTTLE_DELAY);
	};

  this._render_view = function(container)
  {
    var tpl;
    var ctx = this._resource_inspector.get_resource_context();
    var target = container.firstElementChild;

    if (ctx)
    {
      ctx.search_term = this.search_term || "";
      tpl = templates.resource_tree.update(ctx);
    }
    else
    {
      tpl = (
        ["div",
         ["span",
          "class", "container-button ui-button reload-window",
          "handler", "reload-window",
          "tabindex", "1"],
         ["p", ui_strings.S_RESOURCE_CLICK_BUTTON_TO_FETCH_RESOURCES],
         "class", "info-box"
        ]
      );
    }

    //  Exit if the template has not changed since last time ( using its JSON representation as hash )
    var tpl_JSON = JSON.stringify(tpl);
    if (tpl_JSON == this.tpl_JSON)
      return;

    this.tpl_JSON = tpl_JSON;

    var scroll_top = target ? target.scrollTop : 0;
    var scroll_left = target ? target.scrollLeft : 0;

    container.clearAndRender(tpl);

    target = container.firstElementChild;
    if (target)
    {
      target.scrollTop = scroll_top;
      target.scrollLeft = scroll_left;
    }
  };

  this.ondestroy = function(container)
  {
    this.tpl_JSON = null;
  };

  this.create_disabled_view = function(container)
  {
    container.clearAndRender(window.templates.disabled_view());
  };

  this._init = function()
  {
    this.id = id;

    var messages = window.messages;
    messages.add_listener("debug-context-selected", this.update_bound);

    var doc_service = window.services["document-manager"];
    doc_service.add_listener("abouttoloaddocument", this.update_bound);
    doc_service.add_listener("documentloaded", this.update_bound);

    ActionHandlerInterface.apply(this);
    this._handlers = {
      "select-next-entry": this._resource_inspector.highlight_next_resource_bound,
      "select-previous-entry": this._resource_inspector.highlight_previous_resource_bound
    };
    ActionBroker.get_instance().register_handler(this);

    this.init(id, name, container_class, html, default_handler);
  };

  this._init(id, name, container_class, html, default_handler);
};

cls.ResourceTreeView.create_ui_widgets = function()
{
  new ToolbarConfig(
  {
    view: "resource_tree_view",
    groups:
    [
      {
        type: UI.TYPE_INPUT,
        items:
        [
          {
            handler: "resource-tree-text-search",
            shortcuts: "resource-tree-text-search",
            title: ui_strings.S_SEARCH_INPUT_TOOLTIP,
            label: ui_strings.S_INPUT_DEFAULT_TEXT_FILTER,
            type: "filter"
          }
        ]
      }
    ]
  });

  var text_search = window.views.resource_tree_view.text_search = new TextSearch();

  text_search.add_listener("onbeforesearch", (function(msg)
  {
    var view = window.views.resource_tree_view;
    view.search_term = msg.search_term;
    view.instant_update();
  }).bind(text_search));

  window.event_handlers.input["resource-tree-text-search"] = function(event, target)
  {
    text_search.searchDelayed(target.value);
  };

  ActionBroker.get_instance().get_global_handler().register_shortcut_listener(
    "resource-tree-text-search",
    cls.Helpers.shortcut_search_cb.bind(text_search)
  );

  var on_view_created = function(msg)
  {
    if (msg.id == "resource_tree_view" && msg.container)
    {
      text_search.setContainer(msg.container);
      text_search.set_query_selector(".resource-tree-resource-label");
    }
  };

  var on_view_destroyed = function(msg)
  {
    if (msg.id == "resource_tree_view")
    {
      text_search.cleanup();
      window.views.resource_tree_view.search_term = "";
    }
  };

  window.messages.add_listener("view-created", on_view_created);
  window.messages.add_listener("view-destroyed", on_view_destroyed);
};

cls.ResourceTreeView.prototype = ViewBase;
<|endoftext|>


<commit_before>// var shell = require('shelljs');
// shell.exec('bash ./commands/dir.sh', {silent:false,async:true}).output;
// if (shell.exec('bash cd ~/Desktop && sudo git init && sudo git commit -am "Auto-commit"').code !== 0) {
'use strict';
var _ = require('lodash');
var fs = require('file-system');
var app=require ('app');
var path = require('path');
var shell = require('shelljs');
var BrowserWindow = require('browser-window');
var notifier = require('node-notifier');
var child_process = require('child_process');
var graphql = require ('graphql').graphql;
var chokidar= require('chokidar');
 var mkdirp = require('mkdirp');
var filessystem = require('fs');

var mainWindow = null;
var globalShortcut = require('global-shortcut');

//install nconf dependency for this configuration to work
var configuration = require('./configuration');

var options = {
	"debug": false,
	"version": "1.0.0",
	"views_dir": "App",
	"root_view": "index.html"
};

options = _.extend({
	// ADDITIONAL CUSTOM SETTINGS
}, options);

require('crash-reporter').start();

app.on('ready', function() {

     if (!configuration.readSettings('shortcutKeys')) {
         configuration.saveSettings('shortcutKeys', ['ctrl', 'shift']);
     };
    mainWindow = new BrowserWindow({frame: false,
            height: 500,
            // show: true,
            resizable: false,
            width: 338});
     setGlobalShortcuts();
     function setGlobalShortcuts() {
         globalShortcut.unregisterAll();

         var shortcutKeysSetting = configuration.readSettings('shortcutKeys');
         var shortcutPrefix = shortcutKeysSetting.length === 0 ? '' : shortcutKeysSetting.join('+') + '+';

         globalShortcut.register(shortcutPrefix + '1', function () {
             mainWindow.webContents.send('global-shortcut', 0);
         });
         globalShortcut.register(shortcutPrefix + '2', function () {
             mainWindow.webContents.send('global-shortcut', 1);
         });
     };
  mainWindow.loadUrl(path.join('file://', __dirname, options.views_dir, options.root_view));
  if(options.debug) { mainWindow.openDevTools(); }
    mainWindow.on('closed', function() { mainWindow = null; });

    var folderWatcher = function(object) {
            fs.readdir(dir, function(err, items) {
            // console.log(items);
            var count=items.length;
            if(count=count+1)
            {
            notifier.notify({
                title: items.length+ 'Files by now!',
                message: 'You have added some Files',
                icon: path.join(__dirname, '/dist/img/app-icon.png'), // Absolute path (doesn't work on balloons)
                sound: true, // Only Notification Center or Windows Toasters
                wait: true // Wait with callback, until user action is taken against notification
                }, function (err, response) {
                // Response is response from notification
                });

                notifier.on('timeout', function (notifierObject, options) {
                // Triggers if `wait: true` and notification closes
                });
            }

        });
    };
    fs.watch("/home/StreamUpBox", { persistent: true }, function (event, fileName) {
        folderWatcher();
    });
    //Creating the Directory and watch it.
    var dir = '/home/StreamUpBox';
    if (!filessystem.existsSync(dir)){
        filessystem.mkdirSync(dir);
        console.log("Folder created Successfully!");
    }
    else
    {
        console.log("Folder already exist!");
    }

});

<commit_msg>closes#1<commit_after>// var shell = require('shelljs');
// shell.exec('bash ./commands/dir.sh', {silent:false,async:true}).output;
// if (shell.exec('bash cd ~/Desktop && sudo git init && sudo git commit -am "Auto-commit"').code !== 0) {
'use strict';
var _ = require('lodash');
var fs = require('file-system');
var app=require ('app');
var path = require('path');
var shell = require('shelljs');
var BrowserWindow = require('browser-window');
var notifier = require('node-notifier');
var child_process = require('child_process');
var graphql = require ('graphql').graphql;
var chokidar= require('chokidar');
 var mkdirp = require('mkdirp');
var filessystem = require('fs');

var mainWindow = null;
var globalShortcut = require('global-shortcut');

//install nconf dependency for this configuration to work
var configuration = require('./configuration');

var options = {
	"debug": false,
	"version": "1.0.0",
	"views_dir": "App",
	"root_view": "index.html"
};

options = _.extend({
	// ADDITIONAL CUSTOM SETTINGS
}, options);

require('crash-reporter').start();
app.on('ready', function() {

     if (!configuration.readSettings('shortcutKeys')) {
         configuration.saveSettings('shortcutKeys', ['ctrl', 'shift']);
     };
    mainWindow = new BrowserWindow({frame: false,
            height: 500,
            // show: true,
            resizable: false,
            width: 338});
     setGlobalShortcuts();
     function setGlobalShortcuts() {
         globalShortcut.unregisterAll();

         var shortcutKeysSetting = configuration.readSettings('shortcutKeys');
         var shortcutPrefix = shortcutKeysSetting.length === 0 ? '' : shortcutKeysSetting.join('+') + '+';

         globalShortcut.register(shortcutPrefix + '1', function () {
             mainWindow.webContents.send('global-shortcut', 0);
         });
         globalShortcut.register(shortcutPrefix + '2', function () {
             mainWindow.webContents.send('global-shortcut', 1);
         });
     };
  mainWindow.loadUrl(path.join('file://', __dirname, options.views_dir, options.root_view));
  if(options.debug) { mainWindow.openDevTools(); }
    mainWindow.on('closed', function() { mainWindow = null; });

    var folderWatcher = function(object) {
            fs.readdir(dir, function(err, items) {
            // console.log(items);
            var count=items.length;
            if(count=count+1)
            {
            notifier.notify({
                title: items.length+ 'Files by now!',
                message: 'You have added some Files',
                icon: path.join(__dirname, '/dist/img/app-icon.png'), // Absolute path (doesn't work on balloons)
                sound: true, // Only Notification Center or Windows Toasters
                wait: true // Wait with callback, until user action is taken against notification
                }, function (err, response) {
                // Response is response from notification
                });

                notifier.on('timeout', function (notifierObject, options) {
                // Triggers if `wait: true` and notification closes
                });
            }

        });
    };
    fs.watch("/home/StreamUpBox", { persistent: true }, function (event, fileName) {
        folderWatcher();
    });
    //Creating the Directory and watch it.
    var dir = '/home/StreamUpBox';
    if (!filessystem.existsSync(dir)){
        filessystem.mkdirSync(dir);
        console.log("Folder created Successfully!");
    }
    else
    {
        console.log("Folder already exist!");
    }

});

<|endoftext|>