<commit_before>/* ************************************ */
/* Define helper functions */
/* ************************************ */
function getDisplayElement() {
  $('

').appendTo('body')
  return $('

').appendTo('body')
}

function evalAttentionChecks() {
  var check_percent = 1
  if (run_attention_checks) {
    var attention_check_trials = jsPsych.data.getTrialsOfType('attention-check')
    var checks_passed = 0
    for (var i = 0; i < attention_check_trials.length; i++) {
      if (attention_check_trials[i].correct === true) {
        checks_passed += 1
      }
    }
    check_percent = checks_passed / attention_check_trials.length
  }
  return check_percent
}

function addID() {
  jsPsych.data.addDataToLastTrial({
    'exp_id': 'hierarchical_rule'
  })
}

var randomDraw = function(lst) {
  var index = Math.floor(Math.random() * (lst.length))
  return lst[index]
}

var getFixLength = function() {
  return 250 + Math.random() * 500
}
var getFeedback = function() {
  var last_trial = jsPsych.data.getLastTrialData()
  if (last_trial.key_press == -1) {
    return '

Respond faster!

'
  } else if (last_trial.key_press == last_trial.correct_response) {
    correct += 1
    return '

Correct

'
  } else {
    return '

Incorrect

'
  }
}

var getHierarchicalStim = function() {
  return hierarchical_stims.stimulus.shift()
}

var getHierarchicalData = function() {
  return hierarchical_stims.data.shift()
}

var getFlatStim = function() {
  return flat_stims.stimulus.shift()
}

var getFlatData = function() {
  return flat_stims.data.shift()
}

var getInstructFeedback = function() {
  return '

' +
    feedback_instruct_text + '

'
}

/* ************************************ */
/* Define experimental variables */
/* ************************************ */
// generic task variables
var run_attention_checks = false
var attention_check_thresh = 0.45
var sumInstructTime = 0 //ms
var instructTimeThresh = 0 ///in seconds

// task specific variables
var exp_len = 200 //number of trials per rule-set
var flat_first = 0 //  Math.floor(Math.random())
var path_source = '/static/experiments/hierarchical_rule/images/'
var stim_prefix = '

<img class = hierarchicalStim src ='
var border_prefix = '<img class = hierarchicalBorder src ='
var prompt_prefix = '<img class = hierarchicalPrompt src ='
var postfix = '

'
var choices = [74, 75, 76]
var correct = 0 // tracks correct trials

//generate stims
//1=red, 2=blue, 3=green, 4=yellow BORDER COLORS
//1=vertical, 2=slant, 3=horizontal ORIENTATION OF STIMS
flat_stims = []
hierarchical_stims = []
colors = jsPsych.randomization.shuffle([1, 2, 3, 4]) //border colors
stims = jsPsych.randomization.shuffle([1, 2, 3, 4, 5, 6])
orientations = [1, 2, 3]
color_data = ['red','blue','green','yellow']
orientation_data = ['vertical','slant','horizontal']
random_correct = jsPsych.randomization.repeat(choices, 6) // correct responses for random stim
for (var c = 0; c < colors.length; c++) {
  for (var s = 0; s < stims.length / 2; s++) {
    for (var o = 0; o < orientations.length; o++) {
      if (c < colors.length / 2) {
        flat_stims.push({
          stimulus: stim_prefix + path_source + stims[s] + orientations[o] + '.bmp ' +
            border_prefix + path_source + colors[c] + '_border.png' + postfix,
          data: {
            stim: stims[s],
            orientation: orientation_data[orientations[o]-1],
            border: color_data[colors[c]-1],
            exp_stage: "test",
            correct_response: random_correct.pop()
          }
        })
      } else {
        if (c == 2) {
          correct_response = choices[s - 1]
        } else if (c == 3) {
          correct_response = choices[o - 1]
        }
        hierarchical_stims.push({
          stimulus: stim_prefix + path_source + stims[s + (stims.length / 2)] + orientations[o] +
            '.bmp ' + border_prefix + path_source + colors[c] + '_border.png' + postfix,
          data: {
            stim: stims[s + (stims.length / 2)],
            orientation: orientation_data[orientations[o]-1],
            exp_stage: "test",
            border: color_data[colors[c]-1],
            correct_response: correct_response
          }
        })
      }
    }
  }
}
// flat_stims = jsPsych.randomization.repeat(flat_stims,20,true)
// hierarchical_stims = jsPsych.randomization.repeat(hierarchical_stims,20,true)
// Change structure of object array to work with new structure
flat_stims = jsPsych.randomization.repeat(flat_stims, 20, true)
hierarchical_stims = jsPsych.randomization.repeat(hierarchical_stims, 20, true)

instructions_grid = '
'
for (var c = 0; c < colors.length / 2; c++) {
  for (var s = 0; s < stims.length / 2; s++) {
    for (var o = 0; o < orientations.length; o++) {
      instructions_grid +=
        '
<img class = gridImage src = ' + path_source + stims[s] +
        orientations[o] + '.bmp '
      instructions_grid +=
        '<img class = gridBorder src = ' + path_source + colors[c] + '_border.png
'
    }
  }
}
instructions_grid += '
'

/* ************************************ */
/* Set up jsPsych blocks */
/* ************************************ */
// Set up attention check node
var attention_check_block = {
  type: 'attention-check',
  data: {
    trial_id: "attention_check"
  },
  timing_response: 180000,
  response_ends_trial: true,
  timing_post_trial: 200
}

var attention_node = {
  timeline: [attention_check_block],
  conditional_function: function() {
    return run_attention_checks
  }
}

/* define static blocks */
var feedback_instruct_text =
  'Welcome to the experiment. Press enter to begin.'
var feedback_instruct_block = {
  type: 'poldrack-text',
  cont_key: [13],
  data: {
    trial_id: "instruction"
  },
  text: getInstructFeedback,
  timing_post_trial: 0,
  timing_response: 180000
};
/// This ensures that the subject does not read through the instructions too quickly.  If they do it too quickly, then we will go over the loop again.
var instruction_trials = []
var instructions_block = {
  type: 'poldrack-instructions',
  data: {
    trial_id: "instruction"
  },
  pages: [
    '

In this experiment stimuli will come up one at a time. You should respond to them by pressing the J, K or L keys, after which you will receive feedback about whether you were right or not. If you were correct you will get points which contribute to your bonus payment.

Your job is to get as many trials correct as possible! On the next page are the stimuli you will be responding to.

',
    instructions_grid,
    '

Make sure you are familiar with the stimuli on the last page. Remember, respond to the stimuli by pressing J, K, or L. You will get a bonus based on your performance so try your best!

This experiment will take about 30 minutes. There will be a break half way through. Good luck!

'
  ],
  allow_keys: false,
  show_clickable_nav: true
};
instruction_trials.push(feedback_instruct_block)
instruction_trials.push(instructions_block)

var instruction_node = {
  timeline: instruction_trials,
  /* This function defines stopping criteria */
  loop_function: function(data) {
    for (i = 0; i < data.length; i++) {
      if ((data[i].trial_type == 'poldrack-instructions') && (data[i].rt != -1)) {
        rt = data[i].rt
        sumInstructTime = sumInstructTime + rt
      }
    }
    if (sumInstructTime <= instructTimeThresh * 1000) {
      feedback_instruct_text =
        'Read through instructions too quickly.  Please take your time and make sure you understand the instructions.  Press enter to continue.'
      return true
    } else if (sumInstructTime > instructTimeThresh * 1000) {
      feedback_instruct_text =
        'Done with instructions. Press enter to continue.'
      return false
    }
  }
}

var end_block = {
  type: 'poldrack-text',
  timing_response: 180000,
  data: {
    trial_id: "end"
  },
  text: '

Thanks for completing this task!

Press enter to begin.

',
  cont_key: [13],
  timing_post_trial: 0
};

var start_test_block = {
  type: 'poldrack-text',
  data: {
    trial_id: "test_intro"
  },
  timing_response: 180000,
  text: '

We will now start the test.

Press enter to begin.

',
  cont_key: [13],
  timing_post_trial: 1000
};

var fixation_block = {
  type: 'poldrack-single-stim',
  stimulus: prompt_prefix + path_source + 'FIX.png' + ' style:"z-index: -1"' + postfix,
  is_html: true,
  choices: 'none',
  data: {
    trial_id: "fixation",
    exp_stage: "test"
  },
  response_ends_trial: false,
  timing_post_trial: 0,
  timing_stim: -1,
  timing_response: getFixLength
}

var feedback_block = {
  type: 'poldrack-single-stim',
  stimulus: getFeedback,
  is_html: true,
  choices: 'none',
  data: {
    trial_id: "feedback",
    exp_stage: "test"
  },
  response_ends_trial: false,
  timing_post_trial: 0,
  timing_stim: 1000,
  timing_response: 1000
}

var flat_stim_block = {
  type: 'poldrack-single-stim',
  stimulus: getFlatStim,
  data: getFlatData,
  is_html: true,
  choices: choices,
  response_ends_trial: false,
  timing_stim: 1000,
  timing_response: 3000,
  prompt: prompt_prefix + path_source + 'FIX_GREEN.png' + ' style:"z-index: -1"' + postfix,
  timing_post_trial: 0,
  on_finish: function() {
    jsPsych.data.addDataToLastTrial({
      trial_id: "flat_stim",
      exp_stage: "test"
    })
  }
}

var hierarchical_stim_block = {
  type: 'poldrack-single-stim',
  stimulus: getHierarchicalStim,
  data: getHierarchicalData,
  is_html: true,
  choices: choices,
  response_ends_trial: false,
  timing_stim: 1000,
  timing_response: 3000,
  prompt: prompt_prefix + path_source + 'FIX_GREEN.png' + ' style:"z-index: -1"' + postfix,
  timing_post_trial: 0,
  on_finish: function() {
    jsPsych.data.addDataToLastTrial({
      trial_id: "hierarchical_stim",
      exp_stage: "test"
    })
  }
}

// loop nodes instead of creating a huge array with three blocks for all trials
var flat_loop_node = {
  timeline: [fixation_block, flat_stim_block, feedback_block],
  loop_function: function(data) {
    if (flat_stims.stimulus.length > 0) {
      return true;
    } else {
      return false;
    }
  }
}

var hierarchical_loop_node = {
  timeline: [fixation_block, hierarchical_stim_block, feedback_block],
  loop_function: function(data) {
    if (hierarchical_stims.stimulus.length > 0) {
      return true;
    } else {
      return false;
    }
  }
}

//Set up experiment
var hierarchical_rule_experiment = []
hierarchical_rule_experiment.push(instruction_node);
hierarchical_rule_experiment.push(start_test_block);
// setup exp w loop nodes after pushing the practice etc. blocks
if (flat_first == 1) {
  hierarchical_rule_experiment.push(flat_loop_node, attention_node, start_test_block,
    hierarchical_loop_node, attention_node);
} else {
  hierarchical_rule_experiment.push(hierarchical_loop_node, attention_node, start_test_block,
    flat_loop_node, attention_node);
}

hierarchical_rule_experiment.push(end_block)<commit_msg>changed color of hierarchical rule task, made the flat task an optional task parameter (and set it to not run for the UH2 grant) and changed some instructions<commit_after>/* ************************************ */
/* Define helper functions */
/* ************************************ */
function getDisplayElement() {
  $('

').appendTo('body')
  return $('

').appendTo('body')
}

function evalAttentionChecks() {
  var check_percent = 1
  if (run_attention_checks) {
    var attention_check_trials = jsPsych.data.getTrialsOfType('attention-check')
    var checks_passed = 0
    for (var i = 0; i < attention_check_trials.length; i++) {
      if (attention_check_trials[i].correct === true) {
        checks_passed += 1
      }
    }
    check_percent = checks_passed / attention_check_trials.length
  }
  return check_percent
}

function addID() {
  jsPsych.data.addDataToLastTrial({
    'exp_id': 'hierarchical_rule'
  })
}

var randomDraw = function(lst) {
  var index = Math.floor(Math.random() * (lst.length))
  return lst[index]
}

var getFixLength = function() {
  return 250 + Math.random() * 500
}
var getFeedback = function() {
  var last_trial = jsPsych.data.getLastTrialData()
  if (last_trial.key_press == -1) {
    return '

Respond faster!

'
  } else if (last_trial.key_press == last_trial.correct_response) {
    correct += 1
    return
      '

Correct!

'
  } else {
    return
      '

Incorrect

'
  }
}

var getHierarchicalStim = function() {
  return hierarchical_stims.stimulus.shift()
}

var getHierarchicalData = function() {
  return hierarchical_stims.data.shift()
}

var getFlatStim = function() {
  return flat_stims.stimulus.shift()
}

var getFlatData = function() {
  return flat_stims.data.shift()
}

var getInstructFeedback = function() {
  return '

' +
    feedback_instruct_text + '

'
}

/* ************************************ */
/* Define experimental variables */
/* ************************************ */
// generic task variables
var run_attention_checks = false
var attention_check_thresh = 0.45
var sumInstructTime = 0 //ms
var instructTimeThresh = 0 ///in seconds

// task specific variables
var hierarchical_only = true //When this is true, do not run the flat task
var exp_len = 360 //number of trials per rule-set
var flat_first = 0 //  Math.floor(Math.random())
var path_source = '/static/experiments/hierarchical_rule/images/'
var stim_prefix = '

<img class = hierarchicalStim src ='
var border_prefix = '<img class = hierarchicalBorder src ='
var prompt_prefix = '<img class = hierarchicalPrompt src ='
var postfix = '

'
var choices = [74, 75, 76]
var correct = 0 // tracks correct trials

//generate stims
//1=red, 2=blue, 3=green, 4=yellow BORDER COLORS
//1=vertical, 2=slant, 3=horizontal ORIENTATION OF STIMS
flat_stims = []
hierarchical_stims = []
colors = jsPsych.randomization.shuffle([1, 2, 3, 4]) //border colors
stims = jsPsych.randomization.shuffle([1, 2, 3, 4, 5, 6])
orientations = [1, 2, 3]
color_data = ['red', 'blue', 'green', 'yellow']
orientation_data = ['vertical', 'slant', 'horizontal']
random_correct = jsPsych.randomization.repeat(choices, 6) // correct responses for random stim
for (var c = 0; c < colors.length; c++) {
  for (var s = 0; s < stims.length / 2; s++) {
    for (var o = 0; o < orientations.length; o++) {
      if (c < colors.length / 2) {
        flat_stims.push({
          stimulus: stim_prefix + path_source + stims[s] + orientations[o] + '.bmp ' +
            border_prefix + path_source + colors[c] + '_border.png' + postfix,
          data: {
            stim: stims[s],
            orientation: orientation_data[orientations[o] - 1],
            border: color_data[colors[c] - 1],
            exp_stage: "test",
            correct_response: random_correct.pop()
          }
        })
      } else {
        if (c == 2) {
          correct_response = choices[s - 1]
        } else if (c == 3) {
          correct_response = choices[o - 1]
        }
        hierarchical_stims.push({
          stimulus: stim_prefix + path_source + stims[s + (stims.length / 2)] + orientations[o] +
            '.bmp ' + border_prefix + path_source + colors[c] + '_border.png' + postfix,
          data: {
            stim: stims[s + (stims.length / 2)],
            orientation: orientation_data[orientations[o] - 1],
            exp_stage: "test",
            border: color_data[colors[c] - 1],
            correct_response: correct_response
          }
        })
      }
    }
  }
}
// flat_stims = jsPsych.randomization.repeat(flat_stims,20,true)
// hierarchical_stims = jsPsych.randomization.repeat(hierarchical_stims,20,true)
// Change structure of object array to work with new structure
flat_stims = jsPsych.randomization.repeat(flat_stims, 20, true)
hierarchical_stims = jsPsych.randomization.repeat(hierarchical_stims, 20, true)

instructions_grid = '
'
for (var c = 0; c < colors.length / 2; c++) {
  for (var s = 0; s < stims.length / 2; s++) {
    for (var o = 0; o < orientations.length; o++) {
      instructions_grid +=
        '
<img class = gridImage src = ' + path_source + stims[s] +
        orientations[o] + '.bmp '
      instructions_grid +=
        '<img class = gridBorder src = ' + path_source + colors[c] + '_border.png
'
    }
  }
}
instructions_grid += '
'

/* ************************************ */
/* Set up jsPsych blocks */
/* ************************************ */
// Set up attention check node
var attention_check_block = {
  type: 'attention-check',
  data: {
    trial_id: "attention_check"
  },
  timing_response: 180000,
  response_ends_trial: true,
  timing_post_trial: 200
}

var attention_node = {
  timeline: [attention_check_block],
  conditional_function: function() {
    return run_attention_checks
  }
}

/* define static blocks */
var feedback_instruct_text =
  'Welcome to the experiment. Press enter to begin.'
var feedback_instruct_block = {
  type: 'poldrack-text',
  cont_key: [13],
  data: {
    trial_id: "instruction"
  },
  text: getInstructFeedback,
  timing_post_trial: 0,
  timing_response: 180000
};
/// This ensures that the subject does not read through the instructions too quickly.  If they do it too quickly, then we will go over the loop again.
var instruction_trials = []
var instructions_block = {
  type: 'poldrack-instructions',
  data: {
    trial_id: "instruction"
  },
  pages: [
    '

In this experiment stimuli will come up one at a time. You should respond to them by pressing the J, K or L keys, after which you will receive feedback about whether you were right or not. If you were correct you will get points which contribute to your bonus payment.

Your job is to get as many trials correct as possible! On the next page are the stimuli you will be responding to.

',
    instructions_grid,
    '

Make sure you are familiar with the stimuli on the last page. Remember, respond to the stimuli by pressing J, K, or L. You will get a bonus based on your performance so try your best!

The experiment will start right after you end the instructions.

'
  ],
  allow_keys: false,
  show_clickable_nav: true
};
instruction_trials.push(feedback_instruct_block)
instruction_trials.push(instructions_block)

var instruction_node = {
  timeline: instruction_trials,
  /* This function defines stopping criteria */
  loop_function: function(data) {
    for (i = 0; i < data.length; i++) {
      if ((data[i].trial_type == 'poldrack-instructions') && (data[i].rt != -1)) {
        rt = data[i].rt
        sumInstructTime = sumInstructTime + rt
      }
    }
    if (sumInstructTime <= instructTimeThresh * 1000) {
      feedback_instruct_text =
        'Read through instructions too quickly.  Please take your time and make sure you understand the instructions.  Press enter to continue.'
      return true
    } else if (sumInstructTime > instructTimeThresh * 1000) {
      feedback_instruct_text =
        'Done with instructions. Press enter to continue.'
      return false
    }
  }
}

var end_block = {
  type: 'poldrack-text',
  timing_response: 180000,
  data: {
    trial_id: "end"
  },
  text: '

Thanks for completing this task!

Press enter to begin.

',
  cont_key: [13],
  timing_post_trial: 0
};

var start_test_block = {
  type: 'poldrack-text',
  data: {
    trial_id: "test_intro"
  },
  timing_response: 180000,
  text: '

We will now start the test.

Press enter to begin.

',
  cont_key: [13],
  timing_post_trial: 1000
};

var fixation_block = {
  type: 'poldrack-single-stim',
  stimulus: prompt_prefix + path_source + 'FIX.png' + ' style:"z-index: -1"' + postfix,
  is_html: true,
  choices: 'none',
  data: {
    trial_id: "fixation",
    exp_stage: "test"
  },
  response_ends_trial: false,
  timing_post_trial: 0,
  timing_stim: -1,
  timing_response: getFixLength
}

var feedback_block = {
  type: 'poldrack-single-stim',
  stimulus: getFeedback,
  is_html: true,
  choices: 'none',
  data: {
    trial_id: "feedback",
    exp_stage: "test"
  },
  response_ends_trial: false,
  timing_post_trial: 0,
  timing_stim: 1000,
  timing_response: 1000
}

var flat_stim_block = {
  type: 'poldrack-single-stim',
  stimulus: getFlatStim,
  data: getFlatData,
  is_html: true,
  choices: choices,
  response_ends_trial: false,
  timing_stim: 1000,
  timing_response: 3000,
  prompt: prompt_prefix + path_source + 'FIX_GREEN.png' + ' style:"z-index: -1"' + postfix,
  timing_post_trial: 0,
  on_finish: function() {
    jsPsych.data.addDataToLastTrial({
      trial_id: "flat_stim",
      exp_stage: "test"
    })
  }
}

var hierarchical_stim_block = {
  type: 'poldrack-single-stim',
  stimulus: getHierarchicalStim,
  data: getHierarchicalData,
  is_html: true,
  choices: choices,
  response_ends_trial: false,
  timing_stim: 1000,
  timing_response: 3000,
  prompt: prompt_prefix + path_source + 'FIX_GREEN.png' + ' style:"z-index: -1"' + postfix,
  timing_post_trial: 0,
  on_finish: function() {
    jsPsych.data.addDataToLastTrial({
      trial_id: "hierarchical_stim",
      exp_stage: "test"
    })
  }
}

// loop nodes instead of creating a huge array with three blocks for all trials
var flat_loop_node = {
  timeline: [fixation_block, flat_stim_block, feedback_block],
  loop_function: function(data) {
    if (flat_stims.stimulus.length > 0) {
      return true;
    } else {
      return false;
    }
  }
}

var hierarchical_loop_node = {
  timeline: [fixation_block, hierarchical_stim_block, feedback_block],
  loop_function: function(data) {
    if (hierarchical_stims.stimulus.length > 0) {
      return true;
    } else {
      return false;
    }
  }
}

//Set up experiment
var hierarchical_rule_experiment = []
hierarchical_rule_experiment.push(instruction_node);
hierarchical_rule_experiment.push(start_test_block);
// setup exp w loop nodes after pushing the practice etc. blocks
if (hierarchical_only) {
  hierarchical_rule_experiment.push(hierarchical_loop_node, attention_node);
} else {
  if (flat_first == 1) {
    hierarchical_rule_experiment.push(flat_loop_node, attention_node, start_test_block,
      hierarchical_loop_node, attention_node);
  } else {
    hierarchical_rule_experiment.push(hierarchical_loop_node, attention_node, start_test_block,
      flat_loop_node, attention_node);
  }
}

hierarchical_rule_experiment.push(end_block)<|endoftext|>


<commit_before>// Expose Raven to the world
window.Raven = Raven;

// AMD
if (typeof define === 'function' && define.amd) {
    define('raven', [], function() { return Raven; });
}

})(window);
<commit_msg>this instead of window<commit_after>// Expose Raven to the world
window.Raven = Raven;

// AMD
if (typeof define === 'function' && define.amd) {
    define('raven', [], function() { return Raven; });
}

})(this);
<|endoftext|>


