<commit_before>/*globals formSerialize, JsonRefs, getJSON, jml*/
(function () {'use strict';

// Todo: change $ref usages to utilize JSON Reference ( https://github.com/whitlockjc/json-refs ) + JSON Pointer-aware library ( https://github.com/manuelstofer/json-pointer ?)

document.title = "Sacred Writings Browser";

// Need for directionality even if language specified (and we don't want to require it as a param)
getJSON('appdata/languages.json', function (langData) {

var langs = langData.languages;

function getDirectionForLanguageCode (code) {
    return langs.find(function (lang) {
        return lang.code === code;
    }).direction;
}

function paramChange () {

    document.body.parentNode.replaceChild(document.createElement('body'), document.body);

    var params = new URLSearchParams(location.hash.slice(1));
    var language = params.get('lang');

    if (!language) {
        jml('div', {'class': 'focus'},
            [['select', {size: langs.length, $on: {change: function (e) {
                params.set('lang', e.target.selectedOptions[0].value);
                location.hash = '#' + params.toString();
            }}}, langs.map(function (lang) {
                return ['option', {value: lang.code}, [lang.name]];
            })]], document.body

            /* Works too:
            langs.map(function (lang) {
                return ['div', [
                    ['a', {href: '#', dataset: {code: lang.code}}, [lang.name]]
                ]];
            }), document.body
            */
        );
        return;
    }

    var lang = language.split('.');

    IMF({
        languages: lang,
        localeFileResolver: function (code) {
            return langData.localeFileBasePath + langs.find(function (lang) {
                return lang.code === code;
            }).locale.$ref; // Todo: We might instead resolve all $ref (as with https://github.com/whitlockjc/json-refs ) and replace IMF() loadLocales behavior with our own now resolved locales; see https://github.com/jdorn/json-editor/issues/132
        },
        callback: function (l, defineFormatter) {

            var ta = defineFormatter('tablealias');

            var direction = getDirectionForLanguageCode(lang[0]);

            getJSON('appdata/files.json', function (dbs) {
                var fileGroups = dbs.groups;
                jml(
                    'div',
                    {'class': 'focus ' + direction},
                    fileGroups.map(function (fileGroup, i) {
                        return ['div', [
                            (i > 0 ? ['br', 'br', 'br'] : ''),
                            ['div', [l(fileGroup.directions)]],
                            ['br'],
                            ['select', {'class': 'file', dataset: {name: fileGroup.name}, $on: {change: function (e) {
                                // Submit
                                // alert(e.target.dataset.name);

                                // Use the following to dynamically add specific file schema in place of generic table schema if validating against files.jsonschema
                                // filesSchema.properties.groups.items.properties.files.items.properties.file.anyOf.splice(1, 1, {$ref: schemaFile});

                                var dataset = e.target.selectedOptions[0].dataset;

                                if (dataset.fileSchema) {
                                    getJSON(
                                        dataset.fileSchema, // Change fileSchema to JSON refs?
                                        function (schema) {
                                            alert(JSON.stringify(schema));
                                        }
                                    );
                                }
                                else {
                                    JsonRefs.resolveRefs({$ref: window.location.href.replace(/(index\.html)?#.*$/, '') + '' + dataset.file + '#/metadata' },
                                    {
                                        // Temporary fix for lack of resolution of relative references: https://github.com/whitlockjc/json-refs/issues/11
                                        processContent: function (content) {
                                            var json = JSON.parse(content);
                                            Object.keys(JsonRefs.findRefs(json)).forEach(function (path) {
                                                var lastParent;
                                                var value = JsonRefs.pathFromPointer(path).reduce(function (json, pathSeg) {
                                                    lastParent = json;
                                                    return json[pathSeg];
                                                }, json);
                                                lastParent.$ref = 'http://127.0.0.1/textbrowser/data/writings/' + value;
                                            });
                                            return json;
                                        }
                                    },
                                    function (err, rJson, metadata) {
                                        if (err) {throw err;}

                                        alert('done:'+JSON.stringify(rJson));
                                        alert('meta:'+JSON.stringify(metadata));
                                    });
                                }

                                // todo: alias fields

                                /*
                                getJSON(dataset.file, function (fileJSON) {
                                    alert(JSON.stringify(fileJSON));
                                });
                                */
                            }}},
                                fileGroup.files.map(function (file) {
                                    return ['option', {value: file.name, dataset: {fileSchema: file.fileSchema ? ((dbs.schemaBaseDirectory || fileGroup.schemaBaseDirectory) + '/' + file.fileSchema) : '', file: (dbs.baseDirectory || fileGroup.baseDirectory) + '/' + file.file.$ref}}, [ta(file.name)]];
                                })
                            ],
                            ['p', [
                                ['input', {type: 'button', value: "Go"}]
                            ]]
                        ]];
                    }),
                    document.body
                );
            });

            /*
            Add back to files.json when overcome memory issue when exporting to JSON from BL
            ,
            {
                "name": "Other Writings",
                "directions": "choosewritings_bahai_writingsotherdb",
                "baseDirectory": "other-works",
                "files": [
                    {"file": "Collins.json", "name": "collins"},
                    {"file": "lights.json", "name": "lights"}
                ]
            }
            */

        }
    });

}

// INIT/ADD EVENTS

paramChange();
window.addEventListener('hashchange', paramChange, false);

});

}());
<commit_msg>Make base dir dynamic<commit_after>/*globals formSerialize, JsonRefs, getJSON, jml*/
(function () {'use strict';

// Todo: change $ref usages to utilize JSON Reference ( https://github.com/whitlockjc/json-refs ) + JSON Pointer-aware library ( https://github.com/manuelstofer/json-pointer ?)

document.title = "Sacred Writings Browser";

// Need for directionality even if language specified (and we don't want to require it as a param)
getJSON('appdata/languages.json', function (langData) {

var langs = langData.languages;

function getDirectionForLanguageCode (code) {
    return langs.find(function (lang) {
        return lang.code === code;
    }).direction;
}

function paramChange () {

    document.body.parentNode.replaceChild(document.createElement('body'), document.body);

    var params = new URLSearchParams(location.hash.slice(1));
    var language = params.get('lang');

    if (!language) {
        jml('div', {'class': 'focus'},
            [['select', {size: langs.length, $on: {change: function (e) {
                params.set('lang', e.target.selectedOptions[0].value);
                location.hash = '#' + params.toString();
            }}}, langs.map(function (lang) {
                return ['option', {value: lang.code}, [lang.name]];
            })]], document.body

            /* Works too:
            langs.map(function (lang) {
                return ['div', [
                    ['a', {href: '#', dataset: {code: lang.code}}, [lang.name]]
                ]];
            }), document.body
            */
        );
        return;
    }

    var lang = language.split('.');

    IMF({
        languages: lang,
        localeFileResolver: function (code) {
            return langData.localeFileBasePath + langs.find(function (lang) {
                return lang.code === code;
            }).locale.$ref; // Todo: We might instead resolve all $ref (as with https://github.com/whitlockjc/json-refs ) and replace IMF() loadLocales behavior with our own now resolved locales; see https://github.com/jdorn/json-editor/issues/132
        },
        callback: function (l, defineFormatter) {

            var ta = defineFormatter('tablealias');

            var direction = getDirectionForLanguageCode(lang[0]);

            getJSON('appdata/files.json', function (dbs) {
                var fileGroups = dbs.groups;
                jml(
                    'div',
                    {'class': 'focus ' + direction},
                    fileGroups.map(function (fileGroup, i) {
                        return ['div', [
                            (i > 0 ? ['br', 'br', 'br'] : ''),
                            ['div', [l(fileGroup.directions)]],
                            ['br'],
                            ['select', {'class': 'file', dataset: {name: fileGroup.name}, $on: {change: function (e) {
                                // Submit
                                // alert(e.target.dataset.name);

                                // Use the following to dynamically add specific file schema in place of generic table schema if validating against files.jsonschema
                                // filesSchema.properties.groups.items.properties.files.items.properties.file.anyOf.splice(1, 1, {$ref: schemaFile});

                                var dataset = e.target.selectedOptions[0].dataset;

                                if (dataset.fileSchema) {
                                    getJSON(
                                        dataset.fileSchema, // Change fileSchema to JSON refs?
                                        function (schema) {
                                            alert(JSON.stringify(schema));
                                        }
                                    );
                                }
                                else {
                                    var currDir = window.location.href.replace(/(index\.html)?#.*$/, '');
                                    JsonRefs.resolveRefs({$ref: currDir + dataset.file + '#/metadata' },
                                    {
                                        // Temporary fix for lack of resolution of relative references: https://github.com/whitlockjc/json-refs/issues/11
                                        processContent: function (content) {
                                            var json = JSON.parse(content);
                                            Object.keys(JsonRefs.findRefs(json)).forEach(function (path) {
                                                var lastParent;
                                                var value = JsonRefs.pathFromPointer(path).reduce(function (json, pathSeg) {
                                                    lastParent = json;
                                                    return json[pathSeg];
                                                }, json);
                                                lastParent.$ref = currDir + 'data/writings/' + value;
                                            });
                                            return json;
                                        }
                                    },
                                    function (err, rJson, metadata) {
                                        if (err) {throw err;}

                                        alert('done:'+JSON.stringify(rJson));
                                        // alert('meta:'+JSON.stringify(metadata));
                                    });
                                }

                                // todo: alias fields

                                /*
                                getJSON(dataset.file, function (fileJSON) {
                                    alert(JSON.stringify(fileJSON));
                                });
                                */
                            }}},
                                fileGroup.files.map(function (file) {
                                    return ['option', {value: file.name, dataset: {fileSchema: file.fileSchema ? ((dbs.schemaBaseDirectory || fileGroup.schemaBaseDirectory) + '/' + file.fileSchema) : '', file: (dbs.baseDirectory || fileGroup.baseDirectory) + '/' + file.file.$ref}}, [ta(file.name)]];
                                })
                            ],
                            ['p', [
                                ['input', {type: 'button', value: "Go"}]
                            ]]
                        ]];
                    }),
                    document.body
                );
            });

            /*
            Add back to files.json when overcome memory issue when exporting to JSON from BL
            ,
            {
                "name": "Other Writings",
                "directions": "choosewritings_bahai_writingsotherdb",
                "baseDirectory": "other-works",
                "files": [
                    {"file": "Collins.json", "name": "collins"},
                    {"file": "lights.json", "name": "lights"}
                ]
            }
            */

        }
    });

}

// INIT/ADD EVENTS

paramChange();
window.addEventListener('hashchange', paramChange, false);

});

}());
<|endoftext|>


<commit_before>import test from 'ava';
import fs from 'fs-extra';
import File from '../../src/File';
import assert from '../helpers/assertions';
import webpack from '../helpers/webpack';

import '../helpers/mix';

test('it combines a folder of scripts', async t => {
    let output = `test/fixtures/app/dist/all.js`;

    mix.scripts(`test/fixtures/app/src/js`, output);

    await webpack.compile();

    t.true(File.exists(output));

    t.is(
        "alert('another stub');\n\nalert('stub');\n",
        File.find(output).read()
    );
});

test('it can minify a file', async t => {
    mix.js(`test/fixtures/app/src/js/app.js`, 'js').minify(
        `test/fixtures/app/dist/js/app.js`
    );

    await webpack.compile();

    t.true(File.exists(`test/fixtures/app/dist/js/app.min.js`));

    assert.manifestEquals(
        {
            '/js/app.js': '/js/app.js',
            '/js/app.min.js': '/js/app.min.js'
        },
        t
    );
});

test('it compiles JS and then combines the bundles files.', async t => {
    mix.js(`test/fixtures/app/src/js/app.js`, 'js')
        .js(`test/fixtures/app/src/js/another.js`, 'js')
        .scripts(
            [
                `test/fixtures/app/dist/js/app.js`,
                `test/fixtures/app/dist/js/another.js`
            ],
            `test/fixtures/app/dist/js/all.js`
        );

    await webpack.compile();

    t.true(File.exists(`test/fixtures/app/dist/js/all.js`));

    assert.manifestEquals(
        {
            '/js/app.js': '/js/app.js',
            '/js/another.js': '/js/another.js',
            '/js/all.js': '/js/all.js'
        },
        t
    );
});

test('it concatenates a directory of files, copies the output to a new location, and then minifies it in production mode', async t => {
    Config.production = true;

    // Setup
    new File('test/fixtures/app/src/combine/one.js')
        .makeDirectories()
        .write("alert('one')");

    new File('test/fixtures/app/src/combine/two.js').write("alert('two')");

    mix.scripts(
        [
            `test/fixtures/app/src/combine/one.js`,
            `test/fixtures/app/src/combine/two.js`
        ],
        'test/fixtures/app/dist/output/combined-scripts.js'
    );

    mix.copyDirectory(
        'test/fixtures/app/dist/output',
        'test/fixtures/app/dist/js'
    );

    await webpack.compile();

    let expected = `alert("one"),alert("two");\n`;

    t.is(
        expected,
        File.find('test/fixtures/app/dist/js/combined-scripts.js').read()
    );

    // Clean up
    fs.removeSync('test/fixtures/app/src/combine');
});

test('mix.combine/scripts/styles/babel()', t => {
    t.deepEqual(mix, mix.combine([], 'dist/js/combined.js'));

    t.is(1, Mix.tasks.length);

    t.deepEqual(mix, mix.scripts([], 'dist/js/combined.js'));
    t.deepEqual(mix, mix.babel([], 'dist/js/combined.js'));
});

test('mix.minify()', t => {
    t.deepEqual(mix, mix.minify('dist/js/minify.js'));

    t.is(1, Mix.tasks.length);
});
<commit_msg>Use EOL instead<commit_after>import test from 'ava';
import os from 'os';
import fs from 'fs-extra';
import File from '../../src/File';
import assert from '../helpers/assertions';
import webpack from '../helpers/webpack';

import '../helpers/mix';

test('it combines a folder of scripts', async t => {
    let output = `test/fixtures/app/dist/all.js`;

    mix.scripts(`test/fixtures/app/src/js`, output);

    await webpack.compile();

    t.true(File.exists(output));

    t.is(
        "alert('another stub');\n\nalert('stub');\n",
        File.find(output).read()
    );
});

test('it can minify a file', async t => {
    mix.js(`test/fixtures/app/src/js/app.js`, 'js').minify(
        `test/fixtures/app/dist/js/app.js`
    );

    await webpack.compile();

    t.true(File.exists(`test/fixtures/app/dist/js/app.min.js`));

    assert.manifestEquals(
        {
            '/js/app.js': '/js/app.js',
            '/js/app.min.js': '/js/app.min.js'
        },
        t
    );
});

test('it compiles JS and then combines the bundles files.', async t => {
    mix.js(`test/fixtures/app/src/js/app.js`, 'js')
        .js(`test/fixtures/app/src/js/another.js`, 'js')
        .scripts(
            [
                `test/fixtures/app/dist/js/app.js`,
                `test/fixtures/app/dist/js/another.js`
            ],
            `test/fixtures/app/dist/js/all.js`
        );

    await webpack.compile();

    t.true(File.exists(`test/fixtures/app/dist/js/all.js`));

    assert.manifestEquals(
        {
            '/js/app.js': '/js/app.js',
            '/js/another.js': '/js/another.js',
            '/js/all.js': '/js/all.js'
        },
        t
    );
});

test('it concatenates a directory of files, copies the output to a new location, and then minifies it in production mode', async t => {
    Config.production = true;

    // Setup
    new File('test/fixtures/app/src/combine/one.js')
        .makeDirectories()
        .write("alert('one')");

    new File('test/fixtures/app/src/combine/two.js').write("alert('two')");

    mix.scripts(
        [
            `test/fixtures/app/src/combine/one.js`,
            `test/fixtures/app/src/combine/two.js`
        ],
        'test/fixtures/app/dist/output/combined-scripts.js'
    );

    mix.copyDirectory(
        'test/fixtures/app/dist/output',
        'test/fixtures/app/dist/js'
    );

    await webpack.compile();

    let expected = `alert("one"),alert("two");` + os.EOL;

    t.is(
        expected,
        File.find('test/fixtures/app/dist/js/combined-scripts.js').read()
    );

    // Clean up
    fs.removeSync('test/fixtures/app/src/combine');
});

test('mix.combine/scripts/styles/babel()', t => {
    t.deepEqual(mix, mix.combine([], 'dist/js/combined.js'));

    t.is(1, Mix.tasks.length);

    t.deepEqual(mix, mix.scripts([], 'dist/js/combined.js'));
    t.deepEqual(mix, mix.babel([], 'dist/js/combined.js'));
});

test('mix.minify()', t => {
    t.deepEqual(mix, mix.minify('dist/js/minify.js'));

    t.is(1, Mix.tasks.length);
});
<|endoftext|>


<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const ccxt = require ('ccxt');

//  ---------------------------------------------------------------------------

module.exports = class hitbtc2 extends ccxt.hitbtc2 {
    describe () {
        return this.deepExtend (super.describe (), {
            'has': {
                'ws': true,
                'watchTicker': true,
                'watchTickers': false, // not available on exchange side
                'watchTrades': false, // not implemented yet
                'watchOrderBook': true,
                'watchBalance': false, // not implemented yet
                'watchOHLCV': false, // not implemented yet
            },
            'urls': {
                'api': {
                    'ws': 'wss://api.hitbtc.com/api/2/ws',
                },
            },
            'options': {
                'tradesLimit': 1000,
            },
        });
    }

    async watchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        const market = this.market (symbol);
        const url = this.urls['api']['ws'];
        const messageHash = 'orderbook:' + market['id'];
        const request = {
            'method': 'subscribeOrderbook',
            'params': {
                'symbol': market['id'],
            },
            'id': market['id'],
        };
        const future = this.watch (url, messageHash, request, messageHash);
        return await this.after (future, this.limitOrderBook, symbol, limit, params);
    }

    handleOrderBookSnapshot (client, message) {
        const params = this.safeValue (message, 'params', {});
        const marketId = this.safeString (params, 'symbol');
        let market = undefined;
        let symbol = undefined;
        if (marketId !== undefined) {
            if (marketId in this.markets_by_id) {
                market = this.markets_by_id[marketId];
                symbol = market['symbol'];
            }
        }
        if (symbol === undefined) {
            // if symbol is not available we just return
            return;
        }
        const timestamp = this.parse8601 (this.safeString (params, 'timestamp'));
        const nonce = this.safeInteger (params, 'sequence');
        if (symbol in this.orderbooks) {
            delete this.orderbooks[symbol];
        }
        const snapshot = this.parseOrderBook (params, timestamp, 'bid', 'ask', 'price', 'size');
        const orderbook = this.orderBook (snapshot);
        orderbook['nonce'] = nonce;
        this.orderbooks[symbol] = orderbook;
        const messageHash = 'orderbook:' + marketId;
        client.resolve (orderbook, messageHash);
    }

    handleUpdateOrderbook (client, message) {
        const params = this.safeValue (message, 'params', {});
        const marketId = this.safeString (params, 'symbol');
        let market = undefined;
        let symbol = undefined;
        if (marketId !== undefined) {
            if (marketId in this.markets_by_id) {
                market = this.markets_by_id[marketId];
                symbol = market['symbol'];
            }
        }
        if (symbol === undefined) {
            // if symbol is not available we just return
            return;
        }
        const timestamp = this.parse8601 (this.safeString (params, 'timestamp'));
        const nonce = this.safeInteger (params, 'sequence');
        if (symbol in this.orderbooks) {
            const orderbook = this.orderbooks[symbol];
            const asks = this.safeValue (params, 'ask', []);
            const bids = this.safeValue (params, 'bid', []);
            this.updateOrders (orderbook['asks'], asks);
            this.updateOrders (orderbook['bids'], bids);
            orderbook['timestamp'] = timestamp;
            orderbook['datetime'] = this.iso8601 (timestamp);
            orderbook['nonce'] = nonce;
            this.orderbooks[symbol] = orderbook;
            const messageHash = 'orderbook:' + marketId;
            client.resolve (orderbook, messageHash);
        }
    }

    updateOrders (bookside, data) {
        for (let i = 0; i < data.length; i++) {
            const delta = data[i];
            const price = this.safeFloat (delta, 'price');
            const amount = this.safeFloat (delta, 'size');
            bookside.store (price, amount);
        }
    }

    async watchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        const market = this.market (symbol);
        const url = this.urls['api']['ws'];
        const messageHash = 'ticker:' + market['id'];
        const request = {
            'method': 'subscribeTicker',
            'params': {
                'symbol': market['id'],
            },
            'id': market['id'],
        };
        return await this.watch (url, messageHash, request, messageHash);
    }

    handleTicker (client, message) {
        const params = this.safeValue (message, 'params');
        const marketId = this.safeValue (params, 'symbol');
        let market = undefined;
        let symbol = undefined;
        if (marketId !== undefined) {
            if (marketId in this.markets_by_id) {
                market = this.markets_by_id[marketId];
                symbol = market['symbol'];
            }
        }
        if (market === undefined || symbol === undefined) {
            // if market or symbol is undefined we just return
            return;
        }
        const result = this.parseTicker (params, market);
        this.tickers[symbol] = result;
        const messageHash = 'ticker:' + marketId;
        client.resolve (result, messageHash);
    }

    signMessage (client, messageHash, message, params = {}) {
        // todo: implement hitbtc2 signMessage
        return message;
    }

    handleNotification (client, message) {
        // TODO
        return message;
    }

    handleMessage (client, message) {
        const methods = {
            'snapshotOrderbook': this.handleOrderBookSnapshot,
            'updateOrderbook': this.handleUpdateOrderbook,
            'ticker': this.handleTicker,
        };
        const event = this.safeString (message, 'method');
        const method = this.safeValue (methods, event);
        if (method === undefined) {
            this.handleNotification (client, message);
        } else {
            method.call (this, client, message);
        }
    }
};
<commit_msg>hitbtc2 → hitbtc<commit_after>'use strict';

//  ---------------------------------------------------------------------------

const ccxt = require ('ccxt');

//  ---------------------------------------------------------------------------

module.exports = class hitbtc extends ccxt.hitbtc {
    describe () {
        return this.deepExtend (super.describe (), {
            'has': {
                'ws': true,
                'watchTicker': true,
                'watchTickers': false, // not available on exchange side
                'watchTrades': false, // not implemented yet
                'watchOrderBook': true,
                'watchBalance': false, // not implemented yet
                'watchOHLCV': false, // not implemented yet
            },
            'urls': {
                'api': {
                    'ws': 'wss://api.hitbtc.com/api/2/ws',
                },
            },
            'options': {
                'tradesLimit': 1000,
            },
        });
    }

    async watchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        const market = this.market (symbol);
        const url = this.urls['api']['ws'];
        const messageHash = 'orderbook:' + market['id'];
        const request = {
            'method': 'subscribeOrderbook',
            'params': {
                'symbol': market['id'],
            },
            'id': market['id'],
        };
        const future = this.watch (url, messageHash, request, messageHash);
        return await this.after (future, this.limitOrderBook, symbol, limit, params);
    }

    handleOrderBookSnapshot (client, message) {
        const params = this.safeValue (message, 'params', {});
        const marketId = this.safeString (params, 'symbol');
        let market = undefined;
        let symbol = undefined;
        if (marketId !== undefined) {
            if (marketId in this.markets_by_id) {
                market = this.markets_by_id[marketId];
                symbol = market['symbol'];
            }
        }
        if (symbol === undefined) {
            // if symbol is not available we just return
            return;
        }
        const timestamp = this.parse8601 (this.safeString (params, 'timestamp'));
        const nonce = this.safeInteger (params, 'sequence');
        if (symbol in this.orderbooks) {
            delete this.orderbooks[symbol];
        }
        const snapshot = this.parseOrderBook (params, timestamp, 'bid', 'ask', 'price', 'size');
        const orderbook = this.orderBook (snapshot);
        orderbook['nonce'] = nonce;
        this.orderbooks[symbol] = orderbook;
        const messageHash = 'orderbook:' + marketId;
        client.resolve (orderbook, messageHash);
    }

    handleUpdateOrderbook (client, message) {
        const params = this.safeValue (message, 'params', {});
        const marketId = this.safeString (params, 'symbol');
        let market = undefined;
        let symbol = undefined;
        if (marketId !== undefined) {
            if (marketId in this.markets_by_id) {
                market = this.markets_by_id[marketId];
                symbol = market['symbol'];
            }
        }
        if (symbol === undefined) {
            // if symbol is not available we just return
            return;
        }
        const timestamp = this.parse8601 (this.safeString (params, 'timestamp'));
        const nonce = this.safeInteger (params, 'sequence');
        if (symbol in this.orderbooks) {
            const orderbook = this.orderbooks[symbol];
            const asks = this.safeValue (params, 'ask', []);
            const bids = this.safeValue (params, 'bid', []);
            this.updateOrders (orderbook['asks'], asks);
            this.updateOrders (orderbook['bids'], bids);
            orderbook['timestamp'] = timestamp;
            orderbook['datetime'] = this.iso8601 (timestamp);
            orderbook['nonce'] = nonce;
            this.orderbooks[symbol] = orderbook;
            const messageHash = 'orderbook:' + marketId;
            client.resolve (orderbook, messageHash);
        }
    }

    updateOrders (bookside, data) {
        for (let i = 0; i < data.length; i++) {
            const delta = data[i];
            const price = this.safeFloat (delta, 'price');
            const amount = this.safeFloat (delta, 'size');
            bookside.store (price, amount);
        }
    }

    async watchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        const market = this.market (symbol);
        const url = this.urls['api']['ws'];
        const messageHash = 'ticker:' + market['id'];
        const request = {
            'method': 'subscribeTicker',
            'params': {
                'symbol': market['id'],
            },
            'id': market['id'],
        };
        return await this.watch (url, messageHash, request, messageHash);
    }

    handleTicker (client, message) {
        const params = this.safeValue (message, 'params');
        const marketId = this.safeValue (params, 'symbol');
        let market = undefined;
        let symbol = undefined;
        if (marketId !== undefined) {
            if (marketId in this.markets_by_id) {
                market = this.markets_by_id[marketId];
                symbol = market['symbol'];
            }
        }
        if (market === undefined || symbol === undefined) {
            // if market or symbol is undefined we just return
            return;
        }
        const result = this.parseTicker (params, market);
        this.tickers[symbol] = result;
        const messageHash = 'ticker:' + marketId;
        client.resolve (result, messageHash);
    }

    signMessage (client, messageHash, message, params = {}) {
        // todo: implement hitbtc2 signMessage
        return message;
    }

    handleNotification (client, message) {
        // TODO
        return message;
    }

    handleMessage (client, message) {
        const methods = {
            'snapshotOrderbook': this.handleOrderBookSnapshot,
            'updateOrderbook': this.handleUpdateOrderbook,
            'ticker': this.handleTicker,
        };
        const event = this.safeString (message, 'method');
        const method = this.safeValue (methods, event);
        if (method === undefined) {
            this.handleNotification (client, message);
        } else {
            method.call (this, client, message);
        }
    }
};
<|endoftext|>


