<commit_before>'use strict'

// external deps
var ObjectId = require("mongodb").ObjectId;
var UomManager = require('./uom-manager');
var BaseManager = require('module-toolkit').BaseManager;
var i18n = require('dl-i18n');
var assert = require('assert');

// internal deps
require('mongodb-toolkit');
var DLModels = require('dl-models');
var map = DLModels.map;
var Product = DLModels.master.Product;
var UomManager = require('./uom-manager');
var CurrencyManager = require('./currency-manager');

module.exports = class ProductManager extends BaseManager {
    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(map.master.collection.Product);
        this.uomManager = new UomManager(db, user);
        this.currencyManager = new CurrencyManager(db, user);
    }

    _getQuery(paging) {
        var _default = {
            _deleted: false,

        },
            pagingFilter = paging.filter || {},
            keywordFilter = {},

            query = {};

        if (paging.keyword) {
            var keyRegex = new RegExp(paging.keyword, "i");
            var codeFilter = {
                'code': {
                    '$regex': keyRegex
                }
            };
            var nameFilter = {
                'name': {
                    '$regex': keyRegex
                }
            };

            keywordFilter['$or'] = [codeFilter, nameFilter];
        }

        query["$and"] = [_default, keywordFilter, pagingFilter];
        return query;
    }

    _validate(product) {
        var errors = {};
        var valid = product;

        // 1. begin: Declare promises.
        var getProductPromise = this.collection.singleOrDefault({
            _id: {
                '$ne': new ObjectId(valid._id)
            },
            code: valid.code
        });

        var getUom = valid.uom && ObjectId.isValid(valid.uom._id) ? this.uomManager.getSingleByIdOrDefault(valid.uom._id) : Promise.resolve(null);
        // 2. begin: Validation.
        return Promise.all([getProductPromise, getUom])
            .then((results) => {
                var _module = results[0];
                var _uom = results[1];

                if (!valid.code || valid.code == '')
                    errors["code"] = i18n.__("Product.code.isRequired:%s is required", i18n.__("Product.code._:Code")); // "Kode tidak boleh kosong.";
                else if (_module) {
                    errors["code"] = i18n.__("Product.code.isExists:%s is already exists", i18n.__("Product.code._:Code")); // "Kode sudah terdaftar.";
                }

                if (!valid.name || valid.name == '')
                    errors["name"] = i18n.__("Product.name.isRequired:%s is required", i18n.__("Product.name._:Name")); // "Nama tidak boleh kosong.";

                if (!valid.uom) {
                    errors["uom"] = i18n.__("Product.uom.isRequired:%s is required", i18n.__("Product.uom._:Uom")); //"Satuan tidak boleh kosong";
                }
                if (valid.uom) {
                    if (!valid.uom.unit || valid.uom.unit == '')
                        errors["uom"] = i18n.__("Product.uom.isRequired:%s is required", i18n.__("Product.uom._:Uom")); //"Satuan tidak boleh kosong";
                }
                else if (_uom) {
                    errors["uom"] = i18n.__("Product.uom.noExists:%s is not exists", i18n.__("Product.uom._:Uom")); //"Satuan tidak boleh kosong";
                }

                // 2c. begin: check if data has any error, reject if it has.
                if (Object.getOwnPropertyNames(errors).length > 0) {
                    var ValidationError = require('module-toolkit').ValidationError;
                    return Promise.reject(new ValidationError('Product Manager : data does not pass validation' + JSON.stringify(errors), errors));
                }

                valid.uom = _uom;
                valid.uomId = new ObjectId(valid.uom._id);
                if (!valid.stamp)
                    valid = new Product(valid);
                valid.stamp(this.user.username, 'manager');
                valid.currency.rate = Number(valid.currency.rate);
                valid.price = Number(valid.price);
                return Promise.resolve(valid);
            });
    }

    getProduct() {
        return new Promise((resolve, reject) => {
            var query = {
                _deleted: false
            };
            this.collection
                .where(query)
                .execute()
                .then(products => {
                    resolve(products);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    insert(dataFile) {
        return new Promise((resolve, reject) => {
            var product, uom, currency;
            this.getProduct()
                .then(results => {
                    this.uomManager.getUOM()
                        .then(uoms => {
                            this.currencyManager.getCurrency()
                                .then(currencies => {
                                    product = results.data;
                                    uom = uoms.data;
                                    currency = currencies.data;
                                    var data = [];
                                    if (dataFile != "") {
                                        for (var i = 1; i < dataFile.length; i++) {
                                            data.push({
                                                "code": dataFile[i][0].trim(),
                                                "name": dataFile[i][1].trim(),
                                                "uom": dataFile[i][2].trim(),
                                                "currency": dataFile[i][3].trim(),
                                                "price": dataFile[i][4],
                                                "tags": dataFile[i][5].trim(),
                                                "description": dataFile[i][6].trim()
                                            });
                                        }
                                    }
                                    var dataError = [], errorMessage;
                                    for (var i = 0; i < data.length; i++) {
                                        errorMessage = "";
                                        if (data[i]["code"] === "" || data[i]["code"] === undefined) {
                                            errorMessage = errorMessage + "Kode tidak boleh kosong, ";
                                        }
                                        if (data[i]["name"] === "" || data[i]["name"] === undefined) {
                                            errorMessage = errorMessage + "Nama tidak boleh kosong, ";
                                        }
                                        if (data[i]["uom"] === "" || data[i]["uom"] === undefined) {
                                            errorMessage = errorMessage + "Satuan tidak boleh kosong, ";
                                        }
                                        if (data[i]["currency"] === "" || data[i]["currency"] === undefined) {
                                            errorMessage = errorMessage + "Mata Uang tidak boleh kosong, ";
                                        }
                                        if (data[i]["price"] === "" || data[i]["price"] === undefined) {
                                            errorMessage = errorMessage + "Harga tidak boleh kosong, ";
                                        } else if (isNaN(data[i]["price"])) {
                                            errorMessage = errorMessage + "Harga harus numerik, ";
                                        }
                                        else {
                                            var rateTemp = (data[i]["price"]).toString().split(".");
                                            if (rateTemp[1] === undefined) {
                                            } else if (rateTemp[1].length > 2) {
                                                errorMessage = errorMessage + "Harga maksimal memiliki 2 digit dibelakang koma, ";
                                            }
                                        }
                                        for (var j = 0; j < product.length; j++) {
                                            if (product[j]["code"] === data[i]["code"]) {
                                                errorMessage = errorMessage + "Kode tidak boleh duplikat, ";
                                            }
                                            if (product[j]["name"] === data[i]["name"]) {
                                                errorMessage = errorMessage + "Nama tidak boleh duplikat, ";
                                            }
                                        }
                                        var flagUom = false;
                                        for (var j = 0; j < uom.length; j++) {
                                            if (uom[j]["unit"] === data[i]["uom"]) {
                                                flagUom = true;
                                                break;
                                            }
                                        }
                                        if (flagUom === false) {
                                            errorMessage = errorMessage + "Satuan tidak terdaftar di Master Satuan, ";
                                        }
                                        var flagCurrency = false;
                                        for (var j = 0; j < currency.length; j++) {
                                            if (currency[j]["code"] !== data[i]["currency"]) {
                                                flagCurrency = true;
                                                break;
                                            }
                                        }
                                        if (flagCurrency === false) {
                                            errorMessage = errorMessage + "Mata Uang tidak terdaftar di Master Mata Uang";
                                        }

                                        if (errorMessage !== "") {
                                            dataError.push({ "code": data[i]["code"], "name": data[i]["name"], "uom": data[i]["uom"], "currency": data[i]["currency"], "price": data[i]["price"], "tags": data[i]["tags"], "description": data[i]["description"], "Error": errorMessage });
                                        }
                                    }
                                    if (dataError.length === 0) {
                                        var newProduct = [];
                                        for (var i = 0; i < data.length; i++) {
                                            var valid = new Product(data[i]);
                                            for (var c = 0; c < currency.length; c++) {
                                                for (var j = 0; j < uom.length; j++) {
                                                    if (data[i]["uom"] == uom[j]["unit"] && data[i]["currency"] == currency[c]["code"]) {
                                                        valid.currency = currency[c];
                                                        valid.currency.rate = Number(valid.currency.rate);
                                                        valid.price = Number(valid.price);
                                                        valid.uomId = new ObjectId(uom[j]["_id"]);
                                                        valid.uom = uom[j];
                                                        valid.stamp(this.user.username, 'manager');
                                                        this.collection.insert(valid)
                                                            .then(id => {
                                                                this.getSingleById(id)
                                                                    .then(resultItem => {
                                                                        newProduct.push(resultItem)
                                                                        resolve(newProduct);
                                                                    })
                                                                    .catch(e => {
                                                                        reject(e);
                                                                    });
                                                            })
                                                            .catch(e => {
                                                                reject(e);
                                                            });
                                                        break;
                                                    }

                                                }
                                            }
                                        }
                                    } else {
                                        resolve(dataError);
                                    }
                                })
                        })
                })
        })
    }

    _createIndexes() {
        var dateIndex = {
            name: `ix_${map.master.collection.Product}__updatedDate`,
            key: {
                _updatedDate: -1
            }
        };

        var codeIndex = {
            name: `ix_${map.master.collection.Product}_code`,
            key: {
                code: 1
            },
            unique: true
        };

        return this.collection.createIndexes([dateIndex, codeIndex]);
    }

    getProductByTags(key, tag) {
        return new Promise((resolve, reject) => {
            var regex = new RegExp(key, "i");
            var regex2 = new RegExp(tag, "i");
            this.collection.aggregate(
                [{
                    $match: {
                        $and: [{
                            $and: [{
                                "tags": regex2
                            }, {
                                    "_deleted": false
                                }]
                        }, {
                                "name": {
                                    "$regex": regex
                                }
                            }]
                    }
                }]
            )
                .toArray(function (err, result) {
                    assert.equal(err, null);
                    resolve(result);
                });
        });
    }

    readById(paging) {
        var _paging = Object.assign({
            order: {},
            filter: {},
            select: []
        }, paging);

        return this._createIndexes()
            .then((createIndexResults) => {
                return this.collection
                    .where(_paging.filter)
                    .select(_paging.select)
                    .order(_paging.order)
                    .execute();
            });
    }

    readById(paging) {
        var _paging = Object.assign({
            order: {},
            filter: {},
            select: []
        }, paging);

        return this._createIndexes()
            .then((createIndexResults) => {
                return this.collection
                    .where(_paging.filter)
                    .select(_paging.select)
                    .order(_paging.order)
                    .execute();
            });
    }
};
<commit_msg>update product manager<commit_after>'use strict'

// external deps
var ObjectId = require("mongodb").ObjectId;
var UomManager = require('./uom-manager');
var BaseManager = require('module-toolkit').BaseManager;
var i18n = require('dl-i18n');
var assert = require('assert');

// internal deps
require('mongodb-toolkit');
var DLModels = require('dl-models');
var map = DLModels.map;
var Product = DLModels.master.Product;
var UomManager = require('./uom-manager');
var CurrencyManager = require('./currency-manager');

module.exports = class ProductManager extends BaseManager {
    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(map.master.collection.Product);
        this.uomManager = new UomManager(db, user);
        this.currencyManager = new CurrencyManager(db, user);
    }

    _getQuery(paging) {
        var _default = {
            _deleted: false,

        },
            pagingFilter = paging.filter || {},
            keywordFilter = {},

            query = {};

        if (paging.keyword) {
            var keyRegex = new RegExp(paging.keyword, "i");
            var codeFilter = {
                'code': {
                    '$regex': keyRegex
                }
            };
            var nameFilter = {
                'name': {
                    '$regex': keyRegex
                }
            };

            keywordFilter['$or'] = [codeFilter, nameFilter];
        }

        query["$and"] = [_default, keywordFilter, pagingFilter];
        return query;
    }

    _validate(product) {
        var errors = {};
        var valid = product;

        // 1. begin: Declare promises.
        var getProductPromise = this.collection.singleOrDefault({
            _id: {
                '$ne': new ObjectId(valid._id)
            },
            code: valid.code
        });

        var getUom = valid.uom && ObjectId.isValid(valid.uom._id) ? this.uomManager.getSingleByIdOrDefault(valid.uom._id) : Promise.resolve(null);
        // 2. begin: Validation.
        return Promise.all([getProductPromise, getUom])
            .then((results) => {
                var _module = results[0];
                var _uom = results[1];

                if (!valid.code || valid.code == '')
                    errors["code"] = i18n.__("Product.code.isRequired:%s is required", i18n.__("Product.code._:Code")); // "Kode tidak boleh kosong.";
                else if (_module) {
                    errors["code"] = i18n.__("Product.code.isExists:%s is already exists", i18n.__("Product.code._:Code")); // "Kode sudah terdaftar.";
                }

                if (!valid.name || valid.name == '')
                    errors["name"] = i18n.__("Product.name.isRequired:%s is required", i18n.__("Product.name._:Name")); // "Nama tidak boleh kosong.";

                if (!valid.uom) {
                    errors["uom"] = i18n.__("Product.uom.isRequired:%s is required", i18n.__("Product.uom._:Uom")); //"Satuan tidak boleh kosong";
                }
                if (valid.uom) {
                    if (!valid.uom.unit || valid.uom.unit == '')
                        errors["uom"] = i18n.__("Product.uom.isRequired:%s is required", i18n.__("Product.uom._:Uom")); //"Satuan tidak boleh kosong";
                }
                else if (_uom) {
                    errors["uom"] = i18n.__("Product.uom.noExists:%s is not exists", i18n.__("Product.uom._:Uom")); //"Satuan tidak boleh kosong";
                }

                // 2c. begin: check if data has any error, reject if it has.
                if (Object.getOwnPropertyNames(errors).length > 0) {
                    var ValidationError = require('module-toolkit').ValidationError;
                    return Promise.reject(new ValidationError('Product Manager : data does not pass validation' + JSON.stringify(errors), errors));
                }

                valid.uom = _uom;
                valid.uomId = new ObjectId(valid.uom._id);
                if (!valid.stamp)
                    valid = new Product(valid);
                valid.stamp(this.user.username, 'manager');
                valid.currency.rate = Number(valid.currency.rate);
                valid.price = Number(valid.price);
                return Promise.resolve(valid);
            });
    }

    getProduct() {
        return new Promise((resolve, reject) => {
            var query = {
                _deleted: false
            };
            this.collection
                .where(query)
                .execute()
                .then(products => {
                    resolve(products);
                })
                .catch(e => {
                    reject(e);
                });
        });
    }

    insert(dataFile) {
        return new Promise((resolve, reject) => {
            var product, uom, currency;
            this.getProduct()
                .then(results => {
                    this.uomManager.getUOM()
                        .then(uoms => {
                            this.currencyManager.getCurrency()
                                .then(currencies => {
                                    product = results.data;
                                    uom = uoms.data;
                                    currency = currencies.data;
                                    var data = [];
                                    if (dataFile != "") {
                                        for (var i = 1; i < dataFile.length; i++) {
                                            data.push({
                                                "code": dataFile[i][0].trim(),
                                                "name": dataFile[i][1].trim(),
                                                "uom": dataFile[i][2].trim(),
                                                "currency": dataFile[i][3].trim(),
                                                "price": dataFile[i][4],
                                                "tags": dataFile[i][5].trim(),
                                                "description": dataFile[i][6].trim()
                                            });
                                        }
                                    }
                                    var dataError = [], errorMessage;
                                    for (var i = 0; i < data.length; i++) {
                                        errorMessage = "";
                                        if (data[i]["code"] === "" || data[i]["code"] === undefined) {
                                            errorMessage = errorMessage + "Kode tidak boleh kosong, ";
                                        }
                                        if (data[i]["name"] === "" || data[i]["name"] === undefined) {
                                            errorMessage = errorMessage + "Nama tidak boleh kosong, ";
                                        }
                                        if (data[i]["uom"] === "" || data[i]["uom"] === undefined) {
                                            errorMessage = errorMessage + "Satuan tidak boleh kosong, ";
                                        }
                                        if (data[i]["currency"] === "" || data[i]["currency"] === undefined) {
                                            errorMessage = errorMessage + "Mata Uang tidak boleh kosong, ";
                                        }
                                        if (data[i]["price"] === "" || data[i]["price"] === undefined) {
                                            errorMessage = errorMessage + "Harga tidak boleh kosong, ";
                                        } else if (isNaN(data[i]["price"])) {
                                            errorMessage = errorMessage + "Harga harus numerik, ";
                                        }
                                        else {
                                            var rateTemp = (data[i]["price"]).toString().split(".");
                                            if (rateTemp[1] === undefined) {
                                            } else if (rateTemp[1].length > 2) {
                                                errorMessage = errorMessage + "Harga maksimal memiliki 2 digit dibelakang koma, ";
                                            }
                                        }
                                        for (var j = 0; j < product.length; j++) {
                                            if (product[j]["code"] === data[i]["code"]) {
                                                errorMessage = errorMessage + "Kode tidak boleh duplikat, ";
                                            }
                                            if (product[j]["name"] === data[i]["name"]) {
                                                errorMessage = errorMessage + "Nama tidak boleh duplikat, ";
                                            }
                                        }
                                        var flagUom = false;
                                        for (var j = 0; j < uom.length; j++) {
                                            if (uom[j]["unit"] === data[i]["uom"]) {
                                                flagUom = true;
                                                break;
                                            }
                                        }
                                        if (flagUom === false) {
                                            errorMessage = errorMessage + "Satuan tidak terdaftar di Master Satuan, ";
                                        }
                                        var flagCurrency = false;
                                        for (var j = 0; j < currency.length; j++) {
                                            if (currency[j]["code"] === data[i]["currency"]) {
                                                flagCurrency = true;
                                                break;
                                            }
                                        }
                                        if (flagCurrency === false) {
                                            errorMessage = errorMessage + "Mata Uang tidak terdaftar di Master Mata Uang";
                                        }

                                        if (errorMessage !== "") {
                                            dataError.push({ "code": data[i]["code"], "name": data[i]["name"], "uom": data[i]["uom"], "currency": data[i]["currency"], "price": data[i]["price"], "tags": data[i]["tags"], "description": data[i]["description"], "Error": errorMessage });
                                        }
                                    }
                                    if (dataError.length === 0) {
                                        var newProduct = [];
                                        for (var i = 0; i < data.length; i++) {
                                            var valid = new Product(data[i]);
                                            for (var c = 0; c < currency.length; c++) {
                                                for (var j = 0; j < uom.length; j++) {
                                                    if (data[i]["uom"] == uom[j]["unit"] && data[i]["currency"] == currency[c]["code"]) {
                                                        valid.currency = currency[c];
                                                        valid.currency.rate = Number(valid.currency.rate);
                                                        valid.price = Number(valid.price);
                                                        valid.uomId = new ObjectId(uom[j]["_id"]);
                                                        valid.uom = uom[j];
                                                        valid.stamp(this.user.username, 'manager');
                                                        this.collection.insert(valid)
                                                            .then(id => {
                                                                this.getSingleById(id)
                                                                    .then(resultItem => {
                                                                        newProduct.push(resultItem)
                                                                        resolve(newProduct);
                                                                    })
                                                                    .catch(e => {
                                                                        reject(e);
                                                                    });
                                                            })
                                                            .catch(e => {
                                                                reject(e);
                                                            });
                                                        break;
                                                    }

                                                }
                                            }
                                        }
                                    } else {
                                        resolve(dataError);
                                    }
                                })
                        })
                })
        })
    }

    _createIndexes() {
        var dateIndex = {
            name: `ix_${map.master.collection.Product}__updatedDate`,
            key: {
                _updatedDate: -1
            }
        };

        var codeIndex = {
            name: `ix_${map.master.collection.Product}_code`,
            key: {
                code: 1
            },
            unique: true
        };

        return this.collection.createIndexes([dateIndex, codeIndex]);
    }

    getProductByTags(key, tag) {
        return new Promise((resolve, reject) => {
            var regex = new RegExp(key, "i");
            var regex2 = new RegExp(tag, "i");
            this.collection.aggregate(
                [{
                    $match: {
                        $and: [{
                            $and: [{
                                "tags": regex2
                            }, {
                                    "_deleted": false
                                }]
                        }, {
                                "name": {
                                    "$regex": regex
                                }
                            }]
                    }
                }]
            )
                .toArray(function (err, result) {
                    assert.equal(err, null);
                    resolve(result);
                });
        });
    }

    readById(paging) {
        var _paging = Object.assign({
            order: {},
            filter: {},
            select: []
        }, paging);

        return this._createIndexes()
            .then((createIndexResults) => {
                return this.collection
                    .where(_paging.filter)
                    .select(_paging.select)
                    .order(_paging.order)
                    .execute();
            });
    }

    readById(paging) {
        var _paging = Object.assign({
            order: {},
            filter: {},
            select: []
        }, paging);

        return this._createIndexes()
            .then((createIndexResults) => {
                return this.collection
                    .where(_paging.filter)
                    .select(_paging.select)
                    .order(_paging.order)
                    .execute();
            });
    }
};
<|endoftext|>


<commit_before>import { isNil } from 'core/util';
import { addDomEvent, removeDomEvent, getEventContainerPoint, preventDefault, stopPropagation } from 'core/util/dom';
import Handler from 'handler/Handler';
import Map from '../Map';

class MapScrollWheelZoomHandler extends Handler {
    addHooks() {
        addDomEvent(this.target._containerDOM, 'mousewheel', this._onWheelScroll, this);
    }

    removeHooks() {
        removeDomEvent(this.target._containerDOM, 'mousewheel', this._onWheelScroll);
    }

    _onWheelScroll(evt) {
        preventDefault(evt);
        stopPropagation(evt);
        if (this._zooming) {
            this._requesting++;
            return false;
        }
        this._requesting = 0;
        const map = this.target;
        const container = map._containerDOM;
        this._zooming = true;
        let levelValue = (evt.wheelDelta ? evt.wheelDelta : evt.detail) > 0 ? 1 : -1;
        if (evt.detail) {
            levelValue *= -1;
        }
        let nextZoom = map.getZoom() + levelValue;
        nextZoom = map._checkZoom(levelValue > 0 ? Math.ceil(nextZoom) : Math.floor(nextZoom));
        const origin = map._checkZoomOrigin(getEventContainerPoint(evt, container));
        if (!map.isZooming()) {
            map.onZoomStart(null, origin);
            this._origin = origin;
            this._delta = levelValue;
            this._startZoom = map.getZoom();
        }
        const duration = 120;
        map.animateTo({
            'zoom' : nextZoom - this._delta * 1 / 2,
            'around' : this._origin
        }, {
            'easing' : 'linear',
            'duration' : duration,
            'wheelZoom' : true
        }, frame => {
            if (frame.state.playState !== 'finished') {
                return;
            }
            if (this._requesting === 0 || Math.abs(nextZoom - this._startZoom) > 3) {
                map.animateTo({
                    'zoom' : nextZoom,
                    'around' : this._origin
                }, {
                    'duration' : 160
                }, frame => {
                    if (frame.state.playState === 'finished') {
                        delete this._zooming;
                        delete this._requesting;
                    }
                });
                delete this._startZoom;
                delete this._origin;
                delete this._delta;
                this._requesting = 0;
            } else if (!isNil(this._requesting)) {
                delete this._zooming;
                this._onWheelScroll(evt);
            }
        });
        return false;
    }
}

Map.mergeOptions({
    'scrollWheelZoom': true
});

Map.addOnLoadHook('addHandler', 'scrollWheelZoom', MapScrollWheelZoomHandler);

export default MapScrollWheelZoomHandler;
<commit_msg>delay ending scollzoom to fix tilelayer's animation<commit_after>import { isNil } from 'core/util';
import { addDomEvent, removeDomEvent, getEventContainerPoint, preventDefault, stopPropagation } from 'core/util/dom';
import Handler from 'handler/Handler';
import Map from '../Map';

class MapScrollWheelZoomHandler extends Handler {
    addHooks() {
        addDomEvent(this.target._containerDOM, 'mousewheel', this._onWheelScroll, this);
    }

    removeHooks() {
        removeDomEvent(this.target._containerDOM, 'mousewheel', this._onWheelScroll);
    }

    _onWheelScroll(evt) {
        preventDefault(evt);
        stopPropagation(evt);
        if (this._zooming) {
            this._requesting++;
            return false;
        }
        this._requesting = 0;
        const map = this.target;
        const container = map._containerDOM;
        this._zooming = true;
        let levelValue = (evt.wheelDelta ? evt.wheelDelta : evt.detail) > 0 ? 1 : -1;
        if (evt.detail) {
            levelValue *= -1;
        }
        let nextZoom = map.getZoom() + levelValue;
        nextZoom = map._checkZoom(levelValue > 0 ? Math.ceil(nextZoom) : Math.floor(nextZoom));
        const origin = map._checkZoomOrigin(getEventContainerPoint(evt, container));
        if (!map.isZooming()) {
            map.onZoomStart(null, origin);
            this._origin = origin;
            this._delta = levelValue;
            this._startZoom = map.getZoom();
        }
        const duration = 120;
        map.animateTo({
            'zoom' : nextZoom - this._delta * 1 / 2,
            'around' : this._origin
        }, {
            'easing' : 'linear',
            'duration' : duration,
            'wheelZoom' : true
        }, frame => {
            if (frame.state.playState !== 'finished') {
                return;
            }
            if (this._requesting === 0 || Math.abs(nextZoom - this._startZoom) > 3) {
                map.animateTo({
                    'zoom' : nextZoom,
                    'around' : this._origin
                }, {
                    'duration' : 160
                }, frame => {
                    if (frame.state.playState === 'finished') {
                        setTimeout(() => {
                            delete this._zooming;
                            delete this._requesting;
                        }, 200);
                    }
                });
                delete this._startZoom;
                delete this._origin;
                delete this._delta;
                this._requesting = 0;
            } else if (!isNil(this._requesting)) {
                delete this._zooming;
                this._onWheelScroll(evt);
            }
        });
        return false;
    }
}

Map.mergeOptions({
    'scrollWheelZoom': true
});

Map.addOnLoadHook('addHandler', 'scrollWheelZoom', MapScrollWheelZoomHandler);

export default MapScrollWheelZoomHandler;
<|endoftext|>


<commit_before>import React from 'react';
import {connect} from 'react-redux';
import {Link} from 'react-router-dom'
import { Modal, Button } from 'react-bootstrap';
import Course from './Course';
import {getCourses, deleteCourse} from './adminActions';

const createRow = (row, deleteCallback) => {
    return (

            {
                row.map(course => {
                    return (

                            <Course key={course.meritBadge} course={course} deleteCallback={deleteCallback}/>

                    )
                })
            }

    );
};

const create2DArray = (numCols, list) => {
    const destArray = [];

    let row = 0;
    for(let sourceIndex=0; sourceIndex < list.length;){
        destArray[row] = [];
        for(let col=0; col < numCols && sourceIndex < list.length; col++){
            destArray[row][col] = list[sourceIndex++];
        }
        row++;
    }
    return destArray;
};

class Courses extends React.Component {

    constructor(){
        super();
        this.state = {
            selectedCourse: null,
            showDeleteConfirm: false
        };
        this.closeDeleteConfirm = this.closeDeleteConfirm.bind(this);
        this.openDeleteConfirm = this.openDeleteConfirm.bind(this);
        this.handleDeleteCourse = this.handleDeleteCourse.bind(this);
    };

    handleDeleteCourse(){
        deleteCourse(this.state.selectedCourse._id);
        this.closeDeleteConfirm();
    };

    closeDeleteConfirm(){
        this.setState({
            selectedCourse: null,
            showDeleteConfirm: false
        });
    };

    openDeleteConfirm(course){
        this.setState({
            selectedCourse: course,
            showDeleteConfirm: true
        });
    };

    componentDidMount() {
        getCourses();
    };

    render() {

        const courses = create2DArray(4, this.props.courses);

        const courseName = this.state.selectedCourse ? this.state.selectedCourse.meritBadge : '';

        return (

Courses

                        <Link to={`/admin/edit-course`}>
                            <button id="addNewCourse" type="button" className="btn btn-success btn-lg btn-block" aria-label="Left Align">
                                Add New
                            </button>
                        </Link>

                {
                    courses.map(course => createRow(course, this.openDeleteConfirm))
                }

                <Modal
                    show={this.state.showDeleteConfirm}
                    onHide={this.closeDeleteConfirm}
                    container={this}
                    aria-labelledby="contained-modal-title"
                >
                    <Modal.Header closeButton>
                        <Modal.Title id="contained-modal-title">Delete Course</Modal.Title>
                    </Modal.Header>
                    <Modal.Body>
                        Are you sure you want to delete {courseName}?
                    </Modal.Body>
                    <Modal.Footer>
                        <Button onClick={this.handleDeleteCourse}>Yes, Delete this course</Button>
                        <Button onClick={this.closeDeleteConfirm}>Cancel</Button>
                    </Modal.Footer>
                </Modal>

        );
    };
};

const mapStateToProps = ({admin}) => {
    return admin;
};

export default connect(mapStateToProps)(Courses);<commit_msg>- Courses Screen: add checkbox to view my classes only<commit_after>import _ from 'lodash';
import React from 'react';
import {connect} from 'react-redux';
import {Link} from 'react-router-dom'
import CheckBox from '../common/components/CheckBox';
import { Modal, Button } from 'react-bootstrap';
import Course from './Course';
import {getCourses, deleteCourse} from './adminActions';

const createRow = (row, deleteCallback) => {
    return (

            {
                row.map(course => {
                    return (

                            <Course key={course.meritBadge} course={course} deleteCallback={deleteCallback}/>

                    )
                })
            }

    );
};

const create2DArray = (numCols, list) => {
    const destArray = [];

    let row = 0;
    for(let sourceIndex=0; sourceIndex < list.length;){
        destArray[row] = [];
        for(let col=0; col < numCols && sourceIndex < list.length; col++){
            destArray[row][col] = list[sourceIndex++];
        }
        row++;
    }
    return destArray;
};

class Courses extends React.Component {

    constructor(){
        super();
        this.state = {
            selectedCourse: null,
            showDeleteConfirm: false,
            myCoursesOnly: false
        };
        this.closeDeleteConfirm = this.closeDeleteConfirm.bind(this);
        this.openDeleteConfirm = this.openDeleteConfirm.bind(this);
        this.handleDeleteCourse = this.handleDeleteCourse.bind(this);
        this.handleMyCoursesOnlyChange = this.handleMyCoursesOnlyChange.bind(this);
    };

    handleDeleteCourse(){
        deleteCourse(this.state.selectedCourse._id);
        this.closeDeleteConfirm();
    };

    handleMyCoursesOnlyChange(){
        this.setState({myCoursesOnly: !this.state.myCoursesOnly});
    }

    closeDeleteConfirm(){
        this.setState({
            selectedCourse: null,
            showDeleteConfirm: false
        });
    };

    openDeleteConfirm(course){
        this.setState({
            selectedCourse: course,
            showDeleteConfirm: true
        });
    };

    componentDidMount() {
        getCourses();
    };

    render() {

        const filteredCourses = this.state.myCoursesOnly
            ? _.filter(this.props.courses, (course) => {
                return course.counselors.includes('Jerry Moore');
            })
            : this.props.courses;

        const courseGrid = create2DArray(4, filteredCourses);

        const courseName = this.state.selectedCourse ? this.state.selectedCourse.meritBadge : '';

        return (

Courses

                        <Link to={`/admin/edit-course`}>
                            <button id="addNewCourse" type="button" className="btn btn-success btn-lg btn-block" aria-label="Left Align">
                                Add New
                            </button>
                        </Link>

                        <CheckBox propertyName='myCoursesOnly' propertyValue={this.state.myCoursesOnly}
                                  displayName='Show My Courses Only'
                                  changeHandler={this.handleMyCoursesOnlyChange}/>

                {
                    courseGrid.map(course => createRow(course, this.openDeleteConfirm))
                }

                <Modal
                    show={this.state.showDeleteConfirm}
                    onHide={this.closeDeleteConfirm}
                    container={this}
                    aria-labelledby="contained-modal-title"
                >
                    <Modal.Header closeButton>
                        <Modal.Title id="contained-modal-title">Delete Course</Modal.Title>
                    </Modal.Header>
                    <Modal.Body>
                        Are you sure you want to delete {courseName}?
                    </Modal.Body>
                    <Modal.Footer>
                        <Button onClick={this.handleDeleteCourse}>Yes, Delete this course</Button>
                        <Button onClick={this.closeDeleteConfirm}>Cancel</Button>
                    </Modal.Footer>
                </Modal>

        );
    };
};

const mapStateToProps = ({admin}) => {
    return admin;
};

export default connect(mapStateToProps)(Courses);<|endoftext|>


<commit_before>var Client = require('../rollbar');
var _ = require('../utility');
var API = require('../api');
var logger = require('./logger');
var globals = require('./globalSetup');

var transport = require('./transport');
var urllib = require('./url');

var transforms = require('./transforms');
var sharedTransforms = require('../transforms');
var predicates = require('./predicates');
var sharedPredicates = require('../predicates');
var errorParser = require('./errorParser');
var Instrumenter = require('./telemetry');

function Rollbar(options, client) {
  this.options = _.handleOptions(defaultOptions, options);
  this.options._configuredOptions = options;
  var api = new API(this.options, transport, urllib);
  this.client = client || new Client(this.options, api, logger, 'browser');

  var gWindow = _gWindow();
  var gDocument = (typeof document != 'undefined') && document;
  this.isChrome = gWindow.chrome && gWindow.chrome.runtime; // check .runtime to avoid Edge browsers
  this.anonymousErrorsPending = 0;
  addTransformsToNotifier(this.client.notifier, gWindow);
  addPredicatesToQueue(this.client.queue);
  this.setupUnhandledCapture();
  this.instrumenter = new Instrumenter(this.options, this.client.telemeter, this, gWindow, gDocument);
  this.instrumenter.instrument();
}

var _instance = null;
Rollbar.init = function(options, client) {
  if (_instance) {
    return _instance.global(options).configure(options);
  }
  _instance = new Rollbar(options, client);
  return _instance;
};

function handleUninitialized(maybeCallback) {
  var message = 'Rollbar is not initialized';
  logger.error(message);
  if (maybeCallback) {
    maybeCallback(new Error(message));
  }
}

Rollbar.prototype.global = function(options) {
  this.client.global(options);
  return this;
};
Rollbar.global = function(options) {
  if (_instance) {
    return _instance.global(options);
  } else {
    handleUninitialized();
  }
};

Rollbar.prototype.configure = function(options, payloadData) {
  var oldOptions = this.options;
  var payload = {};
  if (payloadData) {
    payload = {payload: payloadData};
  }
  this.options = _.handleOptions(oldOptions, options, payload);
  this.options._configuredOptions = _.handleOptions(oldOptions._configuredOptions, options, payload);
  this.client.configure(this.options, payloadData);
  this.instrumenter.configure(this.options);
  this.setupUnhandledCapture();
  return this;
};
Rollbar.configure = function(options, payloadData) {
  if (_instance) {
    return _instance.configure(options, payloadData);
  } else {
    handleUninitialized();
  }
};

Rollbar.prototype.lastError = function() {
  return this.client.lastError;
};
Rollbar.lastError = function() {
  if (_instance) {
    return _instance.lastError();
  } else {
    handleUninitialized();
  }
};

Rollbar.prototype.log = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.log(item);
  return {uuid: uuid};
};
Rollbar.log = function() {
  if (_instance) {
    return _instance.log.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.debug = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.debug(item);
  return {uuid: uuid};
};
Rollbar.debug = function() {
  if (_instance) {
    return _instance.debug.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.info = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.info(item);
  return {uuid: uuid};
};
Rollbar.info = function() {
  if (_instance) {
    return _instance.info.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.warn = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.warn(item);
  return {uuid: uuid};
};
Rollbar.warn = function() {
  if (_instance) {
    return _instance.warn.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.warning = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.warning(item);
  return {uuid: uuid};
};
Rollbar.warning = function() {
  if (_instance) {
    return _instance.warning.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.error = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.error(item);
  return {uuid: uuid};
};
Rollbar.error = function() {
  if (_instance) {
    return _instance.error.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.critical = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.critical(item);
  return {uuid: uuid};
};
Rollbar.critical = function() {
  if (_instance) {
    return _instance.critical.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.buildJsonPayload = function(item) {
  return this.client.buildJsonPayload(item);
};
Rollbar.buildJsonPayload = function() {
  if (_instance) {
    return _instance.buildJsonPayload.apply(_instance, arguments);
  } else {
    handleUninitialized();
  }
};

Rollbar.prototype.sendJsonPayload = function(jsonPayload) {
  return this.client.sendJsonPayload(jsonPayload);
};
Rollbar.sendJsonPayload = function() {
  if (_instance) {
    return _instance.sendJsonPayload.apply(_instance, arguments);
  } else {
    handleUninitialized();
  }
};

Rollbar.prototype.setupUnhandledCapture = function() {
  var gWindow = _gWindow();

  if (!this.unhandledExceptionsInitialized) {
    if (this.options.captureUncaught || this.options.handleUncaughtExceptions) {
      globals.captureUncaughtExceptions(gWindow, this);
      if (this.options.wrapGlobalEventHandlers) {
        globals.wrapGlobals(gWindow, this);
      }
      this.unhandledExceptionsInitialized = true;
    }
  }
  if (!this.unhandledRejectionsInitialized) {
    if (this.options.captureUnhandledRejections || this.options.handleUnhandledRejections) {
      globals.captureUnhandledRejections(gWindow, this);
      this.unhandledRejectionsInitialized = true;
    }
  }
};

Rollbar.prototype.handleUncaughtException = function(message, url, lineno, colno, error, context) {
  if (!this.options.captureUncaught && !this.options.handleUncaughtExceptions) {
    return;
  }

  // Chrome will always send 5+ arguments and error will be valid or null, not undefined.
  // If error is undefined, we have a different caller.
  if (this.options.inspectAnonymousErrors && this.isChrome && (error === null)) {
    return 'anonymous';
  }

  var item;
  var stackInfo = _.makeUnhandledStackInfo(
    message,
    url,
    lineno,
    colno,
    error,
    'onerror',
    'uncaught exception',
    errorParser
  );
  if (_.isError(error)) {
    item = this._createItem([message, error, context]);
    item._unhandledStackInfo = stackInfo;
  } else if (_.isError(url)) {
    item = this._createItem([message, url, context]);
    item._unhandledStackInfo = stackInfo;
  } else {
    item = this._createItem([message, context]);
    item.stackInfo = stackInfo;
  }
  item.level = this.options.uncaughtErrorLevel;
  item._isUncaught = true;
  this.client.log(item);
};

/**
 * Chrome only. Other browsers will ignore.
 *
 * Use Error.prepareStackTrace to extract information about errors that
 * do not have a valid error object in onerror().
 *
 * In tested version of Chrome, onerror is called first but has no way
 * to communicate with prepareStackTrace. Use a counter to let this
 * handler know which errors to send to Rollbar.
 *
 * In config options, set inspectAnonymousErrors to enable.
 */
Rollbar.prototype.handleAnonymousErrors = function() {
  if (!this.options.inspectAnonymousErrors || !this.isChrome) {
    return;
  }

  var r = this;
  function prepareStackTrace(error, _stack) { // eslint-disable-line no-unused-vars
    if (r.options.inspectAnonymousErrors) {
      if (r.anonymousErrorsPending) {
        // This is the only known way to detect that onerror saw an anonymous error.
        // It depends on onerror reliably being called before Error.prepareStackTrace,
        // which so far holds true on tested versions of Chrome. If versions of Chrome
        // are tested that behave differently, this logic will need to be updated
        // accordingly.
        r.anonymousErrorsPending -= 1;

        if (!error) {
          // Not likely to get here, but calling handleUncaughtException from here
          // without an error object would throw off the anonymousErrorsPending counter,
          // so return now.
          return;
        }

        // Allow this to be tracked later.
        error._isAnonymous = true;

        // url, lineno, colno shouldn't be needed for these errors.
        // If that changes, update this accordingly, using the unused
        // _stack param as needed (rather than parse error.toString()).
        r.handleUncaughtException(error.message, null, null, null, error);
      }
    }

    return error.toString();
  }

  // https://v8.dev/docs/stack-trace-api
  try {
    Error.prepareStackTrace = prepareStackTrace;
  } catch (e) {
    this.options.inspectAnonymousErrors = false;
    this.error('anonymous error handler failed', e);
  }
}

Rollbar.prototype.handleUnhandledRejection = function(reason, promise) {
  if (!this.options.captureUnhandledRejections && !this.options.handleUnhandledRejections) {
    return;
  }

  var message = 'unhandled rejection was null or undefined!';
  if (reason) {
    if (reason.message) {
      message = reason.message;
    } else {
      var reasonResult = _.stringify(reason);
      if (reasonResult.value) {
        message = reasonResult.value;
      }
    }
  }
  var context = (reason && reason._rollbarContext) || (promise && promise._rollbarContext);

  var item;
  if (_.isError(reason)) {
    item = this._createItem([message, reason, context]);
  } else {
    item = this._createItem([message, reason, context]);
    item.stackInfo = _.makeUnhandledStackInfo(
      message,
      '',
      0,
      0,
      null,
      'unhandledrejection',
      '',
      errorParser
    );
  }
  item.level = this.options.uncaughtErrorLevel;
  item._isUncaught = true;
  item._originalArgs = item._originalArgs || [];
  item._originalArgs.push(promise);
  this.client.log(item);
};

Rollbar.prototype.wrap = function(f, context, _before) {
  try {
    var ctxFn;
    if(_.isFunction(context)) {
      ctxFn = context;
    } else {
      ctxFn = function() { return context || {}; };
    }

    if (!_.isFunction(f)) {
      return f;
    }

    if (f._isWrap) {
      return f;
    }

    if (!f._rollbar_wrapped) {
      f._rollbar_wrapped = function () {
        if (_before && _.isFunction(_before)) {
          _before.apply(this, arguments);
        }
        try {
          return f.apply(this, arguments);
        } catch(exc) {
          var e = exc;
          if (e && window._rollbarWrappedError !== e) {
            if (_.isType(e, 'string')) {
              e = new String(e);
            }
            e._rollbarContext = ctxFn() || {};
            e._rollbarContext._wrappedSource = f.toString();

            window._rollbarWrappedError = e;
          }
          throw e;
        }
      };

      f._rollbar_wrapped._isWrap = true;

      if (f.hasOwnProperty) {
        for (var prop in f) {
          if (f.hasOwnProperty(prop) && prop !== '_rollbar_wrapped') {
            f._rollbar_wrapped[prop] = f[prop];
          }
        }
      }
    }

    return f._rollbar_wrapped;
  } catch (e) {
    // Return the original function if the wrap fails.
    return f;
  }
};
Rollbar.wrap = function(f, context) {
  if (_instance) {
    return _instance.wrap(f, context);
  } else {
    handleUninitialized();
  }
};

Rollbar.prototype.captureEvent = function() {
  var event = _.createTelemetryEvent(arguments);
  return this.client.captureEvent(event.type, event.metadata, event.level);
};
Rollbar.captureEvent = function() {
  if (_instance) {
    return _instance.captureEvent.apply(_instance, arguments);
  } else {
    handleUninitialized();
  }
};

// The following two methods are used internally and are not meant for public use
Rollbar.prototype.captureDomContentLoaded = function(e, ts) {
  if (!ts) {
    ts = new Date();
  }
  return this.client.captureDomContentLoaded(ts);
};

Rollbar.prototype.captureLoad = function(e, ts) {
  if (!ts) {
    ts = new Date();
  }
  return this.client.captureLoad(ts);
};

/* Internal */

function addTransformsToNotifier(notifier, gWindow) {
  notifier
    .addTransform(transforms.handleDomException)
    .addTransform(transforms.handleItemWithError)
    .addTransform(transforms.ensureItemHasSomethingToSay)
    .addTransform(transforms.addBaseInfo)
    .addTransform(transforms.addRequestInfo(gWindow))
    .addTransform(transforms.addClientInfo(gWindow))
    .addTransform(transforms.addPluginInfo(gWindow))
    .addTransform(transforms.addBody)
    .addTransform(sharedTransforms.addMessageWithError)
    .addTransform(sharedTransforms.addTelemetryData)
    .addTransform(sharedTransforms.addConfigToPayload)
    .addTransform(transforms.scrubPayload)
    .addTransform(sharedTransforms.userTransform(logger))
    .addTransform(sharedTransforms.addConfiguredOptions)
    .addTransform(sharedTransforms.addDiagnosticKeys)
    .addTransform(sharedTransforms.itemToPayload);
}

function addPredicatesToQueue(queue) {
  queue
    .addPredicate(sharedPredicates.checkLevel)
    .addPredicate(predicates.checkIgnore)
    .addPredicate(sharedPredicates.userCheckIgnore(logger))
    .addPredicate(sharedPredicates.urlIsNotBlacklisted(logger))
    .addPredicate(sharedPredicates.urlIsWhitelisted(logger))
    .addPredicate(sharedPredicates.messageIsIgnored(logger));
}

Rollbar.prototype._createItem = function(args) {
  return _.createItem(args, logger, this);
};

function _getFirstFunction(args) {
  for (var i = 0, len = args.length; i < len; ++i) {
    if (_.isFunction(args[i])) {
      return args[i];
    }
  }
  return undefined;
}

function _gWindow() {
  return ((typeof window != 'undefined') && window) || ((typeof self != 'undefined') && self);
}

/* global __NOTIFIER_VERSION__:false */
/* global __DEFAULT_BROWSER_SCRUB_FIELDS__:false */
/* global __DEFAULT_LOG_LEVEL__:false */
/* global __DEFAULT_REPORT_LEVEL__:false */
/* global __DEFAULT_UNCAUGHT_ERROR_LEVEL:false */
/* global __DEFAULT_ENDPOINT__:false */

var defaultOptions = {
  version: __NOTIFIER_VERSION__,
  scrubFields: __DEFAULT_BROWSER_SCRUB_FIELDS__,
  logLevel: __DEFAULT_LOG_LEVEL__,
  reportLevel: __DEFAULT_REPORT_LEVEL__,
  uncaughtErrorLevel: __DEFAULT_UNCAUGHT_ERROR_LEVEL,
  endpoint: __DEFAULT_ENDPOINT__,
  verbose: false,
  enabled: true,
  transmit: true,
  sendConfig: false,
  includeItemsInTelemetry: true,
  captureIp: true,
  inspectAnonymousErrors: true,
  ignoreDuplicateErrors: true,
  wrapGlobalEventHandlers: false
};

module.exports = Rollbar;
<commit_msg>fix: ensure stack is preserved on chrome<commit_after>var Client = require('../rollbar');
var _ = require('../utility');
var API = require('../api');
var logger = require('./logger');
var globals = require('./globalSetup');

var transport = require('./transport');
var urllib = require('./url');

var transforms = require('./transforms');
var sharedTransforms = require('../transforms');
var predicates = require('./predicates');
var sharedPredicates = require('../predicates');
var errorParser = require('./errorParser');
var Instrumenter = require('./telemetry');

function Rollbar(options, client) {
  this.options = _.handleOptions(defaultOptions, options);
  this.options._configuredOptions = options;
  var api = new API(this.options, transport, urllib);
  this.client = client || new Client(this.options, api, logger, 'browser');

  var gWindow = _gWindow();
  var gDocument = (typeof document != 'undefined') && document;
  this.isChrome = gWindow.chrome && gWindow.chrome.runtime; // check .runtime to avoid Edge browsers
  this.anonymousErrorsPending = 0;
  addTransformsToNotifier(this.client.notifier, gWindow);
  addPredicatesToQueue(this.client.queue);
  this.setupUnhandledCapture();
  this.instrumenter = new Instrumenter(this.options, this.client.telemeter, this, gWindow, gDocument);
  this.instrumenter.instrument();
}

var _instance = null;
Rollbar.init = function(options, client) {
  if (_instance) {
    return _instance.global(options).configure(options);
  }
  _instance = new Rollbar(options, client);
  return _instance;
};

function handleUninitialized(maybeCallback) {
  var message = 'Rollbar is not initialized';
  logger.error(message);
  if (maybeCallback) {
    maybeCallback(new Error(message));
  }
}

Rollbar.prototype.global = function(options) {
  this.client.global(options);
  return this;
};
Rollbar.global = function(options) {
  if (_instance) {
    return _instance.global(options);
  } else {
    handleUninitialized();
  }
};

Rollbar.prototype.configure = function(options, payloadData) {
  var oldOptions = this.options;
  var payload = {};
  if (payloadData) {
    payload = {payload: payloadData};
  }
  this.options = _.handleOptions(oldOptions, options, payload);
  this.options._configuredOptions = _.handleOptions(oldOptions._configuredOptions, options, payload);
  this.client.configure(this.options, payloadData);
  this.instrumenter.configure(this.options);
  this.setupUnhandledCapture();
  return this;
};
Rollbar.configure = function(options, payloadData) {
  if (_instance) {
    return _instance.configure(options, payloadData);
  } else {
    handleUninitialized();
  }
};

Rollbar.prototype.lastError = function() {
  return this.client.lastError;
};
Rollbar.lastError = function() {
  if (_instance) {
    return _instance.lastError();
  } else {
    handleUninitialized();
  }
};

Rollbar.prototype.log = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.log(item);
  return {uuid: uuid};
};
Rollbar.log = function() {
  if (_instance) {
    return _instance.log.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.debug = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.debug(item);
  return {uuid: uuid};
};
Rollbar.debug = function() {
  if (_instance) {
    return _instance.debug.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.info = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.info(item);
  return {uuid: uuid};
};
Rollbar.info = function() {
  if (_instance) {
    return _instance.info.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.warn = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.warn(item);
  return {uuid: uuid};
};
Rollbar.warn = function() {
  if (_instance) {
    return _instance.warn.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.warning = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.warning(item);
  return {uuid: uuid};
};
Rollbar.warning = function() {
  if (_instance) {
    return _instance.warning.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.error = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.error(item);
  return {uuid: uuid};
};
Rollbar.error = function() {
  if (_instance) {
    return _instance.error.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.critical = function() {
  var item = this._createItem(arguments);
  var uuid = item.uuid;
  this.client.critical(item);
  return {uuid: uuid};
};
Rollbar.critical = function() {
  if (_instance) {
    return _instance.critical.apply(_instance, arguments);
  } else {
    var maybeCallback = _getFirstFunction(arguments);
    handleUninitialized(maybeCallback);
  }
};

Rollbar.prototype.buildJsonPayload = function(item) {
  return this.client.buildJsonPayload(item);
};
Rollbar.buildJsonPayload = function() {
  if (_instance) {
    return _instance.buildJsonPayload.apply(_instance, arguments);
  } else {
    handleUninitialized();
  }
};

Rollbar.prototype.sendJsonPayload = function(jsonPayload) {
  return this.client.sendJsonPayload(jsonPayload);
};
Rollbar.sendJsonPayload = function() {
  if (_instance) {
    return _instance.sendJsonPayload.apply(_instance, arguments);
  } else {
    handleUninitialized();
  }
};

Rollbar.prototype.setupUnhandledCapture = function() {
  var gWindow = _gWindow();

  if (!this.unhandledExceptionsInitialized) {
    if (this.options.captureUncaught || this.options.handleUncaughtExceptions) {
      globals.captureUncaughtExceptions(gWindow, this);
      if (this.options.wrapGlobalEventHandlers) {
        globals.wrapGlobals(gWindow, this);
      }
      this.unhandledExceptionsInitialized = true;
    }
  }
  if (!this.unhandledRejectionsInitialized) {
    if (this.options.captureUnhandledRejections || this.options.handleUnhandledRejections) {
      globals.captureUnhandledRejections(gWindow, this);
      this.unhandledRejectionsInitialized = true;
    }
  }
};

Rollbar.prototype.handleUncaughtException = function(message, url, lineno, colno, error, context) {
  if (!this.options.captureUncaught && !this.options.handleUncaughtExceptions) {
    return;
  }

  // Chrome will always send 5+ arguments and error will be valid or null, not undefined.
  // If error is undefined, we have a different caller.
  if (this.options.inspectAnonymousErrors && this.isChrome && (error === null)) {
    return 'anonymous';
  }

  var item;
  var stackInfo = _.makeUnhandledStackInfo(
    message,
    url,
    lineno,
    colno,
    error,
    'onerror',
    'uncaught exception',
    errorParser
  );
  if (_.isError(error)) {
    item = this._createItem([message, error, context]);
    item._unhandledStackInfo = stackInfo;
  } else if (_.isError(url)) {
    item = this._createItem([message, url, context]);
    item._unhandledStackInfo = stackInfo;
  } else {
    item = this._createItem([message, context]);
    item.stackInfo = stackInfo;
  }
  item.level = this.options.uncaughtErrorLevel;
  item._isUncaught = true;
  this.client.log(item);
};

/**
 * Chrome only. Other browsers will ignore.
 *
 * Use Error.prepareStackTrace to extract information about errors that
 * do not have a valid error object in onerror().
 *
 * In tested version of Chrome, onerror is called first but has no way
 * to communicate with prepareStackTrace. Use a counter to let this
 * handler know which errors to send to Rollbar.
 *
 * In config options, set inspectAnonymousErrors to enable.
 */
Rollbar.prototype.handleAnonymousErrors = function() {
  if (!this.options.inspectAnonymousErrors || !this.isChrome) {
    return;
  }

  var r = this;
  function prepareStackTrace(error, _stack) { // eslint-disable-line no-unused-vars
    if (r.options.inspectAnonymousErrors) {
      if (r.anonymousErrorsPending) {
        // This is the only known way to detect that onerror saw an anonymous error.
        // It depends on onerror reliably being called before Error.prepareStackTrace,
        // which so far holds true on tested versions of Chrome. If versions of Chrome
        // are tested that behave differently, this logic will need to be updated
        // accordingly.
        r.anonymousErrorsPending -= 1;

        if (!error) {
          // Not likely to get here, but calling handleUncaughtException from here
          // without an error object would throw off the anonymousErrorsPending counter,
          // so return now.
          return;
        }

        // Allow this to be tracked later.
        error._isAnonymous = true;

        // url, lineno, colno shouldn't be needed for these errors.
        // If that changes, update this accordingly, using the unused
        // _stack param as needed (rather than parse error.toString()).
        r.handleUncaughtException(error.message, null, null, null, error);
      }
    }

    // Workaround to ensure stack is preserved for normal errors.
    error.stack;

    return error.toString();
  }

  // https://v8.dev/docs/stack-trace-api
  try {
    Error.prepareStackTrace = prepareStackTrace;
  } catch (e) {
    this.options.inspectAnonymousErrors = false;
    this.error('anonymous error handler failed', e);
  }
}

Rollbar.prototype.handleUnhandledRejection = function(reason, promise) {
  if (!this.options.captureUnhandledRejections && !this.options.handleUnhandledRejections) {
    return;
  }

  var message = 'unhandled rejection was null or undefined!';
  if (reason) {
    if (reason.message) {
      message = reason.message;
    } else {
      var reasonResult = _.stringify(reason);
      if (reasonResult.value) {
        message = reasonResult.value;
      }
    }
  }
  var context = (reason && reason._rollbarContext) || (promise && promise._rollbarContext);

  var item;
  if (_.isError(reason)) {
    item = this._createItem([message, reason, context]);
  } else {
    item = this._createItem([message, reason, context]);
    item.stackInfo = _.makeUnhandledStackInfo(
      message,
      '',
      0,
      0,
      null,
      'unhandledrejection',
      '',
      errorParser
    );
  }
  item.level = this.options.uncaughtErrorLevel;
  item._isUncaught = true;
  item._originalArgs = item._originalArgs || [];
  item._originalArgs.push(promise);
  this.client.log(item);
};

Rollbar.prototype.wrap = function(f, context, _before) {
  try {
    var ctxFn;
    if(_.isFunction(context)) {
      ctxFn = context;
    } else {
      ctxFn = function() { return context || {}; };
    }

    if (!_.isFunction(f)) {
      return f;
    }

    if (f._isWrap) {
      return f;
    }

    if (!f._rollbar_wrapped) {
      f._rollbar_wrapped = function () {
        if (_before && _.isFunction(_before)) {
          _before.apply(this, arguments);
        }
        try {
          return f.apply(this, arguments);
        } catch(exc) {
          var e = exc;
          if (e && window._rollbarWrappedError !== e) {
            if (_.isType(e, 'string')) {
              e = new String(e);
            }
            e._rollbarContext = ctxFn() || {};
            e._rollbarContext._wrappedSource = f.toString();

            window._rollbarWrappedError = e;
          }
          throw e;
        }
      };

      f._rollbar_wrapped._isWrap = true;

      if (f.hasOwnProperty) {
        for (var prop in f) {
          if (f.hasOwnProperty(prop) && prop !== '_rollbar_wrapped') {
            f._rollbar_wrapped[prop] = f[prop];
          }
        }
      }
    }

    return f._rollbar_wrapped;
  } catch (e) {
    // Return the original function if the wrap fails.
    return f;
  }
};
Rollbar.wrap = function(f, context) {
  if (_instance) {
    return _instance.wrap(f, context);
  } else {
    handleUninitialized();
  }
};

Rollbar.prototype.captureEvent = function() {
  var event = _.createTelemetryEvent(arguments);
  return this.client.captureEvent(event.type, event.metadata, event.level);
};
Rollbar.captureEvent = function() {
  if (_instance) {
    return _instance.captureEvent.apply(_instance, arguments);
  } else {
    handleUninitialized();
  }
};

// The following two methods are used internally and are not meant for public use
Rollbar.prototype.captureDomContentLoaded = function(e, ts) {
  if (!ts) {
    ts = new Date();
  }
  return this.client.captureDomContentLoaded(ts);
};

Rollbar.prototype.captureLoad = function(e, ts) {
  if (!ts) {
    ts = new Date();
  }
  return this.client.captureLoad(ts);
};

/* Internal */

function addTransformsToNotifier(notifier, gWindow) {
  notifier
    .addTransform(transforms.handleDomException)
    .addTransform(transforms.handleItemWithError)
    .addTransform(transforms.ensureItemHasSomethingToSay)
    .addTransform(transforms.addBaseInfo)
    .addTransform(transforms.addRequestInfo(gWindow))
    .addTransform(transforms.addClientInfo(gWindow))
    .addTransform(transforms.addPluginInfo(gWindow))
    .addTransform(transforms.addBody)
    .addTransform(sharedTransforms.addMessageWithError)
    .addTransform(sharedTransforms.addTelemetryData)
    .addTransform(sharedTransforms.addConfigToPayload)
    .addTransform(transforms.scrubPayload)
    .addTransform(sharedTransforms.userTransform(logger))
    .addTransform(sharedTransforms.addConfiguredOptions)
    .addTransform(sharedTransforms.addDiagnosticKeys)
    .addTransform(sharedTransforms.itemToPayload);
}

function addPredicatesToQueue(queue) {
  queue
    .addPredicate(sharedPredicates.checkLevel)
    .addPredicate(predicates.checkIgnore)
    .addPredicate(sharedPredicates.userCheckIgnore(logger))
    .addPredicate(sharedPredicates.urlIsNotBlacklisted(logger))
    .addPredicate(sharedPredicates.urlIsWhitelisted(logger))
    .addPredicate(sharedPredicates.messageIsIgnored(logger));
}

Rollbar.prototype._createItem = function(args) {
  return _.createItem(args, logger, this);
};

function _getFirstFunction(args) {
  for (var i = 0, len = args.length; i < len; ++i) {
    if (_.isFunction(args[i])) {
      return args[i];
    }
  }
  return undefined;
}

function _gWindow() {
  return ((typeof window != 'undefined') && window) || ((typeof self != 'undefined') && self);
}

/* global __NOTIFIER_VERSION__:false */
/* global __DEFAULT_BROWSER_SCRUB_FIELDS__:false */
/* global __DEFAULT_LOG_LEVEL__:false */
/* global __DEFAULT_REPORT_LEVEL__:false */
/* global __DEFAULT_UNCAUGHT_ERROR_LEVEL:false */
/* global __DEFAULT_ENDPOINT__:false */

var defaultOptions = {
  version: __NOTIFIER_VERSION__,
  scrubFields: __DEFAULT_BROWSER_SCRUB_FIELDS__,
  logLevel: __DEFAULT_LOG_LEVEL__,
  reportLevel: __DEFAULT_REPORT_LEVEL__,
  uncaughtErrorLevel: __DEFAULT_UNCAUGHT_ERROR_LEVEL,
  endpoint: __DEFAULT_ENDPOINT__,
  verbose: false,
  enabled: true,
  transmit: true,
  sendConfig: false,
  includeItemsInTelemetry: true,
  captureIp: true,
  inspectAnonymousErrors: true,
  ignoreDuplicateErrors: true,
  wrapGlobalEventHandlers: false
};

module.exports = Rollbar;
<|endoftext|>


<commit_before>

define(['q'], function(Q) {
    'use strict';
    return {
	// create all model nodes and their attributes
	// update all pointers and sets
	importModel: function(core, META, model, rootNode) {
	    var self = this;
	    self.core = core;
	    self.META = META;
	    self.model = model;
	    self.rootNode = rootNode;

	    self.createdObjects = {}; // map of path to WebGME Nodes

	    var modelObjectPaths = Object.keys(self.model.objects);
	    modelObjectPaths.map((modelObjectPath) => {
		self.createObject(modelObjectPath);
	    });
	    return true;
	},
	createObject: function(objectPath) {
	    var self = this;
	    var newNode = null;
	    var object = self.model.objects[objectPath];
            if (object == null) {
                self.logger.error('object is null: ' + objectPath);
            }
            else {
	        var metaNode = self.META[object.type];
                self.logger.error('creating new object: ' + object.name);
                self.logger.error('\tof meta type: ' + object.type + ': '+metaNode);
	        var parentNode = self.createdObjects[object.parentPath];
                // don't want to create the same object multiple times
	        if (self.createdObjects[objectPath] == undefined) {
		    if (self.createdObjects[object.parentPath] == undefined) {
		        // create parent
		        parentNode = self.createObject(object.parentPath);
		    }
                    if (parentNode == null) {
                        parentNode = self.rootNode;
                        self.createdObjects[object.parentPath] = parentNode;
                    }
		    // create object
		    newNode = self.core.createNode({
		        parent: parentNode,
		        base: metaNode
		    });
		    // configure attributes
		    var attributes = Object.keys(object.attributes);
		    attributes.map((attr) => {
		        self.core.setAttribute(newNode, attr, object[attr]);
		    });

		    // add path of object to created objects list
		    self.createdObjects[objectPath] = newNode;
	        }
	        else {
		    newNode = self.createdObjects[objectPath];
	        }
            }
	    return newNode;
	}
    }
});
<commit_msg>working model importer; supports sets and poitners.<commit_after>

define(['q'], function(Q) {
    'use strict';
    return {
	// create all model nodes and their attributes
	// update all pointers and sets
	importModel: function(core, META, model, rootNode) {
	    var self = this;
	    self.core = core;
	    self.META = META;
	    self.model = model;
	    self.rootNode = rootNode;

	    self.createdObjects = {}; // map of path to WebGME Nodes

	    var objectPaths = Object.keys(self.model.objects);
            // create the objects
	    objectPaths.map((objectPath) => {
		self.createObject(objectPath);
	    });
            // resolve references
            objectPaths.map((objectPath) => {
                var object = self.model.objects[objectPath];
                var objNode = self.createdObjects[objectPath];
                if (!objNode)
                    return; // couldn't create this object; can't resolve it's internal data
                // resolve pointers
                var pointerNames = Object.keys(object.pointers);
                pointerNames.map((pointerName) => {
                    if (pointerName == 'base')
                        return;
                    var dstPath = object.pointers[pointerName];
                    var dstNode = self.createdObjects[dstPath];
                    if (!dstNode) {
                        self.logger.error('Couldnt recreate reference for pointer: ' + pointerName);
                    }
                    else {
                        self.core.setPointer(objNode, pointerName, dstNode);
                    }
                });
                // resolve sets
                var setNames = Object.keys(object.sets);
                setNames.map((setName) => {
                    var paths = object.sets[setName];
                    paths.map((path) => {
                        var dstNode = self.createdObjects[path];
                        if (!dstNode) {
                            self.logger.error('Couldnt recreate reference for set: ' + setName);
                        }
                        else {
                            self.core.addMember(objNode, setName, dstNode);
                        }
                    });
                });
            });
	    return true;
	},
	createObject: function(objectPath) {
	    var self = this;
	    var newNode = null;
	    var object = self.model.objects[objectPath];
            if (object == null) {
                self.logger.error('object is null: ' + objectPath);
            }
            else {
	        var metaNode = self.META[object.type];
                //self.logger.info('creating new '+object.type+': ' + object.name);
	        var parentNode = self.createdObjects[object.parentPath];
                // don't want to create the same object multiple times
	        if (self.createdObjects[objectPath] == undefined) {
		    if (self.createdObjects[object.parentPath] == undefined) {
		        // create parent
		        parentNode = self.createObject(object.parentPath);
		    }
                    if (parentNode == null) {
                        parentNode = self.rootNode;
                        self.createdObjects[object.parentPath] = parentNode;
                    }
		    // create object
		    newNode = self.core.createNode({
		        parent: parentNode,
		        base: metaNode
		    });
		    // configure attributes
		    var attributes = Object.keys(object.attributes);
		    attributes.map((attr) => {
		        self.core.setAttribute(newNode, attr, object[attr]);
		    });
		    // add path of object to created objects list
		    self.createdObjects[objectPath] = newNode;
	        }
	        else {
		    newNode = self.createdObjects[objectPath];
	        }
            }
	    return newNode;
	}
    }
});
<|endoftext|>


<commit_before>/* ======= Instance Methods ======= */

var hasConsole = typeof window.console !== undefined;

/**
* Logs a Message
* @param {String} msg
*/
Moon.prototype.log = function(msg) {
  if(!config.silent && hasConsole) console.log(msg);
}

/**
* Throws an Error
* @param {String} msg
*/
Moon.prototype.error = function(msg) {
  if(hasConsole) console.error("[Moon] ERR: " + msg);
}

/**
* Gets Value in Data
* @param {String} key
* @return {String} Value of key in data
*/
Moon.prototype.get = function(key) {
  return this.$data[key];
}

/**
* Sets Value in Data
* @param {String} key
* @param {String} val
*/
Moon.prototype.set = function(key, val) {
  this.$data[key] = val;
  if(!this.$destroyed) this.build(this.$dom.children);
  this.$hooks.updated();
}

/**
* Calls a method
* @param {String} method
*/
Moon.prototype.callMethod = function(method, args) {
  args = args || [];
  this.$methods[method].apply(this, args);
}

// Event Emitter, adapted from https://github.com/KingPixil/voke

/**
* Attaches an Event Listener
* @param {String} eventName
* @param {Function} action
*/
Moon.prototype.on = function(eventName, action) {
  if(this.$events[eventName]) {
    this.$events[eventName].push(action);
  } else {
    this.$events[eventName] = [action];
  }
}

/**
* Removes an Event Listener
* @param {String} eventName
* @param {Function} action
*/
Moon.prototype.off = function(eventName, action) {
  var index = this.$events[eventName].indexOf(action);
  if(index !== -1) {
    this.$events[eventName].splice(index, 1);
  }
}

/**
* Removes All Event Listeners
* @param {String} eventName
* @param {Function} action
*/
Moon.prototype.removeEvents = function() {
  for(var evt in this.$events) {
    this.$events[evt] = [];
  }
}

/**
* Emits an Event
* @param {String} eventName
* @param {Object} meta
*/
Moon.prototype.emit = function(eventName, meta) {
  meta = meta || {};
  meta.type = eventName;

  if(this.$events["*"]) {
    for(var i = 0; i < this.$events["*"].length; i++) {
      var globalHandler = this.$events["*"][i];
      globalHandler(meta);
    }
  }

  for(var i = 0; i < this.$events[eventName].length; i++) {
    var handler = this.$events[eventName][i];
    handler(meta);
  }
}

/**
* Mounts Moon Element
* @param {Node} el
*/
Moon.prototype.mount = function(el) {
  this.$el = document.querySelector(el);

  if(!this.$el) {
    this.error("Element " + this.$opts.el + " not found");
  }

  this.$template = this.$opts.template || this.$el.innerHTML;

  setInitialElementValue(this.$el, this.$template);

  if(this.$opts.render) {
    this.$dom = this.$opts.render(h);
  } else {
    this.$dom = createVirtualDOM(this.$el);
  }

  this.build(this.$dom);
  this.$hooks.mounted();
}

/**
* Renders Virtual DOM
* @return Virtual DOM
*/
Moon.prototype.render = function() {
  if(this.$opts.render) {
    return this.$opts.render(h);
  } else {
    return renderVirtualDOM(this.$dom.children, this.$data);
  }
}

/**
* Destroys Moon Instance
*/
Moon.prototype.destroy = function() {
  Object.defineProperty(this, '$data', {
    set: function(value) {
      _data = value;
    }
  });
  this.removeEvents();
  this.$destroyed = true;
  this.$hooks.destroyed();
}

/**
* Render and Builds the DOM With Data
* @param {Array} vdom
*/
Moon.prototype.build = function(vdom) {
  this.render();
  this.buildNodes(vdom);
}

/**
* Builds Nodes With Data
* @param {Array} vdom
*/
Moon.prototype.buildNodes = function(vdom) {
  for(var i = 0; i < vdom.length; i++) {
    var vnode = vdom[i];
    if(vnode.meta.shouldRender) {
      if(vnode.type === "#text") {
        var valueOfVNode = "";
        valueOfVNode = vnode.val(this.$data);
        if(vnode.node.textContent === valueOfVNode) {
          vnode.meta.shouldRender = false;
        }
        vnode.node.textContent = valueOfVNode;
      } else if(vnode.props) {
        for(var attr in vnode.props) {
          var compiledProp = vnode.props[attr](this.$data);
          if(directives[attr]) {
            vnode.node.removeAttribute(attr);
            directives[attr](vnode.node, compiledProp, vnode);
          } else {
            vnode.node.setAttribute(attr, compiledProp);
          }
        }
      }

      this.buildNodes(vnode.children);
    }
  }
}

/**
* Initializes Moon
*/
Moon.prototype.init = function() {
  this.log("======= Moon =======");
  this.$hooks.created();

  if(this.$opts.el) {
    this.mount(this.$opts.el);
  }
}
<commit_msg>build on $dom<commit_after>/* ======= Instance Methods ======= */

var hasConsole = typeof window.console !== undefined;

/**
* Logs a Message
* @param {String} msg
*/
Moon.prototype.log = function(msg) {
  if(!config.silent && hasConsole) console.log(msg);
}

/**
* Throws an Error
* @param {String} msg
*/
Moon.prototype.error = function(msg) {
  if(hasConsole) console.error("[Moon] ERR: " + msg);
}

/**
* Gets Value in Data
* @param {String} key
* @return {String} Value of key in data
*/
Moon.prototype.get = function(key) {
  return this.$data[key];
}

/**
* Sets Value in Data
* @param {String} key
* @param {String} val
*/
Moon.prototype.set = function(key, val) {
  this.$data[key] = val;
  if(!this.$destroyed) this.build(this.$dom);
  this.$hooks.updated();
}

/**
* Calls a method
* @param {String} method
*/
Moon.prototype.callMethod = function(method, args) {
  args = args || [];
  this.$methods[method].apply(this, args);
}

// Event Emitter, adapted from https://github.com/KingPixil/voke

/**
* Attaches an Event Listener
* @param {String} eventName
* @param {Function} action
*/
Moon.prototype.on = function(eventName, action) {
  if(this.$events[eventName]) {
    this.$events[eventName].push(action);
  } else {
    this.$events[eventName] = [action];
  }
}

/**
* Removes an Event Listener
* @param {String} eventName
* @param {Function} action
*/
Moon.prototype.off = function(eventName, action) {
  var index = this.$events[eventName].indexOf(action);
  if(index !== -1) {
    this.$events[eventName].splice(index, 1);
  }
}

/**
* Removes All Event Listeners
* @param {String} eventName
* @param {Function} action
*/
Moon.prototype.removeEvents = function() {
  for(var evt in this.$events) {
    this.$events[evt] = [];
  }
}

/**
* Emits an Event
* @param {String} eventName
* @param {Object} meta
*/
Moon.prototype.emit = function(eventName, meta) {
  meta = meta || {};
  meta.type = eventName;

  if(this.$events["*"]) {
    for(var i = 0; i < this.$events["*"].length; i++) {
      var globalHandler = this.$events["*"][i];
      globalHandler(meta);
    }
  }

  for(var i = 0; i < this.$events[eventName].length; i++) {
    var handler = this.$events[eventName][i];
    handler(meta);
  }
}

/**
* Mounts Moon Element
* @param {Node} el
*/
Moon.prototype.mount = function(el) {
  this.$el = document.querySelector(el);

  if(!this.$el) {
    this.error("Element " + this.$opts.el + " not found");
  }

  this.$template = this.$opts.template || this.$el.innerHTML;

  setInitialElementValue(this.$el, this.$template);

  if(this.$opts.render) {
    this.$dom = this.$opts.render(h);
  } else {
    this.$dom = createVirtualDOM(this.$el);
  }

  this.build(this.$dom);
  this.$hooks.mounted();
}

/**
* Renders Virtual DOM
* @return Virtual DOM
*/
Moon.prototype.render = function() {
  if(this.$opts.render) {
    return this.$opts.render(h);
  } else {
    return renderVirtualDOM(this.$dom.children, this.$data);
  }
}

/**
* Destroys Moon Instance
*/
Moon.prototype.destroy = function() {
  Object.defineProperty(this, '$data', {
    set: function(value) {
      _data = value;
    }
  });
  this.removeEvents();
  this.$destroyed = true;
  this.$hooks.destroyed();
}

/**
* Render and Builds the DOM With Data
* @param {Array} vdom
*/
Moon.prototype.build = function(vdom) {
  this.render();
  this.buildNodes(vdom);
}

/**
* Builds Nodes With Data
* @param {Array} vdom
*/
Moon.prototype.buildNodes = function(vdom) {
  for(var i = 0; i < vdom.length; i++) {
    var vnode = vdom[i];
    if(vnode.meta.shouldRender) {
      if(vnode.type === "#text") {
        var valueOfVNode = "";
        valueOfVNode = vnode.val(this.$data);
        if(vnode.node.textContent === valueOfVNode) {
          vnode.meta.shouldRender = false;
        }
        vnode.node.textContent = valueOfVNode;
      } else if(vnode.props) {
        for(var attr in vnode.props) {
          var compiledProp = vnode.props[attr](this.$data);
          if(directives[attr]) {
            vnode.node.removeAttribute(attr);
            directives[attr](vnode.node, compiledProp, vnode);
          } else {
            vnode.node.setAttribute(attr, compiledProp);
          }
        }
      }

      this.buildNodes(vnode.children);
    }
  }
}

/**
* Initializes Moon
*/
Moon.prototype.init = function() {
  this.log("======= Moon =======");
  this.$hooks.created();

  if(this.$opts.el) {
    this.mount(this.$opts.el);
  }
}
<|endoftext|>


<commit_before>/* ======= Instance Methods ======= */

var hasConsole = typeof window.console !== undefined;

/**
* Logs a Message
* @param {String} msg
*/
Moon.prototype.log = function(msg) {
  if(!config.silent && hasConsole) console.log(msg);
}

/**
* Throws an Error
* @param {String} msg
*/
Moon.prototype.error = function(msg) {
  if(hasConsole) console.error("[Moon] ERR: " + msg);
}

/**
* Sets Value in Data
* @param {String} key
* @param {String} val
*/
Moon.prototype.set = function(key, val) {
  this.$data[key] = val;
  if(!this.$destroyed) this.build(this.$dom.children);
  this.$hooks.updated();
}

/**
* Gets Value in Data
* @param {String} key
* @return {String} Value of key in data
*/
Moon.prototype.get = function(key) {
  return this.$data[key];
}

/**
* Calls a method
* @param {String} method
*/
Moon.prototype.callMethod = function(method, args) {
  args = args || [];
  this.$methods[method].apply(this, args);
}

/**
* Destroys Moon Instance
*/
Moon.prototype.destroy = function() {
  Object.defineProperty(this, '$data', {
    set: function(value) {
      _data = value;
    }
  });
  this.$destroyed = true;
  this.$hooks.destroyed();
}

/**
* Builds the DOM With Data
* @param {Array} children
*/
Moon.prototype.build = function(vdom) {
  for(var i = 0; i < vdom.length; i++) {
    var vnode = vdom[i];
    if(vnode.shouldRender && !vnode.once) {
      if(vnode.type === "#text") {
        var valueOfVNode = "";
        valueOfVNode = vnode.val(this.$data);
        vnode.node.textContent = valueOfVNode;
      } else if(vnode.props) {
        for(var attr in vnode.props) {
          var compiledProp = vnode.props[attr](this.$data);
          if(directives[attr]) {
            vnode.node.removeAttribute(attr);
            directives[attr](vnode.node, compiledProp, vnode);
          } else {
            vnode.node.setAttribute(attr, compiledProp);
          }
        }
      }

      this.build(vnode.children);
    }
  }
}

/**
* Initializes Moon
*/
Moon.prototype.init = function() {
  this.log("======= Moon =======");
  this.$hooks.created();

  setInitialElementValue(this.$el, this.$template);

  this.$dom = createVirtualDOM(this.$el);

  this.build(this.$dom.children);
  this.$hooks.mounted();
}
<commit_msg>use meta once<commit_after>/* ======= Instance Methods ======= */

var hasConsole = typeof window.console !== undefined;

/**
* Logs a Message
* @param {String} msg
*/
Moon.prototype.log = function(msg) {
  if(!config.silent && hasConsole) console.log(msg);
}

/**
* Throws an Error
* @param {String} msg
*/
Moon.prototype.error = function(msg) {
  if(hasConsole) console.error("[Moon] ERR: " + msg);
}

/**
* Sets Value in Data
* @param {String} key
* @param {String} val
*/
Moon.prototype.set = function(key, val) {
  this.$data[key] = val;
  if(!this.$destroyed) this.build(this.$dom.children);
  this.$hooks.updated();
}

/**
* Gets Value in Data
* @param {String} key
* @return {String} Value of key in data
*/
Moon.prototype.get = function(key) {
  return this.$data[key];
}

/**
* Calls a method
* @param {String} method
*/
Moon.prototype.callMethod = function(method, args) {
  args = args || [];
  this.$methods[method].apply(this, args);
}

/**
* Destroys Moon Instance
*/
Moon.prototype.destroy = function() {
  Object.defineProperty(this, '$data', {
    set: function(value) {
      _data = value;
    }
  });
  this.$destroyed = true;
  this.$hooks.destroyed();
}

/**
* Builds the DOM With Data
* @param {Array} children
*/
Moon.prototype.build = function(vdom) {
  for(var i = 0; i < vdom.length; i++) {
    var vnode = vdom[i];
    if(vnode.shouldRender && !vnode.meta.once) {
      if(vnode.type === "#text") {
        var valueOfVNode = "";
        valueOfVNode = vnode.val(this.$data);
        vnode.node.textContent = valueOfVNode;
      } else if(vnode.props) {
        for(var attr in vnode.props) {
          var compiledProp = vnode.props[attr](this.$data);
          if(directives[attr]) {
            vnode.node.removeAttribute(attr);
            directives[attr](vnode.node, compiledProp, vnode);
          } else {
            vnode.node.setAttribute(attr, compiledProp);
          }
        }
      }

      this.build(vnode.children);
    }
  }
}

/**
* Initializes Moon
*/
Moon.prototype.init = function() {
  this.log("======= Moon =======");
  this.$hooks.created();

  setInitialElementValue(this.$el, this.$template);

  this.$dom = createVirtualDOM(this.$el);

  this.build(this.$dom.children);
  this.$hooks.mounted();
}
<|endoftext|>