<commit_before>import Class from "./class.js"
import _ from "../deps/underscore-1.10.2-esm.js"

//
// Set - set of string
// contents must be string (or at least sortable)
//
const BiwaSet = Class.create({
  initialize : function(/*args*/){
    this.arr = [];
    var i;
    for(i=0; i<arguments.length; i++)
      this.arr[i] = arguments[i];
  },

  equals : function(other){
    if(this.arr.length != other.arr.length)
      return false;

    var a1 = _.clone(this.arr);
    var a2 = _.clone(other.arr);
    a1.sort();
    a2.sort();
    for(var i=0; i<this.arr.length; i++){
      if(a1[i] != a2[i]) return false;
    }
    return true;
  },
  set_cons : function(item){
    var o = new BiwaSet(item);
    o.arr = _.clone(this.arr);
    o.arr.push(item);
    return o;
  },
  set_union : function(/*args*/){
    var o = new BiwaSet();
    o.arr = _.clone(this.arr);

    for(var k=0; k<arguments.length; k++){
      var s2 = arguments[k];
      if(!(s2 instanceof BiwaSet))
        throw new BiwaScheme.Error("set_union: arguments must be a set");

      for(var i=0; i<s2.arr.length; i++)
        o.add(s2.arr[i]);
    }
    return o;
  },
  set_intersect : function(s2){
    if(!(s2 instanceof BiwaSet))
      throw new BiwaScheme.Error("set_intersect: arguments must be a set");

    var o = new BiwaSet();
    for(var i=0; i<this.arr.length; i++)
      if(s2.member(this.arr[i]))
        o.add(this.arr[i]);
    return o;
  },
  set_minus : function(s2){
    if(!(s2 instanceof BiwaSet))
      throw new BiwaScheme.Error("set_minus: arguments must be a set");

    var o = new BiwaSet();
    for(var i=0; i<this.arr.length; i++)
      if(!s2.member(this.arr[i]))
        o.add(this.arr[i]);
    return o;
  },
  add : function(item){
    if(!this.member(item)){
      this.arr.push(item);
    }
  },
  member : function(item){
    for(var i=0; i<this.arr.length; i++)
      if(this.arr[i] == item) return true;

    return false;
  },
  rindex : function(item){
    for(var i=this.arr.length-1; i>=0 ; i--)
      if(this.arr[i] == item) return (this.arr.length-1-i);

    return null;
  },
  index : function(item){
    for(var i=0; i<this.arr.length; i++)
      if(this.arr[i] == item) return i;

    return null;
  },
  inspect : function(){
    return "Set(" + this.arr.join(", ") + ")";
  },
  toString : function(){
    return this.inspect();
  },
  size : function(){
    return this.arr.length;
  }
});

export default BiwaSet;
<commit_msg>feat: esmfy<commit_after>import _ from "../deps/underscore-1.10.2-esm.js"
import Class from "./class.js"
import { BiwaError } from "./error.js"

//
// Set - set of string
// contents must be string (or at least sortable)
//
const BiwaSet = Class.create({
  initialize : function(/*args*/){
    this.arr = [];
    var i;
    for(i=0; i<arguments.length; i++)
      this.arr[i] = arguments[i];
  },

  equals : function(other){
    if(this.arr.length != other.arr.length)
      return false;

    var a1 = _.clone(this.arr);
    var a2 = _.clone(other.arr);
    a1.sort();
    a2.sort();
    for(var i=0; i<this.arr.length; i++){
      if(a1[i] != a2[i]) return false;
    }
    return true;
  },
  set_cons : function(item){
    var o = new BiwaSet(item);
    o.arr = _.clone(this.arr);
    o.arr.push(item);
    return o;
  },
  set_union : function(/*args*/){
    var o = new BiwaSet();
    o.arr = _.clone(this.arr);

    for(var k=0; k<arguments.length; k++){
      var s2 = arguments[k];
      if(!(s2 instanceof BiwaSet))
        throw new BiwaError("set_union: arguments must be a set");

      for(var i=0; i<s2.arr.length; i++)
        o.add(s2.arr[i]);
    }
    return o;
  },
  set_intersect : function(s2){
    if(!(s2 instanceof BiwaSet))
      throw new BiwaError("set_intersect: arguments must be a set");

    var o = new BiwaSet();
    for(var i=0; i<this.arr.length; i++)
      if(s2.member(this.arr[i]))
        o.add(this.arr[i]);
    return o;
  },
  set_minus : function(s2){
    if(!(s2 instanceof BiwaSet))
      throw new BiwaError("set_minus: arguments must be a set");

    var o = new BiwaSet();
    for(var i=0; i<this.arr.length; i++)
      if(!s2.member(this.arr[i]))
        o.add(this.arr[i]);
    return o;
  },
  add : function(item){
    if(!this.member(item)){
      this.arr.push(item);
    }
  },
  member : function(item){
    for(var i=0; i<this.arr.length; i++)
      if(this.arr[i] == item) return true;

    return false;
  },
  rindex : function(item){
    for(var i=this.arr.length-1; i>=0 ; i--)
      if(this.arr[i] == item) return (this.arr.length-1-i);

    return null;
  },
  index : function(item){
    for(var i=0; i<this.arr.length; i++)
      if(this.arr[i] == item) return i;

    return null;
  },
  inspect : function(){
    return "Set(" + this.arr.join(", ") + ")";
  },
  toString : function(){
    return this.inspect();
  },
  size : function(){
    return this.arr.length;
  }
});

export default BiwaSet;
<|endoftext|>


<commit_before>let chokidar = require('chokidar');

class Task {
    /**
     * Create a new task instance.
     *
     * @param {Object} data
     */
    constructor(data) {
        this.data = data;
        this.assets = [];
        this.isBeingWatched = false;
    }

    /**
     * Watch all relevant files for changes.
     *
     * @param {boolean} usePolling
     */
    watch(usePolling = false) {
        if (this.isBeingWatched) return;

        const files = this.files.get()
        const watcher = chokidar.watch(files, { usePolling, persistent: true})
            .on('change', this.onChange.bind(this));

        this.isBeingWatched = true;
    }
}

module.exports = Task;
<commit_msg>Add workaround for atomic writes in watch mode<commit_after>let chokidar = require('chokidar');

class Task {
    /**
     * Create a new task instance.
     *
     * @param {Object} data
     */
    constructor(data) {
        this.data = data;
        this.assets = [];
        this.isBeingWatched = false;
    }

    /**
     * Watch all relevant files for changes.
     *
     * @param {boolean} usePolling
     */
    watch(usePolling = false) {
        if (this.isBeingWatched) return;

        const files = this.files.get()
        const watcher = chokidar.watch(files, { usePolling, persistent: true})
            .on('change', this.onChange.bind(this));

        // workaround for issue with atomic writes (See https://github.com/paulmillr/chokidar/issues/591)
        if (!usePolling) {
            watcher.on('raw', (event, path, {watchedPath}) => {
                if (event === 'rename') {
                    watcher.unwatch(files);
                    watcher.add(files);
                }
            })
        }

        this.isBeingWatched = true;
    }
}

module.exports = Task;
<|endoftext|>


<commit_before>var validUrl = require('valid-url');
var parseDomain = require('parse-domain');
var RtmClient = require('@slack/client').RtmClient;
var RestClient = require('node-rest-client').Client;

var CLIENT_EVENTS = require('@slack/client').CLIENT_EVENTS;
var RTM_EVENTS = require('@slack/client').RTM_EVENTS;

var BLACKLISTED_SITES = require('./blacklisted-sites.js');

// The minimum amount of time to wait between Agolo API requests
// Ensures we don't spam the channel with summaries. Or DoS attack the Agolo API.
var MAX_REQUEST_RATE_MS = 5000;

var SLACK_TOKEN, AGOLO_TOKEN, AGOLO_URL;
var HEROKU = false;

// Determine which environment we're running in
if (process.env.SLACK_TOKEN && process.env.AGOLO_TOKEN) {
  // For Heroku
  SLACK_TOKEN = process.env.SLACK_TOKEN;
  AGOLO_TOKEN = process.env.AGOLO_TOKEN;
  AGOLO_URL = process.env.AGOLO_URL;

  HEROKU = true;

  console.log('Slack token: ' + SLACK_TOKEN);
} else {
  // For local
  var SlackSecret = require('./secrets.js');

  SLACK_TOKEN = SlackSecret.slackToken();

  AGOLO_URL = SlackSecret.agoloURL();
  AGOLO_TOKEN = SlackSecret.agoloToken();
}

var LOG_LEVEL = 'debug';

var slackClient = new RtmClient(SLACK_TOKEN, {logLevel: LOG_LEVEL});
var restClient = new RestClient();

// The timestamp, in milliseconds, of when the latest API request was sent
var lastRequestTimestamp = 0;

/**
 * Helper functions
**/

// Summarize a given URL and call the given callback with the result
var summarize = function(url, typingInterval, callback) {
  var args = {
    data: {
      'coref':'false',
      'summary_length':'3',
      'articles':[
          {
          'type':'article',
          'url': url,
          'metadata':{}
        }
      ]},
    headers: {
      'Content-Type': 'application/json',
      'Ocp-Apim-Subscription-Key': AGOLO_TOKEN
      }
  };

  console.log('Sending Agolo request!', args);

  lastRequestTimestamp = new Date().getTime();
  restClient.post(AGOLO_URL, args, function (data, rawResponse) {
    console.log('Agolo response: ', data);

    clearInterval(typingInterval);

    if (data && data.summary) {
      for (var summIdx = 0; summIdx < data.summary.length; summIdx++) {
        if (data.summary[summIdx].sentences) {
          var sentences = data.summary[summIdx].sentences;

          // Quote each line
          for (var i = 0; i < sentences.length; i++) {
            sentences[i] = '>' + sentences[i];
          }

          var result = "Here's Agolo's summary of \"" + data.title + '"\n';

          result = result + sentences.join('\n-\n');

          callback(result);
        }
      }
    }
  });
};

// Make the decision whether to summarize based on a number of factors
var shouldSummarize = function(message, candidate) {
  // Ignore bot's own messages
  if (!message.user || message.user == BOT) {
    return false;
  }

  // Possibly just another bot talking to us?
  if (message.is_ephemeral) {
    return false;
  }

  // Is this a real URL?
  if (!validUrl.isWebUri(candidate)) {
    return false;
  }

  // Check our blacklist
  var url = parseDomain(candidate);
  if(BLACKLISTED_SITES[url.subdomain + '.' + url.domain + '.' + url.tld]
    || BLACKLISTED_SITES[url.subdomain + '.' + url.domain]
    || BLACKLISTED_SITES[url.domain + '.' + url.tld]
    || BLACKLISTED_SITES[url.domain]) {
    console.log('Blacklisted site: ', url);
    return false;
  }

  // We're summarizing too often
  if (new Date().getTime() - lastRequestTimestamp < MAX_REQUEST_RATE_MS) {
    console.log('We are making too many API requests.');
    return false;
  }

  return true;
};

