<commit_before>var fastMath = require('../util/fastMath');
var SegmentStash = require('./segmentStash');
var Segment = require('./segment');
var Util = require('../util/util');

/**
 * MotionSegment is a collection of other MotionSegments. MotionSegment(s) form the entire MotionProfile
 * Initialize the segment with a unique id and a stash to hold other segments
 * @param {Number} t0 initial Time
 * @param {Number} tf final Time
 */
var MotionSegment = function(t0, tf) {

	Segment.Segment.call(this, t0, tf);

	//each segment can hold other segments
	this.segments = SegmentStash.makeStash();

};

MotionSegment.prototype = Object.create(Segment.Segment.prototype);
MotionSegment.prototype.constructor = MotionSegment;

MotionSegment.prototype.exportData = function() {
	var dataObj = {};

	Util.extend(dataObj, this.segmentData);
	dataObj.constructor = this.constructor.name;

	return dataObj;

};

MotionSegment.prototype.importFromData = function(data) {
	throw new Error("importFromData() function needs to be defined on derived segments!");
};

MotionSegment.prototype.initializeWithSegments = function(segments) {

	if (!Array.isArray(segments))
		throw new Error("Expecting array of segments. Was not an array");

	//add each segment
	for (var i = 0; i < segments.length; i++) {
		this.segments.insertAt(segments[i], null);
	}
};

MotionSegment.prototype.findSegmentAtTime = function(time) {
	var segment = this.segments.getAllSegments().filter(function(bSeg) {
		return fastMath.geq(time, bSeg.initialTime) && fastMath.leq(time, bSeg.finalTime);
	});

	if (!Util.isObject(segment[0]))
		throw new Error("Couldn't find basic segment that contains time " + time);

	// could have two segments, if time falls right at the end of the first segment
	// and the beginning of 2nd
	if (segment.length > 2)
		throw new Error("Found " + segment.length + " segments, expecting 1 or 2.");

	//since all profile variables (p,v,a) are continuous, we'll just pick the first one
	return segment[0];
};

MotionSegment.prototype.evaluatePositionAt = function(x) {
	//which segment does x fall in
	var segment = this.findSegmentAtTime(x);
	if(segment.type !== "basic") {
		return segment.evaluatePositionAt(x);
	} else {
		return segment.positionPoly.evaluateAt(x);
	}
};

MotionSegment.prototype.evaluateVelocityAt = function(x) {
	//which segment does x fall in
	var segment = this.findSegmentAtTime(x);
	if(segment.type !== "basic") {
		return segment.evaluateVelocityAt(x);
	} else {
		return segment.velocityPoly.evaluateAt(x);
	}
};

MotionSegment.prototype.evaluateAccelerationAt = function(x) {
	//which segment does x fall in
	var segment = this.findSegmentAtTime(x);
	if(segment.type !=="basic")
		return segment.evaluateAccelerationAt(x);
	else
		return segment.accelPoly.evaluateAt(x);
};

MotionSegment.prototype.evaluateJerkAt = function(x) {
	//which segment does x fall in

	var segment = this.findSegmentAtTime(x);
	if(segment.type !=="basic")
		return segment.evaluateJerkAt(x);
	else
		return segment.jerkPoly.evaluateAt(x);
};

MotionSegment.prototype.evaluateLoadAt = function(x) {
	//which segment does x fall in

	var segment = this.findSegmentAtTime(x);
	if(segment.type !== "basic")
		return segment.evaluateLoadAt(x);
	else
		return segment.load;
};

MotionSegment.prototype.evaluateThrustAt = function(x) {
	//which segment does x fall in

	var segment = this.findSegmentAtTime(x);
	if(segment.type !=="basic")
		return segment.evaluateThrustAt(x);
	else
		return segment.thrust;
};

MotionSegment.prototype.evaluateFrictionAt = function(x) {
	//which segment does x fall in

	var segment = this.findSegmentAtTime(x);
	if(segment.type !=="basic")
		return segment.evaluateFrictionAt(x);
	else
		return segment.friction;
};

MotionSegment.prototype.getAllSegments = function() {
	return this.segments.getAllSegments();
};

/**
 * Calculates final time, acceleration, velocity and position for this segment
 * @return {Array} [tf,af,vf,pf]
 */
MotionSegment.prototype.getFinalValues = function() {
	var last = this.segments.lastSegment();
	var tf = last.finalTime;
	var af = last.evaluateAccelerationAt(tf);
	var vf = last.evaluateVelocityAt(tf);
	var pf = last.evaluatePositionAt(tf);

	return [tf, af, vf, pf];
};

/**
 * Calculates initial time, acceleration, velocity and position for this segment
 * @return {Array} [tf,af,vf,pf]
 */
MotionSegment.prototype.getInitialValues = function() {
	var last = this.segments.firstSegment();
	var t0 = last.initialTime;
	var a0 = last.evaluateAccelerationAt(t0);
	var v0 = last.evaluateVelocityAt(t0);
	var p0 = last.evaluatePositionAt(t0);

	return [t0, a0, v0, p0];
};

MotionSegment.prototype.setBasicSegmentLoads = function(loads) {
	if (!loads)
		return;
	var segments = this.getAllSegments();

	for (var i = segments.length - 1; i >= 0; i--) {
		segments[i].friction = loads.friction || 0;
		segments[i].thrust = loads.thrust || 0;
		segments[i].load = loads.load || 0;
	}
};

var factory = {};

factory.MotionSegment = MotionSegment;

module.exports = factory;<commit_msg>small variable name change<commit_after>var fastMath = require('../util/fastMath');
var SegmentStash = require('./segmentStash');
var Segment = require('./segment');
var Util = require('../util/util');

/**
 * MotionSegment is a collection of other MotionSegments. MotionSegment(s) form the entire MotionProfile
 * Initialize the segment with a unique id and a stash to hold other segments
 * @param {Number} t0 initial Time
 * @param {Number} tf final Time
 */
var MotionSegment = function(t0, tf) {

	Segment.Segment.call(this, t0, tf);

	//each segment can hold other segments
	this.segments = SegmentStash.makeStash();

};

MotionSegment.prototype = Object.create(Segment.Segment.prototype);
MotionSegment.prototype.constructor = MotionSegment;

MotionSegment.prototype.exportData = function() {
	var dataObj = {};

	Util.extend(dataObj, this.segmentData);
	dataObj.constructor = this.constructor.name;

	return dataObj;

};

MotionSegment.prototype.importFromData = function(data) {
	throw new Error("importFromData() function needs to be defined on derived segments!");
};

MotionSegment.prototype.initializeWithSegments = function(segments) {

	if (!Array.isArray(segments))
		throw new Error("Expecting array of segments. Was not an array");

	//add each segment
	for (var i = 0; i < segments.length; i++) {
		this.segments.insertAt(segments[i], null);
	}
};

MotionSegment.prototype.findSegmentAtTime = function(time) {
	var segment = this.segments.getAllSegments().filter(function(bSeg) {
		return fastMath.geq(time, bSeg.initialTime) && fastMath.leq(time, bSeg.finalTime);
	});

	if (!Util.isObject(segment[0]))
		throw new Error("Couldn't find basic segment that contains time " + time);

	// could have two segments, if time falls right at the end of the first segment
	// and the beginning of 2nd
	if (segment.length > 2)
		throw new Error("Found " + segment.length + " segments, expecting 1 or 2.");

	//since all profile variables (p,v,a) are continuous, we'll just pick the first one
	return segment[0];
};

MotionSegment.prototype.evaluatePositionAt = function(x) {
	//which segment does x fall in
	var segment = this.findSegmentAtTime(x);
	if(segment.type !== "basic") {
		return segment.evaluatePositionAt(x);
	} else {
		return segment.positionPoly.evaluateAt(x);
	}
};

MotionSegment.prototype.evaluateVelocityAt = function(x) {
	//which segment does x fall in
	var segment = this.findSegmentAtTime(x);
	if(segment.type !== "basic") {
		return segment.evaluateVelocityAt(x);
	} else {
		return segment.velocityPoly.evaluateAt(x);
	}
};

MotionSegment.prototype.evaluateAccelerationAt = function(x) {
	//which segment does x fall in
	var segment = this.findSegmentAtTime(x);
	if(segment.type !=="basic")
		return segment.evaluateAccelerationAt(x);
	else
		return segment.accelPoly.evaluateAt(x);
};

MotionSegment.prototype.evaluateJerkAt = function(x) {
	//which segment does x fall in

	var segment = this.findSegmentAtTime(x);
	if(segment.type !=="basic")
		return segment.evaluateJerkAt(x);
	else
		return segment.jerkPoly.evaluateAt(x);
};

MotionSegment.prototype.evaluateLoadAt = function(x) {
	//which segment does x fall in

	var segment = this.findSegmentAtTime(x);
	if(segment.type !== "basic")
		return segment.evaluateLoadAt(x);
	else
		return segment.load;
};

MotionSegment.prototype.evaluateThrustAt = function(x) {
	//which segment does x fall in

	var segment = this.findSegmentAtTime(x);
	if(segment.type !=="basic")
		return segment.evaluateThrustAt(x);
	else
		return segment.thrust;
};

MotionSegment.prototype.evaluateFrictionAt = function(x) {
	//which segment does x fall in

	var segment = this.findSegmentAtTime(x);
	if(segment.type !=="basic")
		return segment.evaluateFrictionAt(x);
	else
		return segment.friction;
};

MotionSegment.prototype.getAllSegments = function() {
	return this.segments.getAllSegments();
};

/**
 * Calculates final time, acceleration, velocity and position for this segment
 * @return {Array} [tf,af,vf,pf]
 */
MotionSegment.prototype.getFinalValues = function() {
	var last = this.segments.lastSegment();
	var tf = last.finalTime;
	var af = last.evaluateAccelerationAt(tf);
	var vf = last.evaluateVelocityAt(tf);
	var pf = last.evaluatePositionAt(tf);

	return [tf, af, vf, pf];
};

/**
 * Calculates initial time, acceleration, velocity and position for this segment
 * @return {Array} [tf,af,vf,pf]
 */
MotionSegment.prototype.getInitialValues = function() {
	var first = this.segments.firstSegment();
	var t0 = first.initialTime;
	var a0 = first.evaluateAccelerationAt(t0);
	var v0 = first.evaluateVelocityAt(t0);
	var p0 = first.evaluatePositionAt(t0);

	return [t0, a0, v0, p0];
};

MotionSegment.prototype.setBasicSegmentLoads = function(loads) {
	if (!loads)
		return;
	var segments = this.getAllSegments();

	for (var i = segments.length - 1; i >= 0; i--) {
		segments[i].friction = loads.friction || 0;
		segments[i].thrust = loads.thrust || 0;
		segments[i].load = loads.load || 0;
	}
};

var factory = {};

factory.MotionSegment = MotionSegment;

module.exports = factory;<|endoftext|>


