<commit_before>/*global AvroDoc:false, _:false */

// Interprets the contents of one Avro Schema (.avsc) file and transforms it into structures
// suitable for rendering.
//
// shared_types: An object of the form
//      {'namespace.name': [{type: 'record', fields: [...]}, {type: 'record', fields: [...]}, ...], ...}
//    This object is mutated as the schema is parsed; we add the types defined in this schema to the
//    structure. Different schema files may define the same type differently, hence the array of
//    types for each qualified name. However, where two different schema files agree on the
//    definition of a type, we can share the parsed type between the different files.
//
// schema_json: The .avsc file, parsed into a structure of JavaScript objects.
//
// filename: The name of the file from which the schema was loaded, if available.
//
AvroDoc.Schema = function (shared_types, schema_json, filename) {
    var _public = {filename: filename};

    // {'namespace.name': {type: 'record', fields: [...]}}
    // containing only types defined in this schema
    var named_types = {};

    var primitive_types = ['null', 'boolean', 'int', 'long', 'float', 'double', 'bytes', 'string'];

    function qualifiedName(schema, namespace) {
        var type_name, _schema = _(schema);
        if (_schema.isString()) {
            type_name = schema;
        } else if (_schema.isObject() && !_schema.isArray()) {
            namespace = schema.namespace || namespace;
            type_name = schema.name || schema.type;
        }

        if (!type_name) {
            throw 'unable to determine type name from schema ' + JSON.stringify(schema) + ' in namespace ' + namespace;
        } else if (type_name.indexOf('.') >= 0) {
            return type_name;
        } else if (_(primitive_types).contains(type_name)) {
            return type_name;
        } else if (namespace) {
            return namespace + '.' + type_name;
        } else {
            return type_name;
        }
    }

    // Takes a node in the schema tree (a JS object) and adds some fields that are useful for
    // template rendering.
    function decorate(schema) {
        schema.filename = filename;
        schema['is_' + schema.type] = true;
        if (_(primitive_types).contains(schema.type)) {
            schema.is_primitive = true;
        } else {
            schema.link = [
                '#', 'schema', encodeURIComponent(filename || 'default'),
                encodeURIComponent(qualifiedName(schema))
            ].join('/');
            schema.shared_link = [
                '#', 'schema', encodeURIComponent(qualifiedName(schema))
            ].join('/');
        }
        if (schema.shared) decorate(schema.shared);
        return schema;
    }

    function joinPath(parent, child) {
        return parent ? [parent, child].join('.') : child;
    }

    // Given a type name and the current namespace, returns an object representing the type that the
    // name refers to (or throws an exception if the name cannot be resolved). For named types, the
    // same (shared) object is returned whenever the same name is requested.
    function lookupNamedType(name, namespace, path) {
        if (_(primitive_types).contains(name)) {
            return decorate({type: name});
        }
        var type = named_types[qualifiedName(name, namespace)];
        if (type) {
            return type;
        } else {
            throw 'Unknown type name ' + JSON.stringify(name) + ' at ' + path;
        }
    }

    // Given an object representing a type (as returned by lookupNamedType, for example), returns
    // the qualified name of that type. We recurse through unnamed complex types (array, map, union)
    // but named types are replaced by their name.
    function extractTypeName(schema, namespace) {
        var _schema = _(schema);
        if (_schema.isString()) {
            return schema;
        } else if (_schema.isObject() && !_schema.isArray()) {
            if (schema.type === 'record' || schema.type === 'enum' || schema.type === 'fixed') {
                return qualifiedName(schema, namespace);
            } else if (schema.type === 'array') {
                return {type: 'array', items: extractTypeName(schema.items, namespace)};
            } else if (schema.type === 'map') {
                return {type: 'map', values: extractTypeName(schema.values, namespace)};
            } else if (schema.type === 'union') {
                return _(schema.types).map(function (type) {
                    return extractTypeName(type, namespace);
                });
            } else if (_(primitive_types).contains(schema.type)) {
                return schema.type;
            } else {
                throw 'extractTypeName: unsupported Avro schema type: ' + JSON.stringify(schema.type);
            }
        } else if (_schema.isArray()) {
            return _schema.map(function (type) {
                return extractTypeName(type, namespace);
            });
        } else {
            throw 'extractTypeName: unexpected schema: ' + JSON.stringify(schema);
        }
    }

    // Given a JSON object representing a named type (record, enum or fixed), returns a new object
    // containing only fields that are essential to the definition of the type. This is useful for
    // equality comparison of types.
    function typeEssence(schema) {
        var essence = {type: schema.type, name: qualifiedName(schema, schema.namespace)};
        if (schema.type === 'record') {
            essence.fields = _(schema.fields).map(function (field) {
                return {name: field.name, type: extractTypeName(field.type, schema.namespace)};
            });
        } else if (schema.type === 'enum') {
            essence.symbols = schema.symbols;
        } else if (schema.type === 'fixed') {
            essence.size = schema.size;
        } else {
            throw 'typeEssence() only supports named types, not ' + schema.type;
        }
        return essence;
    }

    // Takes a named type (record, enum or fixed) and adds it to the maps of name to type. If a type
    // with the same qualified name and the same definition is already defined in another schema
    // file, that existing definition is reused. If the qualified name is not yet defined, or the
    // existing definitions differ from this type, a new definition is registered.
    //
    // Note that within one schema file, a qualified name may only map to one particular definition.
    // However, it is acceptable for different schema files to have conflicting definitions for the
    // same qualified name, because different schema files are independent. The sharing of
    // equivalent types is only for conciceness of display.
    function defineNamedType(schema, path) {
        var qualified_name = qualifiedName(schema, schema.namespace);
        var new_type = typeEssence(schema);
        var shared_schema = null;

        if (_(shared_types).has(qualified_name)) {
            shared_schema = _(shared_types[qualified_name]).find(function (shared_schema) {
                return _(new_type).isEqual(typeEssence(shared_schema));
            });
        } else {
            shared_types[qualified_name] = [];
        }

        if (_(named_types).has(qualified_name)) {
            var existing_type = typeEssence(named_types[qualified_name]);
            if (!_(new_type).isEqual(existing_type)) {
                throw 'Conflicting definition for type ' + qualified_name + ' at ' + path + ': ' +
                        JSON.stringify(existing_type) + ' != ' + JSON.stringify(new_type);
            }
        } else {
            // Type has not yet been defined in this schema file
            named_types[qualified_name] = schema;
            if (shared_schema) {
                shared_schema.definitions.push(schema);
            } else {
                shared_schema = _(schema).clone(); // shallow clone
                shared_schema.definitions = [schema];
                shared_types[qualified_name].push(shared_schema);
            }
        }
        schema.shared = shared_schema;
    }

    function parseSchema(schema, namespace, path) {
        var _schema = _(schema);
        if (_schema.isNull() || _schema.isUndefined()) {
            throw 'Missing schema type at ' + path;
        } else if (_schema.isString()) {
            return lookupNamedType(schema, namespace, path);
        } else if (_schema.isObject() && !_schema.isArray()) {
            if (schema.type === 'record') {
                if (!_(schema.fields).isArray()) {
                    throw 'Unexpected value ' + JSON.stringify(schema.fields) + ' for record fields at ' + path;
                }
                schema.namespace = schema.namespace || namespace;
                defineNamedType(schema, path);
                _(schema.fields).each(function (field) {
                    field.type = parseSchema(field.type, schema.namespace, joinPath(path, field.name));
                });
                return decorate(schema);
            } else if (schema.type === 'enum') {
                if (!_(schema.symbols).isArray()) {
                    throw 'Unexpected value ' + JSON.stringify(schema.symbols) + ' for enum symbols at ' + path;
                }
                schema.namespace = schema.namespace || namespace;
                defineNamedType(schema, path);
                return decorate(schema);
            } else if (schema.type === 'fixed') {
                if (typeof schema.size !== 'number' || schema.size < 1) {
                    throw 'Unexpected size ' + JSON.stringify(schema.size) + ' for fixed type at ' + path;
                }
                schema.namespace = schema.namespace || namespace;
                defineNamedType(schema, path);
                return decorate(schema);
            } else if (schema.type === 'array') {
                schema.items = parseSchema(schema.items, namespace, joinPath(path, 'items'));
                return decorate(schema);
            } else if (schema.type === 'map') {
                schema.values = parseSchema(schema.values, namespace, joinPath(path, 'values'));
                return decorate(schema);
            } else if (_(primitive_types).contains(schema.type)) {
                return decorate(schema);
            } else {
                throw 'Unsupported Avro schema type "' + schema.type + '" at ' + path;
            }
        } else if (_schema.isArray()) {
            if (_schema.isEmpty()) {
                throw 'Unions must have at least one branch type at ' + path;
            }
            return decorate({
                type: 'union',
                types: _schema.map(function (branch_type) {
                    if (_(branch_type).isArray()) {
                        throw 'Unions must not be nested at ' + path;
                    }
                    var type_name = _(branch_type).isObject() ? (branch_type.name || branch_type.type) : branch_type;
                    return parseSchema(branch_type, namespace, joinPath(path, type_name));
                })
            });
        } else {
            throw 'Unexpected schema contents ' + JSON.stringify(schema) + ' at ' + path;
        }
    }

    if (typeof schema_json === 'string') {
        schema_json = JSON.parse(schema_json);
    }

    _public.root_type = parseSchema(schema_json);
    _public.root_type.is_root_type = true;
    _public.named_types = named_types;

    _public.sorted_types = _(named_types).values().sort(function (type1, type2) {
        if (type1.name < type2.name) return -1;
        if (type1.name > type2.name) return +1;
        return 0;
    });

    return _public;
};
<commit_msg>Expose types at the root level of Avro schema as well as all messages<commit_after>/*global AvroDoc:false, _:false */

