<commit_before>"use strict";
var fs = require("fs");
var watch = require("../efront/watch");
var path = require("path");
var isObject = require("../basic/isObject");
var lazy = require("../basic/lazy");
var mimes = require("./mime");
var loading_queue = [], loading_count = 0;
var runPromiseInQueue = function () {
    if (loading_count > 2) return;
    if (loading_queue.length) {
        loading_count++;
        loading_queue.shift()();
    }
};
var delPromiseInQueue = function (a) {
    loading_count--;
    runPromiseInQueue();
    return a;
};
var getPromiseInQueue = function (runner) {
    var promise = new Promise(function (ok) {
        loading_queue.push(ok);
    }).then(function () {
        return new Promise(runner);
    }).then(delPromiseInQueue, delPromiseInQueue);
    runPromiseInQueue();
    return promise;
};

var getfileAsync = function (pathname, buffer_size, stat) {
    if (isFinite(buffer_size) && stat.size > buffer_size)
        return getFileHeadAsync(pathname, 0);
    return getPromiseInQueue(function (ok, oh) {
        fs.readFile(pathname, function (error, data) {
            if (error) oh(error);
            else ok(data);
        });
    });
};
var getFileHeadAsync = function (pathname, buffer_size) {
    return getPromiseInQueue(function (ok, oh) {
        fs.open(pathname, "r", function (err, h) {
            if (err) {
                return oh(err);
            }
            var chunk = Buffer.alloc(buffer_size);
            fs.read(h, chunk, 0, chunk.length, 0, function (err, length, chunk) {
                if (err) return fs.close(h), oh(err);
                if (length < chunk.length) {
                    chunk = chunk.slice(0, length);
                }
                chunk.location = pathname;
                fs.close(h, function (error) {
                    if (error) return oh(error);
                    ok(chunk);
                });
            });
        });
    });
};
var statFile = function (pathname) {
    return getPromiseInQueue(function (ok, oh) {
        fs.stat(pathname, function (error, stat) {
            if (error) return oh(error);
            ok(stat);
        });
    });
};

var readdir = function (pathame) {
    return getPromiseInQueue(function (ok, oh) {
        fs.readdir(pathame, { withFileTypes: true }, function (error, files) {
            if (error) return oh(error);
            ok(files);
        });
    });
};

var matcherReg = /[A-Z]+/g;
var replaceCase = function (match, index, input) {
    if (match.length === 1) {
        return "-" + match.toLowerCase();
    }
    if (match.length === 2) {
        match = match.toLowerCase();
        return "-" + match[0] + "-" + match[1];
    }
    if (index + match.length === input.length) {
        return "-" + match;
    }
    return '-' + match.slice(0, match.length - 1) + "-" + match[match.length - 1].toLowerCase();
};

var getExtts = function (extts) {
    if (extts instanceof Array && extts.length <= 1) extts = extts;
    return extts || "";
};
function PackageData(a) {
    Object.assign(this, JSON.parse(a));
}
PackageData.prototype = Object.create(null);

var $pathname = Symbol(":pathname");
var $updateme = Symbol("/update");
var $isloaded = Symbol(":loaded");
var $promised = Symbol(":promised");
var $geturl = Symbol("/getme");
var $buffered = Symbol(":buffer");
var $mtime = Symbol(":mtime");
var $rebuild = Symbol("/rebuild");
var $limit = Symbol(":limit");
var $root = Symbol(":rootpath");
var $linked = Symbol(":linked");
var $checklink = Symbol("/linked");
var $getbuffer = Symbol("/buffer");
function Directory(pathname, rebuild, limit) {
    this[$rebuild] = rebuild;
    this[$limit] = limit;
    this[$pathname] = pathname;
}
Directory.prototype = Object.create(null);
Directory.prototype[$updateme] = async function (updateonly) {
    var that = this;
    var files = await readdir(that[$pathname]);
    var map = {}, changed = {};
    var limit = that[$limit];
    var rebuild = that[$rebuild];
    var pathname = that[$pathname];
    var updated = false;
    var rest = [];
    for (var f of files) {
        map[f.name] = true;
        if (!that[f.name]) {
            updated = true;
            var p = path.join(pathname, f.name);
            var file = that[f.name] = f.isFile() ? new File(p, rebuild, limit) : new Directory(p, rebuild, limit);
            var key = f.name.replace(/\.\w+$/, '');
            changed[key] = true;
            file[$root] = that[$root] || pathname;
        }
        if (/\-/.test(f.name)) {
            rest.push(f);
        }
    }
    for (var f of rest) {
        var newName = f.name.replace(/\-([\s\S])/g, (_, a) => a.toUpperCase());
        if (!map[newName]) {
            map[newName] = true;
            that[newName] = that[f.name];
        }
    }

    for (var k in that) {
        var o = that[k];
        if (o instanceof Directory || o instanceof File) {
            if (!map[k]) {
                delete that[k];
                var key = k.replace(/\.\w+$/, '');
                changed[key] = true;
                updated = true;
            }
        }
    }
    for (var k in that) {
        var key = k.replace(/\.\w+$/, '');
        var o = that[k];
        if (changed[key]) {
            if (o instanceof File && o[$buffered]) {
                delete o[$buffered];
                delete o[$promised];
                delete o[$mtime];
            }
        } else if (updateonly) {
            var file = that[k];
            if (file instanceof File && file[$buffered]) {
                file[$promised] = file[$updateme]();
            }
            else {
                if (file[$isloaded]) {
                    file[$promised] = file[$updateme](updateonly);
                    await file[$promised];
                }
            }
        }
    }
    if (updated && that[$isloaded]) fireUpdate();
    that[$isloaded] = true;
};
Directory.prototype[$geturl] = function (url) {
    var that = this;
    if (!that[$promised]) that[$promised] = that[$updateme]();
    var reload = function () {
        return that[$geturl](url);
    };
    if (!that[$isloaded]) {
        return that[$promised].then(reload);
    }
    var keeys = url.split(/[\\\/]+/);
    var temps = [that];
    var keypath = [''];
    var temp = that;
    search: for (var cx = 0, dx = keeys.length; cx < dx; cx++) {
        var key = keeys[cx];
        if (key === '' || key === '.') continue;
        if (!(key in temp)) {
            let k = key.replace(matcherReg, replaceCase);
            if (k in temp) {
                key = k;
            }
        }
        if (!(key in temp)) {
            if (!that[$limit]) {
                temp = undefined;
                break;
            }
            for (var cy = temps.length - 1; cy >= 0; cy--) {
                if (key in temps[cy]) {
                    let searched = temps[cy][$geturl](keeys.slice(cx).join("/"));
                    if (searched instanceof Promise) {
                        return searched.then(reload);
                    }
                    if (searched !== undefined) {
                        temp = searched;
                        keypath.splice(cy, keypath.length - cy);
                        if (typeof searched === 'string') {
                            keypath.push.apply(keypath, searched.split('/'));
                        } else {
                            keypath.push.apply(keypath, keeys.slice(cx));
                        }
                        temps.splice(cy, keypath.length - cy, temp);
                        break search;
                    }
                }
            }
            continue;
        }

        keypath.push(key);
        temps.push(temp);
        temp = temp[key];
        if (!temp) break;
        if (temp instanceof Directory) {

            if (!temp[$promised]) temp[$promised] = temp[$updateme]();
            if (!temp[$isloaded]) return temp[$promised].then(reload);
            if (temp[$buffered]) break;
        }
    }
    if (temp instanceof File) {
        temp = temp[$getbuffer]();
    }
    else if (temp instanceof Directory && temp[$buffered]) {
        temp = temp[$buffered];
    }

    if (temp instanceof Function) {
        return temp;
    }
    if (temp instanceof Error) {
        return temp;
    }
    if (!isObject(temp)) {
        return temp;
    }
    var curl = keypath.join('/');
    if (temps.length) {
        if (curl.replace(/^\/|\/$/g, '') === keeys.join('/').replace(/^\/|\/$/g, '')) {
            return temp;
        }
        else {
            if (curl.replace(/^[\s\S]*?([^\/]+)\/?$/, "$1") === url.replace(/^[\s\S]*?([^\/]+)\/?$/, "$1")) {
                return curl;
            }
        }
    }
};

var fireUpdate = lazy(function () {
    for (var cx = 0, dx = _reload_handlers.length; cx < dx; cx++) {
        var a = _reload_handlers[cx];
        a();
    }
    var reload = require("../message").reload;
    if (isFunction(reload)) reload();
}, 60);

function File(pathname, rebuild, limit) {
    this[$pathname] = pathname;
    this[$limit] = limit;
    this[$rebuild] = rebuild;
}
File.prototype = Object.create(null);
File.prototype[$checklink] = async function () {
    var that = this;
    var linked = that[$linked];
    if (!linked || !linked.length || !that[$mtime]) return true;
    var mtime = 0;
    for (var cx = 0, dx = linked.length; cx < dx; cx++) {
        var stat = await statFile(linked[cx]);
        if (stat instanceof fs.Stats) {
            mtime += +stat.mtime;
        }
        if (linked !== that[$linked]) return true;
    }
    if (!linked[$mtime]) {
        linked[$mtime] = mtime;
        return true;
    }
    if (mtime !== linked[$mtime]) {
        linked[$mtime] = mtime
        return false;
    }
    return true;
};
File.prototype[$getbuffer] = function () {
    var that = this;
    if (that[$buffered]) return that[$buffered];
    if (that[$promised]) return that[$promised];
    return that[$promised] = that[$updateme]();
};
File.prototype[$updateme] = async function () {
    var that = this;
    var stats = await statFile(that[$pathname]);
    if (!(stats instanceof fs.Stats)) {
        return that[$buffered] = stats;
    }
    if (+stats.mtime === that[$mtime]) {
        if (await that[$checklink]()) {
            return that[$buffered];
        }
    }
    that[$mtime] = +stats.mtime;
    if (that[$buffered]) that[$buffered] = null, fireUpdate();

    var buffer = await getfileAsync(that[$pathname], that[$limit], stats);
    if (that[$rebuild] instanceof Function && buffer instanceof Buffer) {
        var url = path.relative(that[$root], that[$pathname]);
        url = url.replace(/\.(\w+)$/, '');
        try {
            var linked = that[$linked] = [];
            buffer = await that[$rebuild](buffer, url, that[$pathname], that[$linked]);
            if (linked.length) await that[$checklink]();
        } catch (e) {
            buffer = e;
            console.log(e);
            console.error("编译错误:", that[$pathname]);
        }
    }
    if (typeof buffer === "string") buffer = Buffer.from(buffer);
    if (buffer instanceof Buffer) buffer.stat = stats;
    if (!buffer.mime) {
        var extend = String(that[$pathname]).match(/\.([^\.]*)$/);
        if (extend) buffer.mime = mimes[extend[1]];
    }

    return that[$buffered] = buffer;
};

/**
 * 根椐filesroot路径设置文件缓冲
 * @param {string} filesroot
 */
