<commit_before>#!/usr/bin/env node
"use strict";

const fs = require("fs");
const path = require("path");
const x86_table = require("./x86_table");
const rust_ast = require("./rust_ast");
const { hex, mkdirpSync, get_switch_value, get_switch_exist, finalize_table_rust } = require("./util");

const OUT_DIR = path.join(__dirname, "..", "src/rust/gen/");

mkdirpSync(OUT_DIR);

const table_arg = get_switch_value("--table");
const gen_all = get_switch_exist("--all");
const to_generate = {
    interpreter: gen_all || table_arg === "interpreter",
    interpreter0f_16: gen_all || table_arg === "interpreter0f_16",
    interpreter0f_32: gen_all || table_arg === "interpreter0f_32",
};

console.assert(
    Object.keys(to_generate).some(k => to_generate[k]),
    "Pass --table [interpreter|interpreter0f_16|interpreter0f_32] or --all to pick which tables to generate"
);

gen_table();

function wrap_imm_call(imm)
{
    return `match ${imm} { Ok(o) => o, Err(()) => return }`;
}

function gen_read_imm_call(op, size_variant)
{
    let size = (op.os || op.opcode % 2 === 1) ? size_variant : 8;

    if(op.imm8 || op.imm8s || op.imm16 || op.imm1632 || op.imm32 || op.immaddr)
    {
        if(op.imm8)
        {
            return wrap_imm_call("read_imm8()");
        }
        else if(op.imm8s)
        {
            return wrap_imm_call("read_imm8s()");
        }
        else
        {
            if(op.immaddr)
            {
                // immaddr: depends on address size
                return wrap_imm_call("read_moffs()");
            }
            else
            {
                console.assert(op.imm1632 || op.imm16 || op.imm32);

                if(op.imm1632 && size === 16 || op.imm16)
                {
                    return wrap_imm_call("read_imm16()");
                }
                else
                {
                    console.assert(op.imm1632 && size === 32 || op.imm32);
                    return wrap_imm_call("read_imm32s()");
                }
            }
        }
    }
    else
    {
        return undefined;
    }
}

function gen_call(name, args)
{
    args = args || [];
    return `${name}(${args.join(", ")});`;
}

/*
 * Current naming scheme:
 * instr(16|32|)_(66|F2|F3)?0F?[0-9a-f]{2}(_[0-7])?(_mem|_reg|)
 */
function make_instruction_name(encoding, size)
{
    const suffix = encoding.os ? String(size) : "";
    const opcode_hex = hex(encoding.opcode & 0xFF, 2);
    const first_prefix = (encoding.opcode & 0xFF00) === 0 ? "" : hex(encoding.opcode >> 8 & 0xFF, 2);
    const second_prefix = (encoding.opcode & 0xFF0000) === 0 ? "" : hex(encoding.opcode >> 16 & 0xFF, 2);
    const fixed_g_suffix = encoding.fixed_g === undefined ? "" : `_${encoding.fixed_g}`;

    console.assert(first_prefix === "" || first_prefix === "0F" || first_prefix === "F2" || first_prefix === "F3");
    console.assert(second_prefix === "" || second_prefix === "66" || second_prefix === "F2" || second_prefix === "F3");

    return `instr${suffix}_${second_prefix}${first_prefix}${opcode_hex}${fixed_g_suffix}`;
}

function gen_instruction_body(encodings, size)
{
    const encoding = encodings[0];

    let has_66 = [];
    let has_F2 = [];
    let has_F3 = [];
    let no_prefix = [];

    for(let e of encodings)
    {
        if((e.opcode >>> 16) === 0x66) has_66.push(e);
        else if((e.opcode >>> 8 & 0xFF) === 0xF2 || (e.opcode >>> 16) === 0xF2) has_F2.push(e);
        else if((e.opcode >>> 8 & 0xFF) === 0xF3 || (e.opcode >>> 16) === 0xF3) has_F3.push(e);
        else no_prefix.push(e);
    }

    if(has_F2.length || has_F3.length)
    {
        console.assert((encoding.opcode & 0xFF0000) === 0 || (encoding.opcode & 0xFF00) === 0x0F00);
    }

    if(has_66.length)
    {
        console.assert((encoding.opcode & 0xFF00) === 0x0F00);
    }

    const code = [];

    if(encoding.e)
    {
        code.push(`let modrm_byte = ${wrap_imm_call("read_imm8()")};`);
    }

    if(has_66.length || has_F2.length || has_F3.length)
    {
        const if_blocks = [];

        if(has_66.length) {
            const body = gen_instruction_body_after_prefix(has_66, size);
            if_blocks.push({ condition: "prefixes_ & PREFIX_66 != 0", body, });
        }
        if(has_F2.length) {
            const body = gen_instruction_body_after_prefix(has_F2, size);
            if_blocks.push({ condition: "prefixes_ & PREFIX_F2 != 0", body, });
        }
        if(has_F3.length) {
            const body = gen_instruction_body_after_prefix(has_F3, size);
            if_blocks.push({ condition: "prefixes_ & PREFIX_F3 != 0", body, });
        }

        const check_prefixes = encoding.sse ? "(PREFIX_66 | PREFIX_F2 | PREFIX_F3)" : "(PREFIX_F2 | PREFIX_F3)";

        const else_block = {
            body: [].concat(
                "dbg_assert!((prefixes_ & " + check_prefixes + ") == 0);",
                gen_instruction_body_after_prefix(no_prefix, size)
            )
        };

        return [].concat(
	    "let prefixes_ = *prefixes as i32;",
            code,
            {
                type: "if-else",
                if_blocks,
                else_block,
            }
        );
    }
    else {
        return [].concat(
            code,
            gen_instruction_body_after_prefix(encodings, size)
        );
    }
}

function gen_instruction_body_after_prefix(encodings, size)
{
    const encoding = encodings[0];

    if(encoding.fixed_g !== undefined)
    {
        console.assert(encoding.e);

        // instruction with modrm byte where the middle 3 bits encode the instruction

        // group by opcode without prefix plus middle bits of modrm byte
        let cases = encodings.reduce((cases_by_opcode, case_) => {
            console.assert(typeof case_.fixed_g === "number");
            cases_by_opcode[case_.opcode & 0xFFFF | case_.fixed_g << 16] = case_;
            return cases_by_opcode;
        }, Object.create(null));
        cases = Object.values(cases).sort((e1, e2) => e1.fixed_g - e2.fixed_g);

        return [
            {
                type: "switch",
                condition: "modrm_byte >> 3 & 7",
                cases: cases.map(case_ => {
                    const fixed_g = case_.fixed_g;
                    const body = gen_instruction_body_after_fixed_g(case_, size);

                    return {
                        conditions: [fixed_g],
                        body,
                    };
                }),

                default_case: {
                    body: [
                        "assert!(false);",
                        "trigger_ud();",
                    ],
                }
            },
        ];
    }
    else {
        console.assert(encodings.length === 1);
        return gen_instruction_body_after_fixed_g(encodings[0], size);
    }
}

function gen_instruction_body_after_fixed_g(encoding, size)
{
    const instruction_prefix = [];
    const instruction_postfix = encoding.block_boundary ? ["after_block_boundary();"] : [];

    if(encoding.task_switch_test || encoding.sse)
    {
        instruction_prefix.push(
            {
                type: "if-else",
                if_blocks: [
                    {
                        condition: encoding.sse ? "!task_switch_test_mmx()" : "!task_switch_test()",
                        body: ["return;"],
                    }
                ],
            });
    }

    const imm_read = gen_read_imm_call(encoding, size);
    const instruction_name = make_instruction_name(encoding, size);

    if(encoding.e)
    {
        // instruction with modrm byte

        const instruction_name = make_instruction_name(encoding, size);

        const imm_read = gen_read_imm_call(encoding, size);

        if(encoding.ignore_mod)
        {
            console.assert(!imm_read, "Unexpected instruction (ignore mod with immediate value)");

            // Has modrm byte, but the 2 mod bits are ignored and both
            // operands are always registers (0f20-0f24)

            return [].concat(
                instruction_prefix,
                gen_call(instruction_name, ["modrm_byte & 7", "modrm_byte >> 3 & 7"]),
                instruction_postfix
            );
        }
        else
        {
            let mem_args;

            if(encoding.custom_modrm_resolve)
            {
                // requires special handling around modrm_resolve
                mem_args = ["modrm_byte"];
            }
            else
            {
                mem_args = ["match modrm_resolve(modrm_byte) { Ok(a) => a, Err(()) => return }"];
            }

            const reg_args = ["modrm_byte & 7"];

            if(encoding.fixed_g === undefined)
            {
                mem_args.push("modrm_byte >> 3 & 7");
                reg_args.push("modrm_byte >> 3 & 7");
            }

            if(imm_read)
            {
                mem_args.push(imm_read);
                reg_args.push(imm_read);
            }

            return [].concat(
                instruction_prefix,
                {
                    type: "if-else",
                    if_blocks: [
                        {
                            condition: "modrm_byte < 0xC0",
                            body: [].concat(
                                gen_call(`${instruction_name}_mem`, mem_args)
                            ),
                        }
                    ],
                    else_block: {
                        body: [gen_call(`${instruction_name}_reg`, reg_args)],
                    },
                },
                instruction_postfix
            );
        }
    }
    else
    {
        const args = [];

        if(imm_read)
        {
            args.push(imm_read);
        }

        if(encoding.extra_imm16)
        {
            console.assert(imm_read);
            args.push(wrap_imm_call("read_imm16()"));
        }
        else if(encoding.extra_imm8)
        {
            console.assert(imm_read);
            args.push(wrap_imm_call("read_imm8()"));
        }

        return [].concat(
            instruction_prefix,
            gen_call(instruction_name, args),
            instruction_postfix
        );
    }
}

function gen_table()
{
    let by_opcode = Object.create(null);
    let by_opcode0f = Object.create(null);

    for(let o of x86_table)
    {
        let opcode = o.opcode;

        if((opcode & 0xFF00) === 0x0F00)
        {
            opcode &= 0xFF;
            by_opcode0f[opcode] = by_opcode0f[opcode] || [];
            by_opcode0f[opcode].push(o);
        }
        else
        {
            opcode &= 0xFF;
            by_opcode[opcode] = by_opcode[opcode] || [];
            by_opcode[opcode].push(o);
        }
    }

    let cases = [];
    for(let opcode = 0; opcode < 0x100; opcode++)
    {
        let encoding = by_opcode[opcode];
        console.assert(encoding && encoding.length);

        let opcode_hex = hex(opcode, 2);
        let opcode_high_hex = hex(opcode | 0x100, 2);

        if(encoding[0].os)
        {
            cases.push({
                conditions: [`0x${opcode_hex}`],
                body: gen_instruction_body(encoding, 16),
            });
            cases.push({
                conditions: [`0x${opcode_high_hex}`],
                body: gen_instruction_body(encoding, 32),
            });
        }
        else
        {
            cases.push({
                conditions: [`0x${opcode_hex}`, `0x${opcode_high_hex}`],
                body: gen_instruction_body(encoding, undefined),
            });
        }
    }
    const table = {
        type: "switch",
        condition: "opcode",
        cases,
        default_case: {
            body: ["assert!(false);"]
        },
    };
    if(to_generate.interpreter)
    {
        const code = [
            "#![cfg_attr(rustfmt, rustfmt_skip)]",

            "use cpu2::cpu::*;",
            "use cpu2::instructions::*;",
            "use cpu2::global_pointers::*;",

            "pub unsafe fn run(opcode: u32) {",
            table,
            "}",
        ];

        finalize_table_rust(
            OUT_DIR,
            "interpreter.rs",
            rust_ast.print_syntax_tree([].concat(code)).join("\n") + "\n"
        );
    }

    const cases0f_16 = [];
    const cases0f_32 = [];
    for(let opcode = 0; opcode < 0x100; opcode++)
    {
        let encoding = by_opcode0f[opcode];

        console.assert(encoding && encoding.length);

        let opcode_hex = hex(opcode, 2);

        if(encoding[0].os)
        {
            cases0f_16.push({
                conditions: [`0x${opcode_hex}`],
                body: gen_instruction_body(encoding, 16),
            });
            cases0f_32.push({
                conditions: [`0x${opcode_hex}`],
                body: gen_instruction_body(encoding, 32),
            });
        }
        else
        {
            let block = {
                conditions: [`0x${opcode_hex}`],
                body: gen_instruction_body(encoding, undefined),
            };
            cases0f_16.push(block);
            cases0f_32.push(block);
        }
    }

    const table0f_16 = {
        type: "switch",
        condition: "opcode",
        cases: cases0f_16,
        default_case: {
            body: ["assert!(false);"]
        },
    };
    const table0f_32 = {
        type: "switch",
        condition: "opcode",
        cases: cases0f_32,
        default_case: {
            body: ["assert!(false);"]
        },
    };

    if(to_generate.interpreter0f_16)
    {
        const code = [
            "#![cfg_attr(rustfmt, rustfmt_skip)]",

            "use cpu2::cpu::*;",
            "use cpu2::instructions_0f::*;",
            "use cpu2::global_pointers::*;",

            "pub unsafe fn run(opcode: u8) {",
            table0f_16,
            "}",
        ];

        finalize_table_rust(
            OUT_DIR,
            "interpreter0f_16.rs",
            rust_ast.print_syntax_tree([].concat(code)).join("\n") + "\n"
        );
    }

    if(to_generate.interpreter0f_32)
    {
        const code = [
            "#![cfg_attr(rustfmt, rustfmt_skip)]",

            "use cpu2::cpu::*;",
            "use cpu2::instructions_0f::*;",
            "use cpu2::global_pointers::*;",

            "pub unsafe fn run(opcode: u8) {",
            table0f_32,
            "}",
        ];

        finalize_table_rust(
            OUT_DIR,
            "interpreter0f_32.rs",
            rust_ast.print_syntax_tree([].concat(code)).join("\n") + "\n"
        );
    }
}
<commit_msg>Interpreter detect same block boundaries as jit/analyzer<commit_after>#!/usr/bin/env node
"use strict";