// Interprets the contents of one Avro Schema (.avsc) file and transforms it into structures
// suitable for rendering.
//
// shared_types: An object of the form
//      {'namespace.name': [{type: 'record', fields: [...]}, {type: 'record', fields: [...]}, ...], ...}
//    This object is mutated as the schema is parsed; we add the types defined in this schema to the
//    structure. Different schema files may define the same type differently, hence the array of
//    types for each qualified name. However, where two different schema files agree on the
//    definition of a type, we can share the parsed type between the different files.
//
// schema_json: The .avsc file, parsed into a structure of JavaScript objects.
//
// filename: The name of the file from which the schema was loaded, if available.
//
AvroDoc.Schema = function (shared_types, schema_json, filename) {
    var _public = {filename: filename};

    // {'namespace.name': {type: 'record', fields: [...]}}
    // containing only types and messages defined in this schema
    var named_types = {};

    var primitive_types = ['null', 'boolean', 'int', 'long', 'float', 'double', 'bytes', 'string'];

    function qualifiedName(schema, namespace) {
        var type_name, _schema = _(schema);
        if (_schema.isString()) {
            type_name = schema;
        } else if (_schema.isObject() && !_schema.isArray()) {
            namespace = schema.namespace || namespace;
            type_name = schema.name || schema.type;
        }

        if (!type_name) {
            throw 'unable to determine type name from schema ' + JSON.stringify(schema) + ' in namespace ' + namespace;
        } else if (type_name.indexOf('.') >= 0) {
            return type_name;
        } else if (_(primitive_types).contains(type_name)) {
            return type_name;
        } else if (namespace) {
            return namespace + '.' + type_name;
        } else {
            return type_name;
        }
    }

    // Takes a node in the schema tree (a JS object) and adds some fields that are useful for
    // template rendering.
    function decorate(schema) {
        schema.filename = filename;
        schema['is_' + schema.type] = true;
        if (_(primitive_types).contains(schema.type)) {
            schema.is_primitive = true;
        } else {
            schema.link = [
                '#', 'schema', encodeURIComponent(filename || 'default'),
                encodeURIComponent(qualifiedName(schema))
            ].join('/');
            schema.shared_link = [
                '#', 'schema', encodeURIComponent(qualifiedName(schema))
            ].join('/');
        }
        if (schema.shared) decorate(schema.shared);
        return schema;
    }

    function joinPath(parent, child) {
        return parent ? [parent, child].join('.') : child;
    }

    // Given a type name and the current namespace, returns an object representing the type that the
    // name refers to (or throws an exception if the name cannot be resolved). For named types, the
    // same (shared) object is returned whenever the same name is requested.
    function lookupNamedType(name, namespace, path) {
        if (_(primitive_types).contains(name)) {
            return decorate({type: name});
        }
        var type = named_types[qualifiedName(name, namespace)];
        if (type) {
            return type;
        } else {
            throw 'Unknown type name ' + JSON.stringify(name) + ' at ' + path;
        }
    }

    // Given an object representing a type (as returned by lookupNamedType, for example), returns
    // the qualified name of that type. We recurse through unnamed complex types (array, map, union)
    // but named types are replaced by their name.
    function extractTypeName(schema, namespace) {
        var _schema = _(schema);
        if (_schema.isString()) {
            return schema;
        } else if (_schema.isObject() && !_schema.isArray()) {
            if (schema.type === 'record' || schema.type === 'enum' || schema.type === 'fixed') {
                return qualifiedName(schema, namespace);
            } else if (schema.type === 'array') {
                return {type: 'array', items: extractTypeName(schema.items, namespace)};
            } else if (schema.type === 'map') {
                return {type: 'map', values: extractTypeName(schema.values, namespace)};
            } else if (schema.type === 'union') {
                return _(schema.types).map(function (type) {
                    return extractTypeName(type, namespace);
                });
            } else if (_(primitive_types).contains(schema.type)) {
                return schema.type;
            } else {
                throw 'extractTypeName: unsupported Avro schema type: ' + JSON.stringify(schema.type);
            }
        } else if (_schema.isArray()) {
            return _schema.map(function (type) {
                return extractTypeName(type, namespace);
            });
        } else {
            throw 'extractTypeName: unexpected schema: ' + JSON.stringify(schema);
        }
    }

    // Given a JSON object representing a named type (record, enum, message or fixed), returns a new object
    // containing only fields that are essential to the definition of the type. This is useful for
    // equality comparison of types.
    function typeEssence(schema) {
        var essence = {type: schema.type, name: qualifiedName(schema, schema.namespace)};
        if (schema.type === 'record') {
            essence.fields = _(schema.fields).map(function (field) {
                return {name: field.name, type: extractTypeName(field.type, schema.namespace)};
            });
        } else if (schema.type === 'enum') {
            essence.symbols = schema.symbols;
        } else if (schema.type === 'fixed') {
            essence.size = schema.size;
        } else if (schema.type === 'message') {
            // something needed here?
        } else {
            throw 'typeEssence() only supports named types, not ' + schema.type;
        }
        return essence;
    }

    // Takes a named type (record, enum or fixed) and adds it to the maps of name to type. If a type
    // with the same qualified name and the same definition is already defined in another schema
    // file, that existing definition is reused. If the qualified name is not yet defined, or the
    // existing definitions differ from this type, a new definition is registered.
    //
    // Note that within one schema file, a qualified name may only map to one particular definition.
    // However, it is acceptable for different schema files to have conflicting definitions for the
    // same qualified name, because different schema files are independent. The sharing of
    // equivalent types is only for conciceness of display.
    function defineNamedType(schema, path) {
        var qualified_name = qualifiedName(schema, schema.namespace);
        var new_type = typeEssence(schema);
        var shared_schema = null;

        if (_(shared_types).has(qualified_name)) {
            shared_schema = _(shared_types[qualified_name]).find(function (shared_schema) {
                return _(new_type).isEqual(typeEssence(shared_schema));
            });
        } else {
            shared_types[qualified_name] = [];
        }

        if (_(named_types).has(qualified_name)) {
            var existing_type = typeEssence(named_types[qualified_name]);
            if (!_(new_type).isEqual(existing_type)) {
                throw 'Conflicting definition for type ' + qualified_name + ' at ' + path + ': ' +
                        JSON.stringify(existing_type) + ' != ' + JSON.stringify(new_type);
            }
        } else {
            // Type has not yet been defined in this schema file
            named_types[qualified_name] = schema;
            if (shared_schema) {
                shared_schema.definitions.push(schema);
            } else {
                shared_schema = _(schema).clone(); // shallow clone
                shared_schema.definitions = [schema];
                shared_types[qualified_name].push(shared_schema);
            }
        }
        schema.shared = shared_schema;
    }

    // Decorates a message with some of the basic data that is required and is automatically generated
    // for other types of objects. Generates a link for the response object as well as the list of
    // input parameters.
    function decorateMessage(messageName, schemaMessage, namespace) {
       schemaMessage.type = 'message';
       schemaMessage.namespace = namespace;
       schemaMessage.name = messageName;
       schemaMessage.response = lookupNamedType(schemaMessage.response, namespace);
       if (schemaMessage.request !== null) {
          for (var i = 0; i < schemaMessage.request.length; i++) {
             schemaMessage.request[i].type = lookupNamedType(schemaMessage.request[i].type, namespace);
          }
       }
       schemaMessage = decorate(schemaMessage);
       return schemaMessage;
    }

    // Similar to how a top-level schema is parsed out, parse out all messages
    // in a slightly different manner. This allows for not only the object definitions to
    // be included in the documentation but also any messages included in the Avro schema.
    function parseMessages(schema) {
       var _schema = _(schema);
       if (_schema.isNull() || _schema.isUndefined()) {
          throw 'Schema is null in parseMessages';
       }
       else if (_schema.isObject() && !_schema.isArray()) {
          if (schema.messages !== null) {
             for (var messageName in schema.messages) {
	        var decoratedMessage = decorateMessage(messageName, schema.messages[messageName], schema.namespace);
	        defineNamedType(decoratedMessage);
	     }
          }
       }
    }

    function parseSchema(schema, namespace, path) {
        var _schema = _(schema);
        if (_schema.isNull() || _schema.isUndefined()) {
            throw 'Missing schema type at ' + path;
        } else if (_schema.isString()) {
            return lookupNamedType(schema, namespace, path);
        } else if (_schema.isObject() && !_schema.isArray()) {
            if (schema.type === 'record') {
                if (!_(schema.fields).isArray()) {
                    throw 'Unexpected value ' + JSON.stringify(schema.fields) + ' for record fields at ' + path;
                }
                schema.namespace = schema.namespace || namespace;
                defineNamedType(schema, path);
                _(schema.fields).each(function (field) {
                    field.type = parseSchema(field.type, schema.namespace, joinPath(path, field.name));
                });
                return decorate(schema);
            } else if (schema.type === 'enum') {
                if (!_(schema.symbols).isArray()) {
                    throw 'Unexpected value ' + JSON.stringify(schema.symbols) + ' for enum symbols at ' + path;
                }
                schema.namespace = schema.namespace || namespace;
                defineNamedType(schema, path);
                return decorate(schema);
            } else if (schema.type === 'fixed') {
                if (typeof schema.size !== 'number' || schema.size < 1) {
                    throw 'Unexpected size ' + JSON.stringify(schema.size) + ' for fixed type at ' + path;
                }
                schema.namespace = schema.namespace || namespace;
                defineNamedType(schema, path);
                return decorate(schema);
            } else if (schema.type === 'array') {
                schema.items = parseSchema(schema.items, namespace, joinPath(path, 'items'));
                return decorate(schema);
            } else if (schema.type === 'map') {
                schema.values = parseSchema(schema.values, namespace, joinPath(path, 'values'));
                return decorate(schema);
            } else if (_(primitive_types).contains(schema.type)) {
                return decorate(schema);
            } else if (schema.types !== null) {
                return parseSchema(schema.types, schema.namespace);
            } else {
                throw 'Unsupported Avro schema type "' + schema.type + '" at ' + path;
            }
        } else if (_schema.isArray()) {
            if (_schema.isEmpty()) {
                throw 'Unions must have at least one branch type at ' + path;
            }
            return decorate({
                type: 'union',
                types: _schema.map(function (branch_type) {
                    if (_(branch_type).isArray()) {
                        throw 'Unions must not be nested at ' + path;
                    }
                    var type_name = _(branch_type).isObject() ? (branch_type.name || branch_type.type) : branch_type;
                    return parseSchema(branch_type, namespace, joinPath(path, type_name));
                })
            });
        } else {
            throw 'Unexpected schema contents ' + JSON.stringify(schema) + ' at ' + path;
        }
    }

    if (typeof schema_json === 'string') {
        schema_json = JSON.parse(schema_json);
    }

    _public.root_type = parseSchema(schema_json);
    _public.root_type.is_root_type = true;
    parseMessages(schema_json);
    _public.named_types = named_types;

    _public.sorted_types = _(named_types).values().sort(function (type1, type2) {
        if (type1.name < type2.name) return -1;
        if (type1.name > type2.name) return +1;
        return 0;
    });

    return _public;
};
<|endoftext|>


<commit_before>var colors = {
    0: "lightgray",
    1: "#edc240",
    2: "#afd8f8",
    3: "#cb4b4b",
    4: "#4da74d",
    5: "#9440ed",
    6: "rgb(189, 155, 51)",
    7: "rgb(140,172,198)"
};

var target = $('#target');
$(document)
    .ajaxStart(function () {
        $('html, body').css('cursor', 'wait');
        target.overlay();
    })
    .ajaxStop(function () {
        $('html, body').css('cursor', 'auto');
        target.overlayout();
    });

$(function () {
    initLegend();

    // Load the last 14 days
    getFortnight(function (rawdata) {
        render(rawdata)
    });
});