var cache = function (filesroot, rebuild, buffer_size_limit) {
    var sk = function () {
    };
    filesroot = String(filesroot || '').split(",").map(path.normalize);
    var map = {};
    var treeslist = filesroot.filter(fs.existsSync).map((froot) => {
        var froot = fs.realpathSync(froot);
        if (map[froot]) {
            return;
        }
        map[froot] = true;
        if (fs.existsSync(froot) && fs.statSync(froot).isDirectory()) {
            var roots = new Directory(froot, rebuild, isFinite(buffer_size_limit) && buffer_size_limit >= 0 ? buffer_size_limit | 0 : buffer_size_limit);
            watch(froot, lazy(async function () {
                if (roots[$isloaded]) roots[$promised] = roots[$updateme](true);
                await roots[$promised];
            }, 20), true);
            return roots;
        } else {
            return Object.create(null);
        }
    }).filter(a => !!a);
    map = null;
    var seekerAsync = function (url, extts = "") {
        extts = getExtts(extts);
        if (!Array.isArray(extts)) {
            extts = [extts];
        }
        var findPackage = extts.indexOf(".js") >= 0;
        return new Promise(function (ok, oh) {
            var cy = -1;
            var cx = extts.length;
            var result, matchParent;
            var run = function () {
                if (cx >= extts.length) {
                    cy++;
                    if (cy >= treeslist.length) {
                        if (result === undefined) {
                            if (matchParent) {
                                url = url.replace(/\\/g, '/');
                                if (!/\/$/.test(url)) {
                                    url += '/';
                                    result = url;
                                }
                            }
                        }
                        return ok(result);
                    }
                    cx = 0;
                }
                var tree1 = treeslist[cy];
                var extt = extts[cx];
                var error;
                var promise = tree1[$geturl](url + extt);
                if (promise instanceof Promise) {
                    promise.catch(function (e) {
                        error = e;
                    }).then(function (result) {
                        if (result instanceof Buffer) return ok(result);
                        if (error) oh(error);
                        else run();
                    });
                } else {
                    if (typeof promise === "string" || promise instanceof Buffer || promise instanceof Function) return ok(promise);
                    if (promise instanceof PackageData) return ok(Buffer.from(JSON.stringify(promise)));
                    if (promise instanceof Directory && !result) {
                        if (!findPackage) return ok(promise);
                        var package_file = "package.json";
                        if (package_file in promise) {
                            var file = promise[package_file];
                            if (file instanceof File) {
                                file[$rebuild] = a => a;
                                if (!file[$promised]) file[$promised] = file[$updateme]();
                                if (!file[$buffered]) return file[$promised].then(run, oh);
                                if (file[$buffered] instanceof Buffer) file[$buffered] = new PackageData(file[$buffered]);
                                var package_data = file[$buffered];
                                if (package_data instanceof PackageData && package_data.main) {
                                    var roots = package_data.main.split(/[\/\\]+/).filter(a => a && a !== '.' && !/\:$/.test(a));
                                    if (roots[0] in promise) {
                                        result = path.join(url, roots.join('/')).replace(/\\/g, '/');
                                        return ok(result);
                                    }
                                }
                            }
                        } else {
                            var seek_index = 'index';
                            var index = extts.findIndex(a => seek_index + a in promise);
                            if (~index) {
                                result = path.join(url, seek_index + extts[index]).replace(/\\/g, '/');
                            } else {
                                if (typeof promise === 'string') result = promise;
                            }
                        }
                        matchParent = true;
                    }
                    cx++;
                    run();
                }

            };
            run();
        });
    };
    sk.reset = seekerAsync.reset = function () {
        for (var t of treeslist) {
            delete t[$promised];
        }
    };
    sk.async = seekerAsync;
    return sk;
};
var _reload_handlers = [];
cache.onreload = function (handler) {
    if (handler instanceof Function) _reload_handlers.push(handler);
};
module.exports = cache;<commit_msg>调整设置mime的逻辑<commit_after>"use strict";
var fs = require("fs");
var watch = require("../efront/watch");
var path = require("path");
var isObject = require("../basic/isObject");
var lazy = require("../basic/lazy");
var mimes = require("./mime");
var loading_queue = [], loading_count = 0;
var runPromiseInQueue = function () {
    if (loading_count > 2) return;
    if (loading_queue.length) {
        loading_count++;
        loading_queue.shift()();
    }
};
var delPromiseInQueue = function (a) {
    loading_count--;
    runPromiseInQueue();
    return a;
};
var getPromiseInQueue = function (runner) {
    var promise = new Promise(function (ok) {
        loading_queue.push(ok);
    }).then(function () {
        return new Promise(runner);
    }).then(delPromiseInQueue, delPromiseInQueue);
    runPromiseInQueue();
    return promise;
};

var getfileAsync = function (pathname, buffer_size, stat) {
    if (isFinite(buffer_size) && stat.size > buffer_size)
        return getFileHeadAsync(pathname, 0);
    return getPromiseInQueue(function (ok, oh) {
        fs.readFile(pathname, function (error, data) {
            if (error) oh(error);
            else ok(data);
        });
    });
};
var getFileHeadAsync = function (pathname, buffer_size) {
    return getPromiseInQueue(function (ok, oh) {
        fs.open(pathname, "r", function (err, h) {
            if (err) {
                return oh(err);
            }
            var chunk = Buffer.alloc(buffer_size);
            fs.read(h, chunk, 0, chunk.length, 0, function (err, length, chunk) {
                if (err) return fs.close(h), oh(err);
                if (length < chunk.length) {
                    chunk = chunk.slice(0, length);
                }
                chunk.location = pathname;
                fs.close(h, function (error) {
                    if (error) return oh(error);
                    ok(chunk);
                });
            });
        });
    });
};
var statFile = function (pathname) {
    return getPromiseInQueue(function (ok, oh) {
        fs.stat(pathname, function (error, stat) {
            if (error) return oh(error);
            ok(stat);
        });
    });
};

var readdir = function (pathame) {
    return getPromiseInQueue(function (ok, oh) {
        fs.readdir(pathame, { withFileTypes: true }, function (error, files) {
            if (error) return oh(error);
            ok(files);
        });
    });
};

var matcherReg = /[A-Z]+/g;
var replaceCase = function (match, index, input) {
    if (match.length === 1) {
        return "-" + match.toLowerCase();
    }
    if (match.length === 2) {
        match = match.toLowerCase();
        return "-" + match[0] + "-" + match[1];
    }
    if (index + match.length === input.length) {
        return "-" + match;
    }
    return '-' + match.slice(0, match.length - 1) + "-" + match[match.length - 1].toLowerCase();
};

var getExtts = function (extts) {
    if (extts instanceof Array && extts.length <= 1) extts = extts;
    return extts || "";
};
function PackageData(a) {
    Object.assign(this, JSON.parse(a));
}
PackageData.prototype = Object.create(null);

var $pathname = Symbol(":pathname");
var $updateme = Symbol("/update");
var $isloaded = Symbol(":loaded");
var $promised = Symbol(":promised");
var $geturl = Symbol("/getme");
var $buffered = Symbol(":buffer");
var $mtime = Symbol(":mtime");
var $rebuild = Symbol("/rebuild");
var $limit = Symbol(":limit");
var $root = Symbol(":rootpath");
var $linked = Symbol(":linked");
var $checklink = Symbol("/linked");
var $getbuffer = Symbol("/buffer");
function Directory(pathname, rebuild, limit) {
    this[$rebuild] = rebuild;
    this[$limit] = limit;
    this[$pathname] = pathname;
}
Directory.prototype = Object.create(null);
Directory.prototype[$updateme] = async function (updateonly) {
    var that = this;
    var files = await readdir(that[$pathname]);
    var map = {}, changed = {};
    var limit = that[$limit];
    var rebuild = that[$rebuild];
    var pathname = that[$pathname];
    var updated = false;
    var rest = [];
    for (var f of files) {
        map[f.name] = true;
        if (!that[f.name]) {
            updated = true;
            var p = path.join(pathname, f.name);
            var file = that[f.name] = f.isFile() ? new File(p, rebuild, limit) : new Directory(p, rebuild, limit);
            var key = f.name.replace(/\.\w+$/, '');
            changed[key] = true;
            file[$root] = that[$root] || pathname;
        }
        if (/\-/.test(f.name)) {
            rest.push(f);
        }
    }
    for (var f of rest) {
        var newName = f.name.replace(/\-([\s\S])/g, (_, a) => a.toUpperCase());
        if (!map[newName]) {
            map[newName] = true;
            that[newName] = that[f.name];
        }
    }

    for (var k in that) {
        var o = that[k];
        if (o instanceof Directory || o instanceof File) {
            if (!map[k]) {
                delete that[k];
                var key = k.replace(/\.\w+$/, '');
                changed[key] = true;
                updated = true;
            }
        }
    }
    for (var k in that) {
        var key = k.replace(/\.\w+$/, '');
        var o = that[k];
        if (changed[key]) {
            if (o instanceof File && o[$buffered]) {
                delete o[$buffered];
                delete o[$promised];
                delete o[$mtime];
            }
        } else if (updateonly) {
            var file = that[k];
            if (file instanceof File && file[$buffered]) {
                file[$promised] = file[$updateme]();
            }
            else {
                if (file[$isloaded]) {
                    file[$promised] = file[$updateme](updateonly);
                    await file[$promised];
                }
            }
        }
    }
    if (updated && that[$isloaded]) fireUpdate();
    that[$isloaded] = true;
};
Directory.prototype[$geturl] = function (url) {
    var that = this;
    if (!that[$promised]) that[$promised] = that[$updateme]();
    var reload = function () {
        return that[$geturl](url);
    };
    if (!that[$isloaded]) {
        return that[$promised].then(reload);
    }
    var keeys = url.split(/[\\\/]+/);
    var temps = [that];
    var keypath = [''];
    var temp = that;
    search: for (var cx = 0, dx = keeys.length; cx < dx; cx++) {
        var key = keeys[cx];
        if (key === '' || key === '.') continue;
        if (!(key in temp)) {
            let k = key.replace(matcherReg, replaceCase);
            if (k in temp) {
                key = k;
            }
        }
        if (!(key in temp)) {
            if (!that[$limit]) {
                temp = undefined;
                break;
            }
            for (var cy = temps.length - 1; cy >= 0; cy--) {
                if (key in temps[cy]) {
                    let searched = temps[cy][$geturl](keeys.slice(cx).join("/"));
                    if (searched instanceof Promise) {
                        return searched.then(reload);
                    }
                    if (searched !== undefined) {
                        temp = searched;
                        keypath.splice(cy, keypath.length - cy);
                        if (typeof searched === 'string') {
                            keypath.push.apply(keypath, searched.split('/'));
                        } else {
                            keypath.push.apply(keypath, keeys.slice(cx));
                        }
                        temps.splice(cy, keypath.length - cy, temp);
                        break search;
                    }
                }
            }
            continue;
        }

        keypath.push(key);
        temps.push(temp);
        temp = temp[key];
        if (!temp) break;
        if (temp instanceof Directory) {

            if (!temp[$promised]) temp[$promised] = temp[$updateme]();
            if (!temp[$isloaded]) return temp[$promised].then(reload);
            if (temp[$buffered]) break;
        }
    }
    if (temp instanceof File) {
        temp = temp[$getbuffer]();
    }
    else if (temp instanceof Directory && temp[$buffered]) {
        temp = temp[$buffered];
    }

    if (temp instanceof Function) {
        return temp;
    }
    if (temp instanceof Error) {
        return temp;
    }
    if (!isObject(temp)) {
        return temp;
    }
    var curl = keypath.join('/');
    if (temps.length) {
        if (curl.replace(/^\/|\/$/g, '') === keeys.join('/').replace(/^\/|\/$/g, '')) {
            return temp;
        }
        else {
            if (curl.replace(/^[\s\S]*?([^\/]+)\/?$/, "$1") === url.replace(/^[\s\S]*?([^\/]+)\/?$/, "$1")) {
                return curl;
            }
        }
    }
};

