<commit_before>/**
 * Configuration templates
 *
 * All the default values for config options throughout kiwi are set here, under
 * the 'default' template object below.
 * If a 'default.template' value is set in the user config, this is used to
 * find the next template object below and is merged over the default config
 * template.
 * The user config (config.json by default) is then merged over the resulting
 * config object.
 *
 * The advanced settings dialog also displays these settings by iterating
 * through the keys. The values must not be null otherwise they will not be
 * shown.
 */

export const configTemplates = {

    default: {
        plugins: [],
        windowTitle: 'Kiwi IRC - The web IRC client',
        useMonospace: false,
        language: '',
        theme: 'Default',
        themes: [
            { name: 'Default', url: 'static/themes/default' },
        ],
        // Restricted to a single IRC server
        restricted: true,
        // The startup screen
        startupScreen: 'customServer',
        // Where to find the kiwi server
        kiwiServer: '/webirc/kiwiirc/',
        // If active, all connections will be routed via this BNC server. Network settings
        // will be read and updated to the BNC as they are changed.
        bnc: {
            active: false,
            server: '',
            port: 6667,
            tls: false,
            path: '',
            username: '',
            password: '',
        },
        warnOnExit: true,
        // Default buffer settings
        buffers: {
            messageLayout: 'modern',
            alert_on: 'highlight',
            timestamp_format: '%H:%M:%S',
            // If timestamp_full_format is falsy, the browsers locale date format will be used
            timestamp_full_format: '',
            show_timestamps: true,
            scrollback_size: 250,
            show_hostnames: false,
            show_joinparts: true,
            show_topics: true,
            show_nick_changes: true,
            show_mode_changes: true,
            traffic_as_activity: false,
            coloured_nicklist: true,
            colour_nicknames_in_messages: true,
            block_pms: false,
            show_emoticons: true,
            extra_formatting: true,
            mute_sound: false,
            hide_message_counts: false,
            show_realnames: false,
            default_ban_mask: '*!%i@%h',
            default_kick_reason: 'Your behaviour is not conducive to the desired environment.',
            shared_input: false,
            show_message_info: true,
            who_loop: true,
            share_typing: true,
            // flash_title: message/highlight/off
            flash_title: 'message',
            nicklist_avatars: false,
            show_link_previews: true,
            inline_link_auto_previews: true,
            inline_link_auto_preview_whitelist: '.*',
        },
        // Startup screen default
        startupOptions: {
            server: '',
            port: 6667,
            tls: false,
            channel: '',
            nick: 'kiwi_?',
            direct: false,
            state_key: 'kiwi-state',
            remember_buffers: true,
            nick_format: '',
        },
        autoReconnect: false,
        disconnectOnSaslFail: true,
        allowRegisterProtocolHandler: false,
        noticeActiveBuffer: true,
        nicklistGroupAway: false,
        showChanlistModes: false,
        showAutocomplete: true,
        showEmojiPicker: true,
        showColorPicker: false,
        showSendButton: false,
        showAwayStatusIndicators: true,
        sidebarDefault: 'nicklist',
        showRaw: false,
        hideSettings: null,
        highlights: '',
        teamHighlights: false,
        aliases: `
# General aliases
/p /part $1+
/me /action $destination $1+
/j /join $1+
/q /query $1+
/w /whois $1+
/raw /quote $1+
/connect /server $1+
/cycle $channel? /lines /part $channel | /join $channel
/active /back $1+
/umode /mode $nick $1+

# Op related aliases
/op /quote mode $channel +o $1+
/deop /quote mode $channel -o $1+
/hop /quote mode $channel +h $1+
/dehop /quote mode $channel -h $1+
/voice /quote mode $channel +v $1+
/devoice /quote mode $channel -v $1+
/k /kick $channel $1+
/bans /mode $channel +b
/ban /quote mode $channel +b $1+
/unban /quote mode $channel -b $1+

# Misc aliases
/slap /me slaps $1 around a bit with a large trout
/tick /msg $channel ✔`,
        embedly: {
            Key: '',
        },
        /* eslint-disable quote-props */
        emojis: {
            '-___-': '1f611',
            ':\'-)': '1f602',
            '\':-)': '1f605',
            '\':-D': '1f605',
            '>:-)': '1f606',
            '\':-(': '1f613',
            '>:-(': '1f620',
            ':\'-(': '1f622',
            'O:-)': '1f607',
            '0:-3': '1f607',
            '0:-)': '1f607',
            '0;^)': '1f607',
            'O;-)': '1f607',
            '0;-)': '1f607',
            'O:-3': '1f607',
            '-__-': '1f611',
            ':-Þ': '1f61b',
            '<3': '2764',
            '</3': '1f494',
            ':\')': '1f602',
            ':-D': '1f603',
            '\':)': '1f605',
            '\'=)': '1f605',
            '\':D': '1f605',
            '\'=D': '1f605',
            '>:)': '1f606',
            '>;)': '1f606',
            '>=)': '1f606',
            'XD': '1f606',
            ';-)': '1f609',
            '*-)': '1f609',
            ';-]': '1f609',
            ';^)': '1f609',
            '\':(': '1f613',
            '\'=(': '1f613',
            ':-*': '1f618',
            ':^*': '1f618',
            '>:P': '1f61c',
            'X-P': '1f61c',
            '>:[': '1f61e',
            ':-(': '1f61e',
            ':-[': '1f61e',
            '>:(': '1f620',
            ':\'(': '1f622',
            ';-(': '1f622',
            '>.<': '1f623',
            '#-)': '1f635',
            '%-)': '1f635',
            'X-)': '1f635',
            '\\0/': '1f646',
            '\\O/': '1f646',
            '0:3': '1f607',
            '0:)': '1f607',
            'O:)': '1f607',
            'O=)': '1f607',
            'O:3': '1f607',
            'B-)': '1f60e',
            '8-)': '1f60e',
            'B-D': '1f60e',
            '8-D': '1f60e',
            '-_-': '1f611',
            '>:\\': '1f615',
            '>:/': '1f615',
            ':-/': '1f615',
            ':-.': '1f615',
            ':-P': '1f61b',
            ':Þ': '1f61b',
            ':-b': '1f61b',
            ':-O': '1f62e',
            'O_O': '1f62e',
            '>:O': '1f62e',
            ':-X': '1f636',
            ':-#': '1f636',
            ':-)': '1f642',
            '(y)': '1f44d',
            ':D': '1f603',
            '=D': '1f603',
            ';)': '1f609',
            '*)': '1f609',
            ';]': '1f609',
            ';D': '1f609',
            ':*': '1f618',
            '=*': '1f618',
            ':(': '1f61e',
            ':[': '1f61e',
            '=(': '1f61e',
            ':@': '1f620',
            ';(': '1f622',
            'D:': '1f628',
            ':$': '1f633',
            '=$': '1f633',
            '#)': '1f635',
            '%)': '1f635',
            'X)': '1f635',
            'B)': '1f60e',
            '8)': '1f60e',
            ':/': '1f615',
            ':\\': '1f615',
            '=/': '1f615',
            '=\\': '1f615',
            ':L': '1f615',
            '=L': '1f615',
            ':P': '1f61b',
            ':p': '1f61b',
            '=P': '1f61b',
            ':b': '1f61b',
            ':O': '1f62e',
            ':X': '1f636',
            ':#': '1f636',
            '=X': '1f636',
            '=#': '1f636',
            ':)': '1f642',
            '=]': '1f642',
            '=)': '1f642',
            ':]': '1f642',
        },
        emojiLocation: 'https://kiwiirc.com/shared/emoji/',
        textFormats: {
            user: '%nick',
            user_full: '%nick (%username@%host)',
            channel_join: '→ %text',
            channel_part: '← %text (%reason)',
            channel_quit: '← %text (%reason)',
            channel_kicked: '← %text (%reason)',
            channel_selfkick: '× %text (%reason)',
            channel_badpassword: '× %text',
            channel_topic: 'ⓘ %text',
            channel_banned: '× %text',
            channel_badkey: '⚠ %text',
            channel_inviteonly: '⚠ %channel %text',
            channel_alreadyin: '⚠ %nick %text',
            channel_limitreached: '⚠ %channel %text',
            channel_invalid_name: '⚠ %channel %text',
            channel_topic_setby: 'ⓘ %text',
            channel_has_been_invited: 'ⓘ %nick %text',
            server_connecting: '%text',
            server_connecting_error: '%text',
            mode: 'ⓘ %text',
            selfmode: 'ⓘ %nick %text',
            nickname_alreadyinuse: '⚠ %text',
            network_disconnected: '%text',
            network_connected: '%text',
            whois_channels: '%text',
            whois_idle_and_signon: '%text',
            whois_away: '%text',
            whois_server: '%text',
            whois_idle: '%text',
            whois_notfound: 'ⓘ %text',
            nick_changed: 'ⓘ %text',
            applet_notfound: '⚠ %text',
            encoding_changed: 'ⓘ %text',
            encoding_invalid: '⚠ %text',
            settings_saved: 'ⓘ %text',
            ignore_title: '%text:',
            ignore_none: '%text',
            ignore_nick: '%text',
            ignore_stop_notice: '%text',
            ignore_stopped: '%text',
            chanop_privs_needed: '⚠ %text',
            no_such_nick: 'ⓘ %nick: %text',
            unknown_command: 'ⓘ %text',
            motd: '%text',
            ctcp_response: '[CTCP %nick reply] %message',
            ctcp_request: '[CTCP %nick] %message',
            privmsg: '%text',
            notice: '%text',
            action: '* %nick %text',
            whois_ident: '%nick [%nick!%ident@%host] * %text',
            whois_error: '[%nick] %text',
            whois: '%text',
            whowas_ident: 'was [%nick!%ident@%host] * %name',
            whowas_server: 'using %server (%info)',
            whowas_error: '[%nick] %text',
            who: '%nick [%nick!%ident@%host] * %realname',
            quit: '%text',
            rejoin: '%text',
            set_setting: 'ⓘ %text',
            list_aliases: 'ⓘ %text',
            ignored_pattern: 'ⓘ %text',
            wallops: '[WALLOPS] %text',
            message_nick: '%prefix%nick',
            general_error: '%text',
        },
        presetNetworks: [],
    },

    // Config template for those hardcore irc veterans
    irc: {
        showEmojiPicker: false,
        sidebarDefault: 'nicklist',
        buffers: {
            messageLayout: 'inline',
            show_hostnames: true,
            coloured_nicklist: false,
            colour_nicknames_in_messages: false,
            show_emoticons: false,
            show_message_info: false,
            share_typing: false,
            inline_link_auto_previews: false,
        },
    },

    // Config template for working as part of a team
    team: {
        teamHighlights: true,
        buffers: {
            messageLayout: 'modern',
            show_joinparts: false,
            show_nick_changes: true,
            show_mode_changes: true,
            show_realnames: true,
        },
    },

};
<commit_msg>/disconnect -> /quit alias #1336<commit_after>/**
 * Configuration templates
 *
 * All the default values for config options throughout kiwi are set here, under
 * the 'default' template object below.
 * If a 'default.template' value is set in the user config, this is used to
 * find the next template object below and is merged over the default config
 * template.
 * The user config (config.json by default) is then merged over the resulting
 * config object.
 *
 * The advanced settings dialog also displays these settings by iterating
 * through the keys. The values must not be null otherwise they will not be
 * shown.
 */

