<commit_before>#! /usr/bin/env node
var fs      = require('fs');
var http    = require('http')
var request = require('request')

var config = JSON.parse(
    fs.readFileSync('config.json')
);

// Ensure all files in object
var mandatory_discourse_props = ["api_key", "api_user", "domain", "topic_id"]
var mandatory_webhook_props = ["secret"]

for (property of mandatory_discourse_props) {
    if (!config.discourse.hasOwnProperty(property)) {
        throw new Error("Required property discourse." +
            property +
            " not found in config.json")
    }
}

for (property of mandatory_webhook_props) {
    if (!config.webhook.hasOwnProperty(property)) {
        throw new Error("Required property webhook." +
            property +
            " not found in config.json")
    }
}

var handler = require('github-webhook-handler')({
    path: "/" + config.webhook.path,
    secret: config.webhook.secret
})

// Start the server with our handler
var port = config.webhook.hasOwnProperty('port') ? config.webhook.port : 8080
http.createServer(function (req, res) {
    handler(req, res, function (err) {
        res.statusCode = 404
        res.end('Not Found')
    })
}).listen(port, function() {
    console.log("Accepting webhooks to /" + config.webhook.path + " on port "
                + port)
})

handler.on('push', function(event) {

    console.log("Received push from " + event.respository.full_name)
    var commits = event.payload.commits

    // Handle multiple commits in one webhook
    for (var commit of commits) {

        // BUILD THE MESSAGE
        // We put together the forum post in Markdown
        // by splitting the commit message and adding
        // quote delimeters (`>`) to the beginning of
        // each. If it's the first line, add a `#` to
        // highlight it as a title. If your forum has
        // oneboxes and you'd rather use them, we can
        // skip this.

        var comment_text = ""
        if (config.hasOwnProperty('onebox_enabled') && config.onebox_enabled) {
            commit = commit.message.split("\n")
            comment_text = "_latest changes on github:_\n\n---\n"

            for (var x = 0; x < commit.length; x++) {
                var line = commit[x]
                comment_text += "> " + (x==0 ? "# " : "") + line + "\n"
            }

            comment_text +=
                "\n\n---\n_[more details at github](" +
                commit.url +
                ") - this is an automated post_"
        } else {
            comment_text = commit.url
        }

        // MAKE THE COMMENT
        // Given the details you added to config.json
        // we make a POST to your thread with details
        // about your commit.

        request({
            url:
                (
                    (
                        config.discourse.hasOwnProperty('https_enabled') &&
                        config.discourse.https_enabled
                    )
                    ? "https://"
                    : "http://"
                ) +
                config.discourse.domain +
                "/posts",
            method: "POST",
            qs: {
                'api_key': config.discourse.api_key,
                'api_username': config.discourse.api_user
            },
            form: {
                topic_id: config.discourse.topic_id,
                raw: comment_text
            }
        }, function(err, res, body) {
            if (err) throw err
            console.log("Success: " + commit.id)
            console.log(res)
        })
    };
})

handler.on('ping', function(event) {
    console.log("Received ping: " + event.payload.zen)
})

handler.on('error', function(event) {
    console.log(event)
})
<commit_msg>Improve success logging<commit_after>#! /usr/bin/env node
var fs      = require('fs');
var http    = require('http')
var request = require('request')

var config = JSON.parse(
    fs.readFileSync('config.json')
);

// Ensure all files in object
var mandatory_discourse_props = ["api_key", "api_user", "domain", "topic_id"]
var mandatory_webhook_props = ["secret"]

for (property of mandatory_discourse_props) {
    if (!config.discourse.hasOwnProperty(property)) {
        throw new Error("Required property discourse." +
            property +
            " not found in config.json")
    }
}

for (property of mandatory_webhook_props) {
    if (!config.webhook.hasOwnProperty(property)) {
        throw new Error("Required property webhook." +
            property +
            " not found in config.json")
    }
}

var handler = require('github-webhook-handler')({
    path: "/" + config.webhook.path,
    secret: config.webhook.secret
})

// Start the server with our handler
var port = config.webhook.hasOwnProperty('port') ? config.webhook.port : 8080
http.createServer(function (req, res) {
    handler(req, res, function (err) {
        res.statusCode = 404
        res.end('Not Found')
    })
}).listen(port, function() {
    console.log("Accepting webhooks to /" + config.webhook.path + " on port "
                + port)
})

handler.on('push', function(event) {

    console.log("Received push from " + event.respository.full_name)
    var commits = event.payload.commits

    // Handle multiple commits in one webhook
    for (var commit of commits) {

        // BUILD THE MESSAGE
        // We put together the forum post in Markdown
        // by splitting the commit message and adding
        // quote delimeters (`>`) to the beginning of
        // each. If it's the first line, add a `#` to
        // highlight it as a title. If your forum has
        // oneboxes and you'd rather use them, we can
        // skip this.

        var comment_text = ""
        if (config.hasOwnProperty('onebox_enabled') && config.onebox_enabled) {
            commit = commit.message.split("\n")
            comment_text = "_latest changes on github:_\n\n---\n"

            for (var x = 0; x < commit.length; x++) {
                var line = commit[x]
                comment_text += "> " + (x==0 ? "# " : "") + line + "\n"
            }

            comment_text +=
                "\n\n---\n_[more details at github](" +
                commit.url +
                ") - this is an automated post_"
        } else {
            comment_text = commit.url
        }

        // MAKE THE COMMENT
        // Given the details you added to config.json
        // we make a POST to your thread with details
        // about your commit.

        var discourse_url = ((
            config.discourse.hasOwnProperty('https_enabled') &&
            config.discourse.https_enabled)
            ? "https://"
            : "http://"
        ) + config.discourse.domain

        request({
            url: discourse_url + "/posts",
            method: "POST",
            qs: {
                'api_key': config.discourse.api_key,
                'api_username': config.discourse.api_user
            },
            form: {
                topic_id: config.discourse.topic_id,
                raw: comment_text
            }
        }, function(err, res, body) {
            if (err) throw err
            var post_url = discourse_url + "/t/" + config.discourse.topic_id +
                "/" + res.body["post_number"]
            console.log("Success: " + commit.id + " / " + post_url)
        })
    };
})

handler.on('ping', function(event) {
    console.log("Received ping: " + event.payload.zen)
})

handler.on('error', function(event) {
    console.log(event)
})
<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';

import { Icon, Button, Menu, Modal } from 'antd';

import FilesystemBrowser from './Filesystem/FilesystemBrowser';
import IDFileModal from './ID/IDFileModal';
import IDMultipleEpisodesModal from './ID/IDMultipleEpisodesModal';
import TrashModal from './Filesystem/TrashModal';
import UntagModal from './ID/UntagModal';

class FileManager extends Component {
    VIDEO_FILE_REGX = /(\.mp4|\.mkv|\.avi)$/;
    constructor(props){
        super(props);

        this.state = {
            currentToplevelDirSetting: {},
            currentToplevelDirectory: "",
            currentPath: "",
            currentPathInfo: {},
            dirList: [],
            idmultipleIsModalVisible: false,
            idmultipleEpisodes: [],
            idsingleFilename: "",
            idsingleIsModalVisible: false,
            isReloading: false,
            isTrashVisible: false,
            itemsToTrash: [],
            selectedRows: [],
            untagIsModalVisible: false,
            untagIDinfo: []
        };
    }

    _reloadDirList(){
        this.setState({
            isReloading: true
        });
    }

    _handleChangeDirectory(newDir, dirList){
        const { currentToplevelDirectory, currentPathInfo } = this.state;

        const subpath = newDir.slice(currentToplevelDirectory.length + 1);
        currentPathInfo.subpath = subpath;
        this.setState({
            currentPathInfo,
            currentPath: newDir,
            dirList,
            selectedRows: [],
            isReloading: false
        })
    }

    _handleSelectTopLevelDir(dir) {
        const pathInfo = {
            setting_id: dir.id,
            subpath: ""
        };
        this.setState({
            currentPathInfo: pathInfo,
            currentToplevelDirectory: dir.value,
            currentPath: dir.value
        });
    }

    _handleSelectionChange(selectedRows){
        this.setState({
            selectedRows
        });
    }

    _handleClickTrash(evt){
        let itemsToTrash = [];
        if(evt.currentTarget.tagName === "BUTTON"){
            itemsToTrash = [...this.state.selectedRows];
        } else {
            const item = evt.currentTarget.getAttribute('data-item-name');
            itemsToTrash = [item];
        }

        this.setState({
            isTrashVisible: true,
            itemsToTrash
        });
    }

    _handleTrashComplete(){
        this.setState({
            isReloading: true,
            isTrashVisible: false,
            itemsToTrash: []
        });
    }

    _handleCancelTrash(){
        this.setState({
            isTrashVisible: false,
            itemsToTrash: []
        });
    }

    _handleClickIDFile(filename){
        this.setState({
            idsingleFilename: filename,
            idsingleIsModalVisible: true
        });
    }

    _handleIDModalCancel(){
        this.setState({
            idsingleIsModalVisible: false,
            idsingleFilename: ""
        });
    }

    _handleIDModalComplete(){
        this.setState({
            isReloading: true,
            idsingleIsModalVisible: false,
            idsingleFilename: ""
        });
    }

    _handleClickIDMultipleEpisodes(){
        const { dirList } = this.state;

        const filenamesToID = [...this.state.selectedRows];

        const idItems = [];
        filenamesToID.forEach((filename)=>{
            dirList.forEach((item)=>{
                if(item.name === filename &&
                    item.name.search(this.VIDEO_FILE_REGX) > -1){
                    idItems.push(item);
                }
            })
        });

        if(idItems.length > 0){
            this.setState({
                idmultipleIsModalVisible: true,
                idmultipleEpisodes: idItems
            });
        }
    }

    _handleIDMultipleCancel(){
        this.setState({
            idmultipleIsModalVisible: false,
            idmultipleEpisodes: []
        });
    }