var fireUpdate = lazy(function () {
    for (var cx = 0, dx = _reload_handlers.length; cx < dx; cx++) {
        var a = _reload_handlers[cx];
        a();
    }
    var reload = require("../message").reload;
    if (isFunction(reload)) reload();
}, 60);

function File(pathname, rebuild, limit) {
    this[$pathname] = pathname;
    this[$limit] = limit;
    this[$rebuild] = rebuild;
}
File.prototype = Object.create(null);
File.prototype[$checklink] = async function () {
    var that = this;
    var linked = that[$linked];
    if (!linked || !linked.length || !that[$mtime]) return true;
    var mtime = 0;
    for (var cx = 0, dx = linked.length; cx < dx; cx++) {
        var stat = await statFile(linked[cx]);
        if (stat instanceof fs.Stats) {
            mtime += +stat.mtime;
        }
        if (linked !== that[$linked]) return true;
    }
    if (!linked[$mtime]) {
        linked[$mtime] = mtime;
        return true;
    }
    if (mtime !== linked[$mtime]) {
        linked[$mtime] = mtime
        return false;
    }
    return true;
};
File.prototype[$getbuffer] = function () {
    var that = this;
    if (that[$buffered]) return that[$buffered];
    if (that[$promised]) return that[$promised];
    return that[$promised] = that[$updateme]();
};
File.prototype[$updateme] = async function () {
    var that = this;
    var stats = await statFile(that[$pathname]);
    if (!(stats instanceof fs.Stats)) {
        return that[$buffered] = stats;
    }
    if (+stats.mtime === that[$mtime]) {
        if (await that[$checklink]()) {
            return that[$buffered];
        }
    }
    that[$mtime] = +stats.mtime;
    if (that[$buffered]) that[$buffered] = null, fireUpdate();

    var buffer = await getfileAsync(that[$pathname], that[$limit], stats);
    if (that[$rebuild] instanceof Function && buffer instanceof Buffer) {
        var url = path.relative(that[$root], that[$pathname]);
        url = url.replace(/\.(\w+)$/, '');
        try {
            var linked = that[$linked] = [];
            buffer = await that[$rebuild](buffer, url, that[$pathname], that[$linked]);
            if (linked.length) await that[$checklink]();
            if (typeof buffer === "string") buffer = Buffer.from(buffer);
            if (buffer instanceof Buffer) buffer.stat = stats;
            if (buffer && !buffer.mime) {
                var extend = String(that[$pathname]).match(/\.([^\.]*)$/);
                if (extend) buffer.mime = mimes[extend[1]];
            }
        } catch (e) {
            buffer = e;
            console.log(e);
            console.error("编译错误:", that[$pathname]);
        }
    }

    return that[$buffered] = buffer;
};

/**
 * 根椐filesroot路径设置文件缓冲
 * @param {string} filesroot
 */
var cache = function (filesroot, rebuild, buffer_size_limit) {
    var sk = function () {
    };
    filesroot = String(filesroot || '').split(",").map(path.normalize);
    var map = {};
    var treeslist = filesroot.filter(fs.existsSync).map((froot) => {
        var froot = fs.realpathSync(froot);
        if (map[froot]) {
            return;
        }
        map[froot] = true;
        if (fs.existsSync(froot) && fs.statSync(froot).isDirectory()) {
            var roots = new Directory(froot, rebuild, isFinite(buffer_size_limit) && buffer_size_limit >= 0 ? buffer_size_limit | 0 : buffer_size_limit);
            watch(froot, lazy(async function () {
                if (roots[$isloaded]) roots[$promised] = roots[$updateme](true);
                await roots[$promised];
            }, 20), true);
            return roots;
        } else {
            return Object.create(null);
        }
    }).filter(a => !!a);
    map = null;
    var seekerAsync = function (url, extts = "") {
        extts = getExtts(extts);
        if (!Array.isArray(extts)) {
            extts = [extts];
        }
        var findPackage = extts.indexOf(".js") >= 0;
        return new Promise(function (ok, oh) {
            var cy = -1;
            var cx = extts.length;
            var result, matchParent;
            var run = function () {
                if (cx >= extts.length) {
                    cy++;
                    if (cy >= treeslist.length) {
                        if (result === undefined) {
                            if (matchParent) {
                                url = url.replace(/\\/g, '/');
                                if (!/\/$/.test(url)) {
                                    url += '/';
                                    result = url;
                                }
                            }
                        }
                        return ok(result);
                    }
                    cx = 0;
                }
                var tree1 = treeslist[cy];
                var extt = extts[cx];
                var error;
                var promise = tree1[$geturl](url + extt);
                if (promise instanceof Promise) {
                    promise.catch(function (e) {
                        error = e;
                    }).then(function (result) {
                        if (result instanceof Buffer) return ok(result);
                        if (error) oh(error);
                        else run();
                    });
                } else {
                    if (typeof promise === "string" || promise instanceof Buffer || promise instanceof Function) return ok(promise);
                    if (promise instanceof PackageData) return ok(Buffer.from(JSON.stringify(promise)));
                    if (promise instanceof Directory && !result) {
                        if (!findPackage) return ok(promise);
                        var package_file = "package.json";
                        if (package_file in promise) {
                            var file = promise[package_file];
                            if (file instanceof File) {
                                file[$rebuild] = a => a;
                                if (!file[$promised]) file[$promised] = file[$updateme]();
                                if (!file[$buffered]) return file[$promised].then(run, oh);
                                if (file[$buffered] instanceof Buffer) file[$buffered] = new PackageData(file[$buffered]);
                                var package_data = file[$buffered];
                                if (package_data instanceof PackageData && package_data.main) {
                                    var roots = package_data.main.split(/[\/\\]+/).filter(a => a && a !== '.' && !/\:$/.test(a));
                                    if (roots[0] in promise) {
                                        result = path.join(url, roots.join('/')).replace(/\\/g, '/');
                                        return ok(result);
                                    }
                                }
                            }
                        } else {
                            var seek_index = 'index';
                            var index = extts.findIndex(a => seek_index + a in promise);
                            if (~index) {
                                result = path.join(url, seek_index + extts[index]).replace(/\\/g, '/');
                            } else {
                                if (typeof promise === 'string') result = promise;
                            }
                        }
                        matchParent = true;
                    }
                    cx++;
                    run();
                }

            };
            run();
        });
    };
    sk.reset = seekerAsync.reset = function () {
        for (var t of treeslist) {
            delete t[$promised];
        }
    };
    sk.async = seekerAsync;
    return sk;
};
var _reload_handlers = [];
cache.onreload = function (handler) {
    if (handler instanceof Function) _reload_handlers.push(handler);
};
module.exports = cache;<|endoftext|>


<commit_before>"use strict";
var fs = require("fs");
var watch = require("../efront/watch");
var path = require("path");
var isObject = require("../basic/isObject");
var lazy = require("../basic/lazy");
var loading_queue = [], loading_count = 0;
var runPromiseInQueue = function () {
    if (loading_count > 2) return;
    if (loading_queue.length) {
        loading_count++;
        loading_queue.shift()();
    }
};
var delPromiseInQueue = function (a) {
    loading_count--;
    runPromiseInQueue();
    return a;
};
var getPromiseInQueue = function (runner) {
    var promise = new Promise(function (ok) {
        loading_queue.push(ok);
    }).then(function () {
        return new Promise(runner);
    }).then(delPromiseInQueue, delPromiseInQueue);
    runPromiseInQueue();
    return promise;
};

var getfileAsync = function (pathname, buffer_size, stat) {
    if (isFinite(buffer_size) && stat.size > buffer_size)
        return getFileHeadAsync(pathname, 0);
    return getPromiseInQueue(function (ok, oh) {
        fs.readFile(pathname, function (error, data) {
            if (error) oh(error);
            else ok(data);
        });
    });
};
var getFileHeadAsync = function (pathname, buffer_size) {
    return getPromiseInQueue(function (ok, oh) {
        fs.open(pathname, "r", function (err, h) {
            if (err) {
                return oh(err);
            }
            var chunk = Buffer.alloc(buffer_size);
            fs.read(h, chunk, 0, chunk.length, 0, function (err, length, chunk) {
                if (err) return fs.close(h), oh(err);
                if (length < chunk.length) {
                    chunk = chunk.slice(0, length);
                }
                chunk.location = pathname;
                fs.close(h, function (error) {
                    if (error) return oh(error);
                    ok(chunk);
                });
            });
        });
    });
};
var statFile = function (pathname) {
    return getPromiseInQueue(function (ok, oh) {
        fs.stat(pathname, function (error, stat) {
            if (error) return oh(error);
            ok(stat);
        });
    });
};

var readdir = function (pathame) {
    return getPromiseInQueue(function (ok, oh) {
        fs.readdir(pathame, { withFileTypes: true }, function (error, files) {
            if (error) return oh(error);
            ok(files);
        });
    });
};

var matcherReg = /[A-Z]+/g;
var replaceCase = function (match, index, input) {
    if (match.length === 1) {
        return "-" + match.toLowerCase();
    }
    if (match.length === 2) {
        match = match.toLowerCase();
        return "-" + match[0] + "-" + match[1];
    }
    if (index + match.length === input.length) {
        return "-" + match;
    }
    return '-' + match.slice(0, match.length - 1) + "-" + match[match.length - 1].toLowerCase();
};

var getExtts = function (extts) {
    if (extts instanceof Array && extts.length <= 1) extts = extts;
    return extts || "";
};
function PackageData(a) {
    Object.assign(this, JSON.parse(a));
}
PackageData.prototype = Object.create(null);