<commit_before>import 'leaflet.heightgraph';
import $ from 'jquery';
import L from 'leaflet';

import css from './heightgraph.scss';
import commonUtils from '../../common/utils';
import commonFormat from '../../common/format';

export default class FmHeightgraph extends L.Control.Heightgraph {
	constructor(options) {
		super(Object.assign({
			margins: {
				top: 20,
				right: 10,
				bottom: 45,
				left: 50
			},
			mappings: {
				"": {
					"": { text: 'unknown', color: '#4682B4' }
				},
				steepness: {
					'-5': { text: '16%+', color: '#028306' },
					'-4': { text: '10-15%', color: '#2AA12E' },
					'-3': { text: '7-9%', color: '#53BF56' },
					'-2': { text: '4-6%', color: '#7BDD7E' },
					'-1': { text: '1-3%', color: '#A4FBA6' },
					'0': { text: '0%', color: '#ffcc99' },
					'1': { text: '1-3%', color: '#F29898' },
					'2': { text: '4-6%', color: '#E07575' },
					'3': { text: '7-9%', color: '#CF5352' },
					'4': { text: '10-15%', color: '#BE312F' },
					'5': { text: '16%+', color: '#AD0F0C' }
				},
				waytypes: {
					'0': { text: 'Other', color: '#30959e' },
					'1': { text: 'StateRoad', color: '#3f9da6' },
					'2': { text: 'Road', color: '#4ea5ae' },
					'3': { text: 'Street', color: '#5baeb5' },
					'4': { text: 'Path', color: '#67b5bd' },
					'5': { text: 'Track', color: '#73bdc4' },
					'6': { text: 'Cycleway', color: '#7fc7cd' },
					'7': { text: 'Footway', color: '#8acfd5' },
					'8': { text: 'Steps', color: '#96d7dc' },
					'9': { text: 'Ferry', color: '#a2dfe5' },
					'10': { text: 'Construction', color: '#ade8ed' }
				},
				surface: {
					'0': { text: 'Other', color: '#ddcdeb' },
					'1': { text: 'Paved', color: '#cdb8df' },
					'2': { text: 'Unpaved', color: '#d2c0e3' },
					'3': { text: 'Asphalt', color: '#bca4d3' },
					'4': { text: 'Concrete', color: '#c1abd7' },
					'5': { text: 'Cobblestone', color: '#c7b2db' },
					'6': { text: 'Metal', color: '#e8dcf3' },
					'7': { text: 'Wood', color: '#eee3f7' },
					'8': { text: 'Compacted Gravel', color: '#d8c6e7' },
					'9': { text: 'Fine Gravel', color: '#8f9de4' },
					'10': { text: 'Gravel', color: '#e3d4ef' },
					'11': { text: 'Dirt', color: '#99a6e7' },
					'12': { text: 'Ground', color: '#a3aeeb' },
					'13': { text: 'Ice', color: '#acb6ee' },
					'14': { text: 'Salt', color: '#b6c0f2' },
					'15': { text: 'Sand', color: '#c9d1f8' },
					'16': { text: 'Woodchips', color: '#c0c8f5' },
					'17': { text: 'Grass', color: '#d2dafc' },
					'18': { text: 'Grass Paver', color: '#dbe3ff' }
				},
				tollways: {
					0: { text: "No tollway", color: "#6ca97b" },
					1: { text: "Tollway", color: "#ffb347" }
				}
			}
		}, options));

		for (const i in this.options.mappings) {
			for (const j in this.options.mappings[i]) {
				this.options.mappings[i][j].originalText = this.options.mappings[i][j].text;
			}
		}
	}