    _handleIDMultipleComplete(){
        this.setState({
            isReloading: true,
            idmultipleIsModalVisible: false,
            idmultipleEpisodes: []
        });
    }

    _handleSelectVideos(){
        const { dirList } = this.state;

        let selected = [];
        dirList.forEach((item)=>{
            if(item.name.search(this.VIDEO_FILE_REGX) > -1){
                selected.push(item.name);
            }
        });

        this.setState({
            selectedRows: selected
        });
    }

    _handleClickUntag(evt){
        const { dirList } = this.state;

        let filenamesToUntag = [];
        if(evt.currentTarget.tagName === "BUTTON"){
            filenamesToUntag = [...this.state.selectedRows];
        } else {
            const item = evt.currentTarget.getAttribute('data-item-name');
            filenamesToUntag = [item];
        }

        const untagItems = [];
        filenamesToUntag.forEach((filename)=>{
            dirList.forEach((item)=>{
                if(item.name === filename && item.assocData.hasOwnProperty('type')){
                    untagItems.push(item);
                }
            })
        });

        if(untagItems.length > 0){
            this.setState({
                untagIsModalVisible: true,
                untagIDinfo: untagItems
            });
        }
    }

    _handleUntagModalComplete(){
        this.setState({
            isReloading: true,
            untagIsModalVisible: false,
            untagIDinfo: []
        });
    }

    _handleUntagCancel(){
        this.setState({
            untagIsModalVisible: false,
            untagIDinfo: []
        });
    }

    _buildActionColumns(){

        return [
            {
                title: "",
                dataIndex: "",
                render: (text,record)=>{
                    const { assocData } = record;

                    let tag = "";
                    if(record.name.search(this.VIDEO_FILE_REGX) > -1){
                        if(!('type' in assocData)){
                            tag =
                                        <Icon type="tag"/>
                                    ;
                        }
                    }

                    let untag = "";
                    if('type' in assocData){
                        untag =
                                    <Icon type="disconnect" className="ib-filebrowser-media-play"/>
                                ;
                    }
                    return (

                                <Icon type="delete"/>
                             {tag}{untag}

                    );
                }
            }
        ];
    }

    _buildFileManager(){
        const {
            currentPath,
            currentPathInfo,
            currentToplevelDirectory,
            idmultipleIsModalVisible,
            idmultipleEpisodes,
            idsingleFilename,
            idsingleIsModalVisible,
            isReloading,
            isTrashVisible,
            itemsToTrash,
            selectedRows,
            untagIDinfo,
            untagIsModalVisible
        } = this.state;

        const hasSelected = (selectedRows.length > 0) ? true : false;
        const buttonDisabled = !hasSelected;

        return (

                    <Button
                        type="primary"
                        icon="video-camera"
                        onClick={this._handleSelectVideos.bind(this)}
                    >Select Videos</Button>
                    <Button.Group>
                        <Button
                            icon="tag"
                            disabled={buttonDisabled}
                            onClick={this._handleClickIDMultipleEpisodes.bind(this)}>ID Multiple</Button>
                        <Button
                            type="danger"
                            icon="delete"
                            disabled={buttonDisabled}
                            onClick={this._handleClickTrash.bind(this)}
                        >Trash</Button>
                        <Button
                            type="danger"
                            icon="disconnect"
                            disabled={buttonDisabled}
                            onClick={this._handleClickUntag.bind(this)}
                        >Remove ID</Button>
                    </Button.Group>

                <FilesystemBrowser
                    actionColumns={this._buildActionColumns()}
                    forceReload={isReloading}
                    hasCheckboxes={true}
                    initialPath={currentToplevelDirectory}
                    onChangeDirectory={this._handleChangeDirectory.bind(this)}
                    parentHandleSelectChange={this._handleSelectionChange.bind(this)}
                    selectedRowKeys={selectedRows}
                    showDirectories={true}
                    showFiles={true}
                />
                <TrashModal
                    currentPath={currentPath}
                    isVisible={isTrashVisible}
                    itemsToTrash={itemsToTrash}
                    onTrashComplete={this._handleTrashComplete.bind(this)}
                    onCancel={this._handleCancelTrash.bind(this)}
                />
                <IDFileModal
                    key={idsingleFilename}
                    isVisible={idsingleIsModalVisible}
                    onIDComplete={this._handleIDModalComplete.bind(this)}
                    onCancel={this._handleIDModalCancel.bind(this)}
                    currentFilename={idsingleFilename}
                    currentPathInfo={currentPathInfo}
                    currentToplevelDirectory={currentToplevelDirectory}
                />
                <IDMultipleEpisodesModal
                    currentPathInfo={currentPathInfo}
                    episodesToID={idmultipleEpisodes}
                    isVisible={idmultipleIsModalVisible}
                    onCancel={this._handleIDMultipleCancel.bind(this)}
                    onIDComplete={this._handleIDMultipleComplete.bind(this)}
                />
                <UntagModal
                    isVisible={untagIsModalVisible}
                    onUntagComplete={this._handleUntagModalComplete.bind(this)}
                    onCancel={this._handleUntagCancel.bind(this)}
                    itemsToUntag={untagIDinfo}
                />

        );
    }

    _buildDirectoryMenu(){
        const { toplevelDirectories } = this.props;
        const { currentToplevelDirectory } = this.state;

        const menuList = [];
        toplevelDirectories.forEach((dir)=>{
            const activeClass = (dir.value === currentToplevelDirectory) ? "ib-filemanager-button ib-filemanager-button-active" : "ib-filemanager-button";
            menuList.push(
                <Menu.Item
                    key={dir.value}>

                        {dir.key}

                </Menu.Item>
            );
        });

        return (<Menu mode="horizontal" selectedKeys={[currentToplevelDirectory]}>{menuList}</Menu>);
    }

    render() {
        const { currentToplevelDirectory } = this.state;

        let directoryMenu = this._buildDirectoryMenu();
        let output = "";
        if(currentToplevelDirectory){
            output = this._buildFileManager();
        }
        return (

                    {directoryMenu}

                {output}

        );
    }
}

const mapStateToProps = (state)=>{
    const { settings } = state;

    return {
        toplevelDirectories: settings.settings.directories
    };
}

export default connect(mapStateToProps)(FileManager);<commit_msg>Modified to handle the URL as the manager of the directory.<commit_after>import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { Icon, Button, Menu, Modal } from 'antd';

import FilesystemBrowser from './Filesystem/FilesystemBrowser';
import IDFileModal from './ID/IDFileModal';
import IDMultipleEpisodesModal from './ID/IDMultipleEpisodesModal';
import TrashModal from './Filesystem/TrashModal';
import UntagModal from './ID/UntagModal';

class FileManager extends Component {
    VIDEO_FILE_REGX = /(\.mp4|\.mkv|\.avi)$/;
    constructor(props){
        super(props);

        this.state = {
            currentToplevelDirectory: "",
            currentPath: "",
            currentPathInfo: {},
            dirList: [],
            idmultipleIsModalVisible: false,
            idmultipleEpisodes: [],
            idsingleFilename: "",
            idsingleIsModalVisible: false,
            isReloading: false,
            trashIsModalVisible: false,
            trashSelectedItems: [],
            selectedRows: [],
            untagIsModalVisible: false,
            untagIDinfo: []
        };
    }

    componentWillMount(){
        this._parseURL(this.props);
    }

    componentWillReceiveProps(nextProps){
        this._parseURL(nextProps);
    }

    _parseURL(props) {
        const { toplevelDirectories } = this.props;

        const settingKey = props.match.params.setting_key;

        if(settingKey === undefined){
            this.setState({
                currentPath: "",
                currentPathInfo: {},
                currentToplevelDirecory: "",
                selectedRows: [],
                isReloading: false
            });
            return;
        }

        const newSubpath = props.match.params.subpath;

        let subpath = "";
        if(newSubpath !== undefined){
            subpath = decodeURIComponent(newSubpath);
        }

        const dir = toplevelDirectories.find((dir)=> dir.key === settingKey);

        const pathInfo = {
            setting_id: dir.id,
            setting_key: settingKey,
            subpath
        };
        this.setState({
            currentPath: dir.value + "/" + subpath,
            currentPathInfo: pathInfo,
            currentToplevelDirectory: dir.value,
            selectedRows: [],
            isReloading: false
        });
    }

    _handleChangeDirectory(newDir, dirList){
        const { currentPathInfo, currentToplevelDirectory } = this.state;
        const subpath = newDir.slice(currentToplevelDirectory.length + 1);

        this.setState({
            dirList,
            isReloading: false
        });

        if(currentPathInfo.subpath !== subpath){
            // The subpath has changed so go there
            const location = {
                pathname: "/filemanager/" + currentPathInfo.setting_key + "/" + encodeURIComponent(subpath)
            };
            this.props.history.push(location);
        }
    }

    _reloadDirList(){
        this.setState({
            isReloading: true
        });
    }

    _handleSelectionChange(selectedRows){
        this.setState({
            selectedRows
        });
    }

    _handleClickTrash(evt){
        let trashSelectedItems = [];
        if(evt.currentTarget.tagName === "BUTTON"){
            trashSelectedItems = [...this.state.selectedRows];
        } else {
            const item = evt.currentTarget.getAttribute('data-item-name');
            trashSelectedItems = [item];
        }

        this.setState({
            trashIsModalVisible: true,
            trashSelectedItems
        });
    }

    _handleTrashComplete(){
        this.setState({
            isReloading: true,
            trashIsModalVisible: false,
            trashSelectedItems: []
        });
    }

    _handleCancelTrash(){
        this.setState({
            trashIsModalVisible: false,
            trashSelectedItems: []
        });
    }

    _handleClickIDFile(filename){
        this.setState({
            idsingleFilename: filename,
            idsingleIsModalVisible: true
        });
    }