var $pathname = Symbol(":pathname");
var $updateme = Symbol("?update");
var $isloaded = Symbol(":loaded");
var $promised = Symbol(":promised");
var $geturl = Symbol("?getme");
var $buffered = Symbol(":buffer");
var $mtime = Symbol(":mtime");
var $rebuild = Symbol('?rebuild');
var $limit = Symbol(":limit");
var $root = Symbol(":rootpath");
var $linked = Symbol(":linked");
var $checklink = Symbol("?linked");
var $getbuffer = Symbol("?buffer");
function Directory(pathname, rebuild, limit) {
    this[$rebuild] = rebuild;
    this[$limit] = limit;
    this[$pathname] = pathname;
}
Directory.prototype = Object.create(null);
Directory.prototype[$updateme] = async function (updateonly) {
    var that = this;
    var files = await readdir(that[$pathname]);
    var map = {};
    var limit = that[$limit];
    var rebuild = that[$rebuild];
    var pathname = that[$pathname];
    var updated = false;
    for (var f of files) {
        var p = path.join(pathname, f.name);
        map[f.name] = true;
        if (!that[f.name]) {
            updated = true;
            var file = that[f.name] = f.isFile() ? new File(p, rebuild, limit) : new Directory(p, rebuild, limit);
            file[$root] = that[$root] || pathname;
        }
        else if (updateonly) {
            var file = that[f.name];
            if (file instanceof File && file[$buffered]) {
                file[$promised] = file[$updateme]();
            }
            else {
                if (file[$isloaded]) {
                    file[$promised] = file[$updateme](updateonly);
                    await file[$promised];
                }
            }
        }
    }
    for (var k in that) {
        var o = that[k];
        if (o instanceof Directory || o instanceof File) {
            if (!map[k]) {
                delete that[k];
                updated = true;
            }
        }
    }
    if (updated && that[$isloaded]) fireUpdate();
    that[$isloaded] = true;
};
Directory.prototype[$geturl] = function (url) {

    var that = this;
    if (!that[$promised]) that[$promised] = that[$updateme]();
    var reload = function () {
        return that[$geturl](url);
    };
    if (!that[$isloaded]) {
        return that[$promised].then(reload);
    }
    var keeys = url.split(/[\\\/]+/);
    var temps = [that];
    var keypath = [''];
    var temp = that;
    search: for (var cx = 0, dx = keeys.length; cx < dx; cx++) {
        var key = keeys[cx];
        if (key === '' || key === '.') continue;
        if (!(key in temp)) {
            let k = key.replace(matcherReg, replaceCase);
            if (k in temp) {
                key = k;
            }
        }
        if (!(key in temp)) {
            if (!that[$limit]) {
                temp = undefined;
                break;
            }
            for (var cy = temps.length - 1; cy >= 0; cy--) {
                if (key in temps[cy]) {
                    let searched = temps[cy][$geturl](keeys.slice(cx).join("/"));
                    if (searched instanceof Promise) {
                        return searched.then(reload);
                    }
                    if (searched !== undefined) {
                        temp = searched;
                        keypath.splice(cy, keypath.length - cy);
                        if (typeof searched === 'string') {
                            keypath.push.apply(keypath, searched.split('/'));
                        } else {
                            keypath.push.apply(keypath, keeys.slice(cx));
                        }
                        temps.splice(cy, keypath.length - cy, temp);
                        break search;
                    }
                }
            }
            continue;
        }

        keypath.push(key);
        temps.push(temp);
        temp = temp[key];
        if (!temp) break;
        if (temp instanceof Directory) {

            if (!temp[$promised]) temp[$promised] = temp[$updateme]();
            if (!temp[$isloaded]) return temp[$promised].then(reload);
            if (temp[$buffered]) break;
        }
    }
    if (temp instanceof File) {
        temp = temp[$getbuffer]();
    }
    else if (temp instanceof Directory && temp[$buffered]) {
        temp = temp[$buffered];
    }

    if (temp instanceof Function) {
        return temp;
    }
    if (temp instanceof Error) {
        return temp;
    }
    if (!isObject(temp)) {
        return temp;
    }
    var curl = keypath.join('/');
    if (temps.length) {
        if (curl.replace(/^\/|\/$/g, '') === keeys.join('/').replace(/^\/|\/$/g, '')) {
            return temp;
        }
        else {
            if (curl.replace(/^[\s\S]*?([^\/]+)\/?$/, "$1") === url.replace(/^[\s\S]*?([^\/]+)\/?$/, "$1")) {
                return curl;
            }
        }
    }
};

var fireUpdate = lazy(function () {
    for (var cx = 0, dx = _reload_handlers.length; cx < dx; cx++) {
        var a = _reload_handlers[cx];
        a();
    }
    var reload = require("../message").reload;
    if (isFunction(reload)) reload();
}, 60);

function File(pathname, rebuild, limit) {
    this[$pathname] = pathname;
    this[$limit] = limit;
    this[$rebuild] = rebuild;
}
File.prototype = Object.create(null);
File.prototype[$checklink] = async function () {
    var that = this;
    var linked = that[$linked];
    if (!linked || !linked.length || !that[$mtime]) return;
    var mtime = 0;
    for (var cx = 0, dx = linked.length; cx < dx; cx++) {
        var stat = await statFile(linked[cx]);
        if (stat instanceof fs.Stats) {
            mtime += +stat.mtime;
        }
        if (linked !== that[$linked]) return;
    }
    return mtime !== linked[$mtime];
};
File.prototype[$getbuffer] = function () {
    var that = this;
    if (that[$buffered]) return that[$buffered];
    if (that[$promised]) return that[$promised];
    return that[$promised] = that[$updateme]();
};
File.prototype[$updateme] = async function () {
    var that = this;
    var stats = await statFile(that[$pathname]);
    if (!(stats instanceof fs.Stats)) {
        return that[$buffered] = stats;
    }
    if (+stats.mtime === that[$mtime]) {
        if (!await that[$checklink]()) {
            return that[$buffered];
        }
    }
    if (that[$buffered]) that[$buffered] = null, fireUpdate();

    var buffer = await getfileAsync(that[$pathname], that[$limit], stats);
    if (that[$rebuild] instanceof Function && buffer instanceof Buffer) {
        var url = path.relative(that[$root], that[$pathname]);
        url = url.replace(/\.(\w+)$/, '');
        try {
            var linked = that[$linked] = [];
            buffer = await that[$rebuild](buffer, url, that[$pathname], that[$linked]);
            if (linked.length) await that[$checklink]();
        } catch (e) {
            buffer = e;
            console.log(e);
            console.error("编译错误:", that[$pathname]);
        }
    }
    if (typeof buffer === "string") buffer = Buffer.from(buffer);
    if (buffer instanceof Buffer) buffer.stat = stats;
    return that[$buffered] = buffer;
};

/**
 * 根椐filesroot路径设置文件缓冲
 * @param {string} filesroot
 */
var cache = function (filesroot, rebuild, buffer_size_limit) {
    var sk = function () {
    };
    filesroot = filesroot.split(",");
    var map = {};
    var treeslist = filesroot.filter(fs.existsSync).map((froot, i) => {
        var froot = fs.realpathSync(froot);
        if (map[froot]) {
            return;
        }
        map[froot] = true;
        if (fs.existsSync(froot) && fs.statSync(froot).isDirectory()) {
            var roots = new Directory(froot, rebuild, isFinite(buffer_size_limit) && buffer_size_limit >= 0 ? buffer_size_limit | 0 : buffer_size_limit);
            watch(froot, lazy(async function () {
                if (roots[$isloaded]) roots[$promised] = roots[$updateme](true);
                await roots[$promised];
            }, 20), true);
            return roots;
        } else {
            return Object.create(null);
        }
    }).filter(a => !!a);
    map = null;
    var seekerAsync = function (url, extts = "") {
        extts = getExtts(extts);
        if (!Array.isArray(extts)) {
            extts = [extts];
        }
        var findPackage = extts.indexOf(".js") >= 0;
        return new Promise(function (ok, oh) {
            var cy = 0;
            var cx = 0;
            var result, matchParent;
            var run = function () {
                if (cx >= extts.length) {
                    cy++;
                    if (cy >= treeslist.length) {
                        if (result === undefined) {
                            if (matchParent) {
                                url = url.replace(/\\/g, '/');
                                if (!/\/$/.test(url)) {
                                    url += '/';
                                    result = url;
                                }
                            }
                        }
                        return ok(result);
                    }
                    cx = 0;
                }
                var tree1 = treeslist[cy];
                var extt = extts[cx];
                var error;
                var promise = tree1[$geturl](url + extt);
                if (promise instanceof Promise) {
                    promise.catch(function (e) {
                        error = e;
                    }).then(function (result) {
                        if (result instanceof Buffer) return ok(result);
                        if (error) oh(error);
                        else run();
                    });
                } else {
                    if (typeof promise === "string" || promise instanceof Buffer || promise instanceof Function) return ok(promise);
                    if (promise instanceof PackageData) return ok(Buffer.from(JSON.stringify(promise)));
                    if (promise instanceof Directory && !result) {
                        if (!findPackage) return ok(promise);
                        var package_file = "package.json";
                        if (package_file in promise) {
                            var file = promise[package_file];
                            if (file instanceof File) {
                                if (!file[$promised]) file[$updateme]();
                                if (!file[$buffered]) return file[$promised].then(run, oh);
                                if (file[$buffered] instanceof Buffer) file[$buffered] = new PackageData(file[$buffered]);
                                var package_data = file[$buffered];
                                if (package_data instanceof PackageData && package_data.main) {
                                    var roots = package_data.main.split(/[\/\\]+/).filter(a => a && a !== '.' && !/\:$/.test(a));
                                    if (roots[0] in promise) {
                                        result = path.join(url, roots.join('/')).replace(/\\/g, '/');
                                        return ok(result);
                                    }
                                }
                            }
                        } else {
                            var seek_index = 'index';
                            var index = extts.findIndex(a => seek_index + a in promise);
                            if (~index) {
                                result = path.join(url, seek_index + extts[index]).replace(/\\/g, '/');
                            } else {
                                if (typeof promise === 'string') result = promise;
                            }
                        }
                        matchParent = true;
                    }
                    cx++;
                    run();
                }

            };
            run();
        });
    };
    sk.async = seekerAsync;
    return sk;
};
var _reload_handlers = [];
cache.onreload = function (handler) {
    if (handler instanceof Function) _reload_handlers.push(handler);
};
module.exports = cache;<commit_msg>修复一处错误<commit_after>"use strict";
var fs = require("fs");
var watch = require("../efront/watch");
var path = require("path");
var isObject = require("../basic/isObject");
var lazy = require("../basic/lazy");
var loading_queue = [], loading_count = 0;
var runPromiseInQueue = function () {
    if (loading_count > 2) return;
    if (loading_queue.length) {
        loading_count++;
        loading_queue.shift()();
    }
};
var delPromiseInQueue = function (a) {
    loading_count--;
    runPromiseInQueue();
    return a;
};
var getPromiseInQueue = function (runner) {
    var promise = new Promise(function (ok) {
        loading_queue.push(ok);
    }).then(function () {
        return new Promise(runner);
    }).then(delPromiseInQueue, delPromiseInQueue);
    runPromiseInQueue();
    return promise;
};

var getfileAsync = function (pathname, buffer_size, stat) {
    if (isFinite(buffer_size) && stat.size > buffer_size)
        return getFileHeadAsync(pathname, 0);
    return getPromiseInQueue(function (ok, oh) {
        fs.readFile(pathname, function (error, data) {
            if (error) oh(error);
            else ok(data);
        });
    });
};
var getFileHeadAsync = function (pathname, buffer_size) {
    return getPromiseInQueue(function (ok, oh) {
        fs.open(pathname, "r", function (err, h) {
            if (err) {
                return oh(err);
            }
            var chunk = Buffer.alloc(buffer_size);
            fs.read(h, chunk, 0, chunk.length, 0, function (err, length, chunk) {
                if (err) return fs.close(h), oh(err);
                if (length < chunk.length) {
                    chunk = chunk.slice(0, length);
                }
                chunk.location = pathname;
                fs.close(h, function (error) {
                    if (error) return oh(error);
                    ok(chunk);
                });
            });
        });
    });
};
var statFile = function (pathname) {
    return getPromiseInQueue(function (ok, oh) {
        fs.stat(pathname, function (error, stat) {
            if (error) return oh(error);
            ok(stat);
        });
    });
};

var readdir = function (pathame) {
    return getPromiseInQueue(function (ok, oh) {
        fs.readdir(pathame, { withFileTypes: true }, function (error, files) {
            if (error) return oh(error);
            ok(files);
        });
    });
};

var matcherReg = /[A-Z]+/g;
var replaceCase = function (match, index, input) {
    if (match.length === 1) {
        return "-" + match.toLowerCase();
    }
    if (match.length === 2) {
        match = match.toLowerCase();
        return "-" + match[0] + "-" + match[1];
    }
    if (index + match.length === input.length) {
        return "-" + match;
    }
    return '-' + match.slice(0, match.length - 1) + "-" + match[match.length - 1].toLowerCase();
};

var getExtts = function (extts) {
    if (extts instanceof Array && extts.length <= 1) extts = extts;
    return extts || "";
};
function PackageData(a) {
    Object.assign(this, JSON.parse(a));
}
PackageData.prototype = Object.create(null);

