<commit_before>'use strict';

var extend = require('extend'),
    async = require('async'),
    Promise = require('native-or-bluebird'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    ObjectId = mongoose.Schema.ObjectId,
    mongo = require('./mongo'),
    util = require('./util');

var dbRefSchema = {
    kind: {
        type: String
    },
    id: {
        type: ObjectId
    },
    _id: false
};

var attachmentSchema = {
    _id: ObjectId,
    fileId: ObjectId,
    name: 'string',
    mime: 'string',
    md5: 'string'
};

var baseDefinition = {
    _an: [dbRefSchema],         // Ancestors array
    _ch: [dbRefSchema],         // Children array
    _at: [attachmentSchema],    // Attachments array
    _dc: Date,                  // Date of creation
    _dm: Date,                  // Date of modification
    _gr: [String]               // Groups
};

var baseOptions = {
    strict: 'throw'
};

var kinds = {};

var kindProvider = function defaultProvider(kind, callback) {
    callback(new Error('Kind ' + kind + ' not found'));
};

var hooks = [
    'Save',
    'Remove',
    'Init',
    'Validate'
];

exports.create = function createKind(name, definition, options) {
    if (kinds[name]) {
        throw new Error('Cannot instantiate two kinds with the same name');
    }

    if (!definition || typeof definition !== 'object') {
        throw new Error('Kind definition has to be an object');
    }

    for (var i in definition) {
        if (i[0] === '_') {
            throw new Error('Kind definition cannot contain fields that begin with a "_". Found: ' + i);
        }
    }

    var thisDef = extend({}, baseDefinition, definition);
    var thisOptions = extend({}, baseOptions);

    var thisSchema = new Schema(thisDef, thisOptions);

    options = options || {};

    var hookName, preHookName, postHookName;
    for (i = 0; i < hooks.length; i++) {
        hookName = hooks[i];
        preHookName = 'pre' + hookName;
        if (options[preHookName] && typeof options[preHookName] === 'function') {
            thisSchema.pre(hookName.toLowerCase(), options[preHookName]);
        }
        postHookName = 'post' + hookName;
        if (options[postHookName] && typeof options[postHookName] === 'function') {
            thisSchema.post(hookName.toLowerCase(), options[postHookName]);
        }
    }

    thisSchema.pre('save', function (next) {
        if (!this._dc) {
            this._dc = this._id.getTimestamp();
        }

        this._dm = this.isNew ? this._dc : new Date();

        next();
    });

    thisSchema.index({
        '_an.kind': 1,
        '_an.id': 1
    });

    thisSchema.methods.getKind = thisSchema.statics.getKind = function () {
        return name;
    };

    thisSchema.virtual('owner').set(function (v) {
        this._gr[0] = v; // TODO check
    }).get(function () {
        return this._gr[0];
    });

    thisSchema.methods.createChild = createChild;
    thisSchema.methods.getChildren = getChildren;
    //thisSchema.methods.setParent = setParent;

    thisSchema.methods.createAttachment = createAttachment;
    thisSchema.methods.removeAttachment = removeAttachment;
    thisSchema.methods.getAttachment = getAttachment;

    thisSchema.pre('save', preSaveChild);
    thisSchema.pre('remove', preRemove);

    return kinds[name] = mongoose.model('kind_' + name, thisSchema, 'kind_' + name);
};

function createChild(kind, value) {
    if (this.isNew) {
        throw new Error('Cannot call method createChild of a new unsaved entry');
    }

    var kindModel = exports.getSync(kind);
    var child = new kindModel(value);
    child._gr = this._gr.slice();                           // By default, owner is propagated
    for (var i = 0; i < this._an.length; i++) {
        child._an.push({
            kind: this._an[i].kind,
            id: this._an[i].id
        });
    }
    child._an.push({
        kind: this.getKind(),
        id: this._id
    });
    child._newChild = true;
    child._parent = this;

    util.promisifySave(child);

    return child;
}

function preSaveChild(next) {
    var self = this;
    if (this._newChild) {
        var parentModel = exports.getSync(this._parent.getKind());
        parentModel.findByIdAndUpdate(this._parent._id, {
            $push: {
                _ch: {
                    kind: this.getKind(),
                    id: this._id
                }
            }
        }, function (err) {
            if (err) {
                return next(err);
            }
            self._newChild = false;
            next();
        });
    } else {
        next();
    }
}

function preRemove(next) {
    var ref = {
        kind: this.getKind(),
        id: this._id
    };

    exports.getSync(ref.kind).findById(ref.id, function (err, res) {
        if (err) {
            return next(err);
        }
        // First we have to remove the reference from the parent
        if (res._an.length) {
            var parent = res._an[res._an.length - 1];
            exports.get(parent.kind, function (err, parentModel) {
                if (err) {
                    return next(err);
                }
                parentModel.findByIdAndUpdate(parent.id, {
                    $pull: {
                        _ch: ref
                    }
                }, function (err) {
                    if (err) {
                        return next(err);
                    }
                    async.each(res._ch, removeEntryChildrenAndAttachments, next);
                });
            });
        } else {
            async.each(res._ch, removeEntryChildrenAndAttachments, next);
        }
    });
}

function removeEntryChildrenAndAttachments(entry, cb) {
    exports.get(entry.kind, function (err, entryModel) {
        if (err) {
            return cb(err);
        }
        var childrenRemoved = false,
            attachmentsRemoved = false;

        function checkFinish() {
            if (childrenRemoved && attachmentsRemoved) {
                cb();
            }
        }

        entryModel.findByIdAndRemove(entry.id, function (err, result) {
            if (err) {
                return cb(err);
            }
            if (result) {
                async.each(result._ch, removeEntryChildrenAndAttachments, function (err) {
                    if (err) {
                        return cb(err);
                    }
                    childrenRemoved = true;
                    checkFinish();
                });
                async.each(result._at, removeEntryAttachment, function (err) {
                    if (err) {
                        return cb(err);
                    }
                    attachmentsRemoved = true;
                    checkFinish();
                });
            } else {
                cb();
            }
        });
    });
}

function removeEntryAttachment(att, cb) {
    mongo.removeFile(att.fileId, 'attachments', cb);
}

var getChildrenOptions = {
    kind: null,
    groupKind: false
};
function getChildren(options) {

    options = extend({}, getChildrenOptions, options);

    var ref = {
        kind: this.getKind(),
        id: this._id
    };

    var self = this;

    return new Promise(function (resolve, reject) {
        if (options.kind) { // Search all children of a specific kind
            exports.get(options.kind, function (err, kindModel) {
                if (err) {
                    return reject(err);
                }
                kindModel.find({
                    _an: {
                        $elemMatch: ref
                    }
                }, function (err, res) {
                    if (err) {
                        return reject(err);
                    }
                    resolve(res);
                });
            });
        } else { // Retrieve all first level children of this entry
            var kindModel = exports.getSync(ref.kind);
            kindModel.findOne(self._id, function (err, res) {
                if (err) {
                    return reject(err);
                } else if (!res) {
                    return reject(new Error('Entry with id ' + self._id + ' does not exist anymore'));
                }
                if (!options.groupKind) { // Put all children in the same array
                    async.map(res._ch, getChild, function (err, res) {
                        if (err) {
                            return reject(err);
                        }
                        resolve(res);
                    });
                } else { // Group by child kind
                    var children = {};
                    async.each(res._ch, function (el, cb) {
                        if (!children[el.kind]) {
                            children[el.kind] = [];
                        }
                        exports.get(el.kind, function (err, kindModel) {
                            if (err) {
                                return cb(err);
                            }
                            kindModel.findOne(el.id, function (err, child) {
                                if (err) {
                                    return cb(err);
                                }
                                children[el.kind].push(child);
                                cb();
                            });
                        });
                    }, function (err) {
                        if (err) {
                            return reject(err);
                        }
                        resolve(children);
                    });
                }
            });
        }
    });
}

function getChild(child) {
    return new Promise(function (resolve, reject) {
        exports.get(child.kind, function (err, kindModel) {
            if (err) {
                return reject(err);
            }
            kindModel.findOne(child.id, function (err, res) {
                err ? reject(err) : resolve(res);
            });
        });
    });
}

/** TODO enable setParent
 function setParent(other, callback) {
    var kind = this.getKind(),
        id = this._id;
    exports.getSync(kind).findById(id, function (err, that) {
        if(err) {
            return callback(err);
        }
        if(that._an.length) {

        }
    });
}
 */

function createAttachment(attachment) {
    if (this.isNew) {
        throw new Error('Cannot call method createAttachment of a new unsaved entry');
    }

    var self = this;
    return new Promise(function (resolve, reject) {
        var data = new Buffer(attachment.value, attachment.encoding || 'utf-8');
        mongo.writeFile(data, attachment.filename, {
            root: 'attachments',
            content_type: attachment.contentType
        }, function (err, fileData) {
            if (err) {
                return reject(err);
            }
            var attachment = {
                _id: fileData._id,
                fileId: fileData._id,
                name: fileData.filename,
                mime: fileData.contentType,
                md5: fileData.md5
            };
            exports.getSync(self.getKind()).findByIdAndUpdate(self._id, {
                $push: {
                    _at: attachment
                }
            }, function (err) {
                err ? reject(err) : resolve(attachment);
            });
        });
    });
}

function removeAttachment(attachmentId) {
    var self = this;
    return new Promise(function (resolve, reject) {
        exports.getSync(self.getKind()).findOneAndUpdate({
            _id: this._id,
            '_at._id': attachmentId
        }, {
            $pull: {
                _at: {
                    _id: attachmentId
                }
            }
        }, {
            'new': false // Important because we need to retrieve the fileId
        }, function (err, res) {
            if (err) {
                return reject(err);
            }
            if (!res) { // Attachment not found
                return reject(new Error('attachment with id ' + attachmentId.toString() + ' not found'));
            }
            resolve(null); // File can be removed from GridFS later
            for (var i = 0, ii = res._at.length; i < ii; i++) {
                if (res._at[i]._id.toString() === attachmentId.toString()) {
                    mongo.removeFile(res._at[i].fileId, 'attachments', util.noop);
                }
            }
        });
    });
}

function getAttachment(attachmentId) {
    var self = this;
    return new Promise(function (resolve, reject) {
        exports.getSync(self.getKind()).findOne({
            _id: this._id,
            '_at._id': attachmentId
        }, '_at.$.fileId', function (err, res) {
            if (err) {
                return reject(err);
            }
            mongo.readFile(res._at[0].fileId, {
                root: 'attachments'
            }, function (err, res) {
                err ? reject(err) : resolve(res);
            });
        });
    });
}

exports.setProvider = function setKindProvider(provider) {
    if (typeof provider === 'function') {
        kindProvider = provider;
    } else {
        throw new Error('Kind provider must be a function');
    }
};

exports.get = function getKindModel(name) {
    return new Promise(function (resolve, reject) {
        if (kinds[name]) {
            resolve(kinds[name]);
        } else {
            kindProvider(name, function gotKindHandler(err, res) {
                if (err) {
                    return reject(err);
                }
                exports.create(name, res.definition, res.options);
                resolve(kinds[name]);
            });
        }
    });
};

exports.getSync = function getKindModelSync(name) {
    if (!kinds[name]) {
        throw new Error('Kind ' + name + ' is not loaded');
    }
    return kinds[name];
};
<commit_msg>add support for changing kinds dynamically<commit_after>'use strict';

var extend = require('extend'),
    async = require('async'),
    Promise = require('native-or-bluebird'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    ObjectId = mongoose.Schema.ObjectId,
    mongo = require('./mongo'),
    util = require('./util');

var dbRefSchema = {
    kind: {
        type: String
    },
    id: {
        type: ObjectId
    },
    _id: false
};

var attachmentSchema = {
    _id: ObjectId,
    fileId: ObjectId,
    name: 'string',
    mime: 'string',
    md5: 'string'
};

var baseDefinition = {
    _an: [dbRefSchema],         // Ancestors array
    _ch: [dbRefSchema],         // Children array
    _at: [attachmentSchema],    // Attachments array
    _dc: Date,                  // Date of creation
    _dm: Date,                  // Date of modification
    _gr: [String]               // Groups
};

var baseOptions = {
    strict: 'throw'
};

var kinds = {};

exports.notifyChange = function notifyChange(kind, newdef, newopts) {
    kinds[kind] = null;
    if (newdef) {
        exports.create(kind, newdef, newopts);
    }
};

var kindProvider = function defaultProvider(kind) {
    return Promise.reject(new Error('Kind ' + kind + ' not found'));
};

exports.setProvider = function setKindProvider(provider) {
    if (typeof provider === 'function') {
        kindProvider = provider;
    } else {
        throw new Error('Kind provider must be a function');
    }
};

exports.get = function getKindModel(name) {
    if (kinds[name]) {
        return Promise.resolve(kinds[name]);
    } else {
        return kindProvider(name).then(function gotKindHandler(res) {
            exports.create(name, res.definition, res.options);
            return kinds[name];
        });
    }
};

exports.getSync = function getKindModelSync(name) {
    if (!kinds[name]) {
        throw new Error('Kind ' + name + ' is not loaded');
    }
    return kinds[name];
};

var hooks = [
    'Save',
    'Remove',
    'Init',
    'Validate'
];

exports.create = function createKind(name, definition, options) {
    if (kinds[name]) {
        throw new Error('Cannot instantiate two kinds with the same name');
    }

    if (!definition || typeof definition !== 'object') {
        throw new Error('Kind definition has to be an object');
    }

    for (var i in definition) {
        if (i[0] === '_') {
            throw new Error('Kind definition cannot contain fields that begin with a "_". Found: ' + i);
        }
    }

    var thisDef = extend({}, baseDefinition, definition);
    var thisOptions = extend({}, baseOptions);

    var thisSchema = new Schema(thisDef, thisOptions);

    options = options || {};

    var hookName, preHookName, postHookName;
    for (i = 0; i < hooks.length; i++) {
        hookName = hooks[i];
        preHookName = 'pre' + hookName;
        if (options[preHookName] && typeof options[preHookName] === 'function') {
            thisSchema.pre(hookName.toLowerCase(), options[preHookName]);
        }
        postHookName = 'post' + hookName;
        if (options[postHookName] && typeof options[postHookName] === 'function') {
            thisSchema.post(hookName.toLowerCase(), options[postHookName]);
        }
    }

    thisSchema.pre('save', function (next) {
        if (!this._dc) {
            this._dc = this._id.getTimestamp();
        }

        this._dm = this.isNew ? this._dc : new Date();

        next();
    });

    thisSchema.index({
        '_an.kind': 1,
        '_an.id': 1
    });

    thisSchema.methods.getKind = thisSchema.statics.getKind = function () {
        return name;
    };

    thisSchema.virtual('owner').set(function (v) {
        this._gr[0] = v; // TODO check
    }).get(function () {
        return this._gr[0];
    });

    thisSchema.methods.createChild = createChild;
    thisSchema.methods.getChildren = getChildren;
    //thisSchema.methods.setParent = setParent;

    thisSchema.methods.createAttachment = createAttachment;
    thisSchema.methods.removeAttachment = removeAttachment;
    thisSchema.methods.getAttachment = getAttachment;

    thisSchema.pre('save', preSaveChild);
    thisSchema.pre('remove', preRemove);

    return kinds[name] = mongoose.model('kind_' + name, thisSchema, 'kind_' + name);
};

function createChild(kind, value) {
    if (this.isNew) {
        throw new Error('Cannot call method createChild of a new unsaved entry');
    }

    var kindModel = exports.getSync(kind);
    var child = new kindModel(value);
    child._gr = this._gr.slice();                           // By default, owner is propagated
    for (var i = 0; i < this._an.length; i++) {
        child._an.push({
            kind: this._an[i].kind,
            id: this._an[i].id
        });
    }
    child._an.push({
        kind: this.getKind(),
        id: this._id
    });
    child._newChild = true;
    child._parent = this;

    util.promisifySave(child);

    return child;
}

function preSaveChild(next) {
    var self = this;
    if (this._newChild) {
        var parentModel = exports.getSync(this._parent.getKind());
        parentModel.findByIdAndUpdate(this._parent._id, {
            $push: {
                _ch: {
                    kind: this.getKind(),
                    id: this._id
                }
            }
        }, function (err) {
            if (err) {
                return next(err);
            }
            self._newChild = false;
            next();
        });
    } else {
        next();
    }
}

function preRemove(next) {
    var ref = {
        kind: this.getKind(),
        id: this._id
    };

    exports.getSync(ref.kind).findById(ref.id, function (err, res) {
        if (err) {
            return next(err);
        }
        // First we have to remove the reference from the parent
        if (res._an.length) {
            var parent = res._an[res._an.length - 1];
            exports.get(parent.kind, function (err, parentModel) {
                if (err) {
                    return next(err);
                }
                parentModel.findByIdAndUpdate(parent.id, {
                    $pull: {
                        _ch: ref
                    }
                }, function (err) {
                    if (err) {
                        return next(err);
                    }
                    async.each(res._ch, removeEntryChildrenAndAttachments, next);
                });
            });
        } else {
            async.each(res._ch, removeEntryChildrenAndAttachments, next);
        }
    });
}

function removeEntryChildrenAndAttachments(entry, cb) {
    exports.get(entry.kind, function (err, entryModel) {
        if (err) {
            return cb(err);
        }
        var childrenRemoved = false,
            attachmentsRemoved = false;

        function checkFinish() {
            if (childrenRemoved && attachmentsRemoved) {
                cb();
            }
        }

        entryModel.findByIdAndRemove(entry.id, function (err, result) {
            if (err) {
                return cb(err);
            }
            if (result) {
                async.each(result._ch, removeEntryChildrenAndAttachments, function (err) {
                    if (err) {
                        return cb(err);
                    }
                    childrenRemoved = true;
                    checkFinish();
                });
                async.each(result._at, removeEntryAttachment, function (err) {
                    if (err) {
                        return cb(err);
                    }
                    attachmentsRemoved = true;
                    checkFinish();
                });
            } else {
                cb();
            }
        });
    });
}

function removeEntryAttachment(att, cb) {
    mongo.removeFile(att.fileId, 'attachments', cb);
}

var getChildrenOptions = {
    kind: null,
    groupKind: false
};
function getChildren(options) {

    options = extend({}, getChildrenOptions, options);

    var ref = {
        kind: this.getKind(),
        id: this._id
    };

    var self = this;

    return new Promise(function (resolve, reject) {
        if (options.kind) { // Search all children of a specific kind
            exports.get(options.kind, function (err, kindModel) {
                if (err) {
                    return reject(err);
                }
                kindModel.find({
                    _an: {
                        $elemMatch: ref
                    }
                }, function (err, res) {
                    if (err) {
                        return reject(err);
                    }
                    resolve(res);
                });
            });
        } else { // Retrieve all first level children of this entry
            var kindModel = exports.getSync(ref.kind);
            kindModel.findOne(self._id, function (err, res) {
                if (err) {
                    return reject(err);
                } else if (!res) {
                    return reject(new Error('Entry with id ' + self._id + ' does not exist anymore'));
                }
                if (!options.groupKind) { // Put all children in the same array
                    async.map(res._ch, getChild, function (err, res) {
                        if (err) {
                            return reject(err);
                        }
                        resolve(res);
                    });
                } else { // Group by child kind
                    var children = {};
                    async.each(res._ch, function (el, cb) {
                        if (!children[el.kind]) {
                            children[el.kind] = [];
                        }
                        exports.get(el.kind, function (err, kindModel) {
                            if (err) {
                                return cb(err);
                            }
                            kindModel.findOne(el.id, function (err, child) {
                                if (err) {
                                    return cb(err);
                                }
                                children[el.kind].push(child);
                                cb();
                            });
                        });
                    }, function (err) {
                        if (err) {
                            return reject(err);
                        }
                        resolve(children);
                    });
                }
            });
        }
    });
}

function getChild(child) {
    return new Promise(function (resolve, reject) {
        exports.get(child.kind, function (err, kindModel) {
            if (err) {
                return reject(err);
            }
            kindModel.findOne(child.id, function (err, res) {
                err ? reject(err) : resolve(res);
            });
        });
    });
}

/** TODO enable setParent
 function setParent(other, callback) {
    var kind = this.getKind(),
        id = this._id;
    exports.getSync(kind).findById(id, function (err, that) {
        if(err) {
            return callback(err);
        }
        if(that._an.length) {

        }
    });
}
 */

function createAttachment(attachment) {
    if (this.isNew) {
        throw new Error('Cannot call method createAttachment of a new unsaved entry');
    }

    var self = this;
    return new Promise(function (resolve, reject) {
        var data = new Buffer(attachment.value, attachment.encoding || 'utf-8');
        mongo.writeFile(data, attachment.filename, {
            root: 'attachments',
            content_type: attachment.contentType
        }, function (err, fileData) {
            if (err) {
                return reject(err);
            }
            var attachment = {
                _id: fileData._id,
                fileId: fileData._id,
                name: fileData.filename,
                mime: fileData.contentType,
                md5: fileData.md5
            };
            exports.getSync(self.getKind()).findByIdAndUpdate(self._id, {
                $push: {
                    _at: attachment
                }
            }, function (err) {
                err ? reject(err) : resolve(attachment);
            });
        });
    });
}

function removeAttachment(attachmentId) {
    var self = this;
    return new Promise(function (resolve, reject) {
        exports.getSync(self.getKind()).findOneAndUpdate({
            _id: this._id,
            '_at._id': attachmentId
        }, {
            $pull: {
                _at: {
                    _id: attachmentId
                }
            }
        }, {
            'new': false // Important because we need to retrieve the fileId
        }, function (err, res) {
            if (err) {
                return reject(err);
            }
            if (!res) { // Attachment not found
                return reject(new Error('attachment with id ' + attachmentId.toString() + ' not found'));
            }
            resolve(null); // File can be removed from GridFS later
            for (var i = 0, ii = res._at.length; i < ii; i++) {
                if (res._at[i]._id.toString() === attachmentId.toString()) {
                    mongo.removeFile(res._at[i].fileId, 'attachments', util.noop);
                }
            }
        });
    });
}

function getAttachment(attachmentId) {
    var self = this;
    return new Promise(function (resolve, reject) {
        exports.getSync(self.getKind()).findOne({
            _id: this._id,
            '_at._id': attachmentId
        }, '_at.$.fileId', function (err, res) {
            if (err) {
                return reject(err);
            }
            mongo.readFile(res._at[0].fileId, {
                root: 'attachments'
            }, function (err, res) {
                err ? reject(err) : resolve(res);
            });
        });
    });
}
<|endoftext|>


<commit_before>/* 전체 서버 상태 2017-01-02 */
function allServerViewHost(hostid) {
    $.blockUI(blockUI_opt_all);
    $("[id^=base]").hide();
    $("#base_server").show();

    $("#searchText").val("");
    $("#reload_serverOverview").hide();

    var server_data = '';
    zbxApi.allServerViewHost.get().done(function(data, status, jqXHR) {
        server_data = zbxApi.allServerViewHost.success(data);
        serverOverView(server_data);
    });

};

function serverOverView(server_data) {
    $.blockUI(blockUI_opt_all);
    var tableDataObj = {};
    var tableDataArr = [];

    var serverOverViewHTML = '';
    serverOverViewHTML += '
';
    serverOverViewHTML += '
';
    serverOverViewHTML += '상태	';
    //serverOverViewHTML += '서버명	';
    serverOverViewHTML += '서버명	';
    serverOverViewHTML += 'IP주소	';
    serverOverViewHTML += 'CPU(%)	';
    serverOverViewHTML += '메모리(%)	';
    serverOverViewHTML += '디스크(%)	';
    serverOverViewHTML += '운영체제	';
    serverOverViewHTML += 'CPU	';
    serverOverViewHTML += 'RAM	';
    serverOverViewHTML += '
';
    serverOverViewHTML += '
';
    serverOverViewHTML += '
';

    $.each(server_data.result, function(k, v) {
        var serverStatus = '';
        var hostid = '';
        var serverName = '';
        var serverIP = '';
        var serverPerCPU = 0;
        var serverPerMemory = 0;
        var serverPerDisk = 0;
        var serverOS = '-';
        var serverCPU = '-';
        var serverRAM = '-';

        serverName = v.name;
        hostid = v.hostid;
        serverStatus = zbxSyncApi.serverOverView().result[0].status;
        serverStatus = convHostEvent(serverStatus);
        serverIP = v.interfaces[0].ip;
        console.log("호스트 정보 : " + hostid + " / serverName : " + serverName + " / serverStatus : " + serverStatus);
        var osInfo = v.inventory.os;    //serverOS = v.inventory.os;
        if (osInfo === undefined) {
            serverOS = '-';
        }
        else {
            if (osInfo.match('Linux')) {
                serverOS = 'Linux';
            }
            else if (osInfo.match('Window')) {
                serverOS = 'Windows';
            }
            else {
                serverOS = '-';
            }
        }

        try {
            serverPerCPU = zbxSyncApi.allServerViewItemByName(hostid, "CPU idle time").lastvalue;
            serverPerCPU = Math.floor(serverPerCPU * 100) / 100;

            if (serverPerCPU == 100)
                serverPerCPU = 0;
        } catch (e) {
            console.log(e);
        }

        try {
            serverPerMemory = zbxSyncApi.allServerViewItem(hostid, "vm.memory.size[pused]").lastvalue;
            serverPerMemory = Math.floor(serverPerMemory * 100) / 100;
        } catch (e) {
            console.log(e);
        }

        var value;
        try {
            // TODO pfree to pused.
            value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[/,pfree]").lastvalue;
        } catch (e) {
            console.log(e);
            try {
                value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[C:,pfree]").lastvalue;
            } catch (e) {
                console.log(e);
            }
        }
        console.log("value : " + value);
        serverPerDisk = 100 - value;

        if(value === undefined){
            serverPerDisk = 0;
        }

        if (serverPerDisk == 100)
            serverPerDisk = 0;
        serverPerDisk = Math.floor(serverPerDisk * 100) / 100;

        var infoArr = v.inventory.hardware;     //serverCPU + serverRAM = v.inventory.hardware
        if (infoArr === undefined || infoArr == '') {
            serverCPU = '-';
            serverRAM = '-';
        } else {
            var splitInfo = infoArr.split(",");
            try {
                serverCPU = splitInfo[0].slice(4);
                serverRAM = splitInfo[1].slice(5);
            } catch (e) {
                console.log(e);
            }
        }

        var tableDataObj = {};
        tableDataObj.hostid = hostid;
        tableDataObj.status = serverStatus;
        tableDataObj.name = serverName;
        tableDataObj.ip = serverIP;
        tableDataObj.perCPU = serverPerCPU;
        tableDataObj.perMemory = serverPerMemory;
        tableDataObj.perDisk = serverPerDisk;
        tableDataObj.OS = serverOS;
        tableDataObj.CPU = serverCPU;
        tableDataObj.RAM = serverRAM;
        tableDataArr.push(tableDataObj);

        serverOverViewHTML += '
';
        serverOverViewHTML += '' + serverStatus + '	';
        serverOverViewHTML += '' + serverName + '	';
        serverOverViewHTML += '' + serverIP + '	';
        serverOverViewHTML += '
' +
            '

' +
            '

' + serverPerCPU + '%
	';
        serverOverViewHTML += '
' +
            '

' +
            '

' + serverPerMemory + '%
	';
        serverOverViewHTML += '
' +
            '

' +
            '

' + serverPerDisk + '%
	';
        serverOverViewHTML += '' + serverOS + '	';
        serverOverViewHTML += '' + serverCPU + '	';
        serverOverViewHTML += '' + serverRAM + '	';
        serverOverViewHTML += '
';
    });

    serverOverViewHTML += '
';
    $("#serverList").empty();
    $("#serverList").append(serverOverViewHTML);

    $.each(server_data.result, function(k, v) {
        console.log("IN function");
        hostid = v.hostid;
        var item_id = '';

        //화면 이동
        $("#Name_" + hostid).click(function () {
            console.log("IN function Name_");
            item_id = this.id;
            console.log(" this.id : " + item_id);
            hostid = item_id.substring(item_id.indexOf("_")+1);
            $("#serverInfo").empty();
            $("#serverProcessList").empty();
            $("#serverEventList").empty();
            $("#info_" + hostid).click();
        });

        $("#PerCPU_" + hostid).click(function () {
            console.log("IN function PerCPU_");
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_") + 1);
            $("#cpu_" + hostid).click();
        });

        $("#PerMemory_" + hostid).click(function () {
            console.log("IN function PerMemory_");
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_") + 1);
            $("#memory_" + hostid).click();
        });

        $("#PerDisk_" + hostid).click(function () {
            console.log("IN function PerDisk_");
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_") + 1);
            $("#disk_" + hostid).click();
        });
    });
    /*
     //테이블의 td col 클릭시 정렬된 테이블 내용 생성
     var $table = $("#serverList");
     $("#serverNameTd", $table).each(function (column) {
     $(this).click(function() {
     var sortTable = '';
     var currentThObj = $(this);
     var MAX_COUNT = tableDataArr.length;

     if($(this).is('.sorting_desc')){
     console.log(" >>>>> sorting_desc <<<<<");
     tableDataArr.sort(function (a, b) {
     if(column == 1) {
     return a.name  b.name ? 1 : 0;
     }
     });
     currentThObj.removeClass("sorting_desc").addClass("sorting_asc");
     }else{
     tableDataArr.sort(function (a, b) {
     console.log(" >>>>> sorting_asc <<<<<");
     if(column == 1){
     return a.name > b.name ? -1 : a.name < b.name ? 1 : 0;
     }
     });
     currentThObj.removeClass("sorting_asc").addClass("sorting_desc");
     }//end else
     $('tbody', $table).empty();

     for(var i=0; i<MAX_COUNT; i++){
     var hostid = tableDataArr[i].hostid;
     sortTable += '
';
     sortTable += '' + tableDataArr[i].status + '	';
     sortTable += '' + tableDataArr[i].name + '	';
     sortTable += '' + tableDataArr[i].ip + '	';
     sortTable += '
' +
     '

' +
     '

' + tableDataArr[i].perCPU + '%
	';
     sortTable += '
' +
     '

' +
     '

' + tableDataArr[i].perMemory + '%
	';
     sortTable += '
' +
     '

' +
     '

' + tableDataArr[i].perDisk + '%
	';
     sortTable += '' + tableDataArr[i].OS + '	';
     sortTable += '' + tableDataArr[i].CPU + '	';
     sortTable += '' + tableDataArr[i].RAM + '	';
     sortTable += '
';
     }//end for
     $('tbody', $table).append(sortTable);

     })//end click function
     }); //end each
     */

    //page reloag
    $("#reload_serverOverview").click(function(){
        //int.allServerViewHost();
        console.log("reload_serverOverview");

        var cpu = '';
        var memory = '';
        var disk = '';
        var ROW_COUNT = tableDataArr.length;
        //alert("ROW_COUNT : " + ROW_COUNT);

        for(var i=0; i<ROW_COUNT; i++) {
            var hostid = tableDataArr[i].hostid;
            try {
                cpu = zbxSyncApi.allServerViewItemByName(hostid, "CPU idle time").lastvalue;
                cpu = Math.floor(cpu * 100) / 100;

                if (cpu == 100)
                    cpu = 0;
            } catch (e) {
                console.log(e);
            }
            $("#perCPU_" + hostid).width(cpu + "%");
            $("#perCPU_" + hostid).html(cpu + "%");

            try {
                memory = zbxSyncApi.allServerViewItem(hostid, "vm.memory.size[pused]").lastvalue;
                memory = Math.floor(memory * 100) / 100;
            } catch (e) {
                console.log(e);
            }
            if (memory == 0)
                memory = 0;
            $("#perMemory_" + hostid).width(memory + "%");
            $("#perMemory_" + hostid).html(memory + "%");

            var value;
            try {
                // TODO pfree to pused.
                value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[/,pfree]").lastvalue;
            } catch (e) {
                console.log(e);
                try {
                    value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[C:,pfree]").lastvalue;
                } catch (e) {
                    console.log(e);
                }
            }
            disk = 100 - value;

            if (disk == 100)
                disk = 0;
            disk = Math.floor(disk * 100) / 100;
            $("#perDisk_" + hostid).width(disk + "%");
            $("#perDisk_" + hostid).html(disk + "%");
            console.log("================================");
        }
    });

    /* 검색 */
    $("#searchText").keyup(function() {
        console.log(" CLICK searchText ");
        searchHostBtn();
    });

    $.unblockUI(blockUI_opt_all);
}

function searchHostBtn(){
    console.log(" CLICK searchHostBtn ");
    //$("#searchText").keyup();
    /*var inputText = $("#searchText").val();
     console.log(" searchHostBtn 입력 Text : " + inputText);*/

    var input;
    var filter;
    var table;
    var tr;
    var td;

    input = $("#searchText").val();
    console.log(" input : " + input);
    filter = input.toLowerCase();
    console.log(" filter : " + filter);
    table = document.getElementById("hostInfoList");
    tr = table.getElementsByTagName("tr");
    console.log(" tr Cnt : " + tr.length);

    for(var i=0; i
 -1) {
                tr[i].style.display = "";
                console.log(" OK ");
            } else {
                tr[i].style.display = "none";
                console.log(" FAIL ");
            }
        }
    }
}
<commit_msg>2017.03.27 3차 스프린트 수정<commit_after>/* 전체 서버 상태 2017-01-02 */
function allServerViewHost(hostid) {
    $.blockUI(blockUI_opt_all);
    $("[id^=base]").hide();
    $("#base_server").show();

    $("#searchText").val("");
    $("#reload_serverOverview").hide();

    var server_data = '';
    zbxApi.allServerViewHost.get().done(function(data, status, jqXHR) {
        server_data = zbxApi.allServerViewHost.success(data);
        serverOverView(server_data);
    });

};