// This bot's user ID
var BOT;

// Determines if the bot has been mentioned
var BOT_MENTION_REGEX;

var RESPONSES = [
	':blush:',
	':grin:',
	':innocent:',
	':relaxed:',
	':hugging_face:'
];

// If we've been mentioned, respond
var respondToMentions = function(text, slackClient, channel) {

    var matches = text.match(BOT_MENTION_REGEX);
    if (matches) {
      // Randomly pick a response
      var response = RESPONSES[Math.floor(Math.random() * (RESPONSES.length))];
      slackClient.sendMessage(response, channel);
    }
}

/**
 * Slack Client event handlers
 **/

slackClient.on(CLIENT_EVENTS.RTM.AUTHENTICATED, function (rtmStartData) {
  BOT = rtmStartData.self.id;
  BOT_MENTION_REGEX = new RegExp('<@' + BOT + '>');
});

slackClient.on('open', function() {
  console.log('Connected');
});

slackClient.on('message', function(message) {
  var text = message.text;
  var channel = message.channel;
  var attachments = message.attachments;

  if (text) {
    var urlRegex = /<([^\s]+)>/;

    var matches = text.match(urlRegex);
    if (matches) {
      // Start at index 1 because 0 has the entire match, not just the group
      for (var i = 0; i < matches.length; i++) {
        var candidate = matches[i];
        if (shouldSummarize(message, candidate)) {
          // Show typing indicator as we summarize
          var sendTypingMessage = function() {
            slackClient._send({
              id: 1,
              type: 'typing',
              channel: channel
            });
          }

          // Send out a "Typing..." message once in a while as we wait for the summary
          var TYPING_MESSAGE_SECS = 3;
          var typingInterval = setInterval(function() { sendTypingMessage(); }, TYPING_MESSAGE_SECS * 1000);

          // Kill the "Typing..." indicator after this many seconds
          var MAX_TYPING_INDICATOR_SECS = 30;
          setTimeout(function() { clearInterval(typingInterval); }, MAX_TYPING_INDICATOR_SECS * 1000)

          summarize(candidate, typingInterval, function(result) {
            slackClient.sendMessage(result, channel);
          });
        }
      }
    }

    // Check if someone has mentioned us and respond
    respondToMentions(text, slackClient, channel);
  }
});

// Finally, start listening to Slack
slackClient.start();

// Heroku requires us to run a webserver and periodically ping it
if (HEROKU) {
  var kickoffServer = require('./heroku-http-server.js');
  kickoffServer();
}<commit_msg>Format the article title better<commit_after>var validUrl = require('valid-url');
var parseDomain = require('parse-domain');
var RtmClient = require('@slack/client').RtmClient;
var RestClient = require('node-rest-client').Client;

var CLIENT_EVENTS = require('@slack/client').CLIENT_EVENTS;
var RTM_EVENTS = require('@slack/client').RTM_EVENTS;

var BLACKLISTED_SITES = require('./blacklisted-sites.js');

// The minimum amount of time to wait between Agolo API requests
// Ensures we don't spam the channel with summaries. Or DoS attack the Agolo API.
var MAX_REQUEST_RATE_MS = 5000;

var SLACK_TOKEN, AGOLO_TOKEN, AGOLO_URL;
var HEROKU = false;

// Determine which environment we're running in
if (process.env.SLACK_TOKEN && process.env.AGOLO_TOKEN) {
  // For Heroku
  SLACK_TOKEN = process.env.SLACK_TOKEN;
  AGOLO_TOKEN = process.env.AGOLO_TOKEN;
  AGOLO_URL = process.env.AGOLO_URL;

  HEROKU = true;

  console.log('Slack token: ' + SLACK_TOKEN);
} else {
  // For local
  var SlackSecret = require('./secrets.js');

  SLACK_TOKEN = SlackSecret.slackToken();

  AGOLO_URL = SlackSecret.agoloURL();
  AGOLO_TOKEN = SlackSecret.agoloToken();
}

var LOG_LEVEL = 'debug';

var slackClient = new RtmClient(SLACK_TOKEN, {logLevel: LOG_LEVEL});
var restClient = new RestClient();

// The timestamp, in milliseconds, of when the latest API request was sent
var lastRequestTimestamp = 0;

/**
 * Helper functions
**/

// Summarize a given URL and call the given callback with the result
var summarize = function(url, typingInterval, callback) {
  var args = {
    data: {
      'coref':'false',
      'summary_length':'3',
      'articles':[
          {
          'type':'article',
          'url': url,
          'metadata':{}
        }
      ]},
    headers: {
      'Content-Type': 'application/json',
      'Ocp-Apim-Subscription-Key': AGOLO_TOKEN
      }
  };

  console.log('Sending Agolo request!', args);

  lastRequestTimestamp = new Date().getTime();
  restClient.post(AGOLO_URL, args, function (data, rawResponse) {
    console.log('Agolo response: ', data);

    clearInterval(typingInterval);

    if (data && data.summary) {
      for (var summIdx = 0; summIdx < data.summary.length; summIdx++) {
        if (data.summary[summIdx].sentences) {
          var sentences = data.summary[summIdx].sentences;

          // Quote each line
          for (var i = 0; i < sentences.length; i++) {
            sentences[i] = '>' + sentences[i];
          }

          var result = "Here's Agolo's summary of \u201c_" + data.title + '_\u201d\n';

          result = result + sentences.join('\n-\n');

          callback(result);
        }
      }
    }
  });
};

// Make the decision whether to summarize based on a number of factors
var shouldSummarize = function(message, candidate) {
  // Ignore bot's own messages
  if (!message.user || message.user == BOT) {
    return false;
  }

  // Possibly just another bot talking to us?
  if (message.is_ephemeral) {
    return false;
  }

  // Is this a real URL?
  if (!validUrl.isWebUri(candidate)) {
    return false;
  }

  // Check our blacklist
  var url = parseDomain(candidate);
  if(BLACKLISTED_SITES[url.subdomain + '.' + url.domain + '.' + url.tld]
    || BLACKLISTED_SITES[url.subdomain + '.' + url.domain]
    || BLACKLISTED_SITES[url.domain + '.' + url.tld]
    || BLACKLISTED_SITES[url.domain]) {
    console.log('Blacklisted site: ', url);
    return false;
  }

  // We're summarizing too often
  if (new Date().getTime() - lastRequestTimestamp < MAX_REQUEST_RATE_MS) {
    console.log('We are making too many API requests.');
    return false;
  }

  return true;
};

// This bot's user ID
var BOT;

// Determines if the bot has been mentioned
var BOT_MENTION_REGEX;

var RESPONSES = [
	':blush:',
	':grin:',
	':innocent:',
	':relaxed:',
	':hugging_face:'
];

// If we've been mentioned, respond
var respondToMentions = function(text, slackClient, channel) {

    var matches = text.match(BOT_MENTION_REGEX);
    if (matches) {
      // Randomly pick a response
      var response = RESPONSES[Math.floor(Math.random() * (RESPONSES.length))];
      slackClient.sendMessage(response, channel);
    }
}

/**
 * Slack Client event handlers
 **/

slackClient.on(CLIENT_EVENTS.RTM.AUTHENTICATED, function (rtmStartData) {
  BOT = rtmStartData.self.id;
  BOT_MENTION_REGEX = new RegExp('<@' + BOT + '>');
});

slackClient.on('open', function() {
  console.log('Connected');
});

slackClient.on('message', function(message) {
  var text = message.text;
  var channel = message.channel;
  var attachments = message.attachments;

  if (text) {
    var urlRegex = /<([^\s]+)>/;

    var matches = text.match(urlRegex);
    if (matches) {
      // Start at index 1 because 0 has the entire match, not just the group
      for (var i = 0; i < matches.length; i++) {
        var candidate = matches[i];
        if (shouldSummarize(message, candidate)) {
          // Show typing indicator as we summarize
          var sendTypingMessage = function() {
            slackClient._send({
              id: 1,
              type: 'typing',
              channel: channel
            });
          }

          // Send out a "Typing..." message once in a while as we wait for the summary
          var TYPING_MESSAGE_SECS = 3;
          var typingInterval = setInterval(function() { sendTypingMessage(); }, TYPING_MESSAGE_SECS * 1000);

          // Kill the "Typing..." indicator after this many seconds
          var MAX_TYPING_INDICATOR_SECS = 30;
          setTimeout(function() { clearInterval(typingInterval); }, MAX_TYPING_INDICATOR_SECS * 1000)

          summarize(candidate, typingInterval, function(result) {
            slackClient.sendMessage(result, channel);
          });
        }
      }
    }

    // Check if someone has mentioned us and respond
    respondToMentions(text, slackClient, channel);
  }
});

// Finally, start listening to Slack
slackClient.start();

// Heroku requires us to run a webserver and periodically ping it
if (HEROKU) {
  var kickoffServer = require('./heroku-http-server.js');
  kickoffServer();
}<|endoftext|>


<commit_before>const axios = require("axios");
const https = require("https");
const { expect } = require("chai");
const httpsAgent = new https.Agent({
  rejectUnauthorized: false, // curl -k
});
axios.defaults.httpsAgent = httpsAgent;

const {
  ensureCommerceMockLocalTestFixture,
  checkAppGatewayResponse,
  sendEventAndCheckResponse,
  cleanMockTestFixture,
} = require("./fixtures/commerce-mock");
const {
  printRestartReport,
  getContainerRestartsForAllNamespaces,
  eventingSubscription,
  waitForFunction,
  waitForSubscription,
  k8sApply,
  genRandom,
  retryPromise,
  debug,
} = require("../utils");