    _handleIDModalCancel(){
        this.setState({
            idsingleIsModalVisible: false,
            idsingleFilename: ""
        });
    }

    _handleIDModalComplete(){
        this.setState({
            isReloading: true,
            idsingleIsModalVisible: false,
            idsingleFilename: ""
        });
    }

    _handleClickIDMultipleEpisodes(){
        const { dirList } = this.state;

        const filenamesToID = [...this.state.selectedRows];

        const idItems = [];
        filenamesToID.forEach((filename)=>{
            dirList.forEach((item)=>{
                if(item.name === filename &&
                    item.name.search(this.VIDEO_FILE_REGX) > -1){
                    idItems.push(item);
                }
            })
        });

        if(idItems.length > 0){
            this.setState({
                idmultipleIsModalVisible: true,
                idmultipleEpisodes: idItems
            });
        }
    }

    _handleIDMultipleCancel(){
        this.setState({
            idmultipleIsModalVisible: false,
            idmultipleEpisodes: []
        });
    }

    _handleIDMultipleComplete(){
        this.setState({
            isReloading: true,
            idmultipleIsModalVisible: false,
            idmultipleEpisodes: []
        });
    }

    _handleSelectVideos(){
        const { dirList } = this.state;

        let selected = [];
        dirList.forEach((item)=>{
            if(item.name.search(this.VIDEO_FILE_REGX) > -1){
                selected.push(item.name);
            }
        });

        this.setState({
            selectedRows: selected
        });
    }

    _handleClickUntag(evt){
        const { dirList } = this.state;

        let filenamesToUntag = [];
        if(evt.currentTarget.tagName === "BUTTON"){
            filenamesToUntag = [...this.state.selectedRows];
        } else {
            const item = evt.currentTarget.getAttribute('data-item-name');
            filenamesToUntag = [item];
        }

        const untagItems = [];
        filenamesToUntag.forEach((filename)=>{
            dirList.forEach((item)=>{
                if(item.name === filename && item.assocData.hasOwnProperty('type')){
                    untagItems.push(item);
                }
            })
        });

        if(untagItems.length > 0){
            this.setState({
                untagIsModalVisible: true,
                untagIDinfo: untagItems
            });
        }
    }

    _handleUntagModalComplete(){
        this.setState({
            isReloading: true,
            untagIsModalVisible: false,
            untagIDinfo: []
        });
    }

    _handleUntagCancel(){
        this.setState({
            untagIsModalVisible: false,
            untagIDinfo: []
        });
    }

    _buildActionColumns(){

        return [
            {
                title: "",
                dataIndex: "",
                render: (text,record)=>{
                    const { assocData } = record;

                    let tag = "";
                    if(record.name.search(this.VIDEO_FILE_REGX) > -1){
                        if(!('type' in assocData)){
                            tag =
                                        <Icon type="tag"/>
                                    ;
                        }
                    }

                    let untag = "";
                    if('type' in assocData){
                        untag =
                                    <Icon type="disconnect" className="ib-filebrowser-media-play"/>
                                ;
                    }
                    return (

                                <Icon type="delete"/>
                             {tag}{untag}

                    );
                }
            }
        ];
    }

    _buildFileManager(){
        const {
            currentPath,
            currentPathInfo,
            currentToplevelDirectory,
            idmultipleIsModalVisible,
            idmultipleEpisodes,
            idsingleFilename,
            idsingleIsModalVisible,
            isReloading,
            trashIsModalVisible,
            trashSelectedItems,
            selectedRows,
            untagIDinfo,
            untagIsModalVisible
        } = this.state;

        const hasSelected = (selectedRows.length > 0) ? true : false;
        const buttonDisabled = !hasSelected;

        return (

                    <Button
                        type="primary"
                        icon="video-camera"
                        onClick={this._handleSelectVideos.bind(this)}
                    >Select Videos</Button>
                    <Button.Group>
                        <Button
                            icon="tag"
                            disabled={buttonDisabled}
                            onClick={this._handleClickIDMultipleEpisodes.bind(this)}>ID Multiple</Button>
                        <Button
                            type="danger"
                            icon="delete"
                            disabled={buttonDisabled}
                            onClick={this._handleClickTrash.bind(this)}
                        >Trash</Button>
                        <Button
                            type="danger"
                            icon="disconnect"
                            disabled={buttonDisabled}
                            onClick={this._handleClickUntag.bind(this)}
                        >Remove ID</Button>
                    </Button.Group>

                <FilesystemBrowser
                    actionColumns={this._buildActionColumns()}
                    basePath={currentToplevelDirectory}
                    currentPath={currentPath}
                    forceReload={isReloading}
                    hasCheckboxes={true}
                    onChangeDirectory={this._handleChangeDirectory.bind(this)}
                    parentHandleSelectChange={this._handleSelectionChange.bind(this)}
                    selectedRowKeys={selectedRows}
                    showDirectories={true}
                    showFiles={true}
                />
                <TrashModal
                    currentPath={currentPath}
                    isVisible={trashIsModalVisible}
                    itemsToTrash={trashSelectedItems}
                    onTrashComplete={this._handleTrashComplete.bind(this)}
                    onCancel={this._handleCancelTrash.bind(this)}
                />
                <IDFileModal
                    key={idsingleFilename}
                    isVisible={idsingleIsModalVisible}
                    onIDComplete={this._handleIDModalComplete.bind(this)}
                    onCancel={this._handleIDModalCancel.bind(this)}
                    currentFilename={idsingleFilename}
                    currentPathInfo={currentPathInfo}
                    currentToplevelDirectory={currentToplevelDirectory}
                />
                <IDMultipleEpisodesModal
                    currentPathInfo={currentPathInfo}
                    episodesToID={idmultipleEpisodes}
                    isVisible={idmultipleIsModalVisible}
                    onCancel={this._handleIDMultipleCancel.bind(this)}
                    onIDComplete={this._handleIDMultipleComplete.bind(this)}
                />
                <UntagModal
                    isVisible={untagIsModalVisible}
                    onUntagComplete={this._handleUntagModalComplete.bind(this)}
                    onCancel={this._handleUntagCancel.bind(this)}
                    itemsToUntag={untagIDinfo}
                />

        );
    }

    _buildDirectoryMenu(){
        const { toplevelDirectories } = this.props;
        const { currentToplevelDirectory } = this.state;

        const menuList = [];
        toplevelDirectories.forEach((dir)=>{
            const activeClass = (dir.value === currentToplevelDirectory) ? "ib-filemanager-button ib-filemanager-button-active" : "ib-filemanager-button";
            menuList.push(
                <Menu.Item
                    key={dir.value}>
                    <Link to={"/filemanager/" + dir.key}>
                        {dir.key}
                    </Link>
                </Menu.Item>
            );
        });

        return (<Menu mode="horizontal" selectedKeys={[currentToplevelDirectory]}>{menuList}</Menu>);
    }

    render() {
        const { currentToplevelDirectory } = this.state;

        let directoryMenu = this._buildDirectoryMenu();
        let output = "";
        if(currentToplevelDirectory){
            output = this._buildFileManager();
        }
        return (

                    {directoryMenu}

                {output}

        );
    }
}

const mapStateToProps = (state)=>{
    const { settings } = state;

    return {
        toplevelDirectories: settings.settings.directories
    };
}

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


<commit_before>/* -*- js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80; */
"use strict";

function isEmpty(input) {
  return !input.length;
}

