<commit_before>/**
 * @file Tbody component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import Tr from '../_Tr';

import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

import Util from '../_vendors/Util';

class Tbody extends Component {

    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    isItemChecked = rowData => {

        const {selectMode, idProp, value} = this.props;

        if (!rowData || !value || selectMode === SelectMode.NORMAL) {
            return false;
        }

        switch (selectMode) {
            case SelectMode.MULTI_SELECT:
                return value && value.findIndex(item => item[idProp] === rowData[idProp]) !== -1;
            case SelectMode.SINGLE_SELECT:
                return value[idProp] === rowData[idProp];
        }

    };

    render() {

        const {
            className, style, columns, data, startIndex, idProp, disabled,
            ...restProps
        } = this.props;

        return (
            <tbody className={className}
                   style={style}>
                {
                    data && data.map((row, rowIndex) => row ?
                        <Tr {...restProps}
                            key={idProp && idProp in row ? row[idProp] : rowIndex}
                            rowIndex={startIndex + rowIndex}
                            columns={columns}
                            data={row}
                            tableData={data}
                            isChecked={this.isItemChecked(row)}
                            disabled={disabled || row.disabled}/>
                        :
                        null
                    )
                }
            </tbody>
        );

    }
}

Tbody.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,

    /**
     * The select mode of table.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * The select all mode of table, all or current page.
     */
    selectAllMode: PropTypes.oneOf(Util.enumerateValue(SelectAllMode)),

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * fixed position of column ( true / 'left' / 'right' )
         */
        fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))]),

        /**
         * width of column
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * minimum width of column
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headRenderer: PropTypes.any,

        /**
         * column span of table header
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * column span of table body
         *  (1) function callback:
         *      function (rowData, colIndex, rowIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footRenderer: PropTypes.any,

        /**
         * column span of table foot.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * If true,this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType))

    })).isRequired,

    data: PropTypes.array,
    value: PropTypes.any,
    startIndex: PropTypes.number,
    idProp: PropTypes.string,
    disabled: PropTypes.bool,
    baseColIndex: PropTypes.number,
    expandRows: PropTypes.array,

    /**
     * sorting
     */
    sorting: PropTypes.shape({
        prop: PropTypes.string,
        type: PropTypes.oneOf(Util.enumerateValue(SortingType))
    }),

    /**
     * callback
     */
    onRowClick: PropTypes.func,
    onCellClick: PropTypes.func,
    onExpand: PropTypes.func,
    onCollapse: PropTypes.func

};

Tbody.defaultProps = {
    selectMode: SelectMode.SINGLE_SELECT,
    startIndex: 0,
    idProp: 'id',
    disabled: false,
    baseColIndex: 0,
    expandRows: []
};

export default Tbody;
<commit_msg>update Tbody<commit_after>/**
 * @file Tbody component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import Tr from '../_Tr';

import HorizontalAlign from '../_statics/HorizontalAlign';
import SelectMode from '../_statics/SelectMode';
import SelectAllMode from '../_statics/SelectAllMode';
import SortingType from '../_statics/SortingType';

import Util from '../_vendors/Util';

class Tbody extends Component {

    static Align = HorizontalAlign;
    static SelectMode = SelectMode;
    static SelectAllMode = SelectAllMode;
    static SortingType = SortingType;

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    isItemChecked = rowData => {

        const {selectMode, idProp, value} = this.props;

        if (!rowData || !value || selectMode === SelectMode.NORMAL) {
            return false;
        }

        switch (selectMode) {
            case SelectMode.MULTI_SELECT:
                return value && value.findIndex(item => item[idProp] === rowData[idProp]) !== -1;
            case SelectMode.SINGLE_SELECT:
                return value[idProp] === rowData[idProp];
        }

    };

    render() {

        const {
            className, style, columns, data, startIndex, idProp, disabled,
            ...restProps
        } = this.props;

        return (
            <tbody className={className}
                   style={style}>
                {
                    data && data.map((row, rowIndex) => row ?
                        <Tr {...restProps}
                            key={idProp && idProp in row ? row[idProp] : rowIndex}
                            rowIndex={startIndex + rowIndex}
                            columns={columns}
                            data={row}
                            tableData={data}
                            isChecked={this.isItemChecked(row)}
                            disabled={disabled || row.disabled}/>
                        :
                        null
                    )
                }
            </tbody>
        );

    }
}

Tbody.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,

    /**
     * The select mode of table.
     */
    selectMode: PropTypes.oneOf(Util.enumerateValue(SelectMode)),

    /**
     * The select all mode of table, all or current page.
     */
    selectAllMode: PropTypes.oneOf(Util.enumerateValue(SelectAllMode)),

    /**
     * Children passed into table header.
     */
    columns: PropTypes.arrayOf(PropTypes.shape({

        /**
         * fixed position of column ( true / 'left' / 'right' ).
         */
        fixed: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(Util.enumerateValue(HorizontalAlign))]),

        /**
         * width of column.
         */
        width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * minimum width of column.
         */
        minWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),

        /**
         * align of current column.
         */
        align: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * no wrap of current column.
         */
        noWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of header.
         */
        headClassName: PropTypes.string,

        /**
         * Override the styles of header.
         */
        headStyle: PropTypes.object,

        /**
         * align of table header cell
         */
        headAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table head.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        headRenderer: PropTypes.any,

        /**
         * column span of table header.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        headSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table header.
         */
        headNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of td.
         */
        bodyClassName: PropTypes.string,

        /**
         * Override the styles of td.
         */
        bodyStyle: PropTypes.object,

        /**
         * align of table body cell.
         */
        bodyAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table body.
         *  (1) callback:
         *      function (rowData, rowIndex, colIndex) {
         *          return rowData.id;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        bodyRenderer: PropTypes.any,

        /**
         * column span of table body.
         *  (1) function callback:
         *      function (rowData, colIndex, rowIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        bodySpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table body.
         */
        bodyNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * The class name of footer.
         */
        footClassName: PropTypes.string,

        /**
         * Override the styles of footer.
         */
        footStyle: PropTypes.object,

        /**
         * align of table footer cell
         */
        footAlign: PropTypes.oneOf(Util.enumerateValue(HorizontalAlign)),

        /**
         * The render content in table foot.
         *  (1) callback:
         *      function (tableData, colIndex) {
         *          return colIndex;
         *      }
         *
         *  (2) others:
         *      render whatever you pass
         */
        footRenderer: PropTypes.any,

        /**
         * column span of table foot.
         *  (1) function callback:
         *      function (tableData, colIndex) {
         *          return null;
         *      }
         *
         *  (2) number:
         *      render whatever you pass
         */
        footSpan: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

        /**
         * no wrap of table foot.
         */
        footNoWrap: PropTypes.oneOfType([PropTypes.bool, PropTypes.func]),

        /**
         * If true,this column can be sorted.
         */
        sortable: PropTypes.bool,

        /**
         * Sorting property.
         */
        sortingProp: PropTypes.string,

        defaultSortingType: PropTypes.oneOf(Util.enumerateValue(SortingType))

    })).isRequired,

    data: PropTypes.array,
    value: PropTypes.any,
    startIndex: PropTypes.number,
    idProp: PropTypes.string,
    disabled: PropTypes.bool,
    baseColIndex: PropTypes.number,
    expandRows: PropTypes.array,

    /**
     * sorting
     */
    sorting: PropTypes.shape({
        prop: PropTypes.string,
        type: PropTypes.oneOf(Util.enumerateValue(SortingType))
    }),

    /**
     * callback
     */
    onRowClick: PropTypes.func,
    onCellClick: PropTypes.func,
    onExpand: PropTypes.func,
    onCollapse: PropTypes.func

};

Tbody.defaultProps = {
    selectMode: SelectMode.SINGLE_SELECT,
    startIndex: 0,
    idProp: 'id',
    disabled: false,
    baseColIndex: 0,
    expandRows: []
};

export default Tbody;
<|endoftext|>


<commit_before>/**
 * @file Thead component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import TableHeader from '../_TableHeader';

export default class Thead extends Component {

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    render() {

        const {className, style, columns, sort, hidden, onSort} = this.props;

        return (

                    {
                        columns.map((item, index) => {

                            const headerClassName = (item.sortable ? 'sortable ' : '')
                                + (sort && sort.prop === item.sortProp ? (sort.type > 0 ? ' asc' : ' desc') : '')
                                + (item.headerClassName ? ' ' + item.headerClassName : '');

                            return (
                                <TableHeader key={index}
                                             className={headerClassName}
                                             style={item.headerStyle}
                                             header={item.header}
                                             colIndex={index}
                                             sortable={item.sortable}
                                             sort={sort}
                                             hidden={hidden}
                                             onSort={() => {
                                                 onSort(item.sortProp);
                                             }}/>
                            );

                        })
                    }

        );

    }
};

Thead.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,

    columns: PropTypes.array,
    sort: PropTypes.object,
    hidden: PropTypes.bool,

    onSort: PropTypes.func

};

Thead.defaultProps = {

    className: '',
    style: null,

    columns: [],
    sort: null,
    hidden: false

};<commit_msg>update Thead to support self defined sort icon<commit_after>/**
 * @file Thead component
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import React, {Component} from 'react';
import PropTypes from 'prop-types';

import TableHeader from '../_TableHeader';

export default class Thead extends Component {

    constructor(props, ...restArgs) {
        super(props, ...restArgs);
    }

    render() {

        const {className, style, columns, sort, sortAscIconCls, sortDescIconCls, hidden, onSort} = this.props;

        return (

                    {
                        columns.map((item, index) => {

                            const headerClassName = (item.sortable ? 'sortable ' : '')
                                + (sort && sort.prop === item.sortProp ? (sort.type > 0 ? ' asc' : ' desc') : '')
                                + (item.headerClassName ? ' ' + item.headerClassName : '');

                            return (
                                <TableHeader key={index}
                                             className={headerClassName}
                                             style={item.headerStyle}
                                             header={item.header}
                                             colIndex={index}
                                             sortable={item.sortable}
                                             sort={sort}
                                             sortAscIconCls={sortAscIconCls}
                                             sortDescIconCls={sortDescIconCls}
                                             hidden={hidden}
                                             onSort={() => {
                                                 onSort(item.sortProp);
                                             }}/>
                            );

                        })
                    }

        );

    }
};

Thead.propTypes = {

    className: PropTypes.string,
    style: PropTypes.object,

    columns: PropTypes.array,
    sort: PropTypes.object,
    sortAscIconCls: PropTypes.string,
    sortDescIconCls: PropTypes.string,
    hidden: PropTypes.bool,

    onSort: PropTypes.func

};

Thead.defaultProps = {

    className: '',
    style: null,

    columns: [],
    sort: null,
    sortAscIconCls: 'fa fa-angle-up',
    sortDescIconCls: 'fa fa-angle-down',
    hidden: false

};<|endoftext|>


<commit_before>/*
 * h5ai %BUILD_VERSION%
 *
 * Configuration
 * options, types and localization
 */