function serverOverView(server_data) {
    $.blockUI(blockUI_opt_all);
    var tableDataObj = {};
    var tableDataArr = [];

    var serverOverViewHTML = '';
    serverOverViewHTML += '
';
    serverOverViewHTML += '
';
    serverOverViewHTML += '상태	';
    //serverOverViewHTML += '서버명	';
    serverOverViewHTML += '서버명	';
    serverOverViewHTML += 'IP주소	';
    serverOverViewHTML += 'CPU(%)	';
    serverOverViewHTML += '메모리(%)	';
    serverOverViewHTML += '디스크(%)	';
    serverOverViewHTML += '운영체제	';
    serverOverViewHTML += 'CPU	';
    serverOverViewHTML += 'RAM	';
    serverOverViewHTML += '
';
    serverOverViewHTML += '
';
    serverOverViewHTML += '
';

    $.each(server_data.result, function(k, v) {
        var serverStatus = '';
        var hostid = '';
        var serverName = '';
        var serverIP = '';
        var serverPerCPU = 0;
        var serverPerMemory = 0;
        var serverPerDisk = 0;
        var serverOS = '-';
        var serverCPU = '-';
        var serverRAM = '-';

        serverName = v.name;
        hostid = v.hostid;
        serverStatus = zbxSyncApi.serverOverView().result[0].status;
        serverStatus = convHostEvent(serverStatus);
        serverIP = v.interfaces[0].ip;
        console.log("호스트 정보 : " + hostid + " / serverName : " + serverName + " / serverStatus : " + serverStatus);
        var osInfo = v.inventory.os;    //serverOS = v.inventory.os;
        if (osInfo === undefined) {
            serverOS = '-';
        }
        else {
            if (osInfo.match('Linux')) {
                serverOS = 'Linux';
            }
            else if (osInfo.match('Window')) {
                serverOS = 'Windows';
            }
            else {
                serverOS = '-';
            }
        }

        try {
            serverPerCPU = zbxSyncApi.allServerViewItemByName(hostid, "CPU idle time").lastvalue;
            serverPerCPU = Math.floor(serverPerCPU * 100) / 100;

            if (serverPerCPU == 100)
                serverPerCPU = 0;
        } catch (e) {
            console.log(e);
        }

        try {
            serverPerMemory = zbxSyncApi.allServerViewItem(hostid, "vm.memory.size[pused]").lastvalue;
            serverPerMemory = Math.floor(serverPerMemory * 100) / 100;
        } catch (e) {
            console.log(e);
        }

        var value;
        try {
            // TODO pfree to pused.
            value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[/,pfree]").lastvalue;
        } catch (e) {
            console.log(e);
            try {
                value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[C:,pfree]").lastvalue;
            } catch (e) {
                console.log(e);
            }
        }
        console.log("value : " + value);
        serverPerDisk = 100 - value;

        if(value === undefined){
            serverPerDisk = 0;
        }

        if (serverPerDisk == 100)
            serverPerDisk = 0;
        serverPerDisk = Math.floor(serverPerDisk * 100) / 100;

        var infoArr = v.inventory.hardware;     //serverCPU + serverRAM = v.inventory.hardware
        if (infoArr === undefined || infoArr == '') {
            serverCPU = '-';
            serverRAM = '-';
        } else {
            var splitInfo = infoArr.split(",");
            try {
                serverCPU = splitInfo[0].slice(4);
                serverRAM = splitInfo[1].slice(5);
            } catch (e) {
                console.log(e);
            }
        }

        var tableDataObj = {};
        tableDataObj.hostid = hostid;
        tableDataObj.status = serverStatus;
        tableDataObj.name = serverName;
        tableDataObj.ip = serverIP;
        tableDataObj.perCPU = serverPerCPU;
        tableDataObj.perMemory = serverPerMemory;
        tableDataObj.perDisk = serverPerDisk;
        tableDataObj.OS = serverOS;
        tableDataObj.CPU = serverCPU;
        tableDataObj.RAM = serverRAM;
        tableDataArr.push(tableDataObj);

        serverOverViewHTML += '
';
        serverOverViewHTML += '' + serverStatus + '	';
        serverOverViewHTML += '' + serverName + '	';
        serverOverViewHTML += '' + serverIP + '	';
        serverOverViewHTML += '
' +
            '

' +
            '

' + serverPerCPU + '%
	';
        serverOverViewHTML += '
' +
            '

' +
            '

' + serverPerMemory + '%
	';
        serverOverViewHTML += '
' +
            '

' +
            '

' + serverPerDisk + '%
	';
        serverOverViewHTML += '' + serverOS + '	';
        serverOverViewHTML += '' + serverCPU + '	';
        serverOverViewHTML += '' + serverRAM + '	';
        serverOverViewHTML += '
';
    });

    serverOverViewHTML += '
';
    $("#serverList").empty();
    $("#serverList").append(serverOverViewHTML);

    $.each(server_data.result, function(k, v) {
        console.log("IN function");
        hostid = v.hostid;
        var item_id = '';

        //화면 이동
        $("#Name_" + hostid).click(function () {
            console.log("IN function Name_");
            item_id = this.id;
            console.log(" this.id : " + item_id);
            hostid = item_id.substring(item_id.indexOf("_")+1);
            $("#serverInfo").empty();
            $("#serverProcessList").empty();
            $("#serverEventList").empty();
            $("#info_" + hostid).click();
        });

        $("#PerCPU_" + hostid).click(function () {
            console.log("IN function PerCPU_");
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_") + 1);
            $("#cpu_" + hostid).click();
        });

        $("#PerMemory_" + hostid).click(function () {
            console.log("IN function PerMemory_");
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_") + 1);
            $("#memory_" + hostid).click();
        });

        $("#PerDisk_" + hostid).click(function () {
            console.log("IN function PerDisk_");
            item_id = this.id;
            hostid = item_id.substring(item_id.indexOf("_") + 1);
            $("#disk_" + hostid).click();
        });
    });

    //page reloag
    $("#reload_serverOverview").click(function(){
        //int.allServerViewHost();
        console.log("reload_serverOverview");

        var cpu = '';
        var memory = '';
        var disk = '';
        var ROW_COUNT = tableDataArr.length;
        //alert("ROW_COUNT : " + ROW_COUNT);

        for(var i=0; i<ROW_COUNT; i++) {
            var hostid = tableDataArr[i].hostid;
            try {
                cpu = zbxSyncApi.allServerViewItemByName(hostid, "CPU idle time").lastvalue;
                cpu = Math.floor(cpu * 100) / 100;

                if (cpu == 100)
                    cpu = 0;
            } catch (e) {
                console.log(e);
            }
            $("#perCPU_" + hostid).width(cpu + "%");
            $("#perCPU_" + hostid).html(cpu + "%");

            try {
                memory = zbxSyncApi.allServerViewItem(hostid, "vm.memory.size[pused]").lastvalue;
                memory = Math.floor(memory * 100) / 100;
            } catch (e) {
                console.log(e);
            }
            if (memory == 0)
                memory = 0;
            $("#perMemory_" + hostid).width(memory + "%");
            $("#perMemory_" + hostid).html(memory + "%");

            var value;
            try {
                // TODO pfree to pused.
                value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[/,pfree]").lastvalue;
            } catch (e) {
                console.log(e);
                try {
                    value = zbxSyncApi.allServerViewItem(hostid, "vfs.fs.size[C:,pfree]").lastvalue;
                } catch (e) {
                    console.log(e);
                }
            }
            disk = 100 - value;

            if (disk == 100)
                disk = 0;
            disk = Math.floor(disk * 100) / 100;
            $("#perDisk_" + hostid).width(disk + "%");
            $("#perDisk_" + hostid).html(disk + "%");
            console.log("================================");
        }
    });

    /* 검색 */
    $("#searchText").keyup(function() {
        console.log(" CLICK searchText ");
        searchHostBtn();
    });

    $.unblockUI(blockUI_opt_all);
}