const fs = require("fs");
const path = require("path");
const x86_table = require("./x86_table");
const rust_ast = require("./rust_ast");
const { hex, mkdirpSync, get_switch_value, get_switch_exist, finalize_table_rust } = require("./util");

const OUT_DIR = path.join(__dirname, "..", "src/rust/gen/");

mkdirpSync(OUT_DIR);

const table_arg = get_switch_value("--table");
const gen_all = get_switch_exist("--all");
const to_generate = {
    interpreter: gen_all || table_arg === "interpreter",
    interpreter0f_16: gen_all || table_arg === "interpreter0f_16",
    interpreter0f_32: gen_all || table_arg === "interpreter0f_32",
};

console.assert(
    Object.keys(to_generate).some(k => to_generate[k]),
    "Pass --table [interpreter|interpreter0f_16|interpreter0f_32] or --all to pick which tables to generate"
);

gen_table();

function wrap_imm_call(imm)
{
    return `match ${imm} { Ok(o) => o, Err(()) => return }`;
}

function gen_read_imm_call(op, size_variant)
{
    let size = (op.os || op.opcode % 2 === 1) ? size_variant : 8;

    if(op.imm8 || op.imm8s || op.imm16 || op.imm1632 || op.imm32 || op.immaddr)
    {
        if(op.imm8)
        {
            return wrap_imm_call("read_imm8()");
        }
        else if(op.imm8s)
        {
            return wrap_imm_call("read_imm8s()");
        }
        else
        {
            if(op.immaddr)
            {
                // immaddr: depends on address size
                return wrap_imm_call("read_moffs()");
            }
            else
            {
                console.assert(op.imm1632 || op.imm16 || op.imm32);

                if(op.imm1632 && size === 16 || op.imm16)
                {
                    return wrap_imm_call("read_imm16()");
                }
                else
                {
                    console.assert(op.imm1632 && size === 32 || op.imm32);
                    return wrap_imm_call("read_imm32s()");
                }
            }
        }
    }
    else
    {
        return undefined;
    }
}

function gen_call(name, args)
{
    args = args || [];
    return `${name}(${args.join(", ")});`;
}

/*
 * Current naming scheme:
 * instr(16|32|)_(66|F2|F3)?0F?[0-9a-f]{2}(_[0-7])?(_mem|_reg|)
 */
function make_instruction_name(encoding, size)
{
    const suffix = encoding.os ? String(size) : "";
    const opcode_hex = hex(encoding.opcode & 0xFF, 2);
    const first_prefix = (encoding.opcode & 0xFF00) === 0 ? "" : hex(encoding.opcode >> 8 & 0xFF, 2);
    const second_prefix = (encoding.opcode & 0xFF0000) === 0 ? "" : hex(encoding.opcode >> 16 & 0xFF, 2);
    const fixed_g_suffix = encoding.fixed_g === undefined ? "" : `_${encoding.fixed_g}`;

    console.assert(first_prefix === "" || first_prefix === "0F" || first_prefix === "F2" || first_prefix === "F3");
    console.assert(second_prefix === "" || second_prefix === "66" || second_prefix === "F2" || second_prefix === "F3");

    return `instr${suffix}_${second_prefix}${first_prefix}${opcode_hex}${fixed_g_suffix}`;
}

function gen_instruction_body(encodings, size)
{
    const encoding = encodings[0];

    let has_66 = [];
    let has_F2 = [];
    let has_F3 = [];
    let no_prefix = [];

    for(let e of encodings)
    {
        if((e.opcode >>> 16) === 0x66) has_66.push(e);
        else if((e.opcode >>> 8 & 0xFF) === 0xF2 || (e.opcode >>> 16) === 0xF2) has_F2.push(e);
        else if((e.opcode >>> 8 & 0xFF) === 0xF3 || (e.opcode >>> 16) === 0xF3) has_F3.push(e);
        else no_prefix.push(e);
    }

    if(has_F2.length || has_F3.length)
    {
        console.assert((encoding.opcode & 0xFF0000) === 0 || (encoding.opcode & 0xFF00) === 0x0F00);
    }

    if(has_66.length)
    {
        console.assert((encoding.opcode & 0xFF00) === 0x0F00);
    }

    const code = [];

    if(encoding.e)
    {
        code.push(`let modrm_byte = ${wrap_imm_call("read_imm8()")};`);
    }

    if(has_66.length || has_F2.length || has_F3.length)
    {
        const if_blocks = [];

        if(has_66.length) {
            const body = gen_instruction_body_after_prefix(has_66, size);
            if_blocks.push({ condition: "prefixes_ & PREFIX_66 != 0", body, });
        }
        if(has_F2.length) {
            const body = gen_instruction_body_after_prefix(has_F2, size);
            if_blocks.push({ condition: "prefixes_ & PREFIX_F2 != 0", body, });
        }
        if(has_F3.length) {
            const body = gen_instruction_body_after_prefix(has_F3, size);
            if_blocks.push({ condition: "prefixes_ & PREFIX_F3 != 0", body, });
        }

        const check_prefixes = encoding.sse ? "(PREFIX_66 | PREFIX_F2 | PREFIX_F3)" : "(PREFIX_F2 | PREFIX_F3)";

        const else_block = {
            body: [].concat(
                "dbg_assert!((prefixes_ & " + check_prefixes + ") == 0);",
                gen_instruction_body_after_prefix(no_prefix, size)
            )
        };

        return [].concat(
	    "let prefixes_ = *prefixes as i32;",
            code,
            {
                type: "if-else",
                if_blocks,
                else_block,
            }
        );
    }
    else {
        return [].concat(
            code,
            gen_instruction_body_after_prefix(encodings, size)
        );
    }
}

function gen_instruction_body_after_prefix(encodings, size)
{
    const encoding = encodings[0];

    if(encoding.fixed_g !== undefined)
    {
        console.assert(encoding.e);

        // instruction with modrm byte where the middle 3 bits encode the instruction

        // group by opcode without prefix plus middle bits of modrm byte
        let cases = encodings.reduce((cases_by_opcode, case_) => {
            console.assert(typeof case_.fixed_g === "number");
            cases_by_opcode[case_.opcode & 0xFFFF | case_.fixed_g << 16] = case_;
            return cases_by_opcode;
        }, Object.create(null));
        cases = Object.values(cases).sort((e1, e2) => e1.fixed_g - e2.fixed_g);

        return [
            {
                type: "switch",
                condition: "modrm_byte >> 3 & 7",
                cases: cases.map(case_ => {
                    const fixed_g = case_.fixed_g;
                    const body = gen_instruction_body_after_fixed_g(case_, size);

                    return {
                        conditions: [fixed_g],
                        body,
                    };
                }),

                default_case: {
                    body: [
                        "assert!(false);",
                        "trigger_ud();",
                    ],
                }
            },
        ];
    }
    else {
        console.assert(encodings.length === 1);
        return gen_instruction_body_after_fixed_g(encodings[0], size);
    }
}

function gen_instruction_body_after_fixed_g(encoding, size)
{
    const instruction_prefix = [];
    const instruction_postfix = encoding.block_boundary || (!encoding.custom && encoding.e) || encoding.sse || encoding.task_switch_test ? ["after_block_boundary();"] : [];

    if(encoding.task_switch_test || encoding.sse)
    {
        instruction_prefix.push(
            {
                type: "if-else",
                if_blocks: [
                    {
                        condition: encoding.sse ? "!task_switch_test_mmx()" : "!task_switch_test()",
                        body: ["return;"],
                    }
                ],
            });
    }

    const imm_read = gen_read_imm_call(encoding, size);
    const instruction_name = make_instruction_name(encoding, size);

    if(encoding.e)
    {
        // instruction with modrm byte

        const instruction_name = make_instruction_name(encoding, size);

        const imm_read = gen_read_imm_call(encoding, size);

        if(encoding.ignore_mod)
        {
            console.assert(!imm_read, "Unexpected instruction (ignore mod with immediate value)");

            // Has modrm byte, but the 2 mod bits are ignored and both
            // operands are always registers (0f20-0f24)

            return [].concat(
                instruction_prefix,
                gen_call(instruction_name, ["modrm_byte & 7", "modrm_byte >> 3 & 7"]),
                instruction_postfix
            );
        }
        else
        {
            let mem_args;

            if(encoding.custom_modrm_resolve)
            {
                // requires special handling around modrm_resolve
                mem_args = ["modrm_byte"];
            }
            else
            {
                mem_args = ["match modrm_resolve(modrm_byte) { Ok(a) => a, Err(()) => return }"];
            }

            const reg_args = ["modrm_byte & 7"];

            if(encoding.fixed_g === undefined)
            {
                mem_args.push("modrm_byte >> 3 & 7");
                reg_args.push("modrm_byte >> 3 & 7");
            }

            if(imm_read)
            {
                mem_args.push(imm_read);
                reg_args.push(imm_read);
            }

            return [].concat(
                instruction_prefix,
                {
                    type: "if-else",
                    if_blocks: [
                        {
                            condition: "modrm_byte < 0xC0",
                            body: [].concat(
                                gen_call(`${instruction_name}_mem`, mem_args)
                            ),
                        }
                    ],
                    else_block: {
                        body: [gen_call(`${instruction_name}_reg`, reg_args)],
                    },
                },
                instruction_postfix
            );
        }
    }
    else
    {
        const args = [];

        if(imm_read)
        {
            args.push(imm_read);
        }

        if(encoding.extra_imm16)
        {
            console.assert(imm_read);
            args.push(wrap_imm_call("read_imm16()"));
        }
        else if(encoding.extra_imm8)
        {
            console.assert(imm_read);
            args.push(wrap_imm_call("read_imm8()"));
        }

        return [].concat(
            instruction_prefix,
            gen_call(instruction_name, args),
            instruction_postfix
        );
    }
}