export const configTemplates = {

    default: {
        plugins: [],
        windowTitle: 'Kiwi IRC - The web IRC client',
        useMonospace: false,
        language: '',
        theme: 'Default',
        themes: [
            { name: 'Default', url: 'static/themes/default' },
        ],
        // Restricted to a single IRC server
        restricted: true,
        // The startup screen
        startupScreen: 'customServer',
        // Where to find the kiwi server
        kiwiServer: '/webirc/kiwiirc/',
        // If active, all connections will be routed via this BNC server. Network settings
        // will be read and updated to the BNC as they are changed.
        bnc: {
            active: false,
            server: '',
            port: 6667,
            tls: false,
            path: '',
            username: '',
            password: '',
        },
        warnOnExit: true,
        // Default buffer settings
        buffers: {
            messageLayout: 'modern',
            alert_on: 'highlight',
            timestamp_format: '%H:%M:%S',
            // If timestamp_full_format is falsy, the browsers locale date format will be used
            timestamp_full_format: '',
            show_timestamps: true,
            scrollback_size: 250,
            show_hostnames: false,
            show_joinparts: true,
            show_topics: true,
            show_nick_changes: true,
            show_mode_changes: true,
            traffic_as_activity: false,
            coloured_nicklist: true,
            colour_nicknames_in_messages: true,
            block_pms: false,
            show_emoticons: true,
            extra_formatting: true,
            mute_sound: false,
            hide_message_counts: false,
            show_realnames: false,
            default_ban_mask: '*!%i@%h',
            default_kick_reason: 'Your behaviour is not conducive to the desired environment.',
            shared_input: false,
            show_message_info: true,
            who_loop: true,
            share_typing: true,
            // flash_title: message/highlight/off
            flash_title: 'message',
            nicklist_avatars: false,
            show_link_previews: true,
            inline_link_auto_previews: true,
            inline_link_auto_preview_whitelist: '.*',
        },
        // Startup screen default
        startupOptions: {
            server: '',
            port: 6667,
            tls: false,
            channel: '',
            nick: 'kiwi_?',
            direct: false,
            state_key: 'kiwi-state',
            remember_buffers: true,
            nick_format: '',
        },
        autoReconnect: false,
        disconnectOnSaslFail: true,
        allowRegisterProtocolHandler: false,
        noticeActiveBuffer: true,
        nicklistGroupAway: false,
        showChanlistModes: false,
        showAutocomplete: true,
        showEmojiPicker: true,
        showColorPicker: false,
        showSendButton: false,
        showAwayStatusIndicators: true,
        sidebarDefault: 'nicklist',
        showRaw: false,
        hideSettings: null,
        highlights: '',
        teamHighlights: false,
        aliases: `
# General aliases
/p /part $1+
/me /action $destination $1+
/j /join $1+
/q /query $1+
/w /whois $1+
/raw /quote $1+
/connect /server $1+
/disconnect /quit $1+
/cycle $channel? /lines /part $channel | /join $channel
/active /back $1+
/umode /mode $nick $1+

# Op related aliases
/op /quote mode $channel +o $1+
/deop /quote mode $channel -o $1+
/hop /quote mode $channel +h $1+
/dehop /quote mode $channel -h $1+
/voice /quote mode $channel +v $1+
/devoice /quote mode $channel -v $1+
/k /kick $channel $1+
/bans /mode $channel +b
/ban /quote mode $channel +b $1+
/unban /quote mode $channel -b $1+

# Misc aliases
/slap /me slaps $1 around a bit with a large trout
/tick /msg $channel ✔`,
        embedly: {
            Key: '',
        },
        /* eslint-disable quote-props */
        emojis: {
            '-___-': '1f611',
            ':\'-)': '1f602',
            '\':-)': '1f605',
            '\':-D': '1f605',
            '>:-)': '1f606',
            '\':-(': '1f613',
            '>:-(': '1f620',
            ':\'-(': '1f622',
            'O:-)': '1f607',
            '0:-3': '1f607',
            '0:-)': '1f607',
            '0;^)': '1f607',
            'O;-)': '1f607',
            '0;-)': '1f607',
            'O:-3': '1f607',
            '-__-': '1f611',
            ':-Þ': '1f61b',
            '<3': '2764',
            '</3': '1f494',
            ':\')': '1f602',
            ':-D': '1f603',
            '\':)': '1f605',
            '\'=)': '1f605',
            '\':D': '1f605',
            '\'=D': '1f605',
            '>:)': '1f606',
            '>;)': '1f606',
            '>=)': '1f606',
            'XD': '1f606',
            ';-)': '1f609',
            '*-)': '1f609',
            ';-]': '1f609',
            ';^)': '1f609',
            '\':(': '1f613',
            '\'=(': '1f613',
            ':-*': '1f618',
            ':^*': '1f618',
            '>:P': '1f61c',
            'X-P': '1f61c',
            '>:[': '1f61e',
            ':-(': '1f61e',
            ':-[': '1f61e',
            '>:(': '1f620',
            ':\'(': '1f622',
            ';-(': '1f622',
            '>.<': '1f623',
            '#-)': '1f635',
            '%-)': '1f635',
            'X-)': '1f635',
            '\\0/': '1f646',
            '\\O/': '1f646',
            '0:3': '1f607',
            '0:)': '1f607',
            'O:)': '1f607',
            'O=)': '1f607',
            'O:3': '1f607',
            'B-)': '1f60e',
            '8-)': '1f60e',
            'B-D': '1f60e',
            '8-D': '1f60e',
            '-_-': '1f611',
            '>:\\': '1f615',
            '>:/': '1f615',
            ':-/': '1f615',
            ':-.': '1f615',
            ':-P': '1f61b',
            ':Þ': '1f61b',
            ':-b': '1f61b',
            ':-O': '1f62e',
            'O_O': '1f62e',
            '>:O': '1f62e',
            ':-X': '1f636',
            ':-#': '1f636',
            ':-)': '1f642',
            '(y)': '1f44d',
            ':D': '1f603',
            '=D': '1f603',
            ';)': '1f609',
            '*)': '1f609',
            ';]': '1f609',
            ';D': '1f609',
            ':*': '1f618',
            '=*': '1f618',
            ':(': '1f61e',
            ':[': '1f61e',
            '=(': '1f61e',
            ':@': '1f620',
            ';(': '1f622',
            'D:': '1f628',
            ':$': '1f633',
            '=$': '1f633',
            '#)': '1f635',
            '%)': '1f635',
            'X)': '1f635',
            'B)': '1f60e',
            '8)': '1f60e',
            ':/': '1f615',
            ':\\': '1f615',
            '=/': '1f615',
            '=\\': '1f615',
            ':L': '1f615',
            '=L': '1f615',
            ':P': '1f61b',
            ':p': '1f61b',
            '=P': '1f61b',
            ':b': '1f61b',
            ':O': '1f62e',
            ':X': '1f636',
            ':#': '1f636',
            '=X': '1f636',
            '=#': '1f636',
            ':)': '1f642',
            '=]': '1f642',
            '=)': '1f642',
            ':]': '1f642',
        },
        emojiLocation: 'https://kiwiirc.com/shared/emoji/',
        textFormats: {
            user: '%nick',
            user_full: '%nick (%username@%host)',
            channel_join: '→ %text',
            channel_part: '← %text (%reason)',
            channel_quit: '← %text (%reason)',
            channel_kicked: '← %text (%reason)',
            channel_selfkick: '× %text (%reason)',
            channel_badpassword: '× %text',
            channel_topic: 'ⓘ %text',
            channel_banned: '× %text',
            channel_badkey: '⚠ %text',
            channel_inviteonly: '⚠ %channel %text',
            channel_alreadyin: '⚠ %nick %text',
            channel_limitreached: '⚠ %channel %text',
            channel_invalid_name: '⚠ %channel %text',
            channel_topic_setby: 'ⓘ %text',
            channel_has_been_invited: 'ⓘ %nick %text',
            server_connecting: '%text',
            server_connecting_error: '%text',
            mode: 'ⓘ %text',
            selfmode: 'ⓘ %nick %text',
            nickname_alreadyinuse: '⚠ %text',
            network_disconnected: '%text',
            network_connected: '%text',
            whois_channels: '%text',
            whois_idle_and_signon: '%text',
            whois_away: '%text',
            whois_server: '%text',
            whois_idle: '%text',
            whois_notfound: 'ⓘ %text',
            nick_changed: 'ⓘ %text',
            applet_notfound: '⚠ %text',
            encoding_changed: 'ⓘ %text',
            encoding_invalid: '⚠ %text',
            settings_saved: 'ⓘ %text',
            ignore_title: '%text:',
            ignore_none: '%text',
            ignore_nick: '%text',
            ignore_stop_notice: '%text',
            ignore_stopped: '%text',
            chanop_privs_needed: '⚠ %text',
            no_such_nick: 'ⓘ %nick: %text',
            unknown_command: 'ⓘ %text',
            motd: '%text',
            ctcp_response: '[CTCP %nick reply] %message',
            ctcp_request: '[CTCP %nick] %message',
            privmsg: '%text',
            notice: '%text',
            action: '* %nick %text',
            whois_ident: '%nick [%nick!%ident@%host] * %text',
            whois_error: '[%nick] %text',
            whois: '%text',
            whowas_ident: 'was [%nick!%ident@%host] * %name',
            whowas_server: 'using %server (%info)',
            whowas_error: '[%nick] %text',
            who: '%nick [%nick!%ident@%host] * %realname',
            quit: '%text',
            rejoin: '%text',
            set_setting: 'ⓘ %text',
            list_aliases: 'ⓘ %text',
            ignored_pattern: 'ⓘ %text',
            wallops: '[WALLOPS] %text',
            message_nick: '%prefix%nick',
            general_error: '%text',
        },
        presetNetworks: [],
    },

    // Config template for those hardcore irc veterans
    irc: {
        showEmojiPicker: false,
        sidebarDefault: 'nicklist',
        buffers: {
            messageLayout: 'inline',
            show_hostnames: true,
            coloured_nicklist: false,
            colour_nicknames_in_messages: false,
            show_emoticons: false,
            show_message_info: false,
            share_typing: false,
            inline_link_auto_previews: false,
        },
    },

    // Config template for working as part of a team
    team: {
        teamHighlights: true,
        buffers: {
            messageLayout: 'modern',
            show_joinparts: false,
            show_nick_changes: true,
            show_mode_changes: true,
            show_realnames: true,
        },
    },

};
<|endoftext|>