<commit_before>function progressViewModel() {
  var self = this;

  self.progressHtml = ko.observable();
  self.done = ko.observable(false);
  self.error = ko.observable(false);
  self.progressBarWidth = ko.observable("0%");
  self.triggerDone = function() {
    self.done(true);
    clearInterval(app.timer);
    app.timer = null;
  };
  self.checkTimer = function() {
    var checkProgress = function () {
        var url = $('#selected_progress_url').attr('value');
        var elem = $('#scenario_progress_html');
        if (elem.length === 0) {
            self.triggerDone();
            return false;
        }
        if (!self.done()) {
            $.get(url, function(data) {
                self.progressHtml(data.html);
                if (data.error == 1) {
                    self.error(true);
                    // stop timer without declaring done
                    clearInterval(app.timer);
                    app.timer = null;
                }
                var pct = parseInt((data.complete / data.total) * 100.0, 10);
                self.progressBarWidth(pct + "%");
                if (pct >= 100) {
                    self.triggerDone();
                }
            });
        }
    };
    if (!app.timer) {
        checkProgress();
        app.timer = setInterval(checkProgress, 5000);
    } else {
        console.log("Warning: app.timer is set and checkTimer was called!");
    }
 };

  return self;
}

function scenariosViewModel() {
  var self = this;

  // this will get bound to the active scenario
  self.selectedFeature = ko.observable(false);
  // display the form panel entirely
  self.showScenarioPanels = ko.observable();
  // display initial help
  self.showScenarioHelp = ko.observable(true);
  // display form
  self.showScenarioFormPanel = ko.observable(false);
  // display list of scenarios
  self.showScenarioList = ko.observable(true);
  self.scenarioLoadError = ko.observable(false);
  self.scenarioLoadComplete = ko.observable(false);
  self.reportLoadError = ko.observable(false);
  self.reportLoadComplete = ko.observable(false);
  self.planningUnitsLoadError = ko.observable(false);
  self.planningUnitsLoadComplete = ko.observable(false);
  self.formLoadError = ko.observable(false);
  self.formLoadComplete = ko.observable(true);
  // list of all scenarios, primary viewmodel
  self.scenarioList = ko.observableArray();
  // display mode
  self.dataMode = ko.observable('manage');

  // pagination config will display x items
  // from this zero based index
  self.listStart = ko.observable(0);
  self.listDisplayCount = 9;

  // paginated list
  self.scenarioListPaginated = ko.computed(function () {
    return self.scenarioList.slice(self.listStart(), self.listDisplayCount+self.listStart());
  });

  // this list is model for pagination controls
  self.paginationList = ko.computed(function () {
    var list = [], listIndex = 0, displayIndex = 1;
    for (listIndex=0; listIndex < self.scenarioList().length; listIndex++) {
      if (listIndex % self.listDisplayCount === 0 && Math.abs(listIndex - self.listStart()) < 5 * self.listDisplayCount) {
        list.push({'displayIndex': 1 + (listIndex/self.listDisplayCount), 'listIndex': listIndex });
      }
    }
    if (list.length < self.scenarioList().length / self.listDisplayCount) {
      list.push({'displayIndex': '...', 'listIndex': null });
      list.push({'displayIndex': '»', 'listIndex': null });

    }
    if (self.listStart() > self.listDisplayCount) {
      list.shift({'displayIndex': '«', 'listIndex': null });
    }
    return list;
  });

  self.setListIndex = function (button, event) {
    var listStart = self.listStart();
    if (button.displayIndex === '»') {
      self.listStart(listStart + self.listDisplayCount * 5);
    } else {
    self.listStart(button.listIndex);
    }
    self.selectFeature(self.scenarioList()[button.listIndex || self.listStart()]);
  };

  self.showScenarioForm = function(action, uid) {
    // get the form
    var formUrl;
    if (action === "create") {
      formUrl = app.workspace["feature-classes"][0]["link-relations"]["create"]["uri-template"];
    } else if (action === "edit") {
      formUrl = app.workspace["feature-classes"][0]["link-relations"]["edit"][0]["uri-template"];
      formUrl = formUrl.replace('{uid}', uid);
    }
    // clean up and show the form
    var jqxhr = $.get(formUrl, function(data) {
      var $form = $(data).find('form');
      $form.find('input:submit').remove();
      // app.cleanupForm($form);
      $('#scenarios-form-container').empty().append(data);
      self.showScenarioFormPanel(true);
      $form.find('input:visible:first').focus();
      $form.bind('submit', function(event) {
        event.preventDefault();
      });
    })
    .success( function() {
        selectFeatureControl.unselectAll();
        selectGeographyControl.activate();
        self.showScenarioList(false);
        // TODO geography control -> if edit, select the selectedFeature's possible_fids
        self.selectedFeature(false);
        self.showScenarioList(false);
    })
    .error( function() { self.formLoadError(true); } )
    .complete( function() { self.formLoadComplete(true); } )
  };

  self.updateScenario = function(scenario_id, isNew) {
    var updateUrl = '/features/generic-links/links/geojson/{uid}/'.replace('{uid}', scenario_id);
    $.get(updateUrl, function(data) {
      if (isNew) {
        self.scenarioList.unshift(ko.mapping.fromJS(data.features[0].properties));
        self.selectedFeature(self.scenarioList()[0]);
      } else {
        ko.mapping.fromJS(data.features[0].properties, self.selectedFeature());
        self.showScenarioFormPanel(false);
        self.showScenarioList(true);
      }
    });
  };

  self.associateScenario = function(scenario_id, property_id) {
    var url = "/features/folder/{folder_uid}/add/{scenario_uid}";
    url = url.replace('{folder_uid}', property_id).replace('{scenario_uid}', scenario_id);
    $.ajax({
      url: url,
      type: "POST",
      success: function(data) {
        self.updateScenario(JSON.parse(data)["X-Madrona-Select"], true);
        app.scenarios.viewModel.showScenarioFormPanel(false);
        app.scenarios.viewModel.showScenarioList(true);
        app.new_features.removeAllFeatures();
      }
    });
  };

  self.saveScenarioForm = function(self, event) {
      // pass
  };

  self.OLDsaveScenarioForm = function(self, event) {
    var isNew, $dialog = $('#scenarios-form-container'),
      $form = $dialog.find('form'),
      actionUrl = $form.attr('action'),
      values = {},
      error = false;
    $form.find('input,select').each(function() {
      var $input = $(this);
      if ($input.closest('.field').hasClass('required') && $input.attr('type') !== 'hidden' && !$input.val()) {
        error = true;
        $input.closest('.control-group').addClass('error');
        $input.siblings('p.help-block').text('This field is required.');
      } else {
        values[$input.attr('name')] = $input.val();
      }
    });
    if (error) {
      return false;
    }
    if (self.modifyFeature.active) {
      values.geometry_final = values.geometry_orig = self.modifyFeature.feature.geometry.toString();
      self.modifyFeature.deactivate();
      isNew = false;
    } else {
      //values.geometry_final = values.geometry_orig = app.scenarios.geometry;
      values.geometry_orig = app.scenarios.geometry;
      isNew = true;
    }
    $form.addClass('form-horizontal');
    $.ajax({
      url: actionUrl,
      type: "POST",
      data: values,
      success: function(data, textStatus, jqXHR) {
        var scenario_uid = JSON.parse(data)["X-Madrona-Select"];
        if (isNew) {
          self.associateScenario(scenario_uid, self.property.uid());
        } else {
          self.updateScenario(scenario_uid, false);
        }
      },
      error: function(jqXHR, textStatus, errorThrown) {
        self.cancelAddScenario();
      }
    });
  };

  self.showDeleteDialog = function () {
    $("#scenario-delete-dialog").modal("show");
  };

  self.closeDialog = function () {
    $("#scenario-delete-dialog").modal("hide");
  };

  self.deleteFeature = function () {
    var url = "/features/generic-links/links/delete/{uid}/".replace("{uid}", self.selectedFeature().uid());
    $('#scenario-delete-dialog').modal('hide');
    $.ajax({
      url: url,
      type: "DELETE",
      success: function (data, textStatus, jqXHR) {
        self.scenarioList.remove(self.selectedFeature());
        self.selectedFeature(false);
        self.showScenarioList(true);
        self.selectControl.unselectAll();
      }
    });
  };

  // start the scenario editing process
  self.editScenario = function() {
    self.formLoadError(false);
    self.formLoadComplete(false);
    self.showScenarioForm("edit", self.selectedFeature().uid());
  };

  self.addScenarioStart = function() {
    self.formLoadError(false);
    self.formLoadComplete(false);
    self.showScenarioForm('create');
    /*
     * Do this only on success
    selectFeatureControl.unselectAll();
    selectGeographyControl.activate();
    self.showScenarioList(false);
    */
  };

  self.cancelAddScenario = function () {
    selectGeographyControl.unselectAll();
    selectGeographyControl.deactivate();
    self.showScenarioFormPanel(false);
    self.showScenarioList(true);
  };

  self.mode = function(m) {
    switch (m) {
        case 'scenarioList':
            break;
        case 'scenarioDetail':
            break;
        case 'scenarioEdit':
            break;
    }
  };

  self.selectControl = {
      /*
       * Controls the map and display panel
       * when features are selected
       */
      unselectAll: function() {
        // $('#scenario-show-container').empty();
      },
      select: function(feature) {

        var uid = feature.uid();
        var showUrl = app.workspace["feature-classes"][0]["link-relations"]["self"]["uri-template"];
        showUrl = showUrl.replace('{uid}', uid);

        self.reportLoadError(false);
        self.reportLoadComplete(false);
        var jqxhr = $.get(showUrl, function(data) {
          var elem = document.getElementById('scenario-show-container');
          ko.cleanNode(elem);
          $('#scenario-show-container').empty().append(data);
          app.scenarios.progressViewModel = null;
          clearInterval(app.timer);
          app.timer = null;
          app.scenarios.progressViewModel = new progressViewModel();

          ko.applyBindings(app.scenarios.progressViewModel, elem);
          app.scenarios.progressViewModel.checkTimer();
        })
        .error(function() { self.reportLoadError(true); })
        .complete(function() { self.reportLoadComplete(true); })

        selectFeatureControl.unselectAll();
        $.each(feature.selected_fids(), function (i, fid) {
            var f = pu_layer.getFeaturesByAttribute("fid",fid)[0];
            if (!f) {
                console.log("warning: fid " + fid + " is not valid");
            }
            selectFeatureControl.select(f);
        });
      }
   };

  self.selectFeature = function(feature, event) {
    self.selectControl.unselectAll();
    self.selectControl.select(feature);
    self.selectedFeature(feature);
    bbox = feature.bbox();
    if (bbox && bbox.length === 4) {
        map.zoomToExtent(bbox);
    }
    self.showScenarioList(false);
  };

  self.selectFeatureById = function (id) {
    var pageSize = self.scenarioList().length / self.listDisplayCount;
    $.each(self.scenarioList(), function (i, feature) {
      if (feature.uid() === id) {
        // set list start to first in list page
        self.listStart(Math.floor(i / self.listDisplayCount) * self.listDisplayCount);
        self.selectedFeature(this);
      }
    });
  };

  self.reloadScenarios = function(property) {
    console.log("reloadScenarios");
    self.scenarioList.removeAll();
    self.loadScenarios();
  };

  self.loadViewModel = function (data) {
    self.scenarioList($.map(data.features, function (feature, i) {
      return ko.mapping.fromJS(feature.properties);
    }));
    // Don't bother selecting the first feature
    //self.selectFeature(self.scenarioList()[0]);
  };

  self.loadScenarios = function() {
    var process = function(data) {
      if (data.features && data.features.length) {
        self.loadViewModel(data);
      } else {
        console.log("NO DATA");
        self.scenarioLoadError(true);
      }
    };
    var jqhxr = $.get('/seak/scenarios.geojson',
        process
    )
    .error(function() { self.scenarioLoadError(true); })
    .complete(function() { self.scenarioLoadComplete(true); })

  };

  self.backToScenarioList = function() {
    selectFeatureControl.unselectAll();
    self.selectedFeature(false);
    self.showScenarioList(true);
  };

  return self;
}
<commit_msg>handle scenarios length == 0 better<commit_after>function progressViewModel() {
  var self = this;

  self.progressHtml = ko.observable();
  self.done = ko.observable(false);
  self.error = ko.observable(false);
  self.progressBarWidth = ko.observable("0%");
  self.triggerDone = function() {
    self.done(true);
    clearInterval(app.timer);
    app.timer = null;
  };
  self.checkTimer = function() {
    var checkProgress = function () {
        var url = $('#selected_progress_url').attr('value');
        var elem = $('#scenario_progress_html');
        if (elem.length === 0) {
            self.triggerDone();
            return false;
        }
        if (!self.done()) {
            $.get(url, function(data) {
                self.progressHtml(data.html);
                if (data.error == 1) {
                    self.error(true);
                    // stop timer without declaring done
                    clearInterval(app.timer);
                    app.timer = null;
                }
                var pct = parseInt((data.complete / data.total) * 100.0, 10);
                self.progressBarWidth(pct + "%");
                if (pct >= 100) {
                    self.triggerDone();
                }
            });
        }
    };
    if (!app.timer) {
        checkProgress();
        app.timer = setInterval(checkProgress, 5000);
    } else {
        console.log("Warning: app.timer is set and checkTimer was called!");
    }
 };

  return self;
}