function gen_table()
{
    let by_opcode = Object.create(null);
    let by_opcode0f = Object.create(null);

    for(let o of x86_table)
    {
        let opcode = o.opcode;

        if((opcode & 0xFF00) === 0x0F00)
        {
            opcode &= 0xFF;
            by_opcode0f[opcode] = by_opcode0f[opcode] || [];
            by_opcode0f[opcode].push(o);
        }
        else
        {
            opcode &= 0xFF;
            by_opcode[opcode] = by_opcode[opcode] || [];
            by_opcode[opcode].push(o);
        }
    }

    let cases = [];
    for(let opcode = 0; opcode < 0x100; opcode++)
    {
        let encoding = by_opcode[opcode];
        console.assert(encoding && encoding.length);

        let opcode_hex = hex(opcode, 2);
        let opcode_high_hex = hex(opcode | 0x100, 2);

        if(encoding[0].os)
        {
            cases.push({
                conditions: [`0x${opcode_hex}`],
                body: gen_instruction_body(encoding, 16),
            });
            cases.push({
                conditions: [`0x${opcode_high_hex}`],
                body: gen_instruction_body(encoding, 32),
            });
        }
        else
        {
            cases.push({
                conditions: [`0x${opcode_hex}`, `0x${opcode_high_hex}`],
                body: gen_instruction_body(encoding, undefined),
            });
        }
    }
    const table = {
        type: "switch",
        condition: "opcode",
        cases,
        default_case: {
            body: ["assert!(false);"]
        },
    };
    if(to_generate.interpreter)
    {
        const code = [
            "#![cfg_attr(rustfmt, rustfmt_skip)]",

            "use cpu2::cpu::*;",
            "use cpu2::instructions::*;",
            "use cpu2::global_pointers::*;",

            "pub unsafe fn run(opcode: u32) {",
            table,
            "}",
        ];

        finalize_table_rust(
            OUT_DIR,
            "interpreter.rs",
            rust_ast.print_syntax_tree([].concat(code)).join("\n") + "\n"
        );
    }

    const cases0f_16 = [];
    const cases0f_32 = [];
    for(let opcode = 0; opcode < 0x100; opcode++)
    {
        let encoding = by_opcode0f[opcode];

        console.assert(encoding && encoding.length);

        let opcode_hex = hex(opcode, 2);

        if(encoding[0].os)
        {
            cases0f_16.push({
                conditions: [`0x${opcode_hex}`],
                body: gen_instruction_body(encoding, 16),
            });
            cases0f_32.push({
                conditions: [`0x${opcode_hex}`],
                body: gen_instruction_body(encoding, 32),
            });
        }
        else
        {
            let block = {
                conditions: [`0x${opcode_hex}`],
                body: gen_instruction_body(encoding, undefined),
            };
            cases0f_16.push(block);
            cases0f_32.push(block);
        }
    }

    const table0f_16 = {
        type: "switch",
        condition: "opcode",
        cases: cases0f_16,
        default_case: {
            body: ["assert!(false);"]
        },
    };
    const table0f_32 = {
        type: "switch",
        condition: "opcode",
        cases: cases0f_32,
        default_case: {
            body: ["assert!(false);"]
        },
    };

    if(to_generate.interpreter0f_16)
    {
        const code = [
            "#![cfg_attr(rustfmt, rustfmt_skip)]",

            "use cpu2::cpu::*;",
            "use cpu2::instructions_0f::*;",
            "use cpu2::global_pointers::*;",

            "pub unsafe fn run(opcode: u8) {",
            table0f_16,
            "}",
        ];

        finalize_table_rust(
            OUT_DIR,
            "interpreter0f_16.rs",
            rust_ast.print_syntax_tree([].concat(code)).join("\n") + "\n"
        );
    }

    if(to_generate.interpreter0f_32)
    {
        const code = [
            "#![cfg_attr(rustfmt, rustfmt_skip)]",

            "use cpu2::cpu::*;",
            "use cpu2::instructions_0f::*;",
            "use cpu2::global_pointers::*;",

            "pub unsafe fn run(opcode: u8) {",
            table0f_32,
            "}",
        ];

        finalize_table_rust(
            OUT_DIR,
            "interpreter0f_32.rs",
            rust_ast.print_syntax_tree([].concat(code)).join("\n") + "\n"
        );
    }
}
<|endoftext|>


<commit_before>/*! politespace - v1.0.0 - 2017-06-05
Politely add spaces to input values to increase readability (credit card numbers, phone numbers, etc).
 * https://github.com/filamentgroup/politespace
 * Copyright (c) 2017 Filament Group (@filamentgroup)
 * MIT License */

// Input a credit card number string, returns a key signifying the type of credit card it is
(function( w ) {
	"use strict";

	var keys = {
		MASTERCARD: "MASTERCARD",
		VISA: "VISA",
		DISCOVER: "DISCOVER",
		AMEX: "AMEX",
		JCB: "JCB"
	};

	var types = {};

	// 2221-2720 and 51-55
	types[ keys.MASTERCARD ] = /^(222[1-9]|22[3-9]|2[3-6]|27[01]|2720|5[1-5])/;

	types[ keys.VISA ] = /^4/;

	// 6011 or 65
	types[ keys.DISCOVER ] = /^6(011|22(12[6-9]|1[3-9]|[2-8]|9[0-1]|92[0-5])|4[4-9]|5)/;

	// 34 or 37
	types[ keys.AMEX ] = /^3[47]/;

	// 35
	types[ keys.JCB ] = /^35/;

	function CreditableCardType( val ) {
		for( var j in types ) {
			if( !!val.match( types[ j ] ) ) {
				return j;
			}
		}

		return -1;
	}

	CreditableCardType.KEYS = keys;
	CreditableCardType.TYPES = types;
	w.CreditableCardType = CreditableCardType;

}( typeof global !== "undefined" ? global : this ));

// UMD module definition
// From: https://github.com/umdjs/umd/blob/master/templates/jqueryPlugin.js

(function (factory) {
	if (typeof define === 'function' && define.amd) {
			// AMD. Register as an anonymous module.
			define(['jquery'], factory);
	} else if (typeof module === 'object' && module.exports) {
		// Node/CommonJS
		module.exports = function( root, jQuery ) {
			if ( jQuery === undefined ) {
				if ( typeof window !== 'undefined' ) {
					jQuery = require('jquery');
				} else {
					jQuery = require('jquery')(root);
				}
			}
			factory(jQuery);
			return jQuery;
		};
	} else {
		// Browser globals
		factory(jQuery);
	}
}(function ($) {
	"use strict";

	var w = typeof window !== "undefined" ? window : this;

	var Politespace = function( element ) {
		if( !element ) {
			throw new Error( "Politespace requires an element argument." );
		}

		if( !element.getAttribute || w.operamini ) {
			// Cut the mustard
			return;
		}

		this.element = element;
		this.$element = $( element );
		this.delimiter = this.$element.attr( "data-politespace-delimiter" ) || " ";
		// https://en.wikipedia.org/wiki/Decimal_mark
		this.decimalMark = this.$element.attr( "data-politespace-decimal-mark" ) || "";
		this.reverse = this.$element.is( "[data-politespace-reverse]" );
		this.strip = this.$element.attr( "data-politespace-strip" );
		this.groupLength = this.$element.attr( "data-politespace-grouplength" ) || 3;

		var proxyAnchorSelector = this.$element.attr( "data-politespace-proxy-anchor" );
		this.$proxyAnchor = this.$element;
		this.$proxy = null;

		if( proxyAnchorSelector ) {
			this.$proxyAnchor = this.$element.closest( proxyAnchorSelector );
		}
	};

	Politespace.prototype._divideIntoArray = function( value ) {
		var split = ( '' + this.groupLength ).split( ',' ),
			isUniformSplit = split.length === 1,
			dividedValue = [],
			loopIndex = 0,
			groupLength,
			substrStart,
			useCharCount;

		while( split.length && loopIndex < value.length ) {
			if( isUniformSplit ) {
				groupLength = split[ 0 ];
			} else {
				// use the next split or the rest of the string if open ended, ala "3,3,"
				groupLength = split.shift() || value.length - loopIndex;
			}

			// Use min if we’re at the end of a reversed string
			// (substrStart below grows larger than the string length)
			useCharCount = Math.min( parseInt( groupLength, 10 ), value.length - loopIndex );

			if( this.reverse ) {
				substrStart = -1 * (useCharCount + loopIndex);
			} else {
				substrStart = loopIndex;
			}
			dividedValue.push( value.substr( substrStart, useCharCount ) );
			loopIndex += useCharCount;
		}

		if( this.reverse ) {
			dividedValue.reverse();
		}

		return dividedValue;
	};

	Politespace.prototype.format = function( value ) {
		var split;
		var val = this.unformat( value );
		if( this.strip ) {
			val = val.replace( new RegExp(  this.strip, 'g' ), "" );
		}
		var suffix = '';

		if( this.decimalMark ) {
			split = val.split( this.decimalMark );
			suffix = split.length > 1 ? this.decimalMark + split[ 1 ] : '';
			val = split[ 0 ];
		}

		return this._divideIntoArray( val ).join( this.delimiter ) + suffix;
	};

	Politespace.prototype.trimMaxlength = function( value ) {
		var maxlength = this.element.getAttribute( "maxlength" );
		// Note input type="number" maxlength does nothing
		if( maxlength ) {
			value = value.substr( 0, maxlength );
		}
		return value;
	};

	Politespace.prototype.getValue = function() {
		return this.trimMaxlength( this.element.value );
	};

	Politespace.prototype.update = function() {
		this.element.value = this.useProxy() || this.$element.attr( "type" ) === "password" ?
			this.getValue() :
			this.format( this.getValue() );
	};

	Politespace.prototype.unformat = function( value ) {
		return value.replace( new RegExp(  this.delimiter, 'g' ), '' );
	};

	Politespace.prototype.reset = function() {
		this.element.value = this.unformat( this.element.value );
	};

	Politespace.prototype.useProxy = function() {
		var pattern = this.$element.attr( "pattern" );
		var type = this.$element.attr( "type" );

		// this needs to be an attr check and not a prop for `type` toggling (like password)
		return type === "number" ||
			// When Chrome validates form fields using native form validation, it uses `pattern`
			// which causes validation errors when we inject delimiters. So use the proxy to avoid
			// delimiters in the form field value.
			// Chrome also has some sort of
			( pattern ? !( new RegExp( "^" + pattern + "$" ) ).test( this.delimiter ) : false );
	};

	Politespace.prototype.updateProxy = function() {
		if( this.useProxy() && this.$proxy.length ) {
			var html = this.format( this.getValue() );
			var width = this.element.offsetWidth;

			this.$proxy.html( html );

			if( width ) {
				this.$proxy.css( "width", width + "px" );
			}

			// Hide if empty, to show placeholder
			this.$proxy.closest( ".politespace-proxy" )[ html ? 'addClass' : 'removeClass' ]( "notempty" );
		}
	};

	Politespace.prototype.createProxy = function() {
		if( !this.useProxy() ) {
			return;
		}

		function sumStyles( el, props ) {
			var total = 0;
			var $el = $( el );
			for( var j=0, k=props.length; j<k; j++ ) {
				total += parseFloat( $el.css( props[ j ] ) );
			}
			return total;
		}

		var $el = $( "<div>" ).addClass( "politespace-proxy active" );
		var $nextSibling = this.$proxyAnchor.next();
		var $parent = this.$proxyAnchor.parent();

		this.$proxy = $( "<div>" ).addClass( "politespace-proxy-val" ).css({
			font: this.$element.css( "font" ),
			"padding-left": sumStyles( this.element, [ "padding-left", "border-left-width" ] ) + "px",
			"padding-right": sumStyles( this.element, [ "padding-right", "border-right-width" ] ) + "px",
			top: sumStyles( this.element, [ "padding-top", "border-top-width", "margin-top" ] ) + "px"
		});
		$el.append( this.$proxy );
		$el.append( this.$proxyAnchor );

		if( $nextSibling.length ) {
			$el.insertBefore( $nextSibling );
		} else {
			$parent.append( $el );
		}

		this.updateProxy();
	};

	Politespace.prototype.setGroupLength = function( length ) {
		this.groupLength = length;
		this.$element.attr( "data-politespace-grouplength", length );
	};

	var componentName = "politespace";

	$.fn[ componentName ] = function(){
		return this.each( function(){
			var $t = $( this );
			if( $t.data( componentName ) ) {
				return;
			}

			var polite = new Politespace( this );
			if( polite.useProxy() ) {
				polite.createProxy();
			}

			$t.bind( "politespace-hide-proxy", function() {
					$( this ).closest( ".politespace-proxy" ).removeClass( "active" );
				})
				.bind( "politespace-show-proxy", function() {
					$( this ).closest( ".politespace-proxy" ).addClass( "active" );

					polite.update();
					polite.updateProxy();
				})
				.bind( "input keydown", function() {
					$( this ).trigger( "politespace-input" );

					polite.updateProxy();
				})
				.bind( "blur", function() {
					$( this ).trigger( "politespace-beforeblur" );

					polite.update();

					if( polite.useProxy() ){
						$( this ).trigger( "politespace-show-proxy" );
					}
				})
				.bind( "focus", function() {
					$( this ).trigger( "politespace-hide-proxy" );
					polite.reset();
				})
				.data( componentName, polite )
				.trigger( "politespace-init" );

			polite.update();
			polite.updateProxy();
		});
	};

	$( document ).bind( "politespace-init politespace-input", function( event ) {
		var $t = $( event.target );
		if( !$t.is( "[data-politespace-creditcard]" ) ) {
			return;
		}
		var pspace = $t.data( "politespace" );
		var val = $t.val();
		var adjustMaxlength = $t.is( "[data-politespace-creditcard-maxlength]" );
		var type = w.CreditableCardType( val );

		if( type === "AMEX" ) {
			pspace.setGroupLength( adjustMaxlength ? "4,6,5" : "4,6," );

			if( adjustMaxlength ) {
				$t.attr( "maxlength", 15 );
			}
		} else if( type === "DISCOVER" || type === "VISA" || type === "MASTERCARD" || type === "JCB") {
			pspace.setGroupLength( adjustMaxlength ? "4,4,4,4" : "4" );

			if( adjustMaxlength ) {
				$t.attr( "maxlength", 16 );
			}
		}
	});

// jQuery Plugin
(function( w, $ ) {
	"use strict";

	var maxlengthCacheKey = "politespace-us-telephone-maxlength";
	var eventName = "politespace-beforeblur.politespace-us-telephone";

	function cleanup( el ) {
		var $t = $( el );
		var val = $t.val();

		$t.val( val.replace( /^1/, "" ) );
	}

	// On init
	$( document ).bind( "politespace-init", function( event ) {
		var $t = $( event.target );
		if( !$t.is( "[data-politespace-us-telephone]" ) ) {
			return;
		}

		// Adjust maxlength
		var maxlength= $t.attr( "maxlength" );

		if( maxlength ) {
			$t.data( maxlengthCacheKey, parseInt( maxlength, 10 ) );

			cleanup( $t[ 0 ] );
			$t.off( eventName ).on( eventName, function() {
				$( this ).attr( "maxlength", $t.data( maxlengthCacheKey ) );
				cleanup( this );
			});
		}
	});

	// On input
	$( document ).bind( "politespace-input", function( event ) {
		var $t = $( event.target );
		if( !$t.is( "[data-politespace-us-telephone]" ) ) {
			return;
		}

		if( $t.val().indexOf( '1' ) === 0 ) {
			$t.attr( "maxlength", $t.data( maxlengthCacheKey ) + 1 );
		}
	});

}( typeof global !== "undefined" ? global : this, jQuery ));

	w.Politespace = Politespace;
}));
<commit_msg>Delete unnecessary commit file<commit_after>/*! politespace - v1.0.0 - 2017-06-05
Politely add spaces to input values to increase readability (credit card numbers, phone numbers, etc).
 * https://github.com/filamentgroup/politespace
 * Copyright (c) 2017 Filament Group (@filamentgroup)
 * MIT License */