<commit_before>// markdown-it
window.mdc = window.markdownit({
  html: true,
  xhtmlOut: true, //
 instead of

  linkify: true
});

// Configuration for Gantt diagrams
mermaid.ganttConfig = {
  axisFormatter: [
    ["%-m/%-d", function (d) {
        return d.getDay() == 1;
    }]
  ]
};

// subscript & superscript
mdc = mdc.use(window.markdownitSub);
mdc = mdc.use(window.markdownitSup);

// footnote
mdc = mdc.use(window.markdownitFootnote);

// containers
mdc = mdc.use(window.markdownitContainer, 'success');
mdc = mdc.use(window.markdownitContainer, 'info');
mdc = mdc.use(window.markdownitContainer, 'warning');
mdc = mdc.use(window.markdownitContainer, 'danger');

// abbreviations
mdc = mdc.use(window.markdownitAbbr);

// definition list
mdc = mdc.use(window.markdownitDeflist);

// insert & mark
mdc = mdc.use(window.markdownitIns);
mdc = mdc.use(window.markdownitMark);

// icons
mdc = mdc.use(window.markdownitIcons);
emojione.cacheBustParam = ''; // change this to invalidate emojione icons cache
emojione.imagePathPNG = 'https://cdn.jsdelivr.net/emojione/assets/png/';
mdc.renderer.rules.emoji = function(token, idx) {
  var shortname = token[idx].markup;
  if(shortname.startsWith('fa-')) { // fontawesome
    return '';
  }
  if(shortname.startsWith('ion-')) { // ionicons
    return '';
  }
  return emojione.shortnameToImage(':' + shortname + ':'); // emojione
};

// task list
mdc.tokens = {};
mdc.renderer.renderToken = function(tokens, idx, options) {
  var tag = tokens[idx].type;
  if (tag.endsWith('_open')) {
    mdc.tokens[tag.substr(0, tag.length - 5)] = true;
  } else if (tag.endsWith('_close')) {
    mdc.tokens[tag.substr(0, tag.length - 6)] = false;
  }
  if(mdc.tokens['bullet_list'] == true && tag == 'list_item_open' && (tokens[idx+2].content.startsWith('[ ] ')||tokens[idx+2].content.startsWith('[x] '))) {
    tokens[idx].attrPush(['class', 'task-list-item']);
  }
  return mdc.renderer.constructor.prototype.renderToken.call(this, tokens, idx, options);
}
mdc.renderer.renderInline = function(tokens, options, env) {
  var result = mdc.renderer.constructor.prototype.renderInline.call(this, tokens, options, env);
  if(mdc.tokens['bullet_list'] == true && mdc.tokens['list_item'] == true) {
    if(result.startsWith('[ ] ')) {
      result = '<input type="checkbox" disabled /> ' + result.substring(4);
    } else if(result.startsWith('[x] ')) {
      result = '<input type="checkbox" disabled checked /> ' + result.substring(4);
    }
  }
  return result;
}

// inline math
mdc.renderer.rules.code_inline = function(token, idx) {
  var code = token[idx].content;
  if(code.startsWith('$') && code.endsWith('$')) { // inline math
    code = code.substr(1, code.length-2);
    try{
      return katex.renderToString(code);
    } catch(err) {
      return '' + err + '';
    }
  }
  return '' + code + ''; // not math
}

// math block
mdc.math_block = function(code) {
  var tex = '';
  code.split(/(?:\n\s*){2,}/).forEach(function(line) { // consecutive new lines means a new formula
    try {
      tex += katex.renderToString(line.trim(), { displayMode: true });
    } catch(err) {
      tex += '
' + err + '
';
    }
  });
  return '
' + tex + '
';
}

// mermaid charts
mermaid.parseError = function(err, hash){
  mdc.mermaidError = err;
};
mdc.mermaid_charts = function(code) {
  if(code.startsWith('sequenceDiagram')) {
    code += '\n'; // append empty line to the end, otherwise syntax error. It's a bug of mermaid.
  }
  if(mermaid.parse(code)) {
    return '
' + code + '
';
  } else {
    return '
' + mdc.mermaidError + '
';
  }
}

