<commit_before>'use strict';

function draw(){
    if(settings['clear']){
        buffer.clearRect(
          0,
          0,
          width,
          height
        );
    }

    buffer.lineWidth = settings['line-width'];
    for(var object in objects){
        // Draw rectangles if not in lines mode.
        if(mode != 1){
            buffer.fillStyle = 'rgb('
              + objects[object]['red'] + ', '
              + objects[object]['green'] + ', '
              + objects[object]['blue'] + ')';

            buffer.fillRect(
              objects[object]['x'],
              objects[object]['y'],
              objects[object]['x'] - mouse_x,
              objects[object]['y'] - mouse_y
            );
        }

        // Draw lines if not in rectangles mode.
        if(mode != 2){
            buffer.beginPath();
            buffer.moveTo(
              objects[object]['x'],
              objects[object]['y']
            );
            buffer.lineTo(
              mouse_x,
              mouse_y
            );
            buffer.closePath();
            buffer.strokeStyle = 'rgb('
              + objects[object]['red'] + ', '
              + objects[object]['green'] + ', '
              + objects[object]['blue'] + ')';
            buffer.stroke();
        }
    }

    if(settings['clear']){
        canvas.clearRect(
          0,
          0,
          width,
          height
        );
    }
    canvas.drawImage(
      document.getElementById('buffer'),
      0,
      0
    );
}

function randomize_objects(){
    objects.length = 0;

    var loop_counter = settings['number-of-objects'] - 1;
    do{
        // Create randomized object.
        objects.push({
          'blue': Math.floor(Math.random() * 255),
          'green': Math.floor(Math.random() * 255),
          'red': Math.floor(Math.random() * 255),
          'x': Math.floor(Math.random() * width),
          'y': Math.floor(Math.random() * height),
        });
    }while(loop_counter--);

    draw();
}

function reset(){
    if(!window.confirm('Reset settings?')){
        return;
    }

    document.getElementById('clear').checked = true;
    document.getElementById('line-width').value = 1;
    document.getElementById('mouse-lock').checked = true;
    document.getElementById('number-of-objects').value = 100;
    document.getElementById('randomize-key').value = 'R';

    save();
}

function resize(){
    if(mode <= 0){
        return;
    }

    height = window.innerHeight;
    document.getElementById('buffer').height = height;
    document.getElementById('canvas').height = height;
    y = height / 2;
    mouse_y = y;

    width = window.innerWidth;
    document.getElementById('buffer').width = width;
    document.getElementById('canvas').width = width;
    x = width / 2;
    mouse_x = x;

    randomize_objects();
}

// Save settings into window.localStorage if they differ from default.
function save(){
    if(document.getElementById('clear').checked){
        window.localStorage.removeItem('Warped.htm-clear');
        settings['clear'] = true;

    }else{
        settings['clear'] = false;
        window.localStorage.setItem(
          'Warped.htm-clear',
          1
        );
    }

    if(isNaN(document.getElementById('line-width').value)
      || document.getElementById('line-width').value < 2){
        window.localStorage.removeItem('Warped.htm-line-width');
        settings['line-width'] = 1;

    }else{
        settings['line-width'] = parseInt(document.getElementById('line-width').value);
        window.localStorage.setItem(
          'Warped.htm-line-width',
          settings['line-width']
        );
    }

    if(document.getElementById('randomize-key').value === 'R'){
        window.localStorage.removeItem('Warped.htm-randomize-key');
        settings['randomize-key'] = 'R';

    }else{
        settings['randomize-key'] = document.getElementById('randomize-key').value;
        window.localStorage.setItem(
          'Warped.htm-randomize-key',
          settings['randomize-key']
        );
    }

    if(document.getElementById('mouse-lock').checked){
        window.localStorage.removeItem('Warped.htm-mouse-lock');
        settings['mouse-lock'] = true;

    }else{
        settings['mouse-lock'] = false;
        window.localStorage.setItem(
          'Warped.htm-mouse-lock',
          1
        );
    }

    if(document.getElementById('number-of-objects').value == 100
      || isNaN(document.getElementById('number-of-objects').value)
      || document.getElementById('number-of-objects').value < 1){
        window.localStorage.removeItem('Warped.htm-number-of-objects');
        settings['number-of-objects'] = 100;

    }else{
        settings['number-of-objects'] = parseInt(document.getElementById('number-of-objects').value);
        window.localStorage.setItem(
          'Warped.htm-number-of-objects',
          settings['number-of-objects']
        );
    }
}

function setmode(newmode){
    mode = newmode;

    // Visualization mode.
    if(mode > 0){
        save();

        document.getElementById('page').innerHTML = '<canvas id=canvas></canvas><canvas id=buffer></canvas>';

        buffer = document.getElementById('buffer').getContext('2d');
        canvas = document.getElementById('canvas').getContext('2d');

        resize();

        return;
    }

    // Main menu mode.
    buffer = 0;
    canvas = 0;

    document.getElementById('page').innerHTML = '

Both
Lines
Rectangles

<input disabled style=border:0 value=ESC>Main Menu
<input id=randomize-key maxlength=1 value='
      + settings['randomize-key'] + '>Randomize

<input '
      + (settings['clear'] ? 'checked ' : '') + 'id=clear type=checkbox>Clear
<input id=line-width value='
      + settings['line-width'] + '>Line Width
<input '
      + (settings['mouse-lock'] ? 'checked ' : '') + 'id=mouse-lock type=checkbox>Mouse Lock
<input id=number-of-objects value='
      + settings['number-of-objects'] + '>Objects
Reset Settings

';
}

var buffer = 0;
var canvas = 0;
var height = 0;
var objects = [];
var mode = 0;
var mouse_x = 0;
var mouse_y = 0;
var settings = {
  'clear': window.localStorage.getItem('Warped.htm-clear') === null,
  'line-width' : parseInt(window.localStorage.getItem('Warped.htm-line-width')) || 1,
  'randomize-key': window.localStorage.getItem('Warped.htm-randomize-key') || 'R',
  'mouse-lock': window.localStorage.getItem('Warped.htm-mouse-lock') === null,
  'number-of-objects': parseInt(window.localStorage.getItem('Warped.htm-number-of-objects')) || 100,
};
var x = 0;
var width = 0;
var y = 0;

window.onkeydown = function(e){
    if(mode <= 0){
        return;
    }

    var key = e.keyCode || e.which;

    // settings['randomize-key']: randomize current objects.
    if(String.fromCharCode(key) === settings['randomize-key']){
        randomize_objects();

    // ESC: return to the main menu.
    }else if(key === 27){
        setmode(0);
    }
};

window.onload = function(e){
    resize();
    setmode(0);
};

window.onmousedown =
  window.ontouchstart = function(e){
    if(mode <= 0){
        return;
    }

    mouse_x = e.pageX;
    mouse_y = e.pageY;

    draw();
};

window.onmousemove = function(e){
    if(mode <= 0
      || !settings['mouse-lock']){
        return;
    }

    mouse_x = e.pageX;
    mouse_y = e.pageY;

    draw();
};

window.onresize = resize;
<commit_msg>replaced rgb with hex<commit_after>'use strict';

function draw(){
    if(settings['clear']){
        buffer.clearRect(
          0,
          0,
          width,
          height
        );
    }

    buffer.lineWidth = settings['line-width'];
    for(var object in objects){
        // Draw rectangles if not in lines mode.
        if(mode != 1){
            buffer.fillStyle = objects[object]['color'];
            buffer.fillRect(
              objects[object]['x'],
              objects[object]['y'],
              objects[object]['x'] - mouse_x,
              objects[object]['y'] - mouse_y
            );
        }

        // Draw lines if not in rectangles mode.
        if(mode != 2){
            buffer.beginPath();
            buffer.moveTo(
              objects[object]['x'],
              objects[object]['y']
            );
            buffer.lineTo(
              mouse_x,
              mouse_y
            );
            buffer.closePath();
            buffer.strokeStyle = objects[object]['color'];
            buffer.stroke();
        }
    }

    if(settings['clear']){
        canvas.clearRect(
          0,
          0,
          width,
          height
        );
    }
    canvas.drawImage(
      document.getElementById('buffer'),
      0,
      0
    );
}

function random_hex(){
    var choices = '0123456789abcdef';
    return '#'
      + choices.charAt(Math.floor(Math.random() * 16))
      + choices.charAt(Math.floor(Math.random() * 16))
      + choices.charAt(Math.floor(Math.random() * 16));
}

function randomize_objects(){
    objects.length = 0;

    var loop_counter = settings['number-of-objects'] - 1;
    do{
        // Create randomized object.
        objects.push({
          'color': random_hex(),
          'x': Math.floor(Math.random() * width),
          'y': Math.floor(Math.random() * height),
        });
    }while(loop_counter--);

    draw();
}

function reset(){
    if(!window.confirm('Reset settings?')){
        return;
    }

    document.getElementById('clear').checked = true;
    document.getElementById('line-width').value = 1;
    document.getElementById('mouse-lock').checked = true;
    document.getElementById('number-of-objects').value = 100;
    document.getElementById('randomize-key').value = 'R';

    save();
}

function resize(){
    if(mode <= 0){
        return;
    }

    height = window.innerHeight;
    document.getElementById('buffer').height = height;
    document.getElementById('canvas').height = height;
    y = height / 2;
    mouse_y = y;

    width = window.innerWidth;
    document.getElementById('buffer').width = width;
    document.getElementById('canvas').width = width;
    x = width / 2;
    mouse_x = x;

    randomize_objects();
}

// Save settings into window.localStorage if they differ from default.
function save(){
    if(document.getElementById('clear').checked){
        window.localStorage.removeItem('Warped.htm-clear');
        settings['clear'] = true;

    }else{
        settings['clear'] = false;
        window.localStorage.setItem(
          'Warped.htm-clear',
          1
        );
    }

    if(isNaN(document.getElementById('line-width').value)
      || document.getElementById('line-width').value < 2){
        window.localStorage.removeItem('Warped.htm-line-width');
        settings['line-width'] = 1;

    }else{
        settings['line-width'] = parseInt(document.getElementById('line-width').value);
        window.localStorage.setItem(
          'Warped.htm-line-width',
          settings['line-width']
        );
    }

    if(document.getElementById('randomize-key').value === 'R'){
        window.localStorage.removeItem('Warped.htm-randomize-key');
        settings['randomize-key'] = 'R';

    }else{
        settings['randomize-key'] = document.getElementById('randomize-key').value;
        window.localStorage.setItem(
          'Warped.htm-randomize-key',
          settings['randomize-key']
        );
    }

    if(document.getElementById('mouse-lock').checked){
        window.localStorage.removeItem('Warped.htm-mouse-lock');
        settings['mouse-lock'] = true;

    }else{
        settings['mouse-lock'] = false;
        window.localStorage.setItem(
          'Warped.htm-mouse-lock',
          1
        );
    }

    if(document.getElementById('number-of-objects').value == 100
      || isNaN(document.getElementById('number-of-objects').value)
      || document.getElementById('number-of-objects').value < 1){
        window.localStorage.removeItem('Warped.htm-number-of-objects');
        settings['number-of-objects'] = 100;

    }else{
        settings['number-of-objects'] = parseInt(document.getElementById('number-of-objects').value);
        window.localStorage.setItem(
          'Warped.htm-number-of-objects',
          settings['number-of-objects']
        );
    }
}