function scenariosViewModel() {
  var self = this;

  // this will get bound to the active scenario
  self.selectedFeature = ko.observable(false);
  // display the form panel entirely
  self.showScenarioPanels = ko.observable();
  // display initial help
  self.showScenarioHelp = ko.observable(true);
  // display form
  self.showScenarioFormPanel = ko.observable(false);
  // display list of scenarios
  self.showScenarioList = ko.observable(true);
  self.scenarioLoadError = ko.observable(false);
  self.scenarioLoadComplete = ko.observable(false);
  self.reportLoadError = ko.observable(false);
  self.reportLoadComplete = ko.observable(false);
  self.planningUnitsLoadError = ko.observable(false);
  self.planningUnitsLoadComplete = ko.observable(false);
  self.formLoadError = ko.observable(false);
  self.formLoadComplete = ko.observable(true);
  // list of all scenarios, primary viewmodel
  self.scenarioList = ko.observableArray();
  // display mode
  self.dataMode = ko.observable('manage');

  // pagination config will display x items
  // from this zero based index
  self.listStart = ko.observable(0);
  self.listDisplayCount = 9;

  // paginated list
  self.scenarioListPaginated = ko.computed(function () {
    return self.scenarioList.slice(self.listStart(), self.listDisplayCount+self.listStart());
  });

  // this list is model for pagination controls
  self.paginationList = ko.computed(function () {
    var list = [], listIndex = 0, displayIndex = 1;
    for (listIndex=0; listIndex < self.scenarioList().length; listIndex++) {
      if (listIndex % self.listDisplayCount === 0 && Math.abs(listIndex - self.listStart()) < 5 * self.listDisplayCount) {
        list.push({'displayIndex': 1 + (listIndex/self.listDisplayCount), 'listIndex': listIndex });
      }
    }
    if (list.length < self.scenarioList().length / self.listDisplayCount) {
      list.push({'displayIndex': '...', 'listIndex': null });
      list.push({'displayIndex': '»', 'listIndex': null });

    }
    if (self.listStart() > self.listDisplayCount) {
      list.shift({'displayIndex': '«', 'listIndex': null });
    }
    return list;
  });

  self.setListIndex = function (button, event) {
    var listStart = self.listStart();
    if (button.displayIndex === '»') {
      self.listStart(listStart + self.listDisplayCount * 5);
    } else {
    self.listStart(button.listIndex);
    }
    self.selectFeature(self.scenarioList()[button.listIndex || self.listStart()]);
  };

  self.showScenarioForm = function(action, uid) {
    // get the form
    var formUrl;
    if (action === "create") {
      formUrl = app.workspace["feature-classes"][0]["link-relations"]["create"]["uri-template"];
    } else if (action === "edit") {
      formUrl = app.workspace["feature-classes"][0]["link-relations"]["edit"][0]["uri-template"];
      formUrl = formUrl.replace('{uid}', uid);
    }
    // clean up and show the form
    var jqxhr = $.get(formUrl, function(data) {
      var $form = $(data).find('form');
      $form.find('input:submit').remove();
      // app.cleanupForm($form);
      $('#scenarios-form-container').empty().append(data);
      self.showScenarioFormPanel(true);
      $form.find('input:visible:first').focus();
      $form.bind('submit', function(event) {
        event.preventDefault();
      });
    })
    .success( function() {
        selectFeatureControl.unselectAll();
        selectGeographyControl.activate();
        self.showScenarioList(false);
        // TODO geography control -> if edit, select the selectedFeature's possible_fids
        self.selectedFeature(false);
        self.showScenarioList(false);
    })
    .error( function() { self.formLoadError(true); } )
    .complete( function() { self.formLoadComplete(true); } )
  };

  self.updateScenario = function(scenario_id, isNew) {
    var updateUrl = '/features/generic-links/links/geojson/{uid}/'.replace('{uid}', scenario_id);
    $.get(updateUrl, function(data) {
      if (isNew) {
        self.scenarioList.unshift(ko.mapping.fromJS(data.features[0].properties));
        self.selectedFeature(self.scenarioList()[0]);
      } else {
        ko.mapping.fromJS(data.features[0].properties, self.selectedFeature());
        self.showScenarioFormPanel(false);
        self.showScenarioList(true);
      }
    });
  };

  self.associateScenario = function(scenario_id, property_id) {
    var url = "/features/folder/{folder_uid}/add/{scenario_uid}";
    url = url.replace('{folder_uid}', property_id).replace('{scenario_uid}', scenario_id);
    $.ajax({
      url: url,
      type: "POST",
      success: function(data) {
        self.updateScenario(JSON.parse(data)["X-Madrona-Select"], true);
        app.scenarios.viewModel.showScenarioFormPanel(false);
        app.scenarios.viewModel.showScenarioList(true);
        app.new_features.removeAllFeatures();
      }
    });
  };

  self.saveScenarioForm = function(self, event) {
      // pass
  };

  self.OLDsaveScenarioForm = function(self, event) {
    var isNew, $dialog = $('#scenarios-form-container'),
      $form = $dialog.find('form'),
      actionUrl = $form.attr('action'),
      values = {},
      error = false;
    $form.find('input,select').each(function() {
      var $input = $(this);
      if ($input.closest('.field').hasClass('required') && $input.attr('type') !== 'hidden' && !$input.val()) {
        error = true;
        $input.closest('.control-group').addClass('error');
        $input.siblings('p.help-block').text('This field is required.');
      } else {
        values[$input.attr('name')] = $input.val();
      }
    });
    if (error) {
      return false;
    }
    if (self.modifyFeature.active) {
      values.geometry_final = values.geometry_orig = self.modifyFeature.feature.geometry.toString();
      self.modifyFeature.deactivate();
      isNew = false;
    } else {
      //values.geometry_final = values.geometry_orig = app.scenarios.geometry;
      values.geometry_orig = app.scenarios.geometry;
      isNew = true;
    }
    $form.addClass('form-horizontal');
    $.ajax({
      url: actionUrl,
      type: "POST",
      data: values,
      success: function(data, textStatus, jqXHR) {
        var scenario_uid = JSON.parse(data)["X-Madrona-Select"];
        if (isNew) {
          self.associateScenario(scenario_uid, self.property.uid());
        } else {
          self.updateScenario(scenario_uid, false);
        }
      },
      error: function(jqXHR, textStatus, errorThrown) {
        self.cancelAddScenario();
      }
    });
  };

  self.showDeleteDialog = function () {
    $("#scenario-delete-dialog").modal("show");
  };

  self.closeDialog = function () {
    $("#scenario-delete-dialog").modal("hide");
  };

  self.deleteFeature = function () {
    var url = "/features/generic-links/links/delete/{uid}/".replace("{uid}", self.selectedFeature().uid());
    $('#scenario-delete-dialog').modal('hide');
    $.ajax({
      url: url,
      type: "DELETE",
      success: function (data, textStatus, jqXHR) {
        self.scenarioList.remove(self.selectedFeature());
        self.selectedFeature(false);
        self.showScenarioList(true);
        self.selectControl.unselectAll();
      }
    });
  };

  // start the scenario editing process
  self.editScenario = function() {
    self.formLoadError(false);
    self.formLoadComplete(false);
    self.showScenarioForm("edit", self.selectedFeature().uid());
  };

  self.addScenarioStart = function() {
    self.formLoadError(false);
    self.formLoadComplete(false);
    self.showScenarioForm('create');
    /*
     * Do this only on success
    selectFeatureControl.unselectAll();
    selectGeographyControl.activate();
    self.showScenarioList(false);
    */
  };

  self.cancelAddScenario = function () {
    selectGeographyControl.unselectAll();
    selectGeographyControl.deactivate();
    self.showScenarioFormPanel(false);
    self.showScenarioList(true);
  };

  self.mode = function(m) {
    switch (m) {
        case 'scenarioList':
            break;
        case 'scenarioDetail':
            break;
        case 'scenarioEdit':
            break;
    }
  };

  self.selectControl = {
      /*
       * Controls the map and display panel
       * when features are selected
       */
      unselectAll: function() {
        // $('#scenario-show-container').empty();
      },
      select: function(feature) {

        var uid = feature.uid();
        var showUrl = app.workspace["feature-classes"][0]["link-relations"]["self"]["uri-template"];
        showUrl = showUrl.replace('{uid}', uid);

        self.reportLoadError(false);
        self.reportLoadComplete(false);
        var jqxhr = $.get(showUrl, function(data) {
          var elem = document.getElementById('scenario-show-container');
          ko.cleanNode(elem);
          $('#scenario-show-container').empty().append(data);
          app.scenarios.progressViewModel = null;
          clearInterval(app.timer);
          app.timer = null;
          app.scenarios.progressViewModel = new progressViewModel();

          ko.applyBindings(app.scenarios.progressViewModel, elem);
          app.scenarios.progressViewModel.checkTimer();
        })
        .error(function() { self.reportLoadError(true); })
        .complete(function() { self.reportLoadComplete(true); })

        selectFeatureControl.unselectAll();
        $.each(feature.selected_fids(), function (i, fid) {
            var f = pu_layer.getFeaturesByAttribute("fid",fid)[0];
            if (!f) {
                console.log("warning: fid " + fid + " is not valid");
            }
            selectFeatureControl.select(f);
        });
      }
   };

  self.selectFeature = function(feature, event) {
    self.selectControl.unselectAll();
    self.selectControl.select(feature);
    self.selectedFeature(feature);
    bbox = feature.bbox();
    if (bbox && bbox.length === 4) {
        map.zoomToExtent(bbox);
    }
    self.showScenarioList(false);
  };

  self.selectFeatureById = function (id) {
    var pageSize = self.scenarioList().length / self.listDisplayCount;
    $.each(self.scenarioList(), function (i, feature) {
      if (feature.uid() === id) {
        // set list start to first in list page
        self.listStart(Math.floor(i / self.listDisplayCount) * self.listDisplayCount);
        self.selectedFeature(this);
      }
    });
  };

  self.reloadScenarios = function(property) {
    console.log("reloadScenarios");
    self.scenarioList.removeAll();
    self.loadScenarios();
  };

  self.loadViewModel = function (data) {
    self.scenarioList($.map(data.features, function (feature, i) {
      return ko.mapping.fromJS(feature.properties);
    }));
    // Don't bother selecting the first feature
    //self.selectFeature(self.scenarioList()[0]);
  };

  self.loadScenarios = function() {
    var process = function(data) {
      if (data.features && data.features.length) {
        self.loadViewModel(data);
      }
    };
    var jqhxr = $.get('/seak/scenarios.geojson',
        process
    )
    .error(function() { self.scenarioLoadError(true); })
    .complete(function() { self.scenarioLoadComplete(true); })

  };

  self.backToScenarioList = function() {
    selectFeatureControl.unselectAll();
    self.selectedFeature(false);
    self.showScenarioList(true);
  };

  return self;
}
<|endoftext|>