	onAdd(map) {
		// Work around double margins (https://github.com/GIScience/Leaflet.Heightgraph/issues/33)
		let sizeBkp = { width: this.options.width, height: this.options.height };
		this.options.width = sizeBkp.width + this.options.margins.left + this.options.margins.right;
		this.options.height = sizeBkp.height + this.options.margins.top + this.options.margins.bottom;

		let el = $("svg", super.onAdd(map));

		Object.assign(this.options, sizeBkp);

		if(this._data)
			super.addData(this._data);

		el.addClass(css.className);

		return el[0];
	}

	addData(extraInfo, trackPoints) {
		let data = FmHeightgraph.createGeoJsonForHeightGraph(extraInfo, trackPoints);

		for (const featureCollection of data) {
			for (const i in featureCollection.properties.distances) {
				const mapping = this.options.mappings[featureCollection.properties.summary] && this.options.mappings[featureCollection.properties.summary][i];
				if (mapping)
					mapping.text = mapping.originalText + " (" + commonFormat.round(featureCollection.properties.distances[i], 2) + " km)";
			}
		}

		if(this._container)
			super.addData(data);
		else
			this._data = data;
	}

	_appendScales() {
		super._appendScales();

		//this._xAxis.ticks(3);
	}

	static trackSegment(trackPoints, fromIdx, toIdx) {
		let ret = [];

		for(let i=fromIdx; i<trackPoints.length; i++) {
			if(trackPoints[i] && trackPoints[i].ele != null) {
				ret.push(trackPoints[i]);

				if(i >= toIdx) // Makes sure that if toIdx does not exist in trackPoints, the next trackPoint is added, which avoids gaps between the segments, as required by leaflet.heightgraph
					break;
			}
		}

		return ret;
	}

	static createGeoJsonForHeightGraph(extraInfo, trackPoints) {
		let geojson = [];

		if(!extraInfo || Object.keys(extraInfo).length == 0)
			extraInfo = { "": [[ 0, trackPoints.length-1, "" ]] };

		for(let i in extraInfo) {
			let featureCollection = {
				type: "FeatureCollection",
				features: [],
				properties: {
					summary: i
				}
			};

			const distances = { };

			for(let segment in extraInfo[i]) {
				const segmentPosList = FmHeightgraph.trackSegment(trackPoints, extraInfo[i][segment][0], extraInfo[i][segment][1]);

				if (distances[extraInfo[i][segment][2]] == null)
					distances[extraInfo[i][segment][2]] = 0;
				distances[extraInfo[i][segment][2]] += commonUtils.calculateDistance(segmentPosList);

				featureCollection.features.push({
					type: "Feature",
					geometry: {
						type: "LineString",
						coordinates: segmentPosList.map((trackPoint) => ([trackPoint.lon, trackPoint.lat, trackPoint.ele]))
					},
					properties: {
						attributeType: extraInfo[i][segment][2]
					}
				});
			}

			featureCollection.properties.distances = distances;

			geojson.push(featureCollection);
		}
		return geojson;
	}
}<commit_msg>Add more labels to heightgraph in case server returns more than requested<commit_after>import 'leaflet.heightgraph';
import $ from 'jquery';
import L from 'leaflet';

import css from './heightgraph.scss';
import commonUtils from '../../common/utils';
import commonFormat from '../../common/format';

export default class FmHeightgraph extends L.Control.Heightgraph {
	constructor(options) {
		super(Object.assign({
			margins: {
				top: 20,
				right: 10,
				bottom: 45,
				left: 50
			},
			mappings: {
				"": {
					"": { text: 'unknown', color: '#4682B4' }
				},
				steepness: {
					"-5": { text: "16%+", color: "#028306" },
					"-4": { text: "10-15%", color: "#2AA12E" },
					"-3": { text: "7-9%", color: "#53BF56" },
					"-2": { text: "4-6%", color: "#7BDD7E" },
					"-1": { text: "1-3%", color: "#A4FBA6" },
					"0": { text: "0%", color: "#ffcc99" },
					"1": { text: "1-3%", color: "#F29898" },
					"2": { text: "4-6%", color: "#E07575" },
					"3": { text: "7-9%", color: "#CF5352" },
					"4": { text: "10-15%", color: "#BE312F" },
					"5": { text: "16%+", color: "#AD0F0C" }
				},
				waytypes: {
					"0": { text: "Other", color: "#30959e" },
					"1": { text: "StateRoad", color: "#3f9da6" },
					"2": { text: "Road", color: "#4ea5ae" },
					"3": { text: "Street", color: "#5baeb5" },
					"4": { text: "Path", color: "#67b5bd" },
					"5": { text: "Track", color: "#73bdc4" },
					"6": { text: "Cycleway", color: "#7fc7cd" },
					"7": { text: "Footway", color: "#8acfd5" },
					"8": { text: "Steps", color: "#96d7dc" },
					"9": { text: "Ferry", color: "#a2dfe5" },
					"10": { text: "Construction", color: "#ade8ed" }
				},
				surface: {
					"0": { text: "Other", color: "#ddcdeb" },
					"1": { text: "Paved", color: "#cdb8df" },
					"2": { text: "Unpaved", color: "#d2c0e3" },
					"3": { text: "Asphalt", color: "#bca4d3" },
					"4": { text: "Concrete", color: "#c1abd7" },
					"5": { text: "Cobblestone", color: "#c7b2db" },
					"6": { text: "Metal", color: "#e8dcf3" },
					"7": { text: "Wood", color: "#eee3f7" },
					"8": { text: "Compacted Gravel", color: "#d8c6e7" },
					"9": { text: "Fine Gravel", color: "#8f9de4" },
					"10": { text: "Gravel", color: "#e3d4ef" },
					"11": { text: "Dirt", color: "#99a6e7" },
					"12": { text: "Ground", color: "#a3aeeb" },
					"13": { text: "Ice", color: "#acb6ee" },
					"14": { text: "Paving Stones", color: "#b6c0f2" },
					"15": { text: "Sand", color: "#c9d1f8" },
					"16": { text: "Woodchips", color: "#c0c8f5" },
					"17": { text: "Grass", color: "#d2dafc" },
					"18": { text: "Grass Paver", color: "#dbe3ff" }
				},
				suitability: {
					"3": { text: "3/10", color: "#3D3D3D" },
					"4": { text: "4/10", color: "#4D4D4D" },
					"5": { text: "5/10", color: "#5D5D5D" },
					"6": { text: "6/10", color: "#6D6D6D" },
					"7": { text: "7/10", color: "#7C7C7C" },
					"8": { text: "8/10", color: "#8D8D8D" },
					"9": { text: "9/10", color: "#9D9D9D" },
					"10": { text: "10/10", color: "#ADADAD" }
				},
				green: {
					"3": { text: "10/10", color: "#8ec639" },
					"4": { text: "9/10", color: "#99c93c" },
					"5": { text: "8/10", color: "#a4cc40" },
					"6": { text: "7/10", color: "#afcf43" },
					"7": { text: "6/10", color: "#bbd246" },
					"8": { text: "5/10", color: "#c6d54a" },
					"9": { text: "4/10", color: "#d1d84e" },
					"10": { text: "3/10", color: "#dcdc51" }
				},
				noise: {
					"7": { text: "7/10", color: "#F8A056" },
					"8": { text: "8/10", color: "#EA7F27" },
					"9": { text: "9/10", color: "#A04900" },
					"10": { text: "10/10", color: "#773600" }
				},
				tollways: {
					"0": { text: "LOCALE_NO_TOLLWAY", color: "#6ca97b" },
					"1": { text: "LOCALE_TOLLWAY", color: "#ffb347" }
				},
				avgspeed: {
					"3": { text: "3 km/h", color: "#f2fdff" },
					"4": { text: "4 km/h", color: "#D8FAFF" },
					"5": { text: "5 km/h", color: "bff7ff" },
					"6": { text: "6-8 km/h", color: "#f2f7ff" },
					"9": { text: "9-12 km/h", color: "#d8e9ff" },
					"13": { text: "13-16 km/h", color: "#bedaff" },
					"17": { text: "17-20 km/h", color: "#a5cbff" },
					"21": { text: "21-24 km/h", color: "#8cbcff" },
					"25": { text: "25-29 km/h", color: "#72aeff" },
					"30": { text: "30-34 km/h", color: "#599fff" },
					"35": { text: "35-39 km/h", color: "#3f91ff" },
					"40": { text: "40-44 km/h", color: "#2682ff" },
					"45": { text: "45-49 km/h", color: "#0d73ff" },
					"50": { text: "50-59 km/h", color: "#0067f2" },
					"60": { text: "60-69 km/h", color: "#005cd9" },
					"70": { text: "70-79 km/h", color: "#0051c0" },
					"80": { text: "80-99 km/h", color: "#0046a6" },
					"100": { text: "100-119 km/h", color: "#003c8d" },
					"120": { text: "+120 km/h", color: "#003174" }
				},
				traildifficulty: {
					"0": { text: "Missing SAC tag", color: "#dfecec" },
					"1": { text: "S0", color: "#9fc6c6" },
					"2": { text: "S1", color: "#80b3b3" },
					"3": { text: "S2", color: "#609f9f" },
					"4": { text: "S3", color: "#4d8080" },
					"5": { text: "S4", color: "#396060" },
					"6": { text: "S5", color: "#264040" },
					"7": { text: ">S5", color: "#132020" }
				},
				roadaccessrestrictions: {
					"0": { text: "None (there are no restrictions)", color: "#fe7f6c" },
					"1": { text: "No", color: "#FE7F9C" },
					"2": { text: "Customers", color: "#FDAB9F" },
					"4": { text: "Destination", color: "#FF66CC" },
					"8": { text: "Delivery", color: "#FDB9C8" },
					"16": { text: "Private", color: "#F64A8A" },
					"32": { text: "Permissive", color: "#E0115F" }
				}
			}
		}, options));

		for (const i in this.options.mappings) {
			for (const j in this.options.mappings[i]) {
				this.options.mappings[i][j].originalText = this.options.mappings[i][j].text;
			}
		}
	}