function initLegend() {
    $('#detail-legend').append('

');
};

function render(rawdata) {

    if (!rawdata) {
        // TODO Show error message
        console.log('Sorry, no data found.');
        return;
    }

    var data = convertDataForFlot(rawdata);

    // Legend -------------------------------------------------------------
    var legendContainer = $('#detail-legend');
    var legendHasNoData = legendContainer.find('.table-row-data').length === 0;
    if (legendHasNoData) {
        $.each(data, function (key, val) {
            var tablerow = '
' +
                '
<input type="checkbox" name="' + key + '" checked="checked" id="id' + key + '"></input>
' +
                '

' +
                '
' + val.label + '
' +
                '

' +
                '
';
            legendContainer.find('.div-table').append(tablerow);
        });
    }
    legendContainer.find("input").click(updatePlot);

    var currentSelection = {
        min: undefined,
        max: undefined
    };

    // Main plotting function ---------------------------------------------
    function updatePlot() {

        var plotdata = [];

        legendContainer.find('input:checked').each(function () {
            var key = $(this).attr('name');
            if (key && data[key]) {
                plotdata.push(data[key])
            }
        });

        var rangeselectionCallback = function (o) {
            console.log('rangeselectionCallback invoked...');
            var xaxis = detailPlot.getAxes().xaxis;

            if (o.start <= xaxis.datamin) {
                loadAnotherFortnight(xaxis.datamin, xaxis.datamax);
            } else {
                xaxis.options.min = o.start;
                xaxis.options.max = o.end;
                detailPlot.setupGrid();
                detailPlot.draw();

                currentSelection.min = o.start;
                currentSelection.max = o.end;
            }
        };

        var detailPlaceholder = $('#detail-placeholder');
        var detailPlot = $.plot(detailPlaceholder, plotdata, {
            xaxis: {
                mode: 'time'
            },
            yaxis: {
                panRange: false
            },
            series: {
                lines: {
                    show: true
                },
                points: {
                    show: false
                }
            },
            legend: {
                show: false // Note: The legend is configured manually (see legendContainer)
            },
            grid: {
                hoverable: true,
                clickable: true,
                autoHighlight: false,
                borderWidth: 0,
                markings: nightAreas
            },
            crosshair: {
                mode: 'x'
            },
            pan: {
                interactive: true
            }
        });

        var overviewPlaceholder = $('#overview-placeholder');
        var overviewData = $.extend(true, [], plotdata);
        for (var i = 0; i < overviewData.length; i++) {
            overviewData[i].color = '#ccc';
            overviewData[i].label = undefined;
        }

        function initializeOverview(plot) {
            var rangeselectionEnd = plot.getData()[0].data[plot.getData()[0].data.length - 1][0];
            var endDate = new Date(rangeselectionEnd);
            endDate.setDate(endDate.getDate() - 1); // endDate = endDate - 1day
            var rangeselectionInitialStart = endDate.getTime();
            plot.getAxes().xaxis.options.min = rangeselectionInitialStart;
            plot.setupGrid();
            plot.draw();

            var initialOverview = {
                start: rangeselectionInitialStart,
                end: rangeselectionEnd
            };
            return initialOverview;
        }
        var overview = initializeOverview(detailPlot);

        var overviewPlot = $.plot(overviewPlaceholder, overviewData, {
            series: {
                lines: {
                    show: true,
                    lineWidth: 1
                },
                shadowSize: 0,
                points: {
                    show: false
                }
            },
            xaxis: {
                mode: "time"
            },
            yaxis: {
                labelWidth: 16,
                reserveSpace: true,
                show: false
            },
            legend: {
                show: false
            },
            grid: {
                hoverable: false,
                borderWidth: {
                    'top': 1,
                    'right': 1,
                    'left': 1,
                    'bottom': 1
                },
                borderColor: 'darkgray',
                markings: weekendAreas
            },
            rangeselection: {
                color: '#999',
                enabled: true,
                start: overview.start,
                end: overview.end,
                callback: rangeselectionCallback
            }
        });

        // Since the canvas is redrawn after every interaction, we have to manually set the selection range (if it exists)
        if (currentSelection.min !== undefined && currentSelection.max !== undefined) {
            var xaxis = detailPlot.getAxes().xaxis;
            xaxis.options.min = currentSelection.min;
            xaxis.options.max = currentSelection.max;
            detailPlot.setupGrid();
            detailPlot.draw();

            overviewPlot.getOptions().rangeselection.start = currentSelection.min;
            overviewPlot.getOptions().rangeselection.end = currentSelection.max;
            overviewPlot.setupGrid();
            overviewPlot.draw();
        }

        // PLOTHOVER: UPDATE VALUE IN LEGEND
        detailPlaceholder.bind('plothover', function (event, pos, item) {
            var updateDetailSelectionTimeout = null;
            var latestPosition = null;

            function updateDetailSelection() {
                updateDetailSelectionTimeout = null;
                var pos = latestPosition;
                var axes = detailPlot.getAxes();
                if (pos.x < axes.xaxis.min || pos.x > axes.xaxis.max ||
                    pos.y < axes.yaxis.min || pos.y > axes.yaxis.max) {
                    //tooltipContainer.hide('slow');
                    return;
                }

                var seriesIndex, dataPointInSeries, dataset = plotdata;

                // Iterate of each time series ('seriesIndex')
                var yMax;
                for (seriesIndex = 0; seriesIndex < dataset.length; ++seriesIndex) {
                    var series = dataset[seriesIndex];

                    // Find the nearest points, x-wise
                    for (dataPointInSeries = 0; series.data.length; ++dataPointInSeries) {
                        if (series.data[dataPointInSeries][0] > pos.x) {
                            break;
                        }
                    }

                    // Now interpolate
                    var y,
                        p1 = series.data[dataPointInSeries - 1],
                        p2 = series.data[dataPointInSeries];

                    if (p1 == null) {
                        y = p2[1];
                    } else if (p2 == null) {
                        y = p1[1];
                    } else {
                        y = p1[1] + (p2[1] - p1[1]) * (pos.x - p1[0]) / (p2[0] - p1[0]);
                    }

                    // Set the correct value for the current sensor
                    if ($.isNumeric(y)) {
                        var temperatureValueContainer = legendContainer.find('#temperature-value' + series.id);
                        if (temperatureValueContainer) {
                            temperatureValueContainer.text(y.toFixed(1));
                        }
                    }

                    if (y > yMax) {
                        yMax = y;
                    }
                }

                // Current time
                var m = moment(pos.x);
                m.add(-2, 'hours'); // fucking time stuff
                $('#detail-selection-header').text(m.format('YYYY-MM-DD HH:mm (ddd)'));
            };

            latestPosition = pos;
            if (!updateDetailSelectionTimeout) {
                updateDetailSelectionTimeout = setTimeout(updateDetailSelection, 400);
            }
        });

        // PLOTPAN: UPDATE OVERVIEW PLOT
        detailPlaceholder.bind('plotpan', function (event, plot) {
            var currentMin = plot.getXAxes()[0].min;
            var dataMin = plot.getXAxes()[0].datamin;
            //            console.log('-------')
            //            console.log(new Date(currentMin));
            //            console.log(new Date(dataMin));
            if (currentMin <= dataMin) {
                loadAnotherFortnight(dataMin, overviewPlot.getAxes().xaxis.datamax);
                return;
            } else {
                function clamp(min, value, max) {
                    return value < min ? min : (value > max ? max : value);
                };

                function clampOverViewPlot(value) {
                    overviewMin = overviewPlot.getAxes().xaxis.min;
                    overviewMax = overviewPlot.getAxes().xaxis.max;
                    return clamp(overviewMin, value, overviewMax);
                };

                currentSelection.min = clampOverViewPlot(detailPlot.getAxes().xaxis.min);
                currentSelection.max = clampOverViewPlot(detailPlot.getAxes().xaxis.max);
                overviewPlot.setSelection(currentSelection.min, currentSelection.max);
            }
        });
    };

    updatePlot();

};

/* From flot demo: http://www.flotcharts.org/flot/examples/visitors/index.html */
function weekendAreas(axes) {
    var markings = [],
        d = new Date(axes.xaxis.min);

    // go to the first Saturday
    d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 1) % 7))
    d.setUTCSeconds(0);
    d.setUTCMinutes(0);
    d.setUTCHours(0);

    var i = d.getTime();

    do {
        markings.push({
            xaxis: {
                from: i,
                to: i + 2 * 24 * 60 * 60 * 1000
            },
            color: '#FBF8EF'
        });
        i += 7 * 24 * 60 * 60 * 1000;
    } while (i < axes.xaxis.max);

    return markings;
};

function nightAreas(axes) {
    var lat = 49.477246;
    var lng = 10.989707;
    var markings = [];

    var day = 24 * 60 * 60 * 1000; // ms
    for (var i = 0; true; i++) {
        var entry = axes.xaxis.min + (i * day);
        var t = SunCalc.getTimes(entry, lat, lng);
        markings.push({
            xaxis: {
                from: t.sunrise.getTime() <= axes.xaxis.min ? axes.xaxis.min : t.sunrise.getTime(),
                to: t.sunset.getTime() >= axes.xaxis.max ? axes.xaxis.max : t.sunset.getTime()
            },
            color: '#ffff99'
        });
        if (entry + day > axes.xaxis.max) {
            break;
        }
    }

    return markings;
};

function loadAnotherFortnight(oldMin, max) {
    console.log('Reloading with oldMin value: ' + new Date(oldMin));
    console.log('Reloading with max value: ' + new Date(max));

    getByFilter(oldMin, max, function (rawdata) {
        console.log('call getByFilter is done.');
        render(rawdata);
    });
};

// Prepare data -------------------------------------------------------------------------------------------
var formatDate = function (date) {
    // requires moment.js
    return moment.utc(new Date(date)).format('ddd, YYYY MMM DD HH:mm');
};

var convertDataForFlot = function (data) {
    var flotdata = [];
    flotdata.push(mapTimeSeries(data, 'WA', 'outside', colors[0]));
    flotdata.push(mapTimeSeries(data, 'Z2', '2nd floor', colors[1]));
    flotdata.push(mapTimeSeries(data, 'Z3', '1st floor (work)', colors[2]));
    flotdata.push(mapTimeSeries(data, 'Z4', '1st floor (bathroom)', colors[3]));
    flotdata.push(mapTimeSeries(data, 'Z5', '1st floor (bedroom)', colors[4]));
    flotdata.push(mapTimeSeries(data, 'Z6', 'ground floor', colors[5]));
    return flotdata;
};

var mapTimeSeries = function (data, sensorName, label, col) {
    var series = [];
    for (var i = 0; i < data.length; i++) {
        if (data[i].sensorName === sensorName) {
            var mDate = moment(data[i].timestamp + ' +02:00', 'YYYY-MM-DD HH:mm:ss ZZ');
            mDate.add(2, 'hours'); // still don't understand why this is really necessary.
            var millis = new Date(mDate.unix()) * 1000;
            series.push([millis, data[i].degreeCelsius]);
        }
    }

    // Note: Add an 'id' property (because the label property is a descriptive string)
    return {
        data: series,
        label: label,
        color: col,
        id: sensorName
    };
};
<commit_msg>fixed timeoffset (again)...<commit_after>var colors = {
    0: "lightgray",
    1: "#edc240",
    2: "#afd8f8",
    3: "#cb4b4b",
    4: "#4da74d",
    5: "#9440ed",
    6: "rgb(189, 155, 51)",
    7: "rgb(140,172,198)"
};

var target = $('#target');
$(document)
    .ajaxStart(function () {
        $('html, body').css('cursor', 'wait');
        target.overlay();
    })
    .ajaxStop(function () {
        $('html, body').css('cursor', 'auto');
        target.overlayout();
    });

$(function () {
    initLegend();

    // Load the last 14 days
    getFortnight(function (rawdata) {
        render(rawdata)
    });
});