var mona = {
  result: function(value) {
    return function(input) {
      return [{val: value, input: input}];
    };
  },

  // TODO - We could add a message here, to provide better failure
  // messagess, but it might need some restructuring of the value data
  // structure.
  fail:  function() {
    return function() {
      return [];
    };
  },

  item: function() {
    return function(input) {
      return isEmpty(input) ? [] : [{
        val: input[0],
        input: input.substr(1)
      }];
    };
  },

  bind: function(parser, fun) {
    return function(input) {
      return parser(input).reduce(function(acc, valObj) {
        return acc.concat(fun(valObj.val)(valObj.input));
      }, []);
    };
  },

  run: function run(parser, input) {
    return parser(input)[0];
  },

  satisfies: function satisfies(predicate) {
    return mona.bind(mona.item(), function(x) {
      return predicate(x) ? mona.result(x) : mona.fail();
    });
  },

  amb: function() {
    var parsers = [].slice.call(arguments);
    return function(input) {
      return parsers.reduce(function(acc, parser) {
        return acc.concat(parser(input));
      }, []);
    };
  },

  endOfInput: function() {
    return function(input) {
      return isEmpty(input) ? [{val: true, input: input}] : [];
    };
  },

  or: function() {
    function orHelper() {
      var parsers = [].slice.call(arguments);
      return function(input) {
        var res = parsers[0](input);
        return res.length ?
          res :
          (parsers.length > 1) ?
          orHelper.apply(this, parsers.slice(1))(input) :
          [];
      };
    }
    return orHelper.apply(this, arguments);
  },

  and: function(parser) {
    var moreParsers = [].slice.call(arguments, 1);
    return mona.bind(parser, function(res) {
      return moreParsers.length ?
        mona.and.apply(null, moreParsers) :
        mona.result(res);
    });
  },

  not: function(parser) {
    return function(input) {
      return parser(input).length ? [] : [{val: true, input: input}];
    };
  },

  unless: function(parser) {
    var moreParsers = [].slice.call(arguments, 1);
    return mona.and.apply(null, [mona.not(parser)].concat(moreParsers));
  },

  character: function(x) {
    return mona.satisfies(function(y) { return x === y; });
  },

  before: function(parser, endParser) {
    return mona.sequence(function(s) {
      var i = s(parser),
          res = s(function(input) {
            return endParser(input).length ? [{val: i, input: input}] : [];
          });
      return mona.result(res);
    });
  },

  string: function(str) {
    return !str.length ?
      mona.result("") :
      mona.sequence(function(s) {
        s(mona.character(str[0]));
        s(mona.string(str.substr(1)));
        return mona.result(str);
      });
  },

  zeroOrMore: function(parser) {
    return function(input) {
      var results = [], value;
      while (value = parser(input), value.length) {
        results.push(value[0].val);
        input = value[0].input;
      }
      return [{val: results, input: input}];
    };
  },

  oneOrMore: function(parser) {
    return mona.sequence(function(s) {
      var x = s(parser),
          y = s(mona.zeroOrMore(parser));
      return mona.result([x].concat(y));
    });
  },

  maybe: function(parser) {
    return mona.or(parser, mona.result(false));
  },

  // TODO - This won't handle ambiguous parses made with amb.
  sequence: function(fun) {
    return function(input) {
      var state, failwhale = {};
      function s(parser) {
        state = parser(input);
        if (state.length > 1) {
          throw new Error("sequence does not currently support "+
                          "ambiguous results. Use bind manually, instead.");
        } else if (state.length) {
          input = state[0].input;
          return state[0].val;
        } else {
          throw failwhale;
        }
      }
      try {
        return fun(s)(input);
      } catch(x) {
        if (x === failwhale) {
          return [];
        } else {
          throw x;
        }
      }
    };
  },

  digitCharacter: function(base) {
    base = base || 10;
    return mona.satisfies(function(x) { return !isNaN(parseInt(x, base)); });
  },

  digit: function(base) {
    base = base || 10;
    return mona.sequence(function(s) {
      var c = s(mona.item()),
          digit = s(mona.result(parseInt(c, base)));
      return isNaN(digit) ? mona.fail() : mona.result(digit);
    });
  },

  naturalNumber: function(base) {
    base = base || 10;
    return mona.sequence(function(s) {
      var xs = s(mona.oneOrMore(mona.digitCharacter(base)));
      return mona.result(parseInt(xs.join(""), base));
    });
  },

  integer: function(base) {
    base = base || 10;
    return mona.sequence(function(s) {
      var sign = s(mona.maybe(mona.or(mona.character("+"),
                                      mona.character("-")))),
          num = s(mona.naturalNumber(base));
      return mona.result(num * (sign === "-" ? -1 : 1));
    });
  },

  oneOf: function(characters) {
    return mona.bind(mona.item(), function(ch) {
      return (characters.indexOf(ch) >= 0) ? mona.result(ch) : mona.fail();
    });
  },

  whitespace: function() {
    return mona.oneOf(" \t\n\r");
  },

  ws: function() {
    return mona.skipWhitespace();
  },

  skipWhitespace: function() {
    return mona.zeroOrMore(mona.whitespace());
  },

  stringOf: function(parser) {
    return mona.bind(parser, function(xs) { return mona.result(xs.join("")); });
  },

  word: function() {
    return mona.stringOf(
      mona.oneOrMore(mona.unless(mona.whitespace(), mona.item())));
  },

  prog1: function(parser) {
    var parsers = [].slice.call(arguments, 1);
    return mona.bind(parser, function(result) {
      return mona.bind(mona.and.apply(null, parsers), function() {
        return mona.result(result);
      });
    });
  },

  text: function(parser) {
    parser = parser || mona.item();
    return mona.stringOf(mona.oneOrMore(parser));
  }
};

module.exports = mona;
<commit_msg>Improving whitespace-related parsers<commit_after>/* -*- js2-basic-offset: 2; indent-tabs-mode: nil; -*- */
/* vim: set ft=javascript ts=2 et sw=2 tw=80; */
"use strict";

function isEmpty(input) {
  return !input.length;
}

var mona = {
  result: function(value) {
    return function(input) {
      return [{val: value, input: input}];
    };
  },

  // TODO - We could add a message here, to provide better failure
  // messagess, but it might need some restructuring of the value data
  // structure.
  fail:  function() {
    return function() {
      return [];
    };
  },

  item: function() {
    return function(input) {
      return isEmpty(input) ? [] : [{
        val: input[0],
        input: input.substr(1)
      }];
    };
  },

  bind: function(parser, fun) {
    return function(input) {
      return parser(input).reduce(function(acc, valObj) {
        return acc.concat(fun(valObj.val)(valObj.input));
      }, []);
    };
  },

  run: function run(parser, input) {
    return parser(input)[0];
  },

  satisfies: function satisfies(predicate) {
    return mona.bind(mona.item(), function(x) {
      return predicate(x) ? mona.result(x) : mona.fail();
    });
  },

  amb: function() {
    var parsers = [].slice.call(arguments);
    return function(input) {
      return parsers.reduce(function(acc, parser) {
        return acc.concat(parser(input));
      }, []);
    };
  },

  endOfInput: function() {
    return function(input) {
      return isEmpty(input) ? [{val: true, input: input}] : [];
    };
  },

  or: function() {
    function orHelper() {
      var parsers = [].slice.call(arguments);
      return function(input) {
        var res = parsers[0](input);
        return res.length ?
          res :
          (parsers.length > 1) ?
          orHelper.apply(this, parsers.slice(1))(input) :
          [];
      };
    }
    return orHelper.apply(this, arguments);
  },

  and: function(parser) {
    var moreParsers = [].slice.call(arguments, 1);
    return mona.bind(parser, function(res) {
      return moreParsers.length ?
        mona.and.apply(null, moreParsers) :
        mona.result(res);
    });
  },

  not: function(parser) {
    return function(input) {
      return parser(input).length ? [] : [{val: true, input: input}];
    };
  },

  unless: function(parser) {
    var moreParsers = [].slice.call(arguments, 1);
    return mona.and.apply(null, [mona.not(parser)].concat(moreParsers));
  },

  character: function(x) {
    return mona.satisfies(function(y) { return x === y; });
  },

  before: function(parser, endParser) {
    return mona.sequence(function(s) {
      var i = s(parser),
          res = s(function(input) {
            return endParser(input).length ? [{val: i, input: input}] : [];
          });
      return mona.result(res);
    });
  },

  string: function(str) {
    return !str.length ?
      mona.result("") :
      mona.sequence(function(s) {
        s(mona.character(str[0]));
        s(mona.string(str.substr(1)));
        return mona.result(str);
      });
  },

  zeroOrMore: function(parser) {
    return function(input) {
      var results = [], value;
      while (value = parser(input), value.length) {
        results.push(value[0].val);
        input = value[0].input;
      }
      return [{val: results, input: input}];
    };
  },

  oneOrMore: function(parser) {
    return mona.sequence(function(s) {
      var x = s(parser),
          y = s(mona.zeroOrMore(parser));
      return mona.result([x].concat(y));
    });
  },

  maybe: function(parser) {
    return mona.or(parser, mona.result(false));
  },

  // TODO - This won't handle ambiguous parses made with amb.
  sequence: function(fun) {
    return function(input) {
      var state, failwhale = {};
      function s(parser) {
        state = parser(input);
        if (state.length > 1) {
          throw new Error("sequence does not currently support "+
                          "ambiguous results. Use bind manually, instead.");
        } else if (state.length) {
          input = state[0].input;
          return state[0].val;
        } else {
          throw failwhale;
        }
      }
      try {
        return fun(s)(input);
      } catch(x) {
        if (x === failwhale) {
          return [];
        } else {
          throw x;
        }
      }
    };
  },

  digitCharacter: function(base) {
    base = base || 10;
    return mona.satisfies(function(x) { return !isNaN(parseInt(x, base)); });
  },

  digit: function(base) {
    base = base || 10;
    return mona.sequence(function(s) {
      var c = s(mona.item()),
          digit = s(mona.result(parseInt(c, base)));
      return isNaN(digit) ? mona.fail() : mona.result(digit);
    });
  },

  naturalNumber: function(base) {
    base = base || 10;
    return mona.sequence(function(s) {
      var xs = s(mona.oneOrMore(mona.digitCharacter(base)));
      return mona.result(parseInt(xs.join(""), base));
    });
  },

  integer: function(base) {
    base = base || 10;
    return mona.sequence(function(s) {
      var sign = s(mona.maybe(mona.or(mona.character("+"),
                                      mona.character("-")))),
          num = s(mona.naturalNumber(base));
      return mona.result(num * (sign === "-" ? -1 : 1));
    });
  },

  oneOf: function(characters) {
    return mona.bind(mona.item(), function(ch) {
      return (characters.indexOf(ch) >= 0) ? mona.result(ch) : mona.fail();
    });
  },

  whitespace: function() {
    return mona.oneOf(" \t\n\r");
  },

  ws: function() {
    return mona.oneOrMore(mona.whitespace());
  },

  skipWhitespace: function() {
    return mona.maybe(mona.ws());
  },

  stringOf: function(parser) {
    return mona.bind(parser, function(xs) { return mona.result(xs.join("")); });
  },

  word: function() {
    return mona.stringOf(
      mona.oneOrMore(mona.unless(mona.whitespace(), mona.item())));
  },

  prog1: function(parser) {
    var parsers = [].slice.call(arguments, 1);
    return mona.bind(parser, function(result) {
      return mona.bind(mona.and.apply(null, parsers), function() {
        return mona.result(result);
      });
    });
  },

  text: function(parser) {
    parser = parser || mona.item();
    return mona.stringOf(mona.oneOrMore(parser));
  },

  normalizedText: function(parser) {
    return mona.bind(mona.text(parser), function(txt) {
      return mona.result(txt.replace(/\s+/g, ' '));
    });
  }
};

module.exports = mona;
<|endoftext|>


<commit_before>'use strict';

/*
 Example of using raml2md as a script.
 */

var raml2md = require('..');

// raml2md.render() needs a config object with at least a `template` property (a url to a Nunjucks template).
// Instead of creating this config object ourselves, we can just ask for raml2md.getDefaultConfig():
var config = raml2md.getDefaultConfig();