var $pathname = Symbol(":pathname");
var $updateme = Symbol("?update");
var $isloaded = Symbol(":loaded");
var $promised = Symbol(":promised");
var $geturl = Symbol("?getme");
var $buffered = Symbol(":buffer");
var $mtime = Symbol(":mtime");
var $rebuild = Symbol('?rebuild');
var $limit = Symbol(":limit");
var $root = Symbol(":rootpath");
var $linked = Symbol(":linked");
var $checklink = Symbol("?linked");
var $getbuffer = Symbol("?buffer");
function Directory(pathname, rebuild, limit) {
    this[$rebuild] = rebuild;
    this[$limit] = limit;
    this[$pathname] = pathname;
}
Directory.prototype = Object.create(null);
Directory.prototype[$updateme] = async function (updateonly) {
    var that = this;
    var files = await readdir(that[$pathname]);
    var map = {};
    var limit = that[$limit];
    var rebuild = that[$rebuild];
    var pathname = that[$pathname];
    var updated = false;
    for (var f of files) {
        var p = path.join(pathname, f.name);
        map[f.name] = true;
        if (!that[f.name]) {
            updated = true;
            var file = that[f.name] = f.isFile() ? new File(p, rebuild, limit) : new Directory(p, rebuild, limit);
            file[$root] = that[$root] || pathname;
        }
        else if (updateonly) {
            var file = that[f.name];
            if (file instanceof File && file[$buffered]) {
                file[$promised] = file[$updateme]();
            }
            else {
                if (file[$isloaded]) {
                    file[$promised] = file[$updateme](updateonly);
                    await file[$promised];
                }
            }
        }
    }
    for (var k in that) {
        var o = that[k];
        if (o instanceof Directory || o instanceof File) {
            if (!map[k]) {
                delete that[k];
                updated = true;
            }
        }
    }
    if (updated && that[$isloaded]) fireUpdate();
    that[$isloaded] = true;
};
Directory.prototype[$geturl] = function (url) {

    var that = this;
    if (!that[$promised]) that[$promised] = that[$updateme]();
    var reload = function () {
        return that[$geturl](url);
    };
    if (!that[$isloaded]) {
        return that[$promised].then(reload);
    }
    var keeys = url.split(/[\\\/]+/);
    var temps = [that];
    var keypath = [''];
    var temp = that;
    search: for (var cx = 0, dx = keeys.length; cx < dx; cx++) {
        var key = keeys[cx];
        if (key === '' || key === '.') continue;
        if (!(key in temp)) {
            let k = key.replace(matcherReg, replaceCase);
            if (k in temp) {
                key = k;
            }
        }
        if (!(key in temp)) {
            if (!that[$limit]) {
                temp = undefined;
                break;
            }
            for (var cy = temps.length - 1; cy >= 0; cy--) {
                if (key in temps[cy]) {
                    let searched = temps[cy][$geturl](keeys.slice(cx).join("/"));
                    if (searched instanceof Promise) {
                        return searched.then(reload);
                    }
                    if (searched !== undefined) {
                        temp = searched;
                        keypath.splice(cy, keypath.length - cy);
                        if (typeof searched === 'string') {
                            keypath.push.apply(keypath, searched.split('/'));
                        } else {
                            keypath.push.apply(keypath, keeys.slice(cx));
                        }
                        temps.splice(cy, keypath.length - cy, temp);
                        break search;
                    }
                }
            }
            continue;
        }

        keypath.push(key);
        temps.push(temp);
        temp = temp[key];
        if (!temp) break;
        if (temp instanceof Directory) {

            if (!temp[$promised]) temp[$promised] = temp[$updateme]();
            if (!temp[$isloaded]) return temp[$promised].then(reload);
            if (temp[$buffered]) break;
        }
    }
    if (temp instanceof File) {
        temp = temp[$getbuffer]();
    }
    else if (temp instanceof Directory && temp[$buffered]) {
        temp = temp[$buffered];
    }

    if (temp instanceof Function) {
        return temp;
    }
    if (temp instanceof Error) {
        return temp;
    }
    if (!isObject(temp)) {
        return temp;
    }
    var curl = keypath.join('/');
    if (temps.length) {
        if (curl.replace(/^\/|\/$/g, '') === keeys.join('/').replace(/^\/|\/$/g, '')) {
            return temp;
        }
        else {
            if (curl.replace(/^[\s\S]*?([^\/]+)\/?$/, "$1") === url.replace(/^[\s\S]*?([^\/]+)\/?$/, "$1")) {
                return curl;
            }
        }
    }
};

var fireUpdate = lazy(function () {
    for (var cx = 0, dx = _reload_handlers.length; cx < dx; cx++) {
        var a = _reload_handlers[cx];
        a();
    }
    var reload = require("../message").reload;
    if (isFunction(reload)) reload();
}, 60);

function File(pathname, rebuild, limit) {
    this[$pathname] = pathname;
    this[$limit] = limit;
    this[$rebuild] = rebuild;
}
File.prototype = Object.create(null);
File.prototype[$checklink] = async function () {
    var that = this;
    var linked = that[$linked];
    if (!linked || !linked.length || !that[$mtime]) return true;
    var mtime = 0;
    for (var cx = 0, dx = linked.length; cx < dx; cx++) {
        var stat = await statFile(linked[cx]);
        if (stat instanceof fs.Stats) {
            mtime += +stat.mtime;
        }
        if (linked !== that[$linked]) return true;
    }
    if (!linked[$mtime]) {
        linked[$mtime] = mtime;
        return true;
    }
    if (linked[$mtime] !== linked[$mtime]) {
        linked[$mtime] = mtime
        return false;
    }
    return true;
};
File.prototype[$getbuffer] = function () {
    var that = this;
    if (that[$buffered]) return that[$buffered];
    if (that[$promised]) return that[$promised];
    return that[$promised] = that[$updateme]();
};
File.prototype[$updateme] = async function () {
    var that = this;
    var stats = await statFile(that[$pathname]);
    if (!(stats instanceof fs.Stats)) {
        return that[$buffered] = stats;
    }
    if (+stats.mtime === that[$mtime]) {
        if (await that[$checklink]()) {
            return that[$buffered];
        }
    }
    that[$mtime] = +stats.mtime;
    if (that[$buffered]) that[$buffered] = null, fireUpdate();

    var buffer = await getfileAsync(that[$pathname], that[$limit], stats);
    if (that[$rebuild] instanceof Function && buffer instanceof Buffer) {
        var url = path.relative(that[$root], that[$pathname]);
        url = url.replace(/\.(\w+)$/, '');
        try {
            var linked = that[$linked] = [];
            buffer = await that[$rebuild](buffer, url, that[$pathname], that[$linked]);
            if (linked.length) await that[$checklink]();
        } catch (e) {
            buffer = e;
            console.log(e);
            console.error("编译错误:", that[$pathname]);
        }
    }
    if (typeof buffer === "string") buffer = Buffer.from(buffer);
    if (buffer instanceof Buffer) buffer.stat = stats;
    return that[$buffered] = buffer;
};

/**
 * 根椐filesroot路径设置文件缓冲
 * @param {string} filesroot
 */
var cache = function (filesroot, rebuild, buffer_size_limit) {
    var sk = function () {
    };
    filesroot = filesroot.split(",");
    var map = {};
    var treeslist = filesroot.filter(fs.existsSync).map((froot, i) => {
        var froot = fs.realpathSync(froot);
        if (map[froot]) {
            return;
        }
        map[froot] = true;
        if (fs.existsSync(froot) && fs.statSync(froot).isDirectory()) {
            var roots = new Directory(froot, rebuild, isFinite(buffer_size_limit) && buffer_size_limit >= 0 ? buffer_size_limit | 0 : buffer_size_limit);
            watch(froot, lazy(async function () {
                if (roots[$isloaded]) roots[$promised] = roots[$updateme](true);
                await roots[$promised];
            }, 20), true);
            return roots;
        } else {
            return Object.create(null);
        }
    }).filter(a => !!a);
    map = null;
    var seekerAsync = function (url, extts = "") {
        extts = getExtts(extts);
        if (!Array.isArray(extts)) {
            extts = [extts];
        }
        var findPackage = extts.indexOf(".js") >= 0;
        return new Promise(function (ok, oh) {
            var cy = 0;
            var cx = 0;
            var result, matchParent;
            var run = function () {
                if (cx >= extts.length) {
                    cy++;
                    if (cy >= treeslist.length) {
                        if (result === undefined) {
                            if (matchParent) {
                                url = url.replace(/\\/g, '/');
                                if (!/\/$/.test(url)) {
                                    url += '/';
                                    result = url;
                                }
                            }
                        }
                        return ok(result);
                    }
                    cx = 0;
                }
                var tree1 = treeslist[cy];
                var extt = extts[cx];
                var error;
                var promise = tree1[$geturl](url + extt);
                if (promise instanceof Promise) {
                    promise.catch(function (e) {
                        error = e;
                    }).then(function (result) {
                        if (result instanceof Buffer) return ok(result);
                        if (error) oh(error);
                        else run();
                    });
                } else {
                    if (typeof promise === "string" || promise instanceof Buffer || promise instanceof Function) return ok(promise);
                    if (promise instanceof PackageData) return ok(Buffer.from(JSON.stringify(promise)));
                    if (promise instanceof Directory && !result) {
                        if (!findPackage) return ok(promise);
                        var package_file = "package.json";
                        if (package_file in promise) {
                            var file = promise[package_file];
                            if (file instanceof File) {
                                if (!file[$promised]) file[$updateme]();
                                if (!file[$buffered]) return file[$promised].then(run, oh);
                                if (file[$buffered] instanceof Buffer) file[$buffered] = new PackageData(file[$buffered]);
                                var package_data = file[$buffered];
                                if (package_data instanceof PackageData && package_data.main) {
                                    var roots = package_data.main.split(/[\/\\]+/).filter(a => a && a !== '.' && !/\:$/.test(a));
                                    if (roots[0] in promise) {
                                        result = path.join(url, roots.join('/')).replace(/\\/g, '/');
                                        return ok(result);
                                    }
                                }
                            }
                        } else {
                            var seek_index = 'index';
                            var index = extts.findIndex(a => seek_index + a in promise);
                            if (~index) {
                                result = path.join(url, seek_index + extts[index]).replace(/\\/g, '/');
                            } else {
                                if (typeof promise === 'string') result = promise;
                            }
                        }
                        matchParent = true;
                    }
                    cx++;
                    run();
                }

            };
            run();
        });
    };
    sk.async = seekerAsync;
    return sk;
};
var _reload_handlers = [];
cache.onreload = function (handler) {
    if (handler instanceof Function) _reload_handlers.push(handler);
};
module.exports = cache;<|endoftext|>


<commit_before>'use strict';

/**
 * Schedule
 *
 * Schedule object
 */
class Schedule {
  /**
   * Constructor
   *
   * @param {string} id         Id
   * @param {Object} attributes Attributes
   */
  constructor(id, attributes) {
    attributes.id = id;

    this.attributes = attributes;
  }
}

module.exports = Schedule;
<commit_msg>GitHub #12 - Add supported attributes<commit_after>'use strict';

const ATTRIBUTE_MAP = {
  'id':          'id',
  'name':        'name',
  'description': 'description',
  'command':     'command',
  'localtime':   'localTime',
  'starttime':   'startTime',
  'status':      'status',
  'autodelete':  'autoDelete',
};

/**
 * Schedule
 *
 * Schedule object
 */
class Schedule {
  /**
   * Constructor
   *
   * @param {string} id         Id
   * @param {Object} attributes Attributes
   */
  constructor(id, attributes) {
    attributes.id = id;

    this.attributes = attributes;
  }