function initLegend() {
    $('#detail-legend').append('

');
};

function render(rawdata) {

    if (!rawdata) {
        // TODO Show error message
        console.log('Sorry, no data found.');
        return;
    }

    var data = convertDataForFlot(rawdata);

    // Legend -------------------------------------------------------------
    var legendContainer = $('#detail-legend');
    var legendHasNoData = legendContainer.find('.table-row-data').length === 0;
    if (legendHasNoData) {
        $.each(data, function (key, val) {
            var tablerow = '
' +
                '
<input type="checkbox" name="' + key + '" checked="checked" id="id' + key + '"></input>
' +
                '

' +
                '
' + val.label + '
' +
                '

' +
                '
';
            legendContainer.find('.div-table').append(tablerow);
        });
    }
    legendContainer.find("input").click(updatePlot);

    var currentSelection = {
        min: undefined,
        max: undefined
    };

    // Main plotting function ---------------------------------------------
    function updatePlot() {

        var plotdata = [];

        legendContainer.find('input:checked').each(function () {
            var key = $(this).attr('name');
            if (key && data[key]) {
                plotdata.push(data[key])
            }
        });

        var rangeselectionCallback = function (o) {
            console.log('rangeselectionCallback invoked...');
            var xaxis = detailPlot.getAxes().xaxis;

            if (o.start <= xaxis.datamin) {
                loadAnotherFortnight(xaxis.datamin, xaxis.datamax);
            } else {
                xaxis.options.min = o.start;
                xaxis.options.max = o.end;
                detailPlot.setupGrid();
                detailPlot.draw();

                currentSelection.min = o.start;
                currentSelection.max = o.end;
            }
        };

        var detailPlaceholder = $('#detail-placeholder');
        var detailPlot = $.plot(detailPlaceholder, plotdata, {
            xaxis: {
                mode: 'time'
            },
            yaxis: {
                panRange: false
            },
            series: {
                lines: {
                    show: true
                },
                points: {
                    show: false
                }
            },
            legend: {
                show: false // Note: The legend is configured manually (see legendContainer)
            },
            grid: {
                hoverable: true,
                clickable: true,
                autoHighlight: false,
                borderWidth: 0,
                markings: nightAreas
            },
            crosshair: {
                mode: 'x'
            },
            pan: {
                interactive: true
            }
        });

        var overviewPlaceholder = $('#overview-placeholder');
        var overviewData = $.extend(true, [], plotdata);
        for (var i = 0; i < overviewData.length; i++) {
            overviewData[i].color = '#ccc';
            overviewData[i].label = undefined;
        }

        function initializeOverview(plot) {
            var rangeselectionEnd = plot.getData()[0].data[plot.getData()[0].data.length - 1][0];
            var endDate = new Date(rangeselectionEnd);
            endDate.setDate(endDate.getDate() - 1); // endDate = endDate - 1day
            var rangeselectionInitialStart = endDate.getTime();
            plot.getAxes().xaxis.options.min = rangeselectionInitialStart;
            plot.setupGrid();
            plot.draw();

            var initialOverview = {
                start: rangeselectionInitialStart,
                end: rangeselectionEnd
            };
            return initialOverview;
        }
        var overview = initializeOverview(detailPlot);

        var overviewPlot = $.plot(overviewPlaceholder, overviewData, {
            series: {
                lines: {
                    show: true,
                    lineWidth: 1
                },
                shadowSize: 0,
                points: {
                    show: false
                }
            },
            xaxis: {
                mode: "time"
            },
            yaxis: {
                labelWidth: 16,
                reserveSpace: true,
                show: false
            },
            legend: {
                show: false
            },
            grid: {
                hoverable: false,
                borderWidth: {
                    'top': 1,
                    'right': 1,
                    'left': 1,
                    'bottom': 1
                },
                borderColor: 'darkgray',
                markings: weekendAreas
            },
            rangeselection: {
                color: '#999',
                enabled: true,
                start: overview.start,
                end: overview.end,
                callback: rangeselectionCallback
            }
        });

        // Since the canvas is redrawn after every interaction, we have to manually set the selection range (if it exists)
        if (currentSelection.min !== undefined && currentSelection.max !== undefined) {
            var xaxis = detailPlot.getAxes().xaxis;
            xaxis.options.min = currentSelection.min;
            xaxis.options.max = currentSelection.max;
            detailPlot.setupGrid();
            detailPlot.draw();

            overviewPlot.getOptions().rangeselection.start = currentSelection.min;
            overviewPlot.getOptions().rangeselection.end = currentSelection.max;
            overviewPlot.setupGrid();
            overviewPlot.draw();
        }

        // PLOTHOVER: UPDATE VALUE IN LEGEND
        detailPlaceholder.bind('plothover', function (event, pos, item) {
            var updateDetailSelectionTimeout = null;
            var latestPosition = null;

            function updateDetailSelection() {
                updateDetailSelectionTimeout = null;
                var pos = latestPosition;
                var axes = detailPlot.getAxes();
                if (pos.x < axes.xaxis.min || pos.x > axes.xaxis.max ||
                    pos.y < axes.yaxis.min || pos.y > axes.yaxis.max) {
                    //tooltipContainer.hide('slow');
                    return;
                }

                var seriesIndex, dataPointInSeries, dataset = plotdata;

                // Iterate of each time series ('seriesIndex')
                var yMax;
                for (seriesIndex = 0; seriesIndex < dataset.length; ++seriesIndex) {
                    var series = dataset[seriesIndex];

                    // Find the nearest points, x-wise
                    for (dataPointInSeries = 0; series.data.length; ++dataPointInSeries) {
                        if (series.data[dataPointInSeries][0] > pos.x) {
                            break;
                        }
                    }

                    // Now interpolate
                    var y,
                        p1 = series.data[dataPointInSeries - 1],
                        p2 = series.data[dataPointInSeries];

                    if (p1 == null) {
                        y = p2[1];
                    } else if (p2 == null) {
                        y = p1[1];
                    } else {
                        y = p1[1] + (p2[1] - p1[1]) * (pos.x - p1[0]) / (p2[0] - p1[0]);
                    }

                    // Set the correct value for the current sensor
                    if ($.isNumeric(y)) {
                        var temperatureValueContainer = legendContainer.find('#temperature-value' + series.id);
                        if (temperatureValueContainer) {
                            temperatureValueContainer.text(y.toFixed(1));
                        }
                    }

                    if (y > yMax) {
                        yMax = y;
                    }
                }

                // Current time
                var m = moment(pos.x);
                m.add(-2, 'hours'); // fucking time stuff
                $('#detail-selection-header').text(m.format('YYYY-MM-DD HH:mm (ddd)'));
            };

            latestPosition = pos;
            if (!updateDetailSelectionTimeout) {
                updateDetailSelectionTimeout = setTimeout(updateDetailSelection, 400);
            }
        });

        // PLOTPAN: UPDATE OVERVIEW PLOT
        detailPlaceholder.bind('plotpan', function (event, plot) {
            var currentMin = plot.getXAxes()[0].min;
            var dataMin = plot.getXAxes()[0].datamin;
            //            console.log('-------')
            //            console.log(new Date(currentMin));
            //            console.log(new Date(dataMin));
            if (currentMin <= dataMin) {
                loadAnotherFortnight(dataMin, overviewPlot.getAxes().xaxis.datamax);
                return;
            } else {
                function clamp(min, value, max) {
                    return value < min ? min : (value > max ? max : value);
                };

                function clampOverViewPlot(value) {
                    overviewMin = overviewPlot.getAxes().xaxis.min;
                    overviewMax = overviewPlot.getAxes().xaxis.max;
                    return clamp(overviewMin, value, overviewMax);
                };

                currentSelection.min = clampOverViewPlot(detailPlot.getAxes().xaxis.min);
                currentSelection.max = clampOverViewPlot(detailPlot.getAxes().xaxis.max);
                overviewPlot.setSelection(currentSelection.min, currentSelection.max);
            }
        });
    };

    updatePlot();

};

/* From flot demo: http://www.flotcharts.org/flot/examples/visitors/index.html */
function weekendAreas(axes) {
    var markings = [],
        d = new Date(axes.xaxis.min);

    // go to the first Saturday
    d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 1) % 7))
    d.setUTCSeconds(0);
    d.setUTCMinutes(0);
    d.setUTCHours(0);

    var i = d.getTime();

    do {
        markings.push({
            xaxis: {
                from: i,
                to: i + 2 * 24 * 60 * 60 * 1000
            },
            color: '#FBF8EF'
        });
        i += 7 * 24 * 60 * 60 * 1000;
    } while (i < axes.xaxis.max);

    return markings;
};

function nightAreas(axes) {
    var lat = 49.477246;
    var lng = 10.989707;
    var markings = [];

    var day = 24 * 60 * 60 * 1000; // ms
    for (var i = 0; true; i++) {
        var entry = axes.xaxis.min + (i * day);
        var t = SunCalc.getTimes(entry, lat, lng);
        markings.push({
            xaxis: {
                from: (t.sunrise.getTime() + (1000 * 60 * 60 * 2)) <= axes.xaxis.min ? axes.xaxis.min : (t.sunrise.getTime() + (1000 * 60 * 60 * 2)),
                to: t.sunset.getTime() >= axes.xaxis.max ? axes.xaxis.max : (t.sunset.getTime() + (1000 * 60 * 60 * 2))
            },
            color: '#ffff99'
        });
        if (entry + day > axes.xaxis.max + (1000 * 60 * 60 * 2)) {
            break;
        }
    }

    return markings;
};

function loadAnotherFortnight(oldMin, max) {
    console.log('Reloading with oldMin value: ' + new Date(oldMin));
    console.log('Reloading with max value: ' + new Date(max));

    getByFilter(oldMin, max, function (rawdata) {
        console.log('call getByFilter is done.');
        render(rawdata);
    });
};

// Prepare data -------------------------------------------------------------------------------------------
var formatDate = function (date) {
    // requires moment.js
    return moment.utc(new Date(date)).format('ddd, YYYY MMM DD HH:mm');
};

var convertDataForFlot = function (data) {
    var flotdata = [];
    flotdata.push(mapTimeSeries(data, 'WA', 'outside', colors[0]));
    flotdata.push(mapTimeSeries(data, 'Z2', '2nd floor', colors[1]));
    flotdata.push(mapTimeSeries(data, 'Z3', '1st floor (work)', colors[2]));
    flotdata.push(mapTimeSeries(data, 'Z4', '1st floor (bathroom)', colors[3]));
    flotdata.push(mapTimeSeries(data, 'Z5', '1st floor (bedroom)', colors[4]));
    flotdata.push(mapTimeSeries(data, 'Z6', 'ground floor', colors[5]));
    return flotdata;
};

var mapTimeSeries = function (data, sensorName, label, col) {
    var series = [];
    for (var i = 0; i < data.length; i++) {
        if (data[i].sensorName === sensorName) {
            var mDate = moment(data[i].timestamp + ' +02:00', 'YYYY-MM-DD HH:mm:ss ZZ');
            mDate.add(2, 'hours'); // still don't understand why this is really necessary.
            var millis = new Date(mDate.unix()) * 1000;
            series.push([millis, data[i].degreeCelsius]);
        }
    }

    // Note: Add an 'id' property (because the label property is a descriptive string)
    return {
        data: series,
        label: label,
        color: col,
        id: sensorName
    };
};
<|endoftext|>