<commit_before>var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var bunyan = require('bunyan');

try {
    var app = express();
    app.set('views', './td/views');
    app.set('view engine', 'jade');

    //static content
    app.use('/public', express.static(path.join(__dirname, 'public')));

    //security headers
    require('./config/securityheaders.config')(app);

    //sessions
    require('./config/session.config')(app);

    //passport
    require('./config/passport.config')(app);

    //favicon
    app.use(favicon(__dirname + '/public/favicon.ico'));

    //logging
    require('./config/loggers.config').config(app);

    //parsers
    require('./config/parsers.config')(app);

    //routes
    require('./config/routes.config')(app);

    bunyan.createLogger({ name: 'threatdragon', level: 'info' }).info('owasp threat dragon application started up');
}
catch (e) {
    var errorLogger = bunyan.createLogger({ name: 'threatdragon' });
    errorLogger.error('owasp threat dragon failed to start up');
    errorLogger.error(e.message);
}

module.exports = app;
<commit_msg>test debug<commit_after>var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var bunyan = require('bunyan');

try {
    var app = express();
    app.set('views', './td/views');
    app.set('view engine', 'jade');

    //static content
    app.use('/public', express.static(path.join(__dirname, 'public')));

    //security headers
    require('./config/securityheaders.config')(app);

    //sessions
    require('./config/session.config')(app);

    //passport
    require('./config/passport.config')(app);

    //favicon
    app.use(favicon(__dirname + '/public/favicon.ico'));

    //logging
    require('./config/loggers.config').config(app);

    //parsers
    require('./config/parsers.config')(app);

    //routes
    require('./config/routes.config')(app);
console.log('log');
console.info('info');

    bunyan.createLogger({ name: 'threatdragon', level: 'info' }).info('owasp threat dragon application started up');
}
catch (e) {
    var errorLogger = bunyan.createLogger({ name: 'threatdragon' });
    errorLogger.error('owasp threat dragon failed to start up');
    errorLogger.error(e.message);
}

