<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.len<commit_msg>Quick fix<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.leng<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info(<commit_msg>Update character<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile,<commit_msg>Update character<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, <|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    v<commit_msg>Re-updating the readme.<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    va<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var args = ['commit'<commit_msg>Update character<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    console.info("Bytes: %s", length)
    try {
      child_process.execFileSync('/usr/bin/git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var args = ['commit',<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One<commit_msg>What do you mean you can't pack up the commit?<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One <|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
  })
} else {
  console.info("Usage:")
  console.info("node commit.js infile outfile [max_time_in_seconds] [step]")
}

function sleep(seconds) {
  var endTime = new Date().getTime() + (seconds * 1000);
  while (new Date().getTime() <= endTime) {;}
}

function randomIntFromInterval(min,max)
{
   return Math.floor(Math.random()*(max-min+1)+min);
}

function commit(t_offset, outFD, outFile, data, counter, length)
{
  if (counter < length)
  {
    var message = commit_messages[randomIntFromInterval(<commit_msg>Fixing a typo added in the last readme update<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
  })
} else {
  console.info("Usage:")
  console.info("node commit.js infile outfile [max_time_in_seconds] [step]")
}

function sleep(seconds) {
  var endTime = new Date().getTime() + (seconds * 1000);
  while (new Date().getTime() <= endTime) {;}
}

function randomIntFromInterval(min,max)
{
   return Math.floor(Math.random()*(max-min+1)+min);
}

function commit(t_offset, outFD, outFile, data, counter, length)
{
  if (counter < length)
  {
    var message = commit_messages[randomIntFromInterval(0<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will gene<commit_msg>Re-commiting last<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more<commit_msg>Found an issue with the letter 'a', so I fixed it.<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more <|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
  })
} else {
  console.info("Usage:")
  console.info("node commit.js infile outfile [max_time_in_seconds] [step]")
}

function sleep(seconds) {
  var endTime = new Date().getTime() + (seconds * 1000);
  while (new Date().getTime() <= endTime) {;}
}

function randomIntFromInterval(min,max)
{
   return Math.floor(Math.random()*(max-min+1)+min);
}

function commit(t_offset, outFD, outFile, data, counter, length)
{
  if (counter < length)
  {
    var message = commit_messages[randomIntFromInterval(0, commit_messages.length - 1)]
    var args = ['commit', outFile, '-m', message]
    if (counter + step >= length) step = length - counter
    process.stdout.write("\033[2K Writing " + counter + "/" + length + " bytes: " + message + "\r");
    fs.writeSync(outFD, data.slice(counter, counter+step), 0, step)
    child_process.execFileSync('/Applications/Xcode.app/Contents/Developer/usr/bin/git', args)
    var timeout = randomIntFr<commit_msg>Reverting changes<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
  })
} else {
  console.info("Usage:")
  console.info("node commit.js infile outfile [max_time_in_seconds] [step]")
}

function sleep(seconds) {
  var endTime = new Date().getTime() + (seconds * 1000);
  while (new Date().getTime() <= endTime) {;}
}

function randomIntFromInterval(min,max)
{
   return Math.floor(Math.random()*(max-min+1)+min);
}

function commit(t_offset, outFD, outFile, data, counter, length)
{
  if (counter < length)
  {
    var message = commit_messages[randomIntFromInterval(0, commit_messages.length - 1)]
    var args = ['commit', outFile, '-m', message]
    if (counter + step >= length) step = length - counter
    process.stdout.write("\033[2K Writing " + counter + "/" + length + " bytes: " + message + "\r");
    fs.writeSync(outFD, data.slice(counter, counter+step), 0, step)
    child_process.execFileSync('/Applications/Xcode.app/Contents/Developer/usr/bin/git', args)
    var timeout = randomIntFro<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
  })
} else {
  console.info("Usage:")
  console.info("node commit.js infile outfile [max_time_in_seconds] [step]")
}

function sleep(seconds) {
  var endTime = new Date().getTime() + (seconds * 1000);
  while (new Date().getTime() <= endTime) {;}
}

function randomIntFromInterval(min,max)
{
   return Math.floor(Math.random()*(max-min+1)+min);
}

function commit(t_offset, outFD, outFile, data, counter, length)
{
  if (counter < length)
  {
    var message = commit_messages[randomIntFromInterval(0, commit_messages.length - 1)]
    var args = ['commit', outFile, <commit_msg>Fast-forwarding changes<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20% buffer, to reduce the likelihood of going in to the future
      t_offset = commit_time * -1.2;
      faketime(t_offset);
    }
    try {
      child_process.execFileSync('git', ['add', outFile])
    } catch (e) {
      console.error("Couldn't add %s to git: %s", outFile, e)
    }
    var counter = 0
    process.stdout.write("Queueing up the first commit...\r");
    var timeout;
    if (process.env.FAKETIME) {
      faketime(t_offset);
      timeout = 20;
    } else {
      timeout = randomIntFromInterval(0, max_sleep) * 1000
    }
    setTimeout(commit, timeout, t_offset, outFD, outFile, data, counter, length);
  })
} else {
  console.info("Usage:")
  console.info("node commit.js infile outfile [max_time_in_seconds] [step]")
}