function setmode(newmode){
    mode = newmode;

    // Visualization mode.
    if(mode > 0){
        save();

        document.getElementById('page').innerHTML = '<canvas id=canvas></canvas><canvas id=buffer></canvas>';

        buffer = document.getElementById('buffer').getContext('2d');
        canvas = document.getElementById('canvas').getContext('2d');

        resize();

        return;
    }

    // Main menu mode.
    buffer = 0;
    canvas = 0;

    document.getElementById('page').innerHTML = '

Both
Lines
Rectangles

<input disabled style=border:0 value=ESC>Main Menu
<input id=randomize-key maxlength=1 value='
      + settings['randomize-key'] + '>Randomize

<input '
      + (settings['clear'] ? 'checked ' : '') + 'id=clear type=checkbox>Clear
<input id=line-width value='
      + settings['line-width'] + '>Line Width
<input '
      + (settings['mouse-lock'] ? 'checked ' : '') + 'id=mouse-lock type=checkbox>Mouse Lock
<input id=number-of-objects value='
      + settings['number-of-objects'] + '>Objects
Reset Settings

';
}

var buffer = 0;
var canvas = 0;
var height = 0;
var objects = [];
var mode = 0;
var mouse_x = 0;
var mouse_y = 0;
var settings = {
  'clear': window.localStorage.getItem('Warped.htm-clear') === null,
  'line-width' : parseInt(window.localStorage.getItem('Warped.htm-line-width')) || 1,
  'randomize-key': window.localStorage.getItem('Warped.htm-randomize-key') || 'R',
  'mouse-lock': window.localStorage.getItem('Warped.htm-mouse-lock') === null,
  'number-of-objects': parseInt(window.localStorage.getItem('Warped.htm-number-of-objects')) || 100,
};
var x = 0;
var width = 0;
var y = 0;

window.onkeydown = function(e){
    if(mode <= 0){
        return;
    }

    var key = e.keyCode || e.which;

    // settings['randomize-key']: randomize current objects.
    if(String.fromCharCode(key) === settings['randomize-key']){
        randomize_objects();

    // ESC: return to the main menu.
    }else if(key === 27){
        setmode(0);
    }
};

window.onload = function(e){
    resize();
    setmode(0);
};

window.onmousedown =
  window.ontouchstart = function(e){
    if(mode <= 0){
        return;
    }

    mouse_x = e.pageX;
    mouse_y = e.pageY;

    draw();
};

window.onmousemove = function(e){
    if(mode <= 0
      || !settings['mouse-lock']){
        return;
    }

    mouse_x = e.pageX;
    mouse_y = e.pageY;

    draw();
};

window.onresize = resize;
<|endoftext|>


<commit_before>'use strict';

function draw(){
    if(settings['clear']){
        buffer.clearRect(
          0,
          0,
          width,
          height
        );
    }

    for(var object in objects){
        // Draw rectangles if not in lines mode.
        if(mode != 1){
            buffer.fillStyle = objects[object]['color'];
            buffer.fillRect(
              objects[object]['x'],
              objects[object]['y'],
              objects[object]['x'] - mouse_x,
              objects[object]['y'] - mouse_y
            );
        }

        // Draw lines if not in rectangles mode.
        if(mode != 2){
            buffer.beginPath();
            buffer.moveTo(
              objects[object]['x'],
              objects[object]['y']
            );

            var extra_x = 0;
            var extra_y = 0;
            var target_x = mouse_x - objects[object]['x'];
            var target_y = mouse_y - objects[object]['y'];

            if(settings['line-fixed-length'] !== 0){
                var length = Math.sqrt(
                  target_x * target_x + target_y * target_y
                );

                target_x /= length;
                target_x *= settings['line-fixed-length'];
                target_y /= length;
                target_y *= settings['line-fixed-length'];
            }

            if(settings['line-length-multiplier'] !== 1){
                target_x *= settings['line-length-multiplier'];
                target_y *= settings['line-length-multiplier'];
            }

            if(settings['line-extra-length'] !== 0){
                extra_x = mouse_x - objects[object]['x'];
                extra_y = mouse_y - objects[object]['y'];

                var length = Math.sqrt(
                  extra_x * extra_x + extra_y * extra_y
                );

                extra_x /= length;
                extra_x *= settings['line-extra-length'];
                extra_y /= length;
                extra_y *= settings['line-extra-length'];
            }

            buffer.lineTo(
              objects[object]['x'] + target_x + extra_x,
              objects[object]['y'] + target_y + extra_y
            );
            buffer.closePath();
            buffer.strokeStyle = objects[object]['color'];
            buffer.stroke();
        }
    }

    if(settings['clear']){
        canvas.clearRect(
          0,
          0,
          width,
          height
        );
    }
    canvas.drawImage(
      document.getElementById('buffer'),
      0,
      0
    );
}

function random_hex(){
    var choices = '0123456789abcdef';
    return '#'
      + choices.charAt(Math.floor(Math.random() * 16))
      + choices.charAt(Math.floor(Math.random() * 16))
      + choices.charAt(Math.floor(Math.random() * 16));
}

function randomize_objects(){
    objects.length = 0;

    var loop_counter = settings['number-of-objects'] - 1;
    do{
        // Create randomized object.
        objects.push({
          'color': random_hex(),
          'x': Math.floor(Math.random() * width),
          'y': Math.floor(Math.random() * height),
        });
    }while(loop_counter--);

    draw();
}

function reset(){
    if(!window.confirm('Reset settings?')){
        return;
    }

    document.getElementById('clear').checked = true;
    document.getElementById('line-extra-length').value = 0;
    document.getElementById('line-fixed-length').value = 0;
    document.getElementById('line-length-multiplier').value = 1;
    document.getElementById('line-width').value = 1;
    document.getElementById('mouse-lock').checked = true;
    document.getElementById('number-of-objects').value = 100;
    document.getElementById('randomize-key').value = 'R';

    save();
}

function resize(){
    if(mode <= 0){
        return;
    }

    height = window.innerHeight;
    document.getElementById('buffer').height = height;
    document.getElementById('canvas').height = height;
    y = height / 2;
    mouse_y = y;

    width = window.innerWidth;
    document.getElementById('buffer').width = width;
    document.getElementById('canvas').width = width;
    x = width / 2;
    mouse_x = x;

    buffer.lineWidth = settings['line-width'];
    mouse_drag = false;
    randomize_objects();
}

// Save settings into window.localStorage if they differ from default.
function save(){
    var ids = [
      'clear',
      'mouse-lock',
    ];
    for(var id in ids){
        var checked = document.getElementById(ids[id]).checked;
        settings[ids[id]] = checked;

        if(checked){
            window.localStorage.removeItem('Warped.htm-' + ids[id]);

        }else{
            window.localStorage.setItem(
              'Warped.htm-' + ids[id],
              1
            );
        }
    }

    ids = {
      'line-extra-length': 0,
      'line-fixed-length': 0,
      'line-length-multiplier': 1,
      'line-width': 1,
    };
    for(id in ids){
        if(isNaN(document.getElementById(id).value)
          || document.getElementById(id).value == ids[id]){
            window.localStorage.removeItem('Warped.htm-' + id);
            settings[id] = ids[id];

        }else{
            settings[id] = parseFloat(document.getElementById(id).value);
            window.localStorage.setItem(
              'Warped.htm-' + id,
              settings[id]
            );
        }
    }

    if(document.getElementById('randomize-key').value === 'R'){
        window.localStorage.removeItem('Warped.htm-randomize-key');
        settings['randomize-key'] = 'R';

    }else{
        settings['randomize-key'] = document.getElementById('randomize-key').value;
        window.localStorage.setItem(
          'Warped.htm-randomize-key',
          settings['randomize-key']
        );
    }

    if(document.getElementById('number-of-objects').value == 100
      || isNaN(document.getElementById('number-of-objects').value)
      || document.getElementById('number-of-objects').value < 1){
        window.localStorage.removeItem('Warped.htm-number-of-objects');
        settings['number-of-objects'] = 100;

    }else{
        settings['number-of-objects'] = parseInt(document.getElementById('number-of-objects').value);
        window.localStorage.setItem(
          'Warped.htm-number-of-objects',
          settings['number-of-objects']
        );
    }
}

function setmode(newmode){
    mode = newmode;

    // Visualization mode.
    if(mode > 0){
        save();

        document.body.innerHTML =
          '<canvas id=canvas></canvas><canvas id=buffer></canvas>';

        var contextAttributes = {
          'alpha': false,
        };
        buffer = document.getElementById('buffer').getContext(
          '2d',
          contextAttributes
        );
        canvas = document.getElementById('canvas').getContext(
          '2d',
          contextAttributes
        );

        resize();

        return;
    }

    // Main menu mode.
    buffer = 0;
    canvas = 0;

    document.body.innerHTML = '

Both
Lines
Rectangles

<input disabled value=ESC>Main Menu
<input id=randomize-key maxlength=1 value='
      + settings['randomize-key'] + '>Randomize

<input '
      + (settings['clear'] ? 'checked ' : '') + 'id=clear type=checkbox>Clear
<input id=line-extra-length value='
      + settings['line-extra-length'] + '>Line Extra Length
<input id=line-fixed-length value='
      + settings['line-fixed-length'] + '>Line Fixed Length
<input id=line-length-multiplier value='
      + settings['line-length-multiplier'] + '>Line Length Multiplier
<input id=line-width value='
      + settings['line-width'] + '>Line Width
<input '
      + (settings['mouse-lock'] ? 'checked ' : '') + 'id=mouse-lock type=checkbox>Mouse Lock
<input id=number-of-objects value='
      + settings['number-of-objects'] + '>Objects
Reset Settings

';
}

var buffer = 0;
var canvas = 0;
var height = 0;
var objects = [];
var mode = 0;
var mouse_drag = false;
var mouse_x = 0;
var mouse_y = 0;
var settings = {
  'clear': window.localStorage.getItem('Warped.htm-clear') === null,
  'line-extra-length': parseInt(window.localStorage.getItem('Warped.htm-line-extra-length')) || 0,
  'line-fixed-length': parseInt(window.localStorage.getItem('Warped.htm-line-fixed-length')) || 0,
  'line-length-multiplier': parseInt(window.localStorage.getItem('Warped.htm-line-length-multiplier')) || 1,
  'line-width': parseInt(window.localStorage.getItem('Warped.htm-line-width')) || 1,
  'randomize-key': window.localStorage.getItem('Warped.htm-randomize-key') || 'R',
  'mouse-lock': window.localStorage.getItem('Warped.htm-mouse-lock') === null,
  'number-of-objects': parseInt(window.localStorage.getItem('Warped.htm-number-of-objects')) || 100,
};
var x = 0;
var width = 0;
var y = 0;

window.onkeydown = function(e){
    if(mode <= 0){
        return;
    }

    var key = e.keyCode || e.which;

    // settings['randomize-key']: randomize current objects.
    if(String.fromCharCode(key) === settings['randomize-key']){
        randomize_objects();

    // ESC: return to the main menu.
    }else if(key === 27){
        setmode(0);
    }
};

window.onload = function(e){
    resize();
    setmode(0);
};

window.onmousedown =
  window.ontouchstart = function(e){
    if(mode <= 0){
        return;
    }

    mouse_drag = true;
    mouse_x = e.pageX;
    mouse_y = e.pageY;

    draw();
};

window.onmousemove = function(e){
    if(mode <= 0
      || (!settings['mouse-lock'] && !mouse_drag)){
        return;
    }

    mouse_x = e.pageX;
    mouse_y = e.pageY;

    draw();
};

window.onmouseup = function(e){
    mouse_drag = false;
};

window.onresize = resize;
<commit_msg>reduced dom checks<commit_after>'use strict';