module.exports = app;
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  package: 'foam.ui',
  name: 'ProgressView',

  extendsModel: 'foam.ui.View',

  properties: [
    {
      //model_: 'FloatProperty',
      name: 'data',
      postSet: function () { this.updateValue(); }
    }
  ],

  methods: {

    toHTML: function() {
      return '<progress value="25" id="' + this.id + '" max="100" >25</progress>';
    },

    updateValue: function() {
      var e = this.$;
      if (!e) return;

      e.value = typeof this.data === 'number' ? this.data : parseInt(this.data);
    },

    initHTML: function() {
      this.updateValue();
    }
  }
});
<commit_msg>Updated ProgressView styling to be a standard size.<commit_after>/**
 * @license
 * Copyright 2014 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  package: 'foam.ui',
  name: 'ProgressView',

  extendsModel: 'foam.ui.View',

  properties: [
    {
      //model_: 'FloatProperty',
      name: 'data',
      postSet: function () { this.updateValue(); }
    }
  ],

  templates: [
    function CSS() {/*
      .progressView {
        margin: 2px 0 0 10px;
        height: 23px;
        width: 183px;
      }
    */},
  ],

  methods: [
    function toHTML() {
      return '<progress class="progressView" value="25" id="' + this.id + '" max="100" >25</progress>';
    },

    function updateValue() {
      var e = this.$;
      if (!e) return;

      e.value = typeof this.data === 'number' ? this.data : parseInt(this.data);
    },

    function initHTML() {
      this.updateValue();
    }
  ]
});
<|endoftext|>


<commit_before>const Immutable = require('immutable');
const diffTree = require('./diffTree');

/**
 * Diff two tree of nodes. It goes down to the characters.
 *
 * @param  {List<Node>} original
 * @param  {List<Node>} modified
 * @return {List<Change>} changes
 */