raml2md.render(__dirname + '/example.raml', config).then(function(result) {
  console.log(result);
}, function(error) {
  console.log('error! ', error);
});
<commit_msg>Fix example so it lints<commit_after>'use strict';

/*
 Example of using raml2md as a script.
 */

var raml2md = require('..');
var path = require('path');

// raml2md.render() needs a config object with at least a `template` property (a url to a Nunjucks template).
// Instead of creating this config object ourselves, we can just ask for raml2md.getDefaultConfig():
var config = raml2md.getDefaultConfig();

raml2md.render(path.join(__dirname, 'example.raml'), config).then(function(result) {
  console.log(result);
}, function(error) {
  console.log('error! ', error);
});
<|endoftext|>


<commit_before>import PropTypes from 'prop-types'
import React from 'react'
import Preview from '../Preview'

const View = props => (

      {!props.readOnly
      && <button
        type="button"
        title={props.deleteTitle || 'delete'}
        className="action btn btn-danger"
        onClick={() => props.onUpload(null)}
      >

      </button>}

    <Preview
      srcUrl={props.value.binaryLink}
      thumbnailUrl={props.value.thumbnailLink}
      caption={props.value.fileName}
      alt={props.value.fileName}
      downloadOnClick
    />

)

View.propTypes = {
  readOnly: PropTypes.bool,
  onUpload: PropTypes.func,
  value: PropTypes.shape({
    fileName: PropTypes.string.isRequired,
    binaryLink: PropTypes.string.isRequired,
    thumbnailLink: PropTypes.string,
    mimeType: PropTypes.string
  }).isRequired,
  deleteTitle: PropTypes.string,
  downloadTitle: PropTypes.string
}

export default View
<commit_msg>style(tocco-ui): upload markup delete button same as download<commit_after>import PropTypes from 'prop-types'
import React from 'react'
import Preview from '../Preview'

const View = props => (

      {!props.readOnly
      &&  props.onUpload(null)}
      >

      }

    <Preview
      srcUrl={props.value.binaryLink}
      thumbnailUrl={props.value.thumbnailLink}
      caption={props.value.fileName}
      alt={props.value.fileName}
      downloadOnClick
    />

)

View.propTypes = {
  readOnly: PropTypes.bool,
  onUpload: PropTypes.func,
  value: PropTypes.shape({
    fileName: PropTypes.string.isRequired,
    binaryLink: PropTypes.string.isRequired,
    thumbnailLink: PropTypes.string,
    mimeType: PropTypes.string
  }).isRequired,
  deleteTitle: PropTypes.string,
  downloadTitle: PropTypes.string
}

export default View
<|endoftext|>


<commit_before>import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';

import { Icon, Button, Modal } from 'antd';

import FilesystemBrowser from './Filesystem/FilesystemBrowser';
import IDFileModal from './IDFileModal';
import TrashModal from './Filesystem/TrashModal';

import { getSettingsForCategory } from '../actions/settings.actions';

class FileManager extends Component {
    VIDEO_FILE_REGX = /(\.mp4|\.mkv|\.avi)$/;
    constructor(props){
        super(props);

        this.state = {
            currentToplevelDirectory: "",
            currentPath: "",
            dirList: [],
            idModalFilename: "",
            isReloading: false,
            isTrashVisible: false,
            isIDModalVisible: false,
            itemsToTrash: [],
            selectedRows: []
        };
    }

    componentWillMount(){
        this.props.getSettingsForCategory('directories');
    }

    _reloadDirList(){
        this.setState({
            isReloading: true
        });
    }

    _handleChangeDirectory(newDir, dirList){
        this.setState({
            currentPath: newDir,
            dirList,
            selectedRows: [],
            isReloading: false
        })
    }

    _handleSelectTopLevelDir(dir) {
        this.setState({
            currentToplevelDirectory: dir.value,
            currentPath: dir.value
        });
    }

    _handleSelectionChange(selectedRows){
        this.setState({
            selectedRows
        });
    }

    _handleClickTrash(evt){
        let itemsToTrash = [];
        if(evt.currentTarget.tagName === "BUTTON"){
            itemsToTrash = [...this.state.selectedRows];
        } else {
            const item = evt.currentTarget.getAttribute('data-item-name');
            itemsToTrash = [item];
        }

        this.setState({
            isTrashVisible: true,
            itemsToTrash
        });
    }

    _handleTrashComplete(){
        this.setState({
            isReloading: true,
            isTrashVisible: false,
            itemsToTrash: []
        });
    }

    _handleCancelTrash(){
        this.setState({
            isTrashVisible: false,
            itemsToTrash: []
        });
    }

    _handleClickIDFile(filename){
        this.setState({
            idModalFilename: filename,
            isIDModalVisible: true
        });
    }

    _handleIDModalCancel(){
        this.setState({
            isIDModalVisible: false,
            idModalFilename: ""
        });
    }

    _handleIDModalComplete(){
        this.setState({
            isIDModalVisible: false,
            idModalFilename: ""
        });
    }

    _handleSelectVideos(){
        const { dirList } = this.state;

        let selected = [];
        dirList.forEach((item)=>{
            if(item.name.search(this.VIDEO_FILE_REGX) > -1){
                selected.push(item.name);
            }
        });

        this.setState({
            selectedRows: selected
        });
    }

    _buildActionColumns(){
        return [
            {
                title: "",
                dataIndex: "",
                render: (text,record)=>{
                    return (

                           <Icon type="delete"/>

                            <Icon type="tag"/>

                    );
                }
            }
        ];
    }

    _buildFileManager(){
        const {
            currentPath,
            currentToplevelDirectory,
            idModalFilename,
            isReloading,
            isIDModalVisible,
            isTrashVisible,
            itemsToTrash,
            selectedRows } = this.state;

        const hasSelected = (selectedRows.length > 0) ? true : false;
        const buttonDisabled = !hasSelected;

        return (

                    <Button
                        type="primary"
                        icon="video-camera"
                        onClick={this._handleSelectVideos.bind(this)}
                    >Select Videos</Button>
                    <Button.Group>
                        <Button type="primary" icon="search" disabled={buttonDisabled}>ID</Button>
                        <Button
                            type="danger"
                            icon="delete"
                            disabled={buttonDisabled}
                            onClick={this._handleClickTrash.bind(this)}
                        >Trash</Button>
                    </Button.Group>

                <FilesystemBrowser
                    actionColumns={this._buildActionColumns()}
                    forceReload={isReloading}
                    hasCheckboxes={true}
                    initialPath={currentToplevelDirectory}
                    onChangeDirectory={this._handleChangeDirectory.bind(this)}
                    parentHandleSelectChange={this._handleSelectionChange.bind(this)}
                    selectedRowKeys={selectedRows}
                    showDirectories={true}
                    showFiles={true}
                />
                <TrashModal
                    currentPath={currentPath}
                    isVisible={isTrashVisible}
                    itemsToTrash={itemsToTrash}
                    onTrashComplete={this._handleTrashComplete.bind(this)}
                    onCancel={this._handleCancelTrash.bind(this)}
                />
                <IDFileModal
                    isVisible={isIDModalVisible}
                    onOk={this._handleIDModalComplete.bind(this)}
                    onCancel={this._handleIDModalCancel.bind(this)}
                    currentFilename={idModalFilename}
                />

        );
    }

    _buildDirectoryButtons(){
        const { toplevelDirectories } = this.props;
        const { currentToplevelDirectory } = this.state;

        const buttonList = [];
        toplevelDirectories.forEach((dir)=>{
            const activeClass = (dir.value === currentToplevelDirectory) ? "ib-filemanager-button ib-filemanager-button-active" : "ib-filemanager-button";
            buttonList.push(
                <Button
                    key={dir.key}
                    onClick={this._handleSelectTopLevelDir.bind(this, dir)}
                    className={activeClass}
                >{dir.key}</Button>
            );
        });

        return (<Button.Group>{buttonList}</Button.Group>);
    }

    render() {
        const { currentToplevelDirectory } = this.state;

        let directoryButtons = this._buildDirectoryButtons();
        let output = "";
        if(currentToplevelDirectory){
            output = this._buildFileManager();
        }
        return (

                    {directoryButtons}

                {output}

        );
    }
}

const mapStateToProps = (state)=>{
    const { settings } = state;

    return {
        toplevelDirectories: settings.settings.directories
    };
}