function draw(){
    if(settings['clear']){
        buffer.clearRect(
          0,
          0,
          width,
          height
        );
    }

    for(var object in objects){
        // Draw rectangles if not in lines mode.
        if(mode != 1){
            buffer.fillStyle = objects[object]['color'];
            buffer.fillRect(
              objects[object]['x'],
              objects[object]['y'],
              objects[object]['x'] - mouse_x,
              objects[object]['y'] - mouse_y
            );
        }

        // Draw lines if not in rectangles mode.
        if(mode != 2){
            buffer.beginPath();
            buffer.moveTo(
              objects[object]['x'],
              objects[object]['y']
            );

            var extra_x = 0;
            var extra_y = 0;
            var target_x = mouse_x - objects[object]['x'];
            var target_y = mouse_y - objects[object]['y'];

            if(settings['line-fixed-length'] !== 0){
                var length = Math.sqrt(
                  target_x * target_x + target_y * target_y
                );

                target_x /= length;
                target_x *= settings['line-fixed-length'];
                target_y /= length;
                target_y *= settings['line-fixed-length'];
            }

            if(settings['line-length-multiplier'] !== 1){
                target_x *= settings['line-length-multiplier'];
                target_y *= settings['line-length-multiplier'];
            }

            if(settings['line-extra-length'] !== 0){
                extra_x = mouse_x - objects[object]['x'];
                extra_y = mouse_y - objects[object]['y'];

                var length = Math.sqrt(
                  extra_x * extra_x + extra_y * extra_y
                );

                extra_x /= length;
                extra_x *= settings['line-extra-length'];
                extra_y /= length;
                extra_y *= settings['line-extra-length'];
            }

            buffer.lineTo(
              objects[object]['x'] + target_x + extra_x,
              objects[object]['y'] + target_y + extra_y
            );
            buffer.closePath();
            buffer.strokeStyle = objects[object]['color'];
            buffer.stroke();
        }
    }

    if(settings['clear']){
        canvas.clearRect(
          0,
          0,
          width,
          height
        );
    }
    canvas.drawImage(
      document.getElementById('buffer'),
      0,
      0
    );
}

function random_hex(){
    var choices = '0123456789abcdef';
    return '#'
      + choices.charAt(Math.floor(Math.random() * 16))
      + choices.charAt(Math.floor(Math.random() * 16))
      + choices.charAt(Math.floor(Math.random() * 16));
}

function randomize_objects(){
    objects.length = 0;

    var loop_counter = settings['number-of-objects'] - 1;
    do{
        // Create randomized object.
        objects.push({
          'color': random_hex(),
          'x': Math.floor(Math.random() * width),
          'y': Math.floor(Math.random() * height),
        });
    }while(loop_counter--);

    draw();
}

function reset(){
    if(!window.confirm('Reset settings?')){
        return;
    }

    document.getElementById('clear').checked = true;
    document.getElementById('line-extra-length').value = 0;
    document.getElementById('line-fixed-length').value = 0;
    document.getElementById('line-length-multiplier').value = 1;
    document.getElementById('line-width').value = 1;
    document.getElementById('mouse-lock').checked = true;
    document.getElementById('number-of-objects').value = 100;
    document.getElementById('randomize-key').value = 'R';

    save();
}

function resize(){
    if(mode <= 0){
        return;
    }

    height = window.innerHeight;
    document.getElementById('buffer').height = height;
    document.getElementById('canvas').height = height;
    y = height / 2;
    mouse_y = y;

    width = window.innerWidth;
    document.getElementById('buffer').width = width;
    document.getElementById('canvas').width = width;
    x = width / 2;
    mouse_x = x;

    buffer.lineWidth = settings['line-width'];
    mouse_drag = false;
    randomize_objects();
}

// Save settings into window.localStorage if they differ from default.
function save(){
    var ids = [
      'clear',
      'mouse-lock',
    ];
    for(var id in ids){
        var checked = document.getElementById(ids[id]).checked;
        settings[ids[id]] = checked;

        if(checked){
            window.localStorage.removeItem('Warped.htm-' + ids[id]);

        }else{
            window.localStorage.setItem(
              'Warped.htm-' + ids[id],
              1
            );
        }
    }

    ids = {
      'line-extra-length': 0,
      'line-fixed-length': 0,
      'line-length-multiplier': 1,
      'line-width': 1,
    };
    for(id in ids){
        var value = document.getElementById(id).value;
        if(isNaN(value)
          || value == ids[id]){
            window.localStorage.removeItem('Warped.htm-' + id);
            settings[id] = ids[id];

        }else{
            settings[id] = parseFloat(value);
            window.localStorage.setItem(
              'Warped.htm-' + id,
              settings[id]
            );
        }
    }

    var randomize_key = document.getElementById('randomize-key').value;
    if(randomize_key === 'R'){
        window.localStorage.removeItem('Warped.htm-randomize-key');
        settings['randomize-key'] = 'R';

    }else{
        settings['randomize-key'] = randomize_key;
        window.localStorage.setItem(
          'Warped.htm-randomize-key',
          settings['randomize-key']
        );
    }

    var number_of_objects = document.getElementById('number-of-objects').value;
    if(isNaN(number_of_objects)
      || number_of_objects == 100
      || number_of_objects < 1){
        window.localStorage.removeItem('Warped.htm-number-of-objects');
        settings['number-of-objects'] = 100;

    }else{
        settings['number-of-objects'] = parseInt(number_of_objects);
        window.localStorage.setItem(
          'Warped.htm-number-of-objects',
          settings['number-of-objects']
        );
    }
}

function setmode(newmode){
    mode = newmode;

    // Visualization mode.
    if(mode > 0){
        save();

        document.body.innerHTML =
          '<canvas id=canvas></canvas><canvas id=buffer></canvas>';

        var contextAttributes = {
          'alpha': false,
        };
        buffer = document.getElementById('buffer').getContext(
          '2d',
          contextAttributes
        );
        canvas = document.getElementById('canvas').getContext(
          '2d',
          contextAttributes
        );

        resize();

        return;
    }

    // Main menu mode.
    buffer = 0;
    canvas = 0;

    document.body.innerHTML = '

Both
Lines
Rectangles

<input disabled value=ESC>Main Menu
<input id=randomize-key maxlength=1 value='
      + settings['randomize-key'] + '>Randomize

<input '
      + (settings['clear'] ? 'checked ' : '') + 'id=clear type=checkbox>Clear
<input id=line-extra-length value='
      + settings['line-extra-length'] + '>Line Extra Length
<input id=line-fixed-length value='
      + settings['line-fixed-length'] + '>Line Fixed Length
<input id=line-length-multiplier value='
      + settings['line-length-multiplier'] + '>Line Length Multiplier
<input id=line-width value='
      + settings['line-width'] + '>Line Width
<input '
      + (settings['mouse-lock'] ? 'checked ' : '') + 'id=mouse-lock type=checkbox>Mouse Lock
<input id=number-of-objects value='
      + settings['number-of-objects'] + '>Objects
Reset Settings

';
}

var buffer = 0;
var canvas = 0;
var height = 0;
var objects = [];
var mode = 0;
var mouse_drag = false;
var mouse_x = 0;
var mouse_y = 0;
var settings = {
  'clear': window.localStorage.getItem('Warped.htm-clear') === null,
  'line-extra-length': parseInt(window.localStorage.getItem('Warped.htm-line-extra-length')) || 0,
  'line-fixed-length': parseInt(window.localStorage.getItem('Warped.htm-line-fixed-length')) || 0,
  'line-length-multiplier': parseInt(window.localStorage.getItem('Warped.htm-line-length-multiplier')) || 1,
  'line-width': parseInt(window.localStorage.getItem('Warped.htm-line-width')) || 1,
  'randomize-key': window.localStorage.getItem('Warped.htm-randomize-key') || 'R',
  'mouse-lock': window.localStorage.getItem('Warped.htm-mouse-lock') === null,
  'number-of-objects': parseInt(window.localStorage.getItem('Warped.htm-number-of-objects')) || 100,
};
var x = 0;
var width = 0;
var y = 0;

window.onkeydown = function(e){
    if(mode <= 0){
        return;
    }

    var key = e.keyCode || e.which;

    // settings['randomize-key']: randomize current objects.
    if(String.fromCharCode(key) === settings['randomize-key']){
        randomize_objects();

    // ESC: return to the main menu.
    }else if(key === 27){
        setmode(0);
    }
};

window.onload = function(e){
    resize();
    setmode(0);
};

window.onmousedown =
  window.ontouchstart = function(e){
    if(mode <= 0){
        return;
    }

    mouse_drag = true;
    mouse_x = e.pageX;
    mouse_y = e.pageY;

    draw();
};

window.onmousemove = function(e){
    if(mode <= 0
      || (!settings['mouse-lock'] && !mouse_drag)){
        return;
    }

    mouse_x = e.pageX;
    mouse_y = e.pageY;

    draw();
};

window.onmouseup = function(e){
    mouse_drag = false;
};

window.onresize = resize;
<|endoftext|>


<commit_before>const { authenticate } = require('@feathersjs/authentication');
const { Forbidden } = require('@feathersjs/errors');
const { hasPermission } = require('../../../hooks');
const { getScopePermissions } = require('../../helpers/scopePermissions/hooks/checkScopePermissions');

/**
 * Returns true if the user making the request has the required permissions
 * in all courses which reference the given material.
 * @param {Context} context hook context
 * @param {ObjectId} id Id of the material
 * @param {Array<String>} permissions Array of required permissions
 * @returns {Boolean} true if conditions are met, false otherwise
 */
const hasMaterialAccess = async (context, id, permissions) => {
	const courses = await context.app.service('courses').find({
		query: {
			materialIds: id,
			$select: ['_id'],
		},
		paginate: false,
	});
	const access = courses.every((course) => {
		const scope = { id: course._id, name: 'courses' };
		const userPermisisons = getScopePermissions(context.app, context.params.account.userId, scope);
		return permissions.every((permission) => userPermisisons.includes(permission));
	});
	return access;
};

/**
 * Before-hook to enforce the requesting user has the required permisions in the course
 * the material is used in. If the material is used in multiple courses, the permissions
 * will be required in all of them.
 * @requires authenticate('jwt')
 * @param  {...String} permissions list of permissions necessary for this hook to resolve
 * @returns {Context} hook context
 */
const checkAssociatedCoursePermission = (...permissions) => async (context) => {
	if (permissions) {
		const access = await hasMaterialAccess(context, context.id, permissions);
		if (!access) {
			throw new Forbidden('No permision to edit this material');
		}
	}
	return context;
};

/**
 * After-hook to filter results of a find query to materials of courses the requesting user
 * has acces to. If a material is used in multiple courses, the permissions will be required
 * in all of them.
 * @requires authenticate('jwt')
 * @param  {...String} permissions list of permissions necessary for this hook to resolve
 * @returns {Context} hook context
 */
const checkAssociatedCoursePermissionForSearchResult = (...permissions) => async (context) => {
	if (permissions) {
		const results = context.result.data ? context.result.data : context.result;
		const filteredResults = [];
		for (const result of results) {
			if (await hasMaterialAccess(context, result._id, permissions)) {
				filteredResults.push(result);
			}
		}
		if (context.result.data) {
			context.result.data = filteredResults;
			context.result.length = filteredResults.length;
		} else {
			context.result = filteredResults;
		}
	}
	return context;
};

exports.before = {
	all: [
		authenticate('jwt'),
	],
	find: [
		// filtered in after-hook
	],
	get: [checkAssociatedCoursePermission('CONTENT_VIEW')],
	create: [
		// We don't have a course id or similar here, so we need to stick to global roles,
		// which is probably okay since the user will need edit rights in the course to add
		// the newly created material to it anyway.
		hasPermission('TOPIC_EDIT'),
	],
	update: [checkAssociatedCoursePermission('TOPIC_EDIT')],
	patch: [checkAssociatedCoursePermission('TOPIC_EDIT')],
	remove: [checkAssociatedCoursePermission('TOPIC_EDIT')],
};

exports.after = {
	all: [],
	find: [checkAssociatedCoursePermissionForSearchResult('CONTENT_VIEW')],
	get: [],
	create: [],
	update: [],
	patch: [],
	remove: [],
};
<commit_msg>Improve error message<commit_after>const { authenticate } = require('@feathersjs/authentication');
const { Forbidden } = require('@feathersjs/errors');
const { hasPermission } = require('../../../hooks');
const { getScopePermissions } = require('../../helpers/scopePermissions/hooks/checkScopePermissions');