var H5AI_CONFIG = {

    "options": {

        /*
         * The absolute links to webroot and h5ai.
         * Do not change this unless you know what you are doing.
         */
        "rootAbsHref": "/",
        "h5aiAbsHref": "/_h5ai/",

        /*
         * Filenames of customized header and footer files to look for
         * in each folder.
         */
        "customHeader": "_h5ai.header.html",
        "customFooter": "_h5ai.footer.html",

        /*
         * An array of view modes the user may choose from. Currently there
         * are two possible values: "details" and "icons". The first value
         * indicates the default view mode. If only one value is given the
         * view mode is fixed and the selector buttons are hidden.
         * The user selected view mode is also stored local in modern browsers
         * so that it will be persistent.
         */
        "viewmodes": ["details", "icons"],

        /*
         * Default sort order is a two letter code. The first letter specifies
         * the column: "n" for "Name", "d" for "Date" or "s" for "Size". The
         * second letter specifies the sort order: "a" for "ascending" or "d"
         * for "descending".
         */
        "sortorder": "na",

        /*
         * Show a folder tree, boolean.
         * Note that this tree might have side effects as it sends HEAD requests
         * to the folders, and therefore will invoke index.php scripts. Use
         * folderStatus below to avoid such requests.
         * It might also affect performance significantly.
         */
        "showTree": true,

        /*
         * Slide tree bar into viewport if there is enough space, boolean.
         */
        "slideTree": true,

        /*
         * Associative array of folders and their HTTP status codes to
         * avoid HEAD requests to that folders. The key (folder) must start
         * and end with a slash (/).
         * For example:
         *   "/some/folder/": 200
         * will always return HTTP status 200 (OK), which will be interpreted
         * as a non auto indexed folder, that means a folder containing an
         * appropriate default index file.
         */
        "folderStatus": {},

        /*
         * Localization, for example "en", "de" etc. - see h5aiLangs below for
         * possible values. Adjust it to your needs. If lang is not found in
         * h5aiLangs it defaults to "en".
         */
        "lang": "en",

        /*
         * Try to use browser language, falls back to previous specified lang.
         */
        "useBrowserLang": true,

        /*
         * Set parent folder labels to real folder names.
         */
        "setParentFolderLabels": true,

        /*
         * Link the hover effects between crumb, extended view and tree.
         */
        "linkHoverStates": true,

        /*
         * Date format in detailed view, for example: "yyyy-MM-dd HH:mm:ss"
         * Syntax as specified by date.js
         * http://code.google.com/p/datejs/wiki/FormatSpecifiers
         */
        "dateFormat": "yyyy-MM-dd HH:mm",

        /*
         * Requires PHP on the server.
         * Show thumbnails for image files.
         */
        "showThumbs": false,

        /*
         * Requires PHP on the server.
         * Enable zipped download of selected entries.
         */
        "zippedDownload": false
    },

    /*
     * File types mapped to file extensions.
     */
    "types": {
        "archive":          [".tar.bz2", ".tar.gz", ".tgz"],
        "audio":            [".aif", ".m4a", ".mid", ".mp3", ".mpa", ".ra", ".ogg", ".wav", ".wma"],
        "authors":          ["authors"],
        "bin":              [".class", ".o", ".so"],
        "blank":            [],
        "bmp":              [".bmp"],
        "c":                [".c"],
        "calc":             [".ods", ".ots", ".xlr", ".xls", ".xlsx"],
        "cd":               [".cue", ".iso"],
        "copying":          ["copying", "license"],
        "cpp":              [".cpp"],
        "css":              [".css", ".less"],
        "deb":              [".deb"],
        "default":          [],
        "doc":              [".doc", ".docx", ".odm", ".odt", ".ott"],
        "draw":             [".drw"],
        "eps":              [".eps"],
        "exe":              [".exe"],
        "folder":           [],
        "folder-home":      [],
        "folder-open":      [],
        "folder-page":      [],
        "folder-parent":    [],
        "gif":              [".gif"],
        "gzip":             [".gz"],
        "h":                [".h"],
        "hpp":              [".hpp"],
        "html":             [".htm", ".html", ".shtml"],
        "ico":              [".ico"],
        "image":            [".xpm"],
        "install":          ["install"],
        "java":             [".java"],
        "jpg":              [".jpg", ".jpeg"],
        "js":               [".js", ".json"],
        "log":              [".log", "changelog"],
        "makefile":         [".pom", "build.xml", "pom.xml"],
        "package":          [],
        "pdf":              [".pdf"],
        "php":              [".php"],
        "playlist":         [".m3u"],
        "png":              [".png"],
        "pres":             [".odp", ".otp", ".pps", ".ppt", ".pptx"],
        "psd":              [".psd"],
        "py":               [".py"],
        "rar":              [".rar"],
        "rb":               [".rb"],
        "readme":           ["readme"],
        "rpm":              [".rpm"],
        "rss":              [".rss"],
        "rtf":              [".rtf"],
        "script":           [".conf", ".csh", ".ini", ".ksh", ".sh", ".shar", ".tcl"],
        "source":           [],
        "sql":              [],
        "tar":              [".tar"],
        "tex":              [".tex"],
        "text":             [".markdown", ".md", ".text", ".txt"],
        "tiff":             [".tiff"],
        "unknown":          [],
        "vcal":             [".vcal"],
        "video":            [".avi", ".flv", ".mov", ".mp4", ".mpg", ".rm", ".swf", ".vob", ".wmv"],
        "xml":              [".xml"],
        "zip":              [".bz2", ".jar", ".war", ".z", ".Z", ".zip"]
    },

    /*
     * Available translations.
     */
    "langs": {

        "en": {
            "lang": "english",
            "details": "details",
            "icons": "icons",
            "name": "Name",
            "lastModified": "Last modified",
            "size": "Size",
            "parentDirectory": "Parent Directory",
            "empty": "empty",
            "folders": "folders",
            "files": "files",
            "download": "download"
        },

        "bg": {
            "lang": "български",
            "details": "детайли",
            "icons": "икони",
            "name": "Име",
            "lastModified": "Последна промяна",
            "size": "Размер",
            "parentDirectory": "Предходна директория",
            "empty": "празно",
            "folders": "папки",
            "files": "файлове",
            "download": "download"
        },

        "cs": {
            "lang": "čeština",
            "details": "podrobnosti",
            "icons": "ikony",
            "name": "Název",
            "lastModified": "Upraveno",
            "size": "Velikost",
            "parentDirectory": "Nadřazený adresář",
            "empty": "prázdný",
            "folders": "složek",
            "files": "souborů",
            "download": "download"
        },

        "de": {
            "lang": "deutsch",
            "details": "Details",
            "icons": "Icons",
            "name": "Name",
            "lastModified": "Geändert",
            "size": "Größe",
            "parentDirectory": "Übergeordnetes Verzeichnis",
            "empty": "leer",
            "folders": "Ordner",
            "files": "Dateien",
            "download": "Download"
        },

        "es": {
            "lang": "español",
            "details": "Detalles",
            "icons": "Íconos",
            "name": "Nombre",
            "lastModified": "Última modificación",
            "size": "Tamaño",
            "parentDirectory": "Directorio superior",
            "empty": "vacío",
            "folders": "folders",
            "files": "files",
            "download": "download"
        },

        "fr": {
            "lang": "français",
            "details": "détails",
            "icons": "icônes",
            "name": "Nom",
            "lastModified": "Dernière modification",
            "size": "Taille",
            "parentDirectory": "Dossier parent",
            "empty": "vide",
            "folders": "Répertoires",
            "files": "Fichiers",
            "download": "télécharger"
        },

        "it": {
            "lang": "italiano",
            "details": "dettagli",
            "icons": "icone",
            "name": "Nome",
            "lastModified": "Ultima modifica",
            "size": "Dimensione",
            "parentDirectory": "Cartella Superiore",
            "empty": "vuota",
            "folders": "cartelle",
            "files": "file",
            "download": "download"
       },

        "lv": {
            "lang": "latviešu",
            "details": "detaļas",
            "icons": "ikonas",
            "name": "Nosaukums",
            "lastModified": "Pēdējoreiz modificēts",
            "size": "Izmērs",
            "parentDirectory": "Vecākdirektorijs",
            "empty": "tukšs",
            "folders": "mapes",
            "files": "faili",
            "download": "lejupielādēt"
        },

        "nl": {
            "lang": "nederlands",
            "details": "details",
            "icons": "iconen",
            "name": "Naam",
            "lastModified": "Laatste wijziging",
            "size": "Grootte",
            "parentDirectory": "Bovenliggende map",
            "empty": "lege",
            "folders": "folders",
            "files": "files",
            "download": "download"
        },

        "pl": {
            "lang": "polski",
            "details": "szczegóły",
            "icons": "ikony",
            "name": "Nazwa",
            "lastModified": "Ostatnia modyfikacja",
            "size": "Rozmiar",
            "parentDirectory": "Katalog nadrzędny",
            "empty": "pusty",
            "folders": "foldery",
            "files": "pliki",
            "download": "download"
        },

        "pt": {
            "lang": "português",
            "details": "detalhes",
            "icons": "ícones",
            "name": "Nome",
            "lastModified": "Última modificação",
            "size": "Tamanho",
            "parentDirectory": "Diretório superior",
            "empty": "vazio",
            "folders": "pastas",
            "files": "arquivos",
            "download": "download"
        },

        "ru": {
            "lang": "русский",
            "details": "детали",
            "icons": "иконки",
            "name": "Имя",
            "lastModified": "Последние изменения",
            "size": "Размер",
            "parentDirectory": "Главная директория",
            "empty": "пусто",
            "folders": "папки",
            "files": "файлы",
            "download": "download"
        },

        "sk": {
            "lang": "slovenčina",
            "details": "podrobnosti",
            "icons": "ikony",
            "name": "Názov",
            "lastModified": "Upravené",
            "size": "Velkosť",
            "parentDirectory": "Nadriadený priečinok",
            "empty": "prázdny",
            "folders": "priečinkov",
            "files": "súborov",
            "download": "download"
        },

        "sv": {
            "lang": "svenska",
            "details": "detaljerad",
            "icons": "ikoner",
            "name": "Filnamn",
            "lastModified": "Senast ändrad",
            "size": "Filstorlek",
            "parentDirectory": "Till överordnad mapp",
            "empty": "tom",
            "folders": "folders",
            "files": "files",
            "download": "download"
        },

        "tr": {
            "lang": "türkçe",
            "details": "detaylar",
            "icons": "ikonlar",
            "name": "İsim",
            "lastModified": "Son Düzenleme",
            "size": "Boyut",
            "parentDirectory": "Üst Dizin",
            "empty": "boş",
            "folders": "klasörler",
            "files": "dosyalar",
            "download": "indir"
        },

        "zh-cn": {
            "lang": "简体中文",
            "details": "详情",
            "icons": "图标",
            "name": "文件名",
            "lastModified": "上次修改",
            "size": "大小",
            "parentDirectory": "上层文件夹",
            "empty": "空文件夹",
            "folders": "文件夹",
            "files": "文件",
            "download": "download"
        }
    }
};
<commit_msg>Updates es translation.<commit_after>/*
 * h5ai %BUILD_VERSION%
 *
 * Configuration
 * options, types and localization
 */