function diffNodes(original, modified) {
    return diffTree(
        original, modified,
        isVariant, isEqual, getChildren
    );
}

/**
 * Get children to diff for a node.
 * @param  {Node} node
 * @return {List<Node|Character>}
 */
function getChildren(node) {
    if (node.kind == 'text') {
        return node.characters;
    } else if (node.kind == 'block' || node.kind == 'inline') {
        return node.nodes;
    } else {
        return [];
    }
}

/**
 * Check if two nodes could be variant.
 * @param  {Node}  a
 * @param  {Node}  b
 * @return {Boolean}
 */
function isVariant(a, b) {
    // For characters, it's always added/removed
    if (a.kind == 'character') {
        return true;
    }

    if (a.kind != b.kind) {
        return false;
    }

    return (a.type == b.type);
}

/**
 * Check if nodes are equal.
 * @param  {Node}  a
 * @param  {Node}  b
 * @return {Boolean}
 */
function isEqual(a, b) {
    switch (a.kind) {

    // We compare the type and the metadata
    case 'inline':
    case 'block':
        return a.type == b.type && Immutable.is(a.data, b.data);

    // Compare the marks and text
    case 'character':
        return Immutable.is(a, b);

    // For text node, the changes are in the characters
    case 'text':
        return true;

    default:
        throw new Error('Invalid kind for isEqual: ' + a.kind);
    }
}

module.exports = diffNodes;
<commit_msg>Consider heading as same variant<commit_after>const Immutable = require('immutable');
const { BLOCKS } = require('markup-it');

const diffTree = require('./diffTree');

/**
 * Diff two tree of nodes. It goes down to the characters.
 *
 * @param  {List<Node>} original
 * @param  {List<Node>} modified
 * @return {List<Change>} changes
 */
function diffNodes(original, modified) {
    return diffTree(
        original, modified,
        isVariant, isEqual, getChildren
    );
}

/**
 * Get children to diff for a node.
 * @param  {Node} node
 * @return {List<Node|Character>}
 */
function getChildren(node) {
    if (node.kind == 'text') {
        return node.characters;
    } else if (node.kind == 'block' || node.kind == 'inline') {
        return node.nodes;
    } else {
        return [];
    }
}

/**
 * Check if two nodes could be variant.
 * @param  {Node}  a
 * @param  {Node}  b
 * @return {Boolean}
 */
function isVariant(a, b) {
    // For characters, it's always added/removed
    if (a.kind == 'character') {
        return true;
    }

    if (a.kind != b.kind) {
        return false;
    }

    return isTypeEqual(a.type, b.type);
}

/**
 * Check if nodes are equal.
 * @param  {Node}  a
 * @param  {Node}  b
 * @return {Boolean}
 */
function isEqual(a, b) {
    switch (a.kind) {

    // We compare the type and the metadata
    case 'inline':
    case 'block':
        return a.type == b.type && Immutable.is(a.data, b.data);

    // Compare the marks and text
    case 'character':
        return Immutable.is(a, b);

    // For text node, the changes are in the characters
    case 'text':
        return true;

    default:
        throw new Error('Invalid kind for isEqual: ' + a.kind);
    }
}

/**
 * Check if node types are equal.
 * @param  {String} a
 * @param  {String} b
 * @return {Boolean}
 */
function isTypeEqual(a, b) {
    if (isHeading(a) && isHeading(b)) {
        return true;
    }

    if (isList(a) & isList(b)) {
        return true;
    }

    return a == b;
}

/**
 * Check if node type is an heading
 * @param  {String} type
 * @return {Boolean}
 */
function isHeading(type) {
    return [
        BLOCKS.HEADING_1,
        BLOCKS.HEADING_2,
        BLOCKS.HEADING_3,
        BLOCKS.HEADING_4,
        BLOCKS.HEADING_5,
        BLOCKS.HEADING_6
    ].includes(type);
}

/**
 * Check if node type is a list.
 * @param  {String} type
 * @return {Boolean}
 */
function isList(type) {
    return [
        BLOCKS.UL_LIST,
        BLOCKS.OL_LIST
    ].includes(type);
}

module.exports = diffNodes;
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  package: 'foam.util',
  name: 'JavaSource',

  requires: [
    'foam.core.types.StringEnumProperty',
    'foam.util.InlineTrait'
  ],

  documentation: function() {/* Generates Java source code from a FOAM
    model. Add a template for each model, named by CONSTANTIZED_MODEL_ID.
  */},

  methods: [
    function prepModel_(model) {
      // Java doesn't support traits, so we'll copy traits into the model directly.
      model = this.InlineTrait.create().inlineTraits(model);
      return model;
    },

    function generate(model) {
      model = this.prepModel_(model);

      var filter = function(m) {
        if ( m.labels && m.labels.indexOf('java') == -1 ) {
          return false;
        }
        return true;
      };

      model.properties = model.properties.filter(filter);
      model.methods = model.methods.filter(filter);
      model.listeners = model.listeners.filter(filter);

      return this.javaSource.call(model, null, this);
    },
  ],

  templates: [
    function javaSource(out, javaSource) {/*// Generated by FOAM, do not modify.
// Version <%= this.version %><%
  var className       = this.javaClassName;
  var parentClassName = 'AbstractFObject';
  var parentModel = '';
  if (this.extendsModel) {
    parentClassName = this.extendsModel;
    parentModel = this.extendsModel + '.MODEL(), ';
  }
  if ( GLOBAL[parentClassName] && GLOBAL[parentClassName].abstract )
    parentClassName = 'Abstract' + parentClassName;
%><% if ( this.package ) { %>
package <%= this.package %>;
<% } %>
import foam.core.*;
import foam.dao.*;
import java.util.Arrays;
import java.util.List;

public<%= this.abstract ? ' abstract' : '' %> class <%= className %>
    extends <%= parentClassName %> {
<% for ( var key in this.properties ) {
  var prop = this.properties[key];
  javaSource.propertySource.call(this, out, prop);
}
if (this.relationships && this.relationships.length) {
  for ( var i = 0; i < this.relationships.length; i++) {
    var rel = this.relationships[i];
    javaSource.relationshipSource.call(this, out, rel);
  }
}

var allProps = this.getRuntimeProperties();
allProps = allProps.filter(function(m) {
  if ( m.labels && m.labels.indexOf('java') == -1 ) {
    return false;
  }
  return true;
});

 %>
final static Model model__ = new AbstractModel(<%= parentModel %>new Property[] {<% for (var i = 0; i < allProps.length; i++) { var prop = allProps[i]; %> <%= constantize(prop.name) %>,<% } %>} , new Relationship[] {<% if (this.relationships && this.relationships.length) { for (var i = 0; i < this.relationships.length; i++) { %> <%= constantize(this.relationships[i].name) %>, <% } } %> }) {
    public String getName() { return "<%= this.id %>"; }
    public String getShortName() { return "<%= this.name %>"; }
    public String getLabel() { return "<%= this.label %>"; }
    public Property getID() { return <%= this.ids.length ? constantize(this.ids[0]) : 'null' %>; }
    public FObject newInstance() { return new <%= className %>(); }
  };

  public Model model() {
    return model__;
  }
  public static Model MODEL() {
    return model__;
  }

  public int hashCode() {
    int hash = 1;
<% for (var i = 0; i < allProps.length; i++) { var prop = allProps[i]; %>
    hash = hash * 31 + hash(<%= prop.name %>_);<% } %>

    return hash;
  }

  public int compareTo(Object obj) {
    if ( obj == this ) return 0;
    if ( obj == null ) return 1;

    <%= this.name %> other = (<%= this.name %>) obj;

    int cmp;
<% for (var i = 0; i < allProps.length; i++) { var prop = allProps[i]; %>
    if ( ( cmp = compare(get<%= prop.name.capitalize() %>(), other.get<%= prop.name.capitalize() %>()) ) != 0 ) return cmp;<% } %>

    return 0;
  }

  public StringBuilder append(StringBuilder b) {
    return b<% for (var i = 0; i < allProps.length; i++) { var prop = allProps[i]; %>
        .append("<%= prop.name %>=").append(get<%= prop.name.capitalize() %>())<%= i < allProps.length - 1 ? '.append(", ")' : '' %><% } %>;
  }

  public <%= className %> fclone() {
    <%= this.name %> c = new <%= this.name %>();
<% for (var i = 0; i < allProps.length; i++) { var prop = allProps[i]; %>
    c.set<%= prop.name.capitalize() %>(get<%= prop.name.capitalize() %>());<% } %>
    return c;
  }
<%
  function feature(f) {
    f.javaSource$f && f.javaSource$f(out, self);
  }

  this.methods.forEach(feature);
  this.listeners.forEach(feature);
%>
}
*/},
  function propertySource(out, prop) {/*<%
    var rawType, wrapperType, genericPropertyType, baseClass;
    rawType = prop.javaType;

    var toWrapperClass = function(name) {
      return name === 'int'  ? 'Integer' :
          name === 'double'  ? 'Double'  :
          name === 'float'   ? 'Float'   :
          name === 'boolean' ? 'Boolean' : name;
    };

    var extraText = '  ';
    if (prop.hidden) extraText += '  public boolean isHidden() { return true; }\u000a  ';
    if (prop.transient) extraText += '  public boolean isTransient() { return true; }\u000a  ';
    if (prop.help) {
      var parts = prop.help.split('\n').map(function(s) { return s.trim(); }).filter(function(s) { return s; });
      extraText += '  public String getHelp() {\u000a  ';
      extraText += '    return "' + parts.join('\\n" +\n          "') + '";\u000a  ';
      extraText += '  }\u000a  ';
    }

    var asDAO = false;

    if (StringArrayProperty.isInstance(prop)) {
      rawType = wrapperType = 'List<String>';
      genericPropertyType = 'ArrayProperty<String>';
      baseClass = 'AbstractStringArrayProperty';
    } else if (ArrayProperty.isInstance(prop) || ReferenceArrayProperty.isInstance(prop)) {
      var elementType = toWrapperClass(prop.subType);
      rawType = wrapperType = 'List<' + elementType + '>';
      var ref = ReferenceArrayProperty.isInstance(prop) ? 'Reference' : '';
      genericPropertyType = ref + 'ArrayProperty<' + elementType + '>';
      baseClass = 'Abstract' + ref + 'ArrayProperty<' + elementType + '>';
      var propType = this.X.lookup(prop.subType) ? 'OBJECT' : constantize(elementType);
      extraText += '  public int getType() { return Property.TYPE_ARRAY | Property.TYPE_' + propType + '; }\u000a  ';
      asDAO = !!(prop.subType && this.X.lookup(prop.subType));
      if (asDAO) {
        extraText += '  public DAO getAsDAO(Object o) { return ((' + this.name + ') o).get' + prop.name.capitalize() + 'AsDAO(); }\u000a  ';
      }
    } else if (ReferenceProperty.isInstance(prop)) {
      wrapperType = toWrapperClass(rawType);
      genericPropertyType = 'ReferenceProperty<' + wrapperType + '>';
      baseClass = 'Abstract' + genericPropertyType;
      extraText += '  public int getType() { return Property.TYPE_' + constantize(wrapperType) + '; }\u000a  ';
    } else if (foam.core.types.StringEnumProperty.isInstance(prop)) {
      wrapperType = 'String';
      genericPropertyType = 'EnumProperty<String>';
      baseClass = 'Abstract' + genericPropertyType;
      var choices = [];
      for (var i = 0; i < prop.choices.length; i++) {
        var c = prop.choices[i];
        if (typeof c === 'string') c = [c, c];
        choices.push('new LabeledItem<String>("' + c[1] + '", "' + c[0] + '")');
      }
      extraText += '  public void initChoices_() { choices_ = Arrays.asList(' + choices.join(', ') + '); }\u000a  ';
      extraText += '  public int getType() { return Property.TYPE_STRING; }\u000a  ';
    } else {
      wrapperType = toWrapperClass(rawType);
      genericPropertyType = 'Property<' + wrapperType + '>';
      baseClass = 'Abstract' + prop.javaType.capitalize() + 'Property';
    }

    if (ReferenceProperty.isInstance(prop)) {
      extraText += '  public Model getSubType() { return ' + prop.subType + '.MODEL(); }\u000a  ';
      extraText += '  public Property getSubKey() { return getSubType().getProperty("' + prop.subKey + '"); }\u000a  ';
    }
%>
  public final static <%= genericPropertyType %> <%= constantize(prop.name) %> = new <%= baseClass %>() {
    public String getName() { return "<%= prop.name %>"; }
    public String getLabel() { return "<%= prop.label %>"; }
    public <%= wrapperType %> get(Object o) { return ((<%= this.name %>) o).get<%= prop.name.capitalize() %>(); }
    public void set(Object o, <%= wrapperType %> v) { ((<%= this.name %>) o).set<%= prop.name.capitalize() %>(v); }
    public int compare(Object o1, Object o2) { return compareValues(((<%= this.name%>)o1).<%= prop.name %>_, ((<%= this.name%>)o2).<%= prop.name %>_); }
<%= extraText %>};

  protected <%= rawType %> <%= prop.name %>_;

  public <%= rawType %> get<%= prop.name.capitalize() %>() {
    return <%= prop.name %>_;
  }
<% if (asDAO) { %>
  DAO <%= prop.name %>DAO_;
  public DAO get<%= prop.name.capitalize() %>AsDAO() {
    if (<%= prop.name %>DAO_ == null) <%= prop.name %>DAO_ = new ArrayDAO(<%= prop.subType %>.MODEL(), <%= prop.name %>_);
    return <%= prop.name %>DAO_;
  }
<% } %>
  public void set<%= prop.name.capitalize() %>(<%= rawType, ' ', prop.name %>) {
    if (isFrozen()) throw new FrozenObjectModificationException();
    <%= rawType %> oldValue = <%= prop.name %>_;
    <%= prop.name %>_ = <%= prop.name %>;
    if (<%= constantize(prop.name) %>.compareValues(oldValue, <%= prop.name %>) != 0) {
      firePropertyChange(<%= constantize(prop.name) %>, oldValue, <%= prop.name %>);
    }
  }
*/},

  function relationshipSource(out, rel) {/*<%
    var shortName = rel.relatedModel.split('.').pop();
    shortName = shortName.substring(0, 1).toLowerCase() + shortName.substring(1);
%>
  public final static Relationship <%= constantize(rel.name) %> = new AbstractRelationship() {
    public String getName() { return "<%= rel.name %>"; }
    public String getLabel() { return "<%= rel.label %>"; }
    public DAO get(Object o) { return ((<%= this.name %>) o).get<%= rel.name.capitalize() %>(); }
  };

  private DAO <%= rel.name %>_;

  public DAO get<%= rel.name.capitalize() %>() {
    if (<%= rel.name %>_ == null) {
      Model model = <%= rel.relatedModel %>.MODEL();
      DAO dao = new RelationshipDAO(model, "<%= shortName %>DAO");
      <%= rel.name %>_ = dao.where(MLang.EQ(model.getProperty("<%= rel.relatedProperty %>"), model().getID().get(this)));
    }
    return <%= rel.name %>_;
  }
  */},
  ]
});
<commit_msg>JavaSource: Filter out compiletime labelled features from code generation, but leave them in the models so feature templates can use them<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