function searchHostBtn(){
    console.log(" CLICK searchHostBtn ");
    //$("#searchText").keyup();
    /*var inputText = $("#searchText").val();
     console.log(" searchHostBtn 입력 Text : " + inputText);*/

    var input;
    var filter;
    var table;
    var tr;
    var td;

    input = $("#searchText").val();
    console.log(" input : " + input);
    filter = input.toLowerCase();
    console.log(" filter : " + filter);
    table = document.getElementById("hostInfoList");
    tr = table.getElementsByTagName("tr");
    console.log(" tr Cnt : " + tr.length);

    for(var i=0; i
 -1) {
                tr[i].style.display = "";
                console.log(" OK ");
            } else {
                tr[i].style.display = "none";
                console.log(" FAIL ");
            }
        }
    }
}
<|endoftext|>


<commit_before>(function (global) {
    'use strict';

    var __extends = function (d, b) {
        for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    };

    var fnTrue = function () { return true; };

    var generator = function* (array) {
        for (let i = 0; i < array.length; i++) {
            yield array[i];
        }
    };

    var Enumerable = function (array) {
        if (this && this.constructor == Enumerable) {
            throw 'This is not a constructable type, don\'t use the `new` operator';
        }
        var instance = generator.bind(this, array);

        __extends(instance, generator);
        return instance
    };

    var first = function (nullable, selector) {
        return function (fn) {
            fn = fn || selector;
            for (let item of this()) {
                if (fn(item)) {
                    return item;
                }
            }

            if (nullable) {
                return undefined;
            }
            throw 'Sequence contains no matching elements';
        };
    };

    var single = function (nullable, selector) {
        return function (fn) {
            fn = fn || selector;
            var matched;
            for (let item of this()) {
                if (fn(item)) {
                    if (matched) {
                        throw 'Sequence contains more than one matching element';
                    }
                    else {
                        matched = item;
                    }
                }
            }

            if (matched) {
                return matched;
            }

            if (!matched && nullable) {
                return undefined;
            }

            throw 'Sequence contains no matching elements';
        };
    };

    var all = function (fn) {
        for (let x of this()) {
            if (!fn(x)) {
                return false;
            }
        }

        return true;
    };

    var any = function (fn) {
        fn = fn || fnTrue;

        for (let x of this()) {
            if (fn(x)) {
                return true;
            }
        }
        return false;
    }

    var count = function (fn) {
        fn = fn || fnTrue;

        var count = 0;
        for (var i of this()) {
            if (fn(i)) {
                count++;
            }
        }
        return count;
    };

    var where = function (fn) {
        return WhereEnumerable(this, fn);
    };

    var select = function (fn) {
        return SelectEnumerable(this, fn);
    };

    var selectMany = function (fn) {
        return SelectManyEnumerable(this, fn);
    };

    var take = function (count) {
        return TakeEnumerable(this, count || 0);
    };

    var takeWhile = function (fn) {
        return TakeEnumerable(this, fn || 0);
    };

    var skip = function (count) {
        return SkipEnumerable(this, count || 0);
    };

    var skipWhile = function (fn) {
        return SkipEnumerable(this, fn || 0);
    };

    var toArray = function() {
        var arr = [];
        for (let i of this()) {
            arr.push(i);
        }
        return arr;
    };

    generator.where = where;
    generator.filter = where;

    generator.select = select;
    generator.map = select;
    generator.selectMany = selectMany;

    generator.first = first(false, fnTrue);
    generator.firstOrDefault = first(true, fnTrue);

    generator.single = single(false, fnTrue);
    generator.singleOrDefault = single(true, fnTrue);

    generator.all = all;
    generator.any = any;
    generator.count = count;

    generator.take = take;
    generator.takeWhile = takeWhile;

    generator.skip = skip;
    generator.skipWhile = skipWhile;

    generator.toArray = toArray;

    var WhereEnumerable = (function (__super) {
        return function WhereEnumerable(parent, fn) {
            function* where(fn) {
                var index = 0;
                for (let x of parent()) {
                    if (fn(x, index)) {
                        yield x;
                    }
                    index++;
                }
            }

            var x = where.bind(this, fn);
            __extends(x, __super);
            return x;
        };
    })(generator);

    var SelectEnumerable = (function (__super) {
        return function (parent, fn) {
            var selector = function* (parent, fn) {
                var index = 0;
                for (let item of parent()) {
                    yield fn(item, index++);
                }
            };

            var instance = selector.bind(this, parent, fn);
            __extends(instance, __super);
            return instance;
        };
    })(generator);

    var SelectManyEnumerable = (function (__super) {
        return function (parent, colSelector, resultSelector) {
            var selectMany = function* (parent, colSelector, resultSelector) {
                resultSelector = resultSelector || function (col, x) { return x; };
                var index = 0;

                for (let item of parent()) {
                    let arr = colSelector(item, index++);
                    for (let i = 0; i < arr.length; i++) {
                        let foo = resultSelector(arr, arr[i]);
                        yield foo;
                    }
                }
            };

            var instance = selectMany.bind(this, parent, colSelector, resultSelector);
            __extends(instance, __super);
            return instance;
        };
    })(generator);

    var RangeEnumerable = (function (__super) {
        return function (start, end) {
            var ranger = function* (start, end) {
                for (start; start <= end; start++) {
                    yield start;
                }
            };

            var instance = ranger.bind(this, start, end);
            __extends(instance, __super);
            return instance;
        };
    })(generator);

    var TakeEnumerable = (function (__super) {
        return function (parent, selector) {
            var taker = function* (parent, selector) {
                var index = 0;
                if (typeof selector === 'number') {
                    for (let item of parent()) {
                        if (index < selector) {
                            yield item;
                            index++;
                        } else {
                            break;
                        }
                    }
                } else if (typeof selector === 'function') {
                    for (let item of parent()) {
                        if (selector(item, index)) {
                            yield item;
                        } else {
                            break;
                        }
                        index++;
                    }
                }
            };

            var instance = taker.bind(this, parent, selector);
            __extends(instance, __super);
            return instance;
        };
    })(generator);

    var SkipEnumerable = (function (__super) {
        return function (parent, selector) {
            var skippy = function* (parent, selector) {
                var index = 0;
                if (typeof selector === 'number') {
                    for (let item of parent()) {
                        if (index >= selector) {
                            yield item;
                        }
                        index++;
                    }
                } else if (typeof selector === 'function') {
                    let flag = false;
                    index = -1;
                    for (let item of parent()) {
                        index++;
                        if (!flag && !selector(item, index)) {
                            flag = true;
                        }

                        if (flag) {
                            yield item;
                        }
                    }
                }
            };

            var instance = skippy.bind(this, parent, selector);
            __extends(instance, __super);
            return instance;
        };
    })(generator);

    var RepeatEnumerable = (function (__super) {
        return function (item, count) {
            var repeater = function* (item, count) {
                var stripped = JSON.stringify(item);
                for (var i = 0; i < count; i++) {
                    yield JSON.parse(stripped);
                }
            };

            var instance = repeater.bind(this, item, count);
            __extends(instance, __super);
            return instance;
        };
    })(generator);

    Enumerable.range = function (start, end) {
        start = start || 0;
        end = end || 0;

        return RangeEnumerable(start, end);
    };

    Enumerable.repeat = function (item, count) {
        return RepeatEnumerable(item, count || 0);
    };

    // extension methods
    Array.prototype.asEnumerable = function() {
        return Enumerable(this);
    };

    if (typeof module === 'object' && typeof module.exports === 'object') {
        module.exports = Enumerable;
    } else if (typeof define === 'function' && define.amd) {
        define('linq', function () {
            return Enumerable;
        });
    } else {
        global.Enumerable = Enumerable;
    }
})(this);<commit_msg>Started working on the aggregate/reduce method<commit_after>(function (global) {
    'use strict';

    var __extends = function (d, b) {
        for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    };

    var fnTrue = function () { return true; };

    var generator = function* (array) {
        for (let i = 0; i < array.length; i++) {
            yield array[i];
        }
    };

    var Enumerable = function (array) {
        if (this && this.constructor == Enumerable) {
            throw 'This is not a constructable type, don\'t use the `new` operator';
        }
        var instance = generator.bind(this, array);

        __extends(instance, generator);
        return instance
    };

    var first = function (nullable, selector) {
        return function (fn) {
            fn = fn || selector;
            for (let item of this()) {
                if (fn(item)) {
                    return item;
                }
            }

            if (nullable) {
                return undefined;
            }
            throw 'Sequence contains no matching elements';
        };
    };

    var single = function (nullable, selector) {
        return function (fn) {
            fn = fn || selector;
            var matched;
            for (let item of this()) {
                if (fn(item)) {
                    if (matched) {
                        throw 'Sequence contains more than one matching element';
                    }
                    else {
                        matched = item;
                    }
                }
            }

            if (matched) {
                return matched;
            }

            if (!matched && nullable) {
                return undefined;
            }

            throw 'Sequence contains no matching elements';
        };
    };

    var all = function (fn) {
        for (let x of this()) {
            if (!fn(x)) {
                return false;
            }
        }

        return true;
    };

    var any = function (fn) {
        fn = fn || fnTrue;

        for (let x of this()) {
            if (fn(x)) {
                return true;
            }
        }
        return false;
    }

    var count = function (fn) {
        fn = fn || fnTrue;

        var count = 0;
        for (var i of this()) {
            if (fn(i)) {
                count++;
            }
        }
        return count;
    };

    var aggregate = function (seed, fn, selector) {
        if (!fn) {
            fn = seed;
            seed = undefined;
        }

        selector = selector || x => x;

        if (seed == undefined) {

        }

        for (let item in this) {

        }
    };

    var where = function (fn) {
        return WhereEnumerable(this, fn);
    };

    var select = function (fn) {
        return SelectEnumerable(this, fn);
    };

    var selectMany = function (fn) {
        return SelectManyEnumerable(this, fn);
    };

    var take = function (count) {
        return TakeEnumerable(this, count || 0);
    };

    var takeWhile = function (fn) {
        return TakeEnumerable(this, fn || 0);
    };

    var skip = function (count) {
        return SkipEnumerable(this, count || 0);
    };

    var skipWhile = function (fn) {
        return SkipEnumerable(this, fn || 0);
    };

    var toArray = function() {
        var arr = [];
        for (let i of this()) {
            arr.push(i);
        }
        return arr;
    };

    generator.where = where;
    generator.filter = where;

    generator.select = select;
    generator.map = select;
    generator.selectMany = selectMany;

    generator.first = first(false, fnTrue);
    generator.firstOrDefault = first(true, fnTrue);

    generator.single = single(false, fnTrue);
    generator.singleOrDefault = single(true, fnTrue);

    generator.all = all;
    generator.any = any;
    generator.count = count;

    generator.take = take;
    generator.takeWhile = takeWhile;

    generator.skip = skip;
    generator.skipWhile = skipWhile;

    generator.toArray = toArray;

    var WhereEnumerable = (function (__super) {
        return function WhereEnumerable(parent, fn) {
            function* where(fn) {
                var index = 0;
                for (let x of parent()) {
                    if (fn(x, index)) {
                        yield x;
                    }
                    index++;
                }
            }

            var x = where.bind(this, fn);
            __extends(x, __super);
            return x;
        };
    })(generator);

    var SelectEnumerable = (function (__super) {
        return function (parent, fn) {
            var selector = function* (parent, fn) {
                var index = 0;
                for (let item of parent()) {
                    yield fn(item, index++);
                }
            };

            var instance = selector.bind(this, parent, fn);
            __extends(instance, __super);
            return instance;
        };
    })(generator);

    var SelectManyEnumerable = (function (__super) {
        return function (parent, colSelector, resultSelector) {
            var selectMany = function* (parent, colSelector, resultSelector) {
                resultSelector = resultSelector || function (col, x) { return x; };
                var index = 0;

                for (let item of parent()) {
                    let arr = colSelector(item, index++);
                    for (let i = 0; i < arr.length; i++) {
                        let foo = resultSelector(arr, arr[i]);
                        yield foo;
                    }
                }
            };

            var instance = selectMany.bind(this, parent, colSelector, resultSelector);
            __extends(instance, __super);
            return instance;
        };
    })(generator);

    var RangeEnumerable = (function (__super) {
        return function (start, end) {
            var ranger = function* (start, end) {
                for (start; start <= end; start++) {
                    yield start;
                }
            };

            var instance = ranger.bind(this, start, end);
            __extends(instance, __super);
            return instance;
        };
    })(generator);

    var TakeEnumerable = (function (__super) {
        return function (parent, selector) {
            var taker = function* (parent, selector) {
                var index = 0;
                if (typeof selector === 'number') {
                    for (let item of parent()) {
                        if (index < selector) {
                            yield item;
                            index++;
                        } else {
                            break;
                        }
                    }
                } else if (typeof selector === 'function') {
                    for (let item of parent()) {
                        if (selector(item, index)) {
                            yield item;
                        } else {
                            break;
                        }
                        index++;
                    }
                }
            };

            var instance = taker.bind(this, parent, selector);
            __extends(instance, __super);
            return instance;
        };
    })(generator);

    var SkipEnumerable = (function (__super) {
        return function (parent, selector) {
            var skippy = function* (parent, selector) {
                var index = 0;
                if (typeof selector === 'number') {
                    for (let item of parent()) {
                        if (index >= selector) {
                            yield item;
                        }
                        index++;
                    }
                } else if (typeof selector === 'function') {
                    let flag = false;
                    index = -1;
                    for (let item of parent()) {
                        index++;
                        if (!flag && !selector(item, index)) {
                            flag = true;
                        }

                        if (flag) {
                            yield item;
                        }
                    }
                }
            };

            var instance = skippy.bind(this, parent, selector);
            __extends(instance, __super);
            return instance;
        };
    })(generator);

    var RepeatEnumerable = (function (__super) {
        return function (item, count) {
            var repeater = function* (item, count) {
                var stripped = JSON.stringify(item);
                for (var i = 0; i < count; i++) {
                    yield JSON.parse(stripped);
                }
            };

            var instance = repeater.bind(this, item, count);
            __extends(instance, __super);
            return instance;
        };
    })(generator);

    Enumerable.range = function (start, end) {
        start = start || 0;
        end = end || 0;

        return RangeEnumerable(start, end);
    };

    Enumerable.repeat = function (item, count) {
        return RepeatEnumerable(item, count || 0);
    };

    // extension methods
    Array.prototype.asEnumerable = function() {
        return Enumerable(this);
    };

    if (typeof module === 'object' && typeof module.exports === 'object') {
        module.exports = Enumerable;
    } else if (typeof define === 'function' && define.amd) {
        define('linq', function () {
            return Enumerable;
        });
    } else {
        global.Enumerable = Enumerable;
    }
})(this);
<|endoftext|>