<commit_before>function scanStatus()
{
	$('.status').each(function()
	{
		$(this).click(function()
		{
			$.getJSON(this.href + '?format=json&jsoncallback=?', function(data)
			{
				$('.status_links_' + data.id).each(function()
				{
					$(this).replaceWith(data.status);
				})
				scanStatus();
			})
			return false;
		})
	})
}

function scanIMDB(server)
{
	var query = '';
	var list = new Array();
	$("a[href*='title/tt']").each(function()
	{

		regexp = /www\.imdb\.com\/title\/tt(\d{7})\/$/;
		if (regexp.test(this.href))
		{
			var array = regexp.exec(this.href);
			var id = array[1];
			if (list[id] == null)
			{
				list[id] = new Array();
				query += id + ',';
			}
			list[id].push(this);
		}

	})

	if (query == '')
		return;

	var url = server + "status/list/movies/" + query + "?format=json&jsoncallback=?";
	$.getJSON(url, function(data)
	{
		$.each(data.status, function(id, status)
		{
			//alert(id);
			//alert(status);
			q = "a[href*='/title/tt" + id.split('_')[0] + "']";

			$(q).before(status);
		});

		scanStatus();
	});
}

$(document).ready(function()
{
	scanStatus();
})
<commit_msg>FIX clean code<commit_after>function scanStatus()
{
	$('.status').each(function()
	{
		$(this).click(function()
		{
			$.getJSON(this.href + '?format=json&jsoncallback=?', function(data)
			{
				$('.status_links_' + data.id).each(function()
				{
					$(this).replaceWith(data.status);
				})
				scanStatus();
			})
			return false;
		})
	})
}

function scanIMDB(server)
{
	var query = '';
	var list = new Array();
	$("a[href*='title/tt']").each(function()
	{

		regexp = /www\.imdb\.com\/title\/tt(\d{7})\/$/;
		if (regexp.test(this.href))
		{
			var array = regexp.exec(this.href);
			var id = array[1];
			if (list[id] == null)
			{
				list[id] = new Array();
				query += id + ',';
			}
			list[id].push(this);
		}

	})

	if (query == '')
		return;

	var url = server + "status/list/movies/" + query + "?format=json&jsoncallback=?";
	$.getJSON(url, function(data)
	{
		$.each(data.status, function(id, status)
		{
			q = "a[href*='/title/tt" + id.split('_')[0] + "']";

			$(q).before(status);
		});

		scanStatus();
	});
}

$(document).ready(function()
{
	scanStatus();
})
<|endoftext|>


<commit_before>var PersonalWebsite = (function (document, window) {
  'use strict';
  var PersonalWebsite = function () {
    var header, hamburgerIcon;

    init();

    function init () {
      header = document.querySelector('.header');
      hamburgerIcon = document.querySelector('.nav__icon');

      bindEvents();
    }

    function bindEvents () {
      window.addEventListener('scroll', toggleFixedHeader);
      hamburgerIcon.addEventListener('click', toggleHeaderAnimation);
      addScroll('.intro__paragraph-pink');
      addScroll('.navigation__item a');
    }

    function toggleFixedHeader () {
      var intro = document.querySelector('.intro');
      var headerHeight = header.offsetHeight;
      var parallaxHeight = document.querySelector('.parallax').offsetHeight;
      if (document.body.scrollTop >= parallaxHeight) {
        header.classList.remove('js-slide-up');
        header.classList.add('js-header--fixed', 'js-slide-down');
        intro.style.paddingTop = headerHeight + 'px';
      } else {
        header.classList.remove('js-header--fixed', 'js-slide-down');
        header.classList.add('js-slide-up');
        intro.style.paddingTop = '0px';
      }
    }

    function toggleHeaderAnimation () {
      var navigation = document.querySelector('.navigation');
      var isOpen = false;
      this.classList.toggle('active'); // animates humburder icon
      if (navigation.classList.contains('active')) {
        navigation.classList.remove('active', 'js-slide-down');
        navigation.classList.add('js-slide-up');
        isOpen = false;
      } else {
        navigation.classList.remove('js-slide-up');
        navigation.classList.add('active', 'js-slide-down');
        isOpen = true;
      }
      resizeHeaderOnMobile(isOpen);
    }
    /**
    *  @param {Boolean} isOpen
    **/
    function resizeHeaderOnMobile (isOpen) {
      if (window.innerWidth < 768 && isOpen === true) {
        header.classList.add('active');
      } else {
        header.classList.remove('active');
      }
    }

    function updateHeader () {
      if (header.classList.contains('active')) {
        header.classList.remove('active');
        document.querySelector('.navigation').classList.remove('active');
        hamburgerIcon.classList.remove('active');
      } else {
        header.classList.add('active');
        document.querySelector('.navigation').classList.add('active');
        hamburgerIcon.classList.add('active');
      }
    }

    /**
    *  @param {String} selector
    **/
    function addScroll (selector) {
      var arrayOfElements = document.querySelectorAll(selector);
      Array.apply(null, arrayOfElements).forEach(function (element) {
        element.addEventListener('click', function (e) {
          e.preventDefault();
          var target = document.getElementById(element.getAttribute('href').slice(1));
          updateHeader();
          scroll(document.body, target.offsetTop, 300);
        });
      });
    }
    /**
    *  @param {HTMLElement} element
    *  @param {HTMLElement} toPosition
    *  @param {Number} duration
    **/
    function scroll (element, toPosition, duration) {
      if (duration <= 0) { return; }
      var distance = toPosition - element.scrollTop;
      var tick = distance / duration * 10;
      setTimeout(function () {
        element.scrollTop += tick;
        scroll(element, toPosition, duration - 10);
      }, 10);
    }
  };
  return PersonalWebsite;
})(document, window);

document.addEventListener('DOMContentLoaded', function () {
  var pw = new PersonalWebsite();
});
<commit_msg>Close menu on click on download cv button<commit_after>var PersonalWebsite = (function (document, window) {
  'use strict';
  var PersonalWebsite = function () {
    var header, hamburgerIcon;

    init();

    function init () {
      header = document.querySelector('.header');
      hamburgerIcon = document.querySelector('.nav__icon');

      bindEvents();
    }

    function bindEvents () {
      window.addEventListener('scroll', toggleFixedHeader);
      hamburgerIcon.addEventListener('click', toggleHeaderAnimation);
      addScroll('.intro__paragraph-pink');
      addScroll('.navigation__item a');
      document.querySelector('.navigation__item--cv').addEventListener('click', updateHeader);
    }

    function toggleFixedHeader () {
      var intro = document.querySelector('.intro');
      var headerHeight = header.offsetHeight;
      var parallaxHeight = document.querySelector('.parallax').offsetHeight;
      if (document.body.scrollTop >= parallaxHeight) {
        header.classList.remove('js-slide-up');
        header.classList.add('js-header--fixed', 'js-slide-down');
        intro.style.paddingTop = headerHeight + 'px';
      } else {
        header.classList.remove('js-header--fixed', 'js-slide-down');
        header.classList.add('js-slide-up');
        intro.style.paddingTop = '0px';
      }
    }

    function toggleHeaderAnimation () {
      var navigation = document.querySelector('.navigation');
      var isOpen = false;
      this.classList.toggle('active'); // animates humburder icon
      if (navigation.classList.contains('active')) {
        navigation.classList.remove('active', 'js-slide-down');
        navigation.classList.add('js-slide-up');
        isOpen = false;
      } else {
        navigation.classList.remove('js-slide-up');
        navigation.classList.add('active', 'js-slide-down');
        isOpen = true;
      }
      resizeHeaderOnMobile(isOpen);
    }
    /**
    *  @param {Boolean} isOpen
    **/
    function resizeHeaderOnMobile (isOpen) {
      if (window.innerWidth < 768 && isOpen === true) {
        header.classList.add('active');
      } else {
        header.classList.remove('active');
      }
    }

    function updateHeader () {
      if (header.classList.contains('active')) {
        header.classList.remove('active');
        document.querySelector('.navigation').classList.remove('active');
        hamburgerIcon.classList.remove('active');
      } else {
        header.classList.add('active');
        document.querySelector('.navigation').classList.add('active');
        hamburgerIcon.classList.add('active');
      }
    }

    /**
    *  @param {String} selector
    **/
    function addScroll (selector) {
      var arrayOfElements = document.querySelectorAll(selector);
      Array.apply(null, arrayOfElements).forEach(function (element) {
        element.addEventListener('click', function (e) {
          e.preventDefault();
          var target = document.getElementById(element.getAttribute('href').slice(1));
          updateHeader();
          scroll(document.body, target.offsetTop, 300);
        });
      });
    }
    /**
    *  @param {HTMLElement} element
    *  @param {HTMLElement} toPosition
    *  @param {Number} duration
    **/
    function scroll (element, toPosition, duration) {
      if (duration <= 0) { return; }
      var distance = toPosition - element.scrollTop;
      var tick = distance / duration * 10;
      setTimeout(function () {
        element.scrollTop += tick;
        scroll(element, toPosition, duration - 10);
      }, 10);
    }
  };
  return PersonalWebsite;
})(document, window);

document.addEventListener('DOMContentLoaded', function () {
  var pw = new PersonalWebsite();
});
<|endoftext|>


<commit_before>(function() {
  module.exports = function(config) {
    return config.set({
      basePath: "public",
      frameworks: ["mocha", "sinon-chai"],
      files: ["bower_components/lodash/dist/lodash.js", "bower_components/jquery/jquery.js", "bower_components/angular/angular.js", "bower_components/angular-sanitize/angular-sanitize.js", "bower_components/angular-ui-router/release/angular-ui-router.js", "bower_components/angular-file-upload/angular-file-upload.js", "bower_components/bootstrap-sass/dist/js/bootstrap.js", "bower_components/firebase/firebase.js", "bower_components/angularfire/angularfire.js", "bower_components/angular/", "bower_components/angular-mocks/angular-mocks.js", "scripts/**/*.coffee", "tests/**/*.coffee"],
      exclude: [],
      port: 8080,
      logLevel: config.LOG_INFO,
      autoWatch: false,
      browsers: ["Chrome"],
      singleRun: false
    });
  };

}).call(this);
<commit_msg>Not sure how that ended up there.<commit_after><|endoftext|>


<commit_before>
(function(document, window, $){

  var apiUrl = 'http://' +  window.location.hostname + ':' + window.location.port;

  var garageDoorStatus = function(){
    return $.get(apiUrl + '/status');
  };

  var toggleGarageDoor = function(){
    return $.post(apiUrl + '/toggle');
  }

  $('#toggleBtn').on('click', function(){
    toggleGarageDoor();
  });

  setTimeout(function(){
    garageDoorStatus().done(function(response){
      $('#status').text(response.text);
    });
  }, 1000)

})(document, window, $)
<commit_msg>setinterval not timeout, duh :: master<commit_after>
(function(document, window, $){
  var apiUrl = 'http://' +  window.location.hostname + ':' + window.location.port;

  var garageDoorStatus = function(){
    return $.get(apiUrl + '/status');
  };

  var toggleGarageDoor = function(){
    return $.post(apiUrl + '/toggle');
  }

  $('#toggleBtn').on('click', function(){
    toggleGarageDoor();
  });

  setInterval(function(){
    garageDoorStatus().done(function(response){
      $('#status').text(response.text);
    });
  }, 1000)

})(document, window, $)
<|endoftext|>