CLASS({
  package: 'foam.util',
  name: 'JavaSource',

  requires: [
    'foam.core.types.StringEnumProperty',
    'foam.util.InlineTrait'
  ],

  documentation: function() {/* Generates Java source code from a FOAM
    model. Add a template for each model, named by CONSTANTIZED_MODEL_ID.
  */},

  methods: [
    function prepModel_(model) {
      // Java doesn't support traits, so we'll copy traits into the model directly.
      model = this.InlineTrait.create().inlineTraits(model);
      return model;
    },

    function generate(model) {
      model = this.prepModel_(model);

      var filter = function(m) {
        if ( m.labels && m.labels.indexOf('java') == -1 ) {
          return false;
        }
        return true;
      };

      model.properties = model.properties.filter(filter);
      model.methods = model.methods.filter(filter);
      model.listeners = model.listeners.filter(filter);

      return this.javaSource.call(model, null, this);
    },
  ],

  templates: [
    function javaSource(out, javaSource) {/*// Generated by FOAM, do not modify.
// Version <%= this.version %><%
  var className       = this.javaClassName;
  var parentClassName = 'AbstractFObject';
  var parentModel = '';
  if (this.extendsModel) {
    parentClassName = this.extendsModel;
    parentModel = this.extendsModel + '.MODEL(), ';
  }
  if ( GLOBAL[parentClassName] && GLOBAL[parentClassName].abstract )
    parentClassName = 'Abstract' + parentClassName;
%><% if ( this.package ) { %>
package <%= this.package %>;
<% } %>
import foam.core.*;
import foam.dao.*;
import java.util.Arrays;
import java.util.List;

public<%= this.abstract ? ' abstract' : '' %> class <%= className %>
    extends <%= parentClassName %> {
<% for ( var key in this.properties ) {
  var prop = this.properties[key];
  if ( prop.labels && prop.labels.indexOf('compiletime') != -1  )
    continue;
  javaSource.propertySource.call(this, out, prop);
}
if (this.relationships && this.relationships.length) {
  for ( var i = 0; i < this.relationships.length; i++) {
    var rel = this.relationships[i];
    javaSource.relationshipSource.call(this, out, rel);
  }
}

var allProps = this.getRuntimeProperties();
allProps = allProps.filter(function(m) {
  if ( m.labels &&
        ( m.labels.indexOf('java') == -1 ||
          m.labels.indexOf("compiletime') != -1 ) {
    return false;
  }
  return true;
});

 %>
final static Model model__ = new AbstractModel(<%= parentModel %>new Property[] {<% for (var i = 0; i < allProps.length; i++) { var prop = allProps[i]; %> <%= constantize(prop.name) %>,<% } %>} , new Relationship[] {<% if (this.relationships && this.relationships.length) { for (var i = 0; i < this.relationships.length; i++) { %> <%= constantize(this.relationships[i].name) %>, <% } } %> }) {
    public String getName() { return "<%= this.id %>"; }
    public String getShortName() { return "<%= this.name %>"; }
    public String getLabel() { return "<%= this.label %>"; }
    public Property getID() { return <%= this.ids.length ? constantize(this.ids[0]) : 'null' %>; }
    public FObject newInstance() { return new <%= className %>(); }
  };

  public Model model() {
    return model__;
  }
  public static Model MODEL() {
    return model__;
  }

  public int hashCode() {
    int hash = 1;
<% for (var i = 0; i < allProps.length; i++) { var prop = allProps[i]; %>
    hash = hash * 31 + hash(<%= prop.name %>_);<% } %>

    return hash;
  }

  public int compareTo(Object obj) {
    if ( obj == this ) return 0;
    if ( obj == null ) return 1;

    <%= this.name %> other = (<%= this.name %>) obj;

    int cmp;
<% for (var i = 0; i < allProps.length; i++) { var prop = allProps[i]; %>
    if ( ( cmp = compare(get<%= prop.name.capitalize() %>(), other.get<%= prop.name.capitalize() %>()) ) != 0 ) return cmp;<% } %>

    return 0;
  }

  public StringBuilder append(StringBuilder b) {
    return b<% for (var i = 0; i < allProps.length; i++) { var prop = allProps[i]; %>
        .append("<%= prop.name %>=").append(get<%= prop.name.capitalize() %>())<%= i < allProps.length - 1 ? '.append(", ")' : '' %><% } %>;
  }

  public <%= className %> fclone() {
    <%= this.name %> c = new <%= this.name %>();
<% for (var i = 0; i < allProps.length; i++) { var prop = allProps[i]; %>
    c.set<%= prop.name.capitalize() %>(get<%= prop.name.capitalize() %>());<% } %>
    return c;
  }
<%
  function feature(f) {
    f.javaSource$f && f.javaSource$f(out, self);
  }

  this.methods.forEach(feature);
  this.listeners.forEach(feature);
%>
}
*/},
  function propertySource(out, prop) {/*<%
    var rawType, wrapperType, genericPropertyType, baseClass;
    rawType = prop.javaType;

    var toWrapperClass = function(name) {
      return name === 'int'  ? 'Integer' :
          name === 'double'  ? 'Double'  :
          name === 'float'   ? 'Float'   :
          name === 'boolean' ? 'Boolean' : name;
    };

    var extraText = '  ';
    if (prop.hidden) extraText += '  public boolean isHidden() { return true; }\u000a  ';
    if (prop.transient) extraText += '  public boolean isTransient() { return true; }\u000a  ';
    if (prop.help) {
      var parts = prop.help.split('\n').map(function(s) { return s.trim(); }).filter(function(s) { return s; });
      extraText += '  public String getHelp() {\u000a  ';
      extraText += '    return "' + parts.join('\\n" +\n          "') + '";\u000a  ';
      extraText += '  }\u000a  ';
    }

    var asDAO = false;

    if (StringArrayProperty.isInstance(prop)) {
      rawType = wrapperType = 'List<String>';
      genericPropertyType = 'ArrayProperty<String>';
      baseClass = 'AbstractStringArrayProperty';
    } else if (ArrayProperty.isInstance(prop) || ReferenceArrayProperty.isInstance(prop)) {
      var elementType = toWrapperClass(prop.subType);
      rawType = wrapperType = 'List<' + elementType + '>';
      var ref = ReferenceArrayProperty.isInstance(prop) ? 'Reference' : '';
      genericPropertyType = ref + 'ArrayProperty<' + elementType + '>';
      baseClass = 'Abstract' + ref + 'ArrayProperty<' + elementType + '>';
      var propType = this.X.lookup(prop.subType) ? 'OBJECT' : constantize(elementType);
      extraText += '  public int getType() { return Property.TYPE_ARRAY | Property.TYPE_' + propType + '; }\u000a  ';
      asDAO = !!(prop.subType && this.X.lookup(prop.subType));
      if (asDAO) {
        extraText += '  public DAO getAsDAO(Object o) { return ((' + this.name + ') o).get' + prop.name.capitalize() + 'AsDAO(); }\u000a  ';
      }
    } else if (ReferenceProperty.isInstance(prop)) {
      wrapperType = toWrapperClass(rawType);
      genericPropertyType = 'ReferenceProperty<' + wrapperType + '>';
      baseClass = 'Abstract' + genericPropertyType;
      extraText += '  public int getType() { return Property.TYPE_' + constantize(wrapperType) + '; }\u000a  ';
    } else if (foam.core.types.StringEnumProperty.isInstance(prop)) {
      wrapperType = 'String';
      genericPropertyType = 'EnumProperty<String>';
      baseClass = 'Abstract' + genericPropertyType;
      var choices = [];
      for (var i = 0; i < prop.choices.length; i++) {
        var c = prop.choices[i];
        if (typeof c === 'string') c = [c, c];
        choices.push('new LabeledItem<String>("' + c[1] + '", "' + c[0] + '")');
      }
      extraText += '  public void initChoices_() { choices_ = Arrays.asList(' + choices.join(', ') + '); }\u000a  ';
      extraText += '  public int getType() { return Property.TYPE_STRING; }\u000a  ';
    } else {
      wrapperType = toWrapperClass(rawType);
      genericPropertyType = 'Property<' + wrapperType + '>';
      baseClass = 'Abstract' + prop.javaType.capitalize() + 'Property';
    }

    if (ReferenceProperty.isInstance(prop)) {
      extraText += '  public Model getSubType() { return ' + prop.subType + '.MODEL(); }\u000a  ';
      extraText += '  public Property getSubKey() { return getSubType().getProperty("' + prop.subKey + '"); }\u000a  ';
    }
%>
  public final static <%= genericPropertyType %> <%= constantize(prop.name) %> = new <%= baseClass %>() {
    public String getName() { return "<%= prop.name %>"; }
    public String getLabel() { return "<%= prop.label %>"; }
    public <%= wrapperType %> get(Object o) { return ((<%= this.name %>) o).get<%= prop.name.capitalize() %>(); }
    public void set(Object o, <%= wrapperType %> v) { ((<%= this.name %>) o).set<%= prop.name.capitalize() %>(v); }
    public int compare(Object o1, Object o2) { return compareValues(((<%= this.name%>)o1).<%= prop.name %>_, ((<%= this.name%>)o2).<%= prop.name %>_); }
<%= extraText %>};

  protected <%= rawType %> <%= prop.name %>_;

  public <%= rawType %> get<%= prop.name.capitalize() %>() {
    return <%= prop.name %>_;
  }
<% if (asDAO) { %>
  DAO <%= prop.name %>DAO_;
  public DAO get<%= prop.name.capitalize() %>AsDAO() {
    if (<%= prop.name %>DAO_ == null) <%= prop.name %>DAO_ = new ArrayDAO(<%= prop.subType %>.MODEL(), <%= prop.name %>_);
    return <%= prop.name %>DAO_;
  }
<% } %>
  public void set<%= prop.name.capitalize() %>(<%= rawType, ' ', prop.name %>) {
    if (isFrozen()) throw new FrozenObjectModificationException();
    <%= rawType %> oldValue = <%= prop.name %>_;
    <%= prop.name %>_ = <%= prop.name %>;
    if (<%= constantize(prop.name) %>.compareValues(oldValue, <%= prop.name %>) != 0) {
      firePropertyChange(<%= constantize(prop.name) %>, oldValue, <%= prop.name %>);
    }
  }
*/},

  function relationshipSource(out, rel) {/*<%
    var shortName = rel.relatedModel.split('.').pop();
    shortName = shortName.substring(0, 1).toLowerCase() + shortName.substring(1);
%>
  public final static Relationship <%= constantize(rel.name) %> = new AbstractRelationship() {
    public String getName() { return "<%= rel.name %>"; }
    public String getLabel() { return "<%= rel.label %>"; }
    public DAO get(Object o) { return ((<%= this.name %>) o).get<%= rel.name.capitalize() %>(); }
  };

  private DAO <%= rel.name %>_;

  public DAO get<%= rel.name.capitalize() %>() {
    if (<%= rel.name %>_ == null) {
      Model model = <%= rel.relatedModel %>.MODEL();
      DAO dao = new RelationshipDAO(model, "<%= shortName %>DAO");
      <%= rel.name %>_ = dao.where(MLang.EQ(model.getProperty("<%= rel.relatedProperty %>"), model().getID().get(this)));
    }
    return <%= rel.name %>_;
  }
  */},
  ]
});
<|endoftext|>