// Input a credit card number string, returns a key signifying the type of credit card it is
(function( w ) {
	"use strict";

	var keys = {
		MASTERCARD: "MASTERCARD",
		VISA: "VISA",
		DISCOVER: "DISCOVER",
		AMEX: "AMEX",
	};

	var types = {};

	// 2221-2720 and 51-55
	types[ keys.MASTERCARD ] = /^(222[1-9]|22[3-9]|2[3-6]|27[01]|2720|5[1-5])/;

	types[ keys.VISA ] = /^4/;

	// 6011 or 65
	types[ keys.DISCOVER ] = /^6(011|22(12[6-9]|1[3-9]|[2-8]|9[0-1]|92[0-5])|4[4-9]|5)/;

	// 34 or 37
	types[ keys.AMEX ] = /^3[47]/;

	function CreditableCardType( val ) {
		for( var j in types ) {
			if( !!val.match( types[ j ] ) ) {
				return j;
			}
		}

		return -1;
	}

	CreditableCardType.KEYS = keys;
	CreditableCardType.TYPES = types;
	w.CreditableCardType = CreditableCardType;

}( typeof global !== "undefined" ? global : this ));

// UMD module definition
// From: https://github.com/umdjs/umd/blob/master/templates/jqueryPlugin.js

(function (factory) {
	if (typeof define === 'function' && define.amd) {
			// AMD. Register as an anonymous module.
			define(['jquery'], factory);
	} else if (typeof module === 'object' && module.exports) {
		// Node/CommonJS
		module.exports = function( root, jQuery ) {
			if ( jQuery === undefined ) {
				if ( typeof window !== 'undefined' ) {
					jQuery = require('jquery');
				} else {
					jQuery = require('jquery')(root);
				}
			}
			factory(jQuery);
			return jQuery;
		};
	} else {
		// Browser globals
		factory(jQuery);
	}
}(function ($) {
	"use strict";

	var w = typeof window !== "undefined" ? window : this;

	var Politespace = function( element ) {
		if( !element ) {
			throw new Error( "Politespace requires an element argument." );
		}

		if( !element.getAttribute || w.operamini ) {
			// Cut the mustard
			return;
		}

		this.element = element;
		this.$element = $( element );
		this.delimiter = this.$element.attr( "data-politespace-delimiter" ) || " ";
		// https://en.wikipedia.org/wiki/Decimal_mark
		this.decimalMark = this.$element.attr( "data-politespace-decimal-mark" ) || "";
		this.reverse = this.$element.is( "[data-politespace-reverse]" );
		this.strip = this.$element.attr( "data-politespace-strip" );
		this.groupLength = this.$element.attr( "data-politespace-grouplength" ) || 3;

		var proxyAnchorSelector = this.$element.attr( "data-politespace-proxy-anchor" );
		this.$proxyAnchor = this.$element;
		this.$proxy = null;

		if( proxyAnchorSelector ) {
			this.$proxyAnchor = this.$element.closest( proxyAnchorSelector );
		}
	};

	Politespace.prototype._divideIntoArray = function( value ) {
		var split = ( '' + this.groupLength ).split( ',' ),
			isUniformSplit = split.length === 1,
			dividedValue = [],
			loopIndex = 0,
			groupLength,
			substrStart,
			useCharCount;

		while( split.length && loopIndex < value.length ) {
			if( isUniformSplit ) {
				groupLength = split[ 0 ];
			} else {
				// use the next split or the rest of the string if open ended, ala "3,3,"
				groupLength = split.shift() || value.length - loopIndex;
			}

			// Use min if we’re at the end of a reversed string
			// (substrStart below grows larger than the string length)
			useCharCount = Math.min( parseInt( groupLength, 10 ), value.length - loopIndex );

			if( this.reverse ) {
				substrStart = -1 * (useCharCount + loopIndex);
			} else {
				substrStart = loopIndex;
			}
			dividedValue.push( value.substr( substrStart, useCharCount ) );
			loopIndex += useCharCount;
		}

		if( this.reverse ) {
			dividedValue.reverse();
		}

		return dividedValue;
	};

	Politespace.prototype.format = function( value ) {
		var split;
		var val = this.unformat( value );
		if( this.strip ) {
			val = val.replace( new RegExp(  this.strip, 'g' ), "" );
		}
		var suffix = '';

		if( this.decimalMark ) {
			split = val.split( this.decimalMark );
			suffix = split.length > 1 ? this.decimalMark + split[ 1 ] : '';
			val = split[ 0 ];
		}

		return this._divideIntoArray( val ).join( this.delimiter ) + suffix;
	};

	Politespace.prototype.trimMaxlength = function( value ) {
		var maxlength = this.element.getAttribute( "maxlength" );
		// Note input type="number" maxlength does nothing
		if( maxlength ) {
			value = value.substr( 0, maxlength );
		}
		return value;
	};

	Politespace.prototype.getValue = function() {
		return this.trimMaxlength( this.element.value );
	};

	Politespace.prototype.update = function() {
		this.element.value = this.useProxy() || this.$element.attr( "type" ) === "password" ?
			this.getValue() :
			this.format( this.getValue() );
	};

	Politespace.prototype.unformat = function( value ) {
		return value.replace( new RegExp(  this.delimiter, 'g' ), '' );
	};

	Politespace.prototype.reset = function() {
		this.element.value = this.unformat( this.element.value );
	};

	Politespace.prototype.useProxy = function() {
		var pattern = this.$element.attr( "pattern" );
		var type = this.$element.attr( "type" );

		// this needs to be an attr check and not a prop for `type` toggling (like password)
		return type === "number" ||
			// When Chrome validates form fields using native form validation, it uses `pattern`
			// which causes validation errors when we inject delimiters. So use the proxy to avoid
			// delimiters in the form field value.
			// Chrome also has some sort of
			( pattern ? !( new RegExp( "^" + pattern + "$" ) ).test( this.delimiter ) : false );
	};

	Politespace.prototype.updateProxy = function() {
		if( this.useProxy() && this.$proxy.length ) {
			var html = this.format( this.getValue() );
			var width = this.element.offsetWidth;

			this.$proxy.html( html );

			if( width ) {
				this.$proxy.css( "width", width + "px" );
			}

			// Hide if empty, to show placeholder
			this.$proxy.closest( ".politespace-proxy" )[ html ? 'addClass' : 'removeClass' ]( "notempty" );
		}
	};

	Politespace.prototype.createProxy = function() {
		if( !this.useProxy() ) {
			return;
		}

		function sumStyles( el, props ) {
			var total = 0;
			var $el = $( el );
			for( var j=0, k=props.length; j<k; j++ ) {
				total += parseFloat( $el.css( props[ j ] ) );
			}
			return total;
		}

		var $el = $( "<div>" ).addClass( "politespace-proxy active" );
		var $nextSibling = this.$proxyAnchor.next();
		var $parent = this.$proxyAnchor.parent();

		this.$proxy = $( "<div>" ).addClass( "politespace-proxy-val" ).css({
			font: this.$element.css( "font" ),
			"padding-left": sumStyles( this.element, [ "padding-left", "border-left-width" ] ) + "px",
			"padding-right": sumStyles( this.element, [ "padding-right", "border-right-width" ] ) + "px",
			top: sumStyles( this.element, [ "padding-top", "border-top-width", "margin-top" ] ) + "px"
		});
		$el.append( this.$proxy );
		$el.append( this.$proxyAnchor );

		if( $nextSibling.length ) {
			$el.insertBefore( $nextSibling );
		} else {
			$parent.append( $el );
		}

		this.updateProxy();
	};

	Politespace.prototype.setGroupLength = function( length ) {
		this.groupLength = length;
		this.$element.attr( "data-politespace-grouplength", length );
	};

	var componentName = "politespace";

	$.fn[ componentName ] = function(){
		return this.each( function(){
			var $t = $( this );
			if( $t.data( componentName ) ) {
				return;
			}

			var polite = new Politespace( this );
			if( polite.useProxy() ) {
				polite.createProxy();
			}

			$t.bind( "politespace-hide-proxy", function() {
					$( this ).closest( ".politespace-proxy" ).removeClass( "active" );
				})
				.bind( "politespace-show-proxy", function() {
					$( this ).closest( ".politespace-proxy" ).addClass( "active" );

					polite.update();
					polite.updateProxy();
				})
				.bind( "input keydown", function() {
					$( this ).trigger( "politespace-input" );

					polite.updateProxy();
				})
				.bind( "blur", function() {
					$( this ).trigger( "politespace-beforeblur" );

					polite.update();

					if( polite.useProxy() ){
						$( this ).trigger( "politespace-show-proxy" );
					}
				})
				.bind( "focus", function() {
					$( this ).trigger( "politespace-hide-proxy" );
					polite.reset();
				})
				.data( componentName, polite )
				.trigger( "politespace-init" );

			polite.update();
			polite.updateProxy();
		});
	};

	$( document ).bind( "politespace-init politespace-input", function( event ) {
		var $t = $( event.target );
		if( !$t.is( "[data-politespace-creditcard]" ) ) {
			return;
		}
		var pspace = $t.data( "politespace" );
		var val = $t.val();
		var adjustMaxlength = $t.is( "[data-politespace-creditcard-maxlength]" );
		var type = w.CreditableCardType( val );

		if( type === "AMEX" ) {
			pspace.setGroupLength( adjustMaxlength ? "4,6,5" : "4,6," );

			if( adjustMaxlength ) {
				$t.attr( "maxlength", 15 );
			}
		} else if( type === "DISCOVER" || type === "VISA" || type === "MASTERCARD" ) {
			pspace.setGroupLength( adjustMaxlength ? "4,4,4,4" : "4" );

			if( adjustMaxlength ) {
				$t.attr( "maxlength", 16 );
			}
		}
	});

// jQuery Plugin
(function( w, $ ) {
	"use strict";

	var maxlengthCacheKey = "politespace-us-telephone-maxlength";
	var eventName = "politespace-beforeblur.politespace-us-telephone";

	function cleanup( el ) {
		var $t = $( el );
		var val = $t.val();

		$t.val( val.replace( /^1/, "" ) );
	}

	// On init
	$( document ).bind( "politespace-init", function( event ) {
		var $t = $( event.target );
		if( !$t.is( "[data-politespace-us-telephone]" ) ) {
			return;
		}

		// Adjust maxlength
		var maxlength= $t.attr( "maxlength" );

		if( maxlength ) {
			$t.data( maxlengthCacheKey, parseInt( maxlength, 10 ) );

			cleanup( $t[ 0 ] );
			$t.off( eventName ).on( eventName, function() {
				$( this ).attr( "maxlength", $t.data( maxlengthCacheKey ) );
				cleanup( this );
			});
		}
	});

	// On input
	$( document ).bind( "politespace-input", function( event ) {
		var $t = $( event.target );
		if( !$t.is( "[data-politespace-us-telephone]" ) ) {
			return;
		}

		if( $t.val().indexOf( '1' ) === 0 ) {
			$t.attr( "maxlength", $t.data( maxlengthCacheKey ) + 1 );
		}
	});

}( typeof global !== "undefined" ? global : this, jQuery ));

	w.Politespace = Politespace;
}));
<|endoftext|>