var H5AI_CONFIG = {

    "options": {

        /*
         * The absolute links to webroot and h5ai.
         * Do not change this unless you know what you are doing.
         */
        "rootAbsHref": "/",
        "h5aiAbsHref": "/_h5ai/",

        /*
         * Filenames of customized header and footer files to look for
         * in each folder.
         */
        "customHeader": "_h5ai.header.html",
        "customFooter": "_h5ai.footer.html",

        /*
         * An array of view modes the user may choose from. Currently there
         * are two possible values: "details" and "icons". The first value
         * indicates the default view mode. If only one value is given the
         * view mode is fixed and the selector buttons are hidden.
         * The user selected view mode is also stored local in modern browsers
         * so that it will be persistent.
         */
        "viewmodes": ["details", "icons"],

        /*
         * Default sort order is a two letter code. The first letter specifies
         * the column: "n" for "Name", "d" for "Date" or "s" for "Size". The
         * second letter specifies the sort order: "a" for "ascending" or "d"
         * for "descending".
         */
        "sortorder": "na",

        /*
         * Show a folder tree, boolean.
         * Note that this tree might have side effects as it sends HEAD requests
         * to the folders, and therefore will invoke index.php scripts. Use
         * folderStatus below to avoid such requests.
         * It might also affect performance significantly.
         */
        "showTree": true,

        /*
         * Slide tree bar into viewport if there is enough space, boolean.
         */
        "slideTree": true,

        /*
         * Associative array of folders and their HTTP status codes to
         * avoid HEAD requests to that folders. The key (folder) must start
         * and end with a slash (/).
         * For example:
         *   "/some/folder/": 200
         * will always return HTTP status 200 (OK), which will be interpreted
         * as a non auto indexed folder, that means a folder containing an
         * appropriate default index file.
         */
        "folderStatus": {},

        /*
         * Localization, for example "en", "de" etc. - see h5aiLangs below for
         * possible values. Adjust it to your needs. If lang is not found in
         * h5aiLangs it defaults to "en".
         */
        "lang": "en",

        /*
         * Try to use browser language, falls back to previous specified lang.
         */
        "useBrowserLang": true,

        /*
         * Set parent folder labels to real folder names.
         */
        "setParentFolderLabels": true,

        /*
         * Link the hover effects between crumb, extended view and tree.
         */
        "linkHoverStates": true,

        /*
         * Date format in detailed view, for example: "yyyy-MM-dd HH:mm:ss"
         * Syntax as specified by date.js
         * http://code.google.com/p/datejs/wiki/FormatSpecifiers
         */
        "dateFormat": "yyyy-MM-dd HH:mm",

        /*
         * Requires PHP on the server.
         * Show thumbnails for image files.
         */
        "showThumbs": false,

        /*
         * Requires PHP on the server.
         * Enable zipped download of selected entries.
         */
        "zippedDownload": false
    },

    /*
     * File types mapped to file extensions.
     */
    "types": {
        "archive":          [".tar.bz2", ".tar.gz", ".tgz"],
        "audio":            [".aif", ".m4a", ".mid", ".mp3", ".mpa", ".ra", ".ogg", ".wav", ".wma"],
        "authors":          ["authors"],
        "bin":              [".class", ".o", ".so"],
        "blank":            [],
        "bmp":              [".bmp"],
        "c":                [".c"],
        "calc":             [".ods", ".ots", ".xlr", ".xls", ".xlsx"],
        "cd":               [".cue", ".iso"],
        "copying":          ["copying", "license"],
        "cpp":              [".cpp"],
        "css":              [".css", ".less"],
        "deb":              [".deb"],
        "default":          [],
        "doc":              [".doc", ".docx", ".odm", ".odt", ".ott"],
        "draw":             [".drw"],
        "eps":              [".eps"],
        "exe":              [".exe"],
        "folder":           [],
        "folder-home":      [],
        "folder-open":      [],
        "folder-page":      [],
        "folder-parent":    [],
        "gif":              [".gif"],
        "gzip":             [".gz"],
        "h":                [".h"],
        "hpp":              [".hpp"],
        "html":             [".htm", ".html", ".shtml"],
        "ico":              [".ico"],
        "image":            [".xpm"],
        "install":          ["install"],
        "java":             [".java"],
        "jpg":              [".jpg", ".jpeg"],
        "js":               [".js", ".json"],
        "log":              [".log", "changelog"],
        "makefile":         [".pom", "build.xml", "pom.xml"],
        "package":          [],
        "pdf":              [".pdf"],
        "php":              [".php"],
        "playlist":         [".m3u"],
        "png":              [".png"],
        "pres":             [".odp", ".otp", ".pps", ".ppt", ".pptx"],
        "psd":              [".psd"],
        "py":               [".py"],
        "rar":              [".rar"],
        "rb":               [".rb"],
        "readme":           ["readme"],
        "rpm":              [".rpm"],
        "rss":              [".rss"],
        "rtf":              [".rtf"],
        "script":           [".conf", ".csh", ".ini", ".ksh", ".sh", ".shar", ".tcl"],
        "source":           [],
        "sql":              [],
        "tar":              [".tar"],
        "tex":              [".tex"],
        "text":             [".markdown", ".md", ".text", ".txt"],
        "tiff":             [".tiff"],
        "unknown":          [],
        "vcal":             [".vcal"],
        "video":            [".avi", ".flv", ".mov", ".mp4", ".mpg", ".rm", ".swf", ".vob", ".wmv"],
        "xml":              [".xml"],
        "zip":              [".bz2", ".jar", ".war", ".z", ".Z", ".zip"]
    },

    /*
     * Available translations.
     */
    "langs": {

        "en": {
            "lang": "english",
            "details": "details",
            "icons": "icons",
            "name": "Name",
            "lastModified": "Last modified",
            "size": "Size",
            "parentDirectory": "Parent Directory",
            "empty": "empty",
            "folders": "folders",
            "files": "files",
            "download": "download"
        },

        "bg": {
            "lang": "български",
            "details": "детайли",
            "icons": "икони",
            "name": "Име",
            "lastModified": "Последна промяна",
            "size": "Размер",
            "parentDirectory": "Предходна директория",
            "empty": "празно",
            "folders": "папки",
            "files": "файлове",
            "download": "download"
        },

        "cs": {
            "lang": "čeština",
            "details": "podrobnosti",
            "icons": "ikony",
            "name": "Název",
            "lastModified": "Upraveno",
            "size": "Velikost",
            "parentDirectory": "Nadřazený adresář",
            "empty": "prázdný",
            "folders": "složek",
            "files": "souborů",
            "download": "download"
        },

        "de": {
            "lang": "deutsch",
            "details": "Details",
            "icons": "Icons",
            "name": "Name",
            "lastModified": "Geändert",
            "size": "Größe",
            "parentDirectory": "Übergeordnetes Verzeichnis",
            "empty": "leer",
            "folders": "Ordner",
            "files": "Dateien",
            "download": "Download"
        },

        "es": {
            "lang": "español",
            "details": "Detalles",
            "icons": "Íconos",
            "name": "Nombre",
            "lastModified": "Última modificación",
            "size": "Tamaño",
            "parentDirectory": "Directorio superior",
            "empty": "vacío",
            "folders": "Directorios",
            "files": "Archivos",
            "download": "Descargar"
        },

        "fr": {
            "lang": "français",
            "details": "détails",
            "icons": "icônes",
            "name": "Nom",
            "lastModified": "Dernière modification",
            "size": "Taille",
            "parentDirectory": "Dossier parent",
            "empty": "vide",
            "folders": "Répertoires",
            "files": "Fichiers",
            "download": "télécharger"
        },

        "it": {
            "lang": "italiano",
            "details": "dettagli",
            "icons": "icone",
            "name": "Nome",
            "lastModified": "Ultima modifica",
            "size": "Dimensione",
            "parentDirectory": "Cartella Superiore",
            "empty": "vuota",
            "folders": "cartelle",
            "files": "file",
            "download": "download"
       },

        "lv": {
            "lang": "latviešu",
            "details": "detaļas",
            "icons": "ikonas",
            "name": "Nosaukums",
            "lastModified": "Pēdējoreiz modificēts",
            "size": "Izmērs",
            "parentDirectory": "Vecākdirektorijs",
            "empty": "tukšs",
            "folders": "mapes",
            "files": "faili",
            "download": "lejupielādēt"
        },

        "nl": {
            "lang": "nederlands",
            "details": "details",
            "icons": "iconen",
            "name": "Naam",
            "lastModified": "Laatste wijziging",
            "size": "Grootte",
            "parentDirectory": "Bovenliggende map",
            "empty": "lege",
            "folders": "folders",
            "files": "files",
            "download": "download"
        },

        "pl": {
            "lang": "polski",
            "details": "szczegóły",
            "icons": "ikony",
            "name": "Nazwa",
            "lastModified": "Ostatnia modyfikacja",
            "size": "Rozmiar",
            "parentDirectory": "Katalog nadrzędny",
            "empty": "pusty",
            "folders": "foldery",
            "files": "pliki",
            "download": "download"
        },

        "pt": {
            "lang": "português",
            "details": "detalhes",
            "icons": "ícones",
            "name": "Nome",
            "lastModified": "Última modificação",
            "size": "Tamanho",
            "parentDirectory": "Diretório superior",
            "empty": "vazio",
            "folders": "pastas",
            "files": "arquivos",
            "download": "download"
        },

        "ru": {
            "lang": "русский",
            "details": "детали",
            "icons": "иконки",
            "name": "Имя",
            "lastModified": "Последние изменения",
            "size": "Размер",
            "parentDirectory": "Главная директория",
            "empty": "пусто",
            "folders": "папки",
            "files": "файлы",
            "download": "download"
        },

        "sk": {
            "lang": "slovenčina",
            "details": "podrobnosti",
            "icons": "ikony",
            "name": "Názov",
            "lastModified": "Upravené",
            "size": "Velkosť",
            "parentDirectory": "Nadriadený priečinok",
            "empty": "prázdny",
            "folders": "priečinkov",
            "files": "súborov",
            "download": "download"
        },

        "sv": {
            "lang": "svenska",
            "details": "detaljerad",
            "icons": "ikoner",
            "name": "Filnamn",
            "lastModified": "Senast ändrad",
            "size": "Filstorlek",
            "parentDirectory": "Till överordnad mapp",
            "empty": "tom",
            "folders": "folders",
            "files": "files",
            "download": "download"
        },

        "tr": {
            "lang": "türkçe",
            "details": "detaylar",
            "icons": "ikonlar",
            "name": "İsim",
            "lastModified": "Son Düzenleme",
            "size": "Boyut",
            "parentDirectory": "Üst Dizin",
            "empty": "boş",
            "folders": "klasörler",
            "files": "dosyalar",
            "download": "indir"
        },

        "zh-cn": {
            "lang": "简体中文",
            "details": "详情",
            "icons": "图标",
            "name": "文件名",
            "lastModified": "上次修改",
            "size": "大小",
            "parentDirectory": "上层文件夹",
            "empty": "空文件夹",
            "folders": "文件夹",
            "files": "文件",
            "download": "download"
        }
    }
};
<|endoftext|>


<commit_before>import { hashHistory } from 'react-router'
import * as actionTypes from '../constants/actionTypes'

export function changePage(page) {
  hashHistory.replace(page);
  return { type: actionTypes.FAILED_REQUESTS_CLEARED }
}<commit_msg>Revert "Fix hashHistory warning"<commit_after>import { hashHistory } from 'react-router'
import * as actionTypes from '../constants/actionTypes'

export function changePage(page) {
  hashHistory.push(page);
  return { type: actionTypes.FAILED_REQUESTS_CLEARED }
}<|endoftext|>


<commit_before>/**
 * dom storage adapter
 * ===
 * - originally authored by Joseph Pecoraro
 *
 */
//
// TODO does it make sense to be chainable all over the place?
// chainable: nuke, remove, all, get, save, all
// perhaps time to look at promises?
// not chainable: valid, keys
//
Lawnchair.adapter('dom', {
    // ensure we are in an env with localStorage
    valid: function () {
        return !!window.Storage
    },

    init: function (options, callback) {
        // yay dom!
        this.storage = window.localStorage
        // indexer helper code
        var self = this
        // the indexer is an encapsulation of the helpers needed to keep an ordered index of the keys
        this.indexer = {
            // the key
            key: self.name + '._index_',
            // returns the index
            all: function() {
                var a = JSON.parse(self.storage.getItem(this.key))
                if (a == null) self.storage.setItem(this.key, JSON.stringify([])) // lazy init
                return JSON.parse(self.storage.getItem(this.key))
            },
            // adds a key to the index
            add: function (key) {
                var a = this.all()
                a.push(key)
                self.storage.setItem(this.key, JSON.stringify(a))
            },
            // deletes a key from the index
            del: function (key) {
                var a = this.all(), r = []
                // FIXME this is crazy inefficient but I'm in a strata meeting and half concentrating
                for (var i = 0, l = a.length; i < l; i++) {
                    if (a[i] != key) r.push(a[i])
                }
                self.storage.setItem(this.key, JSON.stringify(r))
            },
            // returns index for a key
            find: function (key) {
                var a = this.all()
                for (var i = 0, l = a.length; i < l; i++) {
                    if (key === a[i]) return i
                }
                return false
            }
        }

        if (callback) this.fn(this.name, callback).call(this, this)
    },

    save: function (obj, callback) {
        var key = obj.key || this.uuid()
        // if the key is not in the index push it on
        if (!this.indexer.find(key)) this.indexer.add(key)
        // now we kil the key and use it in the store colleciton
        delete obj.key;
        this.storage.setItem(key, JSON.stringify(obj))
        if (callback) {
            obj.key = key
            this.lambda(callback).call(this, obj)
        }
        return this
    },

    batch: function (ary, callback) {
        var saved = []
        // not particularily efficient but this is more for sqlite situations
        for (var i = 0, l = ary.length; i < l; i++) {
            this.save(ary[i], function(r){
                saved.push(r)
            })
        }
        if (callback) this.lambda(callback).call(this, saved)
        return this
    },

    // accepts [options], callback
    keys: function() {
        // TODO support limit/offset options here
        var limit = options.limit || null
        ,   offset = options.offset || 0
        if (callback) this.lambda(callback).call(this, this.indexer.all())
    },

    get: function (key, callback) {
        if (this.isArray(key)) {
            var r = []
            for (var i = 0, l = key.length; i < l; i++) {
                var obj = JSON.parse(this.storage.getItem(key[i]))
                if (obj) {
                    obj.key = key[i]
                    r.push(obj)
                }
            }
            if (callback) this.lambda(callback).call(this, r)
        } else {
            var obj = JSON.parse(this.storage.getItem(key))
            if (obj) obj.key = key
            if (callback) this.lambda(callback).call(this, obj)
        }
        return this
    },
    // NOTE adapters cannot set this.__results but plugins do
    // this probably should be reviewed
    all: function (callback) {
        var idx = this.indexer.all()
        ,   r   = []
        ,   o
        for (var i = 0, l = idx.length; i < l; i++) {
            o = JSON.parse(this.storage.getItem(idx[i]))
            o.key = idx[i]
            r.push(o)
        }
        if (callback) this.fn(this.name, callback).call(this, r)
        return this
    },

    remove: function (keyOrObj, callback) {
        var key = typeof keyOrObj === 'string' ? keyOrObj : keyOrObj.key
        this.indexer.del(key)
        this.storage.removeItem(key)
        if (callback) this.lambda(callback).call(this)
        return this
    },

    nuke: function (callback) {
        this.all(function(r) {
            for (var i = 0, l = r.length; i < l; i++) {
                this.remove(r[i]);
            }
            if (callback) this.lambda(callback).call(this)
        })
        return this
    }
});
<commit_msg>src/adapters/dom.js<commit_after>/**
 * dom storage adapter
 * ===
 * - originally authored by Joseph Pecoraro
 *
 */
//
// TODO does it make sense to be chainable all over the place?
// chainable: nuke, remove, all, get, save, all
// perhaps time to look at promises?
// not chainable: valid, keys
//
Lawnchair.adapter('dom', {
    // ensure we are in an env with localStorage
    valid: function () {
        return !!window.Storage
    },

    init: function (options, callback) {
        // yay dom!
        this.storage = window.localStorage
        // indexer helper code
        var self = this
        // the indexer is an encapsulation of the helpers needed to keep an ordered index of the keys
        this.indexer = {
            // the key
            key: self.name + '._index_',
            // returns the index
            all: function() {
                var a = JSON.parse(self.storage.getItem(this.key))
                if (a == null) self.storage.setItem(this.key, JSON.stringify([])) // lazy init
                return JSON.parse(self.storage.getItem(this.key))
            },
            // adds a key to the index
            add: function (key) {
                var a = this.all()
                a.push(key)
                self.storage.setItem(this.key, JSON.stringify(a))
            },
            // deletes a key from the index
            del: function (key) {
                var a = this.all(), r = []
                // FIXME this is crazy inefficient but I'm in a strata meeting and half concentrating
                for (var i = 0, l = a.length; i < l; i++) {
                    if (a[i] != key) r.push(a[i])
                }
                self.storage.setItem(this.key, JSON.stringify(r))
            },
            // returns index for a key
            find: function (key) {
                var a = this.all()
                for (var i = 0, l = a.length; i < l; i++) {
                    if (key === a[i]) return i
                }
                return false
            }
        }

        if (callback) this.fn(this.name, callback).call(this, this)
    },

    save: function (obj, callback) {
        var key = obj.key || this.uuid()
        // if the key is not in the index push it on
        if (this.indexer.find(key) === false) this.indexer.add(key)
	    // now we kil the key and use it in the store colleciton
        delete obj.key;
        this.storage.setItem(key, JSON.stringify(obj))
        if (callback) {
            obj.key = key
            this.lambda(callback).call(this, obj)
        }
        return this
    },

    batch: function (ary, callback) {
        var saved = []
        // not particularily efficient but this is more for sqlite situations
        for (var i = 0, l = ary.length; i < l; i++) {
            this.save(ary[i], function(r){
                saved.push(r)
            })
        }
        if (callback) this.lambda(callback).call(this, saved)
        return this
    },

    // accepts [options], callback
    keys: function() {
        // TODO support limit/offset options here
        var limit = options.limit || null
        ,   offset = options.offset || 0
        if (callback) this.lambda(callback).call(this, this.indexer.all())
    },

    get: function (key, callback) {
        if (this.isArray(key)) {
            var r = []
            for (var i = 0, l = key.length; i < l; i++) {
                var obj = JSON.parse(this.storage.getItem(key[i]))
                if (obj) {
                    obj.key = key[i]
                    r.push(obj)
                }
            }
            if (callback) this.lambda(callback).call(this, r)
        } else {
            var obj = JSON.parse(this.storage.getItem(key))
            if (obj) obj.key = key
            if (callback) this.lambda(callback).call(this, obj)
        }
        return this
    },
    // NOTE adapters cannot set this.__results but plugins do
    // this probably should be reviewed
    all: function (callback) {
        var idx = this.indexer.all()
        ,   r   = []
        ,   o
        for (var i = 0, l = idx.length; i < l; i++) {
            o = JSON.parse(this.storage.getItem(idx[i]))
            o.key = idx[i]
            r.push(o)
        }
        if (callback) this.fn(this.name, callback).call(this, r)
        return this
    },

    remove: function (keyOrObj, callback) {
        var key = typeof keyOrObj === 'string' ? keyOrObj : keyOrObj.key
        this.indexer.del(key)
        this.storage.removeItem(key)
        if (callback) this.lambda(callback).call(this)
        return this
    },

    nuke: function (callback) {
        this.all(function(r) {
            for (var i = 0, l = r.length; i < l; i++) {
                this.remove(r[i]);
            }
            if (callback) this.lambda(callback).call(this)
        })
        return this
    }
});
<|endoftext|>


<commit_before>/*
 * Add-on Loader app.
 *
 * This app will load an add-on as a standalone process.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

'use strict';

const UserProfile = require('./user-profile');
UserProfile.init();

const config = require('config');
const Constants = require('./constants');
const dynamicRequire = require('./dynamic-require');
const GetOpt = require('node-getopt');
const PluginClient = require('./plugin/plugin-client');
const db = require('./db');
const Settings = require('./models/settings');
const sleep = require('./sleep');
const fs = require('fs');
const path = require('path');

// Open the database.
db.open();

async function loadAddon(addonPath, verbose) {
  // Skip if there's no package.json file.
  const packageJson = path.join(addonPath, 'package.json');
  if (!fs.lstatSync(packageJson).isFile()) {
    const err = `package.json not found: ${packageJson}`;
    return Promise.reject(err);
  }

  // Read the package.json file.
  let data;
  try {
    data = fs.readFileSync(packageJson);
  } catch (e) {
    const err =
      `Failed to read package.json: ${packageJson}\n${e}`;
    return Promise.reject(err);
  }

  let manifest;
  try {
    manifest = JSON.parse(data);
  } catch (e) {
    const err =
      `Failed to parse package.json: ${packageJson}\n${e}`;
    return Promise.reject(err);
  }

  // Verify API version.
  const apiVersion = config.get('addonManager.api');
  if (manifest.moziot.api.min > apiVersion ||
      manifest.moziot.api.max < apiVersion) {
    console.error(
      `API mismatch for package: ${manifest.name}\n` +
      `Current: ${apiVersion} ` +
      `Supported: ${manifest.moziot.api.min}-${manifest.moziot.api.max}`);

    const err =
      `Failed to start ${manifest.display_name} add-on: API version mismatch`;
    return Promise.reject(err);
  }

  // Get any saved settings for this add-on.
  const key = `addons.${manifest.name}`;
  const savedSettings = await Settings.get(key);
  const newSettings = Object.assign({}, manifest);
  if (savedSettings) {
    // Overwrite config values.
    newSettings.moziot.config = Object.assign(manifest.moziot.config || {},
                                              savedSettings.moziot.config);
  } else if (!newSettings.moziot.hasOwnProperty('config')) {
    newSettings.moziot.config = {};
  }

  const pluginClient = new PluginClient(manifest.name, {verbose});

  return pluginClient.register()
    .catch((e) => {
      console.error(e);
      const err = `Failed to register package: ${manifest.name} with gateway`;
      return Promise.reject(err);
    })
    .then((addonManagerProxy) => {
      console.log('Loading add-on for', manifest.name, 'from', addonPath);
      try {
        const addonLoader = dynamicRequire(addonPath);
        addonLoader(addonManagerProxy, newSettings, (packageName, errorStr) => {
          console.error('Failed to load', packageName, '-', errorStr);
          const message =
          `Failed to start ${manifest.display_name} add-on: ${errorStr}`;
          fail(addonManagerProxy, message);
        });

        if (config.get('ipc.protocol') !== 'inproc') {
          pluginClient.on('unloaded', () => {
            sleep(500).then(() => process.exit(0));
          });
        }
      } catch (e) {
        console.error(e);
        const message =
        `Failed to start ${manifest.display_name} add-on: ${
          e.toString().replace(/^Error:\s+/, '')}`;
        fail(addonManagerProxy, message);
      }
    });
}

async function fail(addonManagerProxy, message) {
  addonManagerProxy.sendError(message);
  await sleep(200);
  addonManagerProxy.unloadPlugin();
  await sleep(200);
  process.exit(Constants.DONT_RESTART_EXIT_CODE);
}

// Get some decent error messages for unhandled rejections. This is
// often just errors in the code.
process.on('unhandledRejection', (reason) => {
  console.log('Unhandled Rejection');
  console.error(reason);
});

// Command line arguments
const getopt = new GetOpt([
  ['h', 'help', 'Display help' ],
  ['v', 'verbose', 'Show verbose output'],
]);

const opt = getopt.parseSystem();

if (opt.options.verbose) {
  console.log(opt);
}

if (opt.options.help) {
  getopt.showHelp();
  process.exit(Constants.DONT_RESTART_EXIT_CODE);
}

if (opt.argv.length != 1) {
  console.error('Expecting a single package to load');
  process.exit(Constants.DONT_RESTART_EXIT_CODE);
}
const addonPath = opt.argv[0];

loadAddon(addonPath, opt.verbose).catch((err) => {
  console.error(err);
  process.exit(Constants.DONT_RESTART_EXIT_CODE);
});
<commit_msg>Fixed a typo in the addon-loader (#2001)<commit_after>/*
 * Add-on Loader app.
 *
 * This app will load an add-on as a standalone process.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

'use strict';

const UserProfile = require('./user-profile');
UserProfile.init();

const config = require('config');
const Constants = require('./constants');
const dynamicRequire = require('./dynamic-require');
const GetOpt = require('node-getopt');
const PluginClient = require('./plugin/plugin-client');
const db = require('./db');
const Settings = require('./models/settings');
const sleep = require('./sleep');
const fs = require('fs');
const path = require('path');

// Open the database.
db.open();

async function loadAddon(addonPath, verbose) {
  // Skip if there's no package.json file.
  const packageJson = path.join(addonPath, 'package.json');
  if (!fs.lstatSync(packageJson).isFile()) {
    const err = `package.json not found: ${packageJson}`;
    return Promise.reject(err);
  }

  // Read the package.json file.
  let data;
  try {
    data = fs.readFileSync(packageJson);
  } catch (e) {
    const err =
      `Failed to read package.json: ${packageJson}\n${e}`;
    return Promise.reject(err);
  }

  let manifest;
  try {
    manifest = JSON.parse(data);
  } catch (e) {
    const err =
      `Failed to parse package.json: ${packageJson}\n${e}`;
    return Promise.reject(err);
  }

  // Verify API version.
  const apiVersion = config.get('addonManager.api');
  if (manifest.moziot.api.min > apiVersion ||
      manifest.moziot.api.max < apiVersion) {
    console.error(
      `API mismatch for package: ${manifest.name}\n` +
      `Current: ${apiVersion} ` +
      `Supported: ${manifest.moziot.api.min}-${manifest.moziot.api.max}`);

    const err =
      `Failed to start ${manifest.display_name} add-on: API version mismatch`;
    return Promise.reject(err);
  }

  // Get any saved settings for this add-on.
  const key = `addons.${manifest.name}`;
  const savedSettings = await Settings.get(key);
  const newSettings = Object.assign({}, manifest);
  if (savedSettings) {
    // Overwrite config values.
    newSettings.moziot.config = Object.assign(manifest.moziot.config || {},
                                              savedSettings.moziot.config);
  } else if (!newSettings.moziot.hasOwnProperty('config')) {
    newSettings.moziot.config = {};
  }

  const pluginClient = new PluginClient(manifest.name, {verbose});

  return pluginClient.register()
    .catch((e) => {
      console.error(e);
      const err = `Failed to register package: ${manifest.name} with gateway`;
      return Promise.reject(err);
    })
    .then((addonManagerProxy) => {
      console.log('Loading add-on for', manifest.name, 'from', addonPath);
      try {
        const addonLoader = dynamicRequire(addonPath);
        addonLoader(addonManagerProxy, newSettings, (packageName, errorStr) => {
          console.error('Failed to load', packageName, '-', errorStr);
          const message =
          `Failed to start ${manifest.display_name} add-on: ${errorStr}`;
          fail(addonManagerProxy, message);
        });

        if (config.get('ipc.protocol') !== 'inproc') {
          pluginClient.on('unloaded', () => {
            sleep(500).then(() => process.exit(0));
          });
        }
      } catch (e) {
        console.error(e);
        const message =
        `Failed to start ${manifest.display_name} add-on: ${
          e.toString().replace(/^Error:\s+/, '')}`;
        fail(addonManagerProxy, message);
      }
    });
}

async function fail(addonManagerProxy, message) {
  addonManagerProxy.sendError(message);
  await sleep(200);
  addonManagerProxy.unloadPlugin();
  await sleep(200);
  process.exit(Constants.DONT_RESTART_EXIT_CODE);
}

// Get some decent error messages for unhandled rejections. This is
// often just errors in the code.
process.on('unhandledRejection', (reason) => {
  console.log('Unhandled Rejection');
  console.error(reason);
});

// Command line arguments
const getopt = new GetOpt([
  ['h', 'help', 'Display help' ],
  ['v', 'verbose', 'Show verbose output'],
]);

const opt = getopt.parseSystem();

if (opt.options.verbose) {
  console.log(opt);
}

if (opt.options.help) {
  getopt.showHelp();
  process.exit(Constants.DONT_RESTART_EXIT_CODE);
}

if (opt.argv.length != 1) {
  console.error('Expecting a single package to load');
  process.exit(Constants.DONT_RESTART_EXIT_CODE);
}
const addonPath = opt.argv[0];

loadAddon(addonPath, opt.options.verbose).catch((err) => {
  console.error(err);
  process.exit(Constants.DONT_RESTART_EXIT_CODE);
});
<|endoftext|>


<commit_before>var alarmOptions = new UI.Menu({
    sections: [{
        items: [{
            title: 'Disable'
        }, {
            title: 'Edit'
        }, {
            title: 'Delete'
        }]
    }]
});

alarmOptions.on('select', function(e) {
    switch(e.itemIndex) {
        case 1:
            // Disable or Enable the Alarm
            break;
        case 2:
            //Edit the time of the alarm
            break;
        case 3:
            // Deletes the alarm
            break;
        default:
            console.log("error");
            break;
    }
});
<commit_msg>trying to create an custom menu objec<commit_after>var alarmOptions = new UI.Menu({
    sections: [{
        items: [{
            title: 'Disable'
        }, {
            title: 'Edit'
        }, {
            title: 'Delete'
        }]
    }]
});

/*
var alarmOptions = function(e.) {
    this = new UI.Menu({
        sections: [{
            items: [{
                title: 'Disable'
            }, {
                title: 'Edit'
            }, {
                title: 'Delete'
            }]
        }]
    });
};
*/

alarmOptions.on('select', function(e) {
    switch(e.itemIndex) {
        case 1:
            // Disable or Enable the Alarm
            break;
        case 2:
            //Edit the time of the alarm
            break;
        case 3:
            // Deletes the alarm
            break;
        default:
            console.log("error");
            break;
    }
});
<|endoftext|>


<commit_before>'use strict';
angular.module('ngOboe', [])
        .service('Oboe', ['OboeStream', function (OboeStream) {
                // the passed parameters object need to have a Url and a pattern.
                // all parameters consumed by the oboe module can be passed
                // the url needs to return a json stream. see the oboe documentation
                // the pattern contains a path which selects json objects from the stream
                return function (params) {
                    return OboeStream.get(params);
                };
            }])
        .factory('OboeStream', ['$q', function ($q) {
                return {
                    // the get function calls the oboe module to get the JSON data in a stream
                    get: function (params) {
                        var defer = $q.defer();
                        var stream = oboe(params)
                                // once the stream starts we can callback the start function if passed.
                                .start(function (status, headers) {
                                    if (typeof params.start === 'function' && status === 200) {
                                        params.start(stream);
                                    }
                                })
                                .fail(function (error) {
                                    defer.reject(error);
                                })
                                // for every node containing the specified pattern or if not specified any node
                                .node(params.pattern || '.', function (node) {
                                    defer.notify(node);
                                    return oboe.drop;
                                })
                                .done(function () {
                                    if (typeof params.done === 'function') {
                                        params.done();
                                    }
                                    // resolve the promise
                                    defer.resolve();
                                    // make sure oboe cleans up memory
                                    return oboe.drop;
                                });
                        return defer.promise;
                    }
                };
            }]);<commit_msg>Now ParsedJSON returned by doen function<commit_after>'use strict';
angular.module('ngOboe', [])
        .service('Oboe', ['OboeStream', function (OboeStream) {
                // the passed parameters object need to have a Url and a pattern.
                // all parameters consumed by the oboe module can be passed
                // the url needs to return a json stream. see the oboe documentation
                // the pattern contains a path which selects json objects from the stream
                return function (params) {
                    return OboeStream.get(params);
                };
            }])
        .factory('OboeStream', ['$q', function ($q) {
                return {
                    // the get function calls the oboe module to get the JSON data in a stream
                    get: function (params) {
                        var defer = $q.defer();
                        var stream = oboe(params)
                                // once the stream starts we can callback the start function if passed.
                                .start(function (status, headers) {
                                    if (typeof params.start === 'function' && status === 200) {
                                        params.start(stream);
                                    }
                                })
                                .fail(function (error) {
                                    defer.reject(error);
                                })
                                // for every node containing the specified pattern or if not specified any node
                                .node(params.pattern || '.', function (node) {
                                    defer.notify(node);
                                    return oboe.drop;
                                })
                                .done(function (parsedJSON) {
                                    if (typeof params.done === 'function') {
                                        params.done(parsedJSON);
                                    }
                                    // resolve the promise
                                    defer.resolve();
                                    // make sure oboe cleans up memory
                                    return oboe.drop;
                                });
                        return defer.promise;
                    }
                };
            }]);
<|endoftext|>


<commit_before>var solc = require('solc/wrapper');

var webworkify = require('webworkify');
var utils = require('./utils');

var Base64 = require('js-base64').Base64;

var EventManager = require('../lib/eventManager');

/*
  trigger compilationFinished, compilerLoaded, compilationStarted
*/
function Compiler (editor, handleGithubCall) {
  var self = this;
  this.event = new EventManager();

  var compileJSON;
  var compilerAcceptsMultipleFiles;

  var cachedRemoteFiles = {};
  var worker = null;

  var optimize = false;

  this.setOptimize = function (_optimize) {
    optimize = _optimize;
  };

  var compile = function (missingInputs) {
    editor.clearAnnotations();
    self.event.trigger('compilationStarted', []);
    var input = editor.getValue();
    editor.setCacheFileContent(input);

    var files = {};
    files[utils.fileNameFromKey(editor.getCacheFile())] = input;
    gatherImports(files, missingInputs, function (input, error) {
      if (input === null) {
        self.lastCompilationResult = null;
        self.event.trigger('compilationFinished', [false, { 'error': error }, files]);
      } else {
        compileJSON(input, optimize ? 1 : 0);
      }
    });
  };
  this.compile = compile;

  function setCompileJSON (_compileJSON) {
    compileJSON = _compileJSON;
  }
  this.setCompileJSON = setCompileJSON; // this is exposed for testing

  function onCompilerLoaded (version) {
    self.event.trigger('compilerLoaded', [version]);
  }

  function onInternalCompilerLoaded () {
    if (worker === null) {
      var compiler = solc(window.Module);

      compilerAcceptsMultipleFiles = compiler.supportsMulti;

      compileJSON = function (source, optimize, cb) {
        var missingInputs = [];
        var missingInputsCallback = function (path) {
          missingInputs.push(path);
          return { error: 'Deferred import' };
        };

        var result;
        try {
          result = compiler.compile(source, optimize, missingInputsCallback);
        } catch (exception) {
          result = { error: 'Uncaught JavaScript exception:\n' + exception };
        }

        compilationFinished(result, missingInputs, source);
      };

      onCompilerLoaded(compiler.version());
    }
  }

  this.lastCompilationResult = {
    data: null,
    source: null
  };
  function compilationFinished (data, missingInputs, source) {
    var noFatalErrors = true; // ie warnings are ok

    function isValidError (error) {
      // The deferred import is not a real error
      // FIXME: maybe have a better check?
      if (/Deferred import/.exec(error)) {
        return false;
      }

      return utils.errortype(error) !== 'warning';
    }

    if (data['error'] !== undefined) {
      // Ignore warnings (and the 'Deferred import' error as those are generated by us as a workaround
      if (isValidError(data['error'])) {
        noFatalErrors = false;
      }
    }
    if (data['errors'] !== undefined) {
      data['errors'].forEach(function (err) {
        // Ignore warnings and the 'Deferred import' error as those are generated by us as a workaround
        if (isValidError(err)) {
          noFatalErrors = false;
        }
      });
    }

    if (!noFatalErrors) {
      // There are fatal errors - abort here
      self.lastCompilationResult = null;
      self.event.trigger('compilationFinished', [false, data, source]);
    } else if (missingInputs !== undefined && missingInputs.length > 0) {
      compile(missingInputs);
    } else {
      self.lastCompilationResult = {
        data: data,
        source: source
      };
      self.event.trigger('compilationFinished', [true, data, source]);
    }
  }

  this.loadVersion = function (usingWorker, url) {
    console.log('Loading ' + url + ' ' + (usingWorker ? 'with worker' : 'without worker'));
    self.event.trigger('loadingCompiler', [url, usingWorker]);

    if (usingWorker) {
      loadWorker(url);
    } else {
      loadInternal(url);
    }
  };

  function loadInternal (url) {
    delete window.Module;
    // NOTE: workaround some browsers?
    window.Module = undefined;

    // Set a safe fallback until the new one is loaded
    setCompileJSON(function (source, optimize) {
      compilationFinished({error: 'Compiler not yet loaded.'});
    });

    var newScript = document.createElement('script');
    newScript.type = 'text/javascript';
    newScript.src = url;
    document.getElementsByTagName('head')[0].appendChild(newScript);
    var check = window.setInterval(function () {
      if (!window.Module) {
        return;
      }
      window.clearInterval(check);
      onInternalCompilerLoaded();
    }, 200);
  }

  function loadWorker (url) {
    if (worker !== null) {
      worker.terminate();
    }
    worker = webworkify(require('./compiler-worker.js'));
    var jobs = [];
    worker.addEventListener('message', function (msg) {
      var data = msg.data;
      switch (data.cmd) {
        case 'versionLoaded':
          compilerAcceptsMultipleFiles = !!data.acceptsMultipleFiles;
          onCompilerLoaded(data.data);
          break;
        case 'compiled':
          var result;
          try {
            result = JSON.parse(data.data);
          } catch (exception) {
            result = { 'error': 'Invalid JSON output from the compiler: ' + exception };
          }
          var sources = {};
          if (data.job in jobs !== undefined) {
            sources = jobs[data.job].sources;
            delete jobs[data.job];
          }
          compilationFinished(result, data.missingInputs, sources);
          break;
      }
    });
    worker.onerror = function (msg) {
      compilationFinished({ error: 'Worker error: ' + msg.data });
    };
    worker.addEventListener('error', function (msg) {
      compilationFinished({ error: 'Worker error: ' + msg.data });
    });
    compileJSON = function (source, optimize) {
      jobs.push({sources: source});
      worker.postMessage({cmd: 'compile', job: jobs.length - 1, source: JSON.stringify(source), optimize: optimize});
    };
    worker.postMessage({cmd: 'loadVersion', data: url});
  }

  function gatherImports (files, importHints, cb) {
    importHints = importHints || [];
    if (!compilerAcceptsMultipleFiles) {
      cb(files[editor.getCacheFile()]);
      return;
    }
    var importRegex = /^\s*import\s*[\'\"]([^\'\"]+)[\'\"];/g;
    var reloop = false;
    var githubMatch;
    do {
      reloop = false;
      for (var fileName in files) {
        var match;
        while ((match = importRegex.exec(files[fileName]))) {
          var importFilePath = match[1];
          if (importFilePath.startsWith('./')) {
            importFilePath = importFilePath.slice(2);
          }
          importHints.push(importFilePath);
        }
      }
      while (importHints.length > 0) {
        var m = importHints.pop();
        if (m in files) {
          continue;
        }
        if (editor.hasFile(m)) {
          files[m] = editor.getFile(m);
          reloop = true;
        } else if (m in cachedRemoteFiles) {
          files[m] = cachedRemoteFiles[m];
          reloop = true;
        } else if ((githubMatch = /^(https?:\/\/)?(www.)?github.com\/([^\/]*\/[^\/]*)\/(.*)/.exec(m))) {
          handleGithubCall(githubMatch[3], githubMatch[4], function (result) {
            if ('content' in result) {
              var content = Base64.decode(result.content);
              cachedRemoteFiles[m] = content;
              files[m] = content;
              gatherImports(files, importHints, cb);
            } else {
              cb(null, 'Unable to import "' + m + '"');
            }
          }).fail(function () {
            cb(null, 'Unable to import "' + m + '"');
          });
          return;
        } else if (/^[^:]*:\/\//.exec(m)) {
          cb(null, 'Unable to import "' + m + '": Unsupported URL');
          return;
        } else {
          cb(null, 'Unable to import "' + m + '"');
          return;
        }
      }
    } while (reloop);
    cb({ 'sources': files });
  }
}

module.exports = Compiler;
<commit_msg>List reason why import failed (file not found)<commit_after>var solc = require('solc/wrapper');

var webworkify = require('webworkify');
var utils = require('./utils');

var Base64 = require('js-base64').Base64;

var EventManager = require('../lib/eventManager');

/*
  trigger compilationFinished, compilerLoaded, compilationStarted
*/
function Compiler (editor, handleGithubCall) {
  var self = this;
  this.event = new EventManager();

  var compileJSON;
  var compilerAcceptsMultipleFiles;

  var cachedRemoteFiles = {};
  var worker = null;

  var optimize = false;

  this.setOptimize = function (_optimize) {
    optimize = _optimize;
  };

  var compile = function (missingInputs) {
    editor.clearAnnotations();
    self.event.trigger('compilationStarted', []);
    var input = editor.getValue();
    editor.setCacheFileContent(input);

    var files = {};
    files[utils.fileNameFromKey(editor.getCacheFile())] = input;
    gatherImports(files, missingInputs, function (input, error) {
      if (input === null) {
        self.lastCompilationResult = null;
        self.event.trigger('compilationFinished', [false, { 'error': error }, files]);
      } else {
        compileJSON(input, optimize ? 1 : 0);
      }
    });
  };
  this.compile = compile;

  function setCompileJSON (_compileJSON) {
    compileJSON = _compileJSON;
  }
  this.setCompileJSON = setCompileJSON; // this is exposed for testing

  function onCompilerLoaded (version) {
    self.event.trigger('compilerLoaded', [version]);
  }

  function onInternalCompilerLoaded () {
    if (worker === null) {
      var compiler = solc(window.Module);

      compilerAcceptsMultipleFiles = compiler.supportsMulti;

      compileJSON = function (source, optimize, cb) {
        var missingInputs = [];
        var missingInputsCallback = function (path) {
          missingInputs.push(path);
          return { error: 'Deferred import' };
        };

        var result;
        try {
          result = compiler.compile(source, optimize, missingInputsCallback);
        } catch (exception) {
          result = { error: 'Uncaught JavaScript exception:\n' + exception };
        }

        compilationFinished(result, missingInputs, source);
      };

      onCompilerLoaded(compiler.version());
    }
  }

  this.lastCompilationResult = {
    data: null,
    source: null
  };
  function compilationFinished (data, missingInputs, source) {
    var noFatalErrors = true; // ie warnings are ok

    function isValidError (error) {
      // The deferred import is not a real error
      // FIXME: maybe have a better check?
      if (/Deferred import/.exec(error)) {
        return false;
      }

      return utils.errortype(error) !== 'warning';
    }

    if (data['error'] !== undefined) {
      // Ignore warnings (and the 'Deferred import' error as those are generated by us as a workaround
      if (isValidError(data['error'])) {
        noFatalErrors = false;
      }
    }
    if (data['errors'] !== undefined) {
      data['errors'].forEach(function (err) {
        // Ignore warnings and the 'Deferred import' error as those are generated by us as a workaround
        if (isValidError(err)) {
          noFatalErrors = false;
        }
      });
    }

    if (!noFatalErrors) {
      // There are fatal errors - abort here
      self.lastCompilationResult = null;
      self.event.trigger('compilationFinished', [false, data, source]);
    } else if (missingInputs !== undefined && missingInputs.length > 0) {
      compile(missingInputs);
    } else {
      self.lastCompilationResult = {
        data: data,
        source: source
      };
      self.event.trigger('compilationFinished', [true, data, source]);
    }
  }

  this.loadVersion = function (usingWorker, url) {
    console.log('Loading ' + url + ' ' + (usingWorker ? 'with worker' : 'without worker'));
    self.event.trigger('loadingCompiler', [url, usingWorker]);

    if (usingWorker) {
      loadWorker(url);
    } else {
      loadInternal(url);
    }
  };

  function loadInternal (url) {
    delete window.Module;
    // NOTE: workaround some browsers?
    window.Module = undefined;

    // Set a safe fallback until the new one is loaded
    setCompileJSON(function (source, optimize) {
      compilationFinished({error: 'Compiler not yet loaded.'});
    });

    var newScript = document.createElement('script');
    newScript.type = 'text/javascript';
    newScript.src = url;
    document.getElementsByTagName('head')[0].appendChild(newScript);
    var check = window.setInterval(function () {
      if (!window.Module) {
        return;
      }
      window.clearInterval(check);
      onInternalCompilerLoaded();
    }, 200);
  }

  function loadWorker (url) {
    if (worker !== null) {
      worker.terminate();
    }
    worker = webworkify(require('./compiler-worker.js'));
    var jobs = [];
    worker.addEventListener('message', function (msg) {
      var data = msg.data;
      switch (data.cmd) {
        case 'versionLoaded':
          compilerAcceptsMultipleFiles = !!data.acceptsMultipleFiles;
          onCompilerLoaded(data.data);
          break;
        case 'compiled':
          var result;
          try {
            result = JSON.parse(data.data);
          } catch (exception) {
            result = { 'error': 'Invalid JSON output from the compiler: ' + exception };
          }
          var sources = {};
          if (data.job in jobs !== undefined) {
            sources = jobs[data.job].sources;
            delete jobs[data.job];
          }
          compilationFinished(result, data.missingInputs, sources);
          break;
      }
    });
    worker.onerror = function (msg) {
      compilationFinished({ error: 'Worker error: ' + msg.data });
    };
    worker.addEventListener('error', function (msg) {
      compilationFinished({ error: 'Worker error: ' + msg.data });
    });
    compileJSON = function (source, optimize) {
      jobs.push({sources: source});
      worker.postMessage({cmd: 'compile', job: jobs.length - 1, source: JSON.stringify(source), optimize: optimize});
    };
    worker.postMessage({cmd: 'loadVersion', data: url});
  }

  function gatherImports (files, importHints, cb) {
    importHints = importHints || [];
    if (!compilerAcceptsMultipleFiles) {
      cb(files[editor.getCacheFile()]);
      return;
    }
    var importRegex = /^\s*import\s*[\'\"]([^\'\"]+)[\'\"];/g;
    var reloop = false;
    var githubMatch;
    do {
      reloop = false;
      for (var fileName in files) {
        var match;
        while ((match = importRegex.exec(files[fileName]))) {
          var importFilePath = match[1];
          if (importFilePath.startsWith('./')) {
            importFilePath = importFilePath.slice(2);
          }
          importHints.push(importFilePath);
        }
      }
      while (importHints.length > 0) {
        var m = importHints.pop();
        if (m in files) {
          continue;
        }
        if (editor.hasFile(m)) {
          files[m] = editor.getFile(m);
          reloop = true;
        } else if (m in cachedRemoteFiles) {
          files[m] = cachedRemoteFiles[m];
          reloop = true;
        } else if ((githubMatch = /^(https?:\/\/)?(www.)?github.com\/([^\/]*\/[^\/]*)\/(.*)/.exec(m))) {
          handleGithubCall(githubMatch[3], githubMatch[4], function (result) {
            if ('content' in result) {
              var content = Base64.decode(result.content);
              cachedRemoteFiles[m] = content;
              files[m] = content;
              gatherImports(files, importHints, cb);
            } else {
              cb(null, 'Unable to import "' + m + '"');
            }
          }).fail(function () {
            cb(null, 'Unable to import "' + m + '"');
          });
          return;
        } else if (/^[^:]*:\/\//.exec(m)) {
          cb(null, 'Unable to import "' + m + '": Unsupported URL');
          return;
        } else {
          cb(null, 'Unable to import "' + m + '": File not found');
          return;
        }
      }
    } while (reloop);
    cb({ 'sources': files });
  }
}

module.exports = Compiler;
<|endoftext|>


<commit_before>import Ember from 'ember';
import layout from '../../templates/components/power-select-typeahead/trigger';

const { get } = Ember;

export default Ember.Component.extend({
  layout: layout,
  tagName: '',

  // Observers
  optionsObserver: Ember.observer('options.length', 'searchText.length', function() {
    let select = this.get('select');
    if (!this.get('searchText.length')) {
      if (select.isOpen) { select.actions.close(); }
      return;
    }
    let options = this.get('options');
    if (get(options, 'isPending')) {
      if (get(options, 'length') === 0) { select.actions.close(); }
      this._lastSearch = options;
      options.then((results) => {
        if (this._lastSearch === options && !this.get('select.isOpen')) {
          select.actions.open();
        }
      });
      return;
    }

    if (select.isOpen === false) {
      return select.actions.open();
    }
  }),

  // Actions
  actions: {
    captureMouseDown(e) {
      e.stopPropagation();
    },

    search(term, e) {
      this.get('select.actions.search')(term, e);
    },

    handleKeydown(e) {
      let select = this.get('select');
      if (!select.isOpen) {
        e.stopPropagation();
        return;
      }
      let term = e.target.value;
      if (e.keyCode === 9 || e.keyCode === 13) {
        select.actions.choose(this.get('highlighted'), e);
      }
      if (term.length === 0) {
        e.stopPropagation();
      }
    }
  }
});
<commit_msg>Fix jshint error<commit_after>import Ember from 'ember';
import layout from '../../templates/components/power-select-typeahead/trigger';

const { get } = Ember;

export default Ember.Component.extend({
  layout: layout,
  tagName: '',

  // Observers
  optionsObserver: Ember.observer('options.length', 'searchText.length', function() {
    let select = this.get('select');
    if (!this.get('searchText.length')) {
      if (select.isOpen) { select.actions.close(); }
      return;
    }
    let options = this.get('options');
    if (get(options, 'isPending')) {
      if (get(options, 'length') === 0) { select.actions.close(); }
      this._lastSearch = options;
      options.then(() => {
        if (this._lastSearch === options && !this.get('select.isOpen')) {
          select.actions.open();
        }
      });
      return;
    }

    if (select.isOpen === false) {
      return select.actions.open();
    }
  }),

  // Actions
  actions: {
    captureMouseDown(e) {
      e.stopPropagation();
    },

    search(term, e) {
      this.get('select.actions.search')(term, e);
    },

    handleKeydown(e) {
      let select = this.get('select');
      if (!select.isOpen) {
        e.stopPropagation();
        return;
      }
      let term = e.target.value;
      if (e.keyCode === 9 || e.keyCode === 13) {
        select.actions.choose(this.get('highlighted'), e);
      }
      if (term.length === 0) {
        e.stopPropagation();
      }
    }
  }
});
<|endoftext|>


<commit_before>odoo.define('web.AbstractAction', function (require) {
"use strict";

/**
 * We define here the AbstractAction widget, which implements the ActionMixin.
 * All client actions must extend this widget.
 *
 * @module web.AbstractAction
 */

var ActionMixin = require('web.ActionMixin');
var ControlPanelView = require('web.ControlPanelView');
var Widget = require('web.Widget');

var AbstractAction = Widget.extend(ActionMixin, {
    config: {
        ControlPanelView: ControlPanelView,
    },

    /**
     * If this flag is set to true, the client action will create a control
     * panel whenever it is created.
     *
     * @type boolean
     */
    hasControlPanel: false,

    /**
     * If true, this flag indicates that the client action should automatically
     * fetch the <arch> of a search view (or control panel view).  Note that
     * to do that, it also needs a specific modelName.
     *
     * For example, the Discuss application adds the following line in its
     * constructor::
     *
     *      this.controlPanelParams.modelName = 'mail.message';
     *
     * @type boolean
     */
    loadControlPanel: false,

    /**
     * A client action might want to use a search bar in its control panel, or
     * it could choose not to use it.
     *
     * Note that it only makes sense if hasControlPanel is set to true.
     *
     * @type boolean
     */
    withSearchBar: false,

    /**
     * This parameter can be set to customize the available sub menus in the
     * controlpanel (Filters/Group By/Favorites).  This is basically a list of
     * the sub menus that we want to use.
     *
     * Note that it only makes sense if hasControlPanel is set to true.
     *
     * For example, set ['filter', 'favorite'] to enable the Filters and
     * Favorites menus.
     *
     * @type string[]
     */
    searchMenuTypes: [],

    /**
     * @override
     *
     * @param {Widget} parent
     * @param {Object} action
     * @param {Object} [options]
     */
    init: function (parent, action, options) {
        this._super(parent);
        this._title = action.display_name || action.name;
        this.controlPanelParams = {
            actionId: action.id,
            context: action.context,
            breadcrumbs: options && options.breadcrumbs || [],
            title: this.getTitle(),
            viewId: action.search_view_id && action.search_view_id[0],
            withSearchBar: this.withSearchBar,
            searchMenuTypes: this.searchMenuTypes,
        };
    },
    /**
     * The willStart method is actually quite complicated if the client action
     * has a controlPanel, because it needs to prepare it.
     *
     * @override
     */
    willStart: function () {
        var self = this;
        var defs = [this._super.apply(this, arguments)];
        if (this.hasControlPanel) {
            var params = this.controlPanelParams;
            if (this.loadControlPanel) {
                defs.push(this
                    .loadFieldView(params.modelName, params.context || {}, params.viewId, 'search')
                    .then(function (fieldsView) {
                        params.viewInfo = {
                            arch: fieldsView.arch,
                            fields: fieldsView.fields,
                        };
                    }));
            }
            return Promise.all(defs).then(function () {
                var controlPanelView = new self.config.ControlPanelView(params);
                return controlPanelView.getController(self).then(function (controlPanel) {
                    self._controlPanel = controlPanel;
                    return self._controlPanel.appendTo(document.createDocumentFragment());
                });
            });
        }
        return Promise.all(defs);
    },
    /**
     * @override
     */
    start: function () {
        if (this._controlPanel) {
            this._controlPanel.$el.prependTo(this.$el);
        }
        return this._super.apply(this, arguments);
    },
});

return AbstractAction;

});
<commit_msg>[FIX] web: call super in AbstractAction willStart<commit_after>odoo.define('web.AbstractAction', function (require) {
"use strict";

/**
 * We define here the AbstractAction widget, which implements the ActionMixin.
 * All client actions must extend this widget.
 *
 * @module web.AbstractAction
 */

var ActionMixin = require('web.ActionMixin');
var ControlPanelView = require('web.ControlPanelView');
var Widget = require('web.Widget');

var AbstractAction = Widget.extend(ActionMixin, {
    config: {
        ControlPanelView: ControlPanelView,
    },

    /**
     * If this flag is set to true, the client action will create a control
     * panel whenever it is created.
     *
     * @type boolean
     */
    hasControlPanel: false,

    /**
     * If true, this flag indicates that the client action should automatically
     * fetch the <arch> of a search view (or control panel view).  Note that
     * to do that, it also needs a specific modelName.
     *
     * For example, the Discuss application adds the following line in its
     * constructor::
     *
     *      this.controlPanelParams.modelName = 'mail.message';
     *
     * @type boolean
     */
    loadControlPanel: false,

    /**
     * A client action might want to use a search bar in its control panel, or
     * it could choose not to use it.
     *
     * Note that it only makes sense if hasControlPanel is set to true.
     *
     * @type boolean
     */
    withSearchBar: false,

    /**
     * This parameter can be set to customize the available sub menus in the
     * controlpanel (Filters/Group By/Favorites).  This is basically a list of
     * the sub menus that we want to use.
     *
     * Note that it only makes sense if hasControlPanel is set to true.
     *
     * For example, set ['filter', 'favorite'] to enable the Filters and
     * Favorites menus.
     *
     * @type string[]
     */
    searchMenuTypes: [],

    /**
     * @override
     *
     * @param {Widget} parent
     * @param {Object} action
     * @param {Object} [options]
     */
    init: function (parent, action, options) {
        this._super(parent);
        this._title = action.display_name || action.name;
        this.controlPanelParams = {
            actionId: action.id,
            context: action.context,
            breadcrumbs: options && options.breadcrumbs || [],
            title: this.getTitle(),
            viewId: action.search_view_id && action.search_view_id[0],
            withSearchBar: this.withSearchBar,
            searchMenuTypes: this.searchMenuTypes,
        };
    },
    /**
     * The willStart method is actually quite complicated if the client action
     * has a controlPanel, because it needs to prepare it.
     *
     * @override
     */
    willStart: function () {
        var self = this;
        var proms = [this._super.apply(this, arguments)];
        if (this.hasControlPanel) {
            var params = this.controlPanelParams;
            if (this.loadControlPanel) {
                proms.push(this
                    .loadFieldView(params.modelName, params.context || {}, params.viewId, 'search')
                    .then(function (fieldsView) {
                        params.viewInfo = {
                            arch: fieldsView.arch,
                            fields: fieldsView.fields,
                        };
                    }));
            }
            return Promise.all(proms).then(function () {
                var controlPanelView = new self.config.ControlPanelView(params);
                return controlPanelView.getController(self).then(function (controlPanel) {
                    self._controlPanel = controlPanel;
                    return self._controlPanel.appendTo(document.createDocumentFragment());
                });
            });
        }
        return Promise.all(proms);
    },
    /**
     * @override
     */
    start: function () {
        if (this._controlPanel) {
            this._controlPanel.$el.prependTo(this.$el);
        }
        return this._super.apply(this, arguments);
    },
});

return AbstractAction;

});
<|endoftext|>