const mapDispatchToProps = (dispatch)=>{
    return {
        getSettingsForCategory: (category)=>dispatch(getSettingsForCategory(category))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(FileManager);<commit_msg>Fixed location of new ID File Modal.<commit_after>import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';

import { Icon, Button, Modal } from 'antd';

import FilesystemBrowser from './Filesystem/FilesystemBrowser';
import IDFileModal from './ID/IDFileModal';
import TrashModal from './Filesystem/TrashModal';

import { getSettingsForCategory } from '../actions/settings.actions';

class FileManager extends Component {
    VIDEO_FILE_REGX = /(\.mp4|\.mkv|\.avi)$/;
    constructor(props){
        super(props);

        this.state = {
            currentToplevelDirectory: "",
            currentPath: "",
            dirList: [],
            idModalFilename: "",
            isReloading: false,
            isTrashVisible: false,
            isIDModalVisible: false,
            itemsToTrash: [],
            selectedRows: []
        };
    }

    componentWillMount(){
        this.props.getSettingsForCategory('directories');
    }

    _reloadDirList(){
        this.setState({
            isReloading: true
        });
    }

    _handleChangeDirectory(newDir, dirList){
        this.setState({
            currentPath: newDir,
            dirList,
            selectedRows: [],
            isReloading: false
        })
    }

    _handleSelectTopLevelDir(dir) {
        this.setState({
            currentToplevelDirectory: dir.value,
            currentPath: dir.value
        });
    }

    _handleSelectionChange(selectedRows){
        this.setState({
            selectedRows
        });
    }

    _handleClickTrash(evt){
        let itemsToTrash = [];
        if(evt.currentTarget.tagName === "BUTTON"){
            itemsToTrash = [...this.state.selectedRows];
        } else {
            const item = evt.currentTarget.getAttribute('data-item-name');
            itemsToTrash = [item];
        }

        this.setState({
            isTrashVisible: true,
            itemsToTrash
        });
    }

    _handleTrashComplete(){
        this.setState({
            isReloading: true,
            isTrashVisible: false,
            itemsToTrash: []
        });
    }

    _handleCancelTrash(){
        this.setState({
            isTrashVisible: false,
            itemsToTrash: []
        });
    }

    _handleClickIDFile(filename){
        this.setState({
            idModalFilename: filename,
            isIDModalVisible: true
        });
    }

    _handleIDModalCancel(){
        this.setState({
            isIDModalVisible: false,
            idModalFilename: ""
        });
    }

    _handleIDModalComplete(){
        this.setState({
            isIDModalVisible: false,
            idModalFilename: ""
        });
    }

    _handleSelectVideos(){
        const { dirList } = this.state;

        let selected = [];
        dirList.forEach((item)=>{
            if(item.name.search(this.VIDEO_FILE_REGX) > -1){
                selected.push(item.name);
            }
        });

        this.setState({
            selectedRows: selected
        });
    }

    _buildActionColumns(){
        return [
            {
                title: "",
                dataIndex: "",
                render: (text,record)=>{
                    return (

                           <Icon type="delete"/>

                            <Icon type="tag"/>

                    );
                }
            }
        ];
    }

    _buildFileManager(){
        const {
            currentPath,
            currentToplevelDirectory,
            idModalFilename,
            isReloading,
            isIDModalVisible,
            isTrashVisible,
            itemsToTrash,
            selectedRows } = this.state;

        const hasSelected = (selectedRows.length > 0) ? true : false;
        const buttonDisabled = !hasSelected;

        return (

                    <Button
                        type="primary"
                        icon="video-camera"
                        onClick={this._handleSelectVideos.bind(this)}
                    >Select Videos</Button>
                    <Button.Group>
                        <Button type="primary" icon="search" disabled={buttonDisabled}>ID</Button>
                        <Button
                            type="danger"
                            icon="delete"
                            disabled={buttonDisabled}
                            onClick={this._handleClickTrash.bind(this)}
                        >Trash</Button>
                    </Button.Group>

                <FilesystemBrowser
                    actionColumns={this._buildActionColumns()}
                    forceReload={isReloading}
                    hasCheckboxes={true}
                    initialPath={currentToplevelDirectory}
                    onChangeDirectory={this._handleChangeDirectory.bind(this)}
                    parentHandleSelectChange={this._handleSelectionChange.bind(this)}
                    selectedRowKeys={selectedRows}
                    showDirectories={true}
                    showFiles={true}
                />
                <TrashModal
                    currentPath={currentPath}
                    isVisible={isTrashVisible}
                    itemsToTrash={itemsToTrash}
                    onTrashComplete={this._handleTrashComplete.bind(this)}
                    onCancel={this._handleCancelTrash.bind(this)}
                />
                <IDFileModal
                    isVisible={isIDModalVisible}
                    onOk={this._handleIDModalComplete.bind(this)}
                    onCancel={this._handleIDModalCancel.bind(this)}
                    currentFilename={idModalFilename}
                />

        );
    }

    _buildDirectoryButtons(){
        const { toplevelDirectories } = this.props;
        const { currentToplevelDirectory } = this.state;

        const buttonList = [];
        toplevelDirectories.forEach((dir)=>{
            const activeClass = (dir.value === currentToplevelDirectory) ? "ib-filemanager-button ib-filemanager-button-active" : "ib-filemanager-button";
            buttonList.push(
                <Button
                    key={dir.key}
                    onClick={this._handleSelectTopLevelDir.bind(this, dir)}
                    className={activeClass}
                >{dir.key}</Button>
            );
        });

        return (<Button.Group>{buttonList}</Button.Group>);
    }

    render() {
        const { currentToplevelDirectory } = this.state;

        let directoryButtons = this._buildDirectoryButtons();
        let output = "";
        if(currentToplevelDirectory){
            output = this._buildFileManager();
        }
        return (

                    {directoryButtons}

                {output}

        );
    }
}

const mapStateToProps = (state)=>{
    const { settings } = state;

    return {
        toplevelDirectories: settings.settings.directories
    };
}

const mapDispatchToProps = (dispatch)=>{
    return {
        getSettingsForCategory: (category)=>dispatch(getSettingsForCategory(category))
    }
}

export default connect(mapStateToProps, mapDispatchToProps)(FileManager);<|endoftext|>


<commit_before>var http = require('http');
var fs = require('fs');

var server = http.createServer(function (req, res) {
	if(req.url === '/lib/anthStats.js') {
		res.setHeader("Content-Type", "application/x-javascript")
		fs.createReadStream(__dirname + '/../lib/anthStats.js').pipe(res);
		return;
	}

	if(/^\/(index.html)?/.test(req.url)) {
		res.setHeader("Content-Type", "text/html")
		fs.createReadStream(__dirname + '/static/index.html').pipe(res);
		return;
	}

	if(/^\/stat/.test(req.url)) {
		console.log("Got stat: ", req.url);

		res.setHeader("Content-Type", "image/jpeg")
		res.end();
		return;
	}
});
server.listen(8000);

console.log('Listening for request:');
<commit_msg>fix server response mime<commit_after>var http = require('http');
var fs = require('fs');

var server = http.createServer(function (req, res) {
	if(req.url === '/lib/anthStats.js') {
		res.setHeader("Content-Type", "application/x-javascript");
		fs.createReadStream(__dirname + '/../lib/anthStats.js').pipe(res);
		return;
	}

	if(/^\/stat/.test(req.url)) {
		console.log("Got stat: ", req.url);

		res.setHeader("Content-Type", "image/jpeg");
		res.end();
		return;
	}

	if(/^\/(index.html)?/.test(req.url)) {
		res.setHeader("Content-Type", "text/html");
		fs.createReadStream(__dirname + '/static/index.html').pipe(res);
		return;
	}

});
server.listen(8000);

console.log('Listening for request:');
<|endoftext|>


<commit_before>const test = require("ava")
const css = require(process.cwd())
const fs = require("fs")
const glob = require("glob")

let selectors
let classnames

const classPatterns = [
  // HTML class attributes
  /class="([^"]+)"/ig,
  // assume that ERB helpers generate an element with the same class
  /<%= (\w+)\b/g,
]

// Find unique selectors from the cssstats selector list
function uniqueSelectors(s) {
  s = s.map(s => {
    // split multi-selectors into last class used .foo .bar .baz
    return s.split(" ").pop()
  })
  .filter(s => {
    // remove any selector that aren't just regular classnames eg. ::hover [type]
    return s.match(/^\.[a-z\-_]+$/ig)
  })

  // return only the unique selectors
  return [...new Set(s)]
}

// From the given glob sources array, read the files and return found classnames
function documentedClassnames(sources) {
  const classes = []
  const files = sources.reduce((acc, pattern) => {
    return acc.concat(glob.sync(pattern))
  }, [])

  files.forEach(file => {
    let match = null
    const content = fs.readFileSync(file, "utf8")

    classPatterns.forEach(pattern => {
      // match each pattern against the source
      while (match = pattern.exec(content)) {
        // get the matched classnames and split by whitespace into classes
        const klasses = match[1].trim().split(/\s+/)
        classes.push(...klasses)
      }
    })
  })

  // return only the unique classnames
  return Array.from(new Set(classes))
}

// Before all the tests get the selectors and classnames
test.before(t => {
  selectors = uniqueSelectors(css.cssstats.selectors.values)
  classnames = documentedClassnames([
    "docs/*.md",
    "README.md"
  ])
})

test("Every selector class is documented", t => {
  const undocumented = []
  selectors.forEach(selector => {
    if (!classnames.includes(selector.replace(/^\./, ""))) {
      undocumented.push(selector)
    }
  })
  t.is(undocumented.length, 0, `I did not find documentation for the "${undocumented.join(", ")}" selector(s) in the ${process.env.npm_package_name} module.`);
})
<commit_msg>refactor docs test: more async, one test per class<commit_after>const {join} = require('path')
const fse = require('fs-extra')
const globby = require('globby')
const test = require('ava')
const minimatch = require('minimatch')

const cwd = process.cwd()
const css = require(cwd)
const pkg = require(join(cwd, 'package.json'))

const unique = list => Array.from(new Set(list)).sort()

/*
 * These are the regular expressions that match what we
 * expect to be class name instances in the docs.
 * Patterns should group the matched class name(s) such that:
 *
 * ```js
 * const [, klass, ] = pattern.exec(content)
 * ```
 */
const classPatterns = [
  // HTML class attributes
  /class="([^"]+)"/ig,
  /:class ?=> "([^"]+)"/g,
  /class: "([^"]+)"/g,
  // assume that ERB helpers generate an element with the same class
  /<%= (\w+)\b/g,
]

const whitelistClasses = (pkg.primer ? pkg.primer.class_whitelist || [] : [])
  .concat('js*')

const isWhitelisted = klass => {
  return whitelistClasses.some(glob => minimatch(klass, glob))
}

// Find unique selectors from the cssstats selector list
function uniqueSelectors(selectors) {
  return unique(selectors.map(s => {
    // split multi-selectors into last class used .foo .bar .baz
    return s.split(' ').pop()
  })
  .filter(s => {
    // only match exact class selectors
    return s.match(/^\.[a-z\-_]+$/ig)
  }))
}