function sleep(seconds) {
  var endTime = new Date().getTime() + (seconds * 1000);
  while (new Date().getTime() <= endTime) {;}
}

function randomIntFromInterval(min,max)
{
   return Math.floor(Math.random()*(max-min+1)+min);
}

function commit(t_offset, outFD, outFile, data, counter, length)
{
  if (counter < length)
  {
    var message = commit_messages[randomIntFromInterval(0, commit_messages.length - 1)]
    var args = ['commit', outFile, '<|endoftext|>


<commit_before>const rightSideBuilder = require('imcms-image-editor-right-side-builder');
const leftSideBuilder = require('imcms-image-editor-left-side-builder');
const $ = require('jquery');
const texts = require('imcms-i18n-texts').editors.image;
const bodyHeadBuilder = require('imcms-image-editor-body-head-builder');
const BEM = require('imcms-bem-builder');

const $imageLinkInfo = $('<a>', {
    id: 'data-link-image'
});
const $imageLinkContainerInfo = $('<div>', {
    "class": 'image-editor-info',
    html: $imageLinkInfo
});

module.exports = {
    buildEditor: opts => {
        const $rightSidePanel = rightSideBuilder.build(opts);
        const $leftSide = leftSideBuilder.build();
        const $bodyHead = bodyHeadBuilder.build($rightSidePanel, opts.imageData);
        const $head = opts.imageWindowBuilder.buildHead(texts.title + "- " + texts.page + opts.$tag.attr('data-doc-id')
            + ", " + texts.imageName + opts.$tag.attr('data-index') + " - "
            + texts.teaser + "(" + opts.$tag.width() + " x " + opts.$tag.height() + ")");

        $head.find('.imcms-title').append($imageLinkContainerInfo);

        return new BEM({
            block: "imcms-image_editor",
            elements: {
                "head": $head,
                "image-characteristics": $bodyHead,
                "left-side": $leftSide,
                "right-side": $rightSidePanel
            }
        }).buildBlockStructure("<div>", {"class": "imcms-editor-window"});
    },
    updateImageData: ($tag, imageData) => {
        if ($tag.attr('data-loop-index')) {
            const linkData = '/api/admin/image?meta-id=' + $tag.attr('data-doc-id')
                + '&index=' + $tag.attr('data-index')
                + '&loop-index=' + $tag.attr('data-loop-index')
                + '&loop-entry-index=' + $tag.attr('data-loop-entry-index');

            $imageLinkInfo.text(linkData);

            $imageLinkInfo.attr('href', linkData)

        } else {
            const linkData = '/api/admin/image?meta-id='
                + $tag.attr('data-doc-id')
                + '&index=' + $tag.attr('data-index');

            $imageLinkInfo.text(linkData);

            $imageLinkInfo.attr('href', linkData)
        }
        rightSideBuilder.updateImageData($tag, imageData);
    }
};
<commit_msg>Issue IMCMS-508: Improve the image editor - Improve build and refactor<commit_after>const rightSideBuilder = require('imcms-image-editor-right-side-builder');
const leftSideBuilder = require('imcms-image-editor-left-side-builder');
const $ = require('jquery');
const texts = require('imcms-i18n-texts').editors.image;
const bodyHeadBuilder = require('imcms-image-editor-body-head-builder');
const BEM = require('imcms-bem-builder');
const components = require('imcms-components-builder');

const $imageLinkInfo = $('<a>', {
    id: 'data-link-image'
});

const $imageLinkContainerInfo = new BEM({
    block: 'image-editor-info',
    elements: {
        'icon-link': $('<div>', {
            html: components.controls.permalink()
        }),
        'data-link': $('<div>', {
            html: $imageLinkInfo
        })
    }
}).buildBlockStructure('<div>');

module.exports = {
    buildEditor: opts => {
        const $rightSidePanel = rightSideBuilder.build(opts);
        const $leftSide = leftSideBuilder.build();
        const $bodyHead = bodyHeadBuilder.build($rightSidePanel, opts.imageData);
        const $head = opts.imageWindowBuilder.buildHead(texts.title + "- " + texts.page + opts.$tag.attr('data-doc-id')
            + ", " + texts.imageName + opts.$tag.attr('data-index') + " - "
            + texts.teaser + "(" + opts.$tag.width() + " x " + opts.$tag.height() + ")");

        $head.find('.imcms-title').append($imageLinkContainerInfo);

        return new BEM({
            block: "imcms-image_editor",
            elements: {
                "head": $head,
                "image-characteristics": $bodyHead,
                "left-side": $leftSide,
                "right-side": $rightSidePanel
            }
        }).buildBlockStructure("<div>", {"class": "imcms-editor-window"});
    },
    updateImageData: ($tag, imageData) => {
        if ($tag.attr('data-loop-index')) {
            const linkData = '/api/admin/image?meta-id=' + $tag.attr('data-doc-id')
                + '&index=' + $tag.attr('data-index')
                + '&loop-index=' + $tag.attr('data-loop-index')
                + '&loop-entry-index=' + $tag.attr('data-loop-entry-index');

            $imageLinkInfo.text(linkData);

            $imageLinkInfo.attr('href', linkData)

        } else {
            const linkData = '/api/admin/image?meta-id='
                + $tag.attr('data-doc-id')
                + '&index=' + $tag.attr('data-index');

            $imageLinkInfo.text(linkData);

            $imageLinkInfo.attr('href', linkData)
        }
        rightSideBuilder.updateImageData($tag, imageData);
    }
};
<|endoftext|>


<commit_before>import React from 'react';
import {graphql, compose, withApollo} from 'react-apollo';
import {
  Checkbox,
  Confirm,
  Container,
  Dropdown,
  Button,
  Grid,
  Icon,
  Input,
  Popup,
  Transition,
} from 'semantic-ui-react';
import RunFeed from '../components/RunFeed';
import RunFiltersRedux from './RunFiltersRedux';
import RunColumnsSelector from '../components/RunColumnsSelector';
import ViewModifier from './ViewModifier';
import HelpIcon from '../components/HelpIcon';
import {PROJECT_QUERY, MODIFY_RUNS} from '../graphql/runs';
import {MODEL_UPSERT} from '../graphql/models';
import {connect} from 'react-redux';
import queryString from 'query-string';
import _ from 'lodash';
import {
  sortRuns,
  defaultViews,
  parseBuckets,
  setupKeySuggestions,
} from '../util/runhelpers.js';
import {MAX_HISTORIES_LOADED} from '../util/constants.js';
import {bindActionCreators} from 'redux';
import {setColumns, setFilters} from '../actions/run';
import {
  resetViews,
  setServerViews,
  setBrowserViews,
  setActiveView,
  addView,
} from '../actions/view';
import update from 'immutability-helper';
import {BOARD} from '../util/board';
import withRunsDataLoader from '../containers/RunsDataLoader';
import withRunsQueryRedux from '../containers/RunsQueryRedux';
import * as Filter from '../util/filters';
import * as Selection from '../util/selections';
import * as Query from '../util/query';

class Runs extends React.Component {
  state = {showFailed: false, activeTab: 0, showFilters: false};

  componentDidUpdate() {
    window.Prism.highlightAll();
  }

  onSort = (column, order = 'descending') => {
    this.props.refetch({order: [column, order].join(' ')});
  };

  _shareableUrl(props) {
    let query = {};
    if (!_.isEmpty(props.runFilters)) {
      query.filters = Filter.toURL(props.runFilters);
    }
    if (!_.isEmpty(props.runSelections)) {
      query.selections = Filter.toURL(props.runSelections);
    }
    if (!_.isNil(props.activeView)) {
      query.activeView = props.activeView;
    }
    return (
      `${window.location.protocol}//${window.location.host}${
        window.location.pathname
      }` +
      '?' +
      queryString.stringify(query)
    );
  }

  _readUrl(props) {
    var parsed = queryString.parse(window.location.search);
    if (!parsed) {
      return;
    }
    let filterFilters;
    if (parsed.filters) {
      filterFilters = Filter.fromURL(parsed.filters);
    } else if (parsed.filter) {
      let filts = parsed.filter;
      if (!_.isArray(filts)) {
        filts = [filts];
      }
      filterFilters = Filter.fromOldURL(filts);
    }
    let selectFilters;
    if (parsed.selections) {
      selectFilters = Filter.fromURL(parsed.selections);
    } else if (parsed.select) {
      let filts = parsed.select;
      if (!_.isArray(filts)) {
        filts = [filts];
      }
      selectFilters = Filter.fromOldURL(filts);
    }

    if (filterFilters) {
      this.props.setFilters('filter', filterFilters);
    } else {
      this.props.setFilters('filter', {
        op: 'OR',
        filters: [
          {
            op: 'AND',
            filters: [
              {key: {section: 'tags', name: 'hidden'}, op: '=', value: false},
            ],
          },
        ],
      });
    }

    if (selectFilters) {
      this.props.setFilters('select', selectFilters);
    } else {
      this.props.setFilters('select', Selection.all());
    }

    if (!_.isNil(parsed.activeView)) {
      this.props.setActiveView('runs', parseInt(parsed.activeView, 10));
    }
  }

  componentWillMount() {
    this.props.resetViews();
    this._readUrl(this.props);
  }

  componentDidMount() {
    this.doneLoading = false;
  }

  componentWillReceiveProps(nextProps) {
    // Columns selction is disabled now, everything is automatic. We can re-enable
    // if someone asks for it.
    // if (
    //   !this.doneLoading &&
    //   nextProps.loading === false &&
    //   nextProps.data.base.length > 0
    // ) {
    //   this.doneLoading = true;
    //   let defaultColumns = {
    //     Description: true,
    //     Ran: true,
    //     Runtime: true,
    //     _ConfigAuto: true,
    //     Sweep: _.indexOf(nextProps.data.columnNames, 'Sweep') !== -1,
    //   };
    //   let summaryColumns = nextProps.data.columnNames.filter(col =>
    //     _.startsWith(col, 'summary')
    //   );
    //   for (var col of summaryColumns) {
    //     defaultColumns[col] = true;
    //   }
    //   this.props.setColumns(defaultColumns);
    // }
    // Setup views loaded from server.
    if (
      nextProps.views &&
      nextProps.views.runs &&
      !_.isEqual(nextProps.views, this.props.reduxServerViews)
    ) {
      if (
        _.isEqual(this.props.reduxServerViews, this.props.reduxBrowserViews)
      ) {
        this.props.setBrowserViews(nextProps.views);
      }
      this.props.setServerViews(nextProps.views);
    }
  }

  handleTabChange = (e, {activeIndex}) =>
    this.setState({activeTab: activeIndex});

  render() {
    let ModelInfo = this.props.ModelInfo;
    const filterCount = Filter.countIndividual(this.props.runFilters);
    return (

        <Confirm
          open={this.state.showConfirm}
          onCancel={this.state.handleCancel}
          onConfirm={this.state.handleConfirm}
          content={this.state.confirmText}
          confirmButton={this.state.confirmButton}
        />
        <Grid>
          <Grid.Row divided columns={2}>
            <Grid.Column>{ModelInfo}</Grid.Column>
            <Grid.Column textAlign="right">

                <Popup
                  content={
                    <Input
                      style={{minWidth: 520}}
                      value={this._shareableUrl(this.props)}
                    />
                  }
                  style={{width: '100%'}}
                  on="click"
                  position="bottom right"
                  wide="very"
                  trigger={
                    <Button
                      style={{marginRight: 6}}
                      icon="linkify"
                      size="mini"
                    />
                  }
                />
                {this.props.counts.runs} total runs,{' '}
                {this.props.counts.filtered} filtered,{' '}
                {this.props.counts.selected} selected

                    this.setState({showFilters: !this.state.showFilters})
                  }>
                  <Icon
                    rotated={this.state.showFilters ? null : 'counterclockwise'}
                    name="dropdown"
                  />
                  {filterCount + ' Filter' + (filterCount === 1 ? '' : 's')}

            </Grid.Column>
          </Grid.Row>
          <Grid.Row>
            <Grid.Column>
              <Transition.Group
                className="ui grid"
                animation="slide right"
                duration={200}>
                {this.state.showFilters && (
                  <Grid.Row>
                    <Grid.Column width={16}>

                        Filters{' '}
                        <HelpIcon text="Filters limit the set of runs that will be displayed in charts and tables on this page." />

                      <RunFiltersRedux
                        entityName={this.props.match.params.entity}
                        projectName={this.props.match.params.model}
                        kind="filter"
                        buttonText="Add Filter"
                        filteredRunsCount={this.props.counts.filtered}
                      />
                    </Grid.Column>
                  </Grid.Row>
                )}
              </Transition.Group>
            </Grid.Column>
          </Grid.Row>
          {
            <Grid.Column width={16}>
              {this.props.haveViews && (
                <ViewModifier
                  viewType="runs"
                  data={this.props.data}
                  pageQuery={{
                    entity: this.props.match.params.entity,
                    model: this.props.match.params.model,
                    sort: this.props.sort,
                    filters: this.props.runFilters,
                    selections: this.props.runSelections,
                  }}
                  updateViews={views =>
                    this.props.updateModel({
                      entityName: this.props.match.params.entity,
                      name: this.props.match.params.model,
                      id: this.props.projectID,
                      views: views,
                    })
                  }
                />
              )}
            </Grid.Column>
          }
          <Grid.Column width={16} style={{zIndex: 2}}>
            {/* <Popup
              trigger={
                <Button
                  disabled={this.props.loading}
                  floated="right"
                  icon="columns"
                  content="Columns"
                />
              }
              content={
                <RunColumnsSelector columnNames={this.props.data.columnNames} />
              }
              on="click"
              position="bottom left"
            /> */}
            {!this.props.haveViews && (
              <Button
                floated="right"
                content="Add Charts"
                disabled={this.props.loading}
                icon="area chart"
                onClick={() => this.props.addView('runs', 'Charts', [])}
              />
            )}
            <Button
              floated="right"
              disabled={this.props.counts.selected === 0}
              onClick={e => {
                // TODO(adrian): this should probably just be a separate component
                e.preventDefault();

                this.setState({
                  showConfirm: true,
                  confirmText:
                    'Are you sure you would like to hide these runs? You can reverse this later by removing the "hidden" label.',
                  confirmButton: `Hide ${this.props.counts.selected} run(s)`,
                  handleConfirm: e => {
                    e.preventDefault();
                    this.props.modifyRuns({
                      filters: JSON.stringify(
                        Filter.toMongo(
                          Filter.And([
                            this.props.runFilters,
                            this.props.runSelections,
                          ])
                        )
                      ),
                      entityName: this.props.match.params.entity,
                      projectName: this.props.match.params.model,
                      addTags: ['hidden'],
                    });
                    this.setState({
                      showConfirm: false,
                      handleConfirm: null,
                      handleCancel: null,
                    });
                  },
                  handleCancel: e => {
                    e.preventDefault();
                    this.setState({
                      showConfirm: false,
                      handleConfirm: null,
                      handleCancel: null,
                    });
                  },
                });
              }}>
              <Icon name="hide" />
              Hide {this.props.counts.selected} run(s)
            </Button>
            <Dropdown
              icon={null}
              trigger={
                <Button>
                  <Icon
                    name={
                      this.props.counts.selected === 0
                        ? 'square outline'
                        : this.props.counts.selectedRuns ===
                          this.props.counts.filtered
                          ? 'checkmark box'
                          : 'minus square outline'
                    }
                  />
                  Select
                </Button>
              }
              onClick={(e, {value}) => console.log('dropdown click', value)}>
              <Dropdown.Menu>
                <Dropdown.Item
                  onClick={() =>
                    this.props.setFilters('select', Selection.all())
                  }>
                  <Icon
                    style={{marginRight: 4}}
                    color="grey"
                    name="checkmark box"
                  />{' '}
                  All
                </Dropdown.Item>
                <Dropdown.Item
                  onClick={() =>
                    this.props.setFilters('select', Selection.none())
                  }>
                  <Icon
                    style={{marginRight: 4}}
                    color="grey"
                    name="square outline"
                  />{' '}
                  None
                </Dropdown.Item>
              </Dropdown.Menu>
            </Dropdown>
            {/*

              Select
              all
              none

 */}
          </Grid.Column>
        </Grid>
        <RunFeed
          admin={this.props.user && this.props.user.admin}
          match={this.props.match}
          loading={this.props.loading}
          project={this.props.project}
          onSort={this.onSort}
          showFailed={this.state.showFailed}
          selectable={true}
          // selectedRuns={this.props.data.selectedRunsById}
          // columnNames={this.props.data.columnNames}
          limit={this.props.limit}
          query={{
            entity: this.props.match.params.entity,
            model: this.props.match.params.model,
            strategy: 'root',
            filters: this.props.runFilters,
            page: {
              // num: state.runs.pages[id] ? state.runs.pages[id].current : 0,
              size: 10,
            },
            sort: this.props.sort,
          }}
        />

    );
  }
}

const withMutations = compose(
  graphql(MODEL_UPSERT, {
    props: ({mutate}) => ({
      updateModel: variables =>
        mutate({
          variables: {...variables},
          updateQueries: {
            Model: (prev, {mutationResult}) => {
              const newModel = mutationResult.data.upsertModel.model;
              return update(prev, {model: {$set: newModel}});
            },
          },
        }),
    }),
  }),
  graphql(MODIFY_RUNS, {
    props: ({mutate}) => ({
      modifyRuns: variables => {
        mutate({
          variables: {...variables},
        });
      },
    }),
  })
);

function mapStateToProps(state, ownProps) {
  return {
    jobId: state.runs.currentJob,
    runFilters: state.runs.filters.filter,
    runSelections: state.runs.filters.select,
    user: state.global.user,
    sort: state.runs.sort,
    filterModel: state.runs.filterModel,
    reduxServerViews: state.views.server,
    reduxBrowserViews: state.views.browser,
    activeView: state.views.other.runs.activeView,
    haveViews:
      !_.isEqual(state.views.browser, state.views.server) ||
      state.views.browser.runs.tabs.length > 0,
  };
}

// export dumb component for testing purposes
export {Runs};

const mapDispatchToProps = (dispatch, ownProps) => {
  return bindActionCreators(
    {
      setColumns,
      setFilters,
      setServerViews,
      setBrowserViews,
      setActiveView,
      resetViews,
      addView,
    },
    dispatch
  );
};

const withData = graphql(PROJECT_QUERY, {
  options: ({match, runFilters, runSelections}) => {
    return {
      variables: {
        entityName: match.params.entity,
        name: match.params.model,
        filters: JSON.stringify(Filter.toMongo(runFilters)),
        selections: JSON.stringify(
          Filter.toMongo(Filter.And([runFilters, runSelections]))
        ),
      },
    };
  },
  props: ({data: {loading, project, viewer, fetchMore}, errors}) => {
    //TODO: For some reason the first poll causes loading to be true
    // if (project && projects.runs && loading) loading = false;
    return {
      loading,
      views: project && project.views && JSON.parse(project.views),
      projectID: project && project.id,
      counts: {
        runs: project && project.runCount,
        filtered: project && project.filteredCount,
        selected: project && project.selectedCount,
      },
    };
  },
});

export default connect(mapStateToProps, mapDispatchToProps)(
  withMutations(withData(Runs))
);
<commit_msg>Add query string back to URL on runs page.<commit_after>import React from 'react';
import {graphql, compose, withApollo} from 'react-apollo';
import {
  Checkbox,
  Confirm,
  Container,
  Dropdown,
  Button,
  Grid,
  Icon,
  Input,
  Popup,
  Transition,
} from 'semantic-ui-react';
import RunFeed from '../components/RunFeed';
import RunFiltersRedux from './RunFiltersRedux';
import RunColumnsSelector from '../components/RunColumnsSelector';
import ViewModifier from './ViewModifier';
import HelpIcon from '../components/HelpIcon';
import {PROJECT_QUERY, MODIFY_RUNS} from '../graphql/runs';
import {MODEL_UPSERT} from '../graphql/models';
import {connect} from 'react-redux';
import queryString from 'query-string';
import _ from 'lodash';
import {
  sortRuns,
  defaultViews,
  parseBuckets,
  setupKeySuggestions,
} from '../util/runhelpers.js';
import {MAX_HISTORIES_LOADED} from '../util/constants.js';
import {bindActionCreators} from 'redux';
import {setColumns, setFilters} from '../actions/run';
import {
  resetViews,
  setServerViews,
  setBrowserViews,
  setActiveView,
  addView,
} from '../actions/view';
import update from 'immutability-helper';
import {BOARD} from '../util/board';
import withRunsDataLoader from '../containers/RunsDataLoader';
import withRunsQueryRedux from '../containers/RunsQueryRedux';
import * as Filter from '../util/filters';
import * as Selection from '../util/selections';
import * as Query from '../util/query';

class Runs extends React.Component {
  state = {showFailed: false, activeTab: 0, showFilters: false};

  componentDidUpdate() {
    window.Prism.highlightAll();
  }

  onSort = (column, order = 'descending') => {
    this.props.refetch({order: [column, order].join(' ')});
  };

  _updateQueryFromProps(query, props) {
    if (!_.isEmpty(props.runFilters)) {
      query.filters = Filter.toURL(props.runFilters);
    }
    if (!_.isEmpty(props.runSelections)) {
      query.selections = Filter.toURL(props.runSelections);
    }
    if (!_.isNil(props.activeView)) {
      query.activeView = props.activeView;
    }
  }

  _shareableUrl(props) {
    let query = {};
    this._updateQueryFromProps(query, props);
    return (
      `${window.location.protocol}//${window.location.host}${
        window.location.pathname
      }` +
      '?' +
      queryString.stringify(query)
    );
  }

  _setUrl(props, nextProps) {
    if (
      props.runFilters !== nextProps.runFilters ||
      props.runSelections !== nextProps.runSelections ||
      props.activeView !== nextProps.activeView
    ) {
      let query = queryString.parse(window.location.search) || {};
      this._updateQueryFromProps(query, nextProps);
      let url = `/${nextProps.match.params.entity}/${
        nextProps.match.params.model
      }/runs`;
      if (!_.isEmpty(query)) {
        url += '?' + queryString.stringify(query);
      }
      window.history.replaceState(null, null, url);
    }
  }

  _readUrl(props) {
    var parsed = queryString.parse(window.location.search);
    if (!parsed) {
      return;
    }
    let filterFilters;
    if (parsed.filters) {
      filterFilters = Filter.fromURL(parsed.filters);
    } else if (parsed.filter) {
      let filts = parsed.filter;
      if (!_.isArray(filts)) {
        filts = [filts];
      }
      filterFilters = Filter.fromOldURL(filts);
    }
    let selectFilters;
    if (parsed.selections) {
      selectFilters = Filter.fromURL(parsed.selections);
    } else if (parsed.select) {
      let filts = parsed.select;
      if (!_.isArray(filts)) {
        filts = [filts];
      }
      selectFilters = Filter.fromOldURL(filts);
    }

    if (filterFilters) {
      this.props.setFilters('filter', filterFilters);
    } else {
      this.props.setFilters('filter', {
        op: 'OR',
        filters: [
          {
            op: 'AND',
            filters: [
              {key: {section: 'tags', name: 'hidden'}, op: '=', value: false},
            ],
          },
        ],
      });
    }

    if (selectFilters) {
      this.props.setFilters('select', selectFilters);
    } else {
      this.props.setFilters('select', Selection.all());
    }

    if (!_.isNil(parsed.activeView)) {
      this.props.setActiveView('runs', parseInt(parsed.activeView, 10));
    }
  }

  componentWillMount() {
    this.props.resetViews();
    this._readUrl(this.props);
  }

  componentDidMount() {
    this.doneLoading = false;

    this._setUrl({}, this.props);
  }

  componentWillReceiveProps(nextProps) {
    // Columns selction is disabled now, everything is automatic. We can re-enable
    // if someone asks for it.
    // if (
    //   !this.doneLoading &&
    //   nextProps.loading === false &&
    //   nextProps.data.base.length > 0
    // ) {
    //   this.doneLoading = true;
    //   let defaultColumns = {
    //     Description: true,
    //     Ran: true,
    //     Runtime: true,
    //     _ConfigAuto: true,
    //     Sweep: _.indexOf(nextProps.data.columnNames, 'Sweep') !== -1,
    //   };
    //   let summaryColumns = nextProps.data.columnNames.filter(col =>
    //     _.startsWith(col, 'summary')
    //   );
    //   for (var col of summaryColumns) {
    //     defaultColumns[col] = true;
    //   }
    //   this.props.setColumns(defaultColumns);
    // }
    // Setup views loaded from server.
    if (
      nextProps.views &&
      nextProps.views.runs &&
      !_.isEqual(nextProps.views, this.props.reduxServerViews)
    ) {
      if (
        _.isEqual(this.props.reduxServerViews, this.props.reduxBrowserViews)
      ) {
        this.props.setBrowserViews(nextProps.views);
      }
      this.props.setServerViews(nextProps.views);
    }

    this._setUrl(this.props, nextProps);
  }

  handleTabChange = (e, {activeIndex}) =>
    this.setState({activeTab: activeIndex});

  render() {
    let ModelInfo = this.props.ModelInfo;
    const filterCount = Filter.countIndividual(this.props.runFilters);
    return (

        <Confirm
          open={this.state.showConfirm}
          onCancel={this.state.handleCancel}
          onConfirm={this.state.handleConfirm}
          content={this.state.confirmText}
          confirmButton={this.state.confirmButton}
        />
        <Grid>
          <Grid.Row divided columns={2}>
            <Grid.Column>{ModelInfo}</Grid.Column>
            <Grid.Column textAlign="right">

                <Popup
                  content={
                    <Input
                      style={{minWidth: 520}}
                      value={this._shareableUrl(this.props)}
                    />
                  }
                  style={{width: '100%'}}
                  on="click"
                  position="bottom right"
                  wide="very"
                  trigger={
                    <Button
                      style={{marginRight: 6}}
                      icon="linkify"
                      size="mini"
                    />
                  }
                />
                {this.props.counts.runs} total runs,{' '}
                {this.props.counts.filtered} filtered,{' '}
                {this.props.counts.selected} selected

                    this.setState({showFilters: !this.state.showFilters})
                  }>
                  <Icon
                    rotated={this.state.showFilters ? null : 'counterclockwise'}
                    name="dropdown"
                  />
                  {filterCount + ' Filter' + (filterCount === 1 ? '' : 's')}

            </Grid.Column>
          </Grid.Row>
          <Grid.Row>
            <Grid.Column>
              <Transition.Group
                className="ui grid"
                animation="slide right"
                duration={200}>
                {this.state.showFilters && (
                  <Grid.Row>
                    <Grid.Column width={16}>

                        Filters{' '}
                        <HelpIcon text="Filters limit the set of runs that will be displayed in charts and tables on this page." />

                      <RunFiltersRedux
                        entityName={this.props.match.params.entity}
                        projectName={this.props.match.params.model}
                        kind="filter"
                        buttonText="Add Filter"
                        filteredRunsCount={this.props.counts.filtered}
                      />
                    </Grid.Column>
                  </Grid.Row>
                )}
              </Transition.Group>
            </Grid.Column>
          </Grid.Row>
          {
            <Grid.Column width={16}>
              {this.props.haveViews && (
                <ViewModifier
                  viewType="runs"
                  data={this.props.data}
                  pageQuery={{
                    entity: this.props.match.params.entity,
                    model: this.props.match.params.model,
                    sort: this.props.sort,
                    filters: this.props.runFilters,
                    selections: this.props.runSelections,
                  }}
                  updateViews={views =>
                    this.props.updateModel({
                      entityName: this.props.match.params.entity,
                      name: this.props.match.params.model,
                      id: this.props.projectID,
                      views: views,
                    })
                  }
                />
              )}
            </Grid.Column>
          }
          <Grid.Column width={16} style={{zIndex: 2}}>
            {/* <Popup
              trigger={
                <Button
                  disabled={this.props.loading}
                  floated="right"
                  icon="columns"
                  content="Columns"
                />
              }
              content={
                <RunColumnsSelector columnNames={this.props.data.columnNames} />
              }
              on="click"
              position="bottom left"
            /> */}
            {!this.props.haveViews && (
              <Button
                floated="right"
                content="Add Charts"
                disabled={this.props.loading}
                icon="area chart"
                onClick={() => this.props.addView('runs', 'Charts', [])}
              />
            )}
            <Button
              floated="right"
              disabled={this.props.counts.selected === 0}
              onClick={e => {
                // TODO(adrian): this should probably just be a separate component
                e.preventDefault();

                this.setState({
                  showConfirm: true,
                  confirmText:
                    'Are you sure you would like to hide these runs? You can reverse this later by removing the "hidden" label.',
                  confirmButton: `Hide ${this.props.counts.selected} run(s)`,
                  handleConfirm: e => {
                    e.preventDefault();
                    this.props.modifyRuns({
                      filters: JSON.stringify(
                        Filter.toMongo(
                          Filter.And([
                            this.props.runFilters,
                            this.props.runSelections,
                          ])
                        )
                      ),
                      entityName: this.props.match.params.entity,
                      projectName: this.props.match.params.model,
                      addTags: ['hidden'],
                    });
                    this.setState({
                      showConfirm: false,
                      handleConfirm: null,
                      handleCancel: null,
                    });
                  },
                  handleCancel: e => {
                    e.preventDefault();
                    this.setState({
                      showConfirm: false,
                      handleConfirm: null,
                      handleCancel: null,
                    });
                  },
                });
              }}>
              <Icon name="hide" />
              Hide {this.props.counts.selected} run(s)
            </Button>
            <Dropdown
              icon={null}
              trigger={
                <Button>
                  <Icon
                    name={
                      this.props.counts.selected === 0
                        ? 'square outline'
                        : this.props.counts.selectedRuns ===
                          this.props.counts.filtered
                          ? 'checkmark box'
                          : 'minus square outline'
                    }
                  />
                  Select
                </Button>
              }
              onClick={(e, {value}) => console.log('dropdown click', value)}>
              <Dropdown.Menu>
                <Dropdown.Item
                  onClick={() =>
                    this.props.setFilters('select', Selection.all())
                  }>
                  <Icon
                    style={{marginRight: 4}}
                    color="grey"
                    name="checkmark box"
                  />{' '}
                  All
                </Dropdown.Item>
                <Dropdown.Item
                  onClick={() =>
                    this.props.setFilters('select', Selection.none())
                  }>
                  <Icon
                    style={{marginRight: 4}}
                    color="grey"
                    name="square outline"
                  />{' '}
                  None
                </Dropdown.Item>
              </Dropdown.Menu>
            </Dropdown>
            {/*

              Select
              all
              none

 */}
          </Grid.Column>
        </Grid>
        <RunFeed
          admin={this.props.user && this.props.user.admin}
          match={this.props.match}
          loading={this.props.loading}
          project={this.props.project}
          onSort={this.onSort}
          showFailed={this.state.showFailed}
          selectable={true}
          // selectedRuns={this.props.data.selectedRunsById}
          // columnNames={this.props.data.columnNames}
          limit={this.props.limit}
          query={{
            entity: this.props.match.params.entity,
            model: this.props.match.params.model,
            strategy: 'root',
            filters: this.props.runFilters,
            page: {
              // num: state.runs.pages[id] ? state.runs.pages[id].current : 0,
              size: 10,
            },
            sort: this.props.sort,
          }}
        />

    );
  }
}

const withMutations = compose(
  graphql(MODEL_UPSERT, {
    props: ({mutate}) => ({
      updateModel: variables =>
        mutate({
          variables: {...variables},
          updateQueries: {
            Model: (prev, {mutationResult}) => {
              const newModel = mutationResult.data.upsertModel.model;
              return update(prev, {model: {$set: newModel}});
            },
          },
        }),
    }),
  }),
  graphql(MODIFY_RUNS, {
    props: ({mutate}) => ({
      modifyRuns: variables => {
        mutate({
          variables: {...variables},
        });
      },
    }),
  })
);

function mapStateToProps(state, ownProps) {
  return {
    jobId: state.runs.currentJob,
    runFilters: state.runs.filters.filter,
    runSelections: state.runs.filters.select,
    user: state.global.user,
    sort: state.runs.sort,
    filterModel: state.runs.filterModel,
    reduxServerViews: state.views.server,
    reduxBrowserViews: state.views.browser,
    activeView: state.views.other.runs.activeView,
    haveViews:
      !_.isEqual(state.views.browser, state.views.server) ||
      state.views.browser.runs.tabs.length > 0,
  };
}

// export dumb component for testing purposes
export {Runs};

const mapDispatchToProps = (dispatch, ownProps) => {
  return bindActionCreators(
    {
      setColumns,
      setFilters,
      setServerViews,
      setBrowserViews,
      setActiveView,
      resetViews,
      addView,
    },
    dispatch
  );
};

const withData = graphql(PROJECT_QUERY, {
  options: ({match, runFilters, runSelections}) => {
    return {
      variables: {
        entityName: match.params.entity,
        name: match.params.model,
        filters: JSON.stringify(Filter.toMongo(runFilters)),
        selections: JSON.stringify(
          Filter.toMongo(Filter.And([runFilters, runSelections]))
        ),
      },
    };
  },
  props: ({data: {loading, project, viewer, fetchMore}, errors}) => {
    //TODO: For some reason the first poll causes loading to be true
    // if (project && projects.runs && loading) loading = false;
    return {
      loading,
      views: project && project.views && JSON.parse(project.views),
      projectID: project && project.id,
      counts: {
        runs: project && project.runCount,
        filtered: project && project.filteredCount,
        selected: project && project.selectedCount,
      },
    };
  },
});

export default connect(mapStateToProps, mapDispatchToProps)(
  withMutations(withData(Runs))
);
<|endoftext|>


<commit_before>beforeEach(function () {
  jasmine.addMatchers({
    toBePlaying: function () {
      return {
        compare: function (actual, expected) {
          var player = actual;

          return {
            pass: player.currentlyPlayingSong === expected && player.isPlaying
          }
        }
      };
    }
  });
});
<commit_msg>removed unused stuff<commit_after><|endoftext|>