  /**
   * Set attributes
   *
   * @param {Object} attributes Attributes
   */
  setAttributes(attributes) {
    this.attributes = {};

    for (let key in attributes) {
      let attributeKey = key;
      if (key in ATTRIBUTE_MAP) {
        this.attributes[ATTRIBUTE_MAP[key]] = attributes[key];
      }
    }
  }
}

module.exports = Schedule;
<|endoftext|>


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

  var helper = app.helper || require('../helper.js');
  var dom = app.dom || require('../dom.js');
  var Component = app.Component || require('./component.js');
  var Content = app.Content || require('./content.js');
  var Sidebar = app.Sidebar || require('./sidebar.js');

  var ModuleData = function(props) {
    this.packageName = props.packageName || '';
    this.label = props.label || '';
    this.description = props.description || '';
    this.src = props.src || '';
    this.visiblePortNames = props.visiblePortNames || [];
  };

  ModuleData.prototype.key = function() {
    return this.packageName + '/' + this.src;
  };

  var ModuleDataCollection = function() {
    this.data = {};
  };

  ModuleDataCollection.prototype.load = function() {
    return this.loadPackageNames().then(function(packageNames) {
      return Promise.all(packageNames.map(function(packageName) {
        return this.loadModuleDatas(packageName).then(function(moduleDatas) {
          moduleDatas.forEach(function(moduleData) {
            this.data[moduleData.key()] = moduleData;
          }.bind(this));
        }.bind(this));
      }.bind(this)));
    }.bind(this));
  };

  ModuleDataCollection.prototype.loadPackageNames = function() {
    return dom.ajax({
      type: 'GET',
      url: 'modular_modules/index.json',
    }).then(function(text) {
      return JSON.parse(text);
    });
  };

  ModuleDataCollection.prototype.loadModuleDatas = function(packageName) {
    return dom.ajax({
      type: 'GET',
      url: 'modular_modules/' + packageName + '/index.json',
    }).then(function(text) {
      return JSON.parse(text).map(function(props) {
        return new ModuleData(helper.extend(helper.clone(props), { packageName: packageName }));
      });
    });
  };

  var Body = helper.inherits(function() {
    Body.super_.call(this, { element: dom.body() });

    this.moduleDataCollection = this.prop(new ModuleDataCollection());
    this.dragCount = this.prop(0);

    this.content = new Content({
      element: dom.el('.content'),
      sidebarCollapser: Body.prototype.sidebarCollapser.bind(this),
      sidebarExpander: Body.prototype.sidebarExpander.bind(this),
      moduleDragStarter: Body.prototype.moduleDragStarter.bind(this),
      moduleDragEnder: Body.prototype.moduleDragEnder.bind(this),
    });

    this.sidebar = new Sidebar({
      element: dom.el('.sidebar'),
      moduleDragStarter: Body.prototype.moduleDragStarter.bind(this),
      moduleDragEnder: Body.prototype.moduleDragEnder.bind(this),
      moduleDropper: Body.prototype.moduleDropper.bind(this),
    });

    dom.ready(Body.prototype.onready.bind(this));
  }, Component);

  Body.prototype.incrementDragCount = function() {
    this.dragCount(this.dragCount() + 1);
  };

  Body.prototype.decrementDragCount = function() {
    this.dragCount(this.dragCount() - 1);
  };

  Body.prototype.redraw = function() {
    this.redrawDragCount();
  };

  Body.prototype.redrawDragCount = function() {
    var dragCount = this.dragCount();
    var cache = this.cache();

    if (dragCount === cache.dragCount) {
      return;
    }

    dom.toggleClass(this.element(), 'module-dragging', dragCount > 0);
    cache.dragCount = dragCount;
  };

  Body.prototype.onready = function() {
    this.content.redraw();
  };

  Body.prototype.sidebarCollapser = function() {
    return new Promise(function(resolve, reject) {
      var element = this.element();

      var ontransitionend = function() {
        dom.off(element, 'transitionend', ontransitionend);
        resolve();
      };

      dom.on(element, 'transitionend', ontransitionend);
      dom.addClass(element, 'no-sidebar');
    }.bind(this));
  };

  Body.prototype.sidebarExpander = function() {
    return new Promise(function(resolve, reject) {
      var element = this.element();

      var ontransitionend = function() {
        dom.off(element, 'transitionend', ontransitionend);
        resolve();
      };

      dom.on(element, 'transitionend', ontransitionend);
      dom.removeClass(element, 'no-sidebar');
    }.bind(this));
  };

  Body.prototype.moduleDragStarter = function() {
    this.incrementDragCount();
  };

  Body.prototype.moduleDragEnder = function() {
    this.decrementDragCount();
  };

  Body.prototype.moduleDropper = function(name, x, y) {
    /* TODO: load dropped module */
  };

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = Body;
  } else {
    app.Body = Body;
  }
})(this.app || (this.app = {}));
<commit_msg>Add method to get module-data<commit_after>(function(app) {
  'use strict';

  var helper = app.helper || require('../helper.js');
  var dom = app.dom || require('../dom.js');
  var Component = app.Component || require('./component.js');
  var Content = app.Content || require('./content.js');
  var Sidebar = app.Sidebar || require('./sidebar.js');

  var ModuleData = function(props) {
    this.packageName = props.packageName || '';
    this.label = props.label || '';
    this.description = props.description || '';
    this.src = props.src || '';
    this.visiblePortNames = props.visiblePortNames || [];
  };

  ModuleData.prototype.key = function() {
    return this.packageName + '/' + this.src;
  };

  var ModuleDataCollection = function() {
    this.data = {};
  };

  ModuleDataCollection.prototype.load = function() {
    return this.loadPackageNames().then(function(packageNames) {
      return Promise.all(packageNames.map(function(packageName) {
        return this.loadModuleDatas(packageName).then(function(moduleDatas) {
          moduleDatas.forEach(function(moduleData) {
            this.data[moduleData.key()] = moduleData;
          }.bind(this));
        }.bind(this));
      }.bind(this)));
    }.bind(this));
  };

  ModuleDataCollection.prototype.loadPackageNames = function() {
    return dom.ajax({
      type: 'GET',
      url: 'modular_modules/index.json',
    }).then(function(text) {
      return JSON.parse(text);
    });
  };

  ModuleDataCollection.prototype.loadModuleDatas = function(packageName) {
    return dom.ajax({
      type: 'GET',
      url: 'modular_modules/' + packageName + '/index.json',
    }).then(function(text) {
      return JSON.parse(text).map(function(props) {
        return new ModuleData(helper.extend(helper.clone(props), { packageName: packageName }));
      });
    });
  };

  ModuleDataCollection.prototype.get = function(key) {
    return this.data[key] || null;
  };

  var Body = helper.inherits(function() {
    Body.super_.call(this, { element: dom.body() });

    this.moduleDataCollection = this.prop(new ModuleDataCollection());
    this.dragCount = this.prop(0);

    this.content = new Content({
      element: dom.el('.content'),
      sidebarCollapser: Body.prototype.sidebarCollapser.bind(this),
      sidebarExpander: Body.prototype.sidebarExpander.bind(this),
      moduleDragStarter: Body.prototype.moduleDragStarter.bind(this),
      moduleDragEnder: Body.prototype.moduleDragEnder.bind(this),
    });

    this.sidebar = new Sidebar({
      element: dom.el('.sidebar'),
      moduleDragStarter: Body.prototype.moduleDragStarter.bind(this),
      moduleDragEnder: Body.prototype.moduleDragEnder.bind(this),
      moduleDropper: Body.prototype.moduleDropper.bind(this),
    });

    dom.ready(Body.prototype.onready.bind(this));
  }, Component);

  Body.prototype.incrementDragCount = function() {
    this.dragCount(this.dragCount() + 1);
  };

  Body.prototype.decrementDragCount = function() {
    this.dragCount(this.dragCount() - 1);
  };

  Body.prototype.redraw = function() {
    this.redrawDragCount();
  };

  Body.prototype.redrawDragCount = function() {
    var dragCount = this.dragCount();
    var cache = this.cache();

    if (dragCount === cache.dragCount) {
      return;
    }

    dom.toggleClass(this.element(), 'module-dragging', dragCount > 0);
    cache.dragCount = dragCount;
  };

  Body.prototype.onready = function() {
    this.content.redraw();
  };

  Body.prototype.sidebarCollapser = function() {
    return new Promise(function(resolve, reject) {
      var element = this.element();

      var ontransitionend = function() {
        dom.off(element, 'transitionend', ontransitionend);
        resolve();
      };

      dom.on(element, 'transitionend', ontransitionend);
      dom.addClass(element, 'no-sidebar');
    }.bind(this));
  };

  Body.prototype.sidebarExpander = function() {
    return new Promise(function(resolve, reject) {
      var element = this.element();

      var ontransitionend = function() {
        dom.off(element, 'transitionend', ontransitionend);
        resolve();
      };

      dom.on(element, 'transitionend', ontransitionend);
      dom.removeClass(element, 'no-sidebar');
    }.bind(this));
  };

  Body.prototype.moduleDragStarter = function() {
    this.incrementDragCount();
  };

  Body.prototype.moduleDragEnder = function() {
    this.decrementDragCount();
  };

  Body.prototype.moduleDropper = function(name, x, y) {
    /* TODO: load dropped module */
  };

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = Body;
  } else {
    app.Body = Body;
  }
})(this.app || (this.app = {}));
<|endoftext|>


<commit_before>'use strict';

var Cesium = require('cesium');
var nconf = require('nconf');
var Promise = require('bluebird');
var fs = require('fs');

var loadRepoConfig = require('./loadRepoConfig');
var RepositorySettings = require('./RepositorySettings');

var defined = Cesium.defined;

var Settings = {};

var repositories = {};

function dumpEnvironment(obj, parentName) {
    var envString = '';
    Object.keys(obj).forEach(function(name) {
        var fullName = parentName === '' ? name : parentName + '__' + name;
        if (typeof obj[name] === 'object') {
            var string = dumpEnvironment(obj[name], fullName);
            envString += string;
        } else {
            envString += fullName + ' = ' + obj[name] + '\n';
        }
    });
    return envString;
}

/** Check for necessary settings in `configPath` file and initialize `nconf`
 *
 * @param {String} configPath Path to configuration file (usually `./config.json`)
 * @return {Promise<undefined | String>} Error message if Promise fails
 */
Settings.loadRepositoriesSettings = function (configPath) {
    nconf.env('__')
        .file({
            file: configPath
        })
        .defaults({
            port: 5000,
            listenPath: '/'
        });

    var repositoryNames;
    var configJson;

    if (!defined(nconf.get('secret'))) {
        return Promise.reject('`secret` key must be defined');
    }
    configJson = nconf.get('repositories');
    if (!defined(configJson)) {
        return Promise.reject('`repositories` key must be defined');
    }
    repositoryNames = Object.keys(configJson);
    if (repositoryNames.length === 0) {
        return Promise.reject('`repositories` must be non-empty');
    }

    // Save the configuration to disk so that cron scripts can read from it
    var environmentString = dumpEnvironment(nconf.get(), '');
    fs.writeFile('saved_env', environmentString);

    return Promise.each(repositoryNames, function (name) {
        if (!/\//.test(name)) {
            return Promise.reject('repository ' + name + ' must be in the form {user}/{repository}');
        }

        var repositorySettings = configJson[name];
        if (!defined(repositorySettings.gitHubToken)) {
            return Promise.reject('repository ' + name + ' must have a `gitHubToken`');
        }

        repositorySettings.name = name;

        return loadRepoConfig(name, {
            'User-Agent': 'cesium-concierge',
            Authorization: 'token ' + repositorySettings.gitHubToken
        }, repositorySettings).then(function (settings) {
            repositories[name] = new RepositorySettings(settings);
        });
    });
};