<commit_before>//Class for the Link properties tab that appears when link settings are clicked.

var LinkInspector = Backbone.View.extend({

  className: 'link-inspector',

  template: [
    'Constant Relationship',
    '
',
    '<select class="link-type">',
      '<option value=and>And-Decomposition</option>',
      '<option value=or>Or-Decomposition (Means-end)</option>',
      '<option value=depends>Depends</option>',
      '<option value=makes>Makes</option>',
      '<option value=breaks>Breaks</option>',
      '<option value=helps>Helps</option>',
      '<option value=hurts>Hurts</option>',
    '</select>',
    '
',
      '

',
      '<select id="link-type-begin" class="repeat-select">',
        '<option class="select-placeholder" selected disabled value="">Begin</option>',
      '</select>',
      '<select id="link-type-end" class="repeat-select">',
        '<option class="select-placeholder" selected disabled value="">End</option>',
      '</select>',
      '<button id="switch-link-type" class="inspector-btn small-btn blue-btn">Evolving Relationships</button>',
    '
',
    '
'
  ].join(''),

  actortemplate: [
      ' Link Type
',
      '<select class="link-type">',
        '<option value="is-a">is-a</option>',
        '<option value="plays">plays</option>',
        '<option value="is-part-of">is-part-of</option>',
      '</select>
'].join(''),

  events: {
    'change .link-type': 'updateCell',
    'change #link-type-begin': 'updateEvolvingRelations',
    'change #link-type-end': 'updateEvolvingRelations',

    'click #switch-link-type': 'switchMode',
  },

  //Method to create the Link Inspector using the template.
  render: function(cellView) {
    this._cellView = cellView;
    var cell = this._cellView.model;
    var type = cellView.model.attributes.labels[0].attrs.text.text

    this.relationTextA = ["And-Decomposition", "Or-Decomposition (Means-end)", "Depends"];
    this.relationTextB = ["Makes", "Breaks", "Helps", "Hurts"];
    this.relationValA = ["and", "or", "depends"];
    this.relationValB = ["makes", "breaks", "helps", "hurts"];

    // select template
    if (cell.prop("linktype")){
      this.$el.html(_.template(this.actortemplate)());
    }else{
      this.$el.html(_.template(this.template)());
    }

    // already intialized previously
    if (cell.prop("link-type")){
      var val = cell.prop("link-type").split("|");

      // normal relation
      if (val.length == 1){
        this.$('.link-type').val(val[0]);
        this.$('#link-type-begin').hide();
        this.$('#link-type-end').hide();
        this.evolvingRelations = false;

      // evolving relation
      }else{
        this.evolvingRelations = true;

        $(".link-type").hide();
        this.appendSelectValues($('#link-type-begin'), "All");
        $('#link-type-begin').val(val[0]);
        this.updateEvolvingRelations(null, true);
        $('#link-type-end').val(val[1]);

        $("#repeat-error").text("");
      }
    // unitialzed relations
    }else{
      this.$('#link-type-begin').hide();
      this.$('#link-type-end').hide();
      this.evolvingRelations = false;
    }

    cell.on('remove', function() {
      this.$el.html('');
    }, this);

  },

  // Switch between evolving and constant relationships
  switchMode: function(){
    // Turn on
    if (!this.evolvingRelations){
      $(".link-type").hide();
      $('#link-type-begin').show("fast");
      $('#link-type-end').show("fast");

      $("#link-type-end").prop('disabled', 'disabled');
      $("#link-type-end").css("background-color","grey");

      $("#title").text("Evolving Relationship");
      $("#switch-link-type").text("Constant Relationship");

      this.appendSelectValues($('#link-type-begin'), "All");

    // Turn off
    }else{
      $('.link-type').show("fast");
      $('#link-type-begin').hide();
      $('#link-type-end').hide();
      $("#repeat-error").hide();

      $("#title").text("Constant Relationship");
      $("#switch-link-type").text("Evolving Relationship");
    }

    this.evolvingRelations = !this.evolvingRelations;
  },

  // Generates the drop values based on connected intentions
  updateEvolvingRelations: function(e, intialize){
    var target;
    var value;

    // used to render from initialization
    if (intialize){
      target = "link-type-begin";
      value = $('#link-type-begin').val();

    // used to render from click
    }else{
      target = e.target.id;
      value = e.target.value;
    }

    // update selects for link-type-end
    if (target == "link-type-begin"){

      $("#link-type-end").prop('disabled', '');
      $("#link-type-end").css("background-color","");

      $("#repeat-error").text("Please select End Relationship");
      $("#repeat-error").css("color", "");
      $("#repeat-error").show("fast");

      if (value == "NA"){
        this.appendSelectValues($("#link-type-end"), "All");
      }else if(this.relationValA.indexOf(value) != -1){
        this.appendSelectValues($("#link-type-end"), "A");
      }else if(this.relationValB.indexOf(value) != -1){
        this.appendSelectValues($("#link-type-end"), "B");
      }

    // save value
    }else if(target == "link-type-end"){
      $("#repeat-error").text("Saved!");
      $("#repeat-error").css("color", "lightgreen");

      this.updateCell();
    }
  },

  // Restrict select options based on selection made in link-type begin
  appendSelectValues: function(select, type){
    if (select.attr("id") == "link-type-begin"){
      select.html('<option class="select-placeholder" selected disabled value="">Begin</option>');
    }else if (select.attr("id") == "link-type-end"){
      select.html('<option class="select-placeholder" selected disabled value="">End</option>');
    }

    select.append($('<option></option>').val("NA").html("No Relationship"));
    if(type == "All"){
      for (var i = 0; i < this.relationTextA.length; i++)
        select.append($('<option></option>').val(this.relationValA[i]).html(this.relationTextA[i]));
      for (var i = 0; i < this.relationTextB.length; i++)
        select.append($('<option></option>').val(this.relationValB[i]).html(this.relationTextB[i]));

    }else if (type == "A"){
      select.val("NA");
      $("#repeat-error").text("Saved!");
      $("#repeat-error").css("color", "lightgreen");
      $("#link-type-end").prop('disabled', '');
      $("#link-type-end").css("background-color","");
      this.updateCell();

    }else if (type == "B"){
      for (var i = 0; i < this.relationTextB.length; i++)
        select.append($('<option></option>').val(this.relationValB[i]).html(this.relationTextB[i]));
    }

    // Remove duplicate options
    if (select.attr("id") == "link-type-end"){
      var dupVal = this.$('#link-type-begin').val();
      $("select#link-type-end option").filter("[value='" + dupVal + "']").remove();
    }
  },

  //Whenever something is changed in the inspector, make the corresponding change to the link in the model.
  updateCell: function() {
    var link = this._cellView.model;

    // Save based on evolving relations
    if(this.evolvingRelations){
      var begin = $("#link-type-begin").val();
      var end = $("#link-type-end").val();

      this._cellView.model.prop("link-type", begin + "|" + end);
      link.attr({
        '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
        '.marker-source': {'d': '0'},
        '.marker-target': {stroke: '#000000', "d": 'M 10 0 L 0 5 L 10 10 L 0 5 L 10 10 L 0 5 L 10 5 L 0 5'}
      });
      link.label(0 ,{position: 0.5, attrs: {text: {text: begin + " | " + end}}});

    // Save based on normal relations
    }else{
      this._cellView.model.prop("link-type", this.$('.link-type').val());
      if (this._cellView.model.prop("link-type") == 'and'){
        link.attr({
          '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
          '.marker-source': {'d': '0'},
          '.marker-target': {stroke: '#000000', 'stroke-width': 1, "d": 'M 10 0 L 10 10 M 10 5 L 0 5' }
        });
        link.label(0 ,{position: 0.5, attrs: {text: {text: 'and'}}});

      }else if (this._cellView.model.prop("link-type") == 'or' || this._cellView.model.prop("link-type") == 'xor'){
        link.attr({
          '.connection': {stroke: '#000000', 'stroke-dasharray': '5 2'},
          '.marker-source': {'d': '0'},
          '.marker-target': {stroke: '#000000', "d": 'M 10 0 L 0 5 L 10 10 z'}
        });
        link.label(0 ,{position: 0.5, attrs: {text: {text: link.prop("link-type")}}});

      }else{
        link.attr({
          '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
          '.marker-source': {'d': '0'},
          '.marker-target': {stroke: '#000000', "d": 'M 10 0 L 0 5 L 10 10 L 0 5 L 10 10 L 0 5 L 10 5 L 0 5'}
        });
        link.label(0 ,{position: 0.5, attrs: {text: {text: link.prop("link-type")}}});
      }
    }
  },

  //Displays the additional options when delayed propagation is checked.
  checkboxHandler: function(e){
    if (e.currentTarget.checked){
      document.getElementById("hidden").removeAttribute("style");
    }
    else{
      document.getElementById("hidden").setAttribute("style", "display:none");
    }
  },

  clear: function(){
    this.$el.html('');
  }
});
<commit_msg>Updated constant relationship in linkspector<commit_after>//Class for the Link properties tab that appears when link settings are clicked.

var LinkInspector = Backbone.View.extend({

  className: 'link-inspector',

  template: [
    'Constant Relationship',
    '
',
    '<select class="link-type">',
      '<option value=and>And-Decomposition</option>',
      '<option value=or>Or-Decomposition (Means-end)</option>',
      '<option value=PP>++</option>',
      '<option value=NN>--</option>',
      '<option value=P>+</option>',
      '<option value=N>-</option>',
      '<option value=PS>+S</option>',
      '<option value=PPS>++S</option>',
      '<option value=NS>-S</option>',
      '<option value=NNS>--S</option>',
      '<option value=PD>+D</option>',
      '<option value=PPD>++D</option>',
      '<option value=ND>-D</option>',
      '<option value=NND>--D</option>',
      '<option value=NBT>Noth Both (None)</option>',
      '<option value=NBD>Not Both (Denied)</option>',

    '</select>',
    '
',
      '

',
      '<select id="link-type-begin" class="repeat-select">',
        '<option class="select-placeholder" selected disabled value="">Begin</option>',
      '</select>',
      '<select id="link-type-end" class="repeat-select">',
        '<option class="select-placeholder" selected disabled value="">End</option>',
      '</select>',
      '<button id="switch-link-type" class="inspector-btn small-btn blue-btn">Evolving Relationships</button>',
    '
',
    '
'
  ].join(''),

  actortemplate: [
      ' Link Type
',
      '<select class="link-type">',
        '<option value="is-a">is-a</option>',
        '<option value="plays">plays</option>',
        '<option value="is-part-of">is-part-of</option>',
      '</select>
'].join(''),

  events: {
    'change .link-type': 'updateCell',
    'change #link-type-begin': 'updateEvolvingRelations',
    'change #link-type-end': 'updateEvolvingRelations',

    'click #switch-link-type': 'switchMode',
  },

  //Method to create the Link Inspector using the template.
  render: function(cellView) {
    this._cellView = cellView;
    var cell = this._cellView.model;
    var type = cellView.model.attributes.labels[0].attrs.text.text

    this.relationTextA = ["And-Decomposition", "Or-Decomposition (Means-end)"];
    this.relationTextB = ["Makes", "Breaks", "Helps", "Hurts"];
    this.relationValA = ["and", "or"];
    this.relationValB = ["makes", "breaks", "helps", "hurts"];

    // select template
    if (cell.prop("linktype")){
      this.$el.html(_.template(this.actortemplate)());
    }else{
      this.$el.html(_.template(this.template)());
    }

    // already intialized previously
    if (cell.prop("link-type")){
      var val = cell.prop("link-type").split("|");

      // normal relation
      if (val.length == 1){
        this.$('.link-type').val(val[0]);
        this.$('#link-type-begin').hide();
        this.$('#link-type-end').hide();
        this.evolvingRelations = false;

      // evolving relation
      }else{
        this.evolvingRelations = true;

        $(".link-type").hide();
        this.appendSelectValues($('#link-type-begin'), "All");
        $('#link-type-begin').val(val[0]);
        this.updateEvolvingRelations(null, true);
        $('#link-type-end').val(val[1]);

        $("#repeat-error").text("");
      }
    // unitialzed relations
    }else{
      this.$('#link-type-begin').hide();
      this.$('#link-type-end').hide();
      this.evolvingRelations = false;
    }

    cell.on('remove', function() {
      this.$el.html('');
    }, this);

  },

  // Switch between evolving and constant relationships
  switchMode: function(){
    // Turn on
    if (!this.evolvingRelations){
      $(".link-type").hide();
      $('#link-type-begin').show("fast");
      $('#link-type-end').show("fast");

      $("#link-type-end").prop('disabled', 'disabled');
      $("#link-type-end").css("background-color","grey");

      $("#title").text("Evolving Relationship");
      $("#switch-link-type").text("Constant Relationship");

      this.appendSelectValues($('#link-type-begin'), "All");

    // Turn off
    }else{
      $('.link-type').show("fast");
      $('#link-type-begin').hide();
      $('#link-type-end').hide();
      $("#repeat-error").hide();

      $("#title").text("Constant Relationship");
      $("#switch-link-type").text("Evolving Relationship");
    }

    this.evolvingRelations = !this.evolvingRelations;
  },

  // Generates the drop values based on connected intentions
  updateEvolvingRelations: function(e, intialize){
    var target;
    var value;

    // used to render from initialization
    if (intialize){
      target = "link-type-begin";
      value = $('#link-type-begin').val();

    // used to render from click
    }else{
      target = e.target.id;
      value = e.target.value;
    }

    // update selects for link-type-end
    if (target == "link-type-begin"){

      $("#link-type-end").prop('disabled', '');
      $("#link-type-end").css("background-color","");

      $("#repeat-error").text("Please select End Relationship");
      $("#repeat-error").css("color", "");
      $("#repeat-error").show("fast");

      if (value == "NA"){
        this.appendSelectValues($("#link-type-end"), "All");
      }else if(this.relationValA.indexOf(value) != -1){
        this.appendSelectValues($("#link-type-end"), "A");
      }else if(this.relationValB.indexOf(value) != -1){
        this.appendSelectValues($("#link-type-end"), "B");
      }

    // save value
    }else if(target == "link-type-end"){
      $("#repeat-error").text("Saved!");
      $("#repeat-error").css("color", "lightgreen");

      this.updateCell();
    }
  },

  // Restrict select options based on selection made in link-type begin
  appendSelectValues: function(select, type){
    if (select.attr("id") == "link-type-begin"){
      select.html('<option class="select-placeholder" selected disabled value="">Begin</option>');
    }else if (select.attr("id") == "link-type-end"){
      select.html('<option class="select-placeholder" selected disabled value="">End</option>');
    }

    select.append($('<option></option>').val("NA").html("No Relationship"));
    if(type == "All"){
      for (var i = 0; i < this.relationTextA.length; i++)
        select.append($('<option></option>').val(this.relationValA[i]).html(this.relationTextA[i]));
      for (var i = 0; i < this.relationTextB.length; i++)
        select.append($('<option></option>').val(this.relationValB[i]).html(this.relationTextB[i]));

    }else if (type == "A"){
      select.val("NA");
      $("#repeat-error").text("Saved!");
      $("#repeat-error").css("color", "lightgreen");
      $("#link-type-end").prop('disabled', '');
      $("#link-type-end").css("background-color","");
      this.updateCell();

    }else if (type == "B"){
      for (var i = 0; i < this.relationTextB.length; i++)
        select.append($('<option></option>').val(this.relationValB[i]).html(this.relationTextB[i]));
    }

    // Remove duplicate options
    if (select.attr("id") == "link-type-end"){
      var dupVal = this.$('#link-type-begin').val();
      $("select#link-type-end option").filter("[value='" + dupVal + "']").remove();
    }
  },

  //Whenever something is changed in the inspector, make the corresponding change to the link in the model.
  updateCell: function() {
    var link = this._cellView.model;

    // Save based on evolving relations
    if(this.evolvingRelations){
      var begin = $("#link-type-begin").val();
      var end = $("#link-type-end").val();

      this._cellView.model.prop("link-type", begin + "|" + end);
      link.attr({
        '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
        '.marker-source': {'d': '0'},
        '.marker-target': {stroke: '#000000', "d": 'M 10 0 L 0 5 L 10 10 L 0 5 L 10 10 L 0 5 L 10 5 L 0 5'}
      });
      link.label(0 ,{position: 0.5, attrs: {text: {text: begin + " | " + end}}});

    // Save based on normal relations
    }else{
      this._cellView.model.prop("link-type", this.$('.link-type').val());
      if (this._cellView.model.prop("link-type") == 'and' || this._cellView.model.prop("link-type") == 'or' || this._cellView.model.prop("link-type") == 'NBT' || this._cellView.model.prop("link-type") == 'NBD'){
        link.attr({
          '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
          '.marker-source': {'d': '0'},
          '.marker-target': {stroke: '#000000', "d": 'M 10 0 L 0 5 L 10 10 L 0 5 L 10 10 L 0 5 L 10 5 L 0 5'}
        });
        link.label(0 ,{position: 0.5, attrs: {text: {text: link.prop("link-type")}}});

      }else{
        link.attr({
          '.connection': {stroke: '#000000', 'stroke-dasharray': '0 0'},
          '.marker-source': {'d': '0'},
          '.marker-target': {stroke: '#000000', "d": 'M 10 0 L 0 5 L 10 10 L 0 5 L 10 10 L 0 5 L 10 5 L 0 5'}
        });
        console.log(this.$('.link-type'));
        link.label(0 ,{position: 0.5, attrs: {text: {text: this.$('.link-type option:selected').text()}}});
      }
    }
  },

  //Displays the additional options when delayed propagation is checked.
  checkboxHandler: function(e){
    if (e.currentTarget.checked){
      document.getElementById("hidden").removeAttribute("style");
    }
    else{
      document.getElementById("hidden").setAttribute("style", "display:none");
    }
  },

  clear: function(){
    this.$el.html('');
  }
});
<|endoftext|>


<commit_before>

(/** @lends <global> */function() {

var _api = DataTable.Api;

/**
 *
 */
_api.register( 'rows()', function ( selector, opts ) {
	// argument shifting
	if ( selector === undefined ) {
		selector = '';
	}
	else if ( $.isPlainObject( selector ) ) {
		opts = selector;
		selector = '';
	}

	opts = _selector_opts( opts );

	var inst = this.iterator( 'table', function ( settings ) {
		return _row_selector( settings, selector, opts );
	} );

	// Want argument shifting here and in _row_selector?
	inst.selector.rows = selector;
	inst.selector.opts = opts;

	return inst;
} );

_api.registerPlural( 'rows().nodes()', 'row().node()' , function () {
	return this.iterator( 'row', function ( settings, row ) {
		// use pluck order on an array rather - rows gives an array, row gives it individually
		return settings.aoData[ row ].nTr || undefined;
	} );
} );

_api.register( 'rows().data()', function ( data ) {
	return this.iterator( true, 'rows', function ( settings, rows ) {
		return _pluck_order( settings.aoData, rows, '_aData' );
	} );
} );

_api.registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
	return this.iterator( 'row', function ( settings, row ) {
		_fnInvalidateRow( settings, row, src );
	} );
} );

_api.registerPlural( 'rows().index()', 'row().index()', function ( src ) {
	return this.iterator( 'row', function ( settings, row ) {
		return row;
	} );
} );

_api.registerPlural( 'rows().remove()', 'row().remove()', function () {
	var that = this;

	return this.iterator( 'row', function ( settings, row, thatIdx ) {
		var data = settings.aoData;

		data.splice( row, 1 );

		// Update the _DT_RowIndex parameter on all rows in the table
		for ( var i=0, ien=data.length ; i<ien ; i++ ) {
			if ( data[i].nTr !== null ) {
				data[i].nTr._DT_RowIndex = i;
			}
		}

		// Remove the target row from the search array
		var displayIndex = $.inArray( row, settings.aiDisplay );
		settings.asDataSearch.splice( displayIndex, 1 );

		// Delete from the display arrays
		_fnDeleteIndex( settings.aiDisplayMaster, row );
		_fnDeleteIndex( settings.aiDisplay, row );
		_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes

		// Check for an 'overflow' they case for displaying the table
		_fnLengthOverflow( settings );
	} );
} );

_api.register( 'rows.add()', function ( rows ) {
	var newRows = this.iterator( 'table', function ( settings ) {
			var row, i, ien;
			var out = [];

			for ( i=0, ien=rows.length ; i<ien ; i++ ) {
				row = rows[i];

				if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
					out.push( _fnAddTr( settings, row ) )[0];
				}
				else {
					out.push( _fnAddData( settings, row ) );
				}
			}

			return out;
		} );

	// Return an Api.rows() extended instance, so rows().nodes() etc can be used
	var modRows = this.rows( -1 );
	modRows.pop();
	modRows.push.apply( modRows, newRows );

	return modRows;
} );

/**
 *
 */
_api.register( 'row()', function ( selector, opts ) {
	return _selector_first( this.rows( selector, opts ) );
} );

_api.register( 'row().data()', function ( data ) {
	var ctx = this.context;

	if ( data === undefined ) {
		// Get
		return ctx.length && this.length ?
			ctx[0].aoData[ this[0] ]._aData :
			undefined;
	}

	// Set
	ctx[0].aoData[ this[0] ]._aData = data;

	// Automatically invalidate
	_fnInvalidateRow( ctx[0], this[0], 'data' );

	return this;
} );

_api.register( 'row.add()', function ( row ) {
	// Allow a jQuery object to be passed in - only a single row is added from
	// it though - the first element in the set
	if ( row instanceof $ && row.length ) {
		row = row[0];
	}

	var rows = this.iterator( 'table', function ( settings ) {
		if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
			return _fnAddTr( settings, row )[0];
		}
		return _fnAddData( settings, row );
	} );

	// Return an Api.rows() extended instance, with the newly added row selected
	return this.row( rows[0] );
} );

}());