<commit_before>InstantClick.on('change', function(isInitialLoad) {
    if (isInitialLoad === false) {
        if (typeof _hmt !== 'undefined')  // support 百度统计
            _hmt.push(['_trackPageview', location.pathname + location.search]);
        if (typeof ga !== 'undefined')  // support google analytics
            ga('send', 'pageview', location.pathname + location.search);
    }
});
InstantClick.init();<commit_msg>fix support baidu analysis<commit_after>$(function(){
    InstantClick.on('change', function(isInitialLoad) {
        if (isInitialLoad === false) {
            if (typeof _hmt !== 'undefined')  // support 百度统计
                _hmt.push(['_trackPageview', location.pathname + location.search]);
            if (typeof ga !== 'undefined')  // support google analytics
                ga('send', 'pageview', location.pathname + location.search);
        }
    });
    InstantClick.init();
});<|endoftext|>


<commit_before>/* eslint react/no-multi-comp: 0, react/prop-types: 0 */
import React from 'react';
import { Link } from 'react-router';
import { PrismCode } from 'react-prism';
import Helmet from 'react-helmet';
import {
  Dropdown,
  DropdownToggle,
  DropdownItem,
  DropdownMenu } from 'reactstrap';
import DropdownExample from '../examples/Dropdown';
import DropdownSizingExample from '../examples/DropdownSizing';
import CustomDropdownExample from '../examples/CustomDropdown';
import DropdownUncontrolledExample from '../examples/DropdownUncontrolled';

const DropdownExampleSource = require('!!raw!../examples/Dropdown');
const CustomDropdownExampleSource = require('!!raw!../examples/CustomDropdown');
const DropdownUncontrolledExampleSource = require('!!raw!../examples/DropdownUncontrolled');

export default class DropdownPage extends React.Component {
  constructor(props) {
    super(props);

    this.toggleExample2 = this.toggle.bind(this);
    this.state = {
      example2: false
    };
  }

  toggle() {
    this.setState({
      example2: !this.state.example2
    });
  }

