<commit_before>/*
Copyright 2017 New Vector Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import sdk from '../../../index';
import {_t} from '../../../languageHandler';
import PropTypes from 'prop-types';
import dis from '../../../dispatcher';
import {wantsDateSeparator} from '../../../DateUtils';
import {MatrixEvent, MatrixClient} from 'matrix-js-sdk';
import {makeEventPermalink, makeUserPermalink} from "../../../matrix-to";
import SettingsStore from "../../../settings/SettingsStore";

// This component does no cycle detection, simply because the only way to make such a cycle would be to
// craft event_id's, using a homeserver that generates predictable event IDs; even then the impact would
// be low as each event being loaded (after the first) is triggered by an explicit user action.
export default class ReplyThread extends React.Component {
    static propTypes = {
        // the latest event in this chain of replies
        parentEv: PropTypes.instanceOf(MatrixEvent),
        // called when the ReplyThread contents has changed, including EventTiles thereof
        onWidgetLoad: PropTypes.func.isRequired,
    };

    static contextTypes = {
        matrixClient: PropTypes.instanceOf(MatrixClient).isRequired,
    };

    constructor(props, context) {
        super(props, context);

        this.state = {
            // The loaded events to be rendered as linear-replies
            events: [],

            // The latest loaded event which has not yet been shown
            loadedEv: null,
            // Whether the component is still loading more events
            loading: true,

            // Whether as error was encountered fetching a replied to event.
            err: false,
        };

        this.onQuoteClick = this.onQuoteClick.bind(this);
        this.canCollapse = this.canCollapse.bind(this);
        this.collapse = this.collapse.bind(this);
    }

    componentWillMount() {
        this.unmounted = false;
        this.room = this.context.matrixClient.getRoom(this.props.parentEv.getRoomId());
        this.initialize();
    }

    componentDidUpdate() {
        this.props.onWidgetLoad();
    }

    componentWillUnmount() {
        this.unmounted = true;
    }

    canCollapse() {
        return this.state.events.length > 1;
    }

    collapse() {
        this.initialize();
    }

    async initialize() {
        const {parentEv} = this.props;
        // at time of making this component we checked that props.parentEv has a parentEventId
        const ev = await ReplyThread.getEvent(this.room, ReplyThread.getParentEventId(parentEv));
        if (this.unmounted) return;

        if (ev) {
            this.setState({
                events: [ev],
            }, this.loadNextEvent);
        } else {
            this.setState({err: true});
        }
    }

    async loadNextEvent() {
        if (this.unmounted) return;
        const ev = this.state.events[0];
        const inReplyToEventId = ReplyThread.getParentEventId(ev);

        if (!inReplyToEventId) {
            this.setState({
                loading: false,
            });
            return;
        }

        const loadedEv = await ReplyThread.getEvent(this.room, inReplyToEventId);
        if (this.unmounted) return;

        if (loadedEv) {
            this.setState({loadedEv});
        } else {
            this.setState({err: true});
        }
    }

    static async getEvent(room, eventId) {
        const event = room.findEventById(eventId);
        if (event) return event;

        try {
            await this.context.matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId);
        } catch (e) {
            return null;
        }
        return room.findEventById(eventId);
    }

    onQuoteClick() {
        const events = [this.state.loadedEv, ...this.state.events];

        this.setState({
            loadedEv: null,
            events,
        }, this.loadNextEvent);

        dis.dispatch({action: 'focus_composer'});
    }

    static getParentEventId(ev) {
        if (!ev || ev.isRedacted()) return;

        const mRelatesTo = ev.getWireContent()['m.relates_to'];
        if (mRelatesTo && mRelatesTo['m.in_reply_to']) {
            const mInReplyTo = mRelatesTo['m.in_reply_to'];
            if (mInReplyTo && mInReplyTo['event_id']) return mInReplyTo['event_id'];
        }
    }

    // Part of Replies fallback support
    static stripPlainReply(body) {
        // Removes lines beginning with `> ` until you reach one that doesn't.
        const lines = body.split('\n');
        while (lines.length && lines[0].startsWith('> ')) lines.shift();
        // Reply fallback has a blank line after it, so remove it to prevent leading newline
        if (lines[0] === '') lines.shift();
        return lines.join('\n');
    }

    // Part of Replies fallback support
    static stripHTMLReply(html) {
        return html.replace(/^
[\s\S]+?<\/blockquote>/, '');
    }

    // Part of Replies fallback support
    static getNestedReplyText(ev) {
        if (!ev) return null;

        let {body, formatted_body: html} = ev.getContent();
        if (this.getParentEventId(ev)) {
            if (body) body = this.stripPlainReply(body);
            if (html) html = this.stripHTMLReply(html);
        }

        const evLink = makeEventPermalink(ev.getRoomId(), ev.getId());
        const userLink = makeUserPermalink(ev.getSender());
        const mxid = ev.getSender();

        // This fallback contains text that is explicitly EN.
        switch (ev.getContent().msgtype) {
            case 'm.text':
            case 'm.notice': {
                html = `<blockquote data-mx-reply><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>`
                     + `<br>${html || body}</blockquote>`;
                const lines = body.trim().split('\n');
                if (lines.length > 0) {
                    lines[0] = `<${mxid}> ${lines[0]}`;
                    body = lines.map((line) => `> ${line}`).join('\n') + '\n\n';
                }
                break;
            }
            case 'm.image':
                html = `<blockquote data-mx-reply><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>`
                     + `<br>sent an image.</blockquote>`;
                body = `> <${mxid}> sent an image.\n\n`;
                break;
            case 'm.video':
                html = `<blockquote data-mx-reply><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>`
                    + `<br>sent a video.</blockquote>`;
                body = `> <${mxid}> sent a video.\n\n`;
                break;
            case 'm.audio':
                html = `<blockquote data-mx-reply><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>`
                    + `<br>sent an audio file.</blockquote>`;
                body = `> <${mxid}> sent an audio file.\n\n`;
                break;
            case 'm.file':
                html = `<blockquote data-mx-reply><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>`
                    + `<br>sent a file.</blockquote>`;
                body = `> <${mxid}> sent a file.\n\n`;
                break;
            case 'm.emote': {
                html = `<blockquote data-mx-reply><a href="${evLink}">In reply to</a> * `
                    + `<a href="${userLink}">${mxid}</a><br>${html || body}</blockquote>`;
                const lines = body.trim().split('\n');
                if (lines.length > 0) {
                    lines[0] = `* <${mxid}> ${lines[0]}`;
                    body = lines.map((line) => `> ${line}`).join('\n') + '\n\n';
                }
                break;
            }
            default:
                return null;
        }

        return {body, html};
    }

    static makeReplyMixIn(ev) {
        if (!ev) return {};
        return {
            'm.relates_to': {
                'm.in_reply_to': {
                    'event_id': ev.getId(),
                },
            },
        };
    }

    static makeThread(parentEv, onWidgetLoad, ref) {
        if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !ReplyThread.getParentEventId(parentEv)) {
            return
;
        }
        return <ReplyThread parentEv={parentEv} onWidgetLoad={onWidgetLoad} ref={ref} />;
    }

    render() {
        let header = null;

        if (this.state.err) {
            header =

                {
                    _t('Unable to load event that was replied to, ' +
                        'it either does not exist or you do not have permission to view it.')
                }

;
        } else if (this.state.loadedEv) {
            const ev = this.state.loadedEv;
            const Pill = sdk.getComponent('elements.Pill');
            const room = this.context.matrixClient.getRoom(ev.getRoomId());
            header =

                {
                    _t('In reply to <pill>', {}, {
                        'a': (sub) => { sub },
                        'pill': <Pill type={Pill.TYPE_USER_MENTION} room={room}
                                      url={makeUserPermalink(ev.getSender())} shouldShowPillAvatar={true} />,
                    })
                }

;
        } else if (this.state.loading) {
            const Spinner = sdk.getComponent("elements.Spinner");
            header = <Spinner w={16} h={16} />;
        }

        const EventTile = sdk.getComponent('views.rooms.EventTile');
        const DateSeparator = sdk.getComponent('messages.DateSeparator');
        const evTiles = this.state.events.map((ev) => {
            let dateSep = null;

            if (wantsDateSeparator(this.props.parentEv.getDate(), ev.getDate())) {
                dateSep = <DateSeparator ts={ev.getTs()} />;
            }

            return

                { dateSep }
                <EventTile mxEvent={ev}
                           tileShape="reply"
                           onWidgetLoad={this.props.onWidgetLoad}
                           isTwelveHour={SettingsStore.getValue("showTwelveHourTimestamps")} />

;
        });

        return

{ header }

{ evTiles }

;
    }
}
<commit_msg>add comment<commit_after>/*
Copyright 2017 New Vector Ltd

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
import sdk from '../../../index';
import {_t} from '../../../languageHandler';
import PropTypes from 'prop-types';
import dis from '../../../dispatcher';
import {wantsDateSeparator} from '../../../DateUtils';
import {MatrixEvent, MatrixClient} from 'matrix-js-sdk';
import {makeEventPermalink, makeUserPermalink} from "../../../matrix-to";
import SettingsStore from "../../../settings/SettingsStore";

// This component does no cycle detection, simply because the only way to make such a cycle would be to
// craft event_id's, using a homeserver that generates predictable event IDs; even then the impact would
// be low as each event being loaded (after the first) is triggered by an explicit user action.
export default class ReplyThread extends React.Component {
    static propTypes = {
        // the latest event in this chain of replies
        parentEv: PropTypes.instanceOf(MatrixEvent),
        // called when the ReplyThread contents has changed, including EventTiles thereof
        onWidgetLoad: PropTypes.func.isRequired,
    };

    static contextTypes = {
        matrixClient: PropTypes.instanceOf(MatrixClient).isRequired,
    };

    constructor(props, context) {
        super(props, context);

        this.state = {
            // The loaded events to be rendered as linear-replies
            events: [],

            // The latest loaded event which has not yet been shown
            loadedEv: null,
            // Whether the component is still loading more events
            loading: true,

            // Whether as error was encountered fetching a replied to event.
            err: false,
        };

        this.onQuoteClick = this.onQuoteClick.bind(this);
        this.canCollapse = this.canCollapse.bind(this);
        this.collapse = this.collapse.bind(this);
    }

    componentWillMount() {
        this.unmounted = false;
        this.room = this.context.matrixClient.getRoom(this.props.parentEv.getRoomId());
        this.initialize();
    }

    componentDidUpdate() {
        this.props.onWidgetLoad();
    }

    componentWillUnmount() {
        this.unmounted = true;
    }

    canCollapse() {
        return this.state.events.length > 1;
    }

    collapse() {
        this.initialize();
    }

    async initialize() {
        const {parentEv} = this.props;
        // at time of making this component we checked that props.parentEv has a parentEventId
        const ev = await ReplyThread.getEvent(this.room, ReplyThread.getParentEventId(parentEv));
        if (this.unmounted) return;

        if (ev) {
            this.setState({
                events: [ev],
            }, this.loadNextEvent);
        } else {
            this.setState({err: true});
        }
    }

    async loadNextEvent() {
        if (this.unmounted) return;
        const ev = this.state.events[0];
        const inReplyToEventId = ReplyThread.getParentEventId(ev);

        if (!inReplyToEventId) {
            this.setState({
                loading: false,
            });
            return;
        }

        const loadedEv = await ReplyThread.getEvent(this.room, inReplyToEventId);
        if (this.unmounted) return;

        if (loadedEv) {
            this.setState({loadedEv});
        } else {
            this.setState({err: true});
        }
    }

    static async getEvent(room, eventId) {
        const event = room.findEventById(eventId);
        if (event) return event;

        try {
            // ask the client to fetch the event we want using the context API, only interface to do so is to ask
            // for a timeline with that event, but once it is loaded we can use findEventById to look up the ev map
            await this.context.matrixClient.getEventTimeline(room.getUnfilteredTimelineSet(), eventId);
        } catch (e) {
            return null;
        }
        return room.findEventById(eventId);
    }

    onQuoteClick() {
        const events = [this.state.loadedEv, ...this.state.events];

        this.setState({
            loadedEv: null,
            events,
        }, this.loadNextEvent);

        dis.dispatch({action: 'focus_composer'});
    }

    static getParentEventId(ev) {
        if (!ev || ev.isRedacted()) return;

        const mRelatesTo = ev.getWireContent()['m.relates_to'];
        if (mRelatesTo && mRelatesTo['m.in_reply_to']) {
            const mInReplyTo = mRelatesTo['m.in_reply_to'];
            if (mInReplyTo && mInReplyTo['event_id']) return mInReplyTo['event_id'];
        }
    }

    // Part of Replies fallback support
    static stripPlainReply(body) {
        // Removes lines beginning with `> ` until you reach one that doesn't.
        const lines = body.split('\n');
        while (lines.length && lines[0].startsWith('> ')) lines.shift();
        // Reply fallback has a blank line after it, so remove it to prevent leading newline
        if (lines[0] === '') lines.shift();
        return lines.join('\n');
    }

    // Part of Replies fallback support
    static stripHTMLReply(html) {
        return html.replace(/^
[\s\S]+?<\/blockquote>/, '');
    }

    // Part of Replies fallback support
    static getNestedReplyText(ev) {
        if (!ev) return null;

        let {body, formatted_body: html} = ev.getContent();
        if (this.getParentEventId(ev)) {
            if (body) body = this.stripPlainReply(body);
            if (html) html = this.stripHTMLReply(html);
        }

        const evLink = makeEventPermalink(ev.getRoomId(), ev.getId());
        const userLink = makeUserPermalink(ev.getSender());
        const mxid = ev.getSender();

        // This fallback contains text that is explicitly EN.
        switch (ev.getContent().msgtype) {
            case 'm.text':
            case 'm.notice': {
                html = `<blockquote data-mx-reply><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>`
                     + `<br>${html || body}</blockquote>`;
                const lines = body.trim().split('\n');
                if (lines.length > 0) {
                    lines[0] = `<${mxid}> ${lines[0]}`;
                    body = lines.map((line) => `> ${line}`).join('\n') + '\n\n';
                }
                break;
            }
            case 'm.image':
                html = `<blockquote data-mx-reply><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>`
                     + `<br>sent an image.</blockquote>`;
                body = `> <${mxid}> sent an image.\n\n`;
                break;
            case 'm.video':
                html = `<blockquote data-mx-reply><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>`
                    + `<br>sent a video.</blockquote>`;
                body = `> <${mxid}> sent a video.\n\n`;
                break;
            case 'm.audio':
                html = `<blockquote data-mx-reply><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>`
                    + `<br>sent an audio file.</blockquote>`;
                body = `> <${mxid}> sent an audio file.\n\n`;
                break;
            case 'm.file':
                html = `<blockquote data-mx-reply><a href="${evLink}">In reply to</a> <a href="${userLink}">${mxid}</a>`
                    + `<br>sent a file.</blockquote>`;
                body = `> <${mxid}> sent a file.\n\n`;
                break;
            case 'm.emote': {
                html = `<blockquote data-mx-reply><a href="${evLink}">In reply to</a> * `
                    + `<a href="${userLink}">${mxid}</a><br>${html || body}</blockquote>`;
                const lines = body.trim().split('\n');
                if (lines.length > 0) {
                    lines[0] = `* <${mxid}> ${lines[0]}`;
                    body = lines.map((line) => `> ${line}`).join('\n') + '\n\n';
                }
                break;
            }
            default:
                return null;
        }

        return {body, html};
    }

    static makeReplyMixIn(ev) {
        if (!ev) return {};
        return {
            'm.relates_to': {
                'm.in_reply_to': {
                    'event_id': ev.getId(),
                },
            },
        };
    }

    static makeThread(parentEv, onWidgetLoad, ref) {
        if (!SettingsStore.isFeatureEnabled("feature_rich_quoting") || !ReplyThread.getParentEventId(parentEv)) {
            return
;
        }
        return <ReplyThread parentEv={parentEv} onWidgetLoad={onWidgetLoad} ref={ref} />;
    }

    render() {
        let header = null;

        if (this.state.err) {
            header =

                {
                    _t('Unable to load event that was replied to, ' +
                        'it either does not exist or you do not have permission to view it.')
                }

;
        } else if (this.state.loadedEv) {
            const ev = this.state.loadedEv;
            const Pill = sdk.getComponent('elements.Pill');
            const room = this.context.matrixClient.getRoom(ev.getRoomId());
            header =

                {
                    _t('In reply to <pill>', {}, {
                        'a': (sub) => { sub },
                        'pill': <Pill type={Pill.TYPE_USER_MENTION} room={room}
                                      url={makeUserPermalink(ev.getSender())} shouldShowPillAvatar={true} />,
                    })
                }

;
        } else if (this.state.loading) {
            const Spinner = sdk.getComponent("elements.Spinner");
            header = <Spinner w={16} h={16} />;
        }

        const EventTile = sdk.getComponent('views.rooms.EventTile');
        const DateSeparator = sdk.getComponent('messages.DateSeparator');
        const evTiles = this.state.events.map((ev) => {
            let dateSep = null;

            if (wantsDateSeparator(this.props.parentEv.getDate(), ev.getDate())) {
                dateSep = <DateSeparator ts={ev.getTs()} />;
            }

            return

                { dateSep }
                <EventTile mxEvent={ev}
                           tileShape="reply"
                           onWidgetLoad={this.props.onWidgetLoad}
                           isTwelveHour={SettingsStore.getValue("showTwelveHourTimestamps")} />

;
        });

        return

{ header }

{ evTiles }

;
    }
}
<|endoftext|>


<commit_before>'use strict';

var extend = require('extend'),
    fs = require('fs-extra'),
    cmd = require('child_process'),
    glob = require('glob'),

    WORK_PATH = 'work';

function _cleanWorkspace() {
  if(fs.existsSync(WORK_PATH)) {
    console.log('remove path ' + WORK_PATH);
    fs.removeSync(WORK_PATH);
  }
}

function _error(error, callback) {
  console.error('\n\nERROR!\n');
  console.error(error);
  console.error('\n\n');

  _cleanWorkspace();

  if(callback) {
    callback(false);
  }

  return false;
}

function _success(callback) {
  _cleanWorkspace();

  console.log('\n\nALL IS DONE!\n\n');

  if(callback) {
    callback(true);
  }

  return true;
}

module.exports = function websiteRelease(config, callback) {
  config = extend(true, {
    USER_AGENT: '',
    USER_AGENT_EMAIL: '',
    SECRET: '',
    MEMORYOVERFLOW_REPO: '',
    MEMORYOVERFLOW_PATH: '',
    WEBSITE_REPO: '',
    WEBSITE_PATH: '',
    THEMACHINE_PATH: '',
    COMMIT_LABEL: '',
    commitID: '',
    commitUrl: ''
  }, config);

  _cleanWorkspace();

  config.MEMORYOVERFLOW_PATH = WORK_PATH + '/' + config.MEMORYOVERFLOW_PATH;
  config.WEBSITE_PATH = WORK_PATH + '/' + config.WEBSITE_PATH;
  config.THEMACHINE_PATH = config.MEMORYOVERFLOW_PATH + '/' + config.THEMACHINE_PATH;

  console.log('\ngit clone --depth 1 ' + config.MEMORYOVERFLOW_REPO + ' ' + config.MEMORYOVERFLOW_PATH + '...');

  cmd.exec('git clone --depth 1 ' + config.MEMORYOVERFLOW_REPO + ' ' + config.MEMORYOVERFLOW_PATH, function(error) {
    if(error) {
      return _error(error, callback);
    }

    console.log('\ninstall The Machine...');

    cmd.exec('npm install', {
      cwd: config.THEMACHINE_PATH
    }, function(error) {
      if(error) {
        return _error(error, callback);
      }

      console.log('\nexecute The Machine...');

      cmd.exec('npm run-script generate', {
        cwd: config.THEMACHINE_PATH
      }, function(error) {
        if(error) {
          return _error(error, callback);
        }

        console.log('\ngit clone ' + config.WEBSITE_REPO + ' ' + config.WEBSITE_PATH + '...');

        cmd.exec('git clone ' + config.WEBSITE_REPO + ' ' + config.WEBSITE_PATH, function(error) {
          if(error) {
            return _error(error, callback);
          }

          console.log('\ncopy ' + config.MEMORYOVERFLOW_PATH + '/website' + ' ' + config.WEBSITE_PATH + '...');

          fs.copySync(config.WEBSITE_PATH + '/README.md', config.WEBSITE_PATH + '/README.tmp');

          fs.copySync(config.MEMORYOVERFLOW_PATH + '/website', config.WEBSITE_PATH);

          fs.move(config.WEBSITE_PATH + '/README.tmp', config.WEBSITE_PATH + '/README.md', {
            clobber: true
          }, function(error) {
            if(error) {
              return _error(error, callback);
            }

            console.log('\nremove EJS files...');
            var ejsFiles = glob.sync(config.WEBSITE_PATH + '/**/*.ejs' , {});
            console.log(ejsFiles);

            for(var i = 0, len = ejsFiles.length; i < len; i++) {
              fs.removeSync(ejsFiles[i]);
            }

            console.log('\ngit config user.name "' + config.USER_AGENT + '"');

            cmd.exec('git config user.name "' + config.USER_AGENT + '"', {
              cwd: config.WEBSITE_PATH
            }, function(error) {
              if(error) {
                return _error(error, callback);
              }

              console.log('\ngit config user.email "' + config.USER_AGENT_EMAIL + '"');

              cmd.exec('git config user.email "' + config.USER_AGENT_EMAIL + '"', {
                cwd: config.WEBSITE_PATH
              }, function(error) {
                if(error) {
                  return _error(error, callback);
                }

                console.log('\ngit add -A');

                cmd.exec('git add -A', {
                  cwd: config.WEBSITE_PATH
                }, function(error, stdout) {
                  if(error) {
                    return _error(error, callback);
                  }

                  cmd.exec('git status', {
                    cwd: config.WEBSITE_PATH
                  }, function(error, stdout) {
                    if(error) {
                      return _error(error, callback);
                    }

                    var status = stdout.split('\n');
                    if(status.length && status[1].trim() == 'nothing to commit, working directory clean') {
                      console.log('NOTHING TO COMMIT');
                      return _success(callback);
                    }

                    var commitAuthor = ' --author="' + config.USER_AGENT + ' <' + config.USER_AGENT_EMAIL + '>"',
                        commitLabel = config.COMMIT_LABEL
                          .replace('{commitID}', config.commitID)
                          .replace('{commitUrl}', config.commitUrl)
                          .split('\n')
                          .map(function(line) {
                            return ' -m "' + line + '"';
                          })
                          .join('');

                    console.log('\ngit commit' + commitAuthor + commitLabel);

                    cmd.exec('git commit' + commitAuthor + commitLabel, {
                      cwd: config.WEBSITE_PATH
                    }, function(error) {
                      if(error) {
                        return _error(error, callback);
                      }

                      var pushRepo = config.WEBSITE_REPO.replace('https://', 'https://' + config.USER_AGENT + ':' + config.SECRET + '@');

                      console.log('\ngit push ' + pushRepo.replace(SECRET, 'SECRET') + ' gh-pages');

                      cmd.exec('git push ' + pushRepo + ' gh-pages', {
                        cwd: config.WEBSITE_PATH
                      }, function(error) {
                        if(error) {
                          return _error(error, callback);
                        }

                        return _success(callback);

                      });
                    });
                  });
                });
              });
            });
          });
        });
      });
    });
  });
};
<commit_msg>fix(website-release): add missing config.SECRET<commit_after>'use strict';