Object.defineProperties(Settings, {
    /** Path to listen on for incoming GitHub requests
     * @memberOf Settings
     * @type {String}
     */
    listenPath: {
        get: function () {
            return nconf.get('listenPath');
        }
    },
    /** Port to listen on for incoming GitHub requests
     * @memberOf Settings
     * @type {Number}
     */
    port: {
        get: function () {
            return parseInt(nconf.get('port'));
        }
    },
    /** Array of repository settings objects
     * @memberOf Settings
     * @type {Object[]}
     */
    repositories: {
        get: function () {
            return repositories;
        }
    },
    /** Shared secret to verify incoming GitHub requests
     * @memberOf Settings
     * @type {String}
     */
    secret: {
        get: function () {
            return nconf.get('secret');
        }
    }
});

module.exports = Settings;
<commit_msg>Rename obj to object<commit_after>'use strict';

var Cesium = require('cesium');
var nconf = require('nconf');
var Promise = require('bluebird');
var fs = require('fs');

var loadRepoConfig = require('./loadRepoConfig');
var RepositorySettings = require('./RepositorySettings');

var defined = Cesium.defined;

var Settings = {};

var repositories = {};

function dumpEnvironment(object, parentName) {
    var envString = '';
    Object.keys(object).forEach(function(name) {
        var fullName = parentName === '' ? name : parentName + '__' + name;
        if (typeof object[name] === 'object') {
            var string = dumpEnvironment(object[name], fullName);
            envString += string;
        } else {
            envString += fullName + ' = ' + object[name] + '\n';
        }
    });
    return envString;
}

/** Check for necessary settings in `configPath` file and initialize `nconf`
 *
 * @param {String} configPath Path to configuration file (usually `./config.json`)
 * @return {Promise<undefined | String>} Error message if Promise fails
 */
Settings.loadRepositoriesSettings = function (configPath) {
    nconf.env('__')
        .file({
            file: configPath
        })
        .defaults({
            port: 5000,
            listenPath: '/'
        });

    var repositoryNames;
    var configJson;

    if (!defined(nconf.get('secret'))) {
        return Promise.reject('`secret` key must be defined');
    }
    configJson = nconf.get('repositories');
    if (!defined(configJson)) {
        return Promise.reject('`repositories` key must be defined');
    }
    repositoryNames = Object.keys(configJson);
    if (repositoryNames.length === 0) {
        return Promise.reject('`repositories` must be non-empty');
    }

    // Save the configuration to disk so that cron scripts can read from it
    var environmentString = dumpEnvironment(nconf.get(), '');
    fs.writeFile('saved_env', environmentString);

    return Promise.each(repositoryNames, function (name) {
        if (!/\//.test(name)) {
            return Promise.reject('repository ' + name + ' must be in the form {user}/{repository}');
        }

        var repositorySettings = configJson[name];
        if (!defined(repositorySettings.gitHubToken)) {
            return Promise.reject('repository ' + name + ' must have a `gitHubToken`');
        }

        repositorySettings.name = name;

        return loadRepoConfig(name, {
            'User-Agent': 'cesium-concierge',
            Authorization: 'token ' + repositorySettings.gitHubToken
        }, repositorySettings).then(function (settings) {
            repositories[name] = new RepositorySettings(settings);
        });
    });
};

Object.defineProperties(Settings, {
    /** Path to listen on for incoming GitHub requests
     * @memberOf Settings
     * @type {String}
     */
    listenPath: {
        get: function () {
            return nconf.get('listenPath');
        }
    },
    /** Port to listen on for incoming GitHub requests
     * @memberOf Settings
     * @type {Number}
     */
    port: {
        get: function () {
            return parseInt(nconf.get('port'));
        }
    },
    /** Array of repository settings objects
     * @memberOf Settings
     * @type {Object[]}
     */
    repositories: {
        get: function () {
            return repositories;
        }
    },
    /** Shared secret to verify incoming GitHub requests
     * @memberOf Settings
     * @type {String}
     */
    secret: {
        get: function () {
            return nconf.get('secret');
        }
    }
});

module.exports = Settings;
<|endoftext|>


<commit_before>var colors = ["blue", "red", "white", "gold"];
var names = ["Lucas", "Ivan", "Frida", "Bella"];

colors.push("pink")
names.push("Hiedi")

var horseObject = {},
    i,
    keys =  names //['one', 'two', 'three'],
    values = colors  //['a', 'b', 'c'];

for (i = 0; i < keys.length; i++) {
    horseObject[keys[i]] = values[i];
    horseObject
}

//for (var i = 0; i < colors.length; i++) {
//	console.log(colors[i]);
//}

//console.log("Like my coat, my horses have many colors " + names['name'] + "-" + colors['colors']);<commit_msg>added new contructor function to create car<commit_after>var colors = ["blue", "red", "white", "gold"];
var names = ["Lucas", "Ivan", "Frida", "Bella"];

colors.push("pink")
names.push("Hiedi")

var horseObject = {},
    i,
    keys =  names //['one', 'two', 'three'],
    values = colors  //['a', 'b', 'c'];

for (i = 0; i < keys.length; i++) {
    horseObject[keys[i]] = values[i];
    horseObject
}

//for (var i = 0; i < colors.length; i++) {
//	console.log(colors[i]);
//}

//console.log("Like my coat, my horses have many colors " + names['name'] + "-" + colors['colors']);

//============CAR=======================

var car = {model: 'Spot', year: 3, topSpeed: "100mph"};

function Car(model, year, topSpeed) {
	console.log("Our new car:", this);
	this.go = function() { console.log("Vrrrm!"); };

	console.log("CAR INITIALIZATION COMPLETE");
}
console.log("Let's build a new car ...");
// Here is where we call that constructor function
// that we just made ...
var anotherCar = new Car("Mustang", 2016, "145mph");
console.log(anotherCar);
console.log("Our new car can go:");
anotherCar.go();
console.log("----");

console.log("Let's build another car ...");
var yetAnotherCar = new Car("280z", 1978, "155mph");
//not printing out new model, NEED TO FIX
console.log(yetAnotherCar.model);
console.log("This new dog can go, too:");
yetAnotherCar.go();
console.log("----");

//NEED TO ADD driver code<|endoftext|>


<commit_before>//= require "codemirror"
//= require "mobileCodeMirror"
//= require "library"
//= require "unsaved"
var focusPanel = 'javascript';
var editors = {};
var row = {};
var sql = new Array();

window.editors = editors;

editors.html = CodeMirror.fromTextArea(document.getElementById('html'), {
  parserfile: [],
  tabMode: 'shift',
  mode: 'text/html',
  onChange: changecontrol,
  theme: "eclipse",
  indentUnit: 4,
  lineNumbers: true
});

editors.javascript = CodeMirror.fromTextArea(document.getElementById('javascript'), {
  mode: 'css',
  tabMode: 'shift',
  onChange: changecontrol,
  theme: "eclipse",
  matchBrackets: true,
  indentUnit: 4,
  lineNumbers: true
});

setupEditor('javascript');
setupEditor('html');

var editorsReady = setInterval(function () {
  if (editors.html.ready && editors.javascript.ready) {

    editors.html.setCursor(7, 8);

    clearInterval(editorsReady);
    editors.ready = true;
    if (typeof editors.onReady == 'function') editors.onReady();

    var scrollers = {
      html: $(editors.html.getScrollerElement()),
      javascript: $(editors.javascript.getScrollerElement())
    };

    $document.bind('sizeeditors', function () {
      var top = 0, //$el.offset().top,
          height = $('#bin').height();
      scrollers.html.height(height - top);
      scrollers.javascript.height(height - top - $error.filter(':visible').height());
      editors.javascript.refresh();
      editors.html.refresh();
    });

    $(window).resize(function () {
      setTimeout(function () {
        $document.trigger('sizeeditors');
      }, 100);
    });

    $document.trigger('sizeeditors');
    $document.trigger('jsbinReady');
  }
}, 100);

// $('#javascript').replaceWith('

');
// $('#javascript').css({ height: '100%', width: '100%' });
// $('#html').replaceWith('

');
// $('#html').css({ height: '100%', width: '100%' });
//
// editors.javascript = ace.edit("javascript");
// editors.html = ace.edit("html");
//
// var JavaScriptMode = require("ace/mode/javascript").Mode,
//     HTMLMode = require("ace/mode/html").Mode;
//
// setupAce(editors, 'javascript');
// setupAce(editors, 'html');
//
// function setupAce(editor, type) {
//   var session = editors[type].getSession(),
//       renderer = editors[type].renderer;
//   if (type == 'javascript') {
//     session.setMode(new JavaScriptMode());
//   } else {
//     session.setMode(new HTMLMode());
//   }
//
//   editors[type].setHighlightActiveLine(false);
//   session.setUseWrapMode(true);
//   session.setUseSoftTabs(true);
//   session.setWrapLimitRange(null, null);
//
//   renderer.setShowPrintMargin(false);
//   renderer.setShowGutter(false);
//   renderer.setHScrollBarAlwaysVisible(false);
// }

function focused(editor, event) {
  focusPanel = editor.id;
  snapshot(focusPanel);
  console.log(focusPanel);
}

function getFocusedPanel() {
  return focusPanel;
}

function setupEditor(panel) {
  var e = editors[panel],
      focusedPanel = sessionStorage.getItem('panel');

  // overhang from CodeMirror1
  e.setCode = function (str) {
    e.setValue(str);
  };

  e.getCode = function () {
    return e.getValue();
  };

  e.currentLine = function () {
    var pos = e.getCursor();
    return pos.line;
  };

  e.setOption('onChange', changecontrol);
  e.setOption('onKeyEvent', keycontrol);
  e.setOption('onFocus', focused);

  e.id = panel;

  e.win = e.getWrapperElement();
  e.scroller = $(e.getScrollerElement());

  $(e.win).click(function () {
    e.focus();
  });

  var $label = $('.code.' + panel + ' > .label');
  if (document.body.className.indexOf('ie6') === -1) {
    e.scroller.scroll(function (event) {
      if (this.scrollTop > 10) {
        $label.stop().animate({ opacity: 0 }, 50, function () {
          $(this).hide();
        });
      } else {
        $label.show().stop().animate({ opacity: 1 }, 250);
      }
    });
  }

  populateEditor(panel);
  e.ready = true;

  if (focusedPanel == panel || focusedPanel == null && panel == 'javascript') {
    // e.selectLines(e.nthLine(sessionStorage.getItem('line')), sessionStorage.getItem('character'));
    e.focus();
    e.setCursor({ line: (sessionStorage.getItem('line') || 0) * 1, ch: (sessionStorage.getItem('character') || 0) * 1 });
  }
}

function populateEditor(panel) {
  // populate - should eventually use: session, saved data, local storage
  var data = sessionStorage.getItem(panel), // session code
      saved = localStorage.getItem('saved-' + panel), // user template
      sessionURL = sessionStorage.getItem('url'),
      changed = false;

  if (data == template[panel]) { // restored from original saved
    editors[panel].setCode(data);
  } else if (data && sessionURL == template.url) { // try to restore the session first - only if it matches this url
    editors[panel].setCode(data);
    // tell the document that it's currently being edited, but check that it doesn't match the saved template
    // because sessionStorage gets set on a reload
    changed = data != saved;
  } else if (saved !== null && !/edit/.test(window.location) && !window.location.search) { // then their saved preference
    editors[panel].setCode(saved);
  } else { // otherwise fall back on the JS Bin default
    editors[panel].setCode(template[panel]);
  }

  if (changed) {
    $(document).trigger('codeChange', [ /* revert triggered */ false, /* don't use fade */ true ]);
  }
}