<commit_before>module.exports = function(grunt) {
	var packageVersion = require('../../package.json').version;

	/* -------------
		RELEASE
	------------- */
	grunt.registerTask('notes', 'Run a ruby gem that will request from Github unreleased pull requests', ['shell:notes']);

	grunt.registerTask('updateRelease', '', function () {
		packageVersion = require('../../package.json').version;
	});

	// Maintainers: Run prior to a release. Includes SauceLabs VM tests.
	grunt.registerTask('release', 'Release a new version, push it and publish it', function() {

		// default variables for release task
		var releaseDefaults = {
			release: {
				files: ['dist', 'README.md', 'DETAILS.md', 'bower.json', 'package.json'],
				localBranch: 'release',
				remoteBaseBranch: 'master',
				remoteDestinationBranch: '3.x',
				remoteRepository: 'origin'
			}
		};

		// add releaseDefaults
		grunt.config.merge(releaseDefaults);

		if ( typeof grunt.config('sauceLoginFile') === 'undefined' ) {
			grunt.log.write('The file SAUCE_API_KEY.yml is needed in order to run tests in SauceLabs.'['red'].bold +
				' Please contact another maintainer to obtain this file.');
		}

		if ( typeof grunt.config('cdnLoginFile') === 'undefined' ) {
			grunt.log.write('The file FUEL_CDN.yml is needed in order to upload the release files to the CDN.'['red'].bold +
				' Please contact another maintainer to obtain this file.');
		}

		// update local variable to make sure build prompt is using temp branch's package version
		grunt.task.run(['prompt:tempbranch', 'shell:checkoutRemoteReleaseBranch',
			'updateRelease', 'prompt:build', 'dorelease']);
	});

	grunt.registerTask('dorelease', '', function () {

		grunt.log.writeln('');

		if (!grunt.option('no-tests')) {
			grunt.task.run(['releasetest']); //If phantom timeouts happening because of long-running qunit tests, look into setting `resourceTimeout` in phantom: http://phantomjs.org/api/webpage/property/settings.html
			// Delete any screenshots that may have happened if it got this far. This isn't foolproof
			// because it relies on the phantomjs server/page timeout, which can take longer than this
			// grunt task depending on how long saucelabs takes to run...
			grunt.task.run('clean:screenshots');
		}

		grunt.config('banner', '<%= bannerRelease %>');

		// Run dist again to grab the latest version numbers. Yeah, we're running it twice... ¯\_(ツ)_/¯
		grunt.task.run(['bump-only:' + grunt.config('release.buildSemVerType'), 'replace:readme', 'dist',
			'shell:addReleaseFiles', 'prompt:commit', 'prompt:tag', 'prompt:pushLocalBranchToUpstream',
			'prompt:pushTagToUpstream', 'prompt:uploadToCDN', 'prompt:pushLocalBranchToUpstreamMaster', 'shell:publishToNPM']);
	});

};<commit_msg>(master) makes default upstream<commit_after>module.exports = function(grunt) {
	var packageVersion = require('../../package.json').version;

	/* -------------
		RELEASE
	------------- */
	grunt.registerTask('notes', 'Run a ruby gem that will request from Github unreleased pull requests', ['shell:notes']);

	grunt.registerTask('updateRelease', '', function () {
		packageVersion = require('../../package.json').version;
	});

	// Maintainers: Run prior to a release. Includes SauceLabs VM tests.
	grunt.registerTask('release', 'Release a new version, push it and publish it', function() {

		// default variables for release task
		var releaseDefaults = {
			release: {
				files: ['dist', 'README.md', 'DETAILS.md', 'bower.json', 'package.json'],
				localBranch: 'release',
				remoteBaseBranch: 'master',
				remoteDestinationBranch: '3.x',
				remoteRepository: 'upstream'
			}
		};

		// add releaseDefaults
		grunt.config.merge(releaseDefaults);

		if ( typeof grunt.config('sauceLoginFile') === 'undefined' ) {
			grunt.log.write('The file SAUCE_API_KEY.yml is needed in order to run tests in SauceLabs.'['red'].bold +
				' Please contact another maintainer to obtain this file.');
		}

		if ( typeof grunt.config('cdnLoginFile') === 'undefined' ) {
			grunt.log.write('The file FUEL_CDN.yml is needed in order to upload the release files to the CDN.'['red'].bold +
				' Please contact another maintainer to obtain this file.');
		}

		// update local variable to make sure build prompt is using temp branch's package version
		grunt.task.run(['prompt:tempbranch', 'shell:checkoutRemoteReleaseBranch',
			'updateRelease', 'prompt:build', 'dorelease']);
	});

	grunt.registerTask('dorelease', '', function () {

		grunt.log.writeln('');

		if (!grunt.option('no-tests')) {
			grunt.task.run(['releasetest']); //If phantom timeouts happening because of long-running qunit tests, look into setting `resourceTimeout` in phantom: http://phantomjs.org/api/webpage/property/settings.html
			// Delete any screenshots that may have happened if it got this far. This isn't foolproof
			// because it relies on the phantomjs server/page timeout, which can take longer than this
			// grunt task depending on how long saucelabs takes to run...
			grunt.task.run('clean:screenshots');
		}

		grunt.config('banner', '<%= bannerRelease %>');

		// Run dist again to grab the latest version numbers. Yeah, we're running it twice... ¯\_(ツ)_/¯
		grunt.task.run(['bump-only:' + grunt.config('release.buildSemVerType'), 'replace:readme', 'dist',
			'shell:addReleaseFiles', 'prompt:commit', 'prompt:tag', 'prompt:pushLocalBranchToUpstream',
			'prompt:pushTagToUpstream', 'prompt:uploadToCDN', 'prompt:pushLocalBranchToUpstreamMaster', 'shell:publishToNPM']);
	});

};<|endoftext|>