	onAdd(map) {
		// Work around double margins (https://github.com/GIScience/Leaflet.Heightgraph/issues/33)
		let sizeBkp = { width: this.options.width, height: this.options.height };
		this.options.width = sizeBkp.width + this.options.margins.left + this.options.margins.right;
		this.options.height = sizeBkp.height + this.options.margins.top + this.options.margins.bottom;

		let el = $("svg", super.onAdd(map));

		Object.assign(this.options, sizeBkp);

		if(this._data)
			super.addData(this._data);

		el.addClass(css.className);

		return el[0];
	}

	addData(extraInfo, trackPoints) {
		let data = FmHeightgraph.createGeoJsonForHeightGraph(extraInfo, trackPoints);

		for (const featureCollection of data) {
			for (const i in featureCollection.properties.distances) {
				const mapping = this.options.mappings[featureCollection.properties.summary] && this.options.mappings[featureCollection.properties.summary][i];
				if (mapping)
					mapping.text = mapping.originalText + " (" + commonFormat.round(featureCollection.properties.distances[i], 2) + " km)";
			}
		}

		if(this._container)
			super.addData(data);
		else
			this._data = data;
	}

	_appendScales() {
		super._appendScales();

		//this._xAxis.ticks(3);
	}

	static trackSegment(trackPoints, fromIdx, toIdx) {
		let ret = [];

		for(let i=fromIdx; i<trackPoints.length; i++) {
			if(trackPoints[i] && trackPoints[i].ele != null) {
				ret.push(trackPoints[i]);

				if(i >= toIdx) // Makes sure that if toIdx does not exist in trackPoints, the next trackPoint is added, which avoids gaps between the segments, as required by leaflet.heightgraph
					break;
			}
		}

		return ret;
	}

	static createGeoJsonForHeightGraph(extraInfo, trackPoints) {
		let geojson = [];

		if(!extraInfo || Object.keys(extraInfo).length == 0)
			extraInfo = { "": [[ 0, trackPoints.length-1, "" ]] };

		for(let i in extraInfo) {
			let featureCollection = {
				type: "FeatureCollection",
				features: [],
				properties: {
					summary: i
				}
			};

			const distances = { };

			for(let segment in extraInfo[i]) {
				const segmentPosList = FmHeightgraph.trackSegment(trackPoints, extraInfo[i][segment][0], extraInfo[i][segment][1]);

				if (distances[extraInfo[i][segment][2]] == null)
					distances[extraInfo[i][segment][2]] = 0;
				distances[extraInfo[i][segment][2]] += commonUtils.calculateDistance(segmentPosList);

				featureCollection.features.push({
					type: "Feature",
					geometry: {
						type: "LineString",
						coordinates: segmentPosList.map((trackPoint) => ([trackPoint.lon, trackPoint.lat, trackPoint.ele]))
					},
					properties: {
						attributeType: extraInfo[i][segment][2]
					}
				});
			}

			featureCollection.properties.distances = distances;

			geojson.push(featureCollection);
		}
		return geojson;
	}
}<|endoftext|>


<commit_before>// Welcome!
// Add your github user if you accepted the challenge!

var players = [
    'raphamorim',
    'israelst',
    'afonsopacifer',
    'rafaelfragosom',
    'brunokinoshita',
    'paulinhoerry',
    'enieber',
    'alanrsoares',
    'viniciusdacal',
    'thiagosantana',
    'brunodsgn',
    'danilorb',
    'douglasPinheiro',
    'michelwilhelm',
    'joaovsilva',
    'rafaelstz',
    'andersonweb',
    'luhad',
    'pablobfonseca',
    'willianjusten',
    'vitorleal',
    'IAMFELIPEMATTOS',
    'JulianSansat',
    'brenopolanski',
    'Pompeu',
    'filipedeschamps',
    'felipesousa',
    'gpedro',
    'leaofelipe',
    'wedneyyuri',
    'jonathanveg',
    'filipe1309',
    'afgoulart',
    'helquisson',
    'vulcanobr',
    'guilouro',
    'pedropolisenso',
    'alfv89',
    'jugoncalves'
];

module.exports = players;
<commit_msg>Added my name<commit_after>// Welcome!
// Add your github user if you accepted the challenge!

var players = [
    'raphamorim',
    'israelst',
    'afonsopacifer',
    'rafaelfragosom',
    'brunokinoshita',
    'paulinhoerry',
    'enieber',
    'alanrsoares',
    'viniciusdacal',
    'thiagosantana',
    'brunodsgn',
    'danilorb',
    'douglasPinheiro',
    'michelwilhelm',
    'joaovsilva',
    'rafaelstz',
    'andersonweb',
    'luhad',
    'pablobfonseca',
    'willianjusten',
    'vitorleal',
    'IAMFELIPEMATTOS',
    'JulianSansat',
    'brenopolanski',
    'Pompeu',
    'filipedeschamps',
    'felipesousa',
    'gpedro',
    'leaofelipe',
    'wedneyyuri',
    'jonathanveg',
    'filipe1309',
    'afgoulart',
    'helquisson',
    'vulcanobr',
    'guilouro',
    'pedropolisenso',
    'alfv89',
    'jugoncalves',
    'guilhermeepaixaoo'
];

module.exports = players;
<|endoftext|>


<commit_before>var internalMembers = ["code", "error", "status", "duration", "failed", "total", "message"];
var fs = require("fs");
var print = require("internal").print;