var extend = require('extend'),
    fs = require('fs-extra'),
    cmd = require('child_process'),
    glob = require('glob'),

    WORK_PATH = 'work';

function _cleanWorkspace() {
  if(fs.existsSync(WORK_PATH)) {
    console.log('remove path ' + WORK_PATH);
    fs.removeSync(WORK_PATH);
  }
}

function _error(error, callback) {
  console.error('\n\nERROR!\n');
  console.error(error);
  console.error('\n\n');

  _cleanWorkspace();

  if(callback) {
    callback(false);
  }

  return false;
}

function _success(callback) {
  _cleanWorkspace();

  console.log('\n\nALL IS DONE!\n\n');

  if(callback) {
    callback(true);
  }

  return true;
}

module.exports = function websiteRelease(config, callback) {
  config = extend(true, {
    USER_AGENT: '',
    USER_AGENT_EMAIL: '',
    SECRET: '',
    MEMORYOVERFLOW_REPO: '',
    MEMORYOVERFLOW_PATH: '',
    WEBSITE_REPO: '',
    WEBSITE_PATH: '',
    THEMACHINE_PATH: '',
    COMMIT_LABEL: '',
    commitID: '',
    commitUrl: ''
  }, config);

  _cleanWorkspace();

  config.MEMORYOVERFLOW_PATH = WORK_PATH + '/' + config.MEMORYOVERFLOW_PATH;
  config.WEBSITE_PATH = WORK_PATH + '/' + config.WEBSITE_PATH;
  config.THEMACHINE_PATH = config.MEMORYOVERFLOW_PATH + '/' + config.THEMACHINE_PATH;

  console.log('\ngit clone --depth 1 ' + config.MEMORYOVERFLOW_REPO + ' ' + config.MEMORYOVERFLOW_PATH + '...');

  cmd.exec('git clone --depth 1 ' + config.MEMORYOVERFLOW_REPO + ' ' + config.MEMORYOVERFLOW_PATH, function(error) {
    if(error) {
      return _error(error, callback);
    }

    console.log('\ninstall The Machine...');

    cmd.exec('npm install', {
      cwd: config.THEMACHINE_PATH
    }, function(error) {
      if(error) {
        return _error(error, callback);
      }

      console.log('\nexecute The Machine...');

      cmd.exec('npm run-script generate', {
        cwd: config.THEMACHINE_PATH
      }, function(error) {
        if(error) {
          return _error(error, callback);
        }

        console.log('\ngit clone ' + config.WEBSITE_REPO + ' ' + config.WEBSITE_PATH + '...');

        cmd.exec('git clone ' + config.WEBSITE_REPO + ' ' + config.WEBSITE_PATH, function(error) {
          if(error) {
            return _error(error, callback);
          }

          console.log('\ncopy ' + config.MEMORYOVERFLOW_PATH + '/website' + ' ' + config.WEBSITE_PATH + '...');

          fs.copySync(config.WEBSITE_PATH + '/README.md', config.WEBSITE_PATH + '/README.tmp');

          fs.copySync(config.MEMORYOVERFLOW_PATH + '/website', config.WEBSITE_PATH);

          fs.move(config.WEBSITE_PATH + '/README.tmp', config.WEBSITE_PATH + '/README.md', {
            clobber: true
          }, function(error) {
            if(error) {
              return _error(error, callback);
            }

            console.log('\nremove EJS files...');
            var ejsFiles = glob.sync(config.WEBSITE_PATH + '/**/*.ejs' , {});
            console.log(ejsFiles);

            for(var i = 0, len = ejsFiles.length; i < len; i++) {
              fs.removeSync(ejsFiles[i]);
            }

            console.log('\ngit config user.name "' + config.USER_AGENT + '"');

            cmd.exec('git config user.name "' + config.USER_AGENT + '"', {
              cwd: config.WEBSITE_PATH
            }, function(error) {
              if(error) {
                return _error(error, callback);
              }

              console.log('\ngit config user.email "' + config.USER_AGENT_EMAIL + '"');

              cmd.exec('git config user.email "' + config.USER_AGENT_EMAIL + '"', {
                cwd: config.WEBSITE_PATH
              }, function(error) {
                if(error) {
                  return _error(error, callback);
                }

                console.log('\ngit add -A');

                cmd.exec('git add -A', {
                  cwd: config.WEBSITE_PATH
                }, function(error, stdout) {
                  if(error) {
                    return _error(error, callback);
                  }

                  cmd.exec('git status', {
                    cwd: config.WEBSITE_PATH
                  }, function(error, stdout) {
                    if(error) {
                      return _error(error, callback);
                    }

                    var status = stdout.split('\n');
                    if(status.length && status[1].trim() == 'nothing to commit, working directory clean') {
                      console.log('NOTHING TO COMMIT');
                      return _success(callback);
                    }

                    var commitAuthor = ' --author="' + config.USER_AGENT + ' <' + config.USER_AGENT_EMAIL + '>"',
                        commitLabel = config.COMMIT_LABEL
                          .replace('{commitID}', config.commitID)
                          .replace('{commitUrl}', config.commitUrl)
                          .split('\n')
                          .map(function(line) {
                            return ' -m "' + line + '"';
                          })
                          .join('');

                    console.log('\ngit commit' + commitAuthor + commitLabel);

                    cmd.exec('git commit' + commitAuthor + commitLabel, {
                      cwd: config.WEBSITE_PATH
                    }, function(error) {
                      if(error) {
                        return _error(error, callback);
                      }

                      var pushRepo = config.WEBSITE_REPO.replace('https://', 'https://' + config.USER_AGENT + ':' + config.SECRET + '@');

                      console.log('\ngit push ' + pushRepo.replace(config.SECRET, 'SECRET') + ' gh-pages');

                      cmd.exec('git push ' + pushRepo + ' gh-pages', {
                        cwd: config.WEBSITE_PATH
                      }, function(error) {
                        if(error) {
                          return _error(error, callback);
                        }

                        return _success(callback);

                      });
                    });
                  });
                });
              });
            });
          });
        });
      });
    });
  });
};
<|endoftext|>