<commit_before>var HTMLElement=function(t){function e(){}return e.prototype=window.HTMLElement.prototype,e}(),TokenList=function(t){for(var e=this,n=function(t){console.log("text content",t.textContent),/{(\w+|#)}/.test(t.textContent)&&(t.text=t.textContent).match(/[^{]+(?=})/g).map(function(n){return(e[n]||(e[n]=[])).push(t)})},o=document.createNodeIterator(t,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT,function(t){return t.attributes&&[].slice.call(t.attributes).map(n)||n(t)},null);o.nextNode(););};TokenList.prototype.bind=function(t){var e=function(e){return function(n){return n.textContent=n.textContent.split("{"+e+"}").join(t[e])}};for(var n in this)console.log("symbol",n),this[n].map(function(t){return(t.textContent=t.text)&&t});for(var o in this)this[o].map(e(o))},function(t){function e(t){var e=new XMLHttpRequest;e.link=t,e.onload=n,e.open("GET",t.href),e.responseType="document",e.send()}function n(){for(var t=this.link,e=this.response,n=t.nextChild,r=t.content=e.querySelector("template"),i=0,c=document.querySelectorAll(t.id);i<c.length;i+=1){var l=c[i];r&&o.call(l,r)}for(var s=0,a=e.querySelectorAll("style,link,script");s<a.length;s+=1){!function(t,e,n){var o=e.getAttribute("as"),r=document.createElement("script"==o?o:e.localName);["id","rel","href","src","textContent","as","defer","crossOrigin"].map(function(t){return e[t]&&t in r&&(r[t]=e[t])}),"style"==o&&(r.rel="stylesheet"),"script"==o&&(r.src=r.href),t.parentNode.insertBefore(r,n)}(t,a[s],n)}}function o(t){var e=this;t=document.importNode(t,!0);var n;[].slice.call(t.attributes).map(function(t){return!e.attributes[t.name]&&e.setAttribute(t.name,t.value)});for(var o=0,r=e.querySelectorAll("[slot]");o<r.length;o+=1){var i=r[o];(n=(t.content||t).querySelector("slot[name="+i.getAttribute("slot")+"]"))&&n.parentNode.replaceChild(i,n)}return this.innerHTML=t.innerHTML}new MutationObserver(function(t){for(var n=0,r=t;n<r.length;n+=1)for(var i=0,c=r[n].addedNodes;i<c.length;i+=1){var l=c[i];/^p/.test(l.rel)&&/\-/.test(l.id)&&e(l),/\-/.test(l.localName)&&(link=document.querySelector("#"+l.localName))&&link.content&&o.call(l,link.content)&&customElements.upgrade(l)}}).observe(document.documentElement,{childList:!0,subtree:!0}),[].slice.call(document.querySelectorAll('[rel^=pre][id~="-"]')).map(e)}();var Template=function(t){t.length&&(t=document.querySelector("template[name="+t+"]"));var e=t.innerHTML,n=t.nextSibling;return t.innerHTML="",t.bind=function(t){for(var o=document.createElement("section"),r=0,i=this.dependents||[];r<i.length;r+=1){var c=i[r];c.parentNode.removeChild(c)}o.innerHTML=[].concat(t).reduce(function(t,n,o){var r=e;"object"!=typeof n&&(n={self:n}),n["#"]=o;for(var i in n)r=r.split("{"+i+"}").join(n[i]);return t+r},"");for(var l=0,s=this.dependents=[].slice.call(o.childNodes);l<s.length;l+=1){var a=s[l];this.parentNode.insertBefore(a,n)}}.bind(t),t};window.customElements=window.customElements||{},new(function(){function t(){customElements.define=this.define.bind(this),customElements.upgrade=this.upgrade.bind(this)}return t.prototype.define=function(t,e){this[t]=e,[].slice.call(document.querySelectorAll(t)).map(this.upgrade,this)},t.prototype.upgrade=function(t){this[t.localName]&&Object.setPrototypeOf(t,this[t.localName].prototype).connectedCallback()},t}());var ParentNode=function(t){return function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.select=function(){return(t=this).selectAll.apply(t,arguments)[0];var t},e.prototype.selectAll=function(t){for(var e=[],n=arguments.length-1;n-- >0;)e[n]=arguments[n+1];return t=[].concat(t),[].slice.call(this.querySelectorAll(e.reduce(function(e,n){return e+n+t.shift()},t.shift())))},e}(t)},EventTarget=function(t){return function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.on=function(t,e){this.addEventListener(t,this.renderable(e))},e.prototype.renderable=function(t){var e=this;return function(n){return!1!==t.call(e,n)&&n.defaultPrevented||e.render()}},e}(t)},GlobalEventHandlers=function(t){return function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.onconnect=function(){this.templates=this.selectAll("template[name]").map(Template),this.tokens=new TokenList(this),t.prototype.onconnect&&t.prototype.onconnect.call(this)},e.prototype.reflect=function(t){/^on/.test(t)&&t in HTMLElement.prototype&&this.on(t.substr(2),this[t])},e.prototype.register=function(t,e,n){for(var o=0,r=[].slice.call(t.attributes);o<r.length;o+=1){var i=r[o];/^on/.test(n=i.name)&&(e=(/{\s*(\w+)/.exec(t[n])||[])[1])&&(t[n]=this.renderable(this[e]))}},e}(t)},Custom=function(t){return function(e){function n(){e.apply(this,arguments)}return e&&(n.__proto__=e),n.prototype=Object.create(e&&e.prototype),n.prototype.constructor=n,n.prototype.connectedCallback=function(){this.context={},e.prototype.initialize&&e.prototype.initialize.call(this),Object.getOwnPropertyNames(t.prototype).map(this.reflect,this),this.onconnect(),this.render()},n.prototype.render=function(){for(var t=0,n=this.templates;t<n.length;t+=1){var o=n[t];o.bind(this[o.getAttribute("name")])}this.tokens.bind(this),this.register(this),this.selectAll("*").map(this.register,this),e.prototype.onidle&&e.prototype.onidle.call(this)},n}(ParentNode(EventTarget(GlobalEventHandlers(t))))},Element=function(t){return function(e){return customElements.define(t+"",Custom(e))}};<commit_msg>:muscle: bump MINIFIED distribution dist/snuggsi.min.js<commit_after>var HTMLElement=function(t){function e(){}return e.prototype=window.HTMLElement.prototype,e}(),TokenList=function(t){for(var e=this,n=function(t){console.log("text content",t.textContent),/{(\w+|#)}/.test(t.textContent)&&(t.text=t.textContent).match(/[^{]+(?=})/g).map(function(n){return(e[n]||(e[n]=[])).push(t)})},o=document.createNodeIterator(t,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT,function(t){return t.attributes&&[].slice.call(t.attributes).map(n)||n(t)},null);o.nextNode(););};TokenList.prototype.bind=function(t){var e=function(e){return function(n){return n.textContent=n.textContent.split("{"+e+"}").join(t[e])}};for(var n in this)console.log("symbol",n),this[n].map(function(t){return(t.textContent=t.text)&&t});for(var o in this)this[o].map(e(o))},function(t){function e(t){var e=new XMLHttpRequest;e.link=t,e.onload=n,e.open("GET",t.href),e.responseType="document",e.send()}function n(){for(var t=this.link,e=this.response,n=t.nextChild,r=t.content=e.querySelector("template"),i=0,c=document.querySelectorAll(t.id);i<c.length;i+=1){var l=c[i];r&&o.call(l,r)}for(var s=0,a=e.querySelectorAll("style,link,script");s<a.length;s+=1){!function(t,e,n){var o=e.getAttribute("as"),r=document.createElement("script"==o?o:e.localName);["id","rel","href","src","textContent","as","defer","crossOrigin"].map(function(t){return e[t]&&t in r&&(r[t]=e[t])}),"style"==o&&(r.rel="stylesheet"),"script"==o&&(r.src=r.href),t.parentNode.insertBefore(r,n)}(t,a[s],n)}}function o(t){var e=this;t=document.importNode(t,!0);var n;[].slice.call(t.attributes).map(function(t){return!e.attributes[t.name]&&e.setAttribute(t.name,t.value)});for(var o=0,r=e.querySelectorAll("[slot]");o<r.length;o+=1){var i=r[o];(n=(t.content||t).querySelector("slot[name="+i.getAttribute("slot")+"]"))&&n.parentNode.replaceChild(i,n)}return this.innerHTML=t.innerHTML}new MutationObserver(function(t){for(var n=0,r=t;n<r.length;n+=1)for(var i=0,c=r[n].addedNodes;i<c.length;i+=1){var l=c[i];/^p/.test(l.rel)&&/\-/.test(l.id)&&e(l),/\-/.test(l.localName)&&(link=document.querySelector("#"+l.localName))&&link.content&&o.call(l,link.content)&&customElements.upgrade(l)}}).observe(document.documentElement,{childList:!0,subtree:!0}),[].slice.call(document.querySelectorAll('[rel^=pre][id~="-"]')).map(e)}();var Template=function(t){t.length&&(t=document.querySelector("template[name="+t+"]"));var e=t.innerHTML,n=t.nextSibling;return t.innerHTML="",t.bind=function(t){for(var o=document.createElement("section"),r=0,i=this.dependents||[];r<i.length;r+=1){var c=i[r];c.parentNode.removeChild(c)}o.innerHTML=[].concat(t).reduce(function(t,n,o){var r=e;"object"!=typeof n&&(n={self:n}),n["#"]=o;for(var i in n)r=r.split("{"+i+"}").join(n[i]);return t+r},"");for(var l=0,s=this.dependents=[].slice.call(o.childNodes);l<s.length;l+=1){var a=s[l];this.parentNode.insertBefore(a,n)}}.bind(t),t};new(function(){function t(){customElements.define=this.define.bind(this),customElements.upgrade=this.upgrade.bind(this)}return t.prototype.define=function(t,e){this[t]=e,[].slice.call(document.querySelectorAll(t)).map(this.upgrade,this)},t.prototype.upgrade=function(t){this[t.localName]&&Object.setPrototypeOf(t,this[t.localName].prototype).connectedCallback()},t}());var ParentNode=function(t){return function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.select=function(){return(t=this).selectAll.apply(t,arguments)[0];var t},e.prototype.selectAll=function(t){for(var e=[],n=arguments.length-1;n-- >0;)e[n]=arguments[n+1];return t=[].concat(t),[].slice.call(this.querySelectorAll(e.reduce(function(e,n){return e+n+t.shift()},t.shift())))},e}(t)},EventTarget=function(t){return function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.on=function(t,e){this.addEventListener(t,this.renderable(e))},e.prototype.renderable=function(t){var e=this;return function(n){return!1!==t.call(e,n)&&n.defaultPrevented||e.render()}},e}(t)},GlobalEventHandlers=function(t){return function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.onconnect=function(){this.templates=this.selectAll("template[name]").map(Template),this.tokens=new TokenList(this),t.prototype.onconnect&&t.prototype.onconnect.call(this)},e.prototype.reflect=function(t){/^on/.test(t)&&t in HTMLElement.prototype&&this.on(t.substr(2),this[t])},e.prototype.register=function(t,e,n){for(var o=0,r=[].slice.call(t.attributes);o<r.length;o+=1){var i=r[o];/^on/.test(n=i.name)&&(e=(/{\s*(\w+)/.exec(t[n])||[])[1])&&(t[n]=this.renderable(this[e]))}},e}(t)},Custom=function(t){return function(e){function n(){e.apply(this,arguments)}return e&&(n.__proto__=e),n.prototype=Object.create(e&&e.prototype),n.prototype.constructor=n,n.prototype.connectedCallback=function(){this.context={},e.prototype.initialize&&e.prototype.initialize.call(this),Object.getOwnPropertyNames(t.prototype).map(this.reflect,this),this.onconnect(),this.render()},n.prototype.render=function(){for(var t=0,n=this.templates;t<n.length;t+=1){var o=n[t];o.bind(this[o.getAttribute("name")])}this.tokens.bind(this),this.register(this),this.selectAll("*").map(this.register,this),e.prototype.onidle&&e.prototype.onidle.call(this)},n}(ParentNode(EventTarget(GlobalEventHandlers(t))))},Element=function(t){return function(e){return customElements.define(t+"",Custom(e))}};<|endoftext|>


<commit_before>import Vue from 'vue';
import VueResource from 'vue-resource';

import BootstrapVue from 'bootstrap-vue';
import ElementUI from 'element-ui';
import 'font-awesome/scss/font-awesome.scss';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';
import '../lib/element-theme/index.css';
import './assets/style.scss';

import App from './App';

import router from './router';
import store from './store/store';
import i18n from './lang/locale';

Vue.use(VueResource);
Vue.use(ElementUI, {
  i18n: (key, value) => i18n.t(key, value),
});
Vue.use(BootstrapVue);

Vue.config.productionTip = false;

/* eslint-disable no-new */
new Vue({
  el: '#app',
  store,
  i18n,
  router,
  template: '<App/>',
  components: { App },
});
<commit_msg>Register global ClosableSidebar mixin<commit_after>import Vue from 'vue';
import VueResource from 'vue-resource';

import BootstrapVue from 'bootstrap-vue';
import ElementUI from 'element-ui';
import 'font-awesome/scss/font-awesome.scss';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';
import '../lib/element-theme/index.css';
import './assets/style.scss';

import App from './App';

import router from './router';
import store from './store/store';
import i18n from './lang/locale';

// GLOBAL MIXINS
import ClosableSidebar from './mixins/ClosableSidebar';

Vue.use(VueResource);
Vue.use(ElementUI, {
  i18n: (key, value) => i18n.t(key, value),
});
Vue.use(BootstrapVue);

// GLOBAL MIXINS
Vue.mixin(ClosableSidebar);

Vue.config.productionTip = false;

/* eslint-disable no-new */
new Vue({
  el: '#app',
  store,
  i18n,
  router,
  template: '<App/>',
  components: { App },
});
<|endoftext|>


<commit_before>/*jslint browser: true*/

(function( vui ) {

	'use strict';

	// Check if the provided vui global is defined, otherwise try to require it if
	// we're in a CommonJS environment; otherwise we'll just fail out
	if( vui === undefined ) {
		if( typeof require === 'function' ) {
			vui = require('../../core');
		} else {
			throw new Error('load vui first');
		}
	}

	// Export the vui object if we're in a CommonJS environment.
	// It will already be on the window otherwise
	if( typeof module === 'object' && typeof module.exports === 'object' ) {
		module.exports = vui;
	}

	var collapsedClassName = 'vui-heading-collapsible-collapsed';
	var targetClassName = 'vui-heading-collapsible-target';
	var targetCollapsedClassName = 'vui-heading-collapsible-target-collapsed';
	var hoverClassName = 'vui-heading-collapsible-h';
	var transitionEnd = 'transitionend webkitTransitionEnd';
	var transitionClassName = 'vui-heading-collapsible-transition';

	var $ = vui.$;

	$.widget( 'vui.vui_collapsibleSection', {

		_create: function() {

			var me = this;

			var $elem = this.element;

			var targetInfo = this._getTargetInfo( $elem );
			if( targetInfo === null ) {
				return;
			}
			this.target = targetInfo.$;

			$elem.contents().wrapAll( '' );
			this.anchor = $elem.find( 'a');

			this.icon = $( '' )
				.css( 'vertical-align', 'middle' );
			this.anchor.append( this.icon );

			var evtData = {
					anchor: this.anchor,
					icon: this.icon,
					elem: $elem,
					isFirst: true,
					isHover: false,
					target: targetInfo.$
				};

			$elem
				.on( 'vui-collapse', evtData, this._handleCollapse )
				.on( 'vui-expand', evtData, this._handleExpand )
				.on( 'click.vui', this._handleClick )
				.on( 'mouseover.vui', evtData, this._handleHover )
				.on( 'mouseout.vui', evtData, this._handleBlur )
				.trigger(  targetInfo.isVisible ? 'vui-expand': 'vui-collapse' );

			this.anchor
				.attr( 'aria-controls', targetInfo.id )
				.on( 'focus', evtData, this._handleHover )
				.on( 'blur', evtData, this._handleBlur );

			this.target
				.addClass( targetClassName )
				.on( transitionEnd, evtData, this._handleTransitionEnd );

		},

		_destroy: function () {

			var $elem = this.element;

			$elem
				.off( 'vui-collapse vui-expand click.vui mouseover.vui mouseout.vui' )
				.removeClass( collapsedClassName );

			this.icon.remove();
			this.anchor.contents().unwrap();

			this.target
				.removeClass(
					targetClassName + ' ' +
					targetCollapsedClassName + ' ' +
					transitionClassName
				)
				.off( transitionEnd, this.m_handleTransitionEnd )
				.removeAttr( 'aria-hidden' )
				.removeData( 'height' );

		},

		_getTargetInfo: function( $elem ) {

			var targetId = $elem.attr( 'data-target' );
			if( targetId === undefined ) {
				return null;
			}

			var target = document.getElementById( targetId );
			if( target === null ) {
				return null;
			}

			var $target = $( target );

			var targetInfo = {
					$: $target,
					id: targetId,
					isVisible: $target.is(":visible")
				};

			// initially hidden, we need to calculate height
			if( !targetInfo.isVisible ) {
				$target.css(
						{
							position: 'absolute',
							visibility: 'hidden',
							display: 'block'
						}
					);
			}

			$target.data( 'height', $target.outerHeight( false ) );

			if( !targetInfo.isVisible ) {
				$target.css(
						{
							position: 'static',
							visibility: 'visible',
							display: 'none'
						}
					);
			}

			return targetInfo;

		},

		_handleBlur: function( evt ) {

			evt.data.isHover = false;

			var isCollapsed = evt.data.elem
				.is('.vui-heading-collapsible-collapsed');

			evt.data.elem.removeClass( hoverClassName );

			evt.data.icon.attr(
					'class',
					isCollapsed ? 'vui-icon-expand' : 'vui-icon-collapse'
				);

		},

		_handleClick: function( evt ) {

			var isCollapsed = $( this )
				.is('.vui-heading-collapsible-collapsed');
			$( this ).trigger( isCollapsed ? 'vui-expand' : 'vui-collapse' );

		},

		_handleCollapse: function( evt ) {

			evt.data.isFirst = false;

			evt.data.elem
				.addClass( collapsedClassName );

			var className = evt.data.isHover ?
				'vui-icon-expand-h' : 'vui-icon-expand';

			evt.data.icon
				.attr( 'class', className );

			evt.data.anchor
				.attr( 'aria-expanded', false );

			evt.data.target
				.attr( 'aria-hidden', true );

			var targetIsVisible = evt.data.target.is(":visible");
			if( targetIsVisible ) {
				var targetHeight = evt.data.target.outerHeight( false );
				evt.data.target
					.data( 'height', targetHeight )
					.css( 'height', targetHeight + 'px' );
			}

			setTimeout( function() {
					evt.data.target
						.addClass( transitionClassName + ' ' + targetCollapsedClassName )
						.css( 'height', '' );
				}, 50 );

		},

		_handleExpand: function( evt ) {

			var className = evt.data.isHover ?
				'vui-icon-collapse-h' : 'vui-icon-collapse';

			evt.data.elem
				.removeClass( collapsedClassName );

			evt.data.icon
				.attr( 'class', className );

			evt.data.anchor
				.attr( 'aria-expanded', true );

			evt.data.target
				.css( 'display', 'block' )
				.attr( 'aria-hidden', false );

			if( evt.data.isFirst ) {
				evt.data.isFirst = false;
				return;
			}

			setTimeout( function() {
				evt.data.target
					.addClass( transitionClassName )
					.removeClass( targetCollapsedClassName )
					.css( {
							'height': evt.data.target.data('height') + 'px'
						} );
				}, 50 );

		},

		_handleHover: function( evt ) {

			evt.data.isHover = true;

			var isCollapsed = evt.data.elem
				.is('.vui-heading-collapsible-collapsed');

			evt.data.elem.addClass( hoverClassName );

			evt.data.icon.attr(
					'class',
					isCollapsed ? 'vui-icon-expand-h' : 'vui-icon-collapse-h'
				);

		},

		_handleTransitionEnd: function( evt ) {

			if( evt.originalEvent.propertyName != 'height' ) {
				return;
			}

			evt.data.target.removeClass( transitionClassName );

			var isCollapsed = evt.data.elem
				.is('.vui-heading-collapsible-collapsed');
			if( isCollapsed ) {
				evt.data.target.css( 'display', 'none' );
			} else {
				evt.data.target.css( 'height', '' );
			}

		}

	} );

	vui.addClassInitializer(
			'vui-heading-collapsible',
			function( node ) {
				$( node ).vui_collapsibleSection();
			}
		);

} )( window.vui );<commit_msg>Namespacing the transitionend event so we can remove it without a handle.<commit_after>/*jslint browser: true*/

(function( vui ) {

	'use strict';

	// Check if the provided vui global is defined, otherwise try to require it if
	// we're in a CommonJS environment; otherwise we'll just fail out
	if( vui === undefined ) {
		if( typeof require === 'function' ) {
			vui = require('../../core');
		} else {
			throw new Error('load vui first');
		}
	}

	// Export the vui object if we're in a CommonJS environment.
	// It will already be on the window otherwise
	if( typeof module === 'object' && typeof module.exports === 'object' ) {
		module.exports = vui;
	}

	var collapsedClassName = 'vui-heading-collapsible-collapsed';
	var targetClassName = 'vui-heading-collapsible-target';
	var targetCollapsedClassName = 'vui-heading-collapsible-target-collapsed';
	var hoverClassName = 'vui-heading-collapsible-h';
	var transitionEnd = 'transitionend.vui webkitTransitionEnd.vui';
	var transitionClassName = 'vui-heading-collapsible-transition';

	var $ = vui.$;

	$.widget( 'vui.vui_collapsibleSection', {

		_create: function() {

			var me = this;

			var $elem = this.element;

			var targetInfo = this._getTargetInfo( $elem );
			if( targetInfo === null ) {
				return;
			}
			this.target = targetInfo.$;

			$elem.contents().wrapAll( '' );
			this.anchor = $elem.find( 'a');

			this.icon = $( '' )
				.css( 'vertical-align', 'middle' );
			this.anchor.append( this.icon );

			var evtData = {
					anchor: this.anchor,
					icon: this.icon,
					elem: $elem,
					isFirst: true,
					isHover: false,
					target: targetInfo.$
				};

			$elem
				.on( 'vui-collapse', evtData, this._handleCollapse )
				.on( 'vui-expand', evtData, this._handleExpand )
				.on( 'click.vui', this._handleClick )
				.on( 'mouseover.vui', evtData, this._handleHover )
				.on( 'mouseout.vui', evtData, this._handleBlur )
				.trigger(  targetInfo.isVisible ? 'vui-expand': 'vui-collapse' );

			this.anchor
				.attr( 'aria-controls', targetInfo.id )
				.on( 'focus', evtData, this._handleHover )
				.on( 'blur', evtData, this._handleBlur );

			this.target
				.addClass( targetClassName )
				.on( transitionEnd, evtData, this._handleTransitionEnd );

		},

		_destroy: function () {

			var $elem = this.element;

			$elem
				.off( 'vui-collapse vui-expand click.vui mouseover.vui mouseout.vui' )
				.removeClass( collapsedClassName );

			this.icon.remove();
			this.anchor.contents().unwrap();

			this.target
				.removeClass(
					targetClassName + ' ' +
					targetCollapsedClassName + ' ' +
					transitionClassName
				)
				.off( transitionEnd )
				.removeAttr( 'aria-hidden' )
				.removeData( 'height' );

		},

		_getTargetInfo: function( $elem ) {

			var targetId = $elem.attr( 'data-target' );
			if( targetId === undefined ) {
				return null;
			}

			var target = document.getElementById( targetId );
			if( target === null ) {
				return null;
			}

			var $target = $( target );

			var targetInfo = {
					$: $target,
					id: targetId,
					isVisible: $target.is(":visible")
				};

			// initially hidden, we need to calculate height
			if( !targetInfo.isVisible ) {
				$target.css(
						{
							position: 'absolute',
							visibility: 'hidden',
							display: 'block'
						}
					);
			}

			$target.data( 'height', $target.outerHeight( false ) );

			if( !targetInfo.isVisible ) {
				$target.css(
						{
							position: 'static',
							visibility: 'visible',
							display: 'none'
						}
					);
			}

			return targetInfo;

		},

		_handleBlur: function( evt ) {

			evt.data.isHover = false;

			var isCollapsed = evt.data.elem
				.is('.vui-heading-collapsible-collapsed');

			evt.data.elem.removeClass( hoverClassName );

			evt.data.icon.attr(
					'class',
					isCollapsed ? 'vui-icon-expand' : 'vui-icon-collapse'
				);

		},

		_handleClick: function( evt ) {

			var isCollapsed = $( this )
				.is('.vui-heading-collapsible-collapsed');
			$( this ).trigger( isCollapsed ? 'vui-expand' : 'vui-collapse' );

		},

		_handleCollapse: function( evt ) {

			evt.data.isFirst = false;

			evt.data.elem
				.addClass( collapsedClassName );

			var className = evt.data.isHover ?
				'vui-icon-expand-h' : 'vui-icon-expand';

			evt.data.icon
				.attr( 'class', className );

			evt.data.anchor
				.attr( 'aria-expanded', false );

			evt.data.target
				.attr( 'aria-hidden', true );

			var targetIsVisible = evt.data.target.is(":visible");
			if( targetIsVisible ) {
				var targetHeight = evt.data.target.outerHeight( false );
				evt.data.target
					.data( 'height', targetHeight )
					.css( 'height', targetHeight + 'px' );
			}

			setTimeout( function() {
					evt.data.target
						.addClass( transitionClassName + ' ' + targetCollapsedClassName )
						.css( 'height', '' );
				}, 50 );

		},

		_handleExpand: function( evt ) {

			var className = evt.data.isHover ?
				'vui-icon-collapse-h' : 'vui-icon-collapse';

			evt.data.elem
				.removeClass( collapsedClassName );

			evt.data.icon
				.attr( 'class', className );

			evt.data.anchor
				.attr( 'aria-expanded', true );

			evt.data.target
				.css( 'display', 'block' )
				.attr( 'aria-hidden', false );

			if( evt.data.isFirst ) {
				evt.data.isFirst = false;
				return;
			}

			setTimeout( function() {
				evt.data.target
					.addClass( transitionClassName )
					.removeClass( targetCollapsedClassName )
					.css( {
							'height': evt.data.target.data('height') + 'px'
						} );
				}, 50 );

		},

		_handleHover: function( evt ) {

			evt.data.isHover = true;

			var isCollapsed = evt.data.elem
				.is('.vui-heading-collapsible-collapsed');

			evt.data.elem.addClass( hoverClassName );

			evt.data.icon.attr(
					'class',
					isCollapsed ? 'vui-icon-expand-h' : 'vui-icon-collapse-h'
				);

		},

		_handleTransitionEnd: function( evt ) {

			if( evt.originalEvent.propertyName != 'height' ) {
				return;
			}

			evt.data.target.removeClass( transitionClassName );

			var isCollapsed = evt.data.elem
				.is('.vui-heading-collapsible-collapsed');
			if( isCollapsed ) {
				evt.data.target.css( 'display', 'none' );
			} else {
				evt.data.target.css( 'height', '' );
			}

		}

	} );

	vui.addClassInitializer(
			'vui-heading-collapsible',
			function( node ) {
				$( node ).vui_collapsibleSection();
			}
		);

} )( window.vui );<|endoftext|>


<commit_before>//define AutoForm object; used for forms that are not related to collections

// @export AutoForm
AutoForm = function(schema) {
    var self = this;
    //public properties
    self.invalidFields = [];
    self.deps = {};
    //set up validation dependencies
    var fieldNames = _.keys(schema);
    _.each(fieldNames, function(name) {
        self.deps[name] = new Deps.Dependency;
    });
    //private properties
    self._schema = schema;
    self._simpleSchema = new SimpleSchema(schema);
};

_.extend(AutoForm.prototype, {
    validate: function(doc) {
        var self = this,
                schema = self._simpleSchema,
                addedFields = [],
                removedFields = [],
                changedFields = [];

        //whitelist
        doc = schema.filter(doc);
        doc = schema.autoTypeConvert(doc);

        //note any currently invalid fields so that we can mark them as changed
        //due to new validation (they may be valid now, or invalid in a different way)
        _.each(self.invalidFields, function(obj) {
            removedFields.push(obj.name);
        });

        //perform validation
        self.invalidFields = schema.validate(doc);

        //add newly invalid fields to changedFields
        _.each(self.invalidFields, function(obj) {
            addedFields.push(obj.name);
        });

        //mark all changed fields as changed
        changedFields = _.union(addedFields, removedFields);
        _.each(changedFields, function(name) {
            self.deps[name].changed();
        });

        return !!self.invalidFields.length;
    },
    resetValidation: function() {
        var self = this, removedFields = [];
        _.each(self.invalidFields, function(obj) {
            removedFields.push(obj.name);
        });
        self.invalidFields = [];
        _.each(removedFields, function(name) {
            self.deps[name].changed();
        });
    },
    schema: function(field) {
        if (field) {
            return this._schema[field];
        } else {
            return this._schema;
        }
    },
    simpleSchema: function() {
        return this._simpleSchema;
    }
});<commit_msg>fix return value<commit_after>//define AutoForm object; used for forms that are not related to collections

// @export AutoForm
AutoForm = function(schema) {
    var self = this;
    //public properties
    self.invalidFields = [];
    self.deps = {};
    //set up validation dependencies
    var fieldNames = _.keys(schema);
    _.each(fieldNames, function(name) {
        self.deps[name] = new Deps.Dependency;
    });
    //private properties
    self._schema = schema;
    self._simpleSchema = new SimpleSchema(schema);
};

_.extend(AutoForm.prototype, {
    validate: function(doc) {
        var self = this,
                schema = self._simpleSchema,
                addedFields = [],
                removedFields = [],
                changedFields = [];

        //whitelist
        doc = schema.filter(doc);
        doc = schema.autoTypeConvert(doc);

        //note any currently invalid fields so that we can mark them as changed
        //due to new validation (they may be valid now, or invalid in a different way)
        _.each(self.invalidFields, function(obj) {
            removedFields.push(obj.name);
        });

        //perform validation
        self.invalidFields = schema.validate(doc);

        //add newly invalid fields to changedFields
        _.each(self.invalidFields, function(obj) {
            addedFields.push(obj.name);
        });

        //mark all changed fields as changed
        changedFields = _.union(addedFields, removedFields);
        _.each(changedFields, function(name) {
            self.deps[name].changed();
        });

        return !self.invalidFields.length;
    },
    resetValidation: function() {
        var self = this, removedFields = [];
        _.each(self.invalidFields, function(obj) {
            removedFields.push(obj.name);
        });
        self.invalidFields = [];
        _.each(removedFields, function(name) {
            self.deps[name].changed();
        });
    },
    schema: function(field) {
        if (field) {
            return this._schema[field];
        } else {
            return this._schema;
        }
    },
    simpleSchema: function() {
        return this._simpleSchema;
    }
});<|endoftext|>


<commit_before>'use strict';
const gulp          = require('gulp');
const plugins       = require('gulp-load-plugins');
const $             = plugins();
const config        = require('../config');
const onError       = require('./error');

gulp.task('imagemin', done => {
  return gulp.src('./src/images/**/*')
  .pipe( $.plumber( {errorHandler : onError} ) )
  .pipe( $.imagemin({
    progressive : true,
    multipass : true,
    svgoPlugins : [{
      removeViewBox : false,
      removeDimensions : true
    }]
  }) )
  .pipe( gulp.dest(`${config.exportPath}/images`) );
  done();
});
<commit_msg>fixed imagemin task<commit_after>'use strict';
const gulp          = require('gulp');
const plugins       = require('gulp-load-plugins');
const $             = plugins();
const config        = require('../config');
const onError       = require('./error');

gulp.task('imagemin', done => {
  return gulp.src('./src/images/**/*')
  .pipe( $.plumber( {errorHandler : onError} ) )
  .pipe( $.imagemin({
    progressive : true,
    multipass : true,
    svgoPlugins : [{
      removeViewBox : false,
      removeDimensions : true
    }]
  }) )
  .pipe( gulp.dest(`${config.distFolder}/assets/images`) );
  done();
});
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2009-2010 The Open Planning Project
 *
 * @requires GeoExplorer.js
 */

/** api: (define)
 *  module = GeoExplorer
 *  class = Embed
 *  base_link = GeoExplorer
 */
Ext.namespace("GeoExplorer");

/** api: constructor
 *  ..class:: GeoExplorer.Viewer(config)
 *
 *  Create a GeoExplorer application suitable for embedding in larger pages.
 */
GeoExplorer.Viewer = Ext.extend(GeoExplorer, {

    applyConfig: function(config) {
        var allTools = config.viewerTools || this.viewerTools;
        var tools = [];
        var toolConfig;
        // we need to start counting at 3 since there is the Layer Switcher,
        // logo and a split button already
        var counter = 3;
        for (var i=0, len=allTools.length; i<len; i++) {
            var tool = allTools[i];
            if (tool.checked === true) {
                var properties = ['checked', 'iconCls', 'id', 'leaf', 'loader', 'text'];
                for (var key in properties) {
                    delete tool[properties[key]];
                }
                toolConfig = Ext.applyIf({
                    actionTarget: {target: "paneltbar", index: counter}
                }, tool);
                if (tool.numberOfButtons !== undefined) {
                    counter += tool.numberOfButtons;
                } else {
                    counter++;
                }
                tools.push(toolConfig);
            }
        }
		searchTool = {
			ptype: 'app_geocoder',
			outputTarget: "paneltbar"
			};
		tools.push(searchTool);

		expandTool = {
			ptype: "gxp_vanviewernaarcomposer",
			actionTarget: "paneltbar"
			};
		tools.push(expandTool);

        config.tools = tools;
        GeoExplorer.Viewer.superclass.applyConfig.call(this, config);
    },

    /** private: method[initPortal]
     * Create the various parts that compose the layout.
     */
    initPortal: function() {

        this.toolbar = new Ext.Toolbar({
            disabled: true,
            id: "paneltbar",
            items: this.createTools()
        });
        this.on("ready", function() {this.toolbar.enable();}, this);

        this.mapPanelContainer = new Ext.Panel({
            layout: "card",
            region: "center",
            tbar: this.toolbar,
            defaults: {
                border: false
            },
            items: [
                this.mapPanel
            ],
            activeItem: 0
        });

        var tb = new Ext.Container({
        	style: "background-color: #00A5C7; padding : 5px;",
        	height: 65,
        	html:	"
" + app.about.title  + "
" +
        			"" + app.about['abstract']  + "
"
        	});

        this.portalItems = [{
            region: "center",
            layout: "border",
            tbar: tb,
            items: [
                this.mapPanelContainer
            ]
        }];

        GeoExplorer.superclass.initPortal.apply(this, arguments);

    },

    /**
     * api: method[createTools]
     * Create the various parts that compose the layout.
     */
    createTools: function() {
        var tools = GeoExplorer.Viewer.superclass.createTools.apply(this, arguments);

		var aboutButton = new Ext.Button({
            scale: 'logoklein',
            iconCls: "icon-logo-klein",
            handleMouseEvents: false
        });

        var layerChooser = new Ext.Button({
            tooltip: 'Layer Switcher',
            iconCls: 'icon-layer-switcher',
            menu: new gxp.menu.LayerMenu({
                layers: this.mapPanel.layers
            })
        });

        tools.unshift("-");
        tools.unshift(layerChooser);
        tools.unshift(aboutButton);

        tools.push("->");

        return tools;
    }
});
<commit_msg>Slightly smaller map title bar<commit_after>/**
 * Copyright (c) 2009-2010 The Open Planning Project
 *
 * @requires GeoExplorer.js
 */

/** api: (define)
 *  module = GeoExplorer
 *  class = Embed
 *  base_link = GeoExplorer
 */
Ext.namespace("GeoExplorer");

/** api: constructor
 *  ..class:: GeoExplorer.Viewer(config)
 *
 *  Create a GeoExplorer application suitable for embedding in larger pages.
 */
GeoExplorer.Viewer = Ext.extend(GeoExplorer, {

    applyConfig: function(config) {
        var allTools = config.viewerTools || this.viewerTools;
        var tools = [];
        var toolConfig;
        // we need to start counting at 3 since there is the Layer Switcher,
        // logo and a split button already
        var counter = 3;
        for (var i=0, len=allTools.length; i<len; i++) {
            var tool = allTools[i];
            if (tool.checked === true) {
                var properties = ['checked', 'iconCls', 'id', 'leaf', 'loader', 'text'];
                for (var key in properties) {
                    delete tool[properties[key]];
                }
                toolConfig = Ext.applyIf({
                    actionTarget: {target: "paneltbar", index: counter}
                }, tool);
                if (tool.numberOfButtons !== undefined) {
                    counter += tool.numberOfButtons;
                } else {
                    counter++;
                }
                tools.push(toolConfig);
            }
        }
		searchTool = {
			ptype: 'app_geocoder',
			outputTarget: "paneltbar"
			};
		tools.push(searchTool);

		expandTool = {
			ptype: "gxp_vanviewernaarcomposer",
			actionTarget: "paneltbar"
			};
		tools.push(expandTool);

        config.tools = tools;
        GeoExplorer.Viewer.superclass.applyConfig.call(this, config);
    },

    /** private: method[initPortal]
     * Create the various parts that compose the layout.
     */
    initPortal: function() {

        this.toolbar = new Ext.Toolbar({
            disabled: true,
            id: "paneltbar",
            items: this.createTools()
        });
        this.on("ready", function() {this.toolbar.enable();}, this);

        this.mapPanelContainer = new Ext.Panel({
            layout: "card",
            region: "center",
            tbar: this.toolbar,
            defaults: {
                border: false
            },
            items: [
                this.mapPanel
            ],
            activeItem: 0
        });

        var tb = new Ext.Container({
        	style: "background-color: #00A5C7; padding : 5px;",
        	height: 50,
        	html:	"
" + app.about.title  + "
" +
        			"" + app.about['abstract']  + "
"
        	});

        this.portalItems = [{
            region: "center",
            layout: "border",
            tbar: tb,
            items: [
                this.mapPanelContainer
            ]
        }];

        GeoExplorer.superclass.initPortal.apply(this, arguments);

    },

    /**
     * api: method[createTools]
     * Create the various parts that compose the layout.
     */
    createTools: function() {
        var tools = GeoExplorer.Viewer.superclass.createTools.apply(this, arguments);

		var aboutButton = new Ext.Button({
            scale: 'logoklein',
            iconCls: "icon-logo-klein",
            handleMouseEvents: false
        });

        var layerChooser = new Ext.Button({
            tooltip: 'Layer Switcher',
            iconCls: 'icon-layer-switcher',
            menu: new gxp.menu.LayerMenu({
                layers: this.mapPanel.layers
            })
        });

        tools.unshift("-");
        tools.unshift(layerChooser);
        tools.unshift(aboutButton);

        tools.push("->");

        return tools;
    }
});
<|endoftext|>