// From the given glob sources array, read the files and return found classnames
function getDocumentedClassnames(sources) {
  return globby(sources)
    .then(paths => {
      return Promise.all(paths.map(path => {
        return fse.readFile(path, 'utf8')
          .then(content => ({path, content}))
      }))
    })
    .then(files => {
      return files.reduce((classes, {path, content}) => {
        classPatterns.forEach(pattern => {
          let match
          while (match = pattern.exec(content)) {
            // get the matched classnames and split by whitespace into classes
            let klasses = match[1].trim().split(/\s+/)
            classes.push(...klasses)
          }
        })
        return classes
      }, [])
    })
    .then(classes => unique(classes))
}

const selectors = uniqueSelectors(css.cssstats.selectors.values)
let classnames
test.before(t => {
  return getDocumentedClassnames([
      'docs/*.md',
      'README.md'
    ])
    .then(_ => (classnames = _))
})

selectors.forEach(selector => {
  const klass = selector.replace(/^\./, '')
  test(`Selector "${selector}" is documented/whitelisted`, t => {
    t.plan(1)
    if (isWhitelisted(klass)) {
      t.pass(`Selector "${selector}" is whitelisted`)
    } else {
      t.is(classnames.includes(klass), true, `Selector "${selector}" is not documented`)
    }
  })
})
<|endoftext|>


<commit_before>const _ = require('lodash');

const {applyStyle, removeStyle} = require('../manage-style');

const dynamicScalingfactors = (zoom) => {
  const scalingFactor = (1 / zoom);
  const defaults = {
    fontSize: 40,
    outlineWidth: 4,
    arrowScale: 3,
    edgeWidth: 2,
  };

  const dynamicFontSize = Math.min(defaults.fontSize, Math.max(scalingFactor * 18, 18));
  const dynamicFontOutlineWidth = Math.min(defaults.outlineWidth, Math.max(scalingFactor * 3, 3));
  const dynamicArrowScale = Math.min(defaults.arrowScale, Math.max(scalingFactor * 2.5, 2.5));
  const dynamicEdgewidth = Math.min(defaults.edgeWidth, Math.max(scalingFactor * 2.5, 2.5));

  return {
    fontSize: dynamicFontSize,
    outlineWidth: dynamicFontOutlineWidth,
    arrowScale: dynamicArrowScale,
    edgeWidth: dynamicEdgewidth
  };
};

const scaledDimensions = (node, zoom) => {
  const nw = node.width();
  const nh = node.height();

  if (nw === 0 || nh === 0) { return { w: 0, h: 0 }; }

  const scaledVal = (1 / zoom) * 8;
  const aspectRatio = nw / nh;
  let xIncr = 0;
  let yIncr = 0;

  if (aspectRatio > 1) {
    xIncr = nw + scaledVal;
    yIncr = nh + (scaledVal / aspectRatio);
  } else {
    xIncr = nw + (scaledVal / aspectRatio);
    yIncr = nh + scaledVal;
  }

  return {
    w: xIncr,
    h: yIncr
  };
};

const baseNodeHoverStyle = {
  'background-color': 'blue',
  'opacity': 1,
  'z-compound-depth': 'top',
  'color': 'white',
  'text-outline-color': 'black'
};

const baseEdgeHoverStyle = {
  'line-color': 'orange',
  'opacity': 1
};

const bindHover = (cy) => {
  cy.on('mouseover', 'node[class!="compartment"]', function (evt) {
    const node = evt.target;
    const currZoom = cy.zoom();

    if (node.isParent() && node.isExpanded()) { return; }

    const { fontSize, outlineWidth, arrowScale, edgeWidth } = dynamicScalingfactors(currZoom);

    node.neighborhood().nodes().union(node).forEach((node) => {
      const { w, h } = scaledDimensions(node, currZoom);

      const nodeHoverStyle = _.assign({}, baseNodeHoverStyle, {
        'font-size': fontSize,
        'text-outline-width': outlineWidth,
        'width': w,
        'height': h
      });

      applyStyle(cy, node, nodeHoverStyle, '_hover-style-before');
    });

    const edgeHoverStyle = _.assign({}, baseEdgeHoverStyle, {
      'arrow-scale': arrowScale,
      'width': edgeWidth
    });

    applyStyle(cy, node.neighborhood().edges(), edgeHoverStyle, '_hover-style-before');
  });

  cy.on('mouseout', 'node[class!="compartment"]', function (evt) {
    const node = evt.target;
    const neighborhood = node.neighborhood();

    removeStyle(cy, neighborhood.nodes(), '_hover-style-before');
    removeStyle(cy, node, '_hover-style-before');
    removeStyle(cy, neighborhood.edges(), '_hover-style-before');
  });

  cy.on('mouseover', 'edge', function (evt) {
    const edge = evt.target;
    const currZoom = cy.zoom();

    const { fontSize, outlineWidth, arrowScale, edgeWidth } = dynamicScalingfactors(currZoom);

    const edgeHoverStyle = _.assign({}, baseEdgeHoverStyle, {
      'arrow-scale': arrowScale,
      'width': edgeWidth
    });
    applyStyle(cy, edge, edgeHoverStyle, '_hover-style-before');

    edge.source().union(edge.target()).forEach((node) => {
      const { w, h } = scaledDimensions(node, currZoom);
      const nodeHoverStyle = _.assign({}, baseNodeHoverStyle, {
        'width': w,
        'height': h,
        'font-size': fontSize,
        'color': 'white',
        'text-outline-color': 'black',
        'text-outline-width': outlineWidth,
        'opacity': 1,
        'background-color': 'blue',
        'z-compound-depth': 'top'
      });
      applyStyle(cy, node, nodeHoverStyle, '_hover-style-before');
    });
  });

  cy.on('mouseout', 'edge', function (evt) {
    const edge = evt.target;

    removeStyle(cy, edge, '_hover-style-before');
    removeStyle(cy, edge.source(), '_hover-style-before');
    removeStyle(cy, edge.target(), '_hover-style-before');
  });

};

module.exports = bindHover;<commit_msg>add ability to specify style to bindHover - requires a better common cy module that accepts style arguments that trickles down to bindHover<commit_after>const _ = require('lodash');

const {applyStyle, removeStyle} = require('../manage-style');

const dynamicScalingfactors = (zoom) => {
  const scalingFactor = (1 / zoom);
  const defaults = {
    fontSize: 40,
    outlineWidth: 4,
    arrowScale: 3,
    edgeWidth: 2,
  };

  const dynamicFontSize = Math.min(defaults.fontSize, Math.max(scalingFactor * 18, 18));
  const dynamicFontOutlineWidth = Math.min(defaults.outlineWidth, Math.max(scalingFactor * 3, 3));
  const dynamicArrowScale = Math.min(defaults.arrowScale, Math.max(scalingFactor * 2.5, 2.5));
  const dynamicEdgewidth = Math.min(defaults.edgeWidth, Math.max(scalingFactor * 2.5, 2.5));

  return {
    fontSize: dynamicFontSize,
    outlineWidth: dynamicFontOutlineWidth,
    arrowScale: dynamicArrowScale,
    edgeWidth: dynamicEdgewidth
  };
};

const scaledDimensions = (node, zoom) => {
  const nw = node.width();
  const nh = node.height();

  if (nw === 0 || nh === 0) { return { w: 0, h: 0 }; }

  const scaledVal = (1 / zoom) * 8;
  const aspectRatio = nw / nh;
  let xIncr = 0;
  let yIncr = 0;

  if (aspectRatio > 1) {
    xIncr = nw + scaledVal;
    yIncr = nh + (scaledVal / aspectRatio);
  } else {
    xIncr = nw + (scaledVal / aspectRatio);
    yIncr = nh + scaledVal;
  }

  return {
    w: xIncr,
    h: yIncr
  };
};

const baseNodeHoverStyle = {
  'background-color': 'blue',
  'opacity': 1,
  'z-compound-depth': 'top',
  'color': 'white',
  'text-outline-color': 'black'
};

const baseEdgeHoverStyle = {
  'line-color': 'orange',
  'opacity': 1
};

const bindHover = (cy, nodeStyle = baseNodeHoverStyle, edgeStyle = baseEdgeHoverStyle) => {
  cy.on('mouseover', 'node[class!="compartment"]', function (evt) {
    const node = evt.target;
    const currZoom = cy.zoom();

    if (node.isParent() && node.isExpanded()) { return; }

    const { fontSize, outlineWidth, arrowScale, edgeWidth } = dynamicScalingfactors(currZoom);

    node.neighborhood().nodes().union(node).forEach((node) => {
      const { w, h } = scaledDimensions(node, currZoom);

      const nodeHoverStyle = _.assign({}, nodeStyle, {
        'font-size': fontSize,
        'text-outline-width': outlineWidth,
        'width': w,
        'height': h
      });

      applyStyle(cy, node, nodeHoverStyle, '_hover-style-before');
    });

    const edgeHoverStyle = _.assign({}, edgeStyle, {
      'arrow-scale': arrowScale,
      'width': edgeWidth
    });

    applyStyle(cy, node.neighborhood().edges(), edgeHoverStyle, '_hover-style-before');
  });

  cy.on('mouseout', 'node[class!="compartment"]', function (evt) {
    const node = evt.target;
    const neighborhood = node.neighborhood();

    removeStyle(cy, neighborhood.nodes(), '_hover-style-before');
    removeStyle(cy, node, '_hover-style-before');
    removeStyle(cy, neighborhood.edges(), '_hover-style-before');
  });

  cy.on('mouseover', 'edge', function (evt) {
    const edge = evt.target;
    const currZoom = cy.zoom();

    const { fontSize, outlineWidth, arrowScale, edgeWidth } = dynamicScalingfactors(currZoom);

    const edgeHoverStyle = _.assign({}, edgeStyle, {
      'arrow-scale': arrowScale,
      'width': edgeWidth
    });
    applyStyle(cy, edge, edgeHoverStyle, '_hover-style-before');

    edge.source().union(edge.target()).forEach((node) => {
      const { w, h } = scaledDimensions(node, currZoom);
      const nodeHoverStyle = _.assign({}, nodeStyle, {
        'width': w,
        'height': h,
        'font-size': fontSize,
        'color': 'white',
        'text-outline-color': 'black',
        'text-outline-width': outlineWidth,
        'opacity': 1,
        'background-color': 'blue',
        'z-compound-depth': 'top'
      });
      applyStyle(cy, node, nodeHoverStyle, '_hover-style-before');
    });
  });

  cy.on('mouseout', 'edge', function (evt) {
    const edge = evt.target;

    removeStyle(cy, edge, '_hover-style-before');
    removeStyle(cy, edge.source(), '_hover-style-before');
    removeStyle(cy, edge.target(), '_hover-style-before');
  });

};