// fence block
mdc.renderer.rules.fence = function(token, idx) {
  var code = token[idx].content.trim();
  if(token[idx].info == 'math') { // math
    return mdc.math_block(code);
  }
  if(token[idx].info.length > 0) { // programming language
    return '
' + hljs.highlightAuto(code, [token[idx].info]).value + '
';
  }
  var firstLine = code.split(/\n/)[0].trim();
  if(firstLine === 'gantt' || firstLine === 'sequenceDiagram' || firstLine.match(/^graph (?:TB|BT|RL|LR|TD);?$/)) {
    return mdc.mermaid_charts(code) // mermaid
  }
  return '
' + hljs.highlightAuto(code).value + '
'; // unknown programming language
}

// code block
mdc.renderer.rules.code_block = function(token, idx) {
  var code = token[idx].content.trim();
  return '
' + hljs.highlightAuto(code).value + '
';
}

// convert markdown into HTML
mdc.init = function(markdown, debug) {
  var result = mdc.render(markdown);
  if(debug === true) {
    console.log(result);
  }
  $('article.markdown-body').html(result);
  if($('.mermaid').length > 0) {
    mermaid.init();
  }
}
<commit_msg>Refactor code about task list<commit_after>// markdown-it
window.mdc = window.markdownit({
  html: true,
  xhtmlOut: true, //
 instead of

  linkify: true
});

// Configuration for Gantt diagrams
mermaid.ganttConfig = {
  axisFormatter: [
    ["%-m/%-d", function (d) {
        return d.getDay() == 1;
    }]
  ]
};

// subscript & superscript
mdc = mdc.use(window.markdownitSub);
mdc = mdc.use(window.markdownitSup);

// footnote
mdc = mdc.use(window.markdownitFootnote);

// containers
mdc = mdc.use(window.markdownitContainer, 'success');
mdc = mdc.use(window.markdownitContainer, 'info');
mdc = mdc.use(window.markdownitContainer, 'warning');
mdc = mdc.use(window.markdownitContainer, 'danger');

// abbreviations
mdc = mdc.use(window.markdownitAbbr);

// definition list
mdc = mdc.use(window.markdownitDeflist);

// insert & mark
mdc = mdc.use(window.markdownitIns);
mdc = mdc.use(window.markdownitMark);

// icons
mdc = mdc.use(window.markdownitIcons);
emojione.cacheBustParam = ''; // change this to invalidate emojione icons cache
emojione.imagePathPNG = 'https://cdn.jsdelivr.net/emojione/assets/png/';
mdc.renderer.rules.emoji = function(token, idx) {
  var shortname = token[idx].markup;
  if(shortname.startsWith('fa-')) { // fontawesome
    return '';
  }
  if(shortname.startsWith('ion-')) { // ionicons
    return '';
  }
  return emojione.shortnameToImage(':' + shortname + ':'); // emojione
};

mdc.tokens = {};
mdc.renderer.renderToken = function(tokens, idx, options) {
  var tag = tokens[idx].type;
  if (tag.endsWith('_open')) {
    mdc.tokens[tag.substr(0, tag.length - 5)] = true;
  } else if (tag.endsWith('_close')) {
    mdc.tokens[tag.substr(0, tag.length - 6)] = false;
  }

  // task list
  if(mdc.tokens['bullet_list'] == true && tag == 'list_item_open' && (tokens[idx+2].content.startsWith('[ ] ') || tokens[idx+2].content.startsWith('[x] '))) {
    tokens[idx].attrPush(['class', 'task-list-item']);
    tokens[idx+2].children[0].content = tokens[idx+2].children[0].content.substring(4);
    if(tokens[idx+2].content.startsWith('[ ] ')) { // unfinished task
      return mdc.renderer.constructor.prototype.renderToken.call(this, tokens, idx, options) + '<input type="checkbox" disabled /> ';
    }
    // finished task
    return mdc.renderer.constructor.prototype.renderToken.call(this, tokens, idx, options) + '<input type="checkbox" disabled checked /> ';
  }

  return mdc.renderer.constructor.prototype.renderToken.call(this, tokens, idx, options);
}

// inline math
mdc.renderer.rules.code_inline = function(token, idx) {
  var code = token[idx].content;
  if(code.startsWith('$') && code.endsWith('$')) { // inline math
    code = code.substr(1, code.length-2);
    try{
      return katex.renderToString(code);
    } catch(err) {
      return '' + err + '';
    }
  }
  return '' + code + ''; // not math
}

// math block
mdc.math_block = function(code) {
  var tex = '';
  code.split(/(?:\n\s*){2,}/).forEach(function(line) { // consecutive new lines means a new formula
    try {
      tex += katex.renderToString(line.trim(), { displayMode: true });
    } catch(err) {
      tex += '
' + err + '
';
    }
  });
  return '
' + tex + '
';
}

// mermaid charts
mermaid.parseError = function(err, hash){
  mdc.mermaidError = err;
};
mdc.mermaid_charts = function(code) {
  if(code.startsWith('sequenceDiagram')) {
    code += '\n'; // append empty line to the end, otherwise syntax error. It's a bug of mermaid.
  }
  if(mermaid.parse(code)) {
    return '
' + code + '
';
  } else {
    return '
' + mdc.mermaidError + '
';
  }
}

// fence block
mdc.renderer.rules.fence = function(token, idx) {
  var code = token[idx].content.trim();
  if(token[idx].info == 'math') { // math
    return mdc.math_block(code);
  }
  if(token[idx].info.length > 0) { // programming language
    return '
' + hljs.highlightAuto(code, [token[idx].info]).value + '
';
  }
  var firstLine = code.split(/\n/)[0].trim();
  if(firstLine === 'gantt' || firstLine === 'sequenceDiagram' || firstLine.match(/^graph (?:TB|BT|RL|LR|TD);?$/)) {
    return mdc.mermaid_charts(code) // mermaid
  }
  return '
' + hljs.highlightAuto(code).value + '
'; // unknown programming language
}

// code block
mdc.renderer.rules.code_block = function(token, idx) {
  var code = token[idx].content.trim();
  return '
' + hljs.highlightAuto(code).value + '
';
}

// convert markdown into HTML
mdc.init = function(markdown, debug) {
  var result = mdc.render(markdown);
  if(debug === true) {
    console.log(result);
  }
  $('article.markdown-body').html(result);
  if($('.mermaid').length > 0) {
    mermaid.init();
  }
}
<|endoftext|>


<commit_before>var gulp = require('gulp');
var bower = require('gulp-bower');
var path = require('path');

// installs bower dependencies & pipes them into dist/lib
gulp.task('bower', function(cb) {
  return bower();
});<commit_msg>removing not used require<commit_after>var gulp = require('gulp');
var bower = require('gulp-bower');

// installs bower dependencies & pipes them into dist/lib
gulp.task('bower', function(cb) {
  return bower();
});<|endoftext|>