/**
 * Returns true if the user making the request has the required permissions
 * in all courses which reference the given material.
 * @param {Context} context hook context
 * @param {ObjectId} id Id of the material
 * @param {Array<String>} permissions Array of required permissions
 * @returns {Boolean} true if conditions are met, false otherwise
 */
const hasMaterialAccess = async (context, id, permissions) => {
	const courses = await context.app.service('courses').find({
		query: {
			materialIds: id,
			$select: ['_id'],
		},
		paginate: false,
	});
	const access = courses.every((course) => {
		const scope = { id: course._id, name: 'courses' };
		const userPermisisons = getScopePermissions(context.app, context.params.account.userId, scope);
		return permissions.every((permission) => userPermisisons.includes(permission));
	});
	return access;
};

/**
 * Before-hook to enforce the requesting user has the required permisions in the course
 * the material is used in. If the material is used in multiple courses, the permissions
 * will be required in all of them.
 * @requires authenticate('jwt')
 * @param  {...String} permissions list of permissions necessary for this hook to resolve
 * @returns {Context} hook context
 */
const checkAssociatedCoursePermission = (...permissions) => async (context) => {
	if (permissions) {
		const access = await hasMaterialAccess(context, context.id, permissions);
		if (!access) {
			throw new Forbidden('No permision to access this material');
		}
	}
	return context;
};

/**
 * After-hook to filter results of a find query to materials of courses the requesting user
 * has acces to. If a material is used in multiple courses, the permissions will be required
 * in all of them.
 * @requires authenticate('jwt')
 * @param  {...String} permissions list of permissions necessary for this hook to resolve
 * @returns {Context} hook context
 */
const checkAssociatedCoursePermissionForSearchResult = (...permissions) => async (context) => {
	if (permissions) {
		const results = context.result.data ? context.result.data : context.result;
		const filteredResults = [];
		for (const result of results) {
			if (await hasMaterialAccess(context, result._id, permissions)) {
				filteredResults.push(result);
			}
		}
		if (context.result.data) {
			context.result.data = filteredResults;
			context.result.length = filteredResults.length;
		} else {
			context.result = filteredResults;
		}
	}
	return context;
};

exports.before = {
	all: [
		authenticate('jwt'),
	],
	find: [
		// filtered in after-hook
	],
	get: [checkAssociatedCoursePermission('CONTENT_VIEW')],
	create: [
		// We don't have a course id or similar here, so we need to stick to global roles,
		// which is probably okay since the user will need edit rights in the course to add
		// the newly created material to it anyway.
		hasPermission('TOPIC_EDIT'),
	],
	update: [checkAssociatedCoursePermission('TOPIC_EDIT')],
	patch: [checkAssociatedCoursePermission('TOPIC_EDIT')],
	remove: [checkAssociatedCoursePermission('TOPIC_EDIT')],
};

exports.after = {
	all: [],
	find: [checkAssociatedCoursePermissionForSearchResult('CONTENT_VIEW')],
	get: [],
	create: [],
	update: [],
	patch: [],
	remove: [],
};
<|endoftext|>


<commit_before>// Utility
if ( typeof Object.create !== 'function' ) {
	Object.create = function( obj ) {
		function F() {};
		F.prototype = obj;
		return new F();
	};
}

(function( $, window, document, undefined ) {
	var Webrtc = {
		init: function( options, elem ) {
			var self = this;

			self.elem = elem;
			self.$elem = $( elem );

			/*self.search = ( typeof options === 'string' )
				? options
				: options.search;*/

			//self.options = $.extend( {}, $.fn.createWebtc.options, options );

			console.log("Initializing");

		    self.localVideo = self.$elem.find('#localVideo');
		    self.remoteVideo = self.$elem.find('#remoteVideo');

		    self.connection = null;

		    self.openChannel();
		    self.getUserMedia();
		},

		openChannel: function() {
			var self = this;

			self.connection = new WebSocket('ws://localhost:8080/');

			// When the connection is open, send some data to the server
			self.connection.onopen = self.onChannelOpened.call(self);

			// Log errors
			self.connection.onerror = function (error) {
			console.log('WebSocket Error ' + error);
			}
			// Log messages from the server
			self.connection.onmessage = self.onChannelMessage;

			self.connection.onclose = self.onChannelClosed;
		},

		getUserMedia: function() {
			var self = this;
			try {
				navigator.webkitGetUserMedia("video,audio", self.onUserMediaSuccess, self.onUserMediaError);
				console.log("Requested access to local media.");
			} catch (e) {
				console.log("getUserMedia error.");
			}
		},

		onUserMediaSuccess: function(stream) {
			var self = this;

		    console.log("User has granted access to local media.");
		    var url = webkitURL.createObjectURL(stream);
		    self.localVideo.css("opacity", "1");
		    self.localVideo.attr("src", url);
		    self.localStream = stream;
		    if (self.guest) self.maybeStart();
		},

		onUserMediaError: function(error) {
		    console.log("Failed to get access to local media. Error code was " + error.code);
		    alert("Failed to get access to local media. Error code was " + error.code + ".");
		},

		maybeStart: function() {
			var self = this;

		    if (!self.started && self.localStream && self.channelReady) {
		        console.log("Creating PeerConnection.");
		        createPeerConnection();
		        console.log("Adding local stream.");
		        self.pc.addStream(localStream);
		        self.started = true;
		    }
		},

		createPeerConnection: function() {
			var self = this;

		    self.pc = new webkitPeerConnection("NONE", self.onSignalingMessage);
		    self.pc.onconnecting = self.onSessionConnecting;
		    self.pc.onopen = self.onSessionOpened;
		    self.pc.onaddstream = self.onRemoteStreamAdded;
		    self.pc.onremovestream = self.onRemoteStreamRemoved;
		},

		onSignalingMessage: function(message) {
		    console.log("onSignalingMessage " + message);
		    this.message = JSON.stringify({"type" : "SDP", "value" : message})
		    this.connection.send(this.message);
		},

		onHangup: function() {
		    var self = this;

		    console.log("Hanging up.");
		    self.localVideo.css("opacity", "0");
		    self.remoteVideo.css("opacity", "0");
		    self.pc.close();
		    self.pc = null;
		    self.connection.close();
		},

		onChannelOpened: function() {
		    var self = this;

		    console.log('Channel opened.');
		    self.channelReady = true;
		    if(location.search.substring(1,5) == "room") {
		      self.room = location.search.substring(6);
		      self.message = JSON.stringify({"type" : "INVITE", "value" : room});
		      console.log(self.message);
		      connection.send(self.message);
		      self.guest =1;
		    }
		    else{
		      self.message = JSON.stringify({"type" : "GETROOM", "value" : ""});
		      console.log(self.message);
		      self.connection.send(self.message);
		      self.guest =0;
		    }
		    if (self.guest) self.maybeStart();
		},

		onChannelMessage: function(message) {
		    var self = this;

		    self.message = JSON.parse(message.data);
		    console.log('S->C: ' + self.message["value"]);

		    switch(self.message["type"]) {
		      case "GETROOM" :
		        self.room = self.message["value"];
		        console.log(self.room);
		        self.guest = 0;
		      break;
		      case "SDP" :
		        if (self.message["value"].indexOf("\"ERROR\"", 0) == -1) {
		          if (!self.guest && !self.started) self.maybeStart();
		          self.pc.processSignalingMessage(self.message["value"]);
		        }
		      break;
		    }
		},

		onChannelBye: function() {
			var self = this;

		    console.log('Session terminated.');
		    self.remoteVideo.css("opacity", "0");
		    //self.remoteVideo.attr("src",null);
		    self.guest = 0;
		    self.started = false;
		},

		onChannelError: function() {
		    console.log('Channel error.');
		},

		onChannelClosed: function() {
		    console.log('Channel closed.');
		},

		onSessionConnecting: function(message) {
		    console.log("Session connecting.");
		},

		onSessionOpened: function(message) {
		    console.log("Session opened.");
		},

		onRemoteStreamAdded: function(event) {
		    console.log("Remote stream added.");
		    var url = webkitURL.createObjectURL(event.stream);
		    this.remoteVideo.css("opacity", "1");
		    this.remoteVideo.attr("src",url);
		},

		onRemoteStreamRemoved: function(event) {
		    console.log("Remote stream removed.");
		}
	};

	$.fn.createWebrtc = function( options ) {
		return this.each(function() {
			var webrtc = Object.create( Webrtc );

			webrtc.init( options, this );
		});
	};

	/*$.fn.createWebrtc.options = {
		search: '@tutspremium',
		wrapEachWith: '

',
		limit: 10,
		refresh: null,
		onComplete: null,
		transition: 'fadeToggle'
	};*/

})( jQuery, window, document );
<commit_msg>Plugin fonctionnel Structure en closure<commit_after>(function($){
	$.webRtc = function(elem) {
		var  self = this;
		self.$elem = $(elem);
		self.elem = elem;

		self.init = function() {
			console.log("Initializing");

		    self.localVideo = self.$elem.find('#localVideo');
		    self.remoteVideo = self.$elem.find('#remoteVideo');

		    self.connection = null;
		    self.pc = null;

		    self.openChannel();
		    self.getUserMedia();
		};

		self.openChannel = function() {

			self.connection = new WebSocket('ws://localhost:8080/');

			// When the connection is open, send some data to the server
			self.connection.onopen = self.onChannelOpened;

			// Log errors
			self.connection.onerror = function (error) {
			console.log('WebSocket Error ' + error);
			}
			// Log messages from the server
			self.connection.onmessage = self.onChannelMessage;

			self.connection.onclose = self.onChannelClosed;
		};

		self.getUserMedia = function() {
			try {
				navigator.webkitGetUserMedia("video,audio", self.onUserMediaSuccess,self.onUserMediaError);
				console.log("Requested access to local media.");
			} catch (e) {
				console.log("getUserMedia error.");
			}
		};

		self.onUserMediaSuccess = function(stream) {

		    console.log("User has granted access to local media.");
		    var url = webkitURL.createObjectURL(stream);
		    self.localVideo.css("opacity", "1");
		    self.localVideo.attr("src", url);
		    self.localStream = stream;
		    if (self.guest) self.maybeStart();
		};

		self.onUserMediaError = function(error) {
		    console.log("Failed to get access to local media. Error code was " + error.code);
		    alert("Failed to get access to local media. Error code was " + error.code + ".");
		};

		self.maybeStart = function() {
		    if (!self.started && self.localStream && self.channelReady) {
		        console.log("Creating PeerConnection.");
		        self.createPeerConnection();
		        console.log("Adding local stream.");
		        self.pc.addStream(self.localStream);
		        self.started = true;
		    }
		};

		self.createPeerConnection = function() {
		    self.pc = new webkitPeerConnection("NONE", self.onSignalingMessage);
		    self.pc.onconnecting = self.onSessionConnecting;
		    self.pc.onopen = self.onSessionOpened;
		    self.pc.onaddstream = self.onRemoteStreamAdded;
		    self.pc.onremovestream = self.onRemoteStreamRemoved;
		};

		self.onSignalingMessage = function(message) {
		    console.log("onSignalingMessage " + message);
		    self.message = JSON.stringify({"type" : "SDP", "value" : message})
		    self.connection.send(self.message);
		};

		self.onHangup = function() {
		    console.log("Hanging up.");
		    self.localVideo.css("opacity", "0");
		    self.remoteVideo.css("opacity", "0");
		    self.pc.close();
		    self.pc = null;
		    self.connection.close();
		};

		self.onChannelOpened = function() {
		    console.log('Channel opened.');
		    self.channelReady = true;
		    self.setGuest();
		    if (self.guest) self.maybeStart();
		};

		self.setGuest = function() {
			if(location.search.substring(1,5) == "room") {
		      self.room = location.search.substring(6);
		      self.message = JSON.stringify({"type" : "INVITE", "value" : self.room});
		      console.log(self.message);
		      self.connection.send(self.message);
		      self.guest =1;
		    }
		    else{
		      self.message = JSON.stringify({"type" : "GETROOM", "value" : ""});
		      console.log(self.message);
		      self.connection.send(self.message);
		      self.guest =0;
		    }
		}

		self.onChannelMessage = function(message) {

		    self.message = JSON.parse(message.data);
		    console.log('S->C: ' + self.message["value"]);

		    switch(self.message["type"]) {
		      case "GETROOM" :
		        self.room = self.message["value"];
		        console.log(self.room);
		        self.guest = 0;
		      break;
		      case "SDP" :
		        if (self.message["value"].indexOf("\"ERROR\"", 0) == -1) {
		          if (!self.guest && !self.started) self.maybeStart();
		          self.pc.processSignalingMessage(self.message["value"]);
		        }
		      break;
		    }
		};

		self.onChannelBye = function() {
		    console.log('Session terminated.');
		    self.remoteVideo.css("opacity", "0");
		    //self.remoteVideo.attr("src",null);
		    self.guest = 0;
		    self.started = false;
		};

		self.onChannelError = function() {
		    console.log('Channel error.');
		};

		self.onChannelClosed = function() {
		    console.log('Channel closed.');
		};

		self.onSessionConnecting = function(message) {
		    console.log("Session connecting.");
		};

		self.onSessionOpened = function(message) {
		    console.log("Session opened.");
		};

		self.onRemoteStreamAdded = function(event) {
		    console.log("Remote stream added.");
		    var url = webkitURL.createObjectURL(event.stream);
		    self.remoteVideo.css("opacity", "1");
		    self.remoteVideo.attr("src",url);
		};

		self.onRemoteStreamRemoved = function(event) {
		    console.log("Remote stream removed.");
		};

		self.init();

		return self;
	};

	$.fn.createWebrtc = function( options ) {
		return this.each(function() {
			(new $.webRtc(this));
		});
	};
})(jQuery);<|endoftext|>