<commit_before>dojo.provide("dijit.Dialog");

dojo.require("dojo.dnd.move");
dojo.require("dojo.dnd.TimedMoveable");
dojo.require("dojo.fx");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dijit.form._FormMixin");
dojo.require("dijit._DialogMixin");
dojo.require("dijit.DialogUnderlay");
dojo.require("dijit.layout.ContentPane");
dojo.requireLocalization("dijit", "common");

/*=====
dijit._underlay = function(kwArgs){
	// summary:
	//		A shared instance of a `dijit.DialogUnderlay`
	//
	// description:
	//		A shared instance of a `dijit.DialogUnderlay` created and
	//		used by `dijit.Dialog`, though never created until some Dialog
	//		or subclass thereof is shown.
};
=====*/

dojo.declare(
	"dijit.Dialog",
	[dijit.layout.ContentPane, dijit._Templated, dijit.form._FormMixin, dijit._DialogMixin],
	{
		// summary:
		//		A modal dialog Widget
		//
		// description:
		//		Pops up a modal dialog window, blocking access to the screen
		//		and also graying out the screen Dialog is extended from
		//		ContentPane so it supports all the same parameters (href, etc.)
		//
		// example:
		// |

		//
		// example:
		// |	var foo = new dijit.Dialog({ title: "test dialog", content: "test content" };
		// |	dojo.body().appendChild(foo.domNode);
		// |	foo.startup();

		templateString: null,
		templatePath: dojo.moduleUrl("dijit", "templates/Dialog.html"),
		attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
			title: [
				{ node: "titleNode", type: "innerHTML" },
				{ node: "titleBar", type: "attribute" }
			]
		}),

		// open: Boolean
		//		True if Dialog is currently displayed on screen.
		open: false,

		// duration: Integer
		//		The time in milliseconds it takes the dialog to fade in and out
		duration: dijit.defaultDuration,

		// refocus: Boolean
		// 		A Toggle to modify the default focus behavior of a Dialog, which
		// 		is to re-focus the element which had focus before being opened.
		//		False will disable refocusing. Default: true
		refocus: true,

		// autofocus: Boolean
		// 		A Toggle to modify the default focus behavior of a Dialog, which
		// 		is to focus on the first dialog element after opening the dialog.
		//		False will disable autofocusing. Default: true
		autofocus: true,

		// _firstFocusItem: [private] [readonly] DomNode
		//		The pointer to the first focusable node in the dialog.
		//		Set by `dijit._DialogMixin._getFocusItems`.
		_firstFocusItem: null,

		// _lastFocusItem: [private] [readonly] DomNode
		//		The pointer to which node has focus prior to our dialog.
		//		Set by `dijit._DialogMixin._getFocusItems`.
		_lastFocusItem: null,

		// doLayout: [protected] Boolean
		//		Don't change this parameter from the default value.
		//		This ContentPane parameter doesn't make sense for Dialog, since Dialog
		//		is never a child of a layout container, nor can you specify the size of
		//		Dialog in order to control the size of an inner widget.
		doLayout: false,

		// draggable: Boolean
		//		Toggles the moveable aspect of the Dialog. If true, Dialog
		//		can be dragged by it's title. If false it will remain centered
		//		in the viewport.
		draggable: true,

		postMixInProperties: function(){
			var _nlsResources = dojo.i18n.getLocalization("dijit", "common");
			dojo.mixin(this, _nlsResources);
			this.inherited(arguments);
		},

		postCreate: function(){
			dojo.style(this.domNode, {
				visibility:"hidden",
				position:"absolute",
				display:"",
				top:"-9999px"
			});
			dojo.body().appendChild(this.domNode);

			this.inherited(arguments);

			this.connect(this, "onExecute", "hide");
			this.connect(this, "onCancel", "hide");
			this._modalconnects = [];
		},

		onLoad: function(){
			// summary:
			//		Called when data has been loaded from an href.
			//		Unlike most other callbacks, this function can be connected to (via `dojo.connect`)
			//		but should *not* be overriden.
			// tags:
			//		callback

			// when href is specified we need to reposition the dialog after the data is loaded
			this._position();
			this.inherited(arguments);
		},

		_endDrag: function(e){
			// summary:
			//		Called after dragging the Dialog. Calculates the relative offset
			//		of the Dialog in relation to the viewport.
			// tags:
			//		private
			if(e && e.node && e.node === this.domNode){
				var vp = dijit.getViewport();
				var p = e._leftTop || dojo.coords(e.node,true);
				this._relativePosition = {
					t: p.t - vp.t,
					l: p.l - vp.l
				}
			}
		},

		_setup: function(){
			// summary:
			//		Stuff we need to do before showing the Dialog for the first
			//		time (but we defer it until right beforehand, for
			//		performance reasons).
			// tags:
			//		private

			var node = this.domNode;

			if(this.titleBar && this.draggable){
				this._moveable = (dojo.isIE == 6) ?
					new dojo.dnd.TimedMoveable(node, { handle: this.titleBar }) :	// prevent overload, see #5285
					new dojo.dnd.Moveable(node, { handle: this.titleBar, timeout: 0 });
				dojo.subscribe("/dnd/move/stop",this,"_endDrag");
			}else{
				dojo.addClass(node,"dijitDialogFixed");
			}

			var underlayAttrs = {
				dialogId: this.id,
				"class": dojo.map(this["class"].split(/\s/), function(s){ return s+"_underlay"; }).join(" ")
			};

			var underlay = dijit._underlay;
			if(!underlay){
				underlay = dijit._underlay = new dijit.DialogUnderlay(underlayAttrs);
			}

			this._fadeIn = dojo.fadeIn({
				node: node,
				duration: this.duration,
				beforeBegin: function(){
					underlay.attr(underlayAttrs);
					underlay.show();
				},
				onEnd:	dojo.hitch(this, function(){
					if(this.autofocus){
						// find focusable Items each time dialog is shown since if dialog contains a widget the
						// first focusable items can change
						this._getFocusItems(this.domNode);
						dijit.focus(this._firstFocusItem);
					}
				})
			 });

			this._fadeOut = dojo.fadeOut({
				node: node,
				duration: this.duration,
				onEnd: function(){
					node.style.visibility="hidden";
					node.style.top = "-9999px";
					dijit._underlay.hide();
				}
			 });
		},

		uninitialize: function(){
			var wasPlaying = false;
			if(this._fadeIn && this._fadeIn.status() == "playing"){
				wasPlaying = true;
				this._fadeIn.stop();
			}
			if(this._fadeOut && this._fadeOut.status() == "playing"){
				wasPlaying = true;
				this._fadeOut.stop();
			}
			if(this.open || wasPlaying){
				dijit._underlay.hide();
			}
			if(this._moveable){
				this._moveable.destroy();
			}
		},

		_size: function(){
			// summary:
			// 		Make sure the dialog is small enough to fit in viewport.
			// tags:
			//		private

			var mb = dojo.marginBox(this.domNode);
			var viewport = dijit.getViewport();
			if(mb.w >= viewport.w || mb.h >= viewport.h){
				dojo.style(this.containerNode, {
					width: Math.min(mb.w, Math.floor(viewport.w * 0.75))+"px",
					height: Math.min(mb.h, Math.floor(viewport.h * 0.75))+"px",
					overflow: "auto",
					position: "relative"	// workaround IE bug moving scrollbar or dragging dialog
				});
			}
		},

		_position: function(){
			// summary:
			//		Position modal dialog in the viewport. If no relative offset
			//		in the viewport has been determined (by dragging, for instance),
			//		center the node. Otherwise, use the Dialog's stored relative offset,
			//		and position the node to top: left: values based on the viewport.
			// tags:
			//		private
			if(!dojo.hasClass(dojo.body(),"dojoMove")){

				var node = this.domNode;
				var viewport = dijit.getViewport();
				var p = this._relativePosition;
				var mb = p ? null : dojo.marginBox(node);
				dojo.style(node,{
					left: Math.floor(viewport.l + (p ? p.l : (viewport.w - mb.w) / 2)) + "px",
					top: Math.floor(viewport.t + (p ? p.t : (viewport.h - mb.h) / 2)) + "px"
				});
			}

		},

		_onKey: function(/*Event*/ evt){
			// summary:
			//		Handles the keyboard events for accessibility reasons
			// tags:
			//		private
			if(evt.charOrCode){
				var dk = dojo.keys;
				var node = evt.target;
				if (evt.charOrCode === dk.TAB){
					this._getFocusItems(this.domNode);
				}
				var singleFocusItem = (this._firstFocusItem == this._lastFocusItem);
				// see if we are shift-tabbing from first focusable item on dialog
				if(node == this._firstFocusItem && evt.shiftKey && evt.charOrCode === dk.TAB){
					if(!singleFocusItem){
						dijit.focus(this._lastFocusItem); // send focus to last item in dialog
					}
					dojo.stopEvent(evt);
				}else if(node == this._lastFocusItem && evt.charOrCode === dk.TAB && !evt.shiftKey){
					if (!singleFocusItem){
						dijit.focus(this._firstFocusItem); // send focus to first item in dialog
					}
					dojo.stopEvent(evt);
				}else{
					// see if the key is for the dialog
					while(node){
						if(node == this.domNode){
							if(evt.charOrCode == dk.ESCAPE){
								this.onCancel();
							}else{
								return; // just let it go
							}
						}
						node = node.parentNode;
					}
					// this key is for the disabled document window
					if(evt.charOrCode !== dk.TAB){ // allow tabbing into the dialog for a11y
						dojo.stopEvent(evt);
					// opera won't tab to a div
					}else if(!dojo.isOpera){
						try{
							this._firstFocusItem.focus();
						}catch(e){ /*squelch*/ }
					}
				}
			}
		},

		show: function(){
			// summary:
			//		Display the dialog
			if(this.open){ return; }

			// first time we show the dialog, there's some initialization stuff to do
			if(!this._alreadyInitialized){
				this._setup();
				this._alreadyInitialized=true;
			}

			if(this._fadeOut.status() == "playing"){
				this._fadeOut.stop();
			}

			this._modalconnects.push(dojo.connect(window, "onscroll", this, "layout"));
			this._modalconnects.push(dojo.connect(window, "onresize", this, "layout"));
			this._modalconnects.push(dojo.connect(dojo.doc.documentElement, "onkeypress", this, "_onKey"));

			dojo.style(this.domNode, {
				opacity:0,
				visibility:""
			});

			this.open = true;
			this._onShow(); // lazy load trigger

			this._size();
			this._position();

			this._fadeIn.play();

			this._savedFocus = dijit.getFocus(this);
		},

		hide: function(){
			// summary:
			//		Hide the dialog

			// if we haven't been initialized yet then we aren't showing and we can just return
			if(!this._alreadyInitialized){
				return;
			}

			if(this._fadeIn.status() == "playing"){
				this._fadeIn.stop();
			}
			this._fadeOut.play();

			if (this._scrollConnected){
				this._scrollConnected = false;
			}
			dojo.forEach(this._modalconnects, dojo.disconnect);
			this._modalconnects = [];
			if(this.refocus){
				this.connect(this._fadeOut,"onEnd",dojo.hitch(dijit,"focus",this._savedFocus));
			}
			if(this._relativePosition){
				delete this._relativePosition;
			}
			this.open = false;
		},

		layout: function() {
			// summary:
			//		Position the Dialog and the underlay
			// tags:
			//		private
			if(this.domNode.style.visibility != "hidden"){
				dijit._underlay.layout();
				this._position();
			}
		},

		destroy: function(){
			dojo.forEach(this._modalconnects, dojo.disconnect);
			if(this.refocus && this.open){
				setTimeout(dojo.hitch(dijit,"focus",this._savedFocus), 25);
			}
			this.inherited(arguments);
		},

		_onCloseEnter: function(){
			// summary:
			//		Called when user hovers over close icon
			// tags:
			//		private
			dojo.addClass(this.closeButtonNode, "dijitDialogCloseIcon-hover");
		},

		_onCloseLeave: function(){
			// summary:
			//		Called when user stops hovering over close icon
			// tags:
			//		private
			dojo.removeClass(this.closeButtonNode, "dijitDialogCloseIcon-hover");
		}
	}
);