// work out the browser platform
var ua = navigator.userAgent;
if (/macintosh|mac os x/.test(ua)) {
  $.browser.platform = 'mac';
} else if (/windows|win32/.test(ua)) {
  $.browser.platform = 'win';
} else if (/linux/.test(ua)) {
  $.browser.platform = 'linux';
} else {
  $.browser.platform = '';
}

//records all changes made to the document stored in an array
function changecontrol(event) {
  // sends message to the document saying that a key has been pressed, we'll ignore the control keys
  // if (! ({ 16:1, 17:1, 18:1, 20:1, 27:1, 37:1, 38:1, 39:1, 40:1, 91:1, 93:1 })[event.which] ) {
    $(document).trigger('codeChange');

    snapshot();
  // }

  return true;
}

function roughSizeOfObject(object) {

    var objectList = [];
    var stack = [object];
    var bytes = 0;

    while ( stack.length ) {
        var value = stack.pop();

        if ( typeof value === 'boolean' ) {
            bytes += 4;
        }
        else if ( typeof value === 'string' ) {
            bytes += value.length * 2;
        }
        else if ( typeof value === 'number' ) {
            bytes += 8;
        }
        else if
        (
            typeof value === 'object'
            && objectList.indexOf(value) === -1
        )
        {
            objectList.push( value );
            for (var i in value) {
                try {
                    if (i == 'Blob') bytes += value[i].size || 0;
                    stack.push(value[i]);
                    stack.push(i);
                } catch(e) {};
            };
        }
    }
    return bytes;
  }

function snapshot(extra){
    var html = editors['html'];
    var css = editors['javascript'];
    var time = new Date();
    row.clock = time.getTime();
    row.html = html.getValue();
    row.css= css.getValue();
    row.special = extra;
    sql.push(JSON.stringify(row));
    console.log('SQL Size: '+roughSizeOfObject(sql));
    console.log('SQL Length: '+sql.length);
    console.log(sql);
}

//= require "keycontrol"

<commit_msg>debug logs<commit_after>//= require "codemirror"
//= require "mobileCodeMirror"
//= require "library"
//= require "unsaved"
var focusPanel = 'javascript';
var editors = {};
var row = {};
var sql = new Array();

window.editors = editors;

editors.html = CodeMirror.fromTextArea(document.getElementById('html'), {
  parserfile: [],
  tabMode: 'shift',
  mode: 'text/html',
  onChange: changecontrol,
  theme: "eclipse",
  indentUnit: 4,
  lineNumbers: true
});

editors.javascript = CodeMirror.fromTextArea(document.getElementById('javascript'), {
  mode: 'css',
  tabMode: 'shift',
  onChange: changecontrol,
  theme: "eclipse",
  matchBrackets: true,
  indentUnit: 4,
  lineNumbers: true
});

setupEditor('javascript');
setupEditor('html');

var editorsReady = setInterval(function () {
  if (editors.html.ready && editors.javascript.ready) {

    editors.html.setCursor(7, 8);

    clearInterval(editorsReady);
    editors.ready = true;
    if (typeof editors.onReady == 'function') editors.onReady();

    var scrollers = {
      html: $(editors.html.getScrollerElement()),
      javascript: $(editors.javascript.getScrollerElement())
    };

    $document.bind('sizeeditors', function () {
      var top = 0, //$el.offset().top,
          height = $('#bin').height();
      scrollers.html.height(height - top);
      scrollers.javascript.height(height - top - $error.filter(':visible').height());
      editors.javascript.refresh();
      editors.html.refresh();
    });

    $(window).resize(function () {
      setTimeout(function () {
        $document.trigger('sizeeditors');
      }, 100);
    });

    $document.trigger('sizeeditors');
    $document.trigger('jsbinReady');
  }
}, 100);

// $('#javascript').replaceWith('

');
// $('#javascript').css({ height: '100%', width: '100%' });
// $('#html').replaceWith('

');
// $('#html').css({ height: '100%', width: '100%' });
//
// editors.javascript = ace.edit("javascript");
// editors.html = ace.edit("html");
//
// var JavaScriptMode = require("ace/mode/javascript").Mode,
//     HTMLMode = require("ace/mode/html").Mode;
//
// setupAce(editors, 'javascript');
// setupAce(editors, 'html');
//
// function setupAce(editor, type) {
//   var session = editors[type].getSession(),
//       renderer = editors[type].renderer;
//   if (type == 'javascript') {
//     session.setMode(new JavaScriptMode());
//   } else {
//     session.setMode(new HTMLMode());
//   }
//
//   editors[type].setHighlightActiveLine(false);
//   session.setUseWrapMode(true);
//   session.setUseSoftTabs(true);
//   session.setWrapLimitRange(null, null);
//
//   renderer.setShowPrintMargin(false);
//   renderer.setShowGutter(false);
//   renderer.setHScrollBarAlwaysVisible(false);
// }

function focused(editor, event) {
  focusPanel = editor.id;
  snapshot(focusPanel);
  console.log(focusPanel);
}

function getFocusedPanel() {
  return focusPanel;
}

function setupEditor(panel) {
  var e = editors[panel],
      focusedPanel = sessionStorage.getItem('panel');

  // overhang from CodeMirror1
  e.setCode = function (str) {
    e.setValue(str);
  };

  e.getCode = function () {
    return e.getValue();
  };

  e.currentLine = function () {
    var pos = e.getCursor();
    return pos.line;
  };

  e.setOption('onChange', changecontrol);
  e.setOption('onKeyEvent', keycontrol);
  e.setOption('onFocus', focused);

  e.id = panel;

  e.win = e.getWrapperElement();
  e.scroller = $(e.getScrollerElement());

  $(e.win).click(function () {
    e.focus();
  });

  var $label = $('.code.' + panel + ' > .label');
  if (document.body.className.indexOf('ie6') === -1) {
    e.scroller.scroll(function (event) {
      if (this.scrollTop > 10) {
        $label.stop().animate({ opacity: 0 }, 50, function () {
          $(this).hide();
        });
      } else {
        $label.show().stop().animate({ opacity: 1 }, 250);
      }
    });
  }

  populateEditor(panel);
  e.ready = true;

  if (focusedPanel == panel || focusedPanel == null && panel == 'javascript') {
    // e.selectLines(e.nthLine(sessionStorage.getItem('line')), sessionStorage.getItem('character'));
    e.focus();
    e.setCursor({ line: (sessionStorage.getItem('line') || 0) * 1, ch: (sessionStorage.getItem('character') || 0) * 1 });
  }
}

function populateEditor(panel) {
  // populate - should eventually use: session, saved data, local storage
  var data = sessionStorage.getItem(panel), // session code
      saved = localStorage.getItem('saved-' + panel), // user template
      sessionURL = sessionStorage.getItem('url'),
      changed = false;

  if (data == template[panel]) { // restored from original saved
    editors[panel].setCode(data);
  } else if (data && sessionURL == template.url) { // try to restore the session first - only if it matches this url
    editors[panel].setCode(data);
    // tell the document that it's currently being edited, but check that it doesn't match the saved template
    // because sessionStorage gets set on a reload
    changed = data != saved;
  } else if (saved !== null && !/edit/.test(window.location) && !window.location.search) { // then their saved preference
    editors[panel].setCode(saved);
  } else { // otherwise fall back on the JS Bin default
    editors[panel].setCode(template[panel]);
  }

  if (changed) {
    $(document).trigger('codeChange', [ /* revert triggered */ false, /* don't use fade */ true ]);
  }
}

// work out the browser platform
var ua = navigator.userAgent;
if (/macintosh|mac os x/.test(ua)) {
  $.browser.platform = 'mac';
} else if (/windows|win32/.test(ua)) {
  $.browser.platform = 'win';
} else if (/linux/.test(ua)) {
  $.browser.platform = 'linux';
} else {
  $.browser.platform = '';
}

//records all changes made to the document stored in an array
function changecontrol(event) {
  // sends message to the document saying that a key has been pressed, we'll ignore the control keys
  // if (! ({ 16:1, 17:1, 18:1, 20:1, 27:1, 37:1, 38:1, 39:1, 40:1, 91:1, 93:1 })[event.which] ) {
    $(document).trigger('codeChange');
    if(sql.length > 20){
      saveSnaps();
    }

    snapshot();
  // }

  return true;
}

function roughSizeOfObject(object) {

    var objectList = [];
    var stack = [object];
    var bytes = 0;

    while ( stack.length ) {
        var value = stack.pop();

        if ( typeof value === 'boolean' ) {
            bytes += 4;
        }
        else if ( typeof value === 'string' ) {
            bytes += value.length * 2;
        }
        else if ( typeof value === 'number' ) {
            bytes += 8;
        }
        else if
        (
            typeof value === 'object'
            && objectList.indexOf(value) === -1
        )
        {
            objectList.push( value );
            for (var i in value) {
                try {
                    if (i == 'Blob') bytes += value[i].size || 0;
                    stack.push(value[i]);
                    stack.push(i);
                } catch(e) {};
            };
        }
    }
    return bytes;
  }

function snapshot(extra){
    var html = editors['html'];
    var css = editors['javascript'];
    var time = new Date();
    row.clock = time.getTime();
    row.html = html.getValue();
    row.css= css.getValue();
    row.special = extra;
    sql.push(JSON.stringify(row));
    console.log('SQL Size: '+roughSizeOfObject(sql));
   console.log('SQL Length: '+sql.length);

}

//= require "keycontrol"

<|endoftext|>


<commit_before>var $revert = $('#revert'); //.next().addClass('left').end();
$(document).bind('codeChange', function (event, revert, onload) {
  if (revert == undefined) {
    revert = false;
  } else {
    $revert.removeClass('enable');
  }

  updateTitle(revert, onload);
});

function updateTitle(revert, onload) {
  var title = !documentTitle ? 'JS Bin' : documentTitle;
  if (jsbin.settings.home) title = jsbin.settings.home + '@' + title;
  if (jsbin.panels.ready) {
    if (!revert) {
      document.title = title + ' [unsaved]';
      if ($revert.addClass('enable').is(':hidden')) {
        $revert[onload ? 'show' : 'fadeIn']().next().removeClass('left');
      }
    } else {
      document.title = title;
    }
  }
}
<commit_msg>Trying to bring revert back to life (not quite working yet)<commit_after>var $revert = $('#revert');

$(document).bind('codeChange', function (event, options) { //, revert, onload) {
  options || (options = {});

  if (options.revert == undefined) {
    revert = false;
  } else {
    $revert.removeClass('enable');
    revert = options.revert;
  }

  updateTitle(revert, options.onload);
});

function updateTitle(revert, onload) {
  console.log('revert required? ' + revert);
  var title = !documentTitle ? 'JS Bin' : documentTitle;
  if (jsbin.settings.home) title = jsbin.settings.home + '@' + title;
  if (!revert) {
    document.title = title + ' [unsaved]';
    if ($revert.addClass('enable').is(':hidden')) {
      $revert[onload ? 'show' : 'fadeIn']().next().removeClass('left');
    }
  } else {
    document.title = title;
  }
}
<|endoftext|>