<commit_before>/**
* Module that contains the linked list data structure implementations.
* Depends on core.js, datastructures.js, anim.js, utils.js
*/
/*global JSAV:true */
(function($) {
  if (typeof JSAV === "undefined") { return; }

  var Edge = JSAV._types.ds.Edge;

  var List = function(jsav, options) {
    this.jsav = jsav;
    this.options = $.extend({visible: true, nodegap: 40}, options);
    var el = this.options.element || $("
");
    el.addClass("jsavlist");
    for (var key in this.options) {
      var val = this.options[key];
      if (this.options.hasOwnProperty(key) && typeof(val) === "string" || typeof(val) === "number" || typeof(val) === "boolean") {
        el.attr("data-" + key, val);
      }
    }
    if (!this.options.element) {
      $(jsav.canvas).append(el);
    }
    this.element = el;
    this.element.attr({"id": this.id()});
    JSAV.utils._helpers.handlePosition(this);
    JSAV.utils._helpers.handleVisibility(this, this.options);
  };
  var listproto = List.prototype;
  $.extend(listproto, JSAV._types.ds.common);
  listproto.first = function(newFirst, options) {
    if (typeof newFirst === "undefined") {
      return this._first;
    } else {
      return this.addFirst(newFirst, options);
    }
  };
  listproto._setfirst = JSAV.anim(function(newFirst) {
    var oldFirst = this._first;
    this._first = newFirst;
    return [oldFirst];
  });
  listproto.add = function(index, newValue, options) {
    if (index < 0 || index > this.size()) { return this; }
    if (index === 0) {
      return this.addFirst(newValue, options);
    }
    var node = this.get(index - 1),
      newNode;
    if (newValue instanceof ListNode) {
      newNode = newValue;
    } else {
      newNode = this.newNode(newValue);
    }
    if (node) { // there is node for the index
      newNode.next(node.next(), options);
      node.next(newNode, options);
    }
    return this;
  };
  listproto.addFirst = function(newValue, options) {
    if (newValue instanceof ListNode) {
      newValue.next(this._first, options);
      this._setfirst(newValue, options);
    } else {
      this._setfirst(this.newNode(newValue, $.extend({}, options, {first: true, next: this._first})), options);
    }
    return this;
  };
  /** returns the last item in the list or if newLast is given, adds it to the end */
  listproto.last = function(newLast, options) {
    if (typeof newLast === "undefined") {
      var curNode = this.first();
      while (curNode.next()) {
        curNode = curNode.next();
      }
      return curNode;
    } else {
      this.addLast(newLast, options);
    }
  };
  /** adds the given value/node as the last item in the list */
  listproto.addLast = function(newValue, options) {
    var last = this.last(),
        newNode;
    if (newValue instanceof ListNode) {
      newNode = newValue;
    } else {
      newNode = this.newNode(newValue);
    }
    last.next(newNode, options);
    return this;
  };
  /** Returns the item at index, first node is at index 0 */
  listproto.get = function(index) {
    if (typeof(index) !== "number" || index < 0) { return; }
    var curNode = this.first(),
        pos = 0;
    while (curNode.next() && pos < index) {
      curNode = curNode.next();
      pos++;
    }
    if (pos === index) {
      return curNode;
    } else {
      return undefined;
    }
  };
  listproto.newNode = function(value, options) {
    return new ListNode(this, value, $.extend({first: false}, this.options, options));
  };
  listproto.remove = function(index, options) {
    // TODO: remove bounds checks -> use removefirst/last
    if (index === 0) {
      return this.removeFirst(options);
    } else if (index === this.size() - 1) {
      return this.removeLast(options);
    }
    var prev = this.get(index - 1),
        next = this.get(index + 1),
        oldNode = prev.next();
    prev.next(next, options);
    return oldNode;
  };
  listproto.removeFirst = function(options) {
    var oldFirst = this.first();
    this._setfirst(oldFirst.next(), options);
    return oldFirst;
  };
  listproto.removeLast = function(options) {
    var newLast = this.get(this.size() - 2),
      oldLast = this.last();
    newLast.next(null, options);
    return oldLast;
  };
  listproto.layout = function(options) {
    var layoutAlg = $.extend({}, this.options, options).layout || "_default";
    this.jsav.ds.layout.list[layoutAlg](this, options);
  };
  listproto.state = function(newState) {
    // TODO: implement list.state
  };
  listproto.size = function() {
    var curNode = this.first(),
      size = 0;
    while (curNode) {
      size++;
      curNode = curNode.next();
    }
    return size;
  };
  listproto.css = JSAV.utils._helpers.css;
  listproto._setcss = JSAV.anim(JSAV.utils._helpers._setcss);

  // add the event handler registration functions to the list prototype
  JSAV.utils._events._addEventSupport(listproto);

  var ListNode = function(container, value, options) {
    this.jsav = container.jsav;
    this.container = container;
    this._next = options.next;
    this._value = value;
    this.options = $.extend(true, {visible: true}, options);
    var el = $("
" + this._valstring(value) + "
"),
      valtype = typeof(value);
    if (valtype === "object") { valtype = "string"; }
    this.element = el;
    el.addClass("jsavnode jsavlistnode")
        .attr({"data-value": value, "id": this.id(), "data-value-type": valtype })
        .data("node", this);
    if ("first" in options && options.first) {
      this.container.element.prepend(el);
    } else {
      this.container.element.append(el);
    }
    if (this._next) {
      this._edgetonext = new Edge(this.jsav, this, this._next, {"arrow-end": "classic-wide-long"});
      if (this.options.edgeLabel) {
        this._edgetonext.label(this.options.edgeLabel);
      }
    }
    JSAV.utils._helpers.handleVisibility(this, this.options);
  };

  var listnodeproto = ListNode.prototype;
  $.extend(listnodeproto, JSAV._types.ds.Node.prototype);

  listnodeproto.next = function(newNext, options) {
    if (typeof newNext === "undefined") {
      return this._next;
    } else {
      return this._setnext(newNext, options);
    }
  };
  listnodeproto._setnext = JSAV.anim(function(newNext, options) {
    var oldNext = this._next;
    this._next = newNext;
    if (newNext && this._edgetonext) {
      this._edgetonext.end(newNext);
    } else if (newNext){
      this._edgetonext = new Edge(this.jsav, this, this._next, {"arrow-end": "classic-wide-long"});
    }
    if (options && options.edgeLabel) {
      this._edgetonext.label(options.edgeLabel);
    }
    return [oldNext];
  });
  listnodeproto.edgeToNext = function() {
    return this._edgetonext;
  };
  listnodeproto.state = function(newState) {
    // TODO: implement state
  };
  function centerList(list, options) {
    // center the list inside its parent container
    if (list.options.hasOwnProperty("center") && !list.options.center) {
      // if options center is set to falsy value, return
      return;
    }
    // width of list expected to be last items position + its width
    var width = list.element.outerWidth(),
      containerWidth = $(list.jsav.canvas).width();
    list.css("left", (containerWidth - width)/2, options);
  }

  var horizontalList = function(list, options) {
    var curNode = list.first(),
        prevNode,
        prevLeft = 0,
        opts = $.extend({updateLeft: true, updateTop: true, updateEdges: true}, list.options, options);
    while (curNode) {
      var newPos = { };
      if (opts.updateLeft) { newPos.left = prevLeft; }
      if (opts.updateTop) { newPos.top = 0; }
      curNode.css(newPos);
      prevLeft += opts.nodegap + curNode.element.outerWidth();
      var edge = prevNode?prevNode._edgetonext:undefined;
      if (edge && opts.updateEdges) {
        var start = [0, prevNode.element.position().left + prevNode.element.width() - 5,
                    prevNode.element.position().top + Math.round(prevNode.element.height()/2)],
            end = [1, curNode.element.position().left - 3,
                    curNode.element.position().top + Math.round(curNode.element.height()/2)];
        edge.g.movePoints([start, end], options);
      }
      prevNode = curNode;
      curNode = curNode.next();
    }
    list.css("width", prevLeft - opts.nodegap, options);
    list.css("height", "50px", options);
    centerList(list, opts);
  };

  JSAV.ext.ds.layout.list = {
    "_default": horizontalList
  };

  JSAV.ext.ds.list = function() {
    return new List(this);
  };
})(jQuery);<commit_msg>jshint warnings fixed<commit_after>/**
* Module that contains the linked list data structure implementations.
* Depends on core.js, datastructures.js, anim.js, utils.js
*/
/*global JSAV:true */
(function($) {
  "use strict";
  if (typeof JSAV === "undefined") { return; }

  var Edge = JSAV._types.ds.Edge;

  var List = function(jsav, options) {
    this.jsav = jsav;
    this.options = $.extend({visible: true, nodegap: 40}, options);
    var el = this.options.element || $("
");
    el.addClass("jsavlist");
    for (var key in this.options) {
      var val = this.options[key];
      if (this.options.hasOwnProperty(key) && typeof(val) === "string" || typeof(val) === "number" || typeof(val) === "boolean") {
        el.attr("data-" + key, val);
      }
    }
    if (!this.options.element) {
      $(jsav.canvas).append(el);
    }
    this.element = el;
    this.element.attr({"id": this.id()});
    JSAV.utils._helpers.handlePosition(this);
    JSAV.utils._helpers.handleVisibility(this, this.options);
  };
  var listproto = List.prototype;
  $.extend(listproto, JSAV._types.ds.common);
  listproto.first = function(newFirst, options) {
    if (typeof newFirst === "undefined") {
      return this._first;
    } else {
      return this.addFirst(newFirst, options);
    }
  };
  listproto._setfirst = JSAV.anim(function(newFirst) {
    var oldFirst = this._first;
    this._first = newFirst;
    return [oldFirst];
  });
  listproto.add = function(index, newValue, options) {
    if (index < 0 || index > this.size()) { return this; }
    if (index === 0) {
      return this.addFirst(newValue, options);
    }
    var node = this.get(index - 1),
      newNode;
    if (newValue instanceof ListNode) {
      newNode = newValue;
    } else {
      newNode = this.newNode(newValue);
    }
    if (node) { // there is node for the index
      newNode.next(node.next(), options);
      node.next(newNode, options);
    }
    return this;
  };
  listproto.addFirst = function(newValue, options) {
    if (newValue instanceof ListNode) {
      newValue.next(this._first, options);
      this._setfirst(newValue, options);
    } else {
      this._setfirst(this.newNode(newValue, $.extend({}, options, {first: true, next: this._first})), options);
    }
    return this;
  };
  /** returns the last item in the list or if newLast is given, adds it to the end */
  listproto.last = function(newLast, options) {
    if (typeof newLast === "undefined") {
      var curNode = this.first();
      while (curNode.next()) {
        curNode = curNode.next();
      }
      return curNode;
    } else {
      this.addLast(newLast, options);
    }
  };
  /** adds the given value/node as the last item in the list */
  listproto.addLast = function(newValue, options) {
    var last = this.last(),
        newNode;
    if (newValue instanceof ListNode) {
      newNode = newValue;
    } else {
      newNode = this.newNode(newValue);
    }
    last.next(newNode, options);
    return this;
  };
  /** Returns the item at index, first node is at index 0 */
  listproto.get = function(index) {
    if (typeof(index) !== "number" || index < 0) { return; }
    var curNode = this.first(),
        pos = 0;
    while (curNode.next() && pos < index) {
      curNode = curNode.next();
      pos++;
    }
    if (pos === index) {
      return curNode;
    } else {
      return undefined;
    }
  };
  listproto.newNode = function(value, options) {
    return new ListNode(this, value, $.extend({first: false}, this.options, options));
  };
  listproto.remove = function(index, options) {
    // TODO: remove bounds checks -> use removefirst/last
    if (index === 0) {
      return this.removeFirst(options);
    } else if (index === this.size() - 1) {
      return this.removeLast(options);
    }
    var prev = this.get(index - 1),
        next = this.get(index + 1),
        oldNode = prev.next();
    prev.next(next, options);
    return oldNode;
  };
  listproto.removeFirst = function(options) {
    var oldFirst = this.first();
    this._setfirst(oldFirst.next(), options);
    return oldFirst;
  };
  listproto.removeLast = function(options) {
    var newLast = this.get(this.size() - 2),
      oldLast = this.last();
    newLast.next(null, options);
    return oldLast;
  };
  listproto.layout = function(options) {
    var layoutAlg = $.extend({}, this.options, options).layout || "_default";
    this.jsav.ds.layout.list[layoutAlg](this, options);
  };
  listproto.state = function(newState) {
    // TODO: implement list.state
  };
  listproto.size = function() {
    var curNode = this.first(),
      size = 0;
    while (curNode) {
      size++;
      curNode = curNode.next();
    }
    return size;
  };
  listproto.css = JSAV.utils._helpers.css;
  listproto._setcss = JSAV.anim(JSAV.utils._helpers._setcss);

  // add the event handler registration functions to the list prototype
  JSAV.utils._events._addEventSupport(listproto);

  var ListNode = function(container, value, options) {
    this.jsav = container.jsav;
    this.container = container;
    this._next = options.next;
    this._value = value;
    this.options = $.extend(true, {visible: true}, options);
    var el = $("
" + this._valstring(value) + "
"),
      valtype = typeof(value);
    if (valtype === "object") { valtype = "string"; }
    this.element = el;
    el.addClass("jsavnode jsavlistnode")
        .attr({"data-value": value, "id": this.id(), "data-value-type": valtype })
        .data("node", this);
    if ("first" in options && options.first) {
      this.container.element.prepend(el);
    } else {
      this.container.element.append(el);
    }
    if (this._next) {
      this._edgetonext = new Edge(this.jsav, this, this._next, {"arrow-end": "classic-wide-long"});
      if (this.options.edgeLabel) {
        this._edgetonext.label(this.options.edgeLabel);
      }
    }
    JSAV.utils._helpers.handleVisibility(this, this.options);
  };

  var listnodeproto = ListNode.prototype;
  $.extend(listnodeproto, JSAV._types.ds.Node.prototype);

  listnodeproto.next = function(newNext, options) {
    if (typeof newNext === "undefined") {
      return this._next;
    } else {
      return this._setnext(newNext, options);
    }
  };
  listnodeproto._setnext = JSAV.anim(function(newNext, options) {
    var oldNext = this._next;
    this._next = newNext;
    if (newNext && this._edgetonext) {
      this._edgetonext.end(newNext);
    } else if (newNext){
      this._edgetonext = new Edge(this.jsav, this, this._next, {"arrow-end": "classic-wide-long"});
    }
    if (options && options.edgeLabel) {
      this._edgetonext.label(options.edgeLabel);
    }
    return [oldNext];
  });
  listnodeproto.edgeToNext = function() {
    return this._edgetonext;
  };
  listnodeproto.state = function(newState) {
    // TODO: implement state
  };
  function centerList(list, options) {
    // center the list inside its parent container
    if (list.options.hasOwnProperty("center") && !list.options.center) {
      // if options center is set to falsy value, return
      return;
    }
    // width of list expected to be last items position + its width
    var width = list.element.outerWidth(),
      containerWidth = $(list.jsav.canvas).width();
    list.css("left", (containerWidth - width)/2, options);
  }

  var horizontalList = function(list, options) {
    var curNode = list.first(),
        prevNode,
        prevLeft = 0,
        opts = $.extend({updateLeft: true, updateTop: true, updateEdges: true}, list.options, options);
    while (curNode) {
      var newPos = { };
      if (opts.updateLeft) { newPos.left = prevLeft; }
      if (opts.updateTop) { newPos.top = 0; }
      curNode.css(newPos);
      prevLeft += opts.nodegap + curNode.element.outerWidth();
      var edge = prevNode?prevNode._edgetonext:undefined;
      if (edge && opts.updateEdges) {
        var start = [0, prevNode.element.position().left + prevNode.element.width() - 5,
                    prevNode.element.position().top + Math.round(prevNode.element.height()/2)],
            end = [1, curNode.element.position().left - 3,
                    curNode.element.position().top + Math.round(curNode.element.height()/2)];
        edge.g.movePoints([start, end], options);
      }
      prevNode = curNode;
      curNode = curNode.next();
    }
    list.css("width", prevLeft - opts.nodegap, options);
    list.css("height", "50px", options);
    centerList(list, opts);
  };

  JSAV.ext.ds.layout.list = {
    "_default": horizontalList
  };

  JSAV.ext.ds.list = function() {
    return new List(this);
  };
}(jQuery));<|endoftext|>