function resultsToXml(results, baseName) {
  "use strict";
  function xmlEscape(s) {
    return s.replace(/[<>&"]/g, function (c) {
      return "&"
        + { "<": "lt", ">": "gt", "&": "amp", "\"": "quot" }[c]
        + ";";
    });
  }

  for (var testrun in results) {

    for (var test in  results[testrun]) {
      var xml = [ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ];

      xml.text = function (s) {
        Array.prototype.push.call(this, s);
        return this;
      };

      xml.elem = function (tagName, attrs, close) {
        this.text("<").text(tagName);

        for (var a in attrs || {}) {
          this.text(" ").text(a).text("=\"")
            .text(xmlEscape(String(attrs[a]))).text("\"");
        }

        close && this.text("/");
        this.text(">\n");

        return this;
      };

      xml.elem("testsuite", {
        errors: 0,
        failures: results[testrun][test].failed,
        name: test,
        tests: results[testrun][test].total,
        time: results[testrun][test].duration
      });

      for (var oneTest in  results[testrun][test]) {
        if (internalMembers.indexOf(oneTest) === -1) {
          var result = results[testrun][test][oneTest].status;
          var success = (typeof(result) === 'boolean')? result : false;

          xml.elem("testcase", {
            name: oneTest,
            time: results[testrun][test][oneTest].duration
          }, success);

          if (!success) {
            xml.elem("failure");
            xml.text('<![CDATA[' + results[testrun][test][oneTest].message + ']]>\n');
            xml.elem("/failure");
            xml.elem("/testcase");
          }
        }
      }

      xml.elem("/testsuite");
      var fn = baseName + testrun.replace(/\//g, '_') + '_' + test.replace(/\//g, '_') + ".xml";
      //print('Writing: '+ fn);
      fs.write(fn, xml.join(""));

    }
  }
}

function main (argv) {
  if (argv.length < 2) {
    print("Usage: unittest TESTNAME [OPTIONS]");
    return;
  }
  var test = argv[1];
  var options = {};
  var r;
  if (argv.length >= 3) {
    options = JSON.parse(argv[2]);
  }
  options.jsonReply = true;
  var UnitTest = require("org/arangodb/testing");
  start_pretty_print();

  try {
    r = UnitTest.UnitTest(test,options);
  }
  catch (x) {
    print("Caught exception during test execution!");
    print(x.message);
    print(JSON.stringify(r));
  }
  fs.write("UNITTEST_RESULT.json",JSON.stringify(r));
  fs.write("UNITTEST_RESULT_SUMMARY.txt",JSON.stringify(r.all_ok));
  try {
    resultsToXml(r, "UNITTEST_RESULT_");
  }
  catch (x) {
    print("Exception while serializing status xml!");
    print(x.message);
    print(JSON.stringify(r));
  }

  UnitTest.unitTestPrettyPrintResults(r);
}
<commit_msg>If a whole test suite fails, output the global error message.<commit_after>var internalMembers = ["code", "error", "status", "duration", "failed", "total", "message"];
var fs = require("fs");
var print = require("internal").print;

function resultsToXml(results, baseName) {
  "use strict";
  function xmlEscape(s) {
    return s.replace(/[<>&"]/g, function (c) {
      return "&"
        + { "<": "lt", ">": "gt", "&": "amp", "\"": "quot" }[c]
        + ";";
    });
  }

  for (var testrun in results) {

    for (var test in  results[testrun]) {
      var xml = [ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" ];

      xml.text = function (s) {
        Array.prototype.push.call(this, s);
        return this;
      };

      xml.elem = function (tagName, attrs, close) {
        this.text("<").text(tagName);

        for (var a in attrs || {}) {
          this.text(" ").text(a).text("=\"")
            .text(xmlEscape(String(attrs[a]))).text("\"");
        }

        if (close) {
          this.text("/");
        }
        this.text(">\n");

        return this;
      };

      xml.elem("testsuite", {
        errors: 0,
        failures: results[testrun][test].failed,
        name: test,
        tests: results[testrun][test].total,
        time: results[testrun][test].duration
      });

      for (var oneTest in  results[testrun][test]) {
        if (internalMembers.indexOf(oneTest) === -1) {
          var result = results[testrun][test][oneTest].status;
          var success = (typeof(result) === 'boolean')? result : false;

          xml.elem("testcase", {
            name: oneTest,
            time: results[testrun][test][oneTest].duration
          }, success);

          if (!success) {
            xml.elem("failure");
            xml.text('<![CDATA[' + results[testrun][test][oneTest].message + ']]>\n');
            xml.elem("/failure");
            xml.elem("/testcase");
          }
        }
      }

      if ((!results[testrun][test].status)                 &&
          results[testrun][test].hasOwnProperty('message'))
      {
        xml.elem("failure");
        xml.text('<![CDATA[' + JSON.stringify(results[testrun][test].message) + ']]>\n');
        xml.elem("/failure");
      }
      xml.elem("/testsuite");
      var fn = baseName + testrun.replace(/\//g, '_') + '_' + test.replace(/\//g, '_') + ".xml";
      //print('Writing: '+ fn);
      fs.write(fn, xml.join(""));

    }
  }
}

function main (argv) {
  if (argv.length < 2) {
    print("Usage: unittest TESTNAME [OPTIONS]");
    return;
  }
  var test = argv[1];
  var options = {};
  var r;
  if (argv.length >= 3) {
    options = JSON.parse(argv[2]);
  }
  options.jsonReply = true;
  var UnitTest = require("org/arangodb/testing");
  start_pretty_print();

  try {
    r = UnitTest.UnitTest(test,options);
  }
  catch (x) {
    print("Caught exception during test execution!");
    print(x.message);
    print(JSON.stringify(r));
  }
  fs.write("UNITTEST_RESULT.json",JSON.stringify(r));
  fs.write("UNITTEST_RESULT_SUMMARY.txt",JSON.stringify(r.all_ok));
  try {
    resultsToXml(r, "UNITTEST_RESULT_");
  }
  catch (x) {
    print("Exception while serializing status xml!");
    print(x.message);
    print(JSON.stringify(r));
  }

  UnitTest.unitTestPrettyPrintResults(r);
}
<|endoftext|>


<commit_before>"use strict";

var Shim = require("./shim");
var GenericCollection = require("./generic-collection");
var GenericMap = require("./generic-map");
var PropertyChanges = require("./listen/property-changes");

// Burgled from https://github.com/domenic/dict

module.exports = Dict;
function Dict(values, getDefault) {
    if (!(this instanceof Dict)) {
        return new Dict(values, getDefault);
    }
    getDefault = getDefault || Function.noop;
    this.getDefault = getDefault;
    this.store = Object.create(null);
    this.length = 0;
    this.addEach(values);
}

Dict.Dict = Dict; // hack so require("dict").Dict will work in MontageJS.

Object.addEach(Dict.prototype, GenericCollection.prototype);
Object.addEach(Dict.prototype, GenericMap.prototype);
Object.addEach(Dict.prototype, PropertyChanges.prototype);

Dict.prototype.constructClone = function (values) {
    return new this.constructor(values, this.getDefault);
};

Dict.prototype.assertString = function (key) {
    if (typeof key !== "string") {
        throw new TypeError("key must be a string but Got " + key);
    }
}

Object.defineProperty(Dict.prototype,"$__proto__",{writable:true});
Object.defineProperty(Dict.prototype,"_hasProto",{
    get:function() {
        return this.hasOwnProperty("$__proto__") && typeof this._protoValue !== "undefined";
    }
});
Object.defineProperty(Dict.prototype,"_protoValue",{
    get:function() {
        return this["$__proto__"];
    },
    set: function(value) {
        this["$__proto__"] = value;
    }
});

Dict.prototype.get = function (key, defaultValue) {
    this.assertString(key);
    if (key === "__proto__") {
        if (this._hasProto) {
            return this._protoValue;
        } else if (arguments.length > 1) {
            return defaultValue;
        } else {
            return this.getDefault(key);
        }
    }
    else {
        if (key in this.store) {
            return this.store[key];
        } else if (arguments.length > 1) {
            return defaultValue;
        } else {
            return this.getDefault(key);
        }
    }
};

Dict.prototype.set = function (key, value) {
    this.assertString(key);
    if (key === "__proto__") {
        if (this._hasProto) { // update
            if (this.dispatchesMapChanges) {
                this.dispatchBeforeMapChange(key, this._protoValue);
            }
            this._protoValue = value;
            if (this.dispatchesMapChanges) {
                this.dispatchMapChange(key, value);
            }
            return false;
        } else { // create
            if (this.dispatchesMapChanges) {
                this.dispatchBeforeMapChange(key, undefined);
            }
            this.length++;
            this._protoValue = value;
            if (this.dispatchesMapChanges) {
                this.dispatchMapChange(key, value);
            }
            return true;
        }
    }
    else {
        if (key in this.store) { // update
            if (this.dispatchesMapChanges) {
                this.dispatchBeforeMapChange(key, this.store[key]);
            }
            this.store[key] = value;
            if (this.dispatchesMapChanges) {
                this.dispatchMapChange(key, value);
            }
            return false;
        } else { // create
            if (this.dispatchesMapChanges) {
                this.dispatchBeforeMapChange(key, undefined);
            }
            this.length++;
            this.store[key] = value;
            if (this.dispatchesMapChanges) {
                this.dispatchMapChange(key, value);
            }
            return true;
        }
    }
};

Dict.prototype.has = function (key) {
    this.assertString(key);
    return key === "__proto__" ? this._hasProto : key in this.store;
};

Dict.prototype["delete"] = function (key) {
    this.assertString(key);
    if (key === "__proto__") {
        if (this._hasProto) {
            if (this.dispatchesMapChanges) {
                this.dispatchBeforeMapChange(key, this._protoValue);
            }
            this._protoValue = undefined;
            this.length--;
            if (this.dispatchesMapChanges) {
                this.dispatchMapChange(key, undefined);
            }
            return true;
        }
        return false;
    }
    else {
        if (key in this.store) {
            if (this.dispatchesMapChanges) {
                this.dispatchBeforeMapChange(key, this.store[key]);
            }
            delete this.store[key];
            this.length--;
            if (this.dispatchesMapChanges) {
                this.dispatchMapChange(key, undefined);
            }
            return true;
        }
        return false;
    }
};

Dict.prototype.clear = function () {
    var key;
    if (this._hasProto) {
        if (this.dispatchesMapChanges) {
            this.dispatchBeforeMapChange("__proto__", this._protoValue);
        }
        this._protoValue = undefined;
        if (this.dispatchesMapChanges) {
            this.dispatchMapChange("__proto__", undefined);
        }
    }
    for (key in this.store) {
        if (this.dispatchesMapChanges) {
            this.dispatchBeforeMapChange(key, this.store[key]);
        }
        delete this.store[key];
        if (this.dispatchesMapChanges) {
            this.dispatchMapChange(key, undefined);
        }
    }
    this.length = 0;
};

Dict.prototype.reduce = function (callback, basis, thisp) {
    if(this._hasProto) {
        basis = callback.call(thisp, basis, "$__proto__", "__proto__", this);
    }
    var store = this.store;
    for (var key in this.store) {
        basis = callback.call(thisp, basis, store[key], key, this);
    }
    return basis;
};

Dict.prototype.reduceRight = function (callback, basis, thisp) {
    var self = this;
    var store = this.store;
    basis = Object.keys(this.store).reduceRight(function (basis, key) {
        return callback.call(thisp, basis, store[key], key, self);
    }, basis);

    if(this._hasProto) {
        return callback.call(thisp, basis, this._protoValue, "__proto__", self);
    }
    return basis;
};

Dict.prototype.one = function () {
    var key;
    for (key in this.store) {
        return this.store[key];
    }
    return this._protoValue;
};

Dict.prototype.toJSON = function () {
    return this.toObject();
};
<commit_msg>consolidated logic on set<commit_after>"use strict";

var Shim = require("./shim");
var GenericCollection = require("./generic-collection");
var GenericMap = require("./generic-map");
var PropertyChanges = require("./listen/property-changes");

// Burgled from https://github.com/domenic/dict

module.exports = Dict;
function Dict(values, getDefault) {
    if (!(this instanceof Dict)) {
        return new Dict(values, getDefault);
    }
    getDefault = getDefault || Function.noop;
    this.getDefault = getDefault;
    this.store = Object.create(null);
    this.length = 0;
    this.addEach(values);
}

Dict.Dict = Dict; // hack so require("dict").Dict will work in MontageJS.

Object.addEach(Dict.prototype, GenericCollection.prototype);
Object.addEach(Dict.prototype, GenericMap.prototype);
Object.addEach(Dict.prototype, PropertyChanges.prototype);

Dict.prototype.constructClone = function (values) {
    return new this.constructor(values, this.getDefault);
};

Dict.prototype.assertString = function (key) {
    if (typeof key !== "string") {
        throw new TypeError("key must be a string but Got " + key);
    }
}

Object.defineProperty(Dict.prototype,"$__proto__",{writable:true});
Object.defineProperty(Dict.prototype,"_hasProto",{
    get:function() {
        return this.hasOwnProperty("$__proto__") && typeof this._protoValue !== "undefined";
    }
});
Object.defineProperty(Dict.prototype,"_protoValue",{
    get:function() {
        return this["$__proto__"];
    },
    set: function(value) {
        this["$__proto__"] = value;
    }
});

Dict.prototype.get = function (key, defaultValue) {
    this.assertString(key);
    if (key === "__proto__") {
        if (this._hasProto) {
            return this._protoValue;
        } else if (arguments.length > 1) {
            return defaultValue;
        } else {
            return this.getDefault(key);
        }
    }
    else {
        if (key in this.store) {
            return this.store[key];
        } else if (arguments.length > 1) {
            return defaultValue;
        } else {
            return this.getDefault(key);
        }
    }
};

Dict.prototype.set = function (key, value) {
    this.assertString(key);
    var isProtoKey = (key === "__proto__");

    if (isProtoKey ? this._hasProto : key in this.store) { // update
        if (this.dispatchesMapChanges) {
            this.dispatchBeforeMapChange(key, isProtoKey ? this._protoValue : this.store[key]);
        }

        isProtoKey
            ? this._protoValue = value
            : this.store[key] = value;

        if (this.dispatchesMapChanges) {
            this.dispatchMapChange(key, value);
        }
        return false;
    } else { // create
        if (this.dispatchesMapChanges) {
            this.dispatchBeforeMapChange(key, undefined);
        }
        this.length++;

        isProtoKey
            ? this._protoValue = value
            : this.store[key] = value;

        if (this.dispatchesMapChanges) {
            this.dispatchMapChange(key, value);
        }
        return true;
    }
};

Dict.prototype.has = function (key) {
    this.assertString(key);
    return key === "__proto__" ? this._hasProto : key in this.store;
};

Dict.prototype["delete"] = function (key) {
    this.assertString(key);
    if (key === "__proto__") {
        if (this._hasProto) {
            if (this.dispatchesMapChanges) {
                this.dispatchBeforeMapChange(key, this._protoValue);
            }
            this._protoValue = undefined;
            this.length--;
            if (this.dispatchesMapChanges) {
                this.dispatchMapChange(key, undefined);
            }
            return true;
        }
        return false;
    }
    else {
        if (key in this.store) {
            if (this.dispatchesMapChanges) {
                this.dispatchBeforeMapChange(key, this.store[key]);
            }
            delete this.store[key];
            this.length--;
            if (this.dispatchesMapChanges) {
                this.dispatchMapChange(key, undefined);
            }
            return true;
        }
        return false;
    }
};

Dict.prototype.clear = function () {
    var key;
    if (this._hasProto) {
        if (this.dispatchesMapChanges) {
            this.dispatchBeforeMapChange("__proto__", this._protoValue);
        }
        this._protoValue = undefined;
        if (this.dispatchesMapChanges) {
            this.dispatchMapChange("__proto__", undefined);
        }
    }
    for (key in this.store) {
        if (this.dispatchesMapChanges) {
            this.dispatchBeforeMapChange(key, this.store[key]);
        }
        delete this.store[key];
        if (this.dispatchesMapChanges) {
            this.dispatchMapChange(key, undefined);
        }
    }
    this.length = 0;
};

Dict.prototype.reduce = function (callback, basis, thisp) {
    if(this._hasProto) {
        basis = callback.call(thisp, basis, "$__proto__", "__proto__", this);
    }
    var store = this.store;
    for (var key in this.store) {
        basis = callback.call(thisp, basis, store[key], key, this);
    }
    return basis;
};

Dict.prototype.reduceRight = function (callback, basis, thisp) {
    var self = this;
    var store = this.store;
    basis = Object.keys(this.store).reduceRight(function (basis, key) {
        return callback.call(thisp, basis, store[key], key, self);
    }, basis);

    if(this._hasProto) {
        return callback.call(thisp, basis, this._protoValue, "__proto__", self);
    }
    return basis;
};

Dict.prototype.one = function () {
    var key;
    for (key in this.store) {
        return this.store[key];
    }
    return this._protoValue;
};

Dict.prototype.toJSON = function () {
    return this.toObject();
};
<|endoftext|>


<commit_before>import fm from '../../app';
import $ from 'jquery';
import L from 'leaflet';
import ng from 'angular';

fm.app.factory("fmMapMarkers", function($uibModal, fmUtils, $compile, $timeout, $rootScope) {
	return function(map) {
		var markersById = { };
		let openMarker;

		map.client.on("marker", function(data) {
			if(map.client.filterFunc(data))
				markersUi._addMarker(data);
		});

		map.client.on("deleteMarker", function(data) {
			markersUi._deleteMarker(data);
		});

		map.client.on("filter", function() {
			for(var i in map.client.markers) {
				var show = map.client.filterFunc(map.client.markers[i]);
				if(markersById[i] && !show)
					markersUi._deleteMarker(map.client.markers[i]);
				else if(!markersById[i] && show)
					markersUi._addMarker(map.client.markers[i]);
			}
		});

		var markersUi = {
			_addMarker : function(marker) {
				if(!markersById[marker.id]) {
					markersById[marker.id] = L.marker([ 0, 0 ], { icon: fmUtils.createMarkerIcon(marker.colour, marker.size, marker.symbol)}).addTo(map.markerCluster)
						.on("click", function(e) {
							markersUi.showMarkerInfoBox(map.client.markers[marker.id] || marker);
						}.fmWrapApply($rootScope))
						.bindTooltip("", $.extend({}, map.tooltipOptions, { offset: [ 20, -15 ] }))
						.on("tooltipopen", function() {
							markersById[marker.id].setTooltipContent(fmUtils.quoteHtml(map.client.markers[marker.id].name));
						});
				}

				markersById[marker.id]
					.setLatLng([ marker.lat, marker.lon ])
					.setIcon(fmUtils.createMarkerIcon(marker.colour, marker.size, marker.symbol, null, openMarker && openMarker.id == marker.id));

				if(openMarker && openMarker.id == marker.id)
					markersUi.showMarkerInfoBox(marker);
			},
			_deleteMarker : function(marker) {
				if(!markersById[marker.id])
					return;

				if(openMarker && openMarker.id == marker.id) {
					openMarker.hide();
					openMarker = null;
				}

				markersById[marker.id].removeFrom(map.map);
				delete markersById[marker.id];
			},
			showMarkerInfoBox: function(marker) {
				var scope = $rootScope.$new();

				scope.map = map;
				scope.client = map.client;
				scope.marker = marker;

				scope.edit = function() {
					markersUi.editMarker(scope.marker);
				};

				scope.move = function() {
					markersUi.moveMarker(scope.marker);
				};

				scope['delete'] = function() {
					markersUi.deleteMarker(scope.marker);
				};

				scope.useForRoute = function(mode) {
					map.searchUi.setRouteDestination(`${marker.lat},${marker.lon}`, mode);
				};

				openMarker = {
					hide: map.infoBox.show(require("./view-marker.html"), scope, () => {
						openMarker = null;
						markersById[marker.id].remove();
						markersById[marker.id].options.pane = "markerPane";
						markersById[marker.id].setIcon(fmUtils.createMarkerIcon(marker.colour, marker.size, marker.symbol));
						markersById[marker.id].addTo(map.map);
					}).hide,
					id: marker.id
				};

				markersById[marker.id].remove();
				markersById[marker.id].options.pane = "fmHighlightMarkerPane";
				markersById[marker.id].setIcon(fmUtils.createMarkerIcon(marker.colour, marker.size, marker.symbol, null, true));
				markersById[marker.id].addTo(map.map);
			},
			editMarker: function(marker) {
				var scope = $rootScope.$new();
				scope.client = map.client;

				var dialog = $uibModal.open({
					template: require("./edit-marker.html"),
					scope: scope,
					controller: "fmMapMarkerEditCtrl",
					size: "lg",
					resolve: {
						map: function() { return map; }
					}
				});

				var preserve = fmUtils.preserveObject(scope, "client.markers["+fmUtils.quoteJavaScript(marker.id)+"]", "marker", function() {
					dialog.dismiss();
				});

				dialog.result.then(preserve.leave.bind(preserve), preserve.revert.bind(preserve));
			},
			moveMarker: function(marker) {
				if(!markersById[marker.id])
					return;

				function _finish(save) {
					message.close();

					markersById[marker.id].dragging.disable();

					if(save) {
						var pos = markersById[marker.id].getLatLng();
						map.client.editMarker({ id: marker.id, lat: pos.lat, lon: pos.lng }).then(function(marker) {
							markersUi.showMarkerInfoBox(marker);
						}).catch(function(err) {
							map.messages.showMessage("danger", err);

							markersUi._addMarker(map.client.markers[marker.id]);
						});
					} else {
						markersUi._addMarker(map.client.markers[marker.id]);
					}
				}

				var message = map.messages.showMessage("info", "Drag the marker to reposition it.", [
					{ label: "Save", click: _finish.bind(null, true) },
					{ label: "Cancel", click: _finish}
				], null, _finish);

				markersById[marker.id].dragging.enable();
			},
			deleteMarker: function(marker) {
				map.client.deleteMarker(marker).catch(function(err) {
					map.messages.showMessage("danger", err);
				});
			},
			addMarker: function(type) {
				var message = map.messages.showMessage("info", "Please click on the map to add a marker.", [
					{ label: "Cancel", click: function() {
						message.close();
						listener.cancel();
					}}
				], null, function() { listener.cancel(); });

				var listener = map.addClickListener(function(pos) {
					message.close();

					markersUi.createMarker(pos, type);
				});
			},
			createMarker: function(pos, type, properties, noEdit) {
				return map.client.addMarker($.extend({ lon: pos.lon, lat: pos.lat, typeId: type.id }, properties)).then(function(marker) {
					markersUi._addMarker(marker);

					if(!noEdit) {
						markersUi.showMarkerInfoBox(marker);
						markersUi.editMarker(marker);
					}
				}).catch(function(err) {
					map.messages.showMessage("danger", err);
				});
			}
		};

		return markersUi;
	};
});

fm.app.controller("fmMapMarkerEditCtrl", function($scope, map) {
	$scope.canControl = function(what) {
		return map.typesUi.canControl($scope.client.types[$scope.marker.typeId], what);
	};

	$scope.save = function() {
		$scope.error = null;
		map.client.editMarker($scope.marker).then(function() {
			$scope.$close();
		}).catch(function(err) {
			$scope.error = err;
		});
	};

	$scope.$watchGroup([ "marker.colour", "marker.size", "marker.symbol" ], function() {
		map.markersUi._addMarker($scope.marker);
	});

});
<commit_msg>Fix broken infobox after removing marker<commit_after>import fm from '../../app';
import $ from 'jquery';
import L from 'leaflet';
import ng from 'angular';

fm.app.factory("fmMapMarkers", function($uibModal, fmUtils, $compile, $timeout, $rootScope) {
	return function(map) {
		var markersById = { };
		let openMarker;

		map.client.on("marker", function(data) {
			if(map.client.filterFunc(data))
				markersUi._addMarker(data);
		});

		map.client.on("deleteMarker", function(data) {
			markersUi._deleteMarker(data);
		});

		map.client.on("filter", function() {
			for(var i in map.client.markers) {
				var show = map.client.filterFunc(map.client.markers[i]);
				if(markersById[i] && !show)
					markersUi._deleteMarker(map.client.markers[i]);
				else if(!markersById[i] && show)
					markersUi._addMarker(map.client.markers[i]);
			}
		});

		var markersUi = {
			_addMarker : function(marker) {
				if(!markersById[marker.id]) {
					markersById[marker.id] = L.marker([ 0, 0 ], { icon: fmUtils.createMarkerIcon(marker.colour, marker.size, marker.symbol)}).addTo(map.markerCluster)
						.on("click", function(e) {
							markersUi.showMarkerInfoBox(map.client.markers[marker.id] || marker);
						}.fmWrapApply($rootScope))
						.bindTooltip("", $.extend({}, map.tooltipOptions, { offset: [ 20, -15 ] }))
						.on("tooltipopen", function() {
							markersById[marker.id].setTooltipContent(fmUtils.quoteHtml(map.client.markers[marker.id].name));
						});
				}

				markersById[marker.id]
					.setLatLng([ marker.lat, marker.lon ])
					.setIcon(fmUtils.createMarkerIcon(marker.colour, marker.size, marker.symbol, null, openMarker && openMarker.id == marker.id));

				if(openMarker && openMarker.id == marker.id)
					markersUi.showMarkerInfoBox(marker);
			},
			_deleteMarker : function(marker) {
				if(!markersById[marker.id])
					return;

				if(openMarker && openMarker.id == marker.id) {
					openMarker.hide();
					openMarker = null;
				}

				markersById[marker.id].removeFrom(map.map);
				delete markersById[marker.id];
			},
			showMarkerInfoBox: function(marker) {
				var scope = $rootScope.$new();

				scope.map = map;
				scope.client = map.client;
				scope.marker = marker;

				scope.edit = function() {
					markersUi.editMarker(scope.marker);
				};

				scope.move = function() {
					markersUi.moveMarker(scope.marker);
				};

				scope['delete'] = function() {
					markersUi.deleteMarker(scope.marker);
				};

				scope.useForRoute = function(mode) {
					map.searchUi.setRouteDestination(`${marker.lat},${marker.lon}`, mode);
				};

				openMarker = {
					hide: map.infoBox.show(require("./view-marker.html"), scope, () => {
						openMarker = null;

						if(markersById[marker.id]) {
							markersById[marker.id].remove();
							markersById[marker.id].options.pane = "markerPane";
							markersById[marker.id].setIcon(fmUtils.createMarkerIcon(marker.colour, marker.size, marker.symbol));
							markersById[marker.id].addTo(map.map);
						}
					}).hide,
					id: marker.id
				};

				markersById[marker.id].remove();
				markersById[marker.id].options.pane = "fmHighlightMarkerPane";
				markersById[marker.id].setIcon(fmUtils.createMarkerIcon(marker.colour, marker.size, marker.symbol, null, true));
				markersById[marker.id].addTo(map.map);
			},
			editMarker: function(marker) {
				var scope = $rootScope.$new();
				scope.client = map.client;

				var dialog = $uibModal.open({
					template: require("./edit-marker.html"),
					scope: scope,
					controller: "fmMapMarkerEditCtrl",
					size: "lg",
					resolve: {
						map: function() { return map; }
					}
				});

				var preserve = fmUtils.preserveObject(scope, "client.markers["+fmUtils.quoteJavaScript(marker.id)+"]", "marker", function() {
					dialog.dismiss();
				});

				dialog.result.then(preserve.leave.bind(preserve), preserve.revert.bind(preserve));
			},
			moveMarker: function(marker) {
				if(!markersById[marker.id])
					return;

				function _finish(save) {
					message.close();

					markersById[marker.id].dragging.disable();

					if(save) {
						var pos = markersById[marker.id].getLatLng();
						map.client.editMarker({ id: marker.id, lat: pos.lat, lon: pos.lng }).then(function(marker) {
							markersUi.showMarkerInfoBox(marker);
						}).catch(function(err) {
							map.messages.showMessage("danger", err);

							markersUi._addMarker(map.client.markers[marker.id]);
						});
					} else {
						markersUi._addMarker(map.client.markers[marker.id]);
					}
				}

				var message = map.messages.showMessage("info", "Drag the marker to reposition it.", [
					{ label: "Save", click: _finish.bind(null, true) },
					{ label: "Cancel", click: _finish}
				], null, _finish);

				markersById[marker.id].dragging.enable();
			},
			deleteMarker: function(marker) {
				map.client.deleteMarker(marker).catch(function(err) {
					map.messages.showMessage("danger", err);
				});
			},
			addMarker: function(type) {
				var message = map.messages.showMessage("info", "Please click on the map to add a marker.", [
					{ label: "Cancel", click: function() {
						message.close();
						listener.cancel();
					}}
				], null, function() { listener.cancel(); });

				var listener = map.addClickListener(function(pos) {
					message.close();

					markersUi.createMarker(pos, type);
				});
			},
			createMarker: function(pos, type, properties, noEdit) {
				return map.client.addMarker($.extend({ lon: pos.lon, lat: pos.lat, typeId: type.id }, properties)).then(function(marker) {
					markersUi._addMarker(marker);

					if(!noEdit) {
						markersUi.showMarkerInfoBox(marker);
						markersUi.editMarker(marker);
					}
				}).catch(function(err) {
					map.messages.showMessage("danger", err);
				});
			}
		};

		return markersUi;
	};
});

fm.app.controller("fmMapMarkerEditCtrl", function($scope, map) {
	$scope.canControl = function(what) {
		return map.typesUi.canControl($scope.client.types[$scope.marker.typeId], what);
	};

	$scope.save = function() {
		$scope.error = null;
		map.client.editMarker($scope.marker).then(function() {
			$scope.$close();
		}).catch(function(err) {
			$scope.error = err;
		});
	};

	$scope.$watchGroup([ "marker.colour", "marker.size", "marker.symbol" ], function() {
		map.markersUi._addMarker($scope.marker);
	});

});
<|endoftext|>


<commit_before>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';
process.title = 'FireMon';
require('events').EventEmitter.prototype._maxListeners = 100;

let log = require("../net2/logger.js")(__filename, "info");

const sem = require('../sensor/SensorEventManager.js').getInstance();

var bone = require("../lib/Bone.js");
var config = JSON.parse(require('fs').readFileSync('../net2/config.json', 'utf8'));

const fs = require('fs');

log.info("================================================================================");
log.info("Monitor Starting:",config.version);
log.info("================================================================================");

// api/main/monitor all depends on sysManager configuration
let SysManager = require('../net2/SysManager.js');
let sysManager = new SysManager('info');

if(!bone.isAppConnected()) {
  log.info("Waiting for pairing from first app...");
}

// load feature toggle on/off from redis to memory
require('../net2/config.js').syncDynamicFeaturesConfigs()

run0();

function run0() {
  if (bone.cloudready()==true &&
      bone.isAppConnected() &&
   // this is to ensure sysManager is already initliazed when called in API code
      sysManager.isConfigInitialized()) {
    run();
  } else {
    log.forceInfo("Waiting for first app to connect...");
    setTimeout(()=>{
      sysManager.update(null);
      run0();
    },3000);
  }
}

process.on('uncaughtException',(err)=>{
    log.info("################### CRASH #############");
    log.info("+-+-+-",err.message,err.stack);
    if (err && err.message && err.message.includes("Redis connection")) {
        return;
    }
    bone.log("error",{version:config.version,type:'FIREWALLA.MON.exception',msg:err.message,stack:err.stack},null);
    setTimeout(()=>{
        try {
            require('child_process').execSync("touch /home/pi/.firewalla/managed_reboot")
        } catch(e) {
        }
        process.exit(1);
    },1000*2);
});

process.on('unhandledRejection', (reason, p)=>{
  let msg = "Possibly Unhandled Rejection at: Promise " + p + " reason: "+ reason;
  log.warn('###### Unhandled Rejection',msg,reason.stack,{});
  bone.log("error",{version:config.version,type:'FIREWALLA.MON.unhandledRejection',msg:msg,stack:reason.stack},null);
  // setTimeout(()=>{
  //   require('child_process').execSync("touch /home/pi/.firewalla/managed_reboot")
  //   process.exit(1);
  // },1000*2);
});

let heapSensor = null;

function gc() {
  try {
    if (global.gc) {
      global.gc();
    }
  } catch (err) {
  }
}

let status = {
  dlp: {
    running: false,
    runBy: ''
  },
  detect: {
    running: false,
    runBy: ''
  }
};

function setStatus(type, opts) {
  Object.assign(type, opts);
}

function updateTouchFile() {
  const monitorTouchFile = "/dev/shm/monitor.touch";

  fs.open(monitorTouchFile, 'w', (err, fd) => {
    if(!err) {
      fs.close(fd, (err2) => {

      })
    }
  })
}

function run() {
  const firewallaConfig = require('../net2/config.js').getConfig();
  sysManager.setConfig(firewallaConfig) // update sys config when start

  sysManager = null; // not needed any more after run()

  // listen on request to dump heap for this process, used for memory optmiziation
  // let HeapSensor = require('../sensor/HeapSensor');
  // heapSensor = new HeapSensor();
  // heapSensor.run();

  const tick = 60 * 15; // waking up every 15 min
  const monitorWindow = 60 * 60 * 4; // eight hours window

  const FlowMonitor = require('./FlowMonitor.js');
  const flowMonitor = new FlowMonitor(tick, monitorWindow, 'info');

  log.info("================================================================================");
  log.info("Monitor Running ");
  log.info("================================================================================");

  flowMonitor.run();

  setInterval(() => {
    const type = 'dlp';
    const _status = status[type];

    updateTouchFile();

    setTimeout(() => {
      if (_status.running && _status.runBy !== 'signal') {
        log.error("DLP Timeout", status);
        throw new Error("Monitor DLP Timeout");
      } else {
        log.info("Last DLP Ran Successful");
      }
    }, tick / 2 * 1000);

    if (_status.running) {
      log.warn('Already a dlp session running by signal trigger, skip this time', status);
      return;
    }

    setStatus(_status, {running: true, runBy: 'scheduler'});
    flowMonitor.run(type, tick, () => {
      log.info('Clean up after', type, 'run');
      setStatus(_status, {running: false, runBy: ''});
      gc();
    });
  }, tick * 1000);

  setInterval(() => {
    const type = 'detect';
    const _status = status[type];

    updateTouchFile();

    setTimeout(() => {
      if (_status.running && _status.runBy !== 'signal') {
        log.error("Last Detection Timeout", status);
        throw new Error("Monitor Detect Timeout");
      } else {
        log.info("Last Detect Ran Successful");
      }
    }, 55 * 1000);

    if (_status.running) {
      log.warn('Already a detect session running by signal trigger, skip this time', status);
      return;
    }

    setStatus(_status, {running: true, runBy: 'scheduler'});
    flowMonitor.run(type, 60, () => {
      log.info('Clean up after', type, 'run');
      setStatus(_status, {running: false, runBy: ''});
      gc();
    });
  }, 60 * 1000);

  process.on('SIGUSR1', () => {
    log.info('Received SIGUSR1. Trigger DLP check.');
    const type = 'dlp';
    const _status = status[type];

    if (_status.running) {
      log.warn("DLP check is already running, skip firing", status);
      return;
    }
    setStatus(_status, {running: true, runBy: 'signal'});
    flowMonitor.run(type, tick, () => {
      log.info('Clean up after', type, 'run');
      setStatus(_status, {running: false, runBy: ''});
      gc();
    });
  });

  process.on('SIGUSR2', () => {
    log.info('Received SIGUSR2. Trigger Detect check.');
    const type = 'detect';
    const _status = status[type];

    if (_status.running) {
      log.warn("Detect check is already running, skip firing", status);
      return;
    }
    setStatus(_status, {running: true, runBy: 'signal'});
    flowMonitor.run(type, 60, () => {
      log.info('Clean up after', type, 'run');
      setStatus(_status, {running: false, runBy: ''});
      gc();
    });
  });

}

sem.on("ChangeLogLevel", (event) => {
  if(event.name && event.level) {
    if(event.name === "*") {
      require('./LoggerManager.js').setGlobalLogLevel(event.level);
    } else {
      require('./LoggerManager.js').setLogLevel(event.name, event.level);
    }
  }
});
<commit_msg>bug fix<commit_after>/*    Copyright 2016 Firewalla LLC
 *
 *    This program is free software: you can redistribute it and/or  modify
 *    it under the terms of the GNU Affero General Public License, version 3,
 *    as published by the Free Software Foundation.
 *
 *    This program is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU Affero General Public License for more details.
 *
 *    You should have received a copy of the GNU Affero General Public License
 *    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';
process.title = 'FireMon';
require('events').EventEmitter.prototype._maxListeners = 100;

let log = require("../net2/logger.js")(__filename, "info");

const sem = require('../sensor/SensorEventManager.js').getInstance();

var bone = require("../lib/Bone.js");
var config = JSON.parse(require('fs').readFileSync('../net2/config.json', 'utf8'));

const fs = require('fs');

log.info("================================================================================");
log.info("Monitor Starting:",config.version);
log.info("================================================================================");

// api/main/monitor all depends on sysManager configuration
let SysManager = require('../net2/SysManager.js');
let sysManager = new SysManager('info');

if(!bone.isAppConnected()) {
  log.info("Waiting for pairing from first app...");
}

// load feature toggle on/off from redis to memory
require('../net2/config.js').syncDynamicFeaturesConfigs()

run0();

function run0() {
  if (bone.cloudready()==true &&
      bone.isAppConnected() &&
   // this is to ensure sysManager is already initliazed when called in API code
      sysManager.isConfigInitialized()) {
    run();
  } else {
    log.forceInfo("Waiting for first app to connect...");
    setTimeout(()=>{
      sysManager.update(null);
      run0();
    },3000);
  }
}

process.on('uncaughtException',(err)=>{
    log.info("################### CRASH #############");
    log.info("+-+-+-",err.message,err.stack);
    if (err && err.message && err.message.includes("Redis connection")) {
        return;
    }
    bone.log("error",{version:config.version,type:'FIREWALLA.MON.exception',msg:err.message,stack:err.stack},null);
    setTimeout(()=>{
        try {
            require('child_process').execSync("touch /home/pi/.firewalla/managed_reboot")
        } catch(e) {
        }
        process.exit(1);
    },1000*2);
});

process.on('unhandledRejection', (reason, p)=>{
  let msg = "Possibly Unhandled Rejection at: Promise " + p + " reason: "+ reason;
  log.warn('###### Unhandled Rejection',msg,reason.stack,{});
  bone.log("error",{version:config.version,type:'FIREWALLA.MON.unhandledRejection',msg:msg,stack:reason.stack},null);
  // setTimeout(()=>{
  //   require('child_process').execSync("touch /home/pi/.firewalla/managed_reboot")
  //   process.exit(1);
  // },1000*2);
});

let heapSensor = null;

function gc() {
  try {
    if (global.gc) {
      global.gc();
    }
  } catch (err) {
  }
}

let status = {
  dlp: {
    running: false,
    runBy: ''
  },
  detect: {
    running: false,
    runBy: ''
  }
};

function setStatus(type, opts) {
  Object.assign(type, opts);
}

function updateTouchFile() {
  const monitorTouchFile = "/dev/shm/monitor.touch";

  fs.open(monitorTouchFile, 'w', (err, fd) => {
    if(!err) {
      fs.close(fd, (err2) => {

      })
    }
  })
}

function run() {
  const firewallaConfig = require('../net2/config.js').getConfig();
  sysManager.setConfig(firewallaConfig) // update sys config when start

  sysManager = null; // not needed any more after run()

  // listen on request to dump heap for this process, used for memory optmiziation
  // let HeapSensor = require('../sensor/HeapSensor');
  // heapSensor = new HeapSensor();
  // heapSensor.run();

  const tick = 60 * 15; // waking up every 15 min
  const monitorWindow = 60 * 60 * 4; // eight hours window

  const FlowMonitor = require('./FlowMonitor.js');
  const flowMonitor = new FlowMonitor(tick, monitorWindow, 'info');

  log.info("================================================================================");
  log.info("Monitor Running ");
  log.info("================================================================================");

  flowMonitor.run();

  setInterval(() => {
    const type = 'dlp';
    const _status = status[type];

    updateTouchFile();

    setTimeout(() => {
      if (_status.running && _status.runBy !== 'signal') {
        log.error("DLP Timeout", status);
        throw new Error("Monitor DLP Timeout");
      } else {
        log.info("Last DLP Ran Successful");
      }
    }, tick / 2 * 1000);

    if (_status.running) {
      log.warn('Already a dlp session running by signal trigger, skip this time', status);
      return;
    }

    setStatus(_status, {running: true, runBy: 'scheduler'});
    flowMonitor.run(type, tick, () => {
      log.info('Clean up after', type, 'run');
      setStatus(_status, {running: false, runBy: ''});
      gc();
    });
  }, tick * 1000);

  setInterval(() => {
    const type = 'detect';
    const _status = status[type];

    updateTouchFile();

    setTimeout(() => {
      if (_status.running && _status.runBy !== 'signal') {
        log.error("Last Detection Timeout", status);
        throw new Error("Monitor Detect Timeout");
      } else {
        log.info("Last Detect Ran Successful");
      }
    }, 55 * 1000);

    if (_status.running) {
      log.warn('Already a detect session running by signal trigger, skip this time', status);
      return;
    }

    setStatus(_status, {running: true, runBy: 'scheduler'});
    flowMonitor.run(type, 60, () => {
      log.info('Clean up after', type, 'run');
      setStatus(_status, {running: false, runBy: ''});
      gc();
    });
  }, 60 * 1000);

  process.on('SIGUSR1', () => {
    log.info('Received SIGUSR1. Trigger DLP check.');
    const type = 'dlp';
    const _status = status[type];

    if (_status.running) {
      log.warn("DLP check is already running, skip firing", status);
      return;
    }
    setStatus(_status, {running: true, runBy: 'signal'});
    flowMonitor.run(type, tick, () => {
      log.info('Clean up after', type, 'run');
      setStatus(_status, {running: false, runBy: ''});
      gc();
    });
  });

  process.on('SIGUSR2', () => {
    log.info('Received SIGUSR2. Trigger Detect check.');
    const type = 'detect';
    const _status = status[type];

    if (_status.running) {
      log.warn("Detect check is already running, skip firing", status);
      return;
    }
    setStatus(_status, {running: true, runBy: 'signal'});
    flowMonitor.run(type, 60, () => {
      log.info('Clean up after', type, 'run');
      setStatus(_status, {running: false, runBy: ''});
      gc();
    });
  });

}

sem.on("ChangeLogLevel", (event) => {
  if(event.name && event.level) {
    if(event.name === "*") {
      require('../net2/LoggerManager.js').setGlobalLogLevel(event.level);
    } else {
      require('../net2/LoggerManager.js').setLogLevel(event.name, event.level);
    }
  }
});
<|endoftext|>


<commit_before>/**
 * Bootstrap Table Portuguese Portugal Translation
 * Author: Burnspirit<burnspirit@gmail.com>
 */
(function ($) {
    'use strict';

    $.fn.bootstrapTable.locales['pt-BR'] = {
        formatLoadingMessage: function () {
            return 'A carregar, aguarde...';
        },
        formatRecordsPerPage: function (pageNumber) {
            return pageNumber + ' registos por página';
        },
        formatShowingRows: function (pageFrom, pageTo, totalRows) {
            return 'A mostrar ' + pageFrom + ' até ' + pageTo + ' de ' + totalRows + ' linhas';
        },
        formatSearch: function () {
            return 'Pesquisa';
        },
        formatNoMatches: function () {
            return 'Nenhum registo encontrado';
        }
    };

    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pt-PT']);

})(jQuery);
<commit_msg>Update bootstrap-table-pt-PT.js<commit_after>/**
 * Bootstrap Table Portuguese Portugal Translation
 * Author: Burnspirit<burnspirit@gmail.com>
 */
(function ($) {
    'use strict';

    $.fn.bootstrapTable.locales['pt-PT'] = {
        formatLoadingMessage: function () {
            return 'A carregar, aguarde...';
        },
        formatRecordsPerPage: function (pageNumber) {
            return pageNumber + ' registos por página';
        },
        formatShowingRows: function (pageFrom, pageTo, totalRows) {
            return 'A mostrar ' + pageFrom + ' até ' + pageTo + ' de ' + totalRows + ' linhas';
        },
        formatSearch: function () {
            return 'Pesquisa';
        },
        formatNoMatches: function () {
            return 'Nenhum registo encontrado';
        }
    };

    $.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales['pt-PT']);

})(jQuery);
<|endoftext|>


<commit_before>import Store from "./Store"

const dPersisted = true

function isMtTarget(token) {
  if (token.length < 3) { return false }
  return token[0] === "@" || token[0] === "!"
}

const index = {}

function find(id) {
  return index[id]
}

function indexing(fw) {
  if (fw.id) { index[fw.id] = fw }
}

function parentsFor(fw) {
  const parents = []
  let nextId = fw.prevMtId
  let parentFw = find(nextId)

  while (parentFw) {
    parents.push(parentFw)
    nextId = parentFw.prevMtId
    parentFw = find(nextId)
  }

  return parents
}

function serialize(obj) {
  const mentioned = obj.contents.split(" ")
                       .filter(token => (isMtTarget(token)))
  const owned = Store.getState("user").user_id === obj.user_id
  const data = {
    contents: obj.contents,
    createdAt: obj.created_at,
    id: obj.id,
    imageAdultFlg: obj.image_adult_flg,
    imageUrl: obj.image_url,
    isDm: obj.is_dm,
    name: obj.name,
    prevMtId: obj.prev_mt_id,
    rootMtId: obj.root_mt_id,
    userId: obj.user_id,
    mentionedNames: mentioned,
    persisted: obj.persisted === undefined ? dPersisted : obj.persisted,
    isDeletable: owned,
    inStack: obj.inStack === undefined ? false : obj.inStack
  }
  indexing(data)
  return data
}

export default function (fws, inStack = true) {
  const serializedFws = fws.map((fw) => {
    fw.inStack = inStack
    return serialize(fw)
  })
  serializedFws.forEach((fw) => {
    fw.parents = parentsFor(fw)
  })
  return serializedFws
}
<commit_msg>Give bold style to mentioned current user name<commit_after>import Store from "./Store"

const dPersisted = true

function isMtTarget(token) {
  if (token.length < 3) { return false }
  return token[0] === "@" || token[0] === "!"
}

const index = {}

function find(id) {
  return index[id]
}

function indexing(fw) {
  if (fw.id) { index[fw.id] = fw }
}

function parentsFor(fw) {
  const parents = []
  let nextId = fw.prevMtId
  let parentFw = find(nextId)

  while (parentFw) {
    parents.push(parentFw)
    nextId = parentFw.prevMtId
    parentFw = find(nextId)
  }

  return parents
}

function serialize(obj) {
  const user = Store.getState("user")
  const mentioned = obj.contents.split(" ")
                       .filter(token => (isMtTarget(token)))
  const regex = RegExp(`[@|!]${user.user_name}`)
  const userNamehighlightedContent =
    obj.contents.replace(regex, match => (
      `<span class="font-weight-bold">${match}</span>`
    ))
  const owned = user.user_id === obj.user_id
  const data = {
    contents: userNamehighlightedContent,
    createdAt: obj.created_at,
    id: obj.id,
    imageAdultFlg: obj.image_adult_flg,
    imageUrl: obj.image_url,
    isDm: obj.is_dm,
    name: obj.name,
    prevMtId: obj.prev_mt_id,
    rootMtId: obj.root_mt_id,
    userId: obj.user_id,
    mentionedNames: mentioned,
    isDeletable: owned,
    persisted: obj.persisted === undefined ? dPersisted : obj.persisted,
    inStack: obj.inStack === undefined ? false : obj.inStack
  }
  indexing(data)
  return data
}

export default function (fws, inStack = true) {
  const serializedFws = fws.map((fw) => {
    fw.inStack = inStack
    return serialize(fw)
  })
  serializedFws.forEach((fw) => {
    fw.parents = parentsFor(fw)
  })
  return serializedFws
}
<|endoftext|>