<commit_before>(function() {
  var root;
  if (typeof window !== 'undefined' && window !== null) {
    root = window;
  } else {
    root = global;
  }

  root.$IMA = root.$IMA || {};
  var modules = {};

  root.$IMA.Loader = {
    modules: modules,
    register: function(moduleName, dependencies, moduleFactory) {
      this.modules[moduleName] = {
        dependencies: dependencies,
        dependencyOf: [],
        factory: moduleFactory,
        instance: null
      };
    },
    replaceModule: function(moduleName, dependencies, moduleFactory) {
      var moduleDescriptor = this.modules[moduleName];
      if (!moduleDescriptor) {
        throw new Error(
          'You must register module "' + moduleName + '" at first.'
        );
      }

      Object.keys(this.modules).forEach(function(modulePath) {
        var module = root.$IMA.Loader.modules[modulePath];

        if (module.dependencies.indexOf(moduleName) > -1) {
          module.instance = null;
        }
      });

      moduleDescriptor.dependencies = dependencies;
      moduleDescriptor.factory = moduleFactory;
      moduleDescriptor.dependencyOf = [];
      moduleDescriptor.instance = null;

      return resolveModule(moduleName);
    },
    import: function(moduleName) {
      return Promise.resolve(this.importSync(moduleName));
    },
    importSync: function(moduleName) {
      if (!this.modules[moduleName]) {
        throw new Error(
          '$IMA.Loader.importSync: Module name ' +
            moduleName +
            ' is not registered. Update your build.js.'
        );
      }

      return resolveModule(moduleName);
    },
    initAllModules: function() {
      Object.keys(modules).forEach(function(moduleName) {
        resolveModule(moduleName);
      });

      return Promise.resolve();
    }
  };

  function resolveModule(moduleName, dependencyOf, parentDependencySetter) {
    if (!modules[moduleName]) {
      throw new Error(
        '$IMA.Loader.import: Module name ' +
          moduleName +
          (dependencyOf ? ' (dependency of ' + dependencyOf + ')' : '') +
          ' is not registered. Update your build.js.'
      );
    }

    var module = modules[moduleName];
    if (
      parentDependencySetter &&
      module.dependencyOf.indexOf(parentDependencySetter) === -1
    ) {
      // This is required for circular dependencies
      module.dependencyOf.push(parentDependencySetter);
    }
    if (module.instance) {
      return module.instance;
    }

    var moduleInstance = {};
    var moduleInitializer = module.factory(function _export(key, value) {
      moduleInstance[key] = value;
      // The exported values have been updated, notify the modules that
      // depend on this one - this is required for circular dependencies.
      module.dependencyOf.forEach(function(dependencySetter) {
        dependencySetter(moduleInstance);
      });
    });
    module.instance = moduleInstance; // allow lazy circular dependencies

    module.dependencies.forEach(function(dependencyName, index) {
      var resolvedName = resolveModuleName(moduleName, dependencyName);
      var setter = moduleInitializer.setters[index];
      var dependency = resolveModule(resolvedName, moduleName, setter);
      setter(dependency);
    });

    moduleInitializer.execute();

    return moduleInstance;
  }

  function resolveModuleName(currentModule, referencedModule) {
    var modulePath;
    if (referencedModule.substring(0, 2) === './') {
      if (currentModule.indexOf('/') > -1) {
        modulePath =
          currentModule.substring(0, currentModule.lastIndexOf('/')) +
          '/' +
          referencedModule.substring(2);
      } else {
        // the current module is in the application's root
        modulePath = referencedModule.substring(2);
      }
    } else if (referencedModule.substring(0, 3) === '../') {
      if (currentModule.indexOf('/') === -1) {
        throw new Error(
          'The ' +
            currentModule +
            ' module imports from the ' +
            'module ' +
            referencedModule +
            ' which may reside ' +
            'outside of the application directory'
        );
      }

      modulePath = currentModule.substring(0, currentModule.lastIndexOf('/'));
      modulePath =
        modulePath.substring(0, modulePath.lastIndexOf('/')) +
        '/' +
        referencedModule.substring(3);
    } else {
      return referencedModule;
    }

    modulePath = modulePath.replace(/\/\/+/g, '/');
    while (modulePath.indexOf('/./') > -1) {
      modulePath = modulePath.replace(/\/[.][/]/g, '/');
    }
    while (modulePath.indexOf('../') > -1) {
      if (modulePath.substring(0, 3) === '../') {
        throw new Error(
          'The ' +
            currentModule +
            ' module imports from the ' +
            'module ' +
            referencedModule +
            ' which may reside ' +
            'outside of the application directory'
        );
      }
      modulePath = modulePath.replace(/\/[^.][^/]*\/[.][.]\//g, '/');
      modulePath = modulePath.replace(/^[^.][^/]*\/[.][.]\//g, '');
    }
    modulePath = modulePath.replace(/^[.][/]/g, '');

    return modulePath;
  }
})();
<commit_msg>#! fixed file hot reloading for relative imports<commit_after>(function() {
  var root;
  if (typeof window !== 'undefined' && window !== null) {
    root = window;
  } else {
    root = global;
  }

  root.$IMA = root.$IMA || {};
  var modules = {};

  root.$IMA.Loader = {
    modules: modules,
    register: function(moduleName, dependencies, moduleFactory) {
      this.modules[moduleName] = {
        dependencies: dependencies,
        dependencyOf: [],
        factory: moduleFactory,
        instance: null
      };
    },
    replaceModule: function(moduleName, dependencies, moduleFactory) {
      var moduleDescriptor = this.modules[moduleName];
      if (!moduleDescriptor) {
        throw new Error(
          'You must register module "' + moduleName + '" at first.'
        );
      }

      Object.keys(this.modules).forEach(function(modulePath) {
        var module = root.$IMA.Loader.modules[modulePath];
        module.dependencies.forEach(dependency => {
          if (resolveModuleName(modulePath, dependency) === moduleName) {
            module.instance = null;
          }
        });
      });

      moduleDescriptor.dependencies = dependencies;
      moduleDescriptor.factory = moduleFactory;
      moduleDescriptor.dependencyOf = [];
      moduleDescriptor.instance = null;

      return resolveModule(moduleName);
    },
    import: function(moduleName) {
      return Promise.resolve(this.importSync(moduleName));
    },
    importSync: function(moduleName) {
      if (!this.modules[moduleName]) {
        throw new Error(
          '$IMA.Loader.importSync: Module name ' +
            moduleName +
            ' is not registered. Update your build.js.'
        );
      }

      return resolveModule(moduleName);
    },
    initAllModules: function() {
      Object.keys(modules).forEach(function(moduleName) {
        resolveModule(moduleName);
      });

      return Promise.resolve();
    }
  };

  function resolveModule(moduleName, dependencyOf, parentDependencySetter) {
    if (!modules[moduleName]) {
      throw new Error(
        '$IMA.Loader.import: Module name ' +
          moduleName +
          (dependencyOf ? ' (dependency of ' + dependencyOf + ')' : '') +
          ' is not registered. Update your build.js.'
      );
    }

    var module = modules[moduleName];
    if (
      parentDependencySetter &&
      module.dependencyOf.indexOf(parentDependencySetter) === -1
    ) {
      // This is required for circular dependencies
      module.dependencyOf.push(parentDependencySetter);
    }
    if (module.instance) {
      return module.instance;
    }

    var moduleInstance = {};
    var moduleInitializer = module.factory(function _export(key, value) {
      moduleInstance[key] = value;
      // The exported values have been updated, notify the modules that
      // depend on this one - this is required for circular dependencies.
      module.dependencyOf.forEach(function(dependencySetter) {
        dependencySetter(moduleInstance);
      });
    });
    module.instance = moduleInstance; // allow lazy circular dependencies

    module.dependencies.forEach(function(dependencyName, index) {
      var resolvedName = resolveModuleName(moduleName, dependencyName);
      var setter = moduleInitializer.setters[index];
      var dependency = resolveModule(resolvedName, moduleName, setter);
      setter(dependency);
    });

    moduleInitializer.execute();

    return moduleInstance;
  }

  function resolveModuleName(currentModule, referencedModule) {
    var modulePath;
    if (referencedModule.substring(0, 2) === './') {
      if (currentModule.indexOf('/') > -1) {
        modulePath =
          currentModule.substring(0, currentModule.lastIndexOf('/')) +
          '/' +
          referencedModule.substring(2);
      } else {
        // the current module is in the application's root
        modulePath = referencedModule.substring(2);
      }
    } else if (referencedModule.substring(0, 3) === '../') {
      if (currentModule.indexOf('/') === -1) {
        throw new Error(
          'The ' +
            currentModule +
            ' module imports from the ' +
            'module ' +
            referencedModule +
            ' which may reside ' +
            'outside of the application directory'
        );
      }

      modulePath = currentModule.substring(0, currentModule.lastIndexOf('/'));
      modulePath =
        modulePath.substring(0, modulePath.lastIndexOf('/')) +
        '/' +
        referencedModule.substring(3);
    } else {
      return referencedModule;
    }

    modulePath = modulePath.replace(/\/\/+/g, '/');
    while (modulePath.indexOf('/./') > -1) {
      modulePath = modulePath.replace(/\/[.][/]/g, '/');
    }
    while (modulePath.indexOf('../') > -1) {
      if (modulePath.substring(0, 3) === '../') {
        throw new Error(
          'The ' +
            currentModule +
            ' module imports from the ' +
            'module ' +
            referencedModule +
            ' which may reside ' +
            'outside of the application directory'
        );
      }
      modulePath = modulePath.replace(/\/[^.][^/]*\/[.][.]\//g, '/');
      modulePath = modulePath.replace(/^[^.][^/]*\/[.][.]\//g, '');
    }
    modulePath = modulePath.replace(/^[.][/]/g, '');

    return modulePath;
  }
})();
<|endoftext|>


<commit_before>'use strict'

const RequestClient = require('./RequestClient')
const tokenStorage = require('./tokenStorage')

const _getName = (id) => {
  return id.split('-').map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(' ')
}

module.exports = class Provider extends RequestClient {
  constructor (uppy, opts) {
    super(uppy, opts)
    this.provider = opts.provider
    this.id = this.provider
    this.authProvider = opts.authProvider || this.provider
    this.name = this.opts.name || _getName(this.id)
    this.pluginId = this.opts.pluginId
    this.tokenKey = `companion-${this.pluginId}-auth-token`
  }

  headers () {
    return new Promise((resolve, reject) => {
      super.headers().then((headers) => {
        this.getAuthToken().then((token) => {
          resolve(Object.assign({}, headers, { 'uppy-auth-token': token }))
        })
      }).catch(reject)
    })
  }

  onReceiveResponse (response) {
    response = super.onReceiveResponse(response)
    const authenticated = response.status !== 401
    this.uppy.getPlugin(this.pluginId).setPluginState({ authenticated })
    return response
  }

  // @todo(i.olarewaju) consider whether or not this method should be exposed
  setAuthToken (token) {
    return this.uppy.getPlugin(this.pluginId).storage.setItem(this.tokenKey, token)
  }

  getAuthToken () {
    return this.uppy.getPlugin(this.pluginId).storage.getItem(this.tokenKey)
  }

  authUrl () {
    return `${this.hostname}/${this.id}/connect`
  }

  fileUrl (id) {
    return `${this.hostname}/${this.id}/get/${id}`
  }

  list (directory) {
    return this.get(`${this.id}/list/${directory || ''}`)
  }

  logout (redirect = location.href) {
    return new Promise((resolve, reject) => {
      this.get(`${this.id}/logout?redirect=${redirect}`)
        .then((res) => {
          this.uppy.getPlugin(this.pluginId).storage.removeItem(this.tokenKey)
            .then(() => resolve(res))
            .catch(reject)
        }).catch(reject)
    })
  }

  static initPlugin (plugin, opts, defaultOpts) {
    plugin.type = 'acquirer'
    plugin.files = []
    if (defaultOpts) {
      plugin.opts = Object.assign({}, defaultOpts, opts)
    }

    if (opts.serverUrl || opts.serverPattern) {
      throw new Error('`serverUrl` and `serverPattern` have been renamed to `companionUrl` and `companionAllowedHosts` respectively in 0.30.5 release. Please consult the docs (for example, https://uppy.io/docs/instagram/ for Instagram plugin) and use the updated options.`')
    }

    if (opts.companionAllowedHosts) {
      const pattern = opts.companionAllowedHosts
      // validate companionAllowedHosts param
      if (typeof pattern !== 'string' && !Array.isArray(pattern) && !(pattern instanceof RegExp)) {
        throw new TypeError(`${plugin.id}: the option "companionAllowedHosts" must be one of string, Array, RegExp`)
      }
      plugin.opts.companionAllowedHosts = pattern
    } else {
      // does not start with https://
      if (/^(?!https?:\/\/).*$/i.test(opts.companionUrl)) {
        plugin.opts.companionAllowedHosts = `https://${opts.companionUrl.replace(/^\/\//, '')}`
      } else {
        plugin.opts.companionAllowedHosts = opts.companionUrl
      }
    }

    plugin.storage = plugin.opts.storage || tokenStorage
  }
}
<commit_msg>Update Provider.js<commit_after>'use strict'

const RequestClient = require('./RequestClient')
const tokenStorage = require('./tokenStorage')

const _getName = (id) => {
  return id.split('-').map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(' ')
}

module.exports = class Provider extends RequestClient {
  constructor (uppy, opts) {
    super(uppy, opts)
    this.provider = opts.provider
    this.id = this.provider
    this.authProvider = opts.authProvider || this.provider
    this.name = this.opts.name || _getName(this.id)
    this.pluginId = this.opts.pluginId
    this.tokenKey = `companion-${this.pluginId}-auth-token`
  }

  headers () {
    return new Promise((resolve, reject) => {
      super.headers().then((headers) => {
        this.getAuthToken().then((token) => {
          resolve(Object.assign({}, headers, { 'uppy-auth-token': token }))
        })
      }).catch(reject)
    })
  }

  onReceiveResponse (response) {
    response = super.onReceiveResponse(response)
    const authenticated = response.status !== 401
    this.uppy.getPlugin(this.pluginId).setPluginState({ authenticated })
    return response
  }

  // @todo(i.olarewaju) consider whether or not this method should be exposed
  setAuthToken (token) {
    return this.uppy.getPlugin(this.pluginId).storage.setItem(this.tokenKey, token)
  }

  getAuthToken () {
    return this.uppy.getPlugin(this.pluginId).storage.getItem(this.tokenKey)
  }

  authUrl () {
    return `${this.hostname}/${this.id}/connect`
  }

  fileUrl (id) {
    return `${this.hostname}/${this.id}/get/${id}`
  }

  list (directory) {
    return this.get(`${this.id}/list/${directory || ''}`)
  }

  logout (redirect = location.href) {
    return new Promise((resolve, reject) => {
      this.get(`${this.id}/logout?redirect=${redirect}`)
        .then((res) => {
          this.uppy.getPlugin(this.pluginId).storage.removeItem(this.tokenKey)
            .then(() => resolve(res))
            .catch(reject)
        }).catch(reject)
    })
  }

  static initPlugin (plugin, opts, defaultOpts) {
    plugin.type = 'acquirer'
    plugin.files = []
    if (defaultOpts) {
      plugin.opts = Object.assign({}, defaultOpts, opts)
    }

    if (opts.serverUrl || opts.serverPattern) {
      throw new Error('`serverUrl` and `serverPattern` have been renamed to `companionUrl` and `companionAllowedHosts` respectively in the 0.30.5 release. Please consult the docs (for example, https://uppy.io/docs/instagram/ for the Instagram plugin) and use the updated options.`')
    }

    if (opts.companionAllowedHosts) {
      const pattern = opts.companionAllowedHosts
      // validate companionAllowedHosts param
      if (typeof pattern !== 'string' && !Array.isArray(pattern) && !(pattern instanceof RegExp)) {
        throw new TypeError(`${plugin.id}: the option "companionAllowedHosts" must be one of string, Array, RegExp`)
      }
      plugin.opts.companionAllowedHosts = pattern
    } else {
      // does not start with https://
      if (/^(?!https?:\/\/).*$/i.test(opts.companionUrl)) {
        plugin.opts.companionAllowedHosts = `https://${opts.companionUrl.replace(/^\/\//, '')}`
      } else {
        plugin.opts.companionAllowedHosts = opts.companionUrl
      }
    }

    plugin.storage = plugin.opts.storage || tokenStorage
  }
}
<|endoftext|>


<commit_before>import express from 'express';
import createWebpackMiddleware from 'webpack-dev-middleware';
import createWebpackHotMiddleware from 'webpack-hot-middleware';
import ListenerManager from './listenerManager';
import { log } from '../utils';

class HotClientServer {
  constructor(compiler) {
    const app = express();

    const httpPathRegex = /^https?:\/\/(.*):([\d]{1,5})/i;
    const httpPath = compiler.options.output.publicPath;
    if (!httpPath.startsWith('http') && !httpPathRegex.test(httpPath)) {
      throw new Error(
        'You must supply an absolute public path to a development build of a web target bundle as it will be hosted on a seperate development server to any node target bundles.',
      );
    }

    // eslint-disable-next-line no-unused-vars
    const [_, host, port] = httpPathRegex.exec(httpPath);

    this.webpackDevMiddleware = createWebpackMiddleware(compiler, {
      quiet: true,
      noInfo: true,
      headers: {
        'Access-Control-Allow-Origin': '*',
      },
      // Ensure that the public path is taken from the compiler webpack config
      // as it will have been created as an absolute path to avoid conflicts
      // with an node servers.
      publicPath: compiler.options.output.publicPath,
    });

    app.use(this.webpackDevMiddleware);
    app.use(createWebpackHotMiddleware(compiler));

    const listener = app.listen(port, host);

    this.listenerManager = new ListenerManager(listener, 'client');

    compiler.plugin('compile', () => {
      log({
        title: 'client',
        level: 'info',
        message: 'Building new bundle...',
      });
    });

    compiler.plugin('done', (stats) => {
      if (stats.hasErrors()) {
        log({
          title: 'client',
          level: 'error',
          message: 'Build failed, please check the console for more information.',
          notify: true,
        });
        console.error(stats.toString());
      } else {
        log({
          title: 'client',
          level: 'info',
          message: 'Running with latest changes.',
          notify: true,
        });
      }
    });
  }

  dispose() {
    this.webpackDevMiddleware.close();

    return this.listenerManager ? this.listenerManager.dispose() : Promise.resolve();
  }
}

export default HotClientServer;
<commit_msg>dev server host always 0.0.0.0, not host config<commit_after>import express from 'express';
import createWebpackMiddleware from 'webpack-dev-middleware';
import createWebpackHotMiddleware from 'webpack-hot-middleware';
import ListenerManager from './listenerManager';
import { log } from '../utils';

class HotClientServer {
  constructor(compiler) {
    const app = express();

    const httpPathRegex = /^https?:\/\/(.*):([\d]{1,5})/i;
    const httpPath = compiler.options.output.publicPath;
    if (!httpPath.startsWith('http') && !httpPathRegex.test(httpPath)) {
      throw new Error(
        'You must supply an absolute public path to a development build of a web target bundle as it will be hosted on a seperate development server to any node target bundles.',
      );
    }

    // eslint-disable-next-line no-unused-vars
    const [_, host, port] = httpPathRegex.exec(httpPath);

    this.webpackDevMiddleware = createWebpackMiddleware(compiler, {
      quiet: true,
      noInfo: true,
      headers: {
        'Access-Control-Allow-Origin': '*',
      },
      // Ensure that the public path is taken from the compiler webpack config
      // as it will have been created as an absolute path to avoid conflicts
      // with an node servers.
      publicPath: compiler.options.output.publicPath,
    });

    app.use(this.webpackDevMiddleware);
    app.use(createWebpackHotMiddleware(compiler));

    const listener = app.listen(port);

    this.listenerManager = new ListenerManager(listener, 'client');

    compiler.plugin('compile', () => {
      log({
        title: 'client',
        level: 'info',
        message: 'Building new bundle...',
      });
    });

    compiler.plugin('done', (stats) => {
      if (stats.hasErrors()) {
        log({
          title: 'client',
          level: 'error',
          message: 'Build failed, please check the console for more information.',
          notify: true,
        });
        console.error(stats.toString());
      } else {
        log({
          title: 'client',
          level: 'info',
          message: 'Running with latest changes.',
          notify: true,
        });
      }
    });
  }

  dispose() {
    this.webpackDevMiddleware.close();

    return this.listenerManager ? this.listenerManager.dispose() : Promise.resolve();
  }
}

export default HotClientServer;
<|endoftext|>


<commit_before>/***** BEGIN LICENSE BLOCK ***** {{{
 *
 * Mozilla Public License Notice
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1  (the "License"); you may  not use this  file except in
 * compliance with the  License. You may obtain a  copy of the License
 * at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the  License  for  the   specific  language  governing  rights  and
 * limitations under the License.
 *
}}} ***** END LICENSE BLOCK *****/

// command names taken from:
// http://developer.mozilla.org/en/docs/Editor_Embedding_Guide

function Editor() //{{{
{
    // store our last search with f,F,t or T
    var last_findChar = null;
    var last_findChar_func = null;

    function editor()
    {
        var editor = window.document.commandDispatcher.focusedElement;
        if (editor && editor.mInputField)
            editor = editor.mInputField;
        return editor;
    }

    function getController()
    {
        var editor = editor();
        if (!editor || !editor.controllers)
            return null;

        return editor.controllers.getControllerAt(0);
    }

    this.line = function()
    {
        var line = 1;
        var text = editor().value;
        for (var i = 0; i < editor().selectionStart; i++)
            if (text[i] == "\n")
                line++;
        return line;
    }

    this.col = function()
    {
        var col = 1;
        var text = editor().value;
        for (var i = 0; i < editor().selectionStart; i++)
        {
            col++;
            if (text[i] == "\n")
                col = 1;
        }
        return col;
    }

    this.unselectText = function()
    {
        var elt = window.document.commandDispatcher.focusedElement;
        if (elt && elt.selectionEnd)
            elt.selectionEnd = elt.selectionStart;
    }

    this.selectedText = function()
    {
        var text = editor().value;
        return text.substring(editor().selectionStart, editor().selectionEnd);
    }

    this.pasteClipboard = function()
    {
        var elt = window.document.commandDispatcher.focusedElement;

        if (elt.setSelectionRange && readFromClipboard())
            // readFromClipboard would return 'undefined' if not checked
            // dunno about .setSelectionRange
        {
            var rangeStart = elt.selectionStart; // caret position
            var rangeEnd = elt.selectionEnd;
            var tempStr1 = elt.value.substring(0,rangeStart);
            var tempStr2 = readFromClipboard();
            var tempStr3 = elt.value.substring(rangeEnd);
            elt.value = tempStr1 + tempStr2  + tempStr3;
            elt.selectionStart = rangeStart + tempStr2.length;
            elt.selectionEnd = elt.selectionStart;
        }
    }

    // count is optional, defaults to 1
    this.executeCommand = function(cmd, count)
    {
        var controller = getController();
        var el = window.document.commandDispatcher.focusedElement;
        if (!controller || !el)
            return false;

        if (!controller.supportsCommand(cmd) || !controller.isCommandEnabled(cmd))
        {
            vimperator.beep();
            return false;
        }

        if (typeof count != "number" || count < 1)
            count = 1;

        var did_command = false;
        while(count--)
        {
            // some commands need this try/catch workaround, because a cmd_charPrevious triggered
            // at the beginning of the textarea, would hang the doCommand()
            // good thing is, we need this code anyway for proper beeping
            try
            {
                controller.doCommand(cmd);
                did_command = true;
            }
            catch(e)
            {
                if (!did_command)
                    vimperator.beep();
                return false;
            }
        }

        return true;
    }

    // cmd = y, d, c
    // motion = b, 0, gg, G, etc.
    this.executeCommandWithMotion = function(cmd, motion, count)
    {
        if (!typeof count == "number" || count < 1)
            count = 1;

        if (cmd == motion)
        {
            motion = "j";
            count--;
        }

        vimperator.modes.set(vimperator.modes.VISUAL, vimperator.modes.TEXTAREA);

        switch (motion)
        {
            case "j":
                this.executeCommand("cmd_beginLine", 1);
                this.executeCommand("cmd_selectLineNext", count+1);
                break;
            case "k":
                this.executeCommand("cmd_beginLine", 1);
                this.executeCommand("cmd_lineNext", 1);
                this.executeCommand("cmd_selectLinePrevious", count+1);
                break;
            case "h":
                this.executeCommand("cmd_selectCharPrevious", count);
                break;
            case "l":
                this.executeCommand("cmd_selectCharNext", count);
                break;
            case "e":
            case "w":
                this.executeCommand("cmd_selectWordNext", count);
                break;
            case "b":
                this.executeCommand("cmd_selectWordPrevious", count);
                break;
            case "0":
            case "^":
                this.executeCommand("cmd_selectBeginLine", 1);
                break;
            case "$":
                this.executeCommand("cmd_selectEndLine", 1);
                break;
            case "gg":
                this.executeCommand("cmd_endLine", 1);
                this.executeCommand("cmd_selectTop", 1);
                this.executeCommand("cmd_selectBeginLine", 1);
                break;
            case "G":
                this.executeCommand("cmd_beginLine", 1);
                this.executeCommand("cmd_selectBottom", 1);
                this.executeCommand("cmd_selectEndLine", 1);
                break;

            default:
                vimperator.beep();
                return false;
        }

        switch (cmd)
        {
            case "d":
                this.executeCommand("cmd_delete", 1);
                // need to reset the mode as the visual selection changes it
                vimperator.modes.main = vimperator.modes.TEXTAREA;
                break;
            case "c":
                this.executeCommand("cmd_delete", 1);
                vimperator.modes.set(vimperator.modes.INSERT, vimperator.modes.TEXTAREA);
                break;
            case "y":
                this.executeCommand("cmd_copy", 1);
                this.unselectText();
                break;

            default:
                vimperator.beep();
                return false;
        }
        return true;
    }

    // This function will move/select up to given "pos"
    // Simple setSelectionRange() would be better, but we want to maintain the correct
    // order of selectionStart/End (a firefox bug always makes selectionStart <= selectionEnd)
    // Use only for small movements!
    this.moveToPosition = function(pos, forward, select)
    {
        if (!select)
        {
            editor().setSelectionRange(pos, pos);
            return;
        }

        if (forward)
        {
            if (pos <= editor().selectionEnd || pos > editor().value.length)
                return false;

            do // TODO: test code for endless loops
            {
                this.executeCommand("cmd_selectCharNext", 1);
            }
            while ( editor().selectionEnd != pos );
        }
        else
        {
            if (pos >= editor().selectionStart || pos < 0)
                return false;

            do // TODO: test code for endless loops
            {
                this.executeCommand("cmd_selectCharPrevious", 1);
            }
            while ( editor().selectionStart != pos );
        }
    }

    // returns the position of char
    this.findCharForward = function(char, count)
    {
        if (!editor())
            return -1;

        last_findChar = char;
        last_findChar_func = this.findCharForward;

        var text = editor().value;
        if (!typeof count == "number" || count < 1)
            count = 1;

        for (var i = editor().selectionEnd + 1; i < text.length; i++)
        {
            if (text[i] == "\n")
                break;
            if (text[i] == char)
                count--;
            if (count == 0)
                return i + 1; // always position the cursor after the char
        }

        vimperator.beep();
        return -1;
    }
    // returns the position of char
    this.findCharBackward = function(char, count)
    {
        if (!editor())
            return -1;

        last_findChar = char;
        last_findChar_func = this.findCharBackward;

        var text = editor().value;
        if (!typeof count == "number" || count < 1)
            count = 1;

        for (var i = editor().selectionStart - 1; i >= 0; i--)
        {
            if (text[i] == "\n")
                break;
            if (text[i] == char)
                count--;
            if (count == 0)
                return i;
        }

        vimperator.beep();
        return -1;
    }

} //}}}

// vim: set fdm=marker sw=4 ts=4 et:
<commit_msg>fixed textarea/location bar keys properly (location bar still not working, when completion popup is open)<commit_after>/***** BEGIN LICENSE BLOCK ***** {{{
 *
 * Mozilla Public License Notice
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1  (the "License"); you may  not use this  file except in
 * compliance with the  License. You may obtain a  copy of the License
 * at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the  License  for  the   specific  language  governing  rights  and
 * limitations under the License.
 *
}}} ***** END LICENSE BLOCK *****/

// command names taken from:
// http://developer.mozilla.org/en/docs/Editor_Embedding_Guide

function Editor() //{{{
{
    // store our last search with f,F,t or T
    var last_findChar = null;
    var last_findChar_func = null;

    function editor()
    {
        return window.document.commandDispatcher.focusedElement;
    }

    function getController()
    {
        var ed = editor();
        if (!ed || !ed.controllers)
            return null;

        return ed.controllers.getControllerForCommand("cmd_beginLine");
    }

    this.line = function()
    {
        var line = 1;
        var text = editor().value;
        for (var i = 0; i < editor().selectionStart; i++)
            if (text[i] == "\n")
                line++;
        return line;
    }

    this.col = function()
    {
        var col = 1;
        var text = editor().value;
        for (var i = 0; i < editor().selectionStart; i++)
        {
            col++;
            if (text[i] == "\n")
                col = 1;
        }
        return col;
    }

    this.unselectText = function()
    {
        var elt = window.document.commandDispatcher.focusedElement;
        if (elt && elt.selectionEnd)
            elt.selectionEnd = elt.selectionStart;
    }

    this.selectedText = function()
    {
        var text = editor().value;
        return text.substring(editor().selectionStart, editor().selectionEnd);
    }

    this.pasteClipboard = function()
    {
        var elt = window.document.commandDispatcher.focusedElement;

        if (elt.setSelectionRange && readFromClipboard())
            // readFromClipboard would return 'undefined' if not checked
            // dunno about .setSelectionRange
        {
            var rangeStart = elt.selectionStart; // caret position
            var rangeEnd = elt.selectionEnd;
            var tempStr1 = elt.value.substring(0,rangeStart);
            var tempStr2 = readFromClipboard();
            var tempStr3 = elt.value.substring(rangeEnd);
            elt.value = tempStr1 + tempStr2  + tempStr3;
            elt.selectionStart = rangeStart + tempStr2.length;
            elt.selectionEnd = elt.selectionStart;
        }
    }

    // count is optional, defaults to 1
    this.executeCommand = function(cmd, count)
    {
        var controller = getController();
        if (!controller || !controller.supportsCommand(cmd) || !controller.isCommandEnabled(cmd))
        {
            vimperator.beep();
            return false;
        }

        if (typeof count != "number" || count < 1)
            count = 1;

        var did_command = false;
        while(count--)
        {
            // some commands need this try/catch workaround, because a cmd_charPrevious triggered
            // at the beginning of the textarea, would hang the doCommand()
            // good thing is, we need this code anyway for proper beeping
            try
            {
                controller.doCommand(cmd);
                did_command = true;
            }
            catch(e)
            {
                if (!did_command)
                    vimperator.beep();
                return false;
            }
        }

        return true;
    }

    // cmd = y, d, c
    // motion = b, 0, gg, G, etc.
    this.executeCommandWithMotion = function(cmd, motion, count)
    {
        if (!typeof count == "number" || count < 1)
            count = 1;

        if (cmd == motion)
        {
            motion = "j";
            count--;
        }

        vimperator.modes.set(vimperator.modes.VISUAL, vimperator.modes.TEXTAREA);

        switch (motion)
        {
            case "j":
                this.executeCommand("cmd_beginLine", 1);
                this.executeCommand("cmd_selectLineNext", count+1);
                break;
            case "k":
                this.executeCommand("cmd_beginLine", 1);
                this.executeCommand("cmd_lineNext", 1);
                this.executeCommand("cmd_selectLinePrevious", count+1);
                break;
            case "h":
                this.executeCommand("cmd_selectCharPrevious", count);
                break;
            case "l":
                this.executeCommand("cmd_selectCharNext", count);
                break;
            case "e":
            case "w":
                this.executeCommand("cmd_selectWordNext", count);
                break;
            case "b":
                this.executeCommand("cmd_selectWordPrevious", count);
                break;
            case "0":
            case "^":
                this.executeCommand("cmd_selectBeginLine", 1);
                break;
            case "$":
                this.executeCommand("cmd_selectEndLine", 1);
                break;
            case "gg":
                this.executeCommand("cmd_endLine", 1);
                this.executeCommand("cmd_selectTop", 1);
                this.executeCommand("cmd_selectBeginLine", 1);
                break;
            case "G":
                this.executeCommand("cmd_beginLine", 1);
                this.executeCommand("cmd_selectBottom", 1);
                this.executeCommand("cmd_selectEndLine", 1);
                break;

            default:
                vimperator.beep();
                return false;
        }

        switch (cmd)
        {
            case "d":
                this.executeCommand("cmd_delete", 1);
                // need to reset the mode as the visual selection changes it
                vimperator.modes.main = vimperator.modes.TEXTAREA;
                break;
            case "c":
                this.executeCommand("cmd_delete", 1);
                vimperator.modes.set(vimperator.modes.INSERT, vimperator.modes.TEXTAREA);
                break;
            case "y":
                this.executeCommand("cmd_copy", 1);
                this.unselectText();
                break;

            default:
                vimperator.beep();
                return false;
        }
        return true;
    }

    // This function will move/select up to given "pos"
    // Simple setSelectionRange() would be better, but we want to maintain the correct
    // order of selectionStart/End (a firefox bug always makes selectionStart <= selectionEnd)
    // Use only for small movements!
    this.moveToPosition = function(pos, forward, select)
    {
        if (!select)
        {
            editor().setSelectionRange(pos, pos);
            return;
        }

        if (forward)
        {
            if (pos <= editor().selectionEnd || pos > editor().value.length)
                return false;

            do // TODO: test code for endless loops
            {
                this.executeCommand("cmd_selectCharNext", 1);
            }
            while ( editor().selectionEnd != pos );
        }
        else
        {
            if (pos >= editor().selectionStart || pos < 0)
                return false;

            do // TODO: test code for endless loops
            {
                this.executeCommand("cmd_selectCharPrevious", 1);
            }
            while ( editor().selectionStart != pos );
        }
    }

    // returns the position of char
    this.findCharForward = function(char, count)
    {
        if (!editor())
            return -1;

        last_findChar = char;
        last_findChar_func = this.findCharForward;

        var text = editor().value;
        if (!typeof count == "number" || count < 1)
            count = 1;

        for (var i = editor().selectionEnd + 1; i < text.length; i++)
        {
            if (text[i] == "\n")
                break;
            if (text[i] == char)
                count--;
            if (count == 0)
                return i + 1; // always position the cursor after the char
        }

        vimperator.beep();
        return -1;
    }
    // returns the position of char
    this.findCharBackward = function(char, count)
    {
        if (!editor())
            return -1;

        last_findChar = char;
        last_findChar_func = this.findCharBackward;

        var text = editor().value;
        if (!typeof count == "number" || count < 1)
            count = 1;

        for (var i = editor().selectionStart - 1; i >= 0; i--)
        {
            if (text[i] == "\n")
                break;
            if (text[i] == char)
                count--;
            if (count == 0)
                return i;
        }

        vimperator.beep();
        return -1;
    }

} //}}}

// vim: set fdm=marker sw=4 ts=4 et:
<|endoftext|>