// make is a function that takes an instance of the
// elm runtime
// returns an object where:
//      keys are names to be accessed in pure Elm
//      values are either functions or values
var make = function make(elm) {
    // If Native isn't already bound on elm, bind it!
    elm.Native = elm.Native || {};
    // then the same for our module
    elm.Native.Table = elm.Native.Table || {};

    // `values` is where the object returned by make ends up internally
    // return if it's already set, since you only want one definition of
    // values for speed reasons
    if (elm.Native.Table.values) return elm.Native.Table.values;

    var empty = {
        ctor : 'Table',
        values : []
    };

    var listLength = function(xs){
        var i = 0;
        while (xs.ctor !== '[]')
        {
            i++;
            xs = xs._1;
        }

        return i;
    }

    var listToArray = function (xs) {
        var out = [];
        while (xs.ctor !== '[]')
        {
            out.push(xs._0);
            xs = xs._1;
        }
        return out;
    };

    var fromList = function(list){
        var length = listLength(list);

        if (length < 1)
        {
            return empty;
        }

        var table = new Array(length);
        var i = 0;

        while (list.ctor !== '[]') {
            table[i] = list._0;
            list = list._1;
            i++;
        }
        console.log(table);

        return {
            ctor: 'Table',
            values: table
        };
    };

    var length = function(table){
        return table.values.length;
    };

    var get = function(i, table){
        return table.values[i];
    };

    var update = function(i, f, table){
        var new_value = f(table.values[i]);
        table.values[i] = new_value;
        return table;
    };

    var updateMany = function(batch, table){
        batch.forEach(function(v){
            index = v._0;
            f = v._1;

            table = update(index, f);
        });

        return table;
    };

    var map = function(f, table){
        var len = table.values.length;

        for (var i = 0; i < len; i++){
            table = update(i, f, table);
        }

        return table;
    };

    var indexedMap = function(f, table){
        var len = table.values.length;

        for (var i = 0; i < len; i++){
            table = update(i, f(i), table);
        }

        return table;
    };

    var foldl = function(f, init, table){
        var len = table.values.length;

        for (var i = 0; i < len; i++){
            var item = table.values[i];

            init = f(item)(init);
        }

        return init;
    };

    var foldr = function(f, init, table){
        var len = table.values.length;

        for (var i = len - 1; i > -1; i--){
            var item = table.values[i];

            init = f(item)(init);
        }

        return init;
    };

    var indexedFoldl = function(f, init, table){
        var len = table.values.length;

        for (var i = 0; i < len; i++){
            var item = table.values[i];

            init = f(i)(item)(init);
        }

        return init;
    };

    var indexedFoldr = function(f, init, table){
        var len = table.values.length;

        for (var i = len; i > -1; i--){
            var item = table.values[i];

            init = f(i)(item)(init);
        }

        return init;
    };


    // return the object of your module's stuff!
    return {
        empty: empty,
        fromList: fromList,
        length: length,
        get: get,
        map: F2(map),
        indexedMap: F2(indexedMap),
        update: F2(update),
        updateMany: F2(updateMany),
        foldr: F3(foldr),
        foldl: F3(foldl),
        indexedFoldr: F3(indexedFoldr),
        indexedFoldl: F3(indexedFoldl)
    };
};

// setup code for Table
// Elm.Native.Table should be an object with
// a property `make` which is specified above
Elm.Native.Table = {};
Elm.Native.Table.make = make;

@@ -884,197 +884,159 @@
     
-var listToArray = function (xs) %7B%0A        var out = %5B%5D;%0A        while (xs.ctor !== '%5B%5D')%0A        %7B%0A            out.push(xs._0);%0A            xs = xs._1;%0A        %7D%0A        return out;
+/*%0A        Intended to be a faster version of List.toArray%0A        Preallocates a block array as per https://www.youtube.com/watch?v=UJPdhx5zTaw
 %0A    
-%7D;%0A
+*/
 %0A   
@@ -1364,36 +1364,8 @@
    %7D
-%0A        console.log(table);
 %0A%0A  
@@ -1595,32 +1595,32 @@
 ues%5Bi%5D;%0A    %7D;%0A%0A
-
     var update =
@@ -1635,32 +1635,352 @@
 n(i, f, table)%7B%0A
+        var len = table.values.length;%0A%0A        // when len is bigger than the table%0A        // return early. we don't want to%0A        // create non-sequential arrays as%0A        // they get turned into hashmaps and%0A        // lose performance and size bonuses%0A        if (i %3E= len)%7B%0A            return table;%0A        %7D%0A%0A
         var new_

make sure to only allow updates of items in array