<commit_before>var SN_EXTENDED = SN_EXTENDED || {};

SN_EXTENDED.reorder = function(cls) {

    var divs = $('div[class=' + cls + ']');

    $(divs).each(function(i, div) {
        $(div).find('a.remove_row').show();
        SN_EXTENDED.replaceIndex(SN_EXTENDED.rowIndex(div), i);
    });

    var lastDiv = $(divs).last().closest('tr');
    lastDiv.addClass('supersizeme');

    $(divs).last().find('a.add_row').show();

    if (divs.length == 1) {
        $(divs).find('a.remove_row').hide();
    }
};

SN_EXTENDED.rowIndex = function(div) {
    var idstr = $(div).attr('id');
    var id = idstr.match(/\d+/);
    return id;
};

SN_EXTENDED.rowCount = function(cls) {
    var divs = $.find('div[class=' + cls + ']');
    return divs.length;
};

SN_EXTENDED.replaceIndex = function(elem, oldIndex, newIndex) {
    $(elem).find('*').each(function() {
        $.each(this.attributes, function(i, attrib) {
            var regexp = /extprofile-.*-\d.*/;
            var value = attrib.value;
            var match = value.match(regexp);
            if (match !== null) {
                attrib.value = value.replace("-" + oldIndex, "-" + newIndex);
            }
        });
    });
}

SN_EXTENDED.resetRow = function(elem) {
    $(elem).find('input, textarea').attr('value', '');
    $(elem).find("select option[value='office']").attr("selected", true);
};

SN_EXTENDED.addRow = function() {
    var div = $(this).closest('div');
    var id = div.attr('id');
    var cls = div.attr('class');
    var index = id.match(/\d+/);
    var newIndex = parseInt(index) + 1;
    var newtr = $(div).closest('tr').clone();
    SN_EXTENDED.replaceIndex(newtr, index, newIndex);
    $(newtr).removeClass('supersizeme');
    SN_EXTENDED.resetRow(newtr);
    $(div).closest('tr').after(newtr);
    SN_EXTENDED.reorder(cls);
};

SN_EXTENDED.removeRow = function() {

    var div = $(this).closest('div');
    var id = $(div).attr('id');
    var cls = $(div).attr('class');
    var cnt = SN_EXTENDED.rowCount(cls);

    var that = this;

    $("#confirm-dialog").dialog({
        buttons : {
            "Confirm" : function() {
                var target = $(that).closest('tr');
                target.fadeOut("slow", function() {
                    $(that).remove();
                });
                SN_EXTENDED.reorder(cls);
                $(this).dialog("close");
            },
            "Cancel" : function() {
                $(this).dialog("close");
            }
        }
    });

    if (cnt > 1) {
        $("#confirm-dialog").dialog("open");
    }
};

$(document).ready(function() {

    $("#confirm-dialog").dialog({
        autoOpen: false,
        modal: true
    });

    $("input#extprofile-manager").autocomplete({
        source: 'finduser',
        minLength: 2 });

    $("input[name$=-start], input[name$=-end], #extprofile-birthday").datepicker({ dateFormat: 'd M yy' });

    var multifields = ["phone-item", "experience-item", "education-item", "im-item"];

    for (f in multifields) {
        SN_EXTENDED.reorder(multifields[f]);
    }

    $("input#extprofile-manager").autocomplete({
        source: 'finduser',
        minLength: 2 });

    $('.add_row').live('click', SN_EXTENDED.addRow);
    $('.remove_row').live('click', SN_EXTENDED.removeRow);

});
<commit_msg>Extended profile - hide add button when not needed (regression)<commit_after>var SN_EXTENDED = SN_EXTENDED || {};

SN_EXTENDED.reorder = function(cls) {

    var divs = $('div[class=' + cls + ']');

    $(divs).each(function(i, div) {
        $(div).find('a.add_row').hide();
        $(div).find('a.remove_row').show();
        SN_EXTENDED.replaceIndex(SN_EXTENDED.rowIndex(div), i);
    });

    var lastDiv = $(divs).last().closest('tr');
    lastDiv.addClass('supersizeme');

    $(divs).last().find('a.add_row').show();

    if (divs.length == 1) {
        $(divs).find('a.remove_row').hide();
    }
};

SN_EXTENDED.rowIndex = function(div) {
    var idstr = $(div).attr('id');
    var id = idstr.match(/\d+/);
    return id;
};

SN_EXTENDED.rowCount = function(cls) {
    var divs = $.find('div[class=' + cls + ']');
    return divs.length;
};

SN_EXTENDED.replaceIndex = function(elem, oldIndex, newIndex) {
    $(elem).find('*').each(function() {
        $.each(this.attributes, function(i, attrib) {
            var regexp = /extprofile-.*-\d.*/;
            var value = attrib.value;
            var match = value.match(regexp);
            if (match !== null) {
                attrib.value = value.replace("-" + oldIndex, "-" + newIndex);
            }
        });
    });
}

SN_EXTENDED.resetRow = function(elem) {
    $(elem).find('input, textarea').attr('value', '');
    $(elem).find("select option[value='office']").attr("selected", true);
};

SN_EXTENDED.addRow = function() {
    var div = $(this).closest('div');
    var id = div.attr('id');
    var cls = div.attr('class');
    var index = id.match(/\d+/);
    var newIndex = parseInt(index) + 1;
    var newtr = $(div).closest('tr').clone();
    SN_EXTENDED.replaceIndex(newtr, index, newIndex);
    $(newtr).removeClass('supersizeme');
    SN_EXTENDED.resetRow(newtr);
    $(div).closest('tr').after(newtr);
    SN_EXTENDED.reorder(cls);
};

SN_EXTENDED.removeRow = function() {

    var div = $(this).closest('div');
    var id = $(div).attr('id');
    var cls = $(div).attr('class');
    var cnt = SN_EXTENDED.rowCount(cls);

    var that = this;

    $("#confirm-dialog").dialog({
        buttons : {
            "Confirm" : function() {
                var target = $(that).closest('tr');
                target.fadeOut("slow", function() {
                    $(that).remove();
                });
                SN_EXTENDED.reorder(cls);
                $(this).dialog("close");
            },
            "Cancel" : function() {
                $(this).dialog("close");
            }
        }
    });

    if (cnt > 1) {
        $("#confirm-dialog").dialog("open");
    }
};