<commit_msg>Dev fix: rows.add() API was trying to get the row index from the wrong parameter.<commit_after>

(/** @lends <global> */function() {

var _api = DataTable.Api;

/**
 *
 */
_api.register( 'rows()', function ( selector, opts ) {
	// argument shifting
	if ( selector === undefined ) {
		selector = '';
	}
	else if ( $.isPlainObject( selector ) ) {
		opts = selector;
		selector = '';
	}

	opts = _selector_opts( opts );

	var inst = this.iterator( 'table', function ( settings ) {
		return _row_selector( settings, selector, opts );
	} );

	// Want argument shifting here and in _row_selector?
	inst.selector.rows = selector;
	inst.selector.opts = opts;

	return inst;
} );

_api.registerPlural( 'rows().nodes()', 'row().node()' , function () {
	return this.iterator( 'row', function ( settings, row ) {
		// use pluck order on an array rather - rows gives an array, row gives it individually
		return settings.aoData[ row ].nTr || undefined;
	} );
} );

_api.register( 'rows().data()', function ( data ) {
	return this.iterator( true, 'rows', function ( settings, rows ) {
		return _pluck_order( settings.aoData, rows, '_aData' );
	} );
} );

_api.registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {
	return this.iterator( 'row', function ( settings, row ) {
		_fnInvalidateRow( settings, row, src );
	} );
} );

_api.registerPlural( 'rows().index()', 'row().index()', function ( src ) {
	return this.iterator( 'row', function ( settings, row ) {
		return row;
	} );
} );

_api.registerPlural( 'rows().remove()', 'row().remove()', function () {
	var that = this;

	return this.iterator( 'row', function ( settings, row, thatIdx ) {
		var data = settings.aoData;

		data.splice( row, 1 );

		// Update the _DT_RowIndex parameter on all rows in the table
		for ( var i=0, ien=data.length ; i<ien ; i++ ) {
			if ( data[i].nTr !== null ) {
				data[i].nTr._DT_RowIndex = i;
			}
		}

		// Remove the target row from the search array
		var displayIndex = $.inArray( row, settings.aiDisplay );
		settings.asDataSearch.splice( displayIndex, 1 );

		// Delete from the display arrays
		_fnDeleteIndex( settings.aiDisplayMaster, row );
		_fnDeleteIndex( settings.aiDisplay, row );
		_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes

		// Check for an 'overflow' they case for displaying the table
		_fnLengthOverflow( settings );
	} );
} );

_api.register( 'rows.add()', function ( rows ) {
	var newRows = this.iterator( 'table', function ( settings ) {
			var row, i, ien;
			var out = [];

			for ( i=0, ien=rows.length ; i<ien ; i++ ) {
				row = rows[i];

				if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
					out.push( _fnAddTr( settings, row )[0] );
				}
				else {
					out.push( _fnAddData( settings, row ) );
				}
			}

			return out;
		} );

	// Return an Api.rows() extended instance, so rows().nodes() etc can be used
	var modRows = this.rows( -1 );
	modRows.pop();
	modRows.push.apply( modRows, newRows );

	return modRows;
} );