describe("CommerceMock tests", function () {
  this.timeout(10 * 60 * 1000);
  this.slow(5000);
  const testNamespace = "test";
  let initialRestarts = null;

  it("Listing all pods in cluster", async function () {
    initialRestarts = await getContainerRestartsForAllNamespaces();
  });

  it("CommerceMock test fixture should be ready", async function () {
    await ensureCommerceMockLocalTestFixture("mocks", testNamespace).catch((err) => {
      console.dir(err); // first error is logged
      return ensureCommerceMockLocalTestFixture("mocks", testNamespace);
    });
  });

  it("lastorder function should be ready", async function () {
    await waitForFunction("lastorder", testNamespace);
  });

  it("In-cluster event subscription should be ready", async function () {
    await k8sApply([eventingSubscription(
      `sap.kyma.custom.inapp.order.received.v1`,
      `http://lastorder.${testNamespace}.svc.cluster.local`,
      "order-received",
      testNamespace)]);
      await waitForSubscription("order-received", testNamespace);
      await waitForSubscription("order-created", testNamespace);
    });

  it("in-cluster event should be delivered", async function () {
    const eventId = "event-"+genRandom(5);

    // send event using function query parameter send=true
    await retryPromise(() => axios.post("https://lastorder.local.kyma.dev", { id: eventId }, {params:{send:true}}), 10, 1000)
    // verify if event was received using function query parameter inappevent=eventId
    await retryPromise(async () => {
      debug("Waiting for event: ",eventId);
      let response = await axios.get("https://lastorder.local.kyma.dev", { params: { inappevent: eventId } })
      expect(response).to.have.nested.property("data.id", eventId, "The same event id expected in the result");
      expect(response).to.have.nested.property("data.shipped", true, "Order should have property shipped");
    }, 10, 1000);

  });

  it("function should reach Commerce mock API through app gateway", async function () {
    await checkAppGatewayResponse();
  });

  it("order.created.v1 event should trigger the lastorder function", async function () {
    await sendEventAndCheckResponse();
  });

  it("Should print report of restarted containers, skipped if no crashes happened", async function () {
    const afterTestRestarts = await getContainerRestartsForAllNamespaces();
    printRestartReport(initialRestarts, afterTestRestarts);
  });

  it("Test namespaces should be deleted", async function () {
    await cleanMockTestFixture("mocks", testNamespace, true);
  });
});
<commit_msg>Fix test on remote cluster (#11326)<commit_after>const axios = require("axios");
const https = require("https");
const { expect } = require("chai");
const httpsAgent = new https.Agent({
  rejectUnauthorized: false, // curl -k
});
axios.defaults.httpsAgent = httpsAgent;

const {
  ensureCommerceMockLocalTestFixture,
  checkAppGatewayResponse,
  sendEventAndCheckResponse,
  cleanMockTestFixture,
} = require("./fixtures/commerce-mock");
const {
  printRestartReport,
  getContainerRestartsForAllNamespaces,
  eventingSubscription,
  waitForFunction,
  waitForSubscription,
  k8sApply,
  genRandom,
  retryPromise,
  debug,
  waitForVirtualService,
} = require("../utils");

describe("CommerceMock tests", function () {
  this.timeout(10 * 60 * 1000);
  this.slow(5000);
  const testNamespace = "test";
  let initialRestarts = null;

  it("Listing all pods in cluster", async function () {
    initialRestarts = await getContainerRestartsForAllNamespaces();
  });

  it("CommerceMock test fixture should be ready", async function () {
    await ensureCommerceMockLocalTestFixture("mocks", testNamespace).catch((err) => {
      console.dir(err); // first error is logged
      return ensureCommerceMockLocalTestFixture("mocks", testNamespace);
    });
  });

  it("lastorder function should be ready", async function () {
    await waitForFunction("lastorder", testNamespace);
  });

  it("In-cluster event subscription should be ready", async function () {
    await k8sApply([eventingSubscription(
      `sap.kyma.custom.inapp.order.received.v1`,
      `http://lastorder.${testNamespace}.svc.cluster.local`,
      "order-received",
      testNamespace)]);
      await waitForSubscription("order-received", testNamespace);
      await waitForSubscription("order-created", testNamespace);
    });

  it("in-cluster event should be delivered", async function () {
    const eventId = "event-"+genRandom(5);
    const vs = await waitForVirtualService(testNamespace, "lastorder");
    const mockHost = vs.spec.hosts[0];

    // send event using function query parameter send=true
    await retryPromise(() => axios.post(`https://${mockHost}`, { id: eventId }, {params:{send:true}}), 10, 1000)
    // verify if event was received using function query parameter inappevent=eventId
    await retryPromise(async () => {
      debug("Waiting for event: ",eventId);
      let response = await axios.get(`https://${mockHost}`, { params: { inappevent: eventId } })
      expect(response).to.have.nested.property("data.id", eventId, "The same event id expected in the result");
      expect(response).to.have.nested.property("data.shipped", true, "Order should have property shipped");
    }, 10, 1000);

  });

  it("function should reach Commerce mock API through app gateway", async function () {
    await checkAppGatewayResponse();
  });

  it("order.created.v1 event should trigger the lastorder function", async function () {
    await sendEventAndCheckResponse();
  });

  it("Should print report of restarted containers, skipped if no crashes happened", async function () {
    const afterTestRestarts = await getContainerRestartsForAllNamespaces();
    printRestartReport(initialRestarts, afterTestRestarts);
  });

  it("Test namespaces should be deleted", async function () {
    await cleanMockTestFixture("mocks", testNamespace, true);
  });
});
<|endoftext|>


<commit_before>jQuery(function($){

	// assign json
	if (userData.articleData)
	{
		if (userData.articleData.thumbnail)
		{
			userData.thumbnail = userData.articleData.thumbnail || {};
		}
	}

	// insert source to content form
	var insertSourceToContentForm = function(items)
	{
		// get cursor position
		var getCursorPosition = function($el)
		{
			var el = $el.get(0);
			var pos = 0;
			if ('selectionStart' in el)
			{
				pos = el.selectionStart;
			}
			else if ('selection' in document)
			{
				el.focus();
				var Sel = document.selection.createRange();
				var SelLength = document.selection.createRange().text.length;
				Sel.moveStart('character', -el.value.length);
				pos = Sel.text.length - SelLength;
			}
			return pos;
		};

		var str = '';
		for (var i=0; i<items.length; i++)
		{
			if (/^image/.test(items[i].type))
			{
				str += '![](' + items[i].src + ')\n';
			}
			else
			{
				str += '[' + items[i].name + '](' + items[i].src + ')\n';
			}
		}

		var pos = getCursorPosition($(userData.form.content));
		var val = userData.form.content.value;
		var newContent = val.substr(0, pos) + str + val.substr(pos);
		userData.form.content.value = newContent;
	};

	// get preview markdown data
	var getPreviewMarkdownData = function()
	{
		var defer = $.Deferred();
		var req = $.ajax({
			url : userData.previewScriptPath,
			type : 'post',
			data : {
				content : userData.form.content.value
			}
		});
		req.done(function(str){
			defer.resolve(str);
		});

		return defer.promise();
	};

	// check thumbnail image
	var checkThumbnailImage = function()
	{
		var files = uploader.queue.items.files;
		var inImage = false;

		// check thumbnail queue
		if (userData.form.article_srl.value && uploader.queue.$queue.children('.is-thumbnail').length)
		{
			return false;
		}

		// check image type in queues
		for (var i=0; i<files.length; i++)
		{
			if (/^image/i.test(files[i].type))
			{
				inImage = true;
				break;
			}
		}

		// check thumbnail_image value
		if (inImage && !userData.thumbnail_image)
		{
			alert('not make thumbnail image');
			uploader.queue.$queue.find('.btn-make-thumbnail').eq(0).focus();
			return true;
		}
		else
		{
			return false;
		}
	};

	// get thumbnail size
	var getThumbnailSize = function(setting, file)
	{
		var defer = $.Deferred();
		var image = new Image();

		// get size
		function getSize(type, set_w, set_h, img_w, img_h)
		{
			var size = {};
			switch(type)
			{
				case 'resize':
					if (img_w < img_h)
					{
						size.width = parseInt((img_w / img_h) * set_h);
						size.height = parseInt(set_h);
					}
					else
					{
						size.width = parseInt(set_w);
						size.height = parseInt((img_h / img_w) * set_w);
					}
					break;
				case 'resizeWidth':
					size.width = parseInt(set_w);
					size.height = parseInt((img_h / img_w) * set_w);
					break;
				case 'resizeHeight':
					size.width = parseInt((img_w / img_h) * set_h);
					size.height = parseInt(set_h);
					break;
				default:
					size.width = parseInt(set_w);
					size.height = parseInt(set_h);
					break;
			}
			return size;
		}

		image.onload = function(e)
		{
			var size = getSize(setting.type, setting.size.width, setting.size.height, image.width, image.height);
			defer.resolve(size);
		};
		image.src = userData.root + '/' + file.src;

		return defer.promise();
	};

	// init uploader
	window.uploader = new RGUploader($('#queuesManager'), {
		autoUpload : true,
		allowFileTypes : ['jpeg', 'png', 'gif'],
		limitSize : 3000000,
		limitSizeTotal : 10000000,
		uploadScript : userData.root + '/file/upload/',
		removeScript : userData.root + '/file/remove/',
		uploadParams : {
			ready : 1
		},
		srcPrefixName : userData.url,
		queue : {
			style : 'list',
			height : 150,
			limit : 10,
			datas : userData.pushDatas,
			buttons : [
				{
					name : 'open file',
					iconName : 'open_in_new',
					action : function(app, file) {
						window.open(file.fullSrc);
					}
				},
				{
					name : 'make thumbnail image',
					iconName : 'apps',
					className : 'btn-make-thumbnail',
					show : function(file) {
						return (file.type.split('/')[0] == 'image');
					},
					action : function(app, file) {
						if (!app.plugin.child.thumbnail) return false;
						var plugin = app.plugin.child.thumbnail;
						var option = {};

						// set option
						if (file.srl == userData.thumbnail.srl)
						{
							option.points = userData.thumbnail.points;
							option.zoom = userData.thumbnail.zoom;
						}

						if ((userData.thumbnail.type && userData.thumbnail.type == 'crop') || !userData.thumbnail.type)
						{
							plugin.open(file, option);
						}
						else
						{
							var ready = getThumbnailSize(userData.thumbnailSet, file);
							ready.done(function(size){
								plugin.assignOption({
									output : {
										size : { width : size.width, height : size.height }
									},
									croppie : {
										viewport : { width: size.width, height: size.height }
									}
								});
								plugin.open(file, option);
							});
						}
					}
				},
				{
					name : 'insert editor',
					iconName : 'center_focus_strong',
					action : function(app, file) {
						insertSourceToContentForm([{
							src : file.fullSrc,
							name : file.name,
							type : file.type
						}]);
					}
				},
				{
					name : 'remove queue',
					iconName : 'close',
					action : function(app, file) {
						app.queue.removeQueue(file.id, false, true);
					}
				}
			]
		},
		plugin : [
			{ name : 'preview', obj : new RG_Preview() },
			{ name : 'sizeinfo', obj : new RG_Sizeinfo() },
			{ name : 'dnd', obj : new RG_DragAndDrop() },
			{
				name : 'thumbnail',
				obj : new RG_Thumbnail({
					width : 640,
					height : 480,
					mobileSize : 640,
					url_croppieCSS : userData.root + '/vendor/rg-Uploader/vendor/Croppie/croppie.css',
					url_croppieJS : userData.root + '/vendor/rg-Uploader/vendor/Croppie/croppie.min.js',
					output : {
						type : 'canvas',
						quality : .85,
						format : 'jpeg',
						size : {
							width : userData.thumbnailSet.size.width,
							height : userData.thumbnailSet.size.height
						}
					},
					croppie : {
						viewport : {
							width: userData.thumbnailSet.size.width,
							height: userData.thumbnailSet.size.height,
							type: 'square'
						}
					},
					doneCallback : function(res, app, file) {
						var classBtnMakeThumbnail = '.btn-make-thumbnail';

						// input thumbnail image source
						userData.thumbnail_image = res.src;

						// update on class name
						app.queue.$queue.children().removeClass('is-thumbnail');
						app.queue.$queue.find(classBtnMakeThumbnail).removeClass('on');
						app.queue.selectQueueElement(file.id).find(classBtnMakeThumbnail).addClass('on');

						// set thumbnail data
						var croppie = app.plugin.child.thumbnail.croppie.get();
						var options = app.plugin.child.thumbnail.options;
						userData.thumbnail.srl = file.srl;
						userData.thumbnail.points = croppie.points;
						userData.thumbnail.zoom = croppie.zoom;
						userData.thumbnail.size = options.output.size;
					}
				})
			}
		],
		uploadDataFilter : function(res) {
			return {
				state : res[0].state,
				response : {
					src : res[0].loc,
					srl : res[0].srl,
					name : res[0].name,
					ready : res[0].ready
				}
			}
		},
		removeParamsFilter : function(res) {
			return {
				data : JSON.stringify([{ srl : res.srl }])
			};
		},
		removeDataFilter : function(res) {},
		uploadComplete : function(file) {
			userData.addQueue.push(file.srl);
		},
		init : function(app) {
			// set thumbnail queue
			if (userData.articleData.thumbnail)
			{
				var $queue = app.queue.selectQueueElement(userData.articleData.thumbnail.srl);
				$queue
					.addClass('is-thumbnail')
					.find('.btn-make-thumbnail').addClass('on');
			}
		}
	});

	// toggle edit/preview
	var $mkEditor = $('div.mk-editor');
	var $mkEditorButtons = $mkEditor.find('a[data-control]');
	$mkEditorButtons.on('click', function(){
		var mode = $(this).attr('data-control');
		var $target = $mkEditor.find('[data-target=' + mode + ']');

		if (!$(this).hasClass('active'))
		{
			$mkEditorButtons.removeClass('active');
			$(this).addClass('active');
			$mkEditor.find('[data-target]').removeClass('show');
			$target.addClass('show');

			// load preview data
			if (mode == 'preview' && userData.form.content.value)
			{
				var preview = getPreviewMarkdownData();
				preview.done(function(res){
					$target.html(res);
				});
			}
		}

		return false;
	});

	// init submit
	$(userData.form).on('submit', function(){
		// check thumbnail image
		if (checkThumbnailImage())
		{
			return false;
		}

		// set json and get article json
		var json = userData.articleData;

		// set thumbnail data
		if (userData.thumbnail_image)
		{
			userData.form.thumbnail_image.value = userData.thumbnail_image;
		}

		// set thumbnail
		json.thumbnail = userData.thumbnail;

		// set add queue srl
		userData.form.addQueue.value = userData.addQueue.toString();

		// json object to hidden string
		json = encodeURIComponent(JSON.stringify(json));
		userData.form.json.value = json;

		// return false;
	});

});
<commit_msg>마크다운 파일 업로드 오류 수정<commit_after>jQuery(function($){

	// assign json
	if (userData.articleData)
	{
		if (userData.articleData.thumbnail)
		{
			userData.thumbnail = userData.articleData.thumbnail || {};
		}
	}

	// insert source to content form
	var insertSourceToContentForm = function(items)
	{
		// get cursor position
		var getCursorPosition = function($el)
		{
			var el = $el.get(0);
			var pos = 0;
			if ('selectionStart' in el)
			{
				pos = el.selectionStart;
			}
			else if ('selection' in document)
			{
				el.focus();
				var Sel = document.selection.createRange();
				var SelLength = document.selection.createRange().text.length;
				Sel.moveStart('character', -el.value.length);
				pos = Sel.text.length - SelLength;
			}
			return pos;
		};

		var str = '';
		for (var i=0; i<items.length; i++)
		{
			if (/^image/.test(items[i].type))
			{
				str += '![](' + items[i].src + ')\n';
			}
			else
			{
				str += '[' + items[i].name + '](' + items[i].src + ')\n';
			}
		}

		var pos = getCursorPosition($(userData.form.content));
		var val = userData.form.content.value;
		var newContent = val.substr(0, pos) + str + val.substr(pos);
		userData.form.content.value = newContent;
	};

	// get preview markdown data
	var getPreviewMarkdownData = function()
	{
		var defer = $.Deferred();
		var req = $.ajax({
			url : userData.previewScriptPath,
			type : 'post',
			data : {
				content : userData.form.content.value
			}
		});
		req.done(function(str){
			defer.resolve(str);
		});

		return defer.promise();
	};

	// check thumbnail image
	var checkThumbnailImage = function()
	{
		var files = uploader.queue.items.files;
		var inImage = false;

		// check thumbnail queue
		if (userData.form.article_srl.value && uploader.queue.$queue.children('.is-thumbnail').length)
		{
			return false;
		}

		// check image type in queues
		for (var i=0; i<files.length; i++)
		{
			if (/^image/i.test(files[i].type))
			{
				inImage = true;
				break;
			}
		}

		// check thumbnail_image value
		if (inImage && !userData.thumbnail_image)
		{
			alert('not make thumbnail image');
			uploader.queue.$queue.find('.btn-make-thumbnail').eq(0).focus();
			return true;
		}
		else
		{
			return false;
		}
	};

	// get thumbnail size
	var getThumbnailSize = function(setting, file)
	{
		var defer = $.Deferred();
		var image = new Image();

		// get size
		function getSize(type, set_w, set_h, img_w, img_h)
		{
			var size = {};
			switch(type)
			{
				case 'resize':
					if (img_w < img_h)
					{
						size.width = parseInt((img_w / img_h) * set_h);
						size.height = parseInt(set_h);
					}
					else
					{
						size.width = parseInt(set_w);
						size.height = parseInt((img_h / img_w) * set_w);
					}
					break;
				case 'resizeWidth':
					size.width = parseInt(set_w);
					size.height = parseInt((img_h / img_w) * set_w);
					break;
				case 'resizeHeight':
					size.width = parseInt((img_w / img_h) * set_h);
					size.height = parseInt(set_h);
					break;
				default:
					size.width = parseInt(set_w);
					size.height = parseInt(set_h);
					break;
			}
			return size;
		}

		image.onload = function(e)
		{
			var size = getSize(setting.type, setting.size.width, setting.size.height, image.width, image.height);
			defer.resolve(size);
		};
		image.src = userData.root + '/' + file.src;

		return defer.promise();
	};

	// init uploader
	window.uploader = new RGUploader($('#queuesManager'), {
		autoUpload : true,
		allowFileTypes : ['jpeg', 'png', 'gif'],
		limitSize : 3000000,
		limitSizeTotal : 10000000,
		uploadScript : userData.root + '/File/upload/',
		removeScript : userData.root + '/File/remove/',
		uploadParams : {
			ready : 1
		},
		srcPrefixName : userData.url,
		queue : {
			style : 'list',
			height : 150,
			limit : 10,
			datas : userData.pushDatas,
			buttons : [
				{
					name : 'open file',
					iconName : 'open_in_new',
					action : function(app, file) {
						window.open(file.fullSrc);
					}
				},
				{
					name : 'make thumbnail image',
					iconName : 'apps',
					className : 'btn-make-thumbnail',
					show : function(file) {
						return (file.type.split('/')[0] == 'image');
					},
					action : function(app, file) {
						if (!app.plugin.child.thumbnail) return false;
						var plugin = app.plugin.child.thumbnail;
						var option = {};

						// set option
						if (file.srl == userData.thumbnail.srl)
						{
							option.points = userData.thumbnail.points;
							option.zoom = userData.thumbnail.zoom;
						}

						if ((userData.thumbnail.type && userData.thumbnail.type == 'crop') || !userData.thumbnail.type)
						{
							plugin.open(file, option);
						}
						else
						{
							var ready = getThumbnailSize(userData.thumbnailSet, file);
							ready.done(function(size){
								plugin.assignOption({
									output : {
										size : { width : size.width, height : size.height }
									},
									croppie : {
										viewport : { width: size.width, height: size.height }
									}
								});
								plugin.open(file, option);
							});
						}
					}
				},
				{
					name : 'insert editor',
					iconName : 'center_focus_strong',
					action : function(app, file) {
						insertSourceToContentForm([{
							src : file.fullSrc,
							name : file.name,
							type : file.type
						}]);
					}
				},
				{
					name : 'remove queue',
					iconName : 'close',
					action : function(app, file) {
						app.queue.removeQueue(file.id, false, true);
					}
				}
			]
		},
		plugin : [
			{ name : 'preview', obj : new RG_Preview() },
			{ name : 'sizeinfo', obj : new RG_Sizeinfo() },
			{ name : 'dnd', obj : new RG_DragAndDrop() },
			{
				name : 'thumbnail',
				obj : new RG_Thumbnail({
					width : 640,
					height : 480,
					mobileSize : 640,
					url_croppieCSS : userData.root + '/vendor/rg-Uploader/vendor/Croppie/croppie.css',
					url_croppieJS : userData.root + '/vendor/rg-Uploader/vendor/Croppie/croppie.min.js',
					output : {
						type : 'canvas',
						quality : .85,
						format : 'jpeg',
						size : {
							width : userData.thumbnailSet.size.width,
							height : userData.thumbnailSet.size.height
						}
					},
					croppie : {
						viewport : {
							width: userData.thumbnailSet.size.width,
							height: userData.thumbnailSet.size.height,
							type: 'square'
						}
					},
					doneCallback : function(res, app, file) {
						var classBtnMakeThumbnail = '.btn-make-thumbnail';

						// input thumbnail image source
						userData.thumbnail_image = res.src;

						// update on class name
						app.queue.$queue.children().removeClass('is-thumbnail');
						app.queue.$queue.find(classBtnMakeThumbnail).removeClass('on');
						app.queue.selectQueueElement(file.id).find(classBtnMakeThumbnail).addClass('on');

						// set thumbnail data
						var croppie = app.plugin.child.thumbnail.croppie.get();
						var options = app.plugin.child.thumbnail.options;
						userData.thumbnail.srl = file.srl;
						userData.thumbnail.points = croppie.points;
						userData.thumbnail.zoom = croppie.zoom;
						userData.thumbnail.size = options.output.size;
					}
				})
			}
		],
		uploadDataFilter : function(res) {
			return {
				state : res[0].state,
				response : {
					src : res[0].loc,
					srl : res[0].srl,
					name : res[0].name,
					ready : res[0].ready
				}
			}
		},
		removeParamsFilter : function(res) {
			return {
				data : JSON.stringify([{ srl : res.srl }])
			};
		},
		removeDataFilter : function(res) {},
		uploadComplete : function(file) {
			userData.addQueue.push(file.srl);
		},
		init : function(app) {
			// set thumbnail queue
			if (userData.articleData.thumbnail)
			{
				var $queue = app.queue.selectQueueElement(userData.articleData.thumbnail.srl);
				$queue
					.addClass('is-thumbnail')
					.find('.btn-make-thumbnail').addClass('on');
			}
		}
	});

	// toggle edit/preview
	var $mkEditor = $('div.mk-editor');
	var $mkEditorButtons = $mkEditor.find('a[data-control]');
	$mkEditorButtons.on('click', function(){
		var mode = $(this).attr('data-control');
		var $target = $mkEditor.find('[data-target=' + mode + ']');

		if (!$(this).hasClass('active'))
		{
			$mkEditorButtons.removeClass('active');
			$(this).addClass('active');
			$mkEditor.find('[data-target]').removeClass('show');
			$target.addClass('show');

			// load preview data
			if (mode == 'preview' && userData.form.content.value)
			{
				var preview = getPreviewMarkdownData();
				preview.done(function(res){
					$target.html(res);
				});
			}
		}

		return false;
	});

	// init submit
	$(userData.form).on('submit', function(){
		// check thumbnail image
		if (checkThumbnailImage())
		{
			return false;
		}

		// set json and get article json
		var json = userData.articleData;

		// set thumbnail data
		if (userData.thumbnail_image)
		{
			userData.form.thumbnail_image.value = userData.thumbnail_image;
		}

		// set thumbnail
		json.thumbnail = userData.thumbnail;

		// set add queue srl
		userData.form.addQueue.value = userData.addQueue.toString();

		// json object to hidden string
		json = encodeURIComponent(JSON.stringify(json));
		userData.form.json.value = json;

		// return false;
	});

});
<|endoftext|>


<commit_before>
function _requires (content) {
    var rgx = /(?:requires|mixins)\s*:\s*\[([^\[\]]+)\]/gim,
        rgx_Name = /['"]([^'",]*)['"]/gim,
        requires_lines = content.match(rgx),
        result = [];

    if (requires_lines) {
        requires_lines.forEach(function(l) {
            var names = l.match(rgx_Name);
            if (names) {
                result = result.concat(names.map(function(p) {
                    return p.replace(/['"]*/gim,'').trim();
                }));
            }
        });
    }

    return result;
}

function _extend_requires (content) {
    var rgx = /(?:extend|requires|mixins):\s*['"]([^'"]*)['"]/gim,
        requires_line = content.match(rgx);

    if (requires_line == null)
        return [];

    return requires_line.map(function(l) {
        return l.replace(rgx, '$1');
    });
}

module.exports = {

    getPath: function(blank) {
        var path = blank.split('.'),
            folders;

        if (path.length > 0) {
            folders = path.slice(path.length - 2, path.length - 1 );
            return './' + folders.join('/').toLowerCase() + '/' + path[path.length - 1] + '.js';
        }

        return path + '.js';
    },

    getBlanks: function(content) {
        var blanks;
        blanks = _requires(content);
        blanks = blanks.concat(_extend_requires(content));
        return blanks;
    }
};<commit_msg>added new regexp for mixins<commit_after>
function _requires (content) {
    var rgx = /(?:requires|mixins)\s*:\s*\[([^\[\]]+)\]/gim,
        rgx_name = /['"]([^'",]*)['"]/gim,
        requires_lines = content.match(rgx),
        result = [];

    if (requires_lines) {
        requires_lines.forEach(function(l) {
            var names = l.match(rgx_name);
            if (names) {
                result = result.concat(names.map(function(p) {
                    return p.replace(/['"]*/gim,'').trim();
                }));
            }
        });
    }

    return result;
}

function _extend_requires (content) {
    var rgx = /(?:extend|requires|mixins)\s*:\s*['"]([^'"]*)['"]/gim,
        requires_line = content.match(rgx);

    if (requires_line == null)
        return [];

    return requires_line.map(function(l) {
        return l.replace(rgx, '$1');
    });
}

// for type
/*
 mixins: {
 observable: 'Ext.mixin.Observable'
 }
 */
function _mixmins_hash(content) {
    var rgx = /(?:mixins)\s*:\s*(\{[^\{\}]*\})/gim,
        rgx_name = /:\s['"]([^'"]+)['"]/gim,
        requires_line = content.match(rgx),
        result = [];

    if (requires_line != null) {

        requires_line.forEach(function(l) {
            var names = l.match(rgx_name);
            if (names) {
                result = result.concat(names.map(function(p) {
                    return p.replace(rgx_name,'$1').trim();
                }));
            }
        });
    }
    return result;
}

module.exports = {

    getPath: function(blank) {
        var path = blank.split('.'),
            folders;

        if (path.length > 0) {
            folders = path.slice(path.length - 2, path.length - 1 );
            return './' + folders.join('/').toLowerCase() + '/' + path[path.length - 1] + '.js';
        }

        return path + '.js';
    },

    getBlanks: function(content) {
        var blanks;
        blanks = _requires(content);
        blanks = blanks.concat(_extend_requires(content));
        blanks = blanks.concat(_mixmins_hash(content));
        return blanks;
    }
};<|endoftext|>


<commit_before>/*global define*/
define([
        '../Core/destroyObject',
        '../Core/Ellipsoid',
        '../Core/Cartesian3',
        '../Core/Cartesian4',
        '../Core/Matrix4',
        '../Core/Transforms',
        './CameraEventHandler',
        './CameraEventType',
        './CameraSpindleController',
        './CameraFreeLookController'
    ], function(
        destroyObject,
        Ellipsoid,
        Cartesian3,
        Cartesian4,
        Matrix4,
        Transforms,
        CameraEventHandler,
        CameraEventType,
        CameraSpindleController,
        CameraFreeLookController) {
    "use strict";

    /**
     * DOC_TBD
     * @name CameraCentralBodyController
     * @constructor
     */
    function CameraCentralBodyController(canvas, camera, ellipsoid) {
        this._canvas = canvas;
        this._camera = camera;

        this._spindleController = new CameraSpindleController(canvas, camera, ellipsoid);
        this._freeLookController = new CameraFreeLookController(canvas, camera);
        this._freeLookController.horizontalRotationAxis = Cartesian3.UNIT_Z;

        this._rotateHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG);

        this._transform = Matrix4.IDENTITY;
    }

    /**
     * @private
     */
    CameraCentralBodyController.prototype.update = function() {
        var rotate = this._rotateHandler;
        var rotating = rotate.isMoving() && rotate.getMovement();

        var rotateMovement = rotate.getMovement();
        if (rotate.isButtonDown() && typeof this._transform === 'undefined' && rotateMovement) {
            var center = this._camera.pickEllipsoid(this._spindleController.getEllipsoid(), rotateMovement.startPosition);
            if (typeof center !== 'undefined') {
                this._transform = Transforms.eastNorthUpToFixedFrame(center);
            }
        } else if (!rotate.isButtonDown()) {
            this._transform = undefined;
        }

        if (rotating && typeof this._transform !== 'undefined') {
                this._rotate(rotateMovement);
        }

        this._spindleController.update();
        this._freeLookController.update();

        return true;
    };

    CameraCentralBodyController.prototype._rotate = function(movement) {
        var transform = this._transform;
        var camera = this._camera;
        var position = camera.position;
        var up = camera.up;
        var right = camera.right;
        var direction = camera.direction;

        var oldTransform = camera.transform;
        var oldEllipsoid = this._spindleController.getEllipsoid();
        var oldConstrainedZ = this._spindleController.constrainedAxis;

        this._spindleController.setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE);
        this._spindleController.constrainedAxis = Cartesian3.UNIT_Z;

        var invTransform = camera.getInverseTransform();
        camera.position = invTransform.multiplyWithVector(new Cartesian4(position.x, position.y, position.z, 1.0)).getXYZ();
        camera.up = invTransform.multiplyWithVector(new Cartesian4(up.x, up.y, up.z, 0.0)).getXYZ();
        camera.right = invTransform.multiplyWithVector(new Cartesian4(right.x, right.y, right.z, 0.0)).getXYZ();
        camera.direction = invTransform.multiplyWithVector(new Cartesian4(direction.x, direction.y, direction.z, 0.0)).getXYZ();

        this._spindleController._rotate(movement);

        position = camera.position;
        up = camera.up;
        right = camera.right;
        direction = camera.direction;

        this._spindleController.setReferenceFrame(oldTransform, oldEllipsoid);
        this._spindleController.constrainedAxis = oldConstrainedZ;

        camera.position = transform.multiplyWithVector(new Cartesian4(position.x, position.y, position.z, 1.0)).getXYZ();
        camera.up = transform.multiplyWithVector(new Cartesian4(up.x, up.y, up.z, 0.0)).getXYZ();
        camera.right = transform.multiplyWithVector(new Cartesian4(right.x, right.y, right.z, 0.0)).getXYZ();
        camera.direction = transform.multiplyWithVector(new Cartesian4(direction.x, direction.y, direction.z, 0.0)).getXYZ();
    };

    /**
      * Returns true if this object was destroyed; otherwise, false.
      *

      * If this object was destroyed, it should not be used; calling any function other than
      * isDestroyed will result in a {@link DeveloperError} exception.
      *
      * @memberof CameraCentralBodyController
      *
      * @return {Boolean} true if this object was destroyed; otherwise, false.
      *
      * @see CameraCentralBodyController#destroy
      */
    CameraCentralBodyController.prototype.isDestroyed = function() {
        return false;
    };

    /**
     * Removes mouse and keyboard listeners held by this object.
     *

     * Once an object is destroyed, it should not be used; calling any function other than
     * isDestroyed will result in a {@link DeveloperError} exception.  Therefore,
     * assign the return value (undefined) to the object as done in the example.
     *
     * @memberof CameraCentralBodyController
     *
     * @return {undefined}
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     * @see CameraCentralBodyController#isDestroyed
     *
     * @example
     * controller = controller && controller.destroy();
     */
    CameraCentralBodyController.prototype.destroy = function() {
        this._rotateHandler = this._rotateHandler && this._rotateHandler.destroy();
        this._spindleController = this._spindleController && this._spindleController.destroy();
        this._freeLookController = this._freeLookController && this._freeLookController.destroy();
        return destroyObject(this);
    };

    return CameraCentralBodyController;
});<commit_msg>Fix break after merge.<commit_after>/*global define*/
define([
        '../Core/destroyObject',
        '../Core/Ellipsoid',
        '../Core/Cartesian3',
        '../Core/Cartesian4',
        '../Core/Matrix4',
        '../Core/Transforms',
        './CameraEventHandler',
        './CameraEventType',
        './CameraSpindleController',
        './CameraFreeLookController'
    ], function(
        destroyObject,
        Ellipsoid,
        Cartesian3,
        Cartesian4,
        Matrix4,
        Transforms,
        CameraEventHandler,
        CameraEventType,
        CameraSpindleController,
        CameraFreeLookController) {
    "use strict";

    /**
     * DOC_TBD
     * @name CameraCentralBodyController
     * @constructor
     */
    function CameraCentralBodyController(canvas, camera, ellipsoid) {
        this._canvas = canvas;
        this._camera = camera;

        this._spindleController = new CameraSpindleController(canvas, camera, ellipsoid);
        this._freeLookController = new CameraFreeLookController(canvas, camera);
        this._freeLookController.horizontalRotationAxis = Cartesian3.UNIT_Z;

        this._rotateHandler = new CameraEventHandler(canvas, CameraEventType.MIDDLE_DRAG);

        this._transform = Matrix4.IDENTITY;
    }

    /**
     * @private
     */
    CameraCentralBodyController.prototype.update = function() {
        var rotate = this._rotateHandler;
        var rotating = rotate.isMoving() && rotate.getMovement();

        var rotateMovement = rotate.getMovement();
        if (rotate.isButtonDown() && typeof this._transform === 'undefined' && rotateMovement) {
            var center = this._camera.pickEllipsoid(rotateMovement.startPosition, this._spindleController.getEllipsoid());
            if (typeof center !== 'undefined') {
                this._transform = Transforms.eastNorthUpToFixedFrame(center);
            }
        } else if (!rotate.isButtonDown()) {
            this._transform = undefined;
        }

        if (rotating && typeof this._transform !== 'undefined') {
                this._rotate(rotateMovement);
        }

        this._spindleController.update();
        this._freeLookController.update();

        return true;
    };

    CameraCentralBodyController.prototype._rotate = function(movement) {
        var transform = this._transform;
        var camera = this._camera;
        var position = camera.position;
        var up = camera.up;
        var right = camera.right;
        var direction = camera.direction;

        var oldTransform = camera.transform;
        var oldEllipsoid = this._spindleController.getEllipsoid();
        var oldConstrainedZ = this._spindleController.constrainedAxis;

        this._spindleController.setReferenceFrame(transform, Ellipsoid.UNIT_SPHERE);
        this._spindleController.constrainedAxis = Cartesian3.UNIT_Z;

        var invTransform = camera.getInverseTransform();
        camera.position = invTransform.multiplyWithVector(new Cartesian4(position.x, position.y, position.z, 1.0)).getXYZ();
        camera.up = invTransform.multiplyWithVector(new Cartesian4(up.x, up.y, up.z, 0.0)).getXYZ();
        camera.right = invTransform.multiplyWithVector(new Cartesian4(right.x, right.y, right.z, 0.0)).getXYZ();
        camera.direction = invTransform.multiplyWithVector(new Cartesian4(direction.x, direction.y, direction.z, 0.0)).getXYZ();

        this._spindleController._rotate(movement);

        position = camera.position;
        up = camera.up;
        right = camera.right;
        direction = camera.direction;

        this._spindleController.setReferenceFrame(oldTransform, oldEllipsoid);
        this._spindleController.constrainedAxis = oldConstrainedZ;

        camera.position = transform.multiplyWithVector(new Cartesian4(position.x, position.y, position.z, 1.0)).getXYZ();
        camera.up = transform.multiplyWithVector(new Cartesian4(up.x, up.y, up.z, 0.0)).getXYZ();
        camera.right = transform.multiplyWithVector(new Cartesian4(right.x, right.y, right.z, 0.0)).getXYZ();
        camera.direction = transform.multiplyWithVector(new Cartesian4(direction.x, direction.y, direction.z, 0.0)).getXYZ();
    };

    /**
      * Returns true if this object was destroyed; otherwise, false.
      *

      * If this object was destroyed, it should not be used; calling any function other than
      * isDestroyed will result in a {@link DeveloperError} exception.
      *
      * @memberof CameraCentralBodyController
      *
      * @return {Boolean} true if this object was destroyed; otherwise, false.
      *
      * @see CameraCentralBodyController#destroy
      */
    CameraCentralBodyController.prototype.isDestroyed = function() {
        return false;
    };

    /**
     * Removes mouse and keyboard listeners held by this object.
     *

     * Once an object is destroyed, it should not be used; calling any function other than
     * isDestroyed will result in a {@link DeveloperError} exception.  Therefore,
     * assign the return value (undefined) to the object as done in the example.
     *
     * @memberof CameraCentralBodyController
     *
     * @return {undefined}
     *
     * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
     *
     * @see CameraCentralBodyController#isDestroyed
     *
     * @example
     * controller = controller && controller.destroy();
     */
    CameraCentralBodyController.prototype.destroy = function() {
        this._rotateHandler = this._rotateHandler && this._rotateHandler.destroy();
        this._spindleController = this._spindleController && this._spindleController.destroy();
        this._freeLookController = this._freeLookController && this._freeLookController.destroy();
        return destroyObject(this);
    };

    return CameraCentralBodyController;
});<|endoftext|>


<commit_before>export { Base };

import * as FloatValue from "../../Unpacker/FloatValue.js";
import * as ValueDesc from "../../Unpacker/ValueDesc.js";

/**
 *
 * @member {FloatValue.Bounds} input
 *   The bounds of the input element value. Or say, the domain of the convolution-bias-activation.
 *
 * @member {FloatValue.Bounds} beforeActivation
 *   The bounds of the element value after convolution and bias operation (but before activation).
 *
 * @member {FloatValue.Bounds} output
 *   The bounds of the output element value. Or say, the range of the convolution-bias-activation.
 *
 * @member {FloatValue.ScaleTranslate} beforeActivation_to_activationLinearDomain_ScaleTranslate
 *   The scale-translate for letting beforeActivation bounds moving into the linear domain of the activation function. That is,
 * for letting beforeActivation escape from activation function's non-linear domain.
 */
class Base {

  /**
   * @param {FloatValue.Bounds} inputValueBounds
   *   The bounds of the input element value. Or say, the domain of this convolution-bias-activation.
   */
  constructor( inputValueBounds ) {
    this.set_All_byClone( inputValueBounds ); // (Copy for preventing from modifying.)
  }

  /**
   * Set this.input, this.beforeActivation, this.output by copying the specified inputValueBounds.
   *
   * @param {FloatValue.Bounds} inputValueBounds
   *   The bounds of the input element value. Or say, the domain of this convolution-bias-activation.
   */
  set_all_byClone( inputValueBounds ) {
    this.input = inputValueBounds.clone();
    this.set_beforeActivation_output_byClone_input();
  }

  /**
   * Set this.beforeActivation and this.output by copying this.input.
   */
  set_beforeActivation_output_byClone_input() {
    this.beforeActivation = this.input.clone();
    this.output = this.input.clone();
    this.beforeActivation_to_activationLinearDomain_ScaleTranslate( 1, 0 ); // scale 1 and translate 0. i.e. no change.
  }

  /**
   * Set this.output according to this.beforeActivation and the specified nActivationId. This method will also calculate
   * this.beforeActivation_to_activationLinearDomain_ScaleTranslate.
   *
   * @param {number} nActivationId
   *   The activation function id (ValueDesc.ActivationFunction.Singleton.Ids.Xxx) after the bias operation.
   *     - If ( nActivationId == ValueDesc.ActivationFunction.Singletion.Ids.NONE ), this.output will be the same as this.beforeActivation.
   *     - Otherwise, this.output will be the same as the output range of the activation function.
   */
  set_output_byActivationId( nActivationId ) {

    // 1. Determine output value bounds.
    {
      // If there is no activation function, the output range is determined by input domain, filters, biases.
      if ( this.nActivationId == ValueDesc.ActivationFunction.Singletion.Ids.NONE ) {
        this.output.set_Bounds( this.beforeActivation );

      // Otherwise, the activation function dominates the output range.
      } else {
        let info = ValueDesc.ActivationFunction.Singletion.getInfoById( this.nActivationId );
        this.output.set_Bounds( info.outputRange );
      }
    }

    // 2. Calculate the scale-translate for escaping activation function's non-linear domain.
    this.beforeActivation_to_activationLinearDomain_ScaleTranslate.setBy_FromTo( this.beforeActivation, this.output );
  }

}

<commit_msg>Update ConvBiasActivation_ValueBounds.js<commit_after>export { Base };

import * as FloatValue from "../../Unpacker/FloatValue.js";
import * as ValueDesc from "../../Unpacker/ValueDesc.js";

/**
 *
 * @member {FloatValue.Bounds} input
 *   The bounds of the input element value. Or say, the domain of the convolution-bias-activation.
 *
 * @member {FloatValue.Bounds} beforeActivation
 *   The bounds of the element value after convolution and bias operation (but before activation).
 *
 * @member {FloatValue.Bounds} output
 *   The bounds of the output element value. Or say, the range of the convolution-bias-activation.
 *
 * @member {FloatValue.ScaleTranslate} beforeActivation_to_activationLinearDomain_ScaleTranslate
 *   The scale-translate for letting beforeActivation bounds moving into the linear domain of the activation function. That is,
 * for letting beforeActivation escape from activation function's non-linear domain.
 */
class Base {

  /**
   * @param {FloatValue.Bounds} inputValueBounds
   *   The bounds of the input element value. Or say, the domain of this convolution-bias-activation.
   */
  constructor( inputValueBounds ) {
    this.input = inputValueBounds.clone(); // (Copy for preventing from modifying.)
  }

  /**
   * Set this.input, this.beforeActivation, this.output by copying the specified inputValueBounds.
   *
   * @param {FloatValue.Bounds} inputValueBounds
   *   The bounds of the input element value. Or say, the domain of this convolution-bias-activation.
   */
  set_all_byClone( inputValueBounds ) {
    this.input = inputValueBounds.clone();
    this.set_beforeActivation_output_byClone_input();
  }

  /**
   * Set this.beforeActivation and this.output by copying this.input.
   */
  set_beforeActivation_output_byClone_input() {
    this.beforeActivation = this.input.clone();
    this.output = this.input.clone();
    this.beforeActivation_to_activationLinearDomain_ScaleTranslate( 1, 0 ); // scale 1 and translate 0. i.e. no change.
  }

  /**
   * Set this.output according to this.beforeActivation and the specified nActivationId. This method will also calculate
   * this.beforeActivation_to_activationLinearDomain_ScaleTranslate.
   *
   * @param {number} nActivationId
   *   The activation function id (ValueDesc.ActivationFunction.Singleton.Ids.Xxx) after the bias operation.
   *     - If ( nActivationId == ValueDesc.ActivationFunction.Singletion.Ids.NONE ), this.output will be the same as this.beforeActivation.
   *     - Otherwise, this.output will be the same as the output range of the activation function.
   */
  set_output_byActivationId( nActivationId ) {

    // 1. Determine output value bounds.
    {
      // If there is no activation function, the output range is determined by input domain, filters, biases.
      if ( this.nActivationId == ValueDesc.ActivationFunction.Singletion.Ids.NONE ) {
        this.output.set_Bounds( this.beforeActivation );

      // Otherwise, the activation function dominates the output range.
      } else {
        let info = ValueDesc.ActivationFunction.Singletion.getInfoById( this.nActivationId );
        this.output.set_Bounds( info.outputRange );
      }
    }

    // 2. Calculate the scale-translate for escaping activation function's non-linear domain.
    this.beforeActivation_to_activationLinearDomain_ScaleTranslate.setBy_FromTo( this.beforeActivation, this.output );
  }

}

<|endoftext|>


<commit_before>
var titleTemplate = '' +
    '
' +
    '   {{count}} Stack Overflow question{{^count_is_one}}s{{/count_is_one}}' +
    '
';

function getPepNo() {
    var matches = document.location.pathname.match(/[0-9]+/);
    if(matches) return [0];
}

stackdoc.fetchData("pythonpep", getPepNo(), function(data, renderedList) {
    var titleText = Mustache.render(titleTemplate, {count: data.length, count_is_one: data.length === 1}),
        $sd = $(titleText),
        $sdTitle = $($.grep($sd, function(x) { return x.id === "stackdoc-title"; })[0]);

    if(data.length > 0) {
        $sdTitle.popover({
            content: renderedList,
            classes: "large"
        }).addClass("clickable");
    }

    $sd.insertAfter($("#content table.rfc2822"));
});
<commit_msg>Fix ID fetching.<commit_after>
var titleTemplate = '' +
    '
' +
    '   {{count}} Stack Overflow question{{^count_is_one}}s{{/count_is_one}}' +
    '
';

function getPepNo() {
    var matches = document.location.pathname.match(/[0-9]+/);
    if(matches) return matches[0];
}

stackdoc.fetchData("pythonpep", getPepNo(), function(data, renderedList) {
    var titleText = Mustache.render(titleTemplate, {count: data.length, count_is_one: data.length === 1}),
        $sd = $(titleText),
        $sdTitle = $($.grep($sd, function(x) { return x.id === "stackdoc-title"; })[0]);

    if(data.length > 0) {
        $sdTitle.popover({
            content: renderedList,
            classes: "large"
        }).addClass("clickable");
    }

    $sd.insertAfter($("#content table.rfc2822"));
});
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { connect } from 'react-redux';

import { MEDIA_TYPE, VideoTrack } from '../../base/media';
import { getParticipant } from '../../base/participants';
import { getTrackByMediaTypeAndParticipant } from '../../base/tracks';
import { Avatar } from '../../conference';

import { LargeVideoContainer } from './LargeVideoContainer';
import { styles } from './styles';

/**
 * Large video React component.
 *
 * @extends Component
 */
class LargeVideo extends Component {
    /**
     * Implements React's {@link Component#render()}.
     *
     * @inheritdoc
     * @returns {ReactElement}
     */
    render() {
        const avatar = this.props.avatar;
        const videoTrack = this.props.videoTrack;
        const renderAvatar
            = typeof avatar !== 'undefined'
                && avatar !== ''
                && (!videoTrack
                    || (videoTrack
                        && (!videoTrack.videoStarted || videoTrack.muted)));

        return (
            <LargeVideoContainer>
                { renderAvatar
                    && <Avatar
                        additionalStyle = { styles.dominantSpeakerAvatar }
                        uri = { avatar } /> }

                <VideoTrack
                    videoTrack = { videoTrack }
                    waitForVideoStarted = { true } />
            </LargeVideoContainer>
        );
    }
}

/**
 * Maps parts Redux state to Component's props.
 *
 * @param {Object} state - Redux state.
 * @returns {{
 *      avatar: string,
 *      videoTrack: Track
 * }}
 */
const mapStateToProps = state => {
    const participantId = state['features/largeVideo'].participantId;

    return {
        avatar: (getParticipant(
            state['features/base/participants'],
            participantId) || {}).avatar,
        videoTrack: getTrackByMediaTypeAndParticipant(
            state['features/base/tracks'],
            MEDIA_TYPE.VIDEO,
            participantId)
    };
};

/**
 * LargeVideo component's property types.
 *
 * @static
 */
LargeVideo.propTypes = {
    avatar: React.PropTypes.string,
    dispatch: React.PropTypes.func,
    videoTrack: React.PropTypes.object
};

export default connect(mapStateToProps)(LargeVideo);
<commit_msg>Simplified several pieces of code after review<commit_after>import React, { Component } from 'react';
import { connect } from 'react-redux';

import { MEDIA_TYPE, VideoTrack } from '../../base/media';
import { getParticipant } from '../../base/participants';
import { getTrackByMediaTypeAndParticipant } from '../../base/tracks';
import { Avatar } from '../../conference';

import { LargeVideoContainer } from './LargeVideoContainer';
import { styles } from './styles';

/**
 * Large video React component.
 *
 * @extends Component
 */
class LargeVideo extends Component {
    /**
     * Implements React's {@link Component#render()}.
     *
     * @inheritdoc
     * @returns {ReactElement}
     */
    render() {
        const avatar = this.props.avatar;
        const videoTrack = this.props.videoTrack;
        const renderAvatar
            = typeof avatar !== 'undefined'
                && avatar !== ''
                && (!videoTrack
                    || (!videoTrack.videoStarted || videoTrack.muted));

        return (
            <LargeVideoContainer>
                { renderAvatar
                    && <Avatar
                        additionalStyle = { styles.dominantSpeakerAvatar }
                        uri = { avatar } /> }

                <VideoTrack
                    videoTrack = { videoTrack }
                    waitForVideoStarted = { true } />
            </LargeVideoContainer>
        );
    }
}

/**
 * Maps parts Redux state to Component's props.
 *
 * @param {Object} state - Redux state.
 * @returns {{
 *      avatar: string,
 *      videoTrack: Track
 * }}
 */
const mapStateToProps = state => {
    const participantId = state['features/largeVideo'].participantId;
    const participant = getParticipant(
        state['features/base/participants'],
        participantId);

    return {
        avatar: participant ? participant.avatar : undefined,
        videoTrack: getTrackByMediaTypeAndParticipant(
            state['features/base/tracks'],
            MEDIA_TYPE.VIDEO,
            participantId)
    };
};

/**
 * LargeVideo component's property types.
 *
 * @static
 */
LargeVideo.propTypes = {
    avatar: React.PropTypes.string,
    dispatch: React.PropTypes.func,
    videoTrack: React.PropTypes.object
};

export default connect(mapStateToProps)(LargeVideo);
<|endoftext|>


<commit_before>import React, {PropTypes} from 'react';
import Dropdown from 'src/shared/components/Dropdown';
import {Tab, TabList, TabPanels, TabPanel, Tabs} from 'shared/components/Tabs';

const TABS = ['Threshold', 'Relative', 'Deadman'];
export const ValuesSection = React.createClass({
  propTypes: {
    rule: PropTypes.shape({
      id: PropTypes.string,
    }).isRequired,
    onChooseTrigger: PropTypes.func.isRequired,
    onUpdateValues: PropTypes.func.isRequired,
  },

  // √ when a tab is selected, update the rule.trigger to match
  // when the user interacts with the form associated with a trigger,
  // round up all of the data and overwrite the values in the rule.
  //
  // Then, when save is clicked, the rule will already be in the right state to be sent to the server...
  // We can run validations before we even highlight the save button
  //
  render() {
    const {rule} = this.props;

    return (

            <Tabs onSelect={this.handleChooseTrigger}>
              <TabList>
                {TABS.map(tab => <Tab key={tab}>{tab}</Tab>)}
              </TabList>

              <TabPanels>
                <TabPanel>
                  <Threshold rule={rule} onChange={this.handleValuesChange} />
                </TabPanel>
                <TabPanel>
                  <Relative rule={rule} onChange={this.handleValuesChange} />
                </TabPanel>
                <TabPanel>
                  <Deadman rule={rule} onChange={this.handleValuesChange} />
                </TabPanel>
              </TabPanels>
            </Tabs>

    );
  },

  handleChooseTrigger(triggerIndex) {
    const {rule, onChooseTrigger} = this.props;
    if (TABS[triggerIndex] === rule.trigger) {
      return;
    }

    onChooseTrigger(rule.id, TABS[triggerIndex]);
  },

  handleValuesChange(values) {
    const {onUpdateValues, rule} = this.props;
    onUpdateValues(rule.id, rule.trigger, values);
  },
});

const Threshold = React.createClass({
  propTypes: {
    rule: PropTypes.shape({
      values: PropTypes.shape({
        operator: PropTypes.string,
        value: PropTypes.string,
        relation: PropTypes.string,
        percentile: PropTypes.string,
        duration: PropTypes.string,
      }),
    }),
    onChange: PropTypes.func.isRequired,
  },

  handleDropdownChange(item) {
    const newValues = Object.assign({}, this.props.rule.values, {[item.type]: item.text});
    this.props.onChange(newValues);
  },

  handleInputChange() {
    this.props.onChange(Object.assign({}, this.props.rule.values, {
      value: this.valueInput.value,
      percentile: this.percentileInput.value,
    }));
  },

  render() {
    const {operator, value, relation, percentile, duration} = this.props.rule.values;

    function mapToItems(arr, type) {
      return arr.map((text) => {
        return {text, type};
      });
    }

    const operators = mapToItems(['greater than', 'less than', 'equal to', 'not equal to'], 'operator');
    const relations = mapToItems(['once', 'more than ', 'less than'], 'relation');
    const durations = mapToItems(['1m', '5m', '10m', '30m', '1h', '2h', '1h'], 'duration');

    return (

        Value is
        <Dropdown items={operators} selected={operator} onChoose={this.handleDropdownChange} />
        <input ref={(r) => this.valueInput = r} defaultValue={value} onKeyUp={this.handleInputChange}></input>
        <Dropdown items={relations} selected={relation} onChoose={this.handleDropdownChange} />
        <input ref={(r) => this.percentileInput = r} defaultValue={percentile} onKeyUp={this.handleInputChange}></input>
        during the last
        <Dropdown items={durations} selected={duration} onChoose={this.handleDropdownChange} />

    );
  },
});

const Relative = React.createClass({
  propTypes: {
    rule: PropTypes.shape({
      values: PropTypes.shape({
        func: PropTypes.string,
        change: PropTypes.string,
        duration: PropTypes.string,
        compareDuration: PropTypes.string,
        operator: PropTypes.string,
        value: PropTypes.string,
      }),
    }),
    onChange: PropTypes.func.isRequired,
  },

  handleDropdownChange(item) {
    this.props.onChange(Object.assign({}, this.props.rule.values, {[item.type]: item.text}));
  },

  handleInputChange() {
    this.props.onChange(Object.assign({}, this.props.rule.values, {value: this.input.value}));
  },

  render() {
    const {func, change, duration, compareDuration, operator, value} = this.props.rule.values;

    function mapToItems(arr, type) {
      return arr.map((text) => {
        return {text, type};
      });
    }

    const funcs = mapToItems(['greater than', 'less than', 'equal to', 'not equal to'], 'func');
    const changes = mapToItems(['change', '% change'], 'change');
    const durations = mapToItems(['1m', '5m', '10m', '30m', '1h', '2h', '1h'], 'duration');
    const compareDurations = mapToItems(['1m', '5m', '10m', '30m', '1h', '2h', '1h'], 'compareDuration');
    const operators = mapToItems(['greater than', 'less than', 'equal to', 'not equal to'], 'operator');

    return (

        The
        <Dropdown items={funcs} selected={func} onChoose={this.handleDropdownChange} />
        of the
        <Dropdown items={changes} selected={change} onChoose={this.handleDropdownChange} />
        over
        <Dropdown items={durations} selected={duration} onChoose={this.handleDropdownChange} />
        compared to
        <Dropdown items={compareDurations} selected={compareDuration} onChoose={this.handleDropdownChange} />
        before is
        <Dropdown items={operators} selected={operator} onChoose={this.handleDropdownChange} />
        <input ref={(r) => this.input = r} defaultValue={value} onKeyUp={this.handleInputChange}></input>%

    );
  },
});

const Deadman = React.createClass({
  propTypes: {
    rule: PropTypes.shape({
      values: PropTypes.shape({
        duration: PropTypes.string,
      }),
    }),
    onChange: PropTypes.func.isRequired,
  },

  handleChange(item) {
    this.props.onChange({duration: item.text});
  },

  render() {
    const durations = [{text: '1m'}, {text: '5m'}, {text: '10m'}, {text: '30m'}, {text: '1h'}, {text: '2h'}, {text: '1h'}];

    return (

        Create an alert if data is missing for
        <Dropdown items={durations} selected={this.props.rule.values.duration} onChoose={this.handleChange} />

    );
  },
});

export default ValuesSection;
<commit_msg>Remove percentile if once is selected<commit_after>import React, {PropTypes} from 'react';
import Dropdown from 'src/shared/components/Dropdown';
import {Tab, TabList, TabPanels, TabPanel, Tabs} from 'shared/components/Tabs';

const TABS = ['Threshold', 'Relative', 'Deadman'];
export const ValuesSection = React.createClass({
  propTypes: {
    rule: PropTypes.shape({
      id: PropTypes.string,
    }).isRequired,
    onChooseTrigger: PropTypes.func.isRequired,
    onUpdateValues: PropTypes.func.isRequired,
  },

  // √ when a tab is selected, update the rule.trigger to match
  // when the user interacts with the form associated with a trigger,
  // round up all of the data and overwrite the values in the rule.
  //
  // Then, when save is clicked, the rule will already be in the right state to be sent to the server...
  // We can run validations before we even highlight the save button
  //
  render() {
    const {rule} = this.props;

    return (

            <Tabs onSelect={this.handleChooseTrigger}>
              <TabList>
                {TABS.map(tab => <Tab key={tab}>{tab}</Tab>)}
              </TabList>

              <TabPanels>
                <TabPanel>
                  <Threshold rule={rule} onChange={this.handleValuesChange} />
                </TabPanel>
                <TabPanel>
                  <Relative rule={rule} onChange={this.handleValuesChange} />
                </TabPanel>
                <TabPanel>
                  <Deadman rule={rule} onChange={this.handleValuesChange} />
                </TabPanel>
              </TabPanels>
            </Tabs>

    );
  },

  handleChooseTrigger(triggerIndex) {
    const {rule, onChooseTrigger} = this.props;
    if (TABS[triggerIndex] === rule.trigger) {
      return;
    }

    onChooseTrigger(rule.id, TABS[triggerIndex]);
  },

  handleValuesChange(values) {
    const {onUpdateValues, rule} = this.props;
    onUpdateValues(rule.id, rule.trigger, values);
  },
});

const Threshold = React.createClass({
  propTypes: {
    rule: PropTypes.shape({
      values: PropTypes.shape({
        operator: PropTypes.string,
        value: PropTypes.string,
        relation: PropTypes.string,
        percentile: PropTypes.string,
        duration: PropTypes.string,
      }),
    }),
    onChange: PropTypes.func.isRequired,
  },

  handleDropdownChange(item) {
    const newValues = Object.assign({}, this.props.rule.values, {[item.type]: item.text});
    this.props.onChange(newValues);
  },

  handleInputChange() {
    this.props.onChange(Object.assign({}, this.props.rule.values, {
      value: this.valueInput.value,
      percentile: this.percentileInput.value,
    }));
  },

  render() {
    const {operator, value, relation, percentile, duration} = this.props.rule.values;

    function mapToItems(arr, type) {
      return arr.map((text) => {
        return {text, type};
      });
    }

    const operators = mapToItems(['greater than', 'less than', 'equal to', 'not equal to'], 'operator');
    const relations = mapToItems(['once', 'more than ', 'less than'], 'relation');
    const durations = mapToItems(['1m', '5m', '10m', '30m', '1h', '2h', '1h'], 'duration');

    return (

        Value is
        <Dropdown items={operators} selected={operator} onChoose={this.handleDropdownChange} />
        <input ref={(r) => this.valueInput = r} defaultValue={value} onKeyUp={this.handleInputChange}></input>
        <Dropdown items={relations} selected={relation} onChoose={this.handleDropdownChange} />
        {relation === 'once' ? null : <input ref={(r) => this.percentileInput = r} defaultValue={percentile} onKeyUp={this.handleInputChange}></input>}
        during the last
        <Dropdown items={durations} selected={duration} onChoose={this.handleDropdownChange} />

    );
  },
});

const Relative = React.createClass({
  propTypes: {
    rule: PropTypes.shape({
      values: PropTypes.shape({
        func: PropTypes.string,
        change: PropTypes.string,
        duration: PropTypes.string,
        compareDuration: PropTypes.string,
        operator: PropTypes.string,
        value: PropTypes.string,
      }),
    }),
    onChange: PropTypes.func.isRequired,
  },

  handleDropdownChange(item) {
    this.props.onChange(Object.assign({}, this.props.rule.values, {[item.type]: item.text}));
  },

  handleInputChange() {
    this.props.onChange(Object.assign({}, this.props.rule.values, {value: this.input.value}));
  },

  render() {
    const {func, change, duration, compareDuration, operator, value} = this.props.rule.values;

    function mapToItems(arr, type) {
      return arr.map((text) => {
        return {text, type};
      });
    }

    const funcs = mapToItems(['greater than', 'less than', 'equal to', 'not equal to'], 'func');
    const changes = mapToItems(['change', '% change'], 'change');
    const durations = mapToItems(['1m', '5m', '10m', '30m', '1h', '2h', '1h'], 'duration');
    const compareDurations = mapToItems(['1m', '5m', '10m', '30m', '1h', '2h', '1h'], 'compareDuration');
    const operators = mapToItems(['greater than', 'less than', 'equal to', 'not equal to'], 'operator');

    return (

        The
        <Dropdown items={funcs} selected={func} onChoose={this.handleDropdownChange} />
        of the
        <Dropdown items={changes} selected={change} onChoose={this.handleDropdownChange} />
        over
        <Dropdown items={durations} selected={duration} onChoose={this.handleDropdownChange} />
        compared to
        <Dropdown items={compareDurations} selected={compareDuration} onChoose={this.handleDropdownChange} />
        before is
        <Dropdown items={operators} selected={operator} onChoose={this.handleDropdownChange} />
        <input ref={(r) => this.input = r} defaultValue={value} onKeyUp={this.handleInputChange}></input>%

    );
  },
});

const Deadman = React.createClass({
  propTypes: {
    rule: PropTypes.shape({
      values: PropTypes.shape({
        duration: PropTypes.string,
      }),
    }),
    onChange: PropTypes.func.isRequired,
  },

  handleChange(item) {
    this.props.onChange({duration: item.text});
  },

  render() {
    const durations = [{text: '1m'}, {text: '5m'}, {text: '10m'}, {text: '30m'}, {text: '1h'}, {text: '2h'}, {text: '1h'}];

    return (

        Create an alert if data is missing for
        <Dropdown items={durations} selected={this.props.rule.values.duration} onChoose={this.handleChange} />

    );
  },
});

export default ValuesSection;
<|endoftext|>