  render() {
    return (

        <Helmet title="Dropdowns" />

Dropdowns

          The Dropdown component is used to pass the isOpen & toggle props via context to the following components: DropdownToggle, DropdownMenu. The DropdownToggle uses the Button component internally, meaning it also accepts all the props the <Link to="/components/buttons/">Button component</Link> accepts.

          <DropdownExample />

          <PrismCode className="language-jsx">
            {DropdownExampleSource}
          </PrismCode>

Properties

          <PrismCode className="language-jsx">
{`Dropdown.propTypes = {
  disabled: PropTypes.bool,
  dropup: PropTypes.bool,
  group: PropTypes.bool,
  isOpen: PropTypes.bool,
  tag: PropTypes.string, // default: 'div'
  toggle: PropTypes.func
};

DropdownToggle.propTypes = {
  caret: PropTypes.bool,
  color: PropTypes.string,
  className: PropTypes.string,
  disabled: PropTypes.bool,
  onClick: PropTypes.func,
  'data-toggle': PropTypes.string,
  'aria-haspopup': PropTypes.bool,
  // For DropdownToggle usage inside a Nav
  nav: PropTypes.bool,
  // Defaults to Button component
  tag: PropTypes.any
};

DropdownMenu.propTypes = {
  tag: PropTypes.string,
  children: PropTypes.node.isRequired,
  right: PropTypes.bool,
  flip: PropTypes.bool, // default: true,
  className: PropTypes.string,
  cssModule: PropTypes.object,
};`}
          </PrismCode>

Alignment

To align the DropdownMenu to the right, add a right prop to Dropdown.

            <Dropdown isOpen={this.state.example2} toggle={this.toggleExample2}>
              <DropdownToggle caret>
                This dropdown's menu is right-aligned
              </DropdownToggle>
              <DropdownMenu right>
                <DropdownItem header>Header</DropdownItem>
                <DropdownItem disabled>Action</DropdownItem>
                <DropdownItem>Another Action</DropdownItem>
                <DropdownItem divider />
                <DropdownItem>Another Action</DropdownItem>
              </DropdownMenu>
            </Dropdown>

          <PrismCode className="language-jsx">
{`<Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
  <DropdownToggle caret>
    This dropdown's menu is right-aligned
  </DropdownToggle>
  <DropdownMenu right>
    <DropdownItem header>Header</DropdownItem>
    <DropdownItem disabled>Action</DropdownItem>
    <DropdownItem>Another Action</DropdownItem>
    <DropdownItem divider/>
    <DropdownItem>Another Action</DropdownItem>
  </DropdownMenu>
</Dropdown>`}
          </PrismCode>

Menu Headers

          <PrismCode className="language-jsx">
{'<DropdownItem header>Header</DropdownItem>'}
          </PrismCode>

Menu Dividers

          <PrismCode className="language-jsx">
{'<DropdownItem divider/>'}
          </PrismCode>

Menu Items

          <PrismCode className="language-jsx">
{'<DropdownItem>Action</DropdownItem>'}
          </PrismCode>

Disabled Menu Items

          <PrismCode className="language-jsx">
{'<DropdownItem disabled>Action</DropdownItem>'}
          </PrismCode>

Sizing

            <DropdownSizingExample group size="lg" />
            <DropdownSizingExample className="mt-1" />
            <DropdownSizingExample className="mt-1" group size="sm" />

          <PrismCode className="language-jsx">
{`<Dropdown group isOpen={this.state.dropdownOpen} size="lg" toggle={this.toggle}>
  <DropdownToggle caret>
    Dropdown
  </DropdownToggle>
  <DropdownMenu>
    ...
  </DropdownMenu>
</Dropdown>

<Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
  <DropdownToggle caret>
    Dropdown
  </DropdownToggle>
  <DropdownMenu>
    ...
  </DropdownMenu>
</Dropdown>

<Dropdown group isOpen={this.state.dropdownOpen} size="sm" toggle={this.toggle}>
  <DropdownToggle caret>
    Dropdown
  </DropdownToggle>
  <DropdownMenu>
    ...
  </DropdownMenu>
</Dropdown>`}
          </PrismCode>

Custom Dropdown

          <CustomDropdownExample />

          <PrismCode className="language-jsx">
            {CustomDropdownExampleSource}
          </PrismCode>

Uncontrolled Dropdown

          For the most basic use-case an uncontrolled component can provide the functionality wanted without the need to manage/control the state of the component. UncontrolledDropdown does not require isOpen nor toggle props to work. For the other Dropdown flavors, ButtonDropdown, NavDropdown, uncontrolled components have been made as well; UncontrolledButtonDropdown, UncontrolledNavDropdown respectfully.

          <DropdownUncontrolledExample />

          <PrismCode className="language-jsx">
            {DropdownUncontrolledExampleSource}
          </PrismCode>

    );
  }
}
<commit_msg>docs(DropdownItem): add DropItem props section (#635)<commit_after>/* eslint react/no-multi-comp: 0, react/prop-types: 0 */
import React from 'react';
import { Link } from 'react-router';
import { PrismCode } from 'react-prism';
import Helmet from 'react-helmet';
import {
  Dropdown,
  DropdownToggle,
  DropdownItem,
  DropdownMenu } from 'reactstrap';
import DropdownExample from '../examples/Dropdown';
import DropdownSizingExample from '../examples/DropdownSizing';
import CustomDropdownExample from '../examples/CustomDropdown';
import DropdownUncontrolledExample from '../examples/DropdownUncontrolled';

const DropdownExampleSource = require('!!raw!../examples/Dropdown');
const CustomDropdownExampleSource = require('!!raw!../examples/CustomDropdown');
const DropdownUncontrolledExampleSource = require('!!raw!../examples/DropdownUncontrolled');

export default class DropdownPage extends React.Component {
  constructor(props) {
    super(props);

    this.toggleExample2 = this.toggle.bind(this);
    this.state = {
      example2: false
    };
  }

  toggle() {
    this.setState({
      example2: !this.state.example2
    });
  }

  render() {
    return (

        <Helmet title="Dropdowns" />

Dropdowns

          The Dropdown component is used to pass the isOpen & toggle props via context to the following components: DropdownToggle, DropdownMenu. The DropdownToggle uses the Button component internally, meaning it also accepts all the props the <Link to="/components/buttons/">Button component</Link> accepts.

          <DropdownExample />

          <PrismCode className="language-jsx">
            {DropdownExampleSource}
          </PrismCode>

Properties

          <PrismCode className="language-jsx">
{`Dropdown.propTypes = {
  disabled: PropTypes.bool,
  dropup: PropTypes.bool,
  group: PropTypes.bool,
  isOpen: PropTypes.bool,
  tag: PropTypes.string, // default: 'div'
  toggle: PropTypes.func
};

DropdownToggle.propTypes = {
  caret: PropTypes.bool,
  color: PropTypes.string,
  className: PropTypes.string,
  disabled: PropTypes.bool,
  onClick: PropTypes.func,
  'data-toggle': PropTypes.string,
  'aria-haspopup': PropTypes.bool,
  // For DropdownToggle usage inside a Nav
  nav: PropTypes.bool,
  // Defaults to Button component
  tag: PropTypes.any
};

DropdownMenu.propTypes = {
  tag: PropTypes.string,
  children: PropTypes.node.isRequired,
  right: PropTypes.bool,
  flip: PropTypes.bool, // default: true,
  className: PropTypes.string,
  cssModule: PropTypes.object,
};

DropdownItem.propTypes = {
  children: PropTypes.node,
  active: PropTypes.bool,
  disabled: PropTypes.bool,
  divider: PropTypes.bool,
  tag: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
  header: PropTypes.bool,
  onClick: PropTypes.func,
  className: PropTypes.string,
  cssModule: PropTypes.object,
  toggle: PropTypes.bool // default: true
};`}
          </PrismCode>

Alignment

To align the DropdownMenu to the right, add a right prop to Dropdown.

            <Dropdown isOpen={this.state.example2} toggle={this.toggleExample2}>
              <DropdownToggle caret>
                This dropdown's menu is right-aligned
              </DropdownToggle>
              <DropdownMenu right>
                <DropdownItem header>Header</DropdownItem>
                <DropdownItem disabled>Action</DropdownItem>
                <DropdownItem>Another Action</DropdownItem>
                <DropdownItem divider />
                <DropdownItem>Another Action</DropdownItem>
              </DropdownMenu>
            </Dropdown>

          <PrismCode className="language-jsx">
{`<Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
  <DropdownToggle caret>
    This dropdown's menu is right-aligned
  </DropdownToggle>
  <DropdownMenu right>
    <DropdownItem header>Header</DropdownItem>
    <DropdownItem disabled>Action</DropdownItem>
    <DropdownItem>Another Action</DropdownItem>
    <DropdownItem divider/>
    <DropdownItem>Another Action</DropdownItem>
  </DropdownMenu>
</Dropdown>`}
          </PrismCode>

Menu Headers

          <PrismCode className="language-jsx">
{'<DropdownItem header>Header</DropdownItem>'}
          </PrismCode>

Menu Dividers

          <PrismCode className="language-jsx">
{'<DropdownItem divider/>'}
          </PrismCode>

Menu Items

          <PrismCode className="language-jsx">
{'<DropdownItem>Action</DropdownItem>'}
          </PrismCode>

Disabled Menu Items

          <PrismCode className="language-jsx">
{'<DropdownItem disabled>Action</DropdownItem>'}
          </PrismCode>

Sizing

            <DropdownSizingExample group size="lg" />
            <DropdownSizingExample className="mt-1" />
            <DropdownSizingExample className="mt-1" group size="sm" />

          <PrismCode className="language-jsx">
{`<Dropdown group isOpen={this.state.dropdownOpen} size="lg" toggle={this.toggle}>
  <DropdownToggle caret>
    Dropdown
  </DropdownToggle>
  <DropdownMenu>
    ...
  </DropdownMenu>
</Dropdown>

<Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
  <DropdownToggle caret>
    Dropdown
  </DropdownToggle>
  <DropdownMenu>
    ...
  </DropdownMenu>
</Dropdown>

<Dropdown group isOpen={this.state.dropdownOpen} size="sm" toggle={this.toggle}>
  <DropdownToggle caret>
    Dropdown
  </DropdownToggle>
  <DropdownMenu>
    ...
  </DropdownMenu>
</Dropdown>`}
          </PrismCode>

Custom Dropdown

          <CustomDropdownExample />

          <PrismCode className="language-jsx">
            {CustomDropdownExampleSource}
          </PrismCode>

Uncontrolled Dropdown

          For the most basic use-case an uncontrolled component can provide the functionality wanted without the need to manage/control the state of the component. UncontrolledDropdown does not require isOpen nor toggle props to work. For the other Dropdown flavors, ButtonDropdown, NavDropdown, uncontrolled components have been made as well; UncontrolledButtonDropdown, UncontrolledNavDropdown respectfully.

          <DropdownUncontrolledExample />

          <PrismCode className="language-jsx">
            {DropdownUncontrolledExampleSource}
          </PrismCode>

    );
  }
}
<|endoftext|>


<commit_before>const discord = require('discord.js');
const client = new discord.Client();

function botLog(msg) {
    console.log(`Bot: ${msg}`)
}

function userLog(server, nick, msg) {
    console.log(`[${server}] User ${nick}: ${msg}`);
}

function stringToEmojis(string) {
    let result = [];
    string.split('').forEach(function (c) {
        if (c.search(/a-z/)) {
            let aCode = 97; //https://unicode-table.com/en/0061/
            let regionalIndicatorACode = 127462; //https://unicode-table.com/en/1F1E6/
            let emojiCode = regionalIndicatorACode + c.charCodeAt(0) - aCode;
            result.push(String.fromCodePoint(emojiCode));
        }
    });
    return result;
}

client.on('ready', () => {
	botLog('Ready!');
	client.user.setGame('służę pomocą!');
	client.user.setAvatar('./avatar3.png');
});

client.on('message', message => {
	if(message.author.bot) return;

    let content = message.content;
    let command = message.content.toLowerCase();
    let nick = message.author.username;
    let channel = message.channel;
    let server = message.guild.name;

    switch (command) {
        case '.ping':
            userLog(server, nick, 'command PING');
            message.reply('pong!');
            break;
        case '.pong':
            userLog(server, nick, 'command PONG');
            message.reply('ping!');
            break;
        case 'hi kuvu!':
	case 'cześć kuvu!':
            userLog(server, nick, 'command HI_KUVU');
            channel.sendMessage('Hi ' + message.author.username + '!');
            break;
        case '#reklama':
            userLog(server, nick, 'command REKLAMA');
            message.delete();
            channel.sendMessage('Zapraszam do zapoznania się z innymi projektami mojego stwórcy!\nStrona www: https://kuvus.pl');
            break;
        case '.pomoc':
        case '.help':
            userLog(server, nick, 'command HELP');
            message.author.sendMessage('Oto lista komend:\n```.pomoc - wyświetla pomoc\n.ping - wysyła wiadomość o treści ping\n.avatar - wysyła adres URL do twojego avatara\n.servers - Lista serwerów używających kuvuBota```');
            message.reply('lista komend została wysłana na PW!');
            break;
        case '.servers':
        case '.serwery':
            userLog(server, nick, 'command SERVERS');
			let serversMessage = 'serwery, które używają kuvuBota: \n' + '```' + client.guilds.map(r => '\n' + r.name.replace(/["`"]/g, "").replace(/^\s*/g, "") + ' (#' + r.id + ')') + '```';
            message.reply(serversMessage);
            break;
        default:
            if (command.startsWith('.avatar')) {
                userLog(server, nick, 'command AVATAR');
                let users = message.mentions.users;
                if (users.first()) {
                    let result = '';
                    users.forEach(function (user) {
                        result += user.avatarURL + '\n';
                    });
                    message.reply(result);
                } else {
                    message.reply(message.author.avatarURL);
                }
            } else if (command.startsWith('.text')) {
                userLog(server, nick, 'command TEXT');

                let reply = '';
                let splitted = command.split(' ');
                if (splitted.length == 1) {
                    message.reply('użycie: .text <tekst>');
                } else {
                    for (let i = 1; i < splitted.length; i++) {
                        reply += stringToEmojis(splitted[i]).join(' ') + '   ';
                    }
                }
                channel.sendMessage(reply);
            } else if (command.startsWith('.rawtext')) {
                userLog(server, nick, 'command RAWTEXT');

                let reply = '```';
                let splitted = command.split(' ');
                if (splitted.length == 1) {
                    message.reply('użycie: .rawtext <tekst>');
                } else {
                    for (let i = 1; i < splitted.length; i++) {
                        splitted[i].split('').forEach(function (c) {
                            if (c.search(/a-z/)) {
                                reply += `:regional_indicator_${c}: `;
                            }
                        });
                        reply += '   ';
                    }
                    reply += '```';
                    message.reply(reply);
                }
            } else if (command.startsWith('.react')) {
                userLog(server, nick, 'command REACT');

                let splitted = command.split(' ');
                let emojis = [];
                if (splitted.length == 1) {
                    message.reply('użycie: .react <tekst>');
                } else {
                    for (let i = 1; i < splitted.length; i++) {
                        emojis = emojis.concat(stringToEmojis(splitted[i]));
                    }
                }

                let react = function(i) {
                    if (i < emojis.length) {
                        message.react(emojis[i]).then(function() { react(i + 1); });
                    }
                }
                react(0);
            }
    }
});

client.login('<TOKEN>');
<commit_msg>Bugfix #2<commit_after>const discord = require('discord.js');
const client = new discord.Client();

function botLog(msg) {
    console.log(`Bot: ${msg}`)
}

function userLog(server, nick, msg) {
    console.log(`[${server}] User ${nick}: ${msg}`);
}

function stringToEmojis(string) {
    let result = [];
    string.split('').forEach(function (c) {
        if (c.search(/a-z/)) {
            let aCode = 97; //https://unicode-table.com/en/0061/
            let regionalIndicatorACode = 127462; //https://unicode-table.com/en/1F1E6/
            let emojiCode = regionalIndicatorACode + c.charCodeAt(0) - aCode;
            result.push(String.fromCodePoint(emojiCode));
        }
    });
    return result;
}

client.on('ready', () => {
	botLog('Ready!');
	client.user.setGame('służę pomocą!');
	client.user.setAvatar('./avatar3.png');
});

client.on('message', message => {
	if(message.author.bot) return;

    let content = message.content;
    let command = message.content.toLowerCase();
    let nick = message.author.username;
    let channel = message.channel;
	var server;
	if (channel.type == "text") {
        server = message.guild.name;
	}
	else {
		server = "Private Message";
	}

    switch (command) {
        case '.ping':
            userLog(server, nick, 'command PING');
            message.reply('pong!');
            break;
        case '.pong':
            userLog(server, nick, 'command PONG');
            message.reply('ping!');
            break;
        case 'hi kuvu!':
	case 'cześć kuvu!':
            userLog(server, nick, 'command HI_KUVU');
            channel.sendMessage('Hi ' + message.author.username + '!');
            break;
        case '#reklama':
            userLog(server, nick, 'command REKLAMA');
            message.delete();
            channel.sendMessage('Zapraszam do zapoznania się z innymi projektami mojego stwórcy!\nStrona www: https://kuvus.pl');
            break;
        case '.pomoc':
        case '.help':
            userLog(server, nick, 'command HELP');
            message.author.sendMessage('Oto lista komend:\n```.pomoc - wyświetla pomoc\n.ping - wysyła wiadomość o treści ping\n.avatar - wysyła adres URL do twojego avatara\n.servers - Lista serwerów używających kuvuBota```');
            message.reply('lista komend została wysłana na PW!');
            break;
        case '.servers':
        case '.serwery':
            userLog(server, nick, 'command SERVERS');
			let serversMessage = 'serwery, które używają kuvuBota: \n' + '```' + client.guilds.map(r => '\n' + r.name.replace(/["`"]/g, "").replace(/^\s*/g, "") + ' (#' + r.id + ')') + '```';
            message.reply(serversMessage);
            break;
        default:
            if (command.startsWith('.avatar')) {
                userLog(server, nick, 'command AVATAR');
                let users = message.mentions.users;
                if (users.first()) {
                    let result = '';
                    users.forEach(function (user) {
                        result += user.avatarURL + '\n';
                    });
                    message.reply(result);
                } else {
                    message.reply(message.author.avatarURL);
                }
            } else if (command.startsWith('.text')) {
                userLog(server, nick, 'command TEXT');

                let reply = '';
                let splitted = command.split(' ');
                if (splitted.length == 1) {
                    message.reply('użycie: .text <tekst>');
                } else {
                    for (let i = 1; i < splitted.length; i++) {
                        reply += stringToEmojis(splitted[i]).join(' ') + '   ';
                    }
                }
                channel.sendMessage(reply);
            } else if (command.startsWith('.rawtext')) {
                userLog(server, nick, 'command RAWTEXT');

                let reply = '```';
                let splitted = command.split(' ');
                if (splitted.length == 1) {
                    message.reply('użycie: .rawtext <tekst>');
                } else {
                    for (let i = 1; i < splitted.length; i++) {
                        splitted[i].split('').forEach(function (c) {
                            if (c.search(/a-z/)) {
                                reply += `:regional_indicator_${c}: `;
                            }
                        });
                        reply += '   ';
                    }
                    reply += '```';
                    message.reply(reply);
                }
            } else if (command.startsWith('.react')) {
                userLog(server, nick, 'command REACT');

                let splitted = command.split(' ');
                let emojis = [];
                if (splitted.length == 1) {
                    message.reply('użycie: .react <tekst>');
                } else {
                    for (let i = 1; i < splitted.length; i++) {
                        emojis = emojis.concat(stringToEmojis(splitted[i]));
                    }
                }

                let react = function(i) {
                    if (i < emojis.length) {
                        message.react(emojis[i]).then(function() { react(i + 1); });
                    }
                }
                react(0);
            }
    }
});

client.login('<TOKEN>');
<|endoftext|>


<commit_before>// Form for comment creation and edit
var ui = require('tresdb-ui');
var emitter = require('component-emitter');
var updateHint = require('./updateHint');
var template = require('./template.ejs');
var entryApi = tresdb.stores.entries;

var MIN_LEN = tresdb.config.comments.minMessageLength;
var MAX_LEN = tresdb.config.comments.maxMessageLength;

module.exports = function (entry, comment) {
  // Parameters
  //   entry
  //     entry object
  //   comment
  //     optional comment object. Leave empty for comment creation.
  //

  // Setup
  var $mount = null;
  var children = {};
  var $elems = {};
  var self = this;
  emitter(self);

  // Comment creation vs comment edit
  var isNew = false;
  if (!comment) {
    isNew = true;
    comment = {
      markdown: '',
      attachments: [],
    };
  }

  self.bind = function ($mountEl) {
    $mount = $mountEl;

    $mount.html(template({
      isNew: isNew,
      markdown: comment.markdown,
    }));

    // Cancel button
    $elems.cancel = $mount.find('.comment-form-cancel');
    $elems.cancel.click(function () {
      self.emit('exit');
    });

    // Focus to message
    $elems.message = $mount.find('.comment-form-message');
    $elems.message.focus();

    // Setup message hint
    $elems.hint = $mount.find('.comment-form-hint');
    var handleHint = function () {
      var len = $elems.message.val().length;
      updateHint($elems.hint, len);
    };
    handleHint(); // init
    $elems.message.on('input', handleHint); // on text input

    // Delete button
    if (!isNew) {
      children.delete = { unbind: function () {} };
    }

    // Prepare progress bar and error for submission
    $elems.progress = $mount.find('.comment-form-progress');
    $elems.error = $mount.find('.comment-form-error');

    // Submit
    $elems.form = $mount.find('.entry-comment-form');
    $elems.form.submit(function (ev) {
      ev.preventDefault();

      var markdown = $elems.message.val().trim();
      var len = markdown.length;

      if (len < MIN_LEN || len > MAX_LEN) {
        // Do not submit if too short or long
        return;
      }

      // TODO Purge cache of unfinished comment

      // Hide form and reveal progress
      ui.hide($elems.form);
      ui.show($elems.progress);
      // Hide possible previous messages
      ui.hide($elems.error);

      var locId = entry.locationId;
      var entryId = entry._id;
      entryApi.createComment(locId, entryId, markdown, function (err) {
        // Show form and hide progress
        ui.show($elems.form);
        ui.hide($elems.progress);

        if (err) {
          // Display error
          $elems.error.html(err.message);
          ui.show($elems.error);
        } else {
          // Success.
          // Empty the message input for next comment
          $elems.message.val('');
          // Inform parent for example to unbind the form.
          self.emit('success');
        }
      });
    });
  };

  self.unbind = function () {
    if ($mount) {
      $mount = null;
      ui.unbindAll(children);
      children = {};
      ui.offAll($elems);
      $elems = {};
    }
  };
};
<commit_msg>Working comment editing<commit_after>// Form for comment creation and edit
var ui = require('tresdb-ui');
var emitter = require('component-emitter');
var updateHint = require('./updateHint');
var template = require('./template.ejs');
var entryApi = tresdb.stores.entries;

var MIN_LEN = tresdb.config.comments.minMessageLength;
var MAX_LEN = tresdb.config.comments.maxMessageLength;

module.exports = function (entry, comment) {
  // Parameters
  //   entry
  //     entry object
  //   comment
  //     optional comment object. Leave empty for comment creation.
  //

  // Setup
  var $mount = null;
  var children = {};
  var $elems = {};
  var self = this;
  emitter(self);

  // Comment creation vs comment edit
  var isNew = false;
  if (!comment) {
    isNew = true;
    comment = {
      markdown: '',
      attachments: [],
    };
  }

  var submit = function (markdown, attachments, callback) {
    var locId = entry.locationId;
    var entryId = entry._id;

    if (isNew) {
      entryApi.createComment({
        locationId: locId,
        entryId: entryId,
        markdown: markdown,
        attachments: attachments,
      }, callback);
    } else {
      entryApi.changeComment({
        locationId: locId,
        entryId: entryId,
        commentId: comment.id,
        markdown: markdown,
        attachments: attachments,
      }, callback);
    }
  };

  self.bind = function ($mountEl) {
    $mount = $mountEl;

    $mount.html(template({
      isNew: isNew,
      markdown: comment.markdown,
    }));

    // Cancel button
    $elems.cancel = $mount.find('.comment-form-cancel');
    $elems.cancel.click(function () {
      self.emit('exit');
    });

    // Focus to message
    $elems.message = $mount.find('.comment-form-message');
    $elems.message.focus();

    // Setup message hint
    $elems.hint = $mount.find('.comment-form-hint');
    var handleHint = function () {
      var len = $elems.message.val().length;
      updateHint($elems.hint, len);
    };
    handleHint(); // init
    $elems.message.on('input', handleHint); // on text input

    // Delete button
    if (!isNew) {
      children.delete = { unbind: function () {} };
    }

    // Prepare progress bar and error for submission
    $elems.progress = $mount.find('.comment-form-progress');
    $elems.error = $mount.find('.comment-form-error');

    // Submit
    $elems.form = $mount.find('.entry-comment-form');
    $elems.form.submit(function (ev) {
      ev.preventDefault();

      // Read message
      var markdown = $elems.message.val().trim();
      var len = markdown.length;

      if (len < MIN_LEN || len > MAX_LEN) {
        // Do not submit if too short or long
        return;
      }

      // Read attachments
      var attachments = [];

      // TODO Purge cache of unfinished comment

      // Hide form and reveal progress
      ui.hide($elems.form);
      ui.show($elems.progress);
      // Hide possible previous messages
      ui.hide($elems.error);

      submit(markdown, attachments, function (err) {
        // Show form and hide progress
        ui.show($elems.form);
        ui.hide($elems.progress);

        if (err) {
          // Display error
          $elems.error.html(err.message);
          ui.show($elems.error);
        } else {
          // Success.
          // Empty the message input for next comment
          $elems.message.val('');
          // Inform parent for example to unbind the form.
          self.emit('success');
        }
      });
    });
  };

  self.unbind = function () {
    if ($mount) {
      $mount = null;
      ui.unbindAll(children);
      children = {};
      ui.offAll($elems);
      $elems = {};
    }
  };
};
<|endoftext|>


<commit_before>Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
var XPCOMCoreVersion = '0.4.1'; // DO NOT REMOVE THIS COMMENT OR MOVE THIS LINE. THIS LINE IS AUTO-GENERATED FROM A RAKE TASK. @XPCOMCORE_VERSION@
const $Cc = Components.classes;
const $Ci = Components.interfaces;

var ioService = $Cc["@mozilla.org/network/io-service;1"].getService($Ci.nsIIOService);
var libRoot = ioService.newURI("resource://xpcomcore/lib", null, null).QueryInterface($Ci.nsIFileURL).file.path;
var binRoot = ioService.newURI("resource://xpcomcore/bin", null, null).QueryInterface($Ci.nsIFileURL).file.path;

// NOTE - XPCOMCore is a singleton
var XPCOMCore = function() {
  if (arguments.callee.__singletonInstance__) { return arguments.callee.__singletonInstance__; };

  // Private method that does the work of loading the XPCOMCore kernel
  // into the given scope.
  var loadKernel = function(importScope) {
    var loader = $Cc["@mozilla.org/moz/jssubscript-loader;1"].getService($Ci.mozIJSSubScriptLoader);
    loader.loadSubScript("resource://xpcomcore/lib/kernel.js", importScope);
  };

  // Private method to actually kick off the importing of kernel into the given
  // import scope.
  var import = function(importScope, importKernel) {
    if (importScope.__XPCOMCoreLoaded__) {
      return false;
    } else {
      loadKernel(importScope);
      // FIXME - defineGetter explodes when it's a 'Window' object for some reason. Fine for
      // ChromeWindow and fine for BackstagePass though. Weird.
      // importScope.__defineGetter__('__XPCOMCoreLoaded__', function() { return true; });
      importScope.__XPCOMCoreLoaded__ = true;
      // Automatically mix Kernel into the scope if importKernel is true
      if (importKernel) { importScope.Kernel(importScope); };
      return true;
    }
  };

  // FIXME - hack. hijacking the nsIWritableVariant interface so we can have a constructor that works
  // FIXME - and to boot, for reasons i dont understand, we wrap the scope in another object, hence the options
  // hash. which might be useful anyway.
  this.setFromVariant = function(options) {
    if (!options.scope) { return false; }
    return import(options.scope, !(options.importKernel === false));
  };

  arguments.callee.__singletonInstance__ = this;
  // HACK HACK HACK - this is so we can get a reference to the real constructor
  // from the bootstrapper.
  this.__specialConstructor__ = arguments.callee;
};

// FIXME - maybe? might not really be a 'bug'
// Bahaha - we rely on http://mxr.mozilla.org/mozilla1.8/source/js/src/xpconnect/src/xpcwrappedjsclass.cpp#528
// (as written about in http://weblogs.mozillazine.org/weirdal/archives/019778.html) to expose a getProperty
// method on this object to allow for getting arbitrary properties.
var XPCOMCoreInterfaces = [$Ci.nsIClassInfo, $Ci.nsIPropertyBag, $Ci.nsIWritableVariant];

XPCOMCore.prototype = {
  classDescription: "XPCOMCore Core Object",
  contractID: "@conflagrationjs.org/xpcomcore/core;1",
  classID: Components.ID("{f562f600-9c25-11de-8a39-0800200c9a66}"),
  QueryInterface: XPCOMUtils.generateQI(XPCOMCoreInterfaces),
  _xpcom_categories: [{category: "JavaScript global property", entry: "XPCOMCoreConfig"}],

  // implemented for nsIClassInfo
  getInterfaces: function(aCountRef) {
    aCountRef.value = XPCOMCoreInterfaces.length;
    return XPCOMCoreInterfaces;
  },

  // implemented for nsIClassInfo
  getHelperForLanguage: function(aLanguage) { return null; },

  // implemented for nsIClassInfo
  implementationLanguage: $Ci.nsIProgrammingLanguage.JAVASCRIPT,

  // implemented for nsIClassInfo
  flags: $Ci.nsIClassInfo.SINGLETON,

  get version() { return new String(XPCOMCoreVersion); },
  get libRoot() { return new String(libRoot); },
  get binRoot() { return new String(binRoot); }

};

var XPCOMCoreConstructorInterfaces = [$Ci.nsIClassInfo, $Ci.nsIXPCConstructor, $Ci.nsIXPCScriptable];

// Singleton
var XPCOMCoreConstructor = function() {
  if (arguments.callee.__singletonInstance__) { return arguments.callee.__singletonInstance__; };
  var ctor = Components.Constructor("@conflagrationjs.org/xpcomcore/core;1", Components.interfaces.nsIWritableVariant, "setFromVariant");
  arguments.callee.__singletonInstance__ = ctor;
  return ctor;
};

XPCOMCoreConstructor.prototype = {
  classDescription: "XPCOMCore Core Object Constructor Hack",
  contractID: "@conflagrationjs.org/xpcomcore/core-constructor;1",
  classID: Components.ID("{b5762b40-a0ec-11de-8a39-0800200c9a66}"),
  QueryInterface: XPCOMUtils.generateQI(XPCOMCoreConstructorInterfaces),
  _xpcom_categories: [{category: "JavaScript global property", entry: "XPCOMCore"}],

  // implemented for nsIClassInfo
  getInterfaces: function(aCountRef) {
    aCountRef.value = XPCOMCoreConstructorInterfaces.length;
    return XPCOMCoreConstructorInterfaces;
  },

  // implemented for nsIClassInfo
  getHelperForLanguage: function(aLanguage) { return null; },

  // implemented for nsIClassInfo
  implementationLanguage: $Ci.nsIProgrammingLanguage.JAVASCRIPT,

  // implemented for nsIClassInfo
  flags: $Ci.nsIClassInfo.SINGLETON
}

NSGetModule = function(compMgr, fileSpec) {
  return XPCOMUtils.generateModule([XPCOMCore, XPCOMCoreConstructor]);
};<commit_msg>Updating from build_properties.yml<commit_after>Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
var XPCOMCoreVersion = '0.5.1'; // DO NOT REMOVE THIS COMMENT OR MOVE THIS LINE. THIS LINE IS AUTO-GENERATED FROM A RAKE TASK. @XPCOMCORE_VERSION@const $Cc = Components.classes;
const $Ci = Components.interfaces;

var ioService = $Cc["@mozilla.org/network/io-service;1"].getService($Ci.nsIIOService);
var libRoot = ioService.newURI("resource://xpcomcore/lib", null, null).QueryInterface($Ci.nsIFileURL).file.path;
var binRoot = ioService.newURI("resource://xpcomcore/bin", null, null).QueryInterface($Ci.nsIFileURL).file.path;

// NOTE - XPCOMCore is a singleton
var XPCOMCore = function() {
  if (arguments.callee.__singletonInstance__) { return arguments.callee.__singletonInstance__; };

  // Private method that does the work of loading the XPCOMCore kernel
  // into the given scope.
  var loadKernel = function(importScope) {
    var loader = $Cc["@mozilla.org/moz/jssubscript-loader;1"].getService($Ci.mozIJSSubScriptLoader);
    loader.loadSubScript("resource://xpcomcore/lib/kernel.js", importScope);
  };

  // Private method to actually kick off the importing of kernel into the given
  // import scope.
  var import = function(importScope, importKernel) {
    if (importScope.__XPCOMCoreLoaded__) {
      return false;
    } else {
      loadKernel(importScope);
      // FIXME - defineGetter explodes when it's a 'Window' object for some reason. Fine for
      // ChromeWindow and fine for BackstagePass though. Weird.
      // importScope.__defineGetter__('__XPCOMCoreLoaded__', function() { return true; });
      importScope.__XPCOMCoreLoaded__ = true;
      // Automatically mix Kernel into the scope if importKernel is true
      if (importKernel) { importScope.Kernel(importScope); };
      return true;
    }
  };

  // FIXME - hack. hijacking the nsIWritableVariant interface so we can have a constructor that works
  // FIXME - and to boot, for reasons i dont understand, we wrap the scope in another object, hence the options
  // hash. which might be useful anyway.
  this.setFromVariant = function(options) {
    if (!options.scope) { return false; }
    return import(options.scope, !(options.importKernel === false));
  };

  arguments.callee.__singletonInstance__ = this;
  // HACK HACK HACK - this is so we can get a reference to the real constructor
  // from the bootstrapper.
  this.__specialConstructor__ = arguments.callee;
};

// FIXME - maybe? might not really be a 'bug'
// Bahaha - we rely on http://mxr.mozilla.org/mozilla1.8/source/js/src/xpconnect/src/xpcwrappedjsclass.cpp#528
// (as written about in http://weblogs.mozillazine.org/weirdal/archives/019778.html) to expose a getProperty
// method on this object to allow for getting arbitrary properties.
var XPCOMCoreInterfaces = [$Ci.nsIClassInfo, $Ci.nsIPropertyBag, $Ci.nsIWritableVariant];

XPCOMCore.prototype = {
  classDescription: "XPCOMCore Core Object",
  contractID: "@conflagrationjs.org/xpcomcore/core;1",
  classID: Components.ID("{f562f600-9c25-11de-8a39-0800200c9a66}"),
  QueryInterface: XPCOMUtils.generateQI(XPCOMCoreInterfaces),
  _xpcom_categories: [{category: "JavaScript global property", entry: "XPCOMCoreConfig"}],

  // implemented for nsIClassInfo
  getInterfaces: function(aCountRef) {
    aCountRef.value = XPCOMCoreInterfaces.length;
    return XPCOMCoreInterfaces;
  },

  // implemented for nsIClassInfo
  getHelperForLanguage: function(aLanguage) { return null; },

  // implemented for nsIClassInfo
  implementationLanguage: $Ci.nsIProgrammingLanguage.JAVASCRIPT,

  // implemented for nsIClassInfo
  flags: $Ci.nsIClassInfo.SINGLETON,

  get version() { return new String(XPCOMCoreVersion); },
  get libRoot() { return new String(libRoot); },
  get binRoot() { return new String(binRoot); }

};

var XPCOMCoreConstructorInterfaces = [$Ci.nsIClassInfo, $Ci.nsIXPCConstructor, $Ci.nsIXPCScriptable];

// Singleton
var XPCOMCoreConstructor = function() {
  if (arguments.callee.__singletonInstance__) { return arguments.callee.__singletonInstance__; };
  var ctor = Components.Constructor("@conflagrationjs.org/xpcomcore/core;1", Components.interfaces.nsIWritableVariant, "setFromVariant");
  arguments.callee.__singletonInstance__ = ctor;
  return ctor;
};

XPCOMCoreConstructor.prototype = {
  classDescription: "XPCOMCore Core Object Constructor Hack",
  contractID: "@conflagrationjs.org/xpcomcore/core-constructor;1",
  classID: Components.ID("{b5762b40-a0ec-11de-8a39-0800200c9a66}"),
  QueryInterface: XPCOMUtils.generateQI(XPCOMCoreConstructorInterfaces),
  _xpcom_categories: [{category: "JavaScript global property", entry: "XPCOMCore"}],

  // implemented for nsIClassInfo
  getInterfaces: function(aCountRef) {
    aCountRef.value = XPCOMCoreConstructorInterfaces.length;
    return XPCOMCoreConstructorInterfaces;
  },

  // implemented for nsIClassInfo
  getHelperForLanguage: function(aLanguage) { return null; },

  // implemented for nsIClassInfo
  implementationLanguage: $Ci.nsIProgrammingLanguage.JAVASCRIPT,

  // implemented for nsIClassInfo
  flags: $Ci.nsIClassInfo.SINGLETON
}

NSGetModule = function(compMgr, fileSpec) {
  return XPCOMUtils.generateModule([XPCOMCore, XPCOMCoreConstructor]);
};<|endoftext|>


<commit_before>import React, {Component, PropTypes} from 'react'

import _ from 'lodash'
import uuid from 'node-uuid'

import ResizeContainer, {
  ResizeBottom,
} from 'src/shared/components/ResizeContainer'
import QueryMaker from 'src/data_explorer/components/QueryMaker'
import Visualization from 'src/data_explorer/components/Visualization'
import OverlayControls from 'src/dashboards/components/OverlayControls'
import * as queryModifiers from 'src/utils/queryTransitions'

import defaultQueryConfig from 'src/utils/defaultQueryConfig'
import buildInfluxQLQuery from 'utils/influxql'
import {getQueryConfig} from 'shared/apis'

class CellEditorOverlay extends Component {
  constructor(props) {
    super(props)

    this.queryStateReducer = ::this.queryStateReducer

    this.handleAddQuery = ::this.handleAddQuery
    this.handleDeleteQuery = ::this.handleDeleteQuery

    this.handleSaveCell = ::this.handleSaveCell

    this.handleSelectGraphType = ::this.handleSelectGraphType
    this.handleSetActiveQueryIndex = ::this.handleSetActiveQueryIndex
    this.handleEditRawText = ::this.handleEditRawText

    const {cell: {name, type, queries}} = props

    const queriesWorkingDraft = _.cloneDeep(
      queries.map(({queryConfig}) => ({...queryConfig, id: uuid.v4()}))
    )

    this.state = {
      cellWorkingName: name,
      cellWorkingType: type,
      queriesWorkingDraft,
      activeQueryIndex: 0,
    }
  }

  componentWillReceiveProps(nextProps) {
    const {status, queryID} = this.props.queryStatus
    const nextStatus = nextProps.queryStatus
    if (nextStatus.status && nextStatus.queryID) {
      if (nextStatus.queryID !== queryID || nextStatus.status !== status) {
        const nextQueries = this.state.queriesWorkingDraft.map(
          q => (q.id === queryID ? {...q, status: nextStatus.status} : q)
        )
        this.setState({queriesWorkingDraft: nextQueries})
      }
    }
  }

  queryStateReducer(queryModifier) {
    return (queryID, payload) => {
      const {queriesWorkingDraft} = this.state
      const query = queriesWorkingDraft.find(q => q.id === queryID)

      const nextQuery = queryModifier(query, payload)

      const nextQueries = queriesWorkingDraft.map(
        q => (q.id === query.id ? nextQuery : q)
      )
      this.setState({queriesWorkingDraft: nextQueries})
    }
  }

  handleAddQuery(options) {
    const newQuery = Object.assign({}, defaultQueryConfig(uuid.v4()), options)
    const nextQueries = this.state.queriesWorkingDraft.concat(newQuery)
    this.setState({queriesWorkingDraft: nextQueries})
  }

  handleDeleteQuery(index) {
    const nextQueries = this.state.queriesWorkingDraft.filter(
      (__, i) => i !== index
    )
    this.setState({queriesWorkingDraft: nextQueries})
  }

  handleSaveCell() {
    const {queriesWorkingDraft, cellWorkingType, cellWorkingName} = this.state
    const {cell, timeRange} = this.props

    const newCell = _.cloneDeep(cell)
    newCell.name = cellWorkingName
    newCell.type = cellWorkingType
    newCell.queries = queriesWorkingDraft.map(q => {
      const query = q.rawText || buildInfluxQLQuery(timeRange, q)
      const label = q.rawText ? '' : `${q.measurement}.${q.fields[0].field}`

      return {
        queryConfig: q,
        query,
        label,
      }
    })

    this.props.onSave(newCell)
  }

  handleSelectGraphType(graphType) {
    this.setState({cellWorkingType: graphType})
  }

  handleSetActiveQueryIndex(activeQueryIndex) {
    this.setState({activeQueryIndex})
  }

  async handleEditRawText(url, id, text) {
    // use this as the handler passed into fetchTimeSeries to update a query status
    try {
      const {data} = await getQueryConfig(url, [{query: text, id}])
      const config = data.queries.find(q => q.id === id)
      const nextQueries = this.state.queriesWorkingDraft.map(
        q => (q.id === id ? config.queryConfig : q)
      )
      this.setState({queriesWorkingDraft: nextQueries})
    } catch (error) {
      console.error(error)
    }
  }

  render() {
    const {
      source,
      onCancel,
      templates,
      timeRange,
      autoRefresh,
      editQueryStatus,
    } = this.props

    const {
      activeQueryIndex,
      cellWorkingName,
      cellWorkingType,
      queriesWorkingDraft,
    } = this.state

    const queryActions = {
      addQuery: this.handleAddQuery,
      editRawTextAsync: this.handleEditRawText,
      ..._.mapValues(queryModifiers, qm => this.queryStateReducer(qm)),
    }

    return (

        <ResizeContainer>
          <Visualization
            autoRefresh={autoRefresh}
            timeRange={timeRange}
            templates={templates}
            queryConfigs={queriesWorkingDraft}
            activeQueryIndex={0}
            cellType={cellWorkingType}
            cellName={cellWorkingName}
            editQueryStatus={editQueryStatus}
            views={[]}
          />
          <ResizeBottom>

              <OverlayControls
                selectedGraphType={cellWorkingType}
                onSelectGraphType={this.handleSelectGraphType}
                onCancel={onCancel}
                onSave={this.handleSaveCell}
              />
              <QueryMaker
                source={source}
                templates={templates}
                queries={queriesWorkingDraft}
                actions={queryActions}
                autoRefresh={autoRefresh}
                timeRange={timeRange}
                setActiveQueryIndex={this.handleSetActiveQueryIndex}
                onDeleteQuery={this.handleDeleteQuery}
                activeQueryIndex={activeQueryIndex}
                layout="panel"
              />

          </ResizeBottom>
        </ResizeContainer>

    )
  }
}

const {arrayOf, func, number, shape, string} = PropTypes

CellEditorOverlay.propTypes = {
  onCancel: func.isRequired,
  onSave: func.isRequired,
  cell: shape({}).isRequired,
  templates: arrayOf(
    shape({
      tempVar: string.isRequired,
    })
  ).isRequired,
  timeRange: shape({
    upper: string,
    lower: string,
  }).isRequired,
  autoRefresh: number.isRequired,
  source: shape({
    links: shape({
      proxy: string.isRequired,
      queries: string.isRequired,
    }).isRequired,
  }).isRequired,
  editQueryStatus: func.isRequired,
  queryStatus: shape({
    queryID: string,
    status: shape({}),
  }).isRequired,
}

export default CellEditorOverlay
<commit_msg>Return Cell Edit to previous design<commit_after>import React, {Component, PropTypes} from 'react'

import _ from 'lodash'
import uuid from 'node-uuid'

import ResizeContainer, {
  ResizeBottom,
} from 'src/shared/components/ResizeContainer'
import QueryMaker from 'src/data_explorer/components/QueryMaker'
import Visualization from 'src/data_explorer/components/Visualization'
import OverlayControls from 'src/dashboards/components/OverlayControls'
import * as queryModifiers from 'src/utils/queryTransitions'

import defaultQueryConfig from 'src/utils/defaultQueryConfig'
import buildInfluxQLQuery from 'utils/influxql'
import {getQueryConfig} from 'shared/apis'

class CellEditorOverlay extends Component {
  constructor(props) {
    super(props)

    this.queryStateReducer = ::this.queryStateReducer

    this.handleAddQuery = ::this.handleAddQuery
    this.handleDeleteQuery = ::this.handleDeleteQuery

    this.handleSaveCell = ::this.handleSaveCell

    this.handleSelectGraphType = ::this.handleSelectGraphType
    this.handleSetActiveQueryIndex = ::this.handleSetActiveQueryIndex
    this.handleEditRawText = ::this.handleEditRawText

    const {cell: {name, type, queries}} = props

    const queriesWorkingDraft = _.cloneDeep(
      queries.map(({queryConfig}) => ({...queryConfig, id: uuid.v4()}))
    )

    this.state = {
      cellWorkingName: name,
      cellWorkingType: type,
      queriesWorkingDraft,
      activeQueryIndex: 0,
    }
  }

  componentWillReceiveProps(nextProps) {
    const {status, queryID} = this.props.queryStatus
    const nextStatus = nextProps.queryStatus
    if (nextStatus.status && nextStatus.queryID) {
      if (nextStatus.queryID !== queryID || nextStatus.status !== status) {
        const nextQueries = this.state.queriesWorkingDraft.map(
          q => (q.id === queryID ? {...q, status: nextStatus.status} : q)
        )
        this.setState({queriesWorkingDraft: nextQueries})
      }
    }
  }

  queryStateReducer(queryModifier) {
    return (queryID, payload) => {
      const {queriesWorkingDraft} = this.state
      const query = queriesWorkingDraft.find(q => q.id === queryID)

      const nextQuery = queryModifier(query, payload)

      const nextQueries = queriesWorkingDraft.map(
        q => (q.id === query.id ? nextQuery : q)
      )
      this.setState({queriesWorkingDraft: nextQueries})
    }
  }

  handleAddQuery(options) {
    const newQuery = Object.assign({}, defaultQueryConfig(uuid.v4()), options)
    const nextQueries = this.state.queriesWorkingDraft.concat(newQuery)
    this.setState({queriesWorkingDraft: nextQueries})
  }

  handleDeleteQuery(index) {
    const nextQueries = this.state.queriesWorkingDraft.filter(
      (__, i) => i !== index
    )
    this.setState({queriesWorkingDraft: nextQueries})
  }

  handleSaveCell() {
    const {queriesWorkingDraft, cellWorkingType, cellWorkingName} = this.state
    const {cell, timeRange} = this.props

    const newCell = _.cloneDeep(cell)
    newCell.name = cellWorkingName
    newCell.type = cellWorkingType
    newCell.queries = queriesWorkingDraft.map(q => {
      const query = q.rawText || buildInfluxQLQuery(timeRange, q)
      const label = q.rawText ? '' : `${q.measurement}.${q.fields[0].field}`

      return {
        queryConfig: q,
        query,
        label,
      }
    })

    this.props.onSave(newCell)
  }

  handleSelectGraphType(graphType) {
    this.setState({cellWorkingType: graphType})
  }

  handleSetActiveQueryIndex(activeQueryIndex) {
    this.setState({activeQueryIndex})
  }

  async handleEditRawText(url, id, text) {
    // use this as the handler passed into fetchTimeSeries to update a query status
    try {
      const {data} = await getQueryConfig(url, [{query: text, id}])
      const config = data.queries.find(q => q.id === id)
      const nextQueries = this.state.queriesWorkingDraft.map(
        q => (q.id === id ? config.queryConfig : q)
      )
      this.setState({queriesWorkingDraft: nextQueries})
    } catch (error) {
      console.error(error)
    }
  }

  render() {
    const {
      source,
      onCancel,
      templates,
      timeRange,
      autoRefresh,
      editQueryStatus,
    } = this.props

    const {
      activeQueryIndex,
      cellWorkingName,
      cellWorkingType,
      queriesWorkingDraft,
    } = this.state

    const queryActions = {
      addQuery: this.handleAddQuery,
      editRawTextAsync: this.handleEditRawText,
      ..._.mapValues(queryModifiers, qm => this.queryStateReducer(qm)),
    }

    return (

        <ResizeContainer>
          <Visualization
            autoRefresh={autoRefresh}
            timeRange={timeRange}
            templates={templates}
            queryConfigs={queriesWorkingDraft}
            activeQueryIndex={0}
            cellType={cellWorkingType}
            cellName={cellWorkingName}
            editQueryStatus={editQueryStatus}
            views={[]}
          />
          <ResizeBottom>

              <OverlayControls
                selectedGraphType={cellWorkingType}
                onSelectGraphType={this.handleSelectGraphType}
                onCancel={onCancel}
                onSave={this.handleSaveCell}
              />
              <QueryMaker
                source={source}
                templates={templates}
                queries={queriesWorkingDraft}
                actions={queryActions}
                autoRefresh={autoRefresh}
                timeRange={timeRange}
                setActiveQueryIndex={this.handleSetActiveQueryIndex}
                onDeleteQuery={this.handleDeleteQuery}
                activeQueryIndex={activeQueryIndex}
              />

          </ResizeBottom>
        </ResizeContainer>

    )
  }
}

const {arrayOf, func, number, shape, string} = PropTypes

CellEditorOverlay.propTypes = {
  onCancel: func.isRequired,
  onSave: func.isRequired,
  cell: shape({}).isRequired,
  templates: arrayOf(
    shape({
      tempVar: string.isRequired,
    })
  ).isRequired,
  timeRange: shape({
    upper: string,
    lower: string,
  }).isRequired,
  autoRefresh: number.isRequired,
  source: shape({
    links: shape({
      proxy: string.isRequired,
      queries: string.isRequired,
    }).isRequired,
  }).isRequired,
  editQueryStatus: func.isRequired,
  queryStatus: shape({
    queryID: string,
    status: shape({}),
  }).isRequired,
}

export default CellEditorOverlay
<|endoftext|>