$(document).ready(function() {

    $("#confirm-dialog").dialog({
        autoOpen: false,
        modal: true
    });

    $("input#extprofile-manager").autocomplete({
        source: 'finduser',
        minLength: 2 });

    $("input[name$=-start], input[name$=-end], #extprofile-birthday").datepicker({ dateFormat: 'd M yy' });

    var multifields = ["phone-item", "experience-item", "education-item", "im-item"];

    for (f in multifields) {
        SN_EXTENDED.reorder(multifields[f]);
    }

    $("input#extprofile-manager").autocomplete({
        source: 'finduser',
        minLength: 2 });

    $('.add_row').live('click', SN_EXTENDED.addRow);
    $('.remove_row').live('click', SN_EXTENDED.removeRow);

});
<|endoftext|>


<commit_before>var cadence = require('cadence')
var Interlocutor = require('interlocutor')
var protocols = { http: require('http'), https: require('https') }
var Conduit = require('nascent.upgrader/socket')
var Header = require('nascent.jacket')
var url = require('url')
var Cache = require('magazine')

function Client (middleware, request, socket, head) {
    this._interlocutor = new Interlocutor(middleware)
    this._socket = socket
    this._magazine = new Cache().createMagazine()
    this._header = new Header
    this._consume(head, 0, head.length)
    this._socket.on('data', this._data.bind(this))
}

Client.prototype._data = function (buffer) {
    var count = 0
    for (var start = 0;  start != buffer.length;) {
        if (++count == 5) throw new Error
        start = this._consume(buffer, start, buffer.length)
    }
}

Client.prototype._consume = function (buffer, start, end) {
    if (this._header.object != null) {
        var length = Math.min(buffer.length, this._header.object.length)
        var cartridge = this._magazine.hold(cookie, null)
        cartridge.value.response.write(buffer.slice(start, start + length))
        start += length
        cartridge.release()
        this._header = new Header
    }
    start = this._header.parse(buffer, start, end)
    if (this._header.object != null) {
        switch (this._header.object.type) {
        case 'header':
            var headers = this._header.object.headers
            headers['sec-conduit-rendezvous-actual-path'] = this._header.object.actualPath
            this._header.object.rawHeaders.push('sec-conduit-rendezvous-actual-path', this._header.object.actualPath)
            var request = this._interlocutor.request({
                httpVersion: this._header.object.httpVersion,
                method: this._header.object.method,
                url: this._header.object.url,
                headers: headers,
                rawHeaders: this._header.object.rawHeaders
            })
            var socket = this._socket, cookie = this._header.object.cookie
            request.on('response', function (response) {
                socket.write(new Buffer(JSON.stringify({
                    type: 'header',
                    cookie: cookie,
                    statusCode: response.statusCode,
                    statusMessage: response.statusMessage,
                    headers: response.headers
                }) + '\n'))
                response.on('data', function (buffer) {
                    socket.write(new Buffer(JSON.stringify({
                        type: 'chunk',
                        cookie: cookie,
                        length: buffer.length
                    }) + '\n'))
                    socket.write(buffer)
                })
                response.on('end', function () {
                    socket.write(new Buffer(JSON.stringify({ type: 'trailer', cookie: cookie }) + '\n'))
                })
                // response.on('error', function (error) {})
            })
            this._magazine.hold(this._header.object.cookie, request).release()
            this._header = new Header
            break
        case 'chunk':
            break
        case 'trailer':
            var cartridge = this._magazine.hold(this._header.object.cookie, null)
            cartridge.value.end()
            cartridge.remove()
            this._header = new Header
            break
        }
    }
    return start
}

Client.prototype.close = cadence(function (async) {
    this._socket.end(async())
    this._socket.destroy()
})

exports.connect = cadence(function (async, location, middleware) {
    var parsed = url.parse(location)
    async(function () {
        Conduit.connect({
            secure: parsed.protocol == 'https:',
            host: parsed.hostname,
            port: parsed.port,
            auth: parsed.auth,
            headers: {
                'sec-conduit-rendezvous-path': parsed.path
            }
        }, async())
    }, function (request, socket, head) {
        return new Client(middleware, request, socket, head)
    })
})
<commit_msg>Rename Client to Envoy.<commit_after>var cadence = require('cadence')
var Interlocutor = require('interlocutor')
var protocols = { http: require('http'), https: require('https') }
var Conduit = require('nascent.upgrader/socket')
var Header = require('nascent.jacket')
var url = require('url')
var Cache = require('magazine')

function Envoy (middleware, request, socket, head) {
    this._interlocutor = new Interlocutor(middleware)
    this._socket = socket
    this._magazine = new Cache().createMagazine()
    this._header = new Header
    this._consume(head, 0, head.length)
    this._socket.on('data', this._data.bind(this))
}

Envoy.prototype._data = function (buffer) {
    var count = 0
    for (var start = 0;  start != buffer.length;) {
        if (++count == 5) throw new Error
        start = this._consume(buffer, start, buffer.length)
    }
}

Envoy.prototype._consume = function (buffer, start, end) {
    if (this._header.object != null) {
        var length = Math.min(buffer.length, this._header.object.length)
        var cartridge = this._magazine.hold(cookie, null)
        cartridge.value.response.write(buffer.slice(start, start + length))
        start += length
        cartridge.release()
        this._header = new Header
    }
    start = this._header.parse(buffer, start, end)
    if (this._header.object != null) {
        switch (this._header.object.type) {
        case 'header':
            var headers = this._header.object.headers
            headers['sec-conduit-rendezvous-actual-path'] = this._header.object.actualPath
            this._header.object.rawHeaders.push('sec-conduit-rendezvous-actual-path', this._header.object.actualPath)
            var request = this._interlocutor.request({
                httpVersion: this._header.object.httpVersion,
                method: this._header.object.method,
                url: this._header.object.url,
                headers: headers,
                rawHeaders: this._header.object.rawHeaders
            })
            var socket = this._socket, cookie = this._header.object.cookie
            request.on('response', function (response) {
                socket.write(new Buffer(JSON.stringify({
                    type: 'header',
                    cookie: cookie,
                    statusCode: response.statusCode,
                    statusMessage: response.statusMessage,
                    headers: response.headers
                }) + '\n'))
                response.on('data', function (buffer) {
                    socket.write(new Buffer(JSON.stringify({
                        type: 'chunk',
                        cookie: cookie,
                        length: buffer.length
                    }) + '\n'))
                    socket.write(buffer)
                })
                response.on('end', function () {
                    socket.write(new Buffer(JSON.stringify({ type: 'trailer', cookie: cookie }) + '\n'))
                })
                // response.on('error', function (error) {})
            })
            this._magazine.hold(this._header.object.cookie, request).release()
            this._header = new Header
            break
        case 'chunk':
            break
        case 'trailer':
            var cartridge = this._magazine.hold(this._header.object.cookie, null)
            cartridge.value.end()
            cartridge.remove()
            this._header = new Header
            break
        }
    }
    return start
}

Envoy.prototype.close = cadence(function (async) {
    this._socket.end(async())
    this._socket.destroy()
})

exports.connect = cadence(function (async, location, middleware) {
    var parsed = url.parse(location)
    async(function () {
        Conduit.connect({
            secure: parsed.protocol == 'https:',
            host: parsed.hostname,
            port: parsed.port,
            auth: parsed.auth,
            headers: {
                'sec-conduit-rendezvous-path': parsed.path
            }
        }, async())
    }, function (request, socket, head) {
        return new Envoy(middleware, request, socket, head)
    })
})
<|endoftext|>


<commit_before>

var getRenderer = require('./get_renderer'),
	getPartials = require('./get_partials'),
	build = require("./build"),
	assert = require('assert'),
	Q = require('q'),
	path = require('path');