/**
 *
 */
_api.register( 'row()', function ( selector, opts ) {
	return _selector_first( this.rows( selector, opts ) );
} );

_api.register( 'row().data()', function ( data ) {
	var ctx = this.context;

	if ( data === undefined ) {
		// Get
		return ctx.length && this.length ?
			ctx[0].aoData[ this[0] ]._aData :
			undefined;
	}

	// Set
	ctx[0].aoData[ this[0] ]._aData = data;

	// Automatically invalidate
	_fnInvalidateRow( ctx[0], this[0], 'data' );

	return this;
} );

_api.register( 'row.add()', function ( row ) {
	// Allow a jQuery object to be passed in - only a single row is added from
	// it though - the first element in the set
	if ( row instanceof $ && row.length ) {
		row = row[0];
	}

	var rows = this.iterator( 'table', function ( settings ) {
		if ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {
			return _fnAddTr( settings, row )[0];
		}
		return _fnAddData( settings, row );
	} );

	// Return an Api.rows() extended instance, with the newly added row selected
	return this.row( rows[0] );
} );

}());

<|endoftext|>


<commit_before>// Welcome Dialog
// by Grant Dickie
// MITH 2011

var WelcomeDialog=function(args){
	// Constructor
	// args same as Dialog()
		var self=this;
		// Constructor:
		//
		// @param:
		// Obj: variables:
		// 	loc: {String} DOM object to be attached to
		if((!args.loc)) throw "Not enough arguments passed to Dialog";
		self.loc=args.loc;
		//set up JSON html
		var html='

Welcome

'+
		'

Introduction to TILE
'+
		'
The Text-Image Linking Environment (TILE) is a tool for creating and editing image-based electronic editions and digital archives of humanities texts.
'+
		'
This initial release of TILE features:'+
		'
* importing and exporting transcript lines and images of text
'+
		'* an image markup tool
'+
		'* a semi-automated line recognizer
'+
		'
'+
		'Read more >

Continue >

0.9

'+
		'

';
		$(html).appendTo(self.loc);
		self.index=($("#dialog").length+self.loc.width());

		// flash the a elements to get people to click on them
		$("#welcomeDialog > .body > .description > p > #importHover").animate({color:"green","left":"+=50px"},1000,function(){
			$("#welcomeDialog > .body > .description > p > #importHover").css({color:"#000","left":"-=50px"});
			// animation complete - reset importHover and move to next
			$("#welcomeDialog > .body > .description > p > #imageHover").animate({color:'green'},1000,function(){
				$("#welcomeDialog > .body > .description > p > #imageHover").css({color:'#000'});
				// animation complete - back to normal
				$("#welcomeDialog > .body > .description > p > #ALRHover").animate({color:'green'},1000,function(){
					// finally - return to normal
					$("#welcomeDialog > .body > .description > p > #ALRHover").css({color:'#000'});
				});
			});
		});

		// $('

').appendTo($("body"));
		// 	$('

').appendTo($("body"));
		// 	$('

').appendTo($("body"));

		$("#continueButton").live('click',function(e){
			e.preventDefault();
			$("#light").remove();
			$("#fade").remove();
		});
		// attach events for hover items

		$("#importHover").live('click',function(e){
			e.preventDefault();

			$("#importShot").show();
			// remove from DOM
			$("#light").remove();
			$("#fade").remove();
			// activate the Load Dialog
			$("#azglobalmenu > .globalbuttons > .dataitems > .menuitem > a:contains('Load')").trigger('click');

		});
		// $("#importHover").live('mouseout',function(e){
		// 			$("#importShot").hide();
		// 		});
		$("#imageHover").live('click',function(e){
			e.preventDefault();
			$("#imageShot").show();
			// imagetagger already active, simply remove the dialog from
			// the screen
			$("#light").remove();
			$("#fade").remove();
		});
		// $("#imageHover").live('mouseout',function(e){
		// 			$("#imageShot").hide();
		// 		});
		$("#ALRHover").live('click',function(e){
			e.preventDefault();
			$("#ALRShot").show();
			// remove from DOM
			$("#light").remove();
			$("#fade").remove();
			// activate the ALR
			$("#azglobalmenu > .globalbuttons > .modeitems > .menuitem > a:contains('Auto Line Recognizer')").trigger('click');
		});
		// $("#ALRHover").live('mouseout',function(e){
		// 			$("#ALRShot").hide();
		// 		});
		//lightbox content
		self.light=$("#light");
		self.fade=$("#fade");
		self.DOM=$("#welcomeDialog");

};
WelcomeDialog.prototype={
	showAndHide:function(elem){
		var self=this;

	}
};
var WD={
	id:"WD1090910",
	// wrapper for TILE
	start:function(engine){
		var self=this;
		self.dialog=new WelcomeDialog({loc:$("body")});

		// show dialog at beginning - user clicks continue
		// and dialog goes away
		$("#light").show();
		$("#fade").show();
		$("#welcomeDialog").show();

	}

};<commit_msg>Changed HTML layout for welcome dialog<commit_after>// Welcome Dialog
// by Grant Dickie
// MITH 2011

var WelcomeDialog=function(args){
	// Constructor
	// args same as Dialog()
		var self=this;
		// Constructor:
		//
		// @param:
		// Obj: variables:
		// 	loc: {String} DOM object to be attached to
		if((!args.loc)) throw "Not enough arguments passed to Dialog";
		self.loc=args.loc;
		//set up JSON html
		var html='

Welcome

'+
		'

'+
		'
The Text-Image Linking Environment (TILE) is a tool for creating and editing image-based electronic editions and digital archives of humanities texts.
'+
		'
This 0.9 release of TILE features:'+
		'
* importing and exporting transcript lines and images of text
'+
		'* an image markup tool
'+
		'* a semi-automated line recognizer
'+
		'
'+
		'
Continue >

'+
		'

';
		$(html).appendTo(self.loc);
		self.index=($("#dialog").length+self.loc.width());

		// flash the a elements to get people to click on them
		$("#welcomeDialog > .body > .description > p > #importHover").animate({color:"green","left":"+=50px"},1000,function(){
			$("#welcomeDialog > .body > .description > p > #importHover").css({color:"#000","left":"-=50px"});
			// animation complete - reset importHover and move to next
			$("#welcomeDialog > .body > .description > p > #imageHover").animate({color:'green'},1000,function(){
				$("#welcomeDialog > .body > .description > p > #imageHover").css({color:'#000'});
				// animation complete - back to normal
				$("#welcomeDialog > .body > .description > p > #ALRHover").animate({color:'green'},1000,function(){
					// finally - return to normal
					$("#welcomeDialog > .body > .description > p > #ALRHover").css({color:'#000'});
				});
			});
		});

		// $('

').appendTo($("body"));
		// 	$('

').appendTo($("body"));
		// 	$('

').appendTo($("body"));

		$("#continueButton").live('click',function(e){
			e.preventDefault();
			$("#light").remove();
			$("#fade").remove();
		});
		// attach events for hover items

		$("#importHover").live('click',function(e){
			e.preventDefault();

			$("#importShot").show();
			// remove from DOM
			$("#light").remove();
			$("#fade").remove();
			// activate the Load Dialog
			$("#azglobalmenu > .globalbuttons > .dataitems > .menuitem > a:contains('Load')").trigger('click');

		});
		// $("#importHover").live('mouseout',function(e){
		// 			$("#importShot").hide();
		// 		});
		$("#imageHover").live('click',function(e){
			e.preventDefault();
			$("#imageShot").show();
			// imagetagger already active, simply remove the dialog from
			// the screen
			$("#light").remove();
			$("#fade").remove();
		});
		// $("#imageHover").live('mouseout',function(e){
		// 			$("#imageShot").hide();
		// 		});
		$("#ALRHover").live('click',function(e){
			e.preventDefault();
			$("#ALRShot").show();
			// remove from DOM
			$("#light").remove();
			$("#fade").remove();
			// activate the ALR
			$("#azglobalmenu > .globalbuttons > .modeitems > .menuitem > a:contains('Auto Line Recognizer')").trigger('click');
		});
		// $("#ALRHover").live('mouseout',function(e){
		// 			$("#ALRShot").hide();
		// 		});
		//lightbox content
		self.light=$("#light");
		self.fade=$("#fade");
		self.DOM=$("#welcomeDialog");

};
WelcomeDialog.prototype={
	showAndHide:function(elem){
		var self=this;

	}
};
var WD={
	id:"WD1090910",
	// wrapper for TILE
	start:function(engine){
		var self=this;
		self.dialog=new WelcomeDialog({loc:$("body")});

		// show dialog at beginning - user clicks continue
		// and dialog goes away
		$("#light").show();
		$("#fade").show();
		$("#welcomeDialog").show();

	}

};<|endoftext|>