// For back-compat.  TODO: remove in 2.0
dojo.require("dijit.TooltipDialog");

<commit_msg>Fixes #8837.  Reset width and height in show() so that marginBox returns the correct value.<commit_after>dojo.provide("dijit.Dialog");

dojo.require("dojo.dnd.move");
dojo.require("dojo.dnd.TimedMoveable");
dojo.require("dojo.fx");

dojo.require("dijit._Widget");
dojo.require("dijit._Templated");
dojo.require("dijit.form._FormMixin");
dojo.require("dijit._DialogMixin");
dojo.require("dijit.DialogUnderlay");
dojo.require("dijit.layout.ContentPane");
dojo.requireLocalization("dijit", "common");

/*=====
dijit._underlay = function(kwArgs){
	// summary:
	//		A shared instance of a `dijit.DialogUnderlay`
	//
	// description:
	//		A shared instance of a `dijit.DialogUnderlay` created and
	//		used by `dijit.Dialog`, though never created until some Dialog
	//		or subclass thereof is shown.
};
=====*/

dojo.declare(
	"dijit.Dialog",
	[dijit.layout.ContentPane, dijit._Templated, dijit.form._FormMixin, dijit._DialogMixin],
	{
		// summary:
		//		A modal dialog Widget
		//
		// description:
		//		Pops up a modal dialog window, blocking access to the screen
		//		and also graying out the screen Dialog is extended from
		//		ContentPane so it supports all the same parameters (href, etc.)
		//
		// example:
		// |

		//
		// example:
		// |	var foo = new dijit.Dialog({ title: "test dialog", content: "test content" };
		// |	dojo.body().appendChild(foo.domNode);
		// |	foo.startup();

		templateString: null,
		templatePath: dojo.moduleUrl("dijit", "templates/Dialog.html"),
		attributeMap: dojo.delegate(dijit._Widget.prototype.attributeMap, {
			title: [
				{ node: "titleNode", type: "innerHTML" },
				{ node: "titleBar", type: "attribute" }
			]
		}),

		// open: Boolean
		//		True if Dialog is currently displayed on screen.
		open: false,

		// duration: Integer
		//		The time in milliseconds it takes the dialog to fade in and out
		duration: dijit.defaultDuration,

		// refocus: Boolean
		// 		A Toggle to modify the default focus behavior of a Dialog, which
		// 		is to re-focus the element which had focus before being opened.
		//		False will disable refocusing. Default: true
		refocus: true,

		// autofocus: Boolean
		// 		A Toggle to modify the default focus behavior of a Dialog, which
		// 		is to focus on the first dialog element after opening the dialog.
		//		False will disable autofocusing. Default: true
		autofocus: true,

		// _firstFocusItem: [private] [readonly] DomNode
		//		The pointer to the first focusable node in the dialog.
		//		Set by `dijit._DialogMixin._getFocusItems`.
		_firstFocusItem: null,

		// _lastFocusItem: [private] [readonly] DomNode
		//		The pointer to which node has focus prior to our dialog.
		//		Set by `dijit._DialogMixin._getFocusItems`.
		_lastFocusItem: null,

		// doLayout: [protected] Boolean
		//		Don't change this parameter from the default value.
		//		This ContentPane parameter doesn't make sense for Dialog, since Dialog
		//		is never a child of a layout container, nor can you specify the size of
		//		Dialog in order to control the size of an inner widget.
		doLayout: false,

		// draggable: Boolean
		//		Toggles the moveable aspect of the Dialog. If true, Dialog
		//		can be dragged by it's title. If false it will remain centered
		//		in the viewport.
		draggable: true,

		postMixInProperties: function(){
			var _nlsResources = dojo.i18n.getLocalization("dijit", "common");
			dojo.mixin(this, _nlsResources);
			this.inherited(arguments);
		},

		postCreate: function(){
			dojo.style(this.domNode, {
				visibility:"hidden",
				position:"absolute",
				display:"",
				top:"-9999px"
			});
			dojo.body().appendChild(this.domNode);

			this.inherited(arguments);

			this.connect(this, "onExecute", "hide");
			this.connect(this, "onCancel", "hide");
			this._modalconnects = [];
		},

		onLoad: function(){
			// summary:
			//		Called when data has been loaded from an href.
			//		Unlike most other callbacks, this function can be connected to (via `dojo.connect`)
			//		but should *not* be overriden.
			// tags:
			//		callback

			// when href is specified we need to reposition the dialog after the data is loaded
			this._position();
			this.inherited(arguments);
		},

		_endDrag: function(e){
			// summary:
			//		Called after dragging the Dialog. Calculates the relative offset
			//		of the Dialog in relation to the viewport.
			// tags:
			//		private
			if(e && e.node && e.node === this.domNode){
				var vp = dijit.getViewport();
				var p = e._leftTop || dojo.coords(e.node,true);
				this._relativePosition = {
					t: p.t - vp.t,
					l: p.l - vp.l
				}
			}
		},

		_setup: function(){
			// summary:
			//		Stuff we need to do before showing the Dialog for the first
			//		time (but we defer it until right beforehand, for
			//		performance reasons).
			// tags:
			//		private

			var node = this.domNode;

			if(this.titleBar && this.draggable){
				this._moveable = (dojo.isIE == 6) ?
					new dojo.dnd.TimedMoveable(node, { handle: this.titleBar }) :	// prevent overload, see #5285
					new dojo.dnd.Moveable(node, { handle: this.titleBar, timeout: 0 });
				dojo.subscribe("/dnd/move/stop",this,"_endDrag");
			}else{
				dojo.addClass(node,"dijitDialogFixed");
			}

			var underlayAttrs = {
				dialogId: this.id,
				"class": dojo.map(this["class"].split(/\s/), function(s){ return s+"_underlay"; }).join(" ")
			};

			var underlay = dijit._underlay;
			if(!underlay){
				underlay = dijit._underlay = new dijit.DialogUnderlay(underlayAttrs);
			}

			this._fadeIn = dojo.fadeIn({
				node: node,
				duration: this.duration,
				beforeBegin: function(){
					underlay.attr(underlayAttrs);
					underlay.show();
				},
				onEnd:	dojo.hitch(this, function(){
					if(this.autofocus){
						// find focusable Items each time dialog is shown since if dialog contains a widget the
						// first focusable items can change
						this._getFocusItems(this.domNode);
						dijit.focus(this._firstFocusItem);
					}
				})
			 });

			this._fadeOut = dojo.fadeOut({
				node: node,
				duration: this.duration,
				onEnd: function(){
					node.style.visibility="hidden";
					node.style.top = "-9999px";
					dijit._underlay.hide();
				}
			 });
		},

		uninitialize: function(){
			var wasPlaying = false;
			if(this._fadeIn && this._fadeIn.status() == "playing"){
				wasPlaying = true;
				this._fadeIn.stop();
			}
			if(this._fadeOut && this._fadeOut.status() == "playing"){
				wasPlaying = true;
				this._fadeOut.stop();
			}
			if(this.open || wasPlaying){
				dijit._underlay.hide();
			}
			if(this._moveable){
				this._moveable.destroy();
			}
		},

		_size: function(){
			// summary:
			// 		Make sure the dialog is small enough to fit in viewport.
			// tags:
			//		private

			var mb = dojo.marginBox(this.domNode);
			var viewport = dijit.getViewport();
			if(mb.w >= viewport.w || mb.h >= viewport.h){
				dojo.style(this.containerNode, {
					width: Math.min(mb.w, Math.floor(viewport.w * 0.75))+"px",
					height: Math.min(mb.h, Math.floor(viewport.h * 0.75))+"px",
					overflow: "auto",
					position: "relative"	// workaround IE bug moving scrollbar or dragging dialog
				});
			}
		},

		_position: function(){
			// summary:
			//		Position modal dialog in the viewport. If no relative offset
			//		in the viewport has been determined (by dragging, for instance),
			//		center the node. Otherwise, use the Dialog's stored relative offset,
			//		and position the node to top: left: values based on the viewport.
			// tags:
			//		private
			if(!dojo.hasClass(dojo.body(),"dojoMove")){

				var node = this.domNode;
				var viewport = dijit.getViewport();
				var p = this._relativePosition;
				var mb = p ? null : dojo.marginBox(node);
				dojo.style(node,{
					left: Math.floor(viewport.l + (p ? p.l : (viewport.w - mb.w) / 2)) + "px",
					top: Math.floor(viewport.t + (p ? p.t : (viewport.h - mb.h) / 2)) + "px"
				});
			}

		},

		_onKey: function(/*Event*/ evt){
			// summary:
			//		Handles the keyboard events for accessibility reasons
			// tags:
			//		private
			if(evt.charOrCode){
				var dk = dojo.keys;
				var node = evt.target;
				if (evt.charOrCode === dk.TAB){
					this._getFocusItems(this.domNode);
				}
				var singleFocusItem = (this._firstFocusItem == this._lastFocusItem);
				// see if we are shift-tabbing from first focusable item on dialog
				if(node == this._firstFocusItem && evt.shiftKey && evt.charOrCode === dk.TAB){
					if(!singleFocusItem){
						dijit.focus(this._lastFocusItem); // send focus to last item in dialog
					}
					dojo.stopEvent(evt);
				}else if(node == this._lastFocusItem && evt.charOrCode === dk.TAB && !evt.shiftKey){
					if (!singleFocusItem){
						dijit.focus(this._firstFocusItem); // send focus to first item in dialog
					}
					dojo.stopEvent(evt);
				}else{
					// see if the key is for the dialog
					while(node){
						if(node == this.domNode){
							if(evt.charOrCode == dk.ESCAPE){
								this.onCancel();
							}else{
								return; // just let it go
							}
						}
						node = node.parentNode;
					}
					// this key is for the disabled document window
					if(evt.charOrCode !== dk.TAB){ // allow tabbing into the dialog for a11y
						dojo.stopEvent(evt);
					// opera won't tab to a div
					}else if(!dojo.isOpera){
						try{
							this._firstFocusItem.focus();
						}catch(e){ /*squelch*/ }
					}
				}
			}
		},

		show: function(){
			// summary:
			//		Display the dialog
			if(this.open){ return; }

			// first time we show the dialog, there's some initialization stuff to do
			if(!this._alreadyInitialized){
				this._setup();
				this._alreadyInitialized=true;
			}

			if(this._fadeOut.status() == "playing"){
				this._fadeOut.stop();
			}

			this._modalconnects.push(dojo.connect(window, "onscroll", this, "layout"));
			this._modalconnects.push(dojo.connect(window, "onresize", this, "layout"));
			this._modalconnects.push(dojo.connect(dojo.doc.documentElement, "onkeypress", this, "_onKey"));

			dojo.style(this.domNode, {
				opacity:0,
				visibility:""
			});
			dojo.style(this.containerNode, { // reset width and height so that _size():marginBox works correctly
				width:"auto",
				height:"auto"
			});

			this.open = true;
			this._onShow(); // lazy load trigger

			this._size();
			this._position();

			this._fadeIn.play();

			this._savedFocus = dijit.getFocus(this);
		},

		hide: function(){
			// summary:
			//		Hide the dialog

			// if we haven't been initialized yet then we aren't showing and we can just return
			if(!this._alreadyInitialized){
				return;
			}

			if(this._fadeIn.status() == "playing"){
				this._fadeIn.stop();
			}
			this._fadeOut.play();

			if (this._scrollConnected){
				this._scrollConnected = false;
			}
			dojo.forEach(this._modalconnects, dojo.disconnect);
			this._modalconnects = [];
			if(this.refocus){
				this.connect(this._fadeOut,"onEnd",dojo.hitch(dijit,"focus",this._savedFocus));
			}
			if(this._relativePosition){
				delete this._relativePosition;
			}
			this.open = false;
		},

		layout: function() {
			// summary:
			//		Position the Dialog and the underlay
			// tags:
			//		private
			if(this.domNode.style.visibility != "hidden"){
				dijit._underlay.layout();
				this._position();
			}
		},

		destroy: function(){
			dojo.forEach(this._modalconnects, dojo.disconnect);
			if(this.refocus && this.open){
				setTimeout(dojo.hitch(dijit,"focus",this._savedFocus), 25);
			}
			this.inherited(arguments);
		},

		_onCloseEnter: function(){
			// summary:
			//		Called when user hovers over close icon
			// tags:
			//		private
			dojo.addClass(this.closeButtonNode, "dijitDialogCloseIcon-hover");
		},

		_onCloseLeave: function(){
			// summary:
			//		Called when user stops hovering over close icon
			// tags:
			//		private
			dojo.removeClass(this.closeButtonNode, "dijitDialogCloseIcon-hover");
		}
	}
);

// For back-compat.  TODO: remove in 2.0
dojo.require("dijit.TooltipDialog");

<|endoftext|>