describe("documentjs/lib/generators/html/build",function(){

	it("get_renderer and get_partial work",function(done){
		Q.all([
			getRenderer('documentjs/lib/generators/html/build/test/templates'),
			getPartials('documentjs/lib/generators/html/build/test/templates')
		]).then(function(results){

			var renderer = results[0];

			var result = renderer({subject: "World"});

			assert.equal(result, "
Hello World
")
			done();
		},done).catch(done);
	});

	it("build.renderer build.templates build.helpers",function(done){
		var options = {
			templates: path.join(__dirname,"test","templates_with_helpers"),
			dest: "XXXXYYYZZZ",
			forceBuild: true,
			pageConfig: {
				project: {
					source: "http://test.com"
				}
			}
		};
		buildTemplatesPromise = build.templates(options);

		var data = {subject: "World", message: "hello"};
		var getCurrent = function(){
			return data;
		};

		Q.all([
			build.renderer(buildTemplatesPromise, options),
			build.helpers(buildTemplatesPromise, {}, options, getCurrent)
		]).then(function(results){

			var renderer = results[0];

			var result = renderer({
				subject: "World",
				src: "./index.js",
				type: "",
				line: "100"
			});

			assert.equal(result, "
HELLO World
\n\n
http://test.com/index.js#L100
\n")
			done();
		},done).catch(done);

	});

	it.only("renderBodyAsTemplate",function(done){
		var options = {
			templates: path.join(__dirname,"test","render_body_option"),
			dest: "XXXXYYYZZZ",
			forceBuild: true,
			renderBodyAsTemplate: false,
			pageConfig: {
				project: {
					source: "http://test.com"
				}
			}
		};
		buildTemplatesPromise = build.templates(options);

		var data = {message: "this isnt doing anything"};
		var getCurrent = function(){
			return data;
		};

		Q.all([
			build.renderer(buildTemplatesPromise, options),
			build.helpers(buildTemplatesPromise, {}, options, getCurrent)
		]).then(function(results){

			var renderer = results[0];

			var result = renderer({body: "{{message}} stuff"});

			assert.equal(result, "
{{message}} stuff
\n
static
")
			done();
		},done).catch(done);

	});

});
<commit_msg>removed only on test, and updated test name<commit_after>

var getRenderer = require('./get_renderer'),
	getPartials = require('./get_partials'),
	build = require("./build"),
	assert = require('assert'),
	Q = require('q'),
	path = require('path');

describe("documentjs/lib/generators/html/build",function(){

	it("get_renderer and get_partial work",function(done){
		Q.all([
			getRenderer('documentjs/lib/generators/html/build/test/templates'),
			getPartials('documentjs/lib/generators/html/build/test/templates')
		]).then(function(results){

			var renderer = results[0];

			var result = renderer({subject: "World"});

			assert.equal(result, "
Hello World
")
			done();
		},done).catch(done);
	});

	it("build.renderer build.templates build.helpers",function(done){
		var options = {
			templates: path.join(__dirname,"test","templates_with_helpers"),
			dest: "XXXXYYYZZZ",
			forceBuild: true,
			pageConfig: {
				project: {
					source: "http://test.com"
				}
			}
		};
		buildTemplatesPromise = build.templates(options);

		var data = {subject: "World", message: "hello"};
		var getCurrent = function(){
			return data;
		};

		Q.all([
			build.renderer(buildTemplatesPromise, options),
			build.helpers(buildTemplatesPromise, {}, options, getCurrent)
		]).then(function(results){

			var renderer = results[0];

			var result = renderer({
				subject: "World",
				src: "./index.js",
				type: "",
				line: "100"
			});

			assert.equal(result, "
HELLO World
\n\n
http://test.com/index.js#L100
\n")
			done();
		},done).catch(done);

	});

	it("Does not renderBodyAsTemplate",function(done){
		var options = {
			templates: path.join(__dirname,"test","render_body_option"),
			dest: "XXXXYYYZZZ",
			forceBuild: true,
			renderBodyAsTemplate: false,
			pageConfig: {
				project: {
					source: "http://test.com"
				}
			}
		};
		buildTemplatesPromise = build.templates(options);

		var data = {message: "this isnt doing anything"};
		var getCurrent = function(){
			return data;
		};

		Q.all([
			build.renderer(buildTemplatesPromise, options),
			build.helpers(buildTemplatesPromise, {}, options, getCurrent)
		]).then(function(results){

			var renderer = results[0];

			var result = renderer({body: "{{message}} stuff"});

			assert.equal(result, "
{{message}} stuff
\n
static
")
			done();
		},done).catch(done);

	});

});
<|endoftext|>


<commit_before>/* Mark special links
 *
 * Options:
 *    external_links_open_new_window(boolean): Open external links in a new window. (false)
 *    mark_special_links(boolean): Marks external or special protocl links with class. (true)
 *
 * Documentation:
 *   # General
 *
 *   Scan all links in the container and mark external links with class
 *   if they point outside the site, or are special protocols.
 *   Also implements new window opening for external links.
 *   To disable this effect for links on a one-by-one-basis,
 *   give them a class of 'link-plain'
 *
 *   # Default external link example
 *
 *   {{ example-1 }}
 *
 *   # Open external link in new window
 *
 *   {{ example-2 }}
 *
 *   # Open external link in new window, without icons
 *
 *   {{ example-3 }}
 *
 *   # List of all protocol icons
 *
 *   {{ example-4 }}
 *
 * Example: example-1
 *

 *

 *
Find out What's new in Plone.

 *
Plone is written in Python.

 *
Plone builds on Zope.

 *
Plone uses Mockup.

 *

 *

 *
 * Example: example-2
 *

 *

 *
Find out What's new in Plone.

 *
Plone is written in Python.

 *
Plone builds on Zope.

 *
Plone uses Mockup.

 *

 *

 *
 * Example: example-3
 *

 *

 *
Find out What's new in Plone.

 *
Plone is written in Python.

 *
Plone builds on Zope.

 *
Plone uses Mockup.

 *

 *

 *
 * Example: example-4
 *

 *

 *
http

 *
https

 *
mailto

 *
ftp

 *
news

 *
irc

 *
h323

 *
sip

 *
callto

 *
feed

 *
webcal

 *

 *

 *
 */

define([
  'mockup-patterns-base',
  'jquery'
], function (Base, $) {
  'use strict';

  var MarkSpecialLinks = Base.extend({
    name: 'markspeciallinks',
    trigger: '.pat-markspeciallinks',
    defaults: {
      external_links_open_new_window: false,
      mark_special_links: true
    },
    init: function () {
      var self = this, $el = self.$el;

      // first make external links open in a new window, afterwards do the
      // normal plone link wrapping in only the content area
      var elonw,
          msl,
          url,
          protocols,
          contentarea,
          res;

      if (typeof self.options.external_links_open_new_window === 'string') {
          elonw = self.options.external_links_open_new_window.toLowerCase() === 'true';
      } else if (typeof self.options.external_links_open_new_window === 'boolean') {
          elonw = self.options.external_links_open_new_window;
      }

      if (typeof self.options.mark_special_links === 'string') {
          msl = self.options.mark_special_links.toLowerCase() === 'true';
      } else if (typeof self.options.mark_special_links === 'boolean') {
          msl = self.options.mark_special_links;
      }

      url = window.location.protocol + '//' + window.location.host;
      protocols = /^(mailto|ftp|news|irc|h323|sip|callto|https|feed|webcal)/;
      contentarea = $el;

      if (elonw) {
          // all http links (without the link-plain class), not within this site
          contentarea.find('a[href^="http"]:not(.link-plain):not([href^="' + url + '"])')
                     .attr('target', '_blank');
      }

      if (msl) {
        // All links with an http href (without the link-plain class), not within this site,
        // and no img children should be wrapped in a link-external span
        contentarea.find(
            'a[href^="http:"]:not(.link-plain):not([href^="' + url + '"]):not(:has(img))')
            .before('');
        // All links without an http href (without the link-plain class), not within this site,
        // and no img children should be wrapped in a link-[protocol] span
        contentarea.find(
            'a[href]:not([href^="http:"]):not(.link-plain):not([href^="' + url + '"]):not(:has(img))')
            .each(function() {
                // those without a http link may have another interesting protocol
                // wrap these in a link-[protocol] span
                res = protocols.exec(this.href);
                if (res) {
                    var iconclass = 'glyphicon link-' + res[0];
                    jQuery(this).before('');
                }
            }
        );
      }

    }
  });
  return MarkSpecialLinks;
});
<commit_msg>Don't expect the global jQuery obj to be available.<commit_after>/* Mark special links
 *
 * Options:
 *    external_links_open_new_window(boolean): Open external links in a new window. (false)
 *    mark_special_links(boolean): Marks external or special protocl links with class. (true)
 *
 * Documentation:
 *   # General
 *
 *   Scan all links in the container and mark external links with class
 *   if they point outside the site, or are special protocols.
 *   Also implements new window opening for external links.
 *   To disable this effect for links on a one-by-one-basis,
 *   give them a class of 'link-plain'
 *
 *   # Default external link example
 *
 *   {{ example-1 }}
 *
 *   # Open external link in new window
 *
 *   {{ example-2 }}
 *
 *   # Open external link in new window, without icons
 *
 *   {{ example-3 }}
 *
 *   # List of all protocol icons
 *
 *   {{ example-4 }}
 *
 * Example: example-1
 *

 *

 *
Find out What's new in Plone.

 *
Plone is written in Python.

 *
Plone builds on Zope.

 *
Plone uses Mockup.

 *

 *

 *
 * Example: example-2
 *

 *

 *
Find out What's new in Plone.

 *
Plone is written in Python.

 *
Plone builds on Zope.

 *
Plone uses Mockup.

 *

 *

 *
 * Example: example-3
 *

 *

 *
Find out What's new in Plone.

 *
Plone is written in Python.

 *
Plone builds on Zope.

 *
Plone uses Mockup.

 *

 *

 *
 * Example: example-4
 *

 *

 *
http

 *
https

 *
mailto

 *
ftp

 *
news

 *
irc

 *
h323

 *
sip

 *
callto

 *
feed

 *
webcal

 *

 *

 *
 */

define([
  'mockup-patterns-base',
  'jquery'
], function (Base, $) {
  'use strict';

  var MarkSpecialLinks = Base.extend({
    name: 'markspeciallinks',
    trigger: '.pat-markspeciallinks',
    defaults: {
      external_links_open_new_window: false,
      mark_special_links: true
    },
    init: function () {
      var self = this, $el = self.$el;

      // first make external links open in a new window, afterwards do the
      // normal plone link wrapping in only the content area
      var elonw,
          msl,
          url,
          protocols,
          contentarea,
          res;

      if (typeof self.options.external_links_open_new_window === 'string') {
          elonw = self.options.external_links_open_new_window.toLowerCase() === 'true';
      } else if (typeof self.options.external_links_open_new_window === 'boolean') {
          elonw = self.options.external_links_open_new_window;
      }

      if (typeof self.options.mark_special_links === 'string') {
          msl = self.options.mark_special_links.toLowerCase() === 'true';
      } else if (typeof self.options.mark_special_links === 'boolean') {
          msl = self.options.mark_special_links;
      }

      url = window.location.protocol + '//' + window.location.host;
      protocols = /^(mailto|ftp|news|irc|h323|sip|callto|https|feed|webcal)/;
      contentarea = $el;

      if (elonw) {
          // all http links (without the link-plain class), not within this site
          contentarea.find('a[href^="http"]:not(.link-plain):not([href^="' + url + '"])')
                     .attr('target', '_blank');
      }

      if (msl) {
        // All links with an http href (without the link-plain class), not within this site,
        // and no img children should be wrapped in a link-external span
        contentarea.find(
            'a[href^="http:"]:not(.link-plain):not([href^="' + url + '"]):not(:has(img))')
            .before('');
        // All links without an http href (without the link-plain class), not within this site,
        // and no img children should be wrapped in a link-[protocol] span
        contentarea.find(
            'a[href]:not([href^="http:"]):not(.link-plain):not([href^="' + url + '"]):not(:has(img))')
            .each(function() {
                // those without a http link may have another interesting protocol
                // wrap these in a link-[protocol] span
                res = protocols.exec(this.href);
                if (res) {
                    var iconclass = 'glyphicon link-' + res[0];
                    $(this).before('');
                }
            }
        );
      }
    }
  });
  return MarkSpecialLinks;
});
<|endoftext|>


<commit_before>(function() {

var
	elVideo = dom.jqPlayerVideo[ 0 ],
	jqTxtPosition = dom.jqPlayerTimeText
;

dom.jqPlayerSliderCurrentTime.change( function() {
	if ( elVideo.duration ) {
		var val = this.value * elVideo.duration;
		playerUI.currentTime( val );
		api.video.currentTime( val );
	}
});

// Switch between showing the duration or the remaining time.
jqTxtPosition.click( function() {
	jqTxtPosition.toggleClass( "remaining" );
});

function pos( p ) {
	api.video.currentTime( p );
	var sec = api.video.currentTime();
	playerUI.actionDesc(
		utils.secondsToString( sec ) + " / " +
		utils.secondsToString( api.video.duration() )
	);
	playerUI.currentTime( sec );
}

// Control the position with the arrow keys.
api.keyboard
	.shortcut( "shift+left",  pos.bind( null,  "-=3" ) )
	.shortcut( "shift+right", pos.bind( null,  "+=3" ) )
	.shortcut( "alt+left",    pos.bind( null, "-=10" ) )
	.shortcut( "alt+right",   pos.bind( null, "+=10" ) )
	.shortcut( "ctrl+left",   pos.bind( null, "-=60" ) )
	.shortcut( "ctrl+right",  pos.bind( null, "+=60" ) )
;

})();
<commit_msg>Position: shortcut left/right without shift/alt/ctrl<commit_after>(function() {

var
	elVideo = dom.jqPlayerVideo[ 0 ],
	jqTxtPosition = dom.jqPlayerTimeText
;

dom.jqPlayerSliderCurrentTime.change( function() {
	if ( elVideo.duration ) {
		var val = this.value * elVideo.duration;
		playerUI.currentTime( val );
		api.video.currentTime( val );
	}
});

// Switch between showing the duration or the remaining time.
jqTxtPosition.click( function() {
	jqTxtPosition.toggleClass( "remaining" );
});

function pos( p ) {
	api.video.currentTime( p );
	var sec = api.video.currentTime();
	playerUI.actionDesc(
		utils.secondsToString( sec ) + " / " +
		utils.secondsToString( api.video.duration() )
	);
	playerUI.currentTime( sec );
}

// Control the position with the arrow keys.
api.keyboard
	.shortcut( "left",        pos.bind( null,  "-=1" ) )
	.shortcut( "right",       pos.bind( null,  "+=1" ) )
	.shortcut( "shift+left",  pos.bind( null,  "-=3" ) )
	.shortcut( "shift+right", pos.bind( null,  "+=3" ) )
	.shortcut( "alt+left",    pos.bind( null, "-=10" ) )
	.shortcut( "alt+right",   pos.bind( null, "+=10" ) )
	.shortcut( "ctrl+left",   pos.bind( null, "-=60" ) )
	.shortcut( "ctrl+right",  pos.bind( null, "+=60" ) )
;

})();
<|endoftext|>


<commit_before>'use strict';

module.exports = (function () {
  var tags = '.tags',
    tag = '.tag',
    tag_text = '.tag span',
    url = 'allow.php',
    $input;

  return {
    allow_new: null,
    input: null,
    popup_denied: null,
    popup_no_find: null,
    init: function () {
      var template = require('./templates/tags.jade'),
        autocomplete = require('./autocomplete'),
        sortable = require('./sortable');

      require('./styles/tags.styl');

      $('body').html(template());

      $input = $(this.input);

      this.trigger();
      this.event();

      autocomplete.init();

      sortable.init();
    },
    trigger: function () {
      var that = this;

      $input.on('keydown', function (e) {
        if (e.which === $.ui.keyCode.ENTER) {
          if (!$input.data('autocomplete-open') && $input.val() !== '') {
            $(this).trigger('create_tag.tags', {value: $(this).val()});
          }
        }
        else if (e.which === $.ui.keyCode.BACKSPACE && $(this).val() === '') {
          $(this).trigger({
            type: 'remove_tag.tags',
            tags_tag: $(tag).last()
          });
        }
      });

      $(tags).on('click', '.tag-remove a', function (e) {
        $(this).trigger({
          type: 'remove_tag.tags',
          tags_tag: $(this).closest(tag)
        });
        return false;
      });
    },
    event: function () {
      var $tags = $(tags),
        that = this;

      $tags.on({
        'create_tag.tags': function (e, data) {
          that.create_tag(data.value);
        },
        'remove_tag.tags': function (e) {
          that.remove_tag(e.tags_tag);
        }
      });

      $input.on('keydown', function (e) {
        if (e.which !== $.ui.keyCode.ENTER) {
          $(that.popup_denied).fadeOut();
          $(that.popup_no_find).fadeOut();
          $input.removeData('popup-denied-open');
        }
      });
      $(document).on('mousemove', function (e) {
        $(that.popup_denied).fadeOut();
        $(that.popup_no_find).fadeOut();
        $input.removeData('popup-denied-open');
      });
    },
    create_tag: function (value) {
      var that = this;
      var template = require('./templates/tag.jade');

      if (this.allow_new) {
        this._create(template, value);
      } else {
        $.ajax(url, {
            async: false,
            data: {
              label: value,
              count: that._get_count_terms_by_label(value)
            },
            success: function (data, text_status, jq_xhr) {
              var popup;

              if ($.parseJSON(data)) {
                that._create(template, value);
              } else {
                popup = require('./popup');
                popup.denied();
              }
              $input.autocomplete('close');
            }
          }
        );
      }
    },
    remove_tag: function ($tag) {
      $tag.hide('blind', {direction: 'left'}, 'normal', function () {
        $(this).remove();
      });
    },
    _get_count_terms_by_label: function (label) {
      var $tag_text = $(tag_text),
        count = 0;

      $tag_text.each(function (i, el) {
        if ($(el).text() === label) {
          count++;
        }
      });
      return count;
    },
    _create: function (template, value) {
      $(template({value: value})).appendTo('.tag-cont');
      $input.val('');
    }
  };
})();<commit_msg>tags update<commit_after>'use strict';

module.exports = (function () {
  var tags = '.tags',
    tag = '.tag',
    tag_text = '.tag span',
    url = 'allow.php',
    $input;

  return {
    allow_new: null,
    input: null,
    popup_denied: null,
    popup_no_find: null,
    init: function () {
      var template = require('./templates/tags.jade'),
        autocomplete = require('./autocomplete'),
        sortable = require('./sortable');

      require('./styles/tags.styl');

      $('body').html(template());

      $input = $(this.input);

      this.trigger();
      this.event();

      autocomplete.init();

      sortable.init();
    },
    trigger: function () {
      var that = this;

      $input.on('keydown', function (e) {
        if (e.which === $.ui.keyCode.ENTER) {
          if (!$input.data('autocomplete-open') && $input.val() !== '') {
            $(this).trigger('create_tag.tags', {value: $(this).val()});
          }
        }
        else if (e.which === $.ui.keyCode.BACKSPACE && $(this).val() === '') {
          $(this).trigger({
            type: 'remove_tag.tags',
            tags_tag: $(tag).last()
          });
        }
      });

      $(tags).on('click', '.tag-remove a', function (e) {
        $(this).trigger({
          type: 'remove_tag.tagssdfsdf',
          tags_tag: $(this).closest(tag)
        });
        return false;
      });
    },
    event: function () {
      var $tags = $(tags),
        that = this;

      $tags.on({
        'create_tag.tags': function (e, data) {
          that.create_tag(data.value);
        },
        'remove_tag.tags': function (e) {
          that.remove_tag(e.tags_tag);
        }
      });

      $input.on('keydown', function (e) {
        if (e.which !== $.ui.keyCode.ENTER) {
          $(that.popup_denied).fadeOut();
          $(that.popup_no_find).fadeOut();
          $input.removeData('popup-denied-open');
        }
      });
      $(document).on('mousemove', function (e) {
        $(that.popup_denied).fadeOut();
        $(that.popup_no_find).fadeOut();
        $input.removeData('popup-denied-open');
      });
    },
    create_tag: function (value) {
      var that = this;
      var template = require('./templates/tag.jade');

      if (this.allow_new) {
        this._create(template, value);
      } else {
        $.ajax(url, {
            async: false,
            data: {
              label: value,
              count: that._get_count_terms_by_label(value)
            },
            success: function (data, text_status, jq_xhr) {
              var popup;

              if ($.parseJSON(data)) {
                that._create(template, value);
              } else {
                popup = require('./popup');
                popup.denied();
              }
              $input.autocomplete('close');
            }
          }
        );
      }
    },
    remove_tag: function ($tag) {
      $tag.hide('blind', {direction: 'left'}, 'normal', function () {
        $(this).remove();
      });
    },
    _get_count_terms_by_label: function (label) {
      var $tag_text = $(tag_text),
        count = 0;

      $tag_text.each(function (i, el) {
        if ($(el).text() === label) {
          count++;
        }
      });
      return count;
    },
    _create: function (template, value) {
      $(template({value: value})).appendTo('.tag-cont');
      $input.val('');
    }
  };
})();<|endoftext|>


<commit_before>/**
 * Author: Zeta Ret, Ivo Yankulovski
 * Zeta Ret ProtoSS
 * ProtoSS Class/Interface/Header Manager
 * Requires: protoss.all.js v1.02c
 * Version: 1.04b
 * Date: 2017
**/
window.internal(
function ProtoSS(){
	var o=this,a=arguments;
	o.autoImplement=true;
	o.autoSuper=true;
	o.autoSuperList=true;
	o.autoSuperList2=true;
	o.super(a);
	var m={};
	m.toInterface=function(i, pack){
		var imap={},key;
		for(key in i){
			if (key=="__name")continue;
			imap[key]=i[key].interface(key);
			if (pack)pack.internal(imap[key]);
		}
		return imap;
	};
	m.stringPattern=function(pat, str, pos){
	    if(!pos)pos=0;
	    var num=0;
		while(str.indexOf(pat, pos)==pos){
			num++;
			str=str.substr(0,pos)+str.substr(pos+pat.length,str.length);
		}
		return [num,str];
	};
	m.getSuperCls=function(sname, toppack, path){
		var many=sname.split("|"),
			cls=null,i,sn,tp,sp,pathsplit,s;
		for(i=0;i<many.length;i++){
			sn=many[i];
			tp=toppack;
			sp=o.stringPattern("/",sn);
			if (path && sp[0]>0){
				pathsplit=path.split(".");
				tp=tp.package(pathsplit.slice(0, pathsplit.length-sp[0]+1).join("."));
			}
			s=sp[1].split("::");
			if (s.length==1){
				cls=tp[s[0]];
				if(cls)return cls;
			}
			cls=tp.package(s[0])[s[1]];
			if(cls)return cls;
		}
		return cls;
	};
	m.resolveCls=function(s, toppack, path){
		var k,sk,kk,skk,i;
		for(k in s){
			if (k=="__name")continue;
			sk=s[k];
			for(kk in sk){
				skk=sk[kk];
				for(i=0;i<skk.length;i++){
					if (skk[i].constructor==String){
						skk[i]=o.getSuperCls(skk[i], toppack, path);
					}
				}
			}
		}
		return o;
	};
	m.resolveHeaders=function(toppack, path){
		var i,j,v,vl,c1,c2,sla,ia,sl,sa;
		if(o.autoImplement){
			ia=[];
			for(i=0;i<ProtoSS.headerImplement.length;i++){
				v=ProtoSS.headerImplement[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				c2=o.getSuperCls(v[1], toppack, path);
				if (c2)c1.implement(c2);
				else ia.push(v);
			}
			ProtoSS.headerImplement=ia;
		}
		if(o.autoSuper){
			sa=[];
			for(i=0;i<ProtoSS.headerSuper.length;i++){
				v=ProtoSS.headerSuper[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				c2=o.getSuperCls(v[1], toppack, path);
				if (c2)c1.setSuper(c2);
				else sa.push(v);
			}
			ProtoSS.headerSuper=sa;
		}
		if(o.autoSuperList){
			sla=[];
			for(i=0;i<ProtoSS.headerSuperList.length;i++){
				v=ProtoSS.headerSuperList[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				vl=v[1];
				sl=[];
				for(j=0;j<vl.length;j++){
					c2=o.getSuperCls(vl[j], toppack, path);
					if (c2)sl.push(c2);
					else {
						sla.push(v);
						break;
					}
				}
				if (sl.length==vl.length){
					c1.superList(sl);
				}
			}
			ProtoSS.headerSuperList=sla;
		}
		if(o.autoSuperList2){
			sla=[];
			for(i=0;i<ProtoSS.headerSuperList2.length;i++){
				v=ProtoSS.headerSuperList2[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				vl=v[1];
				sl=[];
				for(j=0;j<vl.length;j++){
					c2=o.getSuperCls(vl[j], toppack, path);
					if (c2)sl.push(c2);
					else {
						sla.push(v);
						break;
					}
				}
				if (sl.length==vl.length){
					c1.superList2(sl);
				}
			}
			ProtoSS.headerSuperList2=sla;
		}
		return o;
	};
	o.superize(a,m,true,true);
	return o;
}
);
ProtoSS.headerImplement=[];
ProtoSS.headerSuper=[];
ProtoSS.headerSuperList=[];
ProtoSS.headerSuperList2=[];
ProtoSS.stringmap={};
ProtoSS.eventProps=function(event, props){
	var l=props.length,i,p,pu;
	event.eventprops=props;
	for(i=0;i<l;i++){
		p=props[i];
		pu=p.toUpperCase();
		event[pu]=p;
		event[pu+"_CHANGE"]=p+"Change";
	}
	return event;
};
ProtoSS.staticProps=function(stat, props){
	var k;
	for(k in props)stat[k]=props[k];
	return stat;
};
ProtoSS.getDefinitionByName=function(sname, toppack){
	if(!toppack)toppack=window;
	var many=sname.split("|"),
		cls=null,i,sn,tp,s;
	for(i=0;i<many.length;i++){
		sn=many[i];
		tp=toppack;
		s=sn.split("::");
		if (s.length==1){
			cls=tp[s[0]];
			if(cls)return cls;
		}
		cls=tp.package(s[0])[s[1]];
		if(cls)return cls;
	}
	return cls;
};<commit_msg>Update ProtoSS.js<commit_after>/**
 * Author: Zeta Ret, Ivo Yankulovski
 * Zeta Ret ProtoSS
 * ProtoSS Class/Interface/Header Manager
 * Requires: protoss.all.js v1.04a
 * Version: 1.04c
 * Date: 2017 - Today
**/
window.internal(
function ProtoSS(){
	var o=this,a=arguments;
	o.autoImplement=true;
	o.autoSuper=true;
	o.autoSuperList=true;
	o.autoSuperList2=true;
	o.errorData=null;
	o.debug=null;
	o.super(a);
	var m={};
	m.toInterface=function(i, pack){
		var imap={},key;
		for(key in i){
			if (key=="__name")continue;
			imap[key]=i[key].interface(key);
			if (pack)pack.internal(imap[key]);
		}
		return imap;
	};
	m.stringPattern=function(pat, str, pos){
	    if(!pos)pos=0;
	    var num=0;
		while(str.indexOf(pat, pos)==pos){
			num++;
			str=str.substr(0,pos)+str.substr(pos+pat.length,str.length);
		}
		return [num,str];
	};
	m.getSuperCls=function(sname, toppack, path){
		var many=sname.split("|"),
			cls=null,i,sn,tp,sp,pathsplit,s;
		for(i=0;i<many.length;i++){
			sn=many[i];
			tp=toppack;
			sp=o.stringPattern("/",sn);
			if (path && sp[0]>0){
				pathsplit=path.split(".");
				tp=tp.package(pathsplit.slice(0, pathsplit.length-sp[0]+1).join("."));
			}
			s=sp[1].split("::");
			if (s.length==1){
				cls=tp[s[0]];
				if(cls)return cls;
			}
			cls=tp.package(s[0])[s[1]];
			if(cls)return cls;
		}
		return cls;
	};
	m.resolveCls=function(s, toppack, path){
		var k,sk,kk,skk,i;
		for(k in s){
			if (k=="__name")continue;
			sk=s[k];
			for(kk in sk){
				skk=sk[kk];
				for(i=0;i<skk.length;i++){
					if (skk[i].constructor==String){
						skk[i]=o.getSuperCls(skk[i], toppack, path);
					}
				}
			}
		}
		return o;
	};
	m.resolveHeaders=function(toppack, path, protoss){
		var i,j,v,vl,c1,c2,sla,ia,sl,sa,ta;
		try{
		if(o.autoImplement){
			ia=[];
			ta=ProtoSS.headerImplement;
			for(i=0;i<ta.length;i++){
				v=ta[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				c2=o.getSuperCls(v[1], toppack, path);
				if (c2)c1.implement(protoss?c2.__protoss||c2:c2);
				else ia.push(v);
			}
			ProtoSS.headerImplement=ia;
		}
		if(o.autoSuper){
			sa=[];
			ta=ProtoSS.headerSuper;
			for(i=0;i<ta.length;i++){
				v=ta[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				c2=o.getSuperCls(v[1], toppack, path);
				if (c2)c1.setSuper(protoss?c2.__protoss||c2:c2);
				else sa.push(v);
			}
			ProtoSS.headerSuper=sa;
		}
		if(o.autoSuperList){
			sla=[];
			ta=ProtoSS.headerSuperList;
			for(i=0;i<ta.length;i++){
				v=ta[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				vl=v[1];
				sl=[];
				for(j=0;j<vl.length;j++){
					c2=o.getSuperCls(vl[j], toppack, path);
					if (c2)sl.push(protoss?c2.__protoss||c2:c2);
					else {
						sla.push(v);
						break;
					}
				}
				if (sl.length==vl.length){
					c1.superList(sl);
				}
			}
			ProtoSS.headerSuperList=sla;
		}
		if(o.autoSuperList2){
			sla=[];
			ta=ProtoSS.headerSuperList2;
			for(i=0;i<ta.length;i++){
				v=ta[i];
				c1=v[0];
				if(c1.constructor===String)c1=o.getSuperCls(c1, toppack, path);
				vl=v[1];
				sl=[];
				for(j=0;j<vl.length;j++){
					c2=o.getSuperCls(vl[j], toppack, path);
					if (c2)sl.push(protoss?c2.__protoss||c2:c2);
					else {
						sla.push(v);
						break;
					}
				}
				if (sl.length==vl.length){
					c1.superList2(sl);
				}
			}
			ProtoSS.headerSuperList2=sla;
		}
		} catch(e){
			o.errorData=[ta,ta[i-1],i,j,v,vl,c1,c2,sla,ia,sl,sa];
			if(o.debug)o.debug("error", "resolveHeaders", o, o.errorData);
			throw(e);
		}

		return o;
	};
	o.superize(a,m,true,true);
	return o;
}
);
ProtoSS.headerImplement=[];
ProtoSS.headerSuper=[];
ProtoSS.headerSuperList=[];
ProtoSS.headerSuperList2=[];
ProtoSS.stringmap={};
ProtoSS.eventProps=function(event, props){
	var l=props.length,i,p,pu;
	event.eventprops=props;
	for(i=0;i<l;i++){
		p=props[i];
		pu=p.toUpperCase();
		event[pu]=p;
		event[pu+"_CHANGE"]=p+"Change";
	}
	return event;
};
ProtoSS.staticProps=function(stat, props){
	var k;
	for(k in props)stat[k]=props[k];
	return stat;
};
ProtoSS.getDefinitionByName=function(sname, toppack){
	if(!toppack)toppack=window;
	var many=sname.split("|"),
		cls=null,i,sn,tp,s;
	for(i=0;i<many.length;i++){
		sn=many[i];
		tp=toppack;
		s=sn.split("::");
		if (s.length==1){
			cls=tp[s[0]];
			if(cls)return cls;
		}
		cls=tp.package(s[0])[s[1]];
		if(cls)return cls;
	}
	return cls;
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

var utils = require('./utils'),
    fs = require('fs'),
    path = require('path'),
    esprima = require('esprima'),
    escodegen = require('escodegen'),
    ast = require('./ast'),
    q = require('q'),

    SRC_DIR = path.join( __dirname, 'src' ),
    EXERCISES_DIR = path.join( SRC_DIR, 'exercises' ),
    STARTER_REPO_DIR = path.join( SRC_DIR, 'starter_repo' ),
    REPO_TMP = path.join( STARTER_REPO_DIR, 'template' ),
    REPO_CONTENTS = path.join( STARTER_REPO_DIR, 'contents' ),
    RESOURCES_DIR_NAME = 'resources',

    GEN_DIR = path.join( __dirname, 'exercises' ),
    REPO_DIR_NAME = 'starting.git',
    MACHINES_FILE = path.join( __dirname, 'machines.js' ),
    VIEWERS_FILE = path.join( __dirname, 'viewers.js' ),
    REPOS_FILE = path.join( __dirname, 'repos.js' ),

    ANGLER_URL = 'http://localhost/hooks';

function createNewRepo( repoDir ) {
    return utils.cp( REPO_CONTENTS, repoDir )
    .then( function() {
        return utils.git( __dirname, 'init', [ '--template=' + REPO_TMP, repoDir ] );
    })
    .then( function() {
        return utils.git( repoDir, 'config', [ 'angler.url', ANGLER_URL ] );
    })
    .then( function() {
        return utils.git( repoDir, 'config', [ 'receive.denyCurrentBranch', 'false' ] );
    });
}

function createExerciseDir( currentExercise ) {
    // copy the exercise resources into the output dir
    var resourcesDir = path.join( EXERCISES_DIR, currentExercise, RESOURCES_DIR_NAME ),
        outputDir = path.join( GEN_DIR, currentExercise ),
        repoPath = path.join( outputDir, REPO_DIR_NAME ),

        pending = [
            q.nfcall( fs.stat, resourcesDir )
            .then( function() {
                return utils.cp( resourcesDir, outputDir );
            })
            .catch( function() { /* do nothing */  }),
            createNewRepo( repoPath )
        ];

    return q.all( pending );
}

utils.getExercises()
.done( function( exerciseConfs ) {
    return q.nfcall( fs.mkdir, GEN_DIR )
    .done( function() {
        var machines = [],
            viewers = [],
            repos = [],
            outputDir;

        // split the configs
        Object.keys( exerciseConfs ).forEach( function( exercise ) {
            var exerciseConf = require( exerciseConfs[ exercise ].path ),
                confAst = esprima.parse( exerciseConfs[ exercise ].data ),
                combinedScopeExprs = ast.getCombinedScopeExprs( confAst ),
                confTrees = ast.getConfSubtrees( confAst );

            // make the output directory
            outputDir = path.join( GEN_DIR, exercise );
            q.nfcall( fs.mkdir, outputDir )
            .done( function() {
                return createExerciseDir( exercise, exerciseConf );
            });

            function mkConfSubmodule( confAst ) {
                var submodule = ast.createSubmodule( combinedScopeExprs, confAst );
                return ast.createProperty( exercise, submodule );
            }

            machines.push( mkConfSubmodule( confTrees.machine ) );
            viewers.push( mkConfSubmodule( confTrees.viewer ) );
            repos.push( mkConfSubmodule( confTrees.repo || ast.createObject([]) ) );
        });

        function writeMod( file, props ) {
            var mod = ast.createModule( null, ast.createObject( props ) );
            fs.writeFile( file, escodegen.generate( mod ) );
        }

        // write out the split configs
        writeMod( MACHINES_FILE, machines );
        writeMod( VIEWERS_FILE, viewers );
        writeMod( REPOS_FILE, repos );
    });
});
<commit_msg>Starting repo starts with base files added<commit_after>#!/usr/bin/env node

'use strict';

var utils = require('./utils'),
    fs = require('fs'),
    path = require('path'),
    esprima = require('esprima'),
    escodegen = require('escodegen'),
    ast = require('./ast'),
    q = require('q'),

    SRC_DIR = path.join( __dirname, 'src' ),
    EXERCISES_DIR = path.join( SRC_DIR, 'exercises' ),
    STARTER_REPO_DIR = path.join( SRC_DIR, 'starter_repo' ),
    REPO_TMP = path.join( STARTER_REPO_DIR, 'template' ),
    REPO_CONTENTS = path.join( STARTER_REPO_DIR, 'contents' ),
    RESOURCES_DIR_NAME = 'resources',

    GEN_DIR = path.join( __dirname, 'exercises' ),
    REPO_DIR_NAME = 'starting.git',
    MACHINES_FILE = path.join( __dirname, 'machines.js' ),
    VIEWERS_FILE = path.join( __dirname, 'viewers.js' ),
    REPOS_FILE = path.join( __dirname, 'repos.js' ),

    ANGLER_URL = 'http://localhost/hooks';

function createNewRepo( repoDir ) {
    var git = utils.git.bind( null, repoDir );

    return utils.cp( REPO_CONTENTS, repoDir )
    .then( function() {
        return utils.git( __dirname, 'init', [ '--template=' + REPO_TMP, repoDir ] );
    })
    .then( function() {
        return git( 'config', [ 'angler.url', ANGLER_URL ] );
    })
    .then( function() {
        return git( 'config', [ 'receive.denyCurrentBranch', 'false' ] );
    })
    .then( function() {
        return git( 'add', ':/' );
    });
}

function createExerciseDir( currentExercise ) {
    // copy the exercise resources into the output dir
    var resourcesDir = path.join( EXERCISES_DIR, currentExercise, RESOURCES_DIR_NAME ),
        outputDir = path.join( GEN_DIR, currentExercise ),
        repoPath = path.join( outputDir, REPO_DIR_NAME ),

        pending = [
            q.nfcall( fs.stat, resourcesDir )
            .then( function() {
                return utils.cp( resourcesDir, outputDir );
            })
            .catch( function() { /* do nothing */  }),
            createNewRepo( repoPath )
        ];

    return q.all( pending );
}

utils.getExercises()
.done( function( exerciseConfs ) {
    return q.nfcall( fs.mkdir, GEN_DIR )
    .done( function() {
        var machines = [],
            viewers = [],
            repos = [],
            outputDir;

        // split the configs
        Object.keys( exerciseConfs ).forEach( function( exercise ) {
            var exerciseConf = require( exerciseConfs[ exercise ].path ),
                confAst = esprima.parse( exerciseConfs[ exercise ].data ),
                combinedScopeExprs = ast.getCombinedScopeExprs( confAst ),
                confTrees = ast.getConfSubtrees( confAst );

            // make the output directory
            outputDir = path.join( GEN_DIR, exercise );
            q.nfcall( fs.mkdir, outputDir )
            .done( function() {
                return createExerciseDir( exercise, exerciseConf );
            });

            function mkConfSubmodule( confAst ) {
                var submodule = ast.createSubmodule( combinedScopeExprs, confAst );
                return ast.createProperty( exercise, submodule );
            }

            machines.push( mkConfSubmodule( confTrees.machine ) );
            viewers.push( mkConfSubmodule( confTrees.viewer ) );
            repos.push( mkConfSubmodule( confTrees.repo || ast.createObject([]) ) );
        });

        function writeMod( file, props ) {
            var mod = ast.createModule( null, ast.createObject( props ) );
            fs.writeFile( file, escodegen.generate( mod ) );
        }

        // write out the split configs
        writeMod( MACHINES_FILE, machines );
        writeMod( VIEWERS_FILE, viewers );
        writeMod( REPOS_FILE, repos );
    });
});
<|endoftext|>


<commit_before>// @AngularClass

exports.config = {
  baseUrl: 'http://localhost:3000/',

  // use `npm run e2e`
  specs: [
    'src/**/**.e2e.ts',
    'src/**/*.e2e.ts'
  ],
  exclude: [],

  framework: 'jasmine',

  allScriptsTimeout: 110000,

  jasmineNodeOpts: {
    showTiming: true,
    showColors: true,
    isVerbose: false,
    includeStackTrace: false,
    defaultTimeoutInterval: 400000
  },
  directConnect: true,

  capabilities: {
    'browserName': 'chrome',
    'chromeOptions': {
      'args': ['show-fps-counter=true']
    }
  },

  onPrepare: function() {
    browser.ignoreSynchronization = true;
  },

  seleniumServerJar: "node_modules/protractor/selenium/selenium-server-standalone-2.48.2.jar",

  /**
   * Angular 2 configuration
   *
   * useAllAngular2AppRoots: tells Protractor to wait for any angular2 apps on the page instead of just the one matching
   * `rootEl`
   *
   */
   useAllAngular2AppRoots: true
};
<commit_msg>updated protractor config<commit_after>// @AngularClass

exports.config = {
  baseUrl: 'http://localhost:3000/',

  // use `npm run e2e`
  specs: [
	'src/**/**.e2e.ts',
	'src/**/*.e2e.ts'
  ],
  exclude: [],

  framework: 'jasmine',

  allScriptsTimeout: 110000,

  jasmineNodeOpts: {
	showTiming: true,
	showColors: true,
	isVerbose: false,
	includeStackTrace: false,
	defaultTimeoutInterval: 400000
  },
  directConnect: true,

  capabilities: {
	'browserName': 'chrome',
	'chromeOptions': {
	  'args': ['show-fps-counter=true']
	}
  },

  onPrepare: function() {
	browser.ignoreSynchronization = true;
  },

  seleniumServerJar: "node_modules/protractor/selenium/selenium-server-standalone-2.48.2.jar",

  /**
   * Angular 2 configuration
   *
   * useAllAngular2AppRoots: tells Protractor to wait for any angular2 apps on the page instead of just the one matching
   * `rootEl`
   *
   */
   useAllAngular2AppRoots: false
};
<|endoftext|>


<commit_before>'use strict';

const Code = require('code');
const Lab = require('lab');
const rewire = require('rewire');
const sinon = require('sinon');
const EventEmitter = require('events').EventEmitter;
var MongooseConnector = rewire('../lib/MongooseConnector');
// This is required to trick lab coverage
var MongooseConnector2 = require('../lib/MongooseConnector'); //eslint-disable-line
MongooseConnector2 = MongooseConnector;

const lab = exports.lab = Lab.script();
const describe = lab.describe;
const it = lab.it;
const beforeEach = lab.beforeEach;
const expect = Code.expect;

describe('Default Options', () => {
  let mongooseConnector, mongooseEmitter, logSpy, pluginStub;
  let MongooseEmitter = require('./artifacts/MongooseEmitter');

  beforeEach(done => {
    mongooseEmitter = new MongooseEmitter('connected');
    pluginStub = {
      log: log => log
    };
    logSpy = sinon.spy(pluginStub, 'log');
    MongooseConnector.__set__('mongoose', mongooseEmitter);
    mongooseConnector = new MongooseConnector({async: false}, pluginStub);
    done();
  });

  it('is an instance of EventEmitter', done => {
    expect(mongooseConnector instanceof EventEmitter).to.equal(true);

    done();
  });

  it('s connection property is an instance of EventEmitter', done => {
    expect(mongooseConnector.connection instanceof EventEmitter).to.equal(true);

    done();
  });

  it('logs a connection event', done => {
    setTimeout(() => {
      const args = logSpy.getCall(0).args;

      expect(args[0][0]).to.equal('info');
      expect(args[1]).to.equal('Connected');

      done();
    }, 2);
  });
});

describe('With Async (bluebird)', () => {
  let mongooseConnector, mongooseEmitter, pluginStub; //eslint-disable-line
  let MongooseEmitter = require('./artifacts/MongooseEmitter');

  beforeEach(done => {
    mongooseEmitter = new MongooseEmitter('connected');
    pluginStub = {
      log: log => log
    };
    MongooseConnector.__set__('mongoose', mongooseEmitter);
    mongooseConnector = new MongooseConnector({async: true}, pluginStub);
    done();
  });

  it('is an instance of EventEmitter', done => {
    expect(typeof mongooseEmitter.createConnectionAsync).to.equal('function');

    done();
  });
});

describe('Default Options with failed connection', () => {
  let mongooseConnector, mongooseEmitter, logSpy, pluginStub;
  let MongooseEmitter = require('./artifacts/MongooseEmitter');

  beforeEach(done => {
    mongooseEmitter = new MongooseEmitter('error', {message: 'test'});
    pluginStub = {
      log: log => log
    };
    logSpy = sinon.spy(pluginStub, 'log');
    MongooseConnector.__set__('mongoose', mongooseEmitter);
    mongooseConnector = new MongooseConnector({async: false}, pluginStub);
    mongooseConnector.on('error', err => err);
    done();
  });

  it('emits an error event from Connector', done => {
    mongooseConnector.on('error', err => {
      expect(err.message).to.equal('test');

      done();
    });
  });

  it('logs a connection event', done => {
    setTimeout(() => {
      const args = logSpy.getCall(0).args;

      expect(args[0][0]).to.equal('error');
      expect(args[1]).to.equal('Unable to connect to database: test');

      done();
    }, 3); // TODO : Avoid using a timeout for events
  });
});

describe('Default Options with closed connection', () => {
  let mongooseConnector, mongooseEmitter, logSpy, pluginStub;
  let MongooseEmitter = require('./artifacts/MongooseEmitter');

  beforeEach(done => {
    mongooseEmitter = new MongooseEmitter('close');
    pluginStub = {
      log: log => log
    };
    logSpy = sinon.spy(pluginStub, 'log');
    MongooseConnector.__set__('mongoose', mongooseEmitter);
    mongooseConnector = new MongooseConnector({async: false}, pluginStub);
    mongooseConnector.on('error', err => err);
    done();
  });

  it('logs a connection event', done => {
    setTimeout(() => {
      const args = logSpy.getCall(0).args;

      expect(args[0][0]).to.equal('info');
      expect(args[1]).to.equal('Connection to database closed');

      done();
    }, 2);
  });
});

describe('Default Options with disconnected connection', () => {
  let mongooseConnector, mongooseEmitter, logSpy, pluginStub;
  let MongooseEmitter = require('./artifacts/MongooseEmitter');

  beforeEach(done => {
    mongooseEmitter = new MongooseEmitter('disconnected');
    pluginStub = {
      log: log => log
    };
    logSpy = sinon.spy(pluginStub, 'log');
    MongooseConnector.__set__('mongoose', mongooseEmitter);
    mongooseConnector = new MongooseConnector({async: false}, pluginStub);
    mongooseConnector.on('error', err => err);
    done();
  });

  it('logs a connection event', done => {
    setTimeout(() => {
      const args = logSpy.getCall(0).args;

      expect(args[0][0]).to.equal('warn');
      expect(args[1]).to.equal('Connection to database disconnected');

      done();
    }, 2);
  });
});
<commit_msg>More timeout time<commit_after>'use strict';

const Code = require('code');
const Lab = require('lab');
const rewire = require('rewire');
const sinon = require('sinon');
const EventEmitter = require('events').EventEmitter;
var MongooseConnector = rewire('../lib/MongooseConnector');
// This is required to trick lab coverage
var MongooseConnector2 = require('../lib/MongooseConnector'); //eslint-disable-line
MongooseConnector2 = MongooseConnector;

const lab = exports.lab = Lab.script();
const describe = lab.describe;
const it = lab.it;
const beforeEach = lab.beforeEach;
const expect = Code.expect;

describe('Default Options', () => {
  let mongooseConnector, mongooseEmitter, logSpy, pluginStub;
  let MongooseEmitter = require('./artifacts/MongooseEmitter');

  beforeEach(done => {
    mongooseEmitter = new MongooseEmitter('connected');
    pluginStub = {
      log: log => log
    };
    logSpy = sinon.spy(pluginStub, 'log');
    MongooseConnector.__set__('mongoose', mongooseEmitter);
    mongooseConnector = new MongooseConnector({async: false}, pluginStub);
    done();
  });

  it('is an instance of EventEmitter', done => {
    expect(mongooseConnector instanceof EventEmitter).to.equal(true);

    done();
  });

  it('s connection property is an instance of EventEmitter', done => {
    expect(mongooseConnector.connection instanceof EventEmitter).to.equal(true);

    done();
  });

  it('logs a connection event', done => {
    setTimeout(() => {
      const args = logSpy.getCall(0).args;

      expect(args[0][0]).to.equal('info');
      expect(args[1]).to.equal('Connected');

      done();
    }, 2);
  });
});

describe('With Async (bluebird)', () => {
  let mongooseConnector, mongooseEmitter, pluginStub; //eslint-disable-line
  let MongooseEmitter = require('./artifacts/MongooseEmitter');

  beforeEach(done => {
    mongooseEmitter = new MongooseEmitter('connected');
    pluginStub = {
      log: log => log
    };
    MongooseConnector.__set__('mongoose', mongooseEmitter);
    mongooseConnector = new MongooseConnector({async: true}, pluginStub);
    done();
  });

  it('is an instance of EventEmitter', done => {
    expect(typeof mongooseEmitter.createConnectionAsync).to.equal('function');

    done();
  });
});

describe('Default Options with failed connection', () => {
  let mongooseConnector, mongooseEmitter, logSpy, pluginStub;
  let MongooseEmitter = require('./artifacts/MongooseEmitter');

  beforeEach(done => {
    mongooseEmitter = new MongooseEmitter('error', {message: 'test'});
    pluginStub = {
      log: log => log
    };
    logSpy = sinon.spy(pluginStub, 'log');
    MongooseConnector.__set__('mongoose', mongooseEmitter);
    mongooseConnector = new MongooseConnector({async: false}, pluginStub);
    mongooseConnector.on('error', err => err);
    done();
  });

  it('emits an error event from Connector', done => {
    mongooseConnector.on('error', err => {
      expect(err.message).to.equal('test');

      done();
    });
  });

  it('logs a connection event', done => {
    setTimeout(() => {
      const args = logSpy.getCall(0).args;

      expect(args[0][0]).to.equal('error');
      expect(args[1]).to.equal('Unable to connect to database: test');

      done();
    }, 100); // TODO : Avoid using a timeout for events
  });
});

describe('Default Options with closed connection', () => {
  let mongooseConnector, mongooseEmitter, logSpy, pluginStub;
  let MongooseEmitter = require('./artifacts/MongooseEmitter');

  beforeEach(done => {
    mongooseEmitter = new MongooseEmitter('close');
    pluginStub = {
      log: log => log
    };
    logSpy = sinon.spy(pluginStub, 'log');
    MongooseConnector.__set__('mongoose', mongooseEmitter);
    mongooseConnector = new MongooseConnector({async: false}, pluginStub);
    mongooseConnector.on('error', err => err);
    done();
  });

  it('logs a connection event', done => {
    setTimeout(() => {
      const args = logSpy.getCall(0).args;

      expect(args[0][0]).to.equal('info');
      expect(args[1]).to.equal('Connection to database closed');

      done();
    }, 2);
  });
});

describe('Default Options with disconnected connection', () => {
  let mongooseConnector, mongooseEmitter, logSpy, pluginStub;
  let MongooseEmitter = require('./artifacts/MongooseEmitter');

  beforeEach(done => {
    mongooseEmitter = new MongooseEmitter('disconnected');
    pluginStub = {
      log: log => log
    };
    logSpy = sinon.spy(pluginStub, 'log');
    MongooseConnector.__set__('mongoose', mongooseEmitter);
    mongooseConnector = new MongooseConnector({async: false}, pluginStub);
    mongooseConnector.on('error', err => err);
    done();
  });

  it('logs a connection event', done => {
    setTimeout(() => {
      const args = logSpy.getCall(0).args;

      expect(args[0][0]).to.equal('warn');
      expect(args[1]).to.equal('Connection to database disconnected');

      done();
    }, 2);
  });
});
<|endoftext|>