<commit_before>/*
 * Fuel UX Wizard
 * https://github.com/ExactTarget/fuelux
 *
 * Copyright (c) 2014 ExactTarget
 * Licensed under the MIT license.
 */

// -- BEGIN UMD WRAPPER PREFACE --

// For more information on UMD visit:
// https://github.com/umdjs/umd/blob/master/jqueryPlugin.js

(function (factory) {
	if (typeof define === 'function' && define.amd) {
		// if AMD loader is available, register as an anonymous module.
		define(['jquery'], factory);
	} else {
		// OR use browser globals if AMD is not present
		factory(jQuery);
	}
}(function ($) {
	// -- END UMD WRAPPER PREFACE --

	// -- BEGIN MODULE CODE HERE --

	var old = $.fn.wizard;

	// WIZARD CONSTRUCTOR AND PROTOTYPE

	var Wizard = function (element, options) {
		var kids;

		this.$element = $(element);
		this.options = $.extend({}, $.fn.wizard.defaults, options);
		this.options.disablePreviousStep = ( this.$element.attr('data-restrict') === "previous" ) ? true : this.options.disablePreviousStep;
		this.currentStep = this.options.selectedItem.step;
		this.numSteps = this.$element.find('.steps li').length;
		this.$prevBtn = this.$element.find('button.btn-prev');
		this.$nextBtn = this.$element.find('button.btn-next');

		kids = this.$nextBtn.children().detach();
		this.nextText = $.trim(this.$nextBtn.text());
		this.$nextBtn.append(kids);

		// handle events
		this.$prevBtn.on('click.fu.wizard', $.proxy(this.previous, this));
		this.$nextBtn.on('click.fu.wizard', $.proxy(this.next, this));
		this.$element.on('click.fu.wizard', 'li.complete', $.proxy(this.stepclicked, this));

		this.selectedItem(this.options.selectedItem);

		if( this.options.disablePreviousStep ) {
			this.$prevBtn.attr( 'disabled', true );
			this.$element.find( '.steps' ).addClass( 'previous-disabled' );
		}
	};

	Wizard.prototype = {

		constructor: Wizard,

		//index is 1 based, remove is how many to remove after adding items
		//third parameter can be array of objects [{ ... }, { ... }] or you can pass n additional objects as args
		//object structure is as follows (all params are optional): { badge: '', label: '', pane: '' }
		addSteps: function(index, remove){
			var items = [].slice.call(arguments).slice(2);
			var $steps = this.$element.find('.steps');
			var $stepContent = this.$element.find('.step-content');
			var i, l, $pane, $startPane, $startStep, $step;

			remove = remove || 0;
			index = (index>(this.numSteps+1)) ? this.numSteps+1 : index;
			if(items[0] instanceof Array){
				items = items[0];
			}

			$startStep = $steps.find('li:nth-child(' + index + ')');
			$startPane = $stepContent.find('.step-pane:nth-child(' + index + ')');
			if($startStep.length<1){
				$startStep = null;
			}

			for(i=0, l=items.length; i<l; i++){
				$step = $('

');
				$step.append(items[i].label || '').append('');
				$step.find('.badge').append(items[i].badge || index);

				$pane = $('

');
				$pane.append(items[i].pane || '');

				if(!$startStep){
					$steps.append($step);
					$stepContent.append($pane);
				}else{
					$startStep.before($step);
					$startPane.before($pane);
				}
				index++;
			}

			if(remove>0){
				this.removeSteps(index, remove);
			}else{
				this.syncSteps();
				this.numSteps = $steps.find('li').length;
				this.setState();
			}
		},

		//index is 1 based, howMany is number to remove
		removeSteps: function(index, howMany){
			var action = 'nextAll';
			var i = 0;
			var $steps = this.$element.find('.steps');
			var $stepContent = this.$element.find('.step-content');
			var $start;

			howMany = (howMany!==undefined) ? howMany : 1;

			if(index>$steps.find('li').length){
				$start = $steps.find('li:last');
			}else{
				$start = $steps.find('li:nth-child(' + index + ')').prev();
				if($start.length<1){
					action = 'children';
					$start = $steps;
				}
			}

			$start[action]().each(function(){
				var item = $(this);
				var step = item.attr('data-step');
				if(i<howMany){
					item.remove();
					$stepContent.find('.step-pane[data-step="' + step + '"]:first').remove();
				}else{
					return false;
				}
				i++;
			});

			this.syncSteps();
			this.numSteps = $steps.find('li').length;
			this.setState();
		},

		setState: function () {
			var canMovePrev = (this.currentStep > 1);
			var firstStep = (this.currentStep === 1);
			var lastStep = (this.currentStep === this.numSteps);

			// disable buttons based on current step
			if( !this.options.disablePreviousStep ) {
				this.$prevBtn.attr('disabled', (firstStep === true || canMovePrev === false));
			}

			// change button text of last step, if specified
			var last = this.$nextBtn.attr('data-last');
			if (last) {
				this.lastText = last;
				// replace text
				var text = (lastStep !== true) ? this.nextText : this.lastText;
				var kids = this.$nextBtn.children().detach();
				this.$nextBtn.text(text).append(kids);
			}

			// reset classes for all steps
			var $steps = this.$element.find('.steps li');
			$steps.removeClass('active').removeClass('complete');
			$steps.find('span.badge').removeClass('badge-info').removeClass('badge-success');

			// set class for all previous steps
			var prevSelector = '.steps li:lt(' + (this.currentStep - 1) + ')';
			var $prevSteps = this.$element.find(prevSelector);
			$prevSteps.addClass('complete');
			$prevSteps.find('span.badge').addClass('badge-success');

			// set class for current step
			var currentSelector = '.steps li:eq(' + (this.currentStep - 1) + ')';
			var $currentStep = this.$element.find(currentSelector);
			$currentStep.addClass('active');
			$currentStep.find('span.badge').addClass('badge-info');

			// set display of target element
			var $stepContent = this.$element.find('.step-content');
			var target = $currentStep.attr('data-step');
			$stepContent.find('.step-pane').removeClass('active');
			$stepContent.find('.step-pane[data-step="' + target + '"]:first').addClass('active');

			// reset the wizard position to the left
			this.$element.find('.steps').first().attr('style','margin-left: 0');

			// check if the steps are wider than the container div
			var totalWidth = 0;
			this.$element.find('.steps > li').each(function () {
				totalWidth += $(this).outerWidth();
			});
			var containerWidth = 0;
			if (this.$element.find('.actions').length) {
				containerWidth = this.$element.width() - this.$element.find('.actions').first().outerWidth();
			} else {
				containerWidth = this.$element.width();
			}
			if (totalWidth > containerWidth) {

				// set the position so that the last step is on the right
				var newMargin = totalWidth - containerWidth;
				this.$element.find('.steps').first().attr('style','margin-left: -' + newMargin + 'px');

				// set the position so that the active step is in a good
				// position if it has been moved out of view
				if (this.$element.find('li.active').first().position().left < 200) {
					newMargin += this.$element.find('li.active').first().position().left - 200;
					if (newMargin < 1) {
						this.$element.find('.steps').first().attr('style','margin-left: 0');
					} else {
						this.$element.find('.steps').first().attr('style','margin-left: -' + newMargin + 'px');
					}
				}
			}

			this.$element.trigger('changed.fu.wizard');
		},

		stepclicked: function (e) {
			var li          = $(e.currentTarget);
			var index       = this.$element.find('.steps li').index(li);
			var canMovePrev = true;

			if( this.options.disablePreviousStep ) {
				if( index < this.currentStep ) {
					canMovePrev = false;
				}
			}

			if( canMovePrev ) {
				var evt = $.Event('stepclick.fu.wizard');
				this.$element.trigger(evt, {step: index + 1});
				if (evt.isDefaultPrevented()) { return; }

				this.currentStep = (index + 1);
				this.setState();
			}
		},

		syncSteps: function(){
			var i = 1;
			var $steps = this.$element.find('.steps');
			var $stepContent = this.$element.find('.step-content');

			$steps.children().each(function(){
				var item = $(this);
				var badge = item.find('.badge');
				var step = item.attr('data-step');

				if(!isNaN(parseInt(badge.html(), 10))){
					badge.html(i);
				}
				item.attr('data-step', i);
				$stepContent.find('.step-pane[data-step="' + step + '"]:last').attr('data-step', i);
				i++;
			});
		},

		previous: function () {
			var canMovePrev = (this.currentStep > 1);
			if( this.options.disablePreviousStep ) {
				canMovePrev = false;
			}
			if (canMovePrev) {
				var e = $.Event('changed.fu.wizard');
				this.$element.trigger(e, {step: this.currentStep, direction: 'previous'});
				if (e.isDefaultPrevented()) { return; }

				this.currentStep -= 1;
				this.setState();
			}
		},

		next: function () {
			var canMoveNext = (this.currentStep + 1 <= this.numSteps);
			var lastStep = (this.currentStep === this.numSteps);

			if (canMoveNext) {
				var e = $.Event('change.fu.wizard');
				this.$element.trigger(e, {step: this.currentStep, direction: 'next'});

				if (e.isDefaultPrevented()) { return; }

				this.currentStep += 1;
				this.setState();
			}
			else if (lastStep) {
				this.$element.trigger('finished.fu.wizard');
			}
		},

		selectedItem: function (selectedItem) {
			var retVal, step;

			if(selectedItem) {

				step = selectedItem.step || -1;

				if(step >= 1 && step <= this.numSteps) {
					this.currentStep = step;
					this.setState();
				}else{
					step = this.$element.find('.steps li.active:first').attr('data-step');
					if(!isNaN(step)){
						this.currentStep = parseInt(step, 10);
						this.setState();
					}
				}

				retVal = this;
			}
			else {
				retVal = { step: this.currentStep };
			}

			return retVal;
		}
	};

	// WIZARD PLUGIN DEFINITION

	$.fn.wizard = function (option) {
		var args = Array.prototype.slice.call( arguments, 1 );
		var methodReturn;

		var $set = this.each(function () {
			var $this   = $( this );
			var data    = $this.data( 'wizard' );
			var options = typeof option === 'object' && option;

			if( !data ) $this.data('wizard', (data = new Wizard( this, options ) ) );
			if( typeof option === 'string' ) methodReturn = data[ option ].apply( data, args );
		});

		return ( methodReturn === undefined ) ? $set : methodReturn;
	};

	$.fn.wizard.defaults = {
		disablePreviousStep: false,
		selectedItem: { step: -1 }	//-1 means it will attempt to look for "active" class in order to set the step
	};

	$.fn.wizard.Constructor = Wizard;

	$.fn.wizard.noConflict = function () {
		$.fn.wizard = old;
		return this;
	};

	// DATA-API

	$(document).on('mouseover.fu.wizard.data-api', '[data-initialize=wizard]', function (e) {
		var $control = $(e.target).closest('.wizard');
		if ( !$control.data('wizard') ) {
			$control.wizard($control.data());
		}
	});

	// Must be domReady for AMD compatibility
	$(function () {
		$('[data-initialize=wizard]').each(function () {
			var $this = $(this);
			if ($this.data('wizard')) return;
			$this.wizard($this.data());
		});
	});

// -- BEGIN UMD WRAPPER AFTERWORD --
}));
	// -- END UMD WRAPPER AFTERWORD --<commit_msg>Make wizard not trigger 'changed' on init, add complete class<commit_after>/*
 * Fuel UX Wizard
 * https://github.com/ExactTarget/fuelux
 *
 * Copyright (c) 2014 ExactTarget
 * Licensed under the MIT license.
 */

// -- BEGIN UMD WRAPPER PREFACE --

// For more information on UMD visit:
// https://github.com/umdjs/umd/blob/master/jqueryPlugin.js

(function (factory) {
	if (typeof define === 'function' && define.amd) {
		// if AMD loader is available, register as an anonymous module.
		define(['jquery'], factory);
	} else {
		// OR use browser globals if AMD is not present
		factory(jQuery);
	}
}(function ($) {
	// -- END UMD WRAPPER PREFACE --

	// -- BEGIN MODULE CODE HERE --

	var old = $.fn.wizard;

	// WIZARD CONSTRUCTOR AND PROTOTYPE

	var Wizard = function (element, options) {
		var kids;

		this.$element = $(element);
		this.options = $.extend({}, $.fn.wizard.defaults, options);
		this.options.disablePreviousStep = ( this.$element.attr('data-restrict') === "previous" ) ? true : this.options.disablePreviousStep;
		this.currentStep = this.options.selectedItem.step;
		this.numSteps = this.$element.find('.steps li').length;
		this.$prevBtn = this.$element.find('button.btn-prev');
		this.$nextBtn = this.$element.find('button.btn-next');

		kids = this.$nextBtn.children().detach();
		this.nextText = $.trim(this.$nextBtn.text());
		this.$nextBtn.append(kids);

		// handle events
		this.$prevBtn.on('click.fu.wizard', $.proxy(this.previous, this));
		this.$nextBtn.on('click.fu.wizard', $.proxy(this.next, this));
		this.$element.on('click.fu.wizard', 'li.complete', $.proxy(this.stepclicked, this));

		this.selectedItem(this.options.selectedItem);

		this.initialized = 'undefined'; // flag set on first state change of step

		if( this.options.disablePreviousStep ) {
			this.$prevBtn.attr( 'disabled', true );
			this.$element.find( '.steps' ).addClass( 'previous-disabled' );
		}
	};

	Wizard.prototype = {

		constructor: Wizard,

		//index is 1 based, remove is how many to remove after adding items
		//third parameter can be array of objects [{ ... }, { ... }] or you can pass n additional objects as args
		//object structure is as follows (all params are optional): { badge: '', label: '', pane: '' }
		addSteps: function(index, remove){
			var items = [].slice.call(arguments).slice(2);
			var $steps = this.$element.find('.steps');
			var $stepContent = this.$element.find('.step-content');
			var i, l, $pane, $startPane, $startStep, $step;

			remove = remove || 0;
			index = (index>(this.numSteps+1)) ? this.numSteps+1 : index;
			if(items[0] instanceof Array){
				items = items[0];
			}

			$startStep = $steps.find('li:nth-child(' + index + ')');
			$startPane = $stepContent.find('.step-pane:nth-child(' + index + ')');
			if($startStep.length<1){
				$startStep = null;
			}

			for(i=0, l=items.length; i<l; i++){
				$step = $('

');
				$step.append(items[i].label || '').append('');
				$step.find('.badge').append(items[i].badge || index);

				$pane = $('

');
				$pane.append(items[i].pane || '');

				if(!$startStep){
					$steps.append($step);
					$stepContent.append($pane);
				}else{
					$startStep.before($step);
					$startPane.before($pane);
				}
				index++;
			}

			if(remove>0){
				this.removeSteps(index, remove);
			}else{
				this.syncSteps();
				this.numSteps = $steps.find('li').length;
				this.setState();
			}
		},

		//index is 1 based, howMany is number to remove
		removeSteps: function(index, howMany){
			var action = 'nextAll';
			var i = 0;
			var $steps = this.$element.find('.steps');
			var $stepContent = this.$element.find('.step-content');
			var $start;

			howMany = (howMany!==undefined) ? howMany : 1;

			if(index>$steps.find('li').length){
				$start = $steps.find('li:last');
			}else{
				$start = $steps.find('li:nth-child(' + index + ')').prev();
				if($start.length<1){
					action = 'children';
					$start = $steps;
				}
			}

			$start[action]().each(function(){
				var item = $(this);
				var step = item.attr('data-step');
				if(i<howMany){
					item.remove();
					$stepContent.find('.step-pane[data-step="' + step + '"]:first').remove();
				}else{
					return false;
				}
				i++;
			});

			this.syncSteps();
			this.numSteps = $steps.find('li').length;
			this.setState();
		},

		setState: function () {
			var canMovePrev = (this.currentStep > 1);
			var firstStep = (this.currentStep === 1);
			var lastStep = (this.currentStep === this.numSteps);

			// disable buttons based on current step
			if( !this.options.disablePreviousStep ) {
				this.$prevBtn.attr('disabled', (firstStep === true || canMovePrev === false));
			}

			// change button text of last step, if specified
			var last = this.$nextBtn.attr('data-last');
			if (last) {
				this.lastText = last;
				// replace text
				var text = this.nextText;
				if ( lastStep === true ) {
					text = this.lastText;
					// add status class to wizard
					this.$element.addClass('complete');
				}
				else {
					this.$element.removeClass('complete');
				}
				var kids = this.$nextBtn.children().detach();
				this.$nextBtn.text(text).append(kids);
			}

			// reset classes for all steps
			var $steps = this.$element.find('.steps li');
			$steps.removeClass('active').removeClass('complete');
			$steps.find('span.badge').removeClass('badge-info').removeClass('badge-success');

			// set class for all previous steps
			var prevSelector = '.steps li:lt(' + (this.currentStep - 1) + ')';
			var $prevSteps = this.$element.find(prevSelector);
			$prevSteps.addClass('complete');
			$prevSteps.find('span.badge').addClass('badge-success');

			// set class for current step
			var currentSelector = '.steps li:eq(' + (this.currentStep - 1) + ')';
			var $currentStep = this.$element.find(currentSelector);
			$currentStep.addClass('active');
			$currentStep.find('span.badge').addClass('badge-info');

			// set display of target element
			var $stepContent = this.$element.find('.step-content');
			var target = $currentStep.attr('data-step');
			$stepContent.find('.step-pane').removeClass('active');
			$stepContent.find('.step-pane[data-step="' + target + '"]:first').addClass('active');

			// reset the wizard position to the left
			this.$element.find('.steps').first().attr('style','margin-left: 0');

			// check if the steps are wider than the container div
			var totalWidth = 0;
			this.$element.find('.steps > li').each(function () {
				totalWidth += $(this).outerWidth();
			});
			var containerWidth = 0;
			if (this.$element.find('.actions').length) {
				containerWidth = this.$element.width() - this.$element.find('.actions').first().outerWidth();
			} else {
				containerWidth = this.$element.width();
			}
			if (totalWidth > containerWidth) {

				// set the position so that the last step is on the right
				var newMargin = totalWidth - containerWidth;
				this.$element.find('.steps').first().attr('style','margin-left: -' + newMargin + 'px');

				// set the position so that the active step is in a good
				// position if it has been moved out of view
				if (this.$element.find('li.active').first().position().left < 200) {
					newMargin += this.$element.find('li.active').first().position().left - 200;
					if (newMargin < 1) {
						this.$element.find('.steps').first().attr('style','margin-left: 0');
					} else {
						this.$element.find('.steps').first().attr('style','margin-left: -' + newMargin + 'px');
					}
				}
			}

			console.log('state change');

			// only fire changed event after initializing
			if(typeof(this.initialized) !== 'undefined' ) {
				this.$element.trigger('changed.fu.wizard');
			}

			this.initialized = true;
		},

		stepclicked: function (e) {
			var li          = $(e.currentTarget);
			var index       = this.$element.find('.steps li').index(li);
			var canMovePrev = true;

			if( this.options.disablePreviousStep ) {
				if( index < this.currentStep ) {
					canMovePrev = false;
				}
			}

			if( canMovePrev ) {
				var evt = $.Event('stepclick.fu.wizard');
				this.$element.trigger(evt, {step: index + 1});
				if (evt.isDefaultPrevented()) { return; }

				this.currentStep = (index + 1);
				this.setState();
			}
		},

		syncSteps: function(){
			var i = 1;
			var $steps = this.$element.find('.steps');
			var $stepContent = this.$element.find('.step-content');

			$steps.children().each(function(){
				var item = $(this);
				var badge = item.find('.badge');
				var step = item.attr('data-step');

				if(!isNaN(parseInt(badge.html(), 10))){
					badge.html(i);
				}
				item.attr('data-step', i);
				$stepContent.find('.step-pane[data-step="' + step + '"]:last').attr('data-step', i);
				i++;
			});
		},

		previous: function () {
			var canMovePrev = (this.currentStep > 1);
			if( this.options.disablePreviousStep ) {
				canMovePrev = false;
			}
			if (canMovePrev) {
				// var e = $.Event('changed.fu.wizard');
				// this.$element.trigger(e, {step: this.currentStep, direction: 'previous'});
				// if (e.isDefaultPrevented()) { return; }

				this.currentStep -= 1;
				this.setState();
			}
		},

		next: function () {
			var canMoveNext = (this.currentStep + 1 <= this.numSteps);
			var lastStep = (this.currentStep === this.numSteps);

			if (canMoveNext) {
				var e = $.Event('change.fu.wizard');
				this.$element.trigger(e, {step: this.currentStep, direction: 'next'});

				if (e.isDefaultPrevented()) { return; }

				this.currentStep += 1;
				this.setState();
			}
			else if (lastStep) {
				this.$element.trigger('finished.fu.wizard');
			}
		},

		selectedItem: function (selectedItem) {
			var retVal, step;

			if(selectedItem) {

				step = selectedItem.step || -1;

				if(step >= 1 && step <= this.numSteps) {
					this.currentStep = step;
					this.setState();
				}else{
					step = this.$element.find('.steps li.active:first').attr('data-step');
					if(!isNaN(step)){
						this.currentStep = parseInt(step, 10);
						this.setState();
					}
				}

				retVal = this;
			}
			else {
				retVal = { step: this.currentStep };
			}

			return retVal;
		}
	};

	// WIZARD PLUGIN DEFINITION

	$.fn.wizard = function (option) {
		var args = Array.prototype.slice.call( arguments, 1 );
		var methodReturn;

		var $set = this.each(function () {
			var $this   = $( this );
			var data    = $this.data( 'wizard' );
			var options = typeof option === 'object' && option;

			if( !data ) $this.data('wizard', (data = new Wizard( this, options ) ) );
			if( typeof option === 'string' ) methodReturn = data[ option ].apply( data, args );
		});

		return ( methodReturn === undefined ) ? $set : methodReturn;
	};

	$.fn.wizard.defaults = {
		disablePreviousStep: false,
		selectedItem: { step: -1 }	//-1 means it will attempt to look for "active" class in order to set the step
	};

	$.fn.wizard.Constructor = Wizard;

	$.fn.wizard.noConflict = function () {
		$.fn.wizard = old;
		return this;
	};

	// DATA-API

	$(document).on('mouseover.fu.wizard.data-api', '[data-initialize=wizard]', function (e) {
		var $control = $(e.target).closest('.wizard');
		if ( !$control.data('wizard') ) {
			$control.wizard($control.data());
		}
	});

	// Must be domReady for AMD compatibility
	$(function () {
		$('[data-initialize=wizard]').each(function () {
			var $this = $(this);
			if ($this.data('wizard')) return;
			$this.wizard($this.data());
		});
	});

// -- BEGIN UMD WRAPPER AFTERWORD --
}));
	// -- END UMD WRAPPER AFTERWORD --<|endoftext|>


<commit_before>// (function () {

  //Goal: Create a game wherein the player and friendly NPC try to escape from zombies.

  var game = {
    zombies: [],
    humans: [],
    survivors: [],
    players: [],
    escapees: [],
    badThings:[
      "tripped and fell",
      "took a wrong turn",
      "is frozen in fear",
      "doesn't know which way to go",
      "got caught in some brambles",
      "is freaking out",
    ],
    distance: 100,
    $console: $("#console ul"),
    $dialogText: $("#dialogText"),

    consoleLog: function (text) {
      game.$console.append("
" + text + "
");
      console.log(text);
    },

    consoleClear: function () {
      //Update arrays and clears game console.
      game.updateHumans();
      game.$console.children().remove();
    },

    createZombies: function (number, position, givenName) {
      var i, name;
      for (i = 0; i < number; i++) {
        if (givenName) {
          name = givenName[i];
        } else {
          name = game.zombies.length + 1;
          name = "Zombie " + name;
        }
        game.zombies.push(new Zombie(name, position));
      }
    },

    createSurvivors: function (number, position, givenName) {
      var i, name;
      for (i = 0; i < number; i++) {
        if (givenName) {
          name = givenName[i];
        } else {
          name = game.survivors.length + 1;
          name = "Survivor " + name;
        }
        game.survivors.push(new Human(name, position));
      }
    },

    createPlayer: function (name, position, speed, focus) {
      game.players.push(new Player(name, position, speed, focus));
    },

    createGame: function (args) {
      //Initialize Values
      game.zombies = [];
      game.humans = [];
      game.survivors = [];
      game.players = [];
      game.escapees = [];

      //Create Participants
      game.createZombies(3);
      game.createSurvivors(3, 10, ["Jonathan", "Heather", "Josh"]);
      game.createPlayer("Maria", 10, 8, 4);
      game.updateHumans();

      //Delete HTML Console

      game.$console.children().remove();
    },

    updateHumans: function () {
      game.humans = game.players.concat(game.survivors);
    },

    turn: {
      full: function () {
        game.consoleClear();
        game.turn.player();
        game.turn.npc();
      },

      npc: function () {
        game.turn.survivor();
        game.turn.zombie();
      },

      player: function () {
        for (var i = 0; i < game.players.length; i++) {
          game.players[i].takeTurn();
          game.players[i].checkPlayerStatus();
        }
      },

      survivor: function () {
        var i, j, message;
        for (i = 0; i < game.survivors.length; i++) {
          game.survivors[i].checkStatus(i);
          if (game.survivors[i]) {
            game.survivors[i].takeTurn(i);
          }
        }
      },

      zombie: function () {
        var i, j, message;
        for (i = 0; i < game.zombies.length; i++) {
          game.zombies[i].takeTurn(i);
          //check if at position of survivor
          for (j = 0; j < game.humans.length; j++) {
            if (game.zombies[i].position == game.humans[j].position) {
              message = "Brains! " + game.zombies[i].name + " caught " + game.humans[j].name + "!";
              game.consoleLog(message);
              game.zombies[i].bite(game.humans[j]);
            }
          }
        }
      }
    },
  };

  function Biped () {
    this.exhausted = false;
    this.state = "stopped";
    this.position = 0;
  }

  Biped.prototype = {
    report: function () {
      var reportText = this.name + " " + this.state + " at " + this.position + ".";
      console.log(reportText);
      game.$console.append(this.toHTML(reportText));
      return reportText;
    },
    toHTML: function (text) {
      return "
" + text + "
";
    },
    move: function (faster) {
      var currentSpeed;
      if (faster) {
        currentSpeed = this.speed * faster;
        this.state = "is running";
      } else if (this.exhausted) {
        currentSpeed = this.speed / 4;
        this.state = "is exhausted";
        this.exhausted = false;
      } else {
        currentSpeed = this.speed;
        this.state = "is walking";
      }
      if (faster || this.focus > randomNumberIn(10)) {
        this.position += currentSpeed;
      } else {
        this.state = game.badThings[randomNumberIn(game.badThings.length)];
      }
    },
    constructor: Biped
  };

  function Zombie (name, position) {
    this.name = name;
    this.speed = 2;
    this.focus = 10;
    if (position) {
      this.position = position;
    }
  }

  Zombie.prototype = new Biped();
  Zombie.prototype.bite = function (victim) {
    //Bites a chosen victim
    var message, random = randomNumberIn(10);

    if (victim.shot || random > 2) {
      victim.bitten++;
      message = this.name + " bites " + victim.name + "! ";
    } else {
      message = victim.name + " narrowly escapes, and ";
    }
    if (!victim.shot) {
      victim.run();
      message += victim.name + " runs to "+ victim.position + " in terror!";
    }
    if (victim instanceof Player) {
      victim.dies(this);
    }
    game.consoleLog(message);
  };
  Zombie.prototype.takeTurn = function () {
    if (!this.shot) {
      this.move();
    }
    this.report();
  };

  function Human (name, position, speed, focus) {
    this.name = name;
    this.speed = speed || 8;
    this.focus = focus || 4;
    this.position = position || 10;
    this.escaped = false;
    this.bitten = 0;
    this.shot = false;
    this.noiseLevel = 4;
    this.inventory = {
      gun: true,
      bullets: randomNumberIn(3)
    };
  }

  Human.prototype = new Biped();
  Human.prototype.run = function (argument) {
    this.move(2);
    this.exhausted = true;
  };
  Human.prototype.checkStatus = function (suvivorIndex) {
    if (this.escaped || this.position >= game.distance) {
      if (!this.escaped) {
        this.escaped = true;
        game.escapees.push(this);
        this.state = "is waiting at the city limits";
      }
    } else {
      if (this.bitten || this.shot) {
        var random = randomNumberIn(10);
        console.log("Random was " + random + ".");
        if (random > 7 - this.bitten) {
          this.zombify(suvivorIndex);
        }
      }
    }

  };
  Human.prototype.zombify = function (suvivorIndex) {
    game.consoleLog(this.name + " became a zombie!");
    game.createZombies(1, this.position, ["Zombified " + this.name]);
    game.survivors.splice(suvivorIndex, 1);
    game.updateHumans();
  };
  Human.prototype.search = function (target) {
    var message, thisStuff = this.inventory.bullets, theirStuff = target.inventory.bullets;

    message = this.name + " searches " + target.name + ", and ";
    if (theirStuff) {
      this.inventory.bullets += target.inventory.bullets;
      target.inventory.bullets = 0;
      message += "finds " + theirStuff + " bullets!";
    } else {
      message += "finds nothing!";
    }
    game.consoleLog(message);
    game.turn.npc();
  };
  Human.prototype.takeTurn = function () {
    if (!this.shot && !this.escaped) {
      this.move();
      // this.checkStatus();
    }
    this.report();
  };

  function Player (name, position, speed, focus) {
    this.name = name;
    this.speed = speed || 8;
    this.focus = focus || 4;
    this.position = position || 10;
    this.inventory = {
      gun: true,
      bullets: 3
    };
  }

  Player.prototype = new Human();
  Player.prototype.sneak = function (argument) {
    this.move(0.5);
    this.noiseLevel = 0;
  };
  Player.prototype.shootAt = function (targetIndex) {
    var message, victim, random = randomNumberIn(10);

    if (this.inventory.bullets) {
      message = "Bang! ";
      this.inventory.bullets--;
      if (random > 7) {
        message += this.name + " killed " + game.zombies[targetIndex].name + "!";
        game.zombies.splice(targetIndex, 1);
      } else if (random >= 1) {
        message += this.name + " misses wildly!";
      } else {
        victim = game.survivors[randomNumberIn(game.survivors.length)];
        message += this.name + " accidentally shot " + victim.name + "! ";
        victim.shot = true;
        victim.speed = 0;
        victim.state = "is dead";
      }
    } else {
      message = "Click! " + this.name + "\'s gun is empty!";
    }
    game.consoleLog(message);
    this.state = "is stopped";
    this.report();
  };
  Player.prototype.checkPlayerStatus = function () {
    if (this.bitten) {
      this.dies();
    } else if (this.position >= game.distance) {
      this.wins();
    }
  };
  Player.prototype.dies = function (fromKiller) {
    var toggleBackground = function () {
      $("#approachImage").hide();
      $("#backgroundImage").toggleClass("overrun");
      $("#youDied").show();
      $(".startGame").show();
    };
    $(".playingGame").hide();
    game.consoleLog(this.name + " dies.");
    game.$console.slideToggle();
    game.$dialogText.text(fromKiller.name + " got " + this.name + "!");
    $("#approachImage")
      .animate({"opacity": "1", "width": "100%"}, "300");
    setTimeout(toggleBackground, [400]);
  };
  Player.prototype.wins = function () { //still has a formatting bug with commas.
    var i, message = "";

    if (game.escapees.length > 1) {
      if (game.escapees.length == 2) {
        message = game.escapees[0].name + " and " + game.escapees[1].name;
        } else {
          var lastMemberIndex = game.escapees.length - 1;
          for (i = 0; i < lastMemberIndex; i++) {
            message += game.escapees[i].name + ", ";
          }
          message += "and " + game.escapees[lastMemberIndex].name;
        }
    }

    message += " escaped from the city alive!";

    game.consoleLog(this.name + " wins.");
    game.$console.slideToggle();
    game.$dialogText.text(message);
    $("#youWon").show();
    $("#backgroundImage").toggleClass("roadClosed");
    $(".playingGame").hide();
    $(".startGame").show();
  };

  function Location (argument) {
    this.name = name;
    this.position = position;
    this.details = details;
    this.inventory = inventory;
  }

  function randomNumberIn (numberSet) {
    return Math.floor(Math.random() * numberSet);
  }

  /*************************
  Image Preload
  **************************/

  $(function () {
    var $preloadContainer = $(document.createElement('span'));
    var $backgroundImage = $("#backgroundImage");

    $($preloadContainer)
      .attr("id", "preload")
      .appendTo($backgroundImage);
  });

  /*************************
  Event Listeners
  **************************/

  //Click handler for startButton.
  $("#startButton").on("click", function (e) {
    e.preventDefault();

    if ($(this).hasClass("newGame")) {
      $("#backgroundImage").removeClass("roadClosed overrun");
      $("#approachImage").removeAttr("style");
      $(".endgame").hide();
    }

    $(this)
      .text("Start New Game")
      .addClass("newGame")
      .hide();
    game.createGame();
    $(".playingGame").show();
    game.$console.slideToggle(200);

    game.turn.full();
  });

  //Click handler for moveButton.
  $("#moveButton").on("click", function (e) {
    e.preventDefault();
    game.consoleClear();
    game.turn.full();
  });

  //Click handler for playerShoots.
  $("#playerShoots").on("click", function (e) {
    e.preventDefault();
    game.consoleClear();
    game.players[0].shootAt(0);
    game.turn.npc();
  });

  //Click handler for playerDeath button.
  $("#playerDeath").on("click", function (e) {
    e.preventDefault();
    game.players[0].dies();
  });

// }()); //End of IIFE
<commit_msg>Fixed another bug with endgame display.<commit_after>// (function () {

  //Goal: Create a game wherein the player and friendly NPC try to escape from zombies.

  var game = {
    zombies: [],
    humans: [],
    survivors: [],
    players: [],
    escapees: [],
    badThings:[
      "tripped and fell",
      "took a wrong turn",
      "is frozen in fear",
      "doesn't know which way to go",
      "got caught in some brambles",
      "is freaking out",
    ],
    distance: 100,
    $console: $("#console ul"),
    $dialogText: $("#dialogText"),

    consoleLog: function (text) {
      game.$console.append("
" + text + "
");
      console.log(text);
    },

    consoleClear: function () {
      //Update arrays and clears game console.
      game.updateHumans();
      game.$console.children().remove();
    },

    createZombies: function (number, position, givenName) {
      var i, name;
      for (i = 0; i < number; i++) {
        if (givenName) {
          name = givenName[i];
        } else {
          name = game.zombies.length + 1;
          name = "Zombie " + name;
        }
        game.zombies.push(new Zombie(name, position));
      }
    },

    createSurvivors: function (number, position, givenName) {
      var i, name;
      for (i = 0; i < number; i++) {
        if (givenName) {
          name = givenName[i];
        } else {
          name = game.survivors.length + 1;
          name = "Survivor " + name;
        }
        game.survivors.push(new Human(name, position));
      }
    },

    createPlayer: function (name, position, speed, focus) {
      game.players.push(new Player(name, position, speed, focus));
    },

    createGame: function (args) {
      //Initialize Values
      game.zombies = [];
      game.humans = [];
      game.survivors = [];
      game.players = [];
      game.escapees = [];

      //Create Participants
      game.createZombies(3);
      game.createSurvivors(3, 10, ["Jonathan", "Heather", "Josh"]);
      game.createPlayer("Maria", 10, 8, 4);
      game.updateHumans();

      //Delete HTML Console

      game.$console.children().remove();
    },

    updateHumans: function () {
      game.humans = game.players.concat(game.survivors);
    },

    turn: {
      full: function () {
        game.consoleClear();
        game.turn.player();
        game.turn.npc();
      },

      npc: function () {
        game.turn.survivor();
        game.turn.zombie();
      },

      player: function () {
        for (var i = 0; i < game.players.length; i++) {
          game.players[i].takeTurn();
          game.players[i].checkPlayerStatus();
        }
      },

      survivor: function () {
        var i, j, message;
        for (i = 0; i < game.survivors.length; i++) {
          game.survivors[i].checkStatus(i);
          if (game.survivors[i]) {
            game.survivors[i].takeTurn(i);
          }
        }
      },

      zombie: function () {
        var i, j, message;
        for (i = 0; i < game.zombies.length; i++) {
          game.zombies[i].takeTurn(i);
          //check if at position of survivor
          for (j = 0; j < game.humans.length; j++) {
            if (game.zombies[i].position == game.humans[j].position) {
              message = "Brains! " + game.zombies[i].name + " caught " + game.humans[j].name + "!";
              game.consoleLog(message);
              game.zombies[i].bite(game.humans[j]);
            }
          }
        }
      }
    },
  };

  function Biped () {
    this.exhausted = false;
    this.state = "stopped";
    this.position = 0;
  }

  Biped.prototype = {
    report: function () {
      var reportText = this.name + " " + this.state + " at " + this.position + ".";
      console.log(reportText);
      game.$console.append(this.toHTML(reportText));
      return reportText;
    },
    toHTML: function (text) {
      return "
" + text + "
";
    },
    move: function (faster) {
      var currentSpeed;
      if (faster) {
        currentSpeed = this.speed * faster;
        this.state = "is running";
      } else if (this.exhausted) {
        currentSpeed = this.speed / 4;
        this.state = "is exhausted";
        this.exhausted = false;
      } else {
        currentSpeed = this.speed;
        this.state = "is walking";
      }
      if (faster || this.focus > randomNumberIn(10)) {
        this.position += currentSpeed;
      } else {
        this.state = game.badThings[randomNumberIn(game.badThings.length)];
      }
    },
    constructor: Biped
  };

  function Zombie (name, position) {
    this.name = name;
    this.speed = 2;
    this.focus = 10;
    if (position) {
      this.position = position;
    }
  }

  Zombie.prototype = new Biped();
  Zombie.prototype.bite = function (victim) {
    //Bites a chosen victim
    var message, random = randomNumberIn(10);

    if (victim.shot || random > 2) {
      victim.bitten++;
      message = this.name + " bites " + victim.name + "! ";
    } else {
      message = victim.name + " narrowly escapes, and ";
    }
    if (!victim.shot) {
      victim.run();
      message += victim.name + " runs to "+ victim.position + " in terror!";
    }
    if (victim instanceof Player) {
      victim.dies(this);
    }
    game.consoleLog(message);
  };
  Zombie.prototype.takeTurn = function () {
    if (!this.shot) {
      this.move();
    }
    this.report();
  };

  function Human (name, position, speed, focus) {
    this.name = name;
    this.speed = speed || 8;
    this.focus = focus || 4;
    this.position = position || 10;
    this.escaped = false;
    this.bitten = 0;
    this.shot = false;
    this.noiseLevel = 4;
    this.inventory = {
      gun: true,
      bullets: randomNumberIn(3)
    };
  }

  Human.prototype = new Biped();
  Human.prototype.run = function (argument) {
    this.move(2);
    this.exhausted = true;
  };
  Human.prototype.checkStatus = function (suvivorIndex) {
    if (this.escaped || this.position >= game.distance) {
      if (!this.escaped) {
        this.escaped = true;
        game.escapees.push(this);
        this.state = "is waiting at the city limits";
      }
    } else {
      if (this.bitten || this.shot) {
        var random = randomNumberIn(10);
        console.log("Random was " + random + ".");
        if (random > 7 - this.bitten) {
          this.zombify(suvivorIndex);
        }
      }
    }

  };
  Human.prototype.zombify = function (suvivorIndex) {
    game.consoleLog(this.name + " became a zombie!");
    game.createZombies(1, this.position, ["Zombified " + this.name]);
    game.survivors.splice(suvivorIndex, 1);
    game.updateHumans();
  };
  Human.prototype.search = function (target) {
    var message, thisStuff = this.inventory.bullets, theirStuff = target.inventory.bullets;

    message = this.name + " searches " + target.name + ", and ";
    if (theirStuff) {
      this.inventory.bullets += target.inventory.bullets;
      target.inventory.bullets = 0;
      message += "finds " + theirStuff + " bullets!";
    } else {
      message += "finds nothing!";
    }
    game.consoleLog(message);
    game.turn.npc();
  };
  Human.prototype.takeTurn = function () {
    if (!this.shot && !this.escaped) {
      this.move();
      // this.checkStatus();
    }
    this.report();
  };

  function Player (name, position, speed, focus) {
    this.name = name;
    this.speed = speed || 8;
    this.focus = focus || 4;
    this.position = position || 10;
    this.inventory = {
      gun: true,
      bullets: 3
    };
  }

  Player.prototype = new Human();
  Player.prototype.sneak = function (argument) {
    this.move(0.5);
    this.noiseLevel = 0;
  };
  Player.prototype.shootAt = function (targetIndex) {
    var message, victim, random = randomNumberIn(10);

    if (this.inventory.bullets) {
      message = "Bang! ";
      this.inventory.bullets--;
      if (random > 7) {
        message += this.name + " killed " + game.zombies[targetIndex].name + "!";
        game.zombies.splice(targetIndex, 1);
      } else if (random >= 1) {
        message += this.name + " misses wildly!";
      } else {
        victim = game.survivors[randomNumberIn(game.survivors.length)];
        message += this.name + " accidentally shot " + victim.name + "! ";
        victim.shot = true;
        victim.speed = 0;
        victim.state = "is dead";
      }
    } else {
      message = "Click! " + this.name + "\'s gun is empty!";
    }
    game.consoleLog(message);
    this.state = "is stopped";
    this.report();
  };
  Player.prototype.checkPlayerStatus = function () {
    if (this.bitten) {
      this.dies();
    } else if (this.position >= game.distance) {
      this.wins();
    }
  };
  Player.prototype.dies = function (fromKiller) {
    var toggleBackground = function () {
      $("#approachImage").hide();
      $("#backgroundImage").toggleClass("overrun");
      $("#youDied").show();
      $(".startGame").show();
    };
    $(".playingGame").hide();
    game.consoleLog(this.name + " dies.");
    game.$console.slideToggle();
    game.$dialogText.text(fromKiller.name + " got " + this.name + "!");
    $("#approachImage")
      .animate({"opacity": "1", "width": "100%"}, "300");
    setTimeout(toggleBackground, [400]);
  };
  Player.prototype.wins = function () { //still has a formatting bug with commas.
    var i, message = "";

    if (game.escapees.length > 1) {
      if (game.escapees.length == 2) {
        message = game.escapees[0].name + " and " + game.escapees[1].name;
        } else {
          var lastMemberIndex = game.escapees.length - 1;
          for (i = 0; i < lastMemberIndex; i++) {
            message += game.escapees[i].name + ", ";
          }
          message += "and " + game.escapees[lastMemberIndex].name;
        }
    }

    message += " escaped from the city alive!";

    game.consoleLog(this.name + " wins.");
    game.$console.slideToggle();
    game.$dialogText.text(message);
    $("#youWon").show();
    $("#backgroundImage").toggleClass("roadClosed");
    $("#approachImage").hide();
    $(".playingGame").hide();
    $(".startGame").show();
  };

  function Location (argument) {
    this.name = name;
    this.position = position;
    this.details = details;
    this.inventory = inventory;
  }

  function randomNumberIn (numberSet) {
    return Math.floor(Math.random() * numberSet);
  }

  /*************************
  Image Preload
  **************************/

  $(function () {
    var $preloadContainer = $(document.createElement('span'));
    var $backgroundImage = $("#backgroundImage");

    $($preloadContainer)
      .attr("id", "preload")
      .appendTo($backgroundImage);
  });

  /*************************
  Event Listeners
  **************************/

  //Click handler for startButton.
  $("#startButton").on("click", function (e) {
    e.preventDefault();

    if ($(this).hasClass("newGame")) {
      $("#backgroundImage").removeClass("roadClosed overrun");
      $("#approachImage").removeAttr("style");
      $(".endgame").hide();
    }

    $(this)
      .text("Start New Game")
      .addClass("newGame")
      .hide();
    game.createGame();
    $(".playingGame").show();
    game.$console.slideToggle(200);

    game.turn.full();
  });

  //Click handler for moveButton.
  $("#moveButton").on("click", function (e) {
    e.preventDefault();
    game.consoleClear();
    game.turn.full();
  });

  //Click handler for playerShoots.
  $("#playerShoots").on("click", function (e) {
    e.preventDefault();
    game.consoleClear();
    game.players[0].shootAt(0);
    game.turn.npc();
  });

  //Click handler for playerDeath button.
  $("#playerDeath").on("click", function (e) {
    e.preventDefault();
    game.players[0].dies();
  });

// }()); //End of IIFE
<|endoftext|>