module.exports = bindHover;<|endoftext|>


<commit_before>/* eslint-env node */

module.exports = function (deployTarget) {
  // these get less aggressive caching because they exist at stable URLs
  let s3PagePattern = '**/*.{html,zip,pdf,css}'; // note that fingerprinting has not been implemented in embroider yet, using less agressive caching for css for now
  let s3WellKnownPattern = '.well-known/*';

  // these get more aggressive caching because they are sub-resources with fingerprinted URLs
  let s3AssetPattern =
    '**/*.{js,png,gif,webp,ico,jpg,map,xml,txt,svg,swf,eot,ttf,woff,woff2,ttc,otf}';

  let ENV = {
    build: {},
    pipeline: {
      activateOnDeploy: true,
      disabled: {},
      alias: {
        s3: {
          as: ['s3Pages', 's3WellKnown', 's3Assets'],
        },
      },
    },
    'revision-data': {
      scm: null,
    },
    s3Assets: {
      filePattern: s3AssetPattern,
      allowOverwrite: true,
    },
    s3Pages: {
      filePattern: s3PagePattern,
      allowOverwrite: true,
      cacheControl: 'max-age=600, public',
    },
    s3WellKnown: {
      filePattern: s3WellKnownPattern,
      allowOverwrite: true,
      cacheControl: 'max-age=600, public',
    },
    cloudfront: {
      objectPaths: [
        '/',
        '/*',
        '/*/*',
        '/index.html',
        '/assets/*',
        '/assets/@cardstack/*',
      ],
    },
  };

  process.env.DEPLOY_TARGET = deployTarget;

  if (deployTarget === 'staging') {
    ENV.build.environment = 'production';
    ENV.s3Assets.bucket =
      ENV.s3Pages.bucket =
      ENV.s3WellKnown.bucket =
        'app-staging-assets-cardstack';
    ENV.cloudfront.region =
      ENV.s3Assets.region =
      ENV.s3Pages.region =
      ENV.s3WellKnown.region =
        'us-east-1';
    ENV.cloudfront.accessKeyId =
      ENV.s3Assets.accessKeyId =
      ENV.s3Pages.accessKeyId =
      ENV.s3WellKnown.accessKeyId =
        process.env.EMBER_DEPLOY_AWS_ACCESS_KEY;
    ENV.cloudfront.secretAccessKey =
      ENV.s3Assets.secretAccessKey =
      ENV.s3Pages.secretAccessKey =
      ENV.s3WellKnown.secretAccessKey =
        process.env.EMBER_DEPLOY_AWS_ACCESS_SECRET;
    ENV.cloudfront.distribution = 'E330O30QIWNDYA';
  }

  if (deployTarget === 'production') {
    ENV.build.environment = 'production';
    ENV.s3Assets.bucket =
      ENV.s3Pages.bucket =
      ENV.s3WellKnown.bucket =
        'app-assets-cardstack';
    ENV.cloudfront.region =
      ENV.s3Assets.region =
      ENV.s3Pages.region =
      ENV.s3WellKnown.region =
        'us-east-1';
    ENV.cloudfront.accessKeyId =
      ENV.s3Assets.accessKeyId =
      ENV.s3Pages.accessKeyId =
      ENV.s3WellKnown.accessKeyId =
        process.env.EMBER_DEPLOY_AWS_ACCESS_KEY;
    ENV.cloudfront.secretAccessKey =
      ENV.s3Assets.secretAccessKey =
      ENV.s3Pages.secretAccessKey =
      ENV.s3WellKnown.secretAccessKey =
        process.env.EMBER_DEPLOY_AWS_ACCESS_SECRET;
    ENV.cloudfront.distribution = 'E3VPNGI7F1WEW8';
  }

  // Note: if you need to build some configuration asynchronously, you can return
  // a promise that resolves with the ENV object instead of returning the
  // ENV object synchronously.
  return ENV;
};
<commit_msg>configure prepaid card asset compression - to enable use on android<commit_after>/* eslint-env node */

module.exports = function (deployTarget) {
  // these get less aggressive caching because they exist at stable URLs
  let s3PagePattern = '**/*.{html,zip,pdf,css}'; // note that fingerprinting has not been implemented in embroider yet, using less agressive caching for css for now
  let s3WellKnownPattern = '.well-known/*';

  // these get more aggressive caching because they are sub-resources with fingerprinted URLs
  let s3AssetPattern =
    '**/*.{js,png,gif,webp,ico,jpg,map,xml,txt,svg,swf,eot,ttf,woff,woff2,ttc,otf}';

  let ENV = {
    build: {},
    pipeline: {
      activateOnDeploy: true,
      disabled: {},
      alias: {
        s3: {
          as: ['s3Pages', 's3WellKnown', 's3Assets'],
        },
        compress: {
          as: ['compressOwnAssets', 'compressPrepaidCardPatterns'],
        },
      },
    },
    'revision-data': {
      scm: null,
    },
    s3Assets: {
      filePattern: s3AssetPattern,
      allowOverwrite: true,
    },
    s3Pages: {
      filePattern: s3PagePattern,
      allowOverwrite: true,
      cacheControl: 'max-age=600, public',
    },
    s3WellKnown: {
      filePattern: s3WellKnownPattern,
      allowOverwrite: true,
      cacheControl: 'max-age=600, public',
    },
    compressOwnAssets: {
      filePattern: '**/*.{js,css,json,ico,map,xml,txt,svg,eot,ttf,woff,woff2}',
      ignorePattern: 'images/prepaid-card-customizations/**/*.svg',
      compression: ['best'],
    },
    compressPrepaidCardPatterns: {
      filePattern: 'images/prepaid-card-customizations/**/*.svg',
      compression: ['gzip'],
    },
    cloudfront: {
      objectPaths: [
        '/',
        '/*',
        '/*/*',
        '/index.html',
        '/assets/*',
        '/assets/@cardstack/*',
      ],
    },
  };

  process.env.DEPLOY_TARGET = deployTarget;

  if (deployTarget === 'staging') {
    ENV.build.environment = 'production';
    ENV.s3Assets.bucket =
      ENV.s3Pages.bucket =
      ENV.s3WellKnown.bucket =
        'app-staging-assets-cardstack';
    ENV.cloudfront.region =
      ENV.s3Assets.region =
      ENV.s3Pages.region =
      ENV.s3WellKnown.region =
        'us-east-1';
    ENV.cloudfront.accessKeyId =
      ENV.s3Assets.accessKeyId =
      ENV.s3Pages.accessKeyId =
      ENV.s3WellKnown.accessKeyId =
        process.env.EMBER_DEPLOY_AWS_ACCESS_KEY;
    ENV.cloudfront.secretAccessKey =
      ENV.s3Assets.secretAccessKey =
      ENV.s3Pages.secretAccessKey =
      ENV.s3WellKnown.secretAccessKey =
        process.env.EMBER_DEPLOY_AWS_ACCESS_SECRET;
    ENV.cloudfront.distribution = 'E330O30QIWNDYA';
  }

  if (deployTarget === 'production') {
    ENV.build.environment = 'production';
    ENV.s3Assets.bucket =
      ENV.s3Pages.bucket =
      ENV.s3WellKnown.bucket =
        'app-assets-cardstack';
    ENV.cloudfront.region =
      ENV.s3Assets.region =
      ENV.s3Pages.region =
      ENV.s3WellKnown.region =
        'us-east-1';
    ENV.cloudfront.accessKeyId =
      ENV.s3Assets.accessKeyId =
      ENV.s3Pages.accessKeyId =
      ENV.s3WellKnown.accessKeyId =
        process.env.EMBER_DEPLOY_AWS_ACCESS_KEY;
    ENV.cloudfront.secretAccessKey =
      ENV.s3Assets.secretAccessKey =
      ENV.s3Pages.secretAccessKey =
      ENV.s3WellKnown.secretAccessKey =
        process.env.EMBER_DEPLOY_AWS_ACCESS_SECRET;
    ENV.cloudfront.distribution = 'E3VPNGI7F1WEW8';
  }

  // Note: if you need to build some configuration asynchronously, you can return
  // a promise that resolves with the ENV object instead of returning the
  // ENV object synchronously.
  return ENV;
};
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import media from '../utils/media';

const ContentDiv = styled.div`
  padding-top: 2rem !important;
  background-color: #fff;

  ${media.tablet`
    padding-left: 33rem !important;
  `}
`;

const PageContent = props => (
  <ContentDiv className="column">
    <div>{props.children}</div>
  </ContentDiv>
);

PageContent.defaultProps = {
  children: null,
};

PageContent.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.object,
    PropTypes.array,
  ]), // eslint-disable-line react/forbid-prop-types
};

export default PageContent;
<commit_msg>simplify DOM<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import media from '../utils/media';

const ContentDiv = styled.div`
  padding-top: 2rem !important;
  background-color: #fff;

  ${media.tablet`
    padding-left: 33rem !important;
  `}
`;

const PageContent = props => (
  <ContentDiv className="column">{props.children}</ContentDiv>
);

PageContent.defaultProps = {
  children: null,
};

PageContent.propTypes = {
  children: PropTypes.oneOfType([
    PropTypes.object,
    PropTypes.array,
  ]), // eslint-disable-line react/forbid-prop-types
};

export default PageContent;
<|endoftext|>