<commit_before>import React, { Component } from 'react';

import AVAILABLE_CONFIGS from 'Parser/AVAILABLE_CONFIGS';

import PatreonLink from './PatreonLink';
import Changelog from './Changelog';

class ReportSelecter extends Component {
  static propTypes = {
    onSubmit: React.PropTypes.func.isRequired,
  };

  codeInput = null;

  constructor() {
    super();
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  componentDidMount() {
    this.codeInput.focus();
  }

  handleSubmit(e) {
    const { onSubmit } = this.props;

    e.preventDefault();

    const code = this.codeInput.value;

    if (!code) {
      alert('Enter the report code.');
      return;
    }

    onSubmit(code.trim());
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit} className="form-inline">

Analyze your performance

The World of Warcraft Analyzer

                Use this tool to analyze your performance based on important metrics for the spec.

                You will need a Warcraft Logs report with advanced combat logging enabled to start. Private logs can not be used, if your guild has private logs you will have to
                {' '}upload your own logs or change the existing logs to the
                {' '}unlisted privacy option instead.

                Feature requests (<dfn data-tip="Provided that you're not using one of Microsoft's browsers.">and bug reports*</dfn>) are welcome!{' '}
                @Zerotorescue on Discord or create an issue{' '}
                <a href={`https://github.com/MartijnHols/WoWAnalyzer/issues`}>here.

Analyze report

                  The Warcraft Logs API is currently down, please try again later.

                    Experiencing an attack through the WCL Web API. For now I'm going to have to disable it completely until I can figure out how to harden it against the attack in the future.

                Enter your Warcraft Logs report code.

                https://www.warcraftlogs.com/reports/<input
                  type="text"
                  name="code"
                  className="form-control"
                  ref={(elem) => {
                    this.codeInput = elem;
                  }}
                  style={{ width: 175 }}
                  placeholder="Report code"
                  autoCorrect="off"
                  autoCapitalize="off"
                  spellCheck="false"
                />/

                <button type="submit" className="btn btn-primary">
                  Analyze
                </button>

About

                Full source is available on GitHub. Contributions are extremely welcome! Add your own module or spec if you want to be able to analyze something not yet available. The repository contains information on how to contribute, if you need any more information please join our Discord (link further below).

                The following specs are available:

                  {AVAILABLE_CONFIGS.map((config) => (

{config.spec.specName} {config.spec.className} maintained by {config.maintainer}

                  ))}

                There are no plans at this time to add support for other specs. The best way to get support for a spec is to add it yourself. Adding specs is easy if you're familiar with JavaScript (ES6), see GitHub and the WoW Analyzer Discord for more information.

                If you're looking to help out development in other ways, please consider donating.

                <PatreonLink />

Discord

                I believe it's important to keep class discussion as much in class Discords as possible, so if you have spec specific questions and/or suggestions please try to discuss them in your class Discord (class Discords mods approve of this message ). The WoW Analyzer Discord is for more general questions and developers looking to contribute.

Features

                    Item performance breakdowns

                    Suggestions for improvement

                    Important spec specific metrics

                    Cooldown usage details

                    Mana breakdown

                    Open source

Changes

                <Changelog />

      </form>
    );
  }
}

export default ReportSelecter;
<commit_msg>Remove WCL is down warning<commit_after>import React, { Component } from 'react';

import AVAILABLE_CONFIGS from 'Parser/AVAILABLE_CONFIGS';

import PatreonLink from './PatreonLink';
import Changelog from './Changelog';

class ReportSelecter extends Component {
  static propTypes = {
    onSubmit: React.PropTypes.func.isRequired,
  };

  codeInput = null;

  constructor() {
    super();
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  componentDidMount() {
    this.codeInput.focus();
  }

  handleSubmit(e) {
    const { onSubmit } = this.props;

    e.preventDefault();

    const code = this.codeInput.value;

    if (!code) {
      alert('Enter the report code.');
      return;
    }

    onSubmit(code.trim());
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit} className="form-inline">

Analyze your performance

The World of Warcraft Analyzer

                Use this tool to analyze your performance based on important metrics for the spec.

                You will need a Warcraft Logs report with advanced combat logging enabled to start. Private logs can not be used, if your guild has private logs you will have to
                {' '}upload your own logs or change the existing logs to the
                {' '}unlisted privacy option instead.

                Feature requests (<dfn data-tip="Provided that you're not using one of Microsoft's browsers.">and bug reports*</dfn>) are welcome!{' '}
                @Zerotorescue on Discord or create an issue{' '}
                <a href={`https://github.com/MartijnHols/WoWAnalyzer/issues`}>here.

Analyze report

                Enter your Warcraft Logs report code.

                https://www.warcraftlogs.com/reports/<input
                  type="text"
                  name="code"
                  className="form-control"
                  ref={(elem) => {
                    this.codeInput = elem;
                  }}
                  style={{ width: 175 }}
                  placeholder="Report code"
                  autoCorrect="off"
                  autoCapitalize="off"
                  spellCheck="false"
                />/

                <button type="submit" className="btn btn-primary">
                  Analyze
                </button>

About

                Full source is available on GitHub. Contributions are extremely welcome! Add your own module or spec if you want to be able to analyze something not yet available. The repository contains information on how to contribute, if you need any more information please join our Discord (link further below).

                The following specs are available:

                  {AVAILABLE_CONFIGS.map((config) => (

{config.spec.specName} {config.spec.className} maintained by {config.maintainer}

                  ))}

                There are no plans at this time to add support for other specs. The best way to get support for a spec is to add it yourself. Adding specs is easy if you're familiar with JavaScript (ES6), see GitHub and the WoW Analyzer Discord for more information.

                If you're looking to help out development in other ways, please consider donating.

                <PatreonLink />

Discord

                I believe it's important to keep class discussion as much in class Discords as possible, so if you have spec specific questions and/or suggestions please try to discuss them in your class Discord (class Discords mods approve of this message ). The WoW Analyzer Discord is for more general questions and developers looking to contribute.

Features

                    Item performance breakdowns

                    Suggestions for improvement

                    Important spec specific metrics

                    Cooldown usage details

                    Mana breakdown

                    Open source

Changes

                <Changelog />

      </form>
    );
  }
}

export default ReportSelecter;
<|endoftext|>


<commit_before>import React from 'react';
import Component from '../../Component';

class MenuItem extends Component {
    constructor(props) {
        super(props);

        this.onClick = this.onClick.bind(this);
        this.onMouseEnter = this.onMouseEnter.bind(this);
        this.onMouseLeave = this.onMouseLeave.bind(this);
    }

    render() {
        return (
            <div
                className={this.className()}
                onClick={this.onClick}
                onMouseEnter={this.onMouseEnter}
                onMouseLeave={this.onMouseLeave}
            >
                {this.props.children}
            </div>
        );
    }

    className() {
        let className = 'menu-item';

        const theme = this.props.theme || this.context.theme;
        if (theme) {
            className += ' menu-item_theme_' + theme;
        }
        if (this.props.size) {
            className += ' menu-item_size_' + this.props.size;
        }
        if (this.props.disabled) {
            className += ' menu-item_disabled';
        }
        if (this.props.hovered) {
            className += ' menu-item_hovered';
        }
        if (this.props.checked) {
            className += ' menu-item_checked';
        }

        if (this.props.className) {
            className += ' ' + this.props.className;
        }

        return className;
    }

    onClick(e) {
        if (this.props.disabled) {
            return;
        }

        this.props.onClick(e, this.props);
    }

    onMouseEnter() {
        if (this.props.disabled) {
            return;
        }

        this.props.onHover(true, this.props);
    }

    onMouseLeave() {
        if (this.props.disabled) {
            return;
        }

        this.props.onHover(false, this.props);
    }
}

MenuItem.contextTypes = {
    theme: React.PropTypes.string,
};

MenuItem.propTypes = {
    index: React.PropTypes.number,
    theme: React.PropTypes.string,
    size: React.PropTypes.string,
    disabled: React.PropTypes.bool,
    checked: React.PropTypes.bool,
    onClick: React.PropTypes.func,
    onHover: React.PropTypes.func,
};

export default MenuItem;
<commit_msg>Menu-Item: add type property<commit_after>import React from 'react';
import Component from '../../Component';

class MenuItem extends Component {
    constructor(props) {
        super(props);

        this.onClick = this.onClick.bind(this);
        this.onMouseEnter = this.onMouseEnter.bind(this);
        this.onMouseLeave = this.onMouseLeave.bind(this);
    }

    render() {
        return (
            <div
                className={this.className()}
                onClick={this.onClick}
                onMouseEnter={this.onMouseEnter}
                onMouseLeave={this.onMouseLeave}
            >
                {this.props.children}
            </div>
        );
    }

    className() {
        let className = 'menu-item';

        const theme = this.props.theme || this.context.theme;
        if (theme) {
            className += ' menu-item_theme_' + theme;
        }
        if (this.props.size) {
            className += ' menu-item_size_' + this.props.size;
        }
        if (this.props.type) {
            className += ' menu-item_type_' + this.props.type;
        }
        if (this.props.disabled) {
            className += ' menu-item_disabled';
        }
        if (this.props.hovered) {
            className += ' menu-item_hovered';
        }
        if (this.props.checked) {
            className += ' menu-item_checked';
        }

        if (this.props.className) {
            className += ' ' + this.props.className;
        }

        return className;
    }

    onClick(e) {
        if (this.props.disabled) {
            return;
        }

        this.props.onClick(e, this.props);
    }

    onMouseEnter() {
        if (this.props.disabled) {
            return;
        }

        this.props.onHover(true, this.props);
    }

    onMouseLeave() {
        if (this.props.disabled) {
            return;
        }

        this.props.onHover(false, this.props);
    }
}

MenuItem.contextTypes = {
    theme: React.PropTypes.string,
};

MenuItem.propTypes = {
    index: React.PropTypes.number,
    theme: React.PropTypes.string,
    size: React.PropTypes.string,
    type: React.PropTypes.string,
    disabled: React.PropTypes.bool,
    checked: React.PropTypes.bool,
    onClick: React.PropTypes.func,
    onHover: React.PropTypes.func,
};

export default MenuItem;
<|endoftext|>


<commit_before>/**
 * Created by gr100287 on 12/05/14.
 */
/*jslint browser: true*/
/*global $, jQuery, alert*/

/* classe menu */
var Scores = function () {
    "use strict";

    /* singleton */
    if (Scores.prototype.instance) {
        return Scores.prototype.instance;
    }
    Scores.prototype.instance = this;

	function isFromGame() {
		var url = window.location.href;
		var splitted = url.split("?");
		if(splitted.length === 1) {
		   return {};
		}
		var paramList = decodeURIComponent(splitted[1]).split("&");
		var params = {};
		for(var i = 0; i < paramList.length; i++) {
			var paramTuple = paramList[i].split("=");
			if (paramTuple[0] == "fromgame") {return true;}
		}
		return false;
	}

    $("body").keypress(function (event) {

        switch (event.keyCode) {
            //escape
            case 27:
                event.preventDefault();
                cancel();
                break;
			case 0 :
				switch (event.charCode) {
					// D : gauche
					case 100:
						event.preventDefault();
						cancel();
						break;
				}
				break;
        }

    });

    function cancel() {
		if (isFromGame()){
			console.log("cancel from game");
			$(location).attr('href', "./jouer.html");
		}
        else {
			console.log("cancel from menu");
			$(location).attr('href', "./index.html");
		}

    }

};

var scores = new Scores();

<commit_msg>no message<commit_after>/**
 * Created by gr100287 on 12/05/14.
 */
/*jslint browser: true*/
/*global $, jQuery, alert*/

/* classe menu */
var Scores = function () {
    "use strict";

    /* singleton */
    if (Scores.prototype.instance) {
        return Scores.prototype.instance;
    }
    Scores.prototype.instance = this;

	function isFromGame() {
		var url = window.location.href;
		var splitted = url.split("?");
		if(splitted.length === 1) {
		   return false;
		}
		var paramList = decodeURIComponent(splitted[1]).split("&");
		var params = {};
		for(var i = 0; i < paramList.length; i++) {
			var paramTuple = paramList[i].split("=");
			if (paramTuple[0] == "fromgame") {return true;}
		}
		return false;
	}

    $("body").keypress(function (event) {

        switch (event.keyCode) {
            //escape
            case 27:
                event.preventDefault();
                cancel();
                break;
			case 0 :
				switch (event.charCode) {
					// D : gauche
					case 100:
						event.preventDefault();
						cancel();
						break;
				}
				break;
        }

    });

    function cancel() {
		if (isFromGame()){
			console.log("cancel from game");
			$(location).attr('href', "./jouer.html");
		}
        else {
			console.log("cancel from menu");
			$(location).attr('href', "./index.html");
		}

    }

};

var scores = new Scores();

<|endoftext|>


<commit_before>(function () {
  var callDepth = 0;
  var locked = function () {
    return !callDepth;
  };
  var protect = function (_O) {
    var O = _O.prototype || _O;
    Object.keys(O)
    .forEach(function (key) {
        var original = O[key];
        var isFunction = typeof original === 'function';
        if (key.indexOf('_') === 0) {
          Object.defineProperty(O, key, {
            get: function () {
              if (locked()) {
                return undefined;
              }
              else {
                if (!isFunction) {
                  return original;
                }
                return function () {
                  return original.apply(this, arguments);
                };
              }
            },
            set: function () {
              if (!locked()) {
                original = arguments[0];
              }
            },
            enumerable: false
          });
        }
        else {
          Object.defineProperty(O, key, {
            get: function () {
              if (!isFunction) {
                return original;
              }
              return function () {
                var result;
                try {
                  callDepth++;
                  result = original.apply(this, arguments);
                }
                catch (e) {
                  throw e;
                }
                finally {
                  callDepth--;
                }
                return result;
              };
            },
            set: function () {
              original = arguments[0];
            }
          });
        }
    });
  };
  if( typeof exports !== 'undefined' ) {
    if( typeof module !== 'undefined' && module.exports ) {
      exports = module.exports = protect;
    }
    exports.protect = protect;
  }
  else {
    this.protect = protect;
  }
}).call(this);
<commit_msg>Partially tidy up<commit_after>(function () {

  var callDepth = 0; // Stores the call depth of the current execution

  var locked = function () {
    return !callDepth;
  };

  // The protect object
  var protect = function (_O) {

    var O = _O.prototype || _O; // Protect the prototype, if there is one

    Object.keys(O).forEach(function (key) {

        var value = O[key]; // The original property value
        var isFunction = typeof value === 'function';

        if (key.indexOf('_') === 0) { // Should the object be protected
          Object.defineProperty(O, key, {
            get: function () {
              if (locked()) {
                return undefined;
              }
              else {
                if (!isFunction) {
                  return value;
                }
                return function () {
                  return value.apply(this, arguments);
                };
              }
            },
            set: function () {
              if (!locked()) {
                value = arguments[0];
              }
            },
            enumerable: false // Remove from Object.keys
          });
        }
        else { // Allow functions to retrieve private properties
          Object.defineProperty(O, key, {
            get: function () {
              if (!isFunction) {
                return value;
              }
              return function () {
                var result;
                try {
                  callDepth++;
                  result = value.apply(this, arguments);
                }
                catch (e) {
                  throw e;
                }
                finally {
                  callDepth--;
                }
                return result;
              };
            },
            set: function () {
              value = arguments[0];
            }
          });
        }
    });
  };

  // Make it available for both Node and Browser
  if( typeof exports !== 'undefined' ) {
    if( typeof module !== 'undefined' && module.exports) {
      exports = module.exports = protect;
    }
    exports.protect = protect;
  }
  else {
    this.protect = protect;
  }

}).call(this);
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');

const hasOwn = Object.prototype.hasOwnProperty;

const indentSize = 4;
let indentLevel = 0;
let ostream = null;

// to dedupe some objects (like getters/setters) that may appear twice.
const seenElements = {};

// queues up some typedefs until we can just write out the interface at the end
const interfaceQueue = [];

/**
 * @param {TAFFY} data - The TaffyDB containing the data that jsdoc parsed.
 * @param {object} opts - Options passed into jsdoc.
 */
module.exports.publish = function (data, opts)
{
    // remove undocumented stuff.
    data({ undocumented: true }).remove();

    const docs = data().get();

    // ostream = fs.createWriteStream('./_temp.d.ts');
    ostream = process.stdout;

    parse(docs);

    while (interfaceQueue.length)
    {
        const element = interfaceQueue.pop();

        // comment
        writeComment(element.comment);

        writeInterfaceForObjectType(element);
    }

    // ostream.end();
};

function parse(docs, parent)
{
    findChildrenOf(docs, (parent ? parent.longname : undefined))
    .forEach((element) =>
    {
        if (element.ignore || seenElements[element.longname])
            return;

        seenElements[element.longname] = true;

        switch (element.kind)
        {
            /* eslint-disable no-multi-spaces */
            case 'class':       return handleClass(docs, element, parent);
            case 'constant':    return handleMember(docs, element, parent);
            case 'function':    return handleFunction(docs, element, parent);
            case 'interface':   return handleClass(docs, element, parent, true);
            case 'member':      return handleMember(docs, element, parent);
            case 'mixin':       return handleClass(docs, element, parent);
            case 'module':      return handleNamespace(docs, element, parent);
            case 'namespace':   return handleNamespace(docs, element, parent);
            case 'package':     return handleNamespace(docs, element, parent);
            case 'typedef':     return handleTypedef(docs, element, parent);
            /* eslint-enable no-multi-spaces */
        }

        return;
    });
}

function write(msg)
{
    if (!msg) return;

    ostream.write(msg);
}

function writeLn(msg)
{
    if (!msg) return;

    startLine();
    write(msg);
    endLine();
}

function writeComment(cmt)
{
    if (!cmt) return;

    cmt
        .split('\n')
        .map((v) => v.trim())
        .map((v) => (v.startsWith('*') ? ` ${v}` : v))
        .forEach(writeLn);
}

function startLine()
{
    const indent = (new Array(indentLevel * indentSize)).join(' ');

    write(indent);
}

function endLine()
{
    write('\n');
}

function indent()
{
    indentLevel++;
}

function unindent()
{
    indentLevel--;
}

function queueInterfaceForObjectType(element)
{
    interfaceQueue.push(element);
}

function writeInterfaceForObjectType(element)
{
    writeLn(`interface I${element.name} {`);
    indent();

    for (let i = 0; i < element.properties.length; ++i)
    {
        const p = element.properties[i];

        writeLn(`${p.name}: ${getTypeName(p)};`);
    }

    unindent();
    writeLn('}');
    endLine();
}

function writeFunctionProto(element, isConstructor, isType)
{
    // params
    write('(');

    // `this` param
    if (element.this)
    {
        write(`this: ${element.this}`);

        if (element.params && element.params.length)
            write(', ');
    }

    if (element.params)
    {
        const params = {};

        // parse params first to combine property syntaxes
        for (let i = 0; i < element.params.length; ++i)
        {
            const p = element.params[i];
            const names = p.name.split('.');

            if (names.length === 1)
                params[p.name] = p;
            else
            {
                let c = params[names[0]];

                for (let j = 1; j < names.length - 1; ++j)
                {
                    const name = names[j];

                    if (!c.properties)
                        c.properties = {};

                    if (!c.properties[name])
                        c.properties[name] = {};

                    c = c.properties[name];
                }

                const name = names[names.length - 1];

                if (!c.properties)
                    c.properties = {};

                c.properties[name] = p;
                p.longname = p.name;
                p.name = name;
            }
        }

        // now output the params
        const keys = Object.keys(params);

        for (let i = 0; i < keys.length; ++i)
        {
            const p = params[keys[i]];

            const opt = typeof p.optional === 'boolean' ? p.optional : false;
            const nul = typeof p.nullable === 'boolean' ? p.nullable : false;

            let type = getTypeName(p);

            if (p.properties)
            {
                const objType = Object.keys(p.properties)
                    .reduce((prev, curr, i, a) =>
                    {
                        if (i === 0) prev += '{ ';

                        const v = p.properties[curr];

                        prev += `${v.name}: ${getTypeName(v)}`;

                        if (i !== a.length - 1)
                            prev += ', ';
                        else
                            prev += ' }';

                        return prev;
                    }, '');

                type = type.replace('Object', objType);
            }

            write(`${p.name}${opt || nul ? '?' : ''}: ${type}`);

            if (i !== keys.length - 1)
                write(', ');
        }
    }

    write(')');

    // return type
    if (!isConstructor)
    {
        write(isType ? ' => ' : ': ');

        if (element.returns && element.returns.length)
            write(`${getTypeName(element.returns[0])}`);
        else
            write('void');
    }

    // done
    write(';');
}

function getTypeName(obj)
{
    let name = 'any';

    if (obj.type)
    {
        if (obj.type.names.length === 1)
            name = obj.type.names[0];
        else
            name = `(${obj.type.names.join('|')})`;
    }

    name = name.trim();
    name = name.replace(/Array\.?<([^>]*)>/gi, '$1[]');
    name = name.replace(/Object\.?<([^,]*), ?([^>]*)>/gi, '{ [k: $1]: $2 }');
    name = name.replace(/\*|mixed/g, 'any');
    name = name.replace(/(^|[^\w])function(?:\(\))?([^\w]|$)/gi, '$1(() => any)$2');
    name = name.replace(/object/g, 'Object');

    return name;
}

function handleNamespace(docs, element, parent)
{
    // comment
    writeComment(element.comment);

    if (element.scope === 'global')
        write('declare ');

    // header
    writeLn(`module ${element.name} {`);

    // children
    handleChildren(docs, element);

    // done
    writeLn('}');
    endLine();
}

function handleFunction(docs, element, parent, isConstructor)
{
    const name = isConstructor ? 'constructor' : element.name;

    // skip if parent already defines it
    if (parent && parent.augments)
    {
        for (let i = 0; i < parent.augments.length; ++i)
        {
            const aug = parent.augments[i];
            const children = findChildrenOf(docs, aug);

            if (children.filter((v) => v.name === element.name).length)
                return;
        }
    }

    // comment
    writeComment(element.comment);

    startLine();

    if (!isConstructor)
    {
        if (element.scope === 'global')
            write('declare function ');
        else if (isClass(parent))
        {
            // access
            if (element.access)
                write(`${element.access} `);

            // static
            if (element.scope === 'static')
                write('static ');
        }
        else
            write('function ');
    }

    // name
    write(name);

    writeFunctionProto(element, isConstructor);
    endLine();
    endLine();
}

function handleMember(docs, element, parent)
{
    // generate an interface for this member
    if (isInterface(element))
        writeInterfaceForObjectType(element);

    // skip if parent already defines it
    if (parent && parent.augments)
    {
        for (let i = 0; i < parent.augments.length; ++i)
        {
            const aug = parent.augments[i];
            const children = findChildrenOf(docs, aug);

            if (children.filter((v) => v.name === element.name).length)
                return;
        }
    }

    // comment
    writeComment(element.comment);

    startLine();

    if (element.isEnum)
    {
        if (element.scope === 'global')
            write('declare ');

        write(`enum ${element.name} {`);
        endLine();

        indent();
        for (let i = 0; i < element.properties.length; ++i)
        {
            const p = element.properties[i];

            writeComment(p.comment);

            startLine();

            write(p.name);

            if (i !== element.properties.length - 1)
                write(',');

            endLine();
        }
        unindent();

        writeLn('}');
    }
    else
    {
        if (element.scope === 'global')
            write('declare var ');
        else
        {
            // member
            if (isClass(parent))
            {
                // access
                if (element.access)
                    write(`${element.access} `);

                // static
                if (element.scope === 'static')
                    write('static ');

                // TODO: Enable this when v2 is out.
                // readonly
                // if (element.readonly)
                //     write('readonly ');
            }
            // constant
            else if (element.kind === 'constant')
                write('const ');
            else
                write('var ');
        }

        write(`${element.name}: ${isInterface(element) ? `I${element.name}` : getTypeName(element)};`);
        endLine();
    }

    // extra newline
    endLine();
}

function handleClass(docs, element, parent, isInterface)
{
    // comment
    writeComment(element.comment);

    startLine();

    if (element.scope === 'global')
        write('declare ');
    // else
    // {
    //     if (element.access)
    //         write(`${element.access} `);
    // }

    // abstract
    if (element.virtual)
        write('abstract ');

    // name
    write(`${isInterface ? 'interface' : 'class'} ${element.name} `);

    // extends
    let augs = [];

    if (element.mixes) augs.push.apply(augs, element.mixes);
    if (element.augments) augs.push.apply(augs, element.augments);

    augs = augs.filter((v) => v.indexOf('module:') === -1);

    if (augs.length)
        write(`extends ${augs} `);

    // implements
    if (element.implements)
        write(`implements ${element.implements.join(', ')} `);

    // header end
    write('{');
    endLine();

    // constructor
    if (!isInterface && !element.virtual)
    {
        indent();
        handleFunction(docs, element, parent, true);
        unindent();
    }

    // children
    handleChildren(docs, element);

    // done
    writeLn('}');
    endLine();
}

function handleTypedef(docs, element, parent)
{
    const rawType = element.type && element.type.names.length === 1 && element.type.names[0];

    if (isInterface(element))
    {
        if (isClass(parent))
            queueInterfaceForObjectType(element);
        else
        {
            // comment
            writeComment(element.comment);

            writeInterfaceForObjectType(element);
        }
    }
    else
    {
        // comment
        writeComment(element.comment);

        startLine();

        // access
        if (element.access)
            write(`${element.access} `);

        // name
        write(`type ${element.name} = `);

        if (rawType === 'function')
            writeFunctionProto(element, false, true);
        else
            write(`${getTypeName(element)};`);

        endLine();
    }
    endLine();
}

function handleChildren(docs, element)
{
    indent();
    parse(docs, element);
    unindent();
}

function isClass(e)
{
    return e && (e.kind === 'class' || e.kind === 'interface' || e.kind === 'mixin');
}

function isInterface(e)
{
    return e && (e.kind === 'interface' || (getTypeName(e) === 'object' && e.properties && e.properties.length));
}

function findChildrenOf(docs, longname)
{
    return docs.filter((e) => e.memberof === longname);
}
<commit_msg>Disable package doclet<commit_after>'use strict';

const fs = require('fs');

const hasOwn = Object.prototype.hasOwnProperty;

const indentSize = 4;
let indentLevel = 0;
let ostream = null;

// to dedupe some objects (like getters/setters) that may appear twice.
const seenElements = {};

// queues up some typedefs until we can just write out the interface at the end
const interfaceQueue = [];

/**
 * @param {TAFFY} data - The TaffyDB containing the data that jsdoc parsed.
 * @param {object} opts - Options passed into jsdoc.
 */
module.exports.publish = function (data, opts)
{
    // remove undocumented stuff.
    data({ undocumented: true }).remove();

    const docs = data().get();

    // ostream = fs.createWriteStream('./_temp.d.ts');
    ostream = process.stdout;

    parse(docs);

    while (interfaceQueue.length)
    {
        const element = interfaceQueue.pop();

        // comment
        writeComment(element.comment);

        writeInterfaceForObjectType(element);
    }

    // ostream.end();
};

function parse(docs, parent)
{
    findChildrenOf(docs, (parent ? parent.longname : undefined))
    .forEach((element) =>
    {
        if (element.ignore || seenElements[element.longname])
            return;

        seenElements[element.longname] = true;

        switch (element.kind)
        {
            /* eslint-disable no-multi-spaces */
            case 'class':       return handleClass(docs, element, parent);
            case 'constant':    return handleMember(docs, element, parent);
            case 'function':    return handleFunction(docs, element, parent);
            case 'interface':   return handleClass(docs, element, parent, true);
            case 'member':      return handleMember(docs, element, parent);
            case 'mixin':       return handleClass(docs, element, parent);
            case 'module':      return handleNamespace(docs, element, parent);
            case 'namespace':   return handleNamespace(docs, element, parent);
            case 'typedef':     return handleTypedef(docs, element, parent);
            /* eslint-enable no-multi-spaces */
        }

        return;
    });
}

function write(msg)
{
    if (!msg) return;

    ostream.write(msg);
}

function writeLn(msg)
{
    if (!msg) return;

    startLine();
    write(msg);
    endLine();
}

function writeComment(cmt)
{
    if (!cmt) return;

    cmt
        .split('\n')
        .map((v) => v.trim())
        .map((v) => (v.startsWith('*') ? ` ${v}` : v))
        .forEach(writeLn);
}

function startLine()
{
    const indent = (new Array(indentLevel * indentSize)).join(' ');

    write(indent);
}

function endLine()
{
    write('\n');
}

function indent()
{
    indentLevel++;
}

function unindent()
{
    indentLevel--;
}

function queueInterfaceForObjectType(element)
{
    interfaceQueue.push(element);
}

function writeInterfaceForObjectType(element)
{
    writeLn(`interface I${element.name} {`);
    indent();

    for (let i = 0; i < element.properties.length; ++i)
    {
        const p = element.properties[i];

        writeLn(`${p.name}: ${getTypeName(p)};`);
    }

    unindent();
    writeLn('}');
    endLine();
}

function writeFunctionProto(element, isConstructor, isType)
{
    // params
    write('(');

    // `this` param
    if (element.this)
    {
        write(`this: ${element.this}`);

        if (element.params && element.params.length)
            write(', ');
    }

    if (element.params)
    {
        const params = {};

        // parse params first to combine property syntaxes
        for (let i = 0; i < element.params.length; ++i)
        {
            const p = element.params[i];
            const names = p.name.split('.');

            if (names.length === 1)
                params[p.name] = p;
            else
            {
                let c = params[names[0]];

                for (let j = 1; j < names.length - 1; ++j)
                {
                    const name = names[j];

                    if (!c.properties)
                        c.properties = {};

                    if (!c.properties[name])
                        c.properties[name] = {};

                    c = c.properties[name];
                }

                const name = names[names.length - 1];

                if (!c.properties)
                    c.properties = {};

                c.properties[name] = p;
                p.longname = p.name;
                p.name = name;
            }
        }

        // now output the params
        const keys = Object.keys(params);

        for (let i = 0; i < keys.length; ++i)
        {
            const p = params[keys[i]];

            const opt = typeof p.optional === 'boolean' ? p.optional : false;
            const nul = typeof p.nullable === 'boolean' ? p.nullable : false;

            let type = getTypeName(p);

            if (p.properties)
            {
                const objType = Object.keys(p.properties)
                    .reduce((prev, curr, i, a) =>
                    {
                        if (i === 0) prev += '{ ';

                        const v = p.properties[curr];

                        prev += `${v.name}: ${getTypeName(v)}`;

                        if (i !== a.length - 1)
                            prev += ', ';
                        else
                            prev += ' }';

                        return prev;
                    }, '');

                type = type.replace('Object', objType);
            }

            write(`${p.name}${opt || nul ? '?' : ''}: ${type}`);

            if (i !== keys.length - 1)
                write(', ');
        }
    }

    write(')');

    // return type
    if (!isConstructor)
    {
        write(isType ? ' => ' : ': ');

        if (element.returns && element.returns.length)
            write(`${getTypeName(element.returns[0])}`);
        else
            write('void');
    }

    // done
    write(';');
}

function getTypeName(obj)
{
    let name = 'any';

    if (obj.type)
    {
        if (obj.type.names.length === 1)
            name = obj.type.names[0];
        else
            name = `(${obj.type.names.join('|')})`;
    }

    name = name.trim();
    name = name.replace(/Array\.?<([^>]*)>/gi, '$1[]');
    name = name.replace(/Object\.?<([^,]*), ?([^>]*)>/gi, '{ [k: $1]: $2 }');
    name = name.replace(/\*|mixed/g, 'any');
    name = name.replace(/(^|[^\w])function(?:\(\))?([^\w]|$)/gi, '$1(() => any)$2');
    name = name.replace(/object/g, 'Object');

    return name;
}

function handleNamespace(docs, element, parent)
{
    // comment
    writeComment(element.comment);

    if (element.scope === 'global')
        write('declare ');

    // header
    writeLn(`module ${element.name} {`);

    // children
    handleChildren(docs, element);

    // done
    writeLn('}');
    endLine();
}

function handleFunction(docs, element, parent, isConstructor)
{
    const name = isConstructor ? 'constructor' : element.name;

    // skip if parent already defines it
    if (parent && parent.augments)
    {
        for (let i = 0; i < parent.augments.length; ++i)
        {
            const aug = parent.augments[i];
            const children = findChildrenOf(docs, aug);

            if (children.filter((v) => v.name === element.name).length)
                return;
        }
    }

    // comment
    writeComment(element.comment);

    startLine();

    if (!isConstructor)
    {
        if (element.scope === 'global')
            write('declare function ');
        else if (isClass(parent))
        {
            // access
            if (element.access)
                write(`${element.access} `);

            // static
            if (element.scope === 'static')
                write('static ');
        }
        else
            write('function ');
    }

    // name
    write(name);

    writeFunctionProto(element, isConstructor);
    endLine();
    endLine();
}

function handleMember(docs, element, parent)
{
    // generate an interface for this member
    if (isInterface(element))
        writeInterfaceForObjectType(element);

    // skip if parent already defines it
    if (parent && parent.augments)
    {
        for (let i = 0; i < parent.augments.length; ++i)
        {
            const aug = parent.augments[i];
            const children = findChildrenOf(docs, aug);

            if (children.filter((v) => v.name === element.name).length)
                return;
        }
    }

    // comment
    writeComment(element.comment);

    startLine();

    if (element.isEnum)
    {
        if (element.scope === 'global')
            write('declare ');

        write(`enum ${element.name} {`);
        endLine();

        indent();
        for (let i = 0; i < element.properties.length; ++i)
        {
            const p = element.properties[i];

            writeComment(p.comment);

            startLine();

            write(p.name);

            if (i !== element.properties.length - 1)
                write(',');

            endLine();
        }
        unindent();

        writeLn('}');
    }
    else
    {
        if (element.scope === 'global')
            write('declare var ');
        else
        {
            // member
            if (isClass(parent))
            {
                // access
                if (element.access)
                    write(`${element.access} `);

                // static
                if (element.scope === 'static')
                    write('static ');

                // TODO: Enable this when v2 is out.
                // readonly
                // if (element.readonly)
                //     write('readonly ');
            }
            // constant
            else if (element.kind === 'constant')
                write('const ');
            else
                write('var ');
        }

        write(`${element.name}: ${isInterface(element) ? `I${element.name}` : getTypeName(element)};`);
        endLine();
    }

    // extra newline
    endLine();
}

function handleClass(docs, element, parent, isInterface)
{
    // comment
    writeComment(element.comment);

    startLine();

    if (element.scope === 'global')
        write('declare ');
    // else
    // {
    //     if (element.access)
    //         write(`${element.access} `);
    // }

    // abstract
    if (element.virtual)
        write('abstract ');

    // name
    write(`${isInterface ? 'interface' : 'class'} ${element.name} `);

    // extends
    let augs = [];

    if (element.mixes) augs.push.apply(augs, element.mixes);
    if (element.augments) augs.push.apply(augs, element.augments);

    augs = augs.filter((v) => v.indexOf('module:') === -1);

    if (augs.length)
        write(`extends ${augs} `);

    // implements
    if (element.implements)
        write(`implements ${element.implements.join(', ')} `);

    // header end
    write('{');
    endLine();

    // constructor
    if (!isInterface && !element.virtual)
    {
        indent();
        handleFunction(docs, element, parent, true);
        unindent();
    }

    // children
    handleChildren(docs, element);

    // done
    writeLn('}');
    endLine();
}

function handleTypedef(docs, element, parent)
{
    const rawType = element.type && element.type.names.length === 1 && element.type.names[0];

    if (isInterface(element))
    {
        if (isClass(parent))
            queueInterfaceForObjectType(element);
        else
        {
            // comment
            writeComment(element.comment);

            writeInterfaceForObjectType(element);
        }
    }
    else
    {
        // comment
        writeComment(element.comment);

        startLine();

        // access
        if (element.access)
            write(`${element.access} `);

        // name
        write(`type ${element.name} = `);

        if (rawType === 'function')
            writeFunctionProto(element, false, true);
        else
            write(`${getTypeName(element)};`);

        endLine();
    }
    endLine();
}

function handleChildren(docs, element)
{
    indent();
    parse(docs, element);
    unindent();
}

function isClass(e)
{
    return e && (e.kind === 'class' || e.kind === 'interface' || e.kind === 'mixin');
}

function isInterface(e)
{
    return e && (e.kind === 'interface' || (getTypeName(e) === 'object' && e.properties && e.properties.length));
}

function findChildrenOf(docs, longname)
{
    return docs.filter((e) => e.memberof === longname);
}
<|endoftext|>


<commit_before>var sys = require('sys')
var exec = require('child_process').exec;
var execSync = require('execSync').run;
var fs = require('fs');

//first update json data
var convertData = execSync("node parser/parser.js");
console.log("converting data to json:\n",convertData);
//move files
console.log("moving generated files to data folder");
fs.renameSync("rooms.json"          , "data/rooms.json");
fs.renameSync("roomsByBuilding.json", "data/roomsByBuilding.json");
fs.renameSync("buildings.json"      , "data/buildings.json");

//vulcanize custom element, just in case
var vulcanize = execSync("vulcanize --inline --output infos.html index.html");
console.log("vulcanizing:\n",vulcanize);

//do some git magic
var addGit = execSync("git add data locales vulcanized.html accessibility-infos.html accessibility-infos.css index.html");
var commitGit = execSync("git commit -m '- autoUpdated data/repository on "+new Date() +"'");
var publishGitMaster = execSync("git push origin master");
var publishGitPages  = execSync("git push -f origin master:gh-pages");
var publishOk = addGit && commitGit && publishGitMaster && publishGitPages;
console.log("Publishing to github:\n",publishOk);

<commit_msg>- small fix in publish.js<commit_after>var sys = require('sys')
var exec = require('child_process').exec;
var execSync = require('execSync').run;
var fs = require('fs');

//first update json data
var convertData = execSync("node parser/parser.js");
console.log("converting data to json:\n",convertData);
//move files
console.log("moving generated files to data folder");
fs.renameSync("rooms.json"          , "data/rooms.json");
fs.renameSync("roomsByBuilding.json", "data/roomsByBuilding.json");
fs.renameSync("buildings.json"      , "data/buildings.json");

//vulcanize custom element, just in case
var vulcanize = execSync("vulcanize --inline --output infos.html index.html");
console.log("vulcanizing:\n",vulcanize);

//do some git magic
var addGit = execSync("git add data locales infos.html accessibility-infos.html accessibility-infos.css index.html");
var commitGit = execSync("git commit -m '- autoUpdated data/repository on "+new Date() +"'");
var publishGitMaster = execSync("git push origin master");
var publishGitPages  = execSync("git push -f origin master:gh-pages");
var publishOk = addGit && commitGit && publishGitMaster && publishGitPages;
console.log("Publishing to github:\n",publishOk);

<|endoftext|>


<commit_before>/**
 * Nodejs client for github.com/zhihu/kids.git
 * 2014 <hit9 hit9@icloud.com>
 *
 * Requires:
 *
 *   - Nodejs 0.8+
 *   - hiredis-node
 *
 * Subscribe:
 *
 *   var client = kids.createClient();
 *   client.subscribe('topic');
 *   client.on('data', function(error, data) {
 *     console.log(data);  // data: {topic:.., message: ..}
 *   });
 *
 * Publish (or Log):
 *
 *   var client = kids.createClient();
 *   client.log('topic', 'hello %s!', 'Mr.Developer');
 */

var events = require('events');
var net = require('net');
var util = require('util');
var hiredis = require('hiredis');

var PUBLISH      = 'PUBLISH';
var SUBSCRIBE    = 'SUBSCRIBE';
var PSUBSCRIBE   = 'PSUBSCRIBE';
var UNSUBSCRIBE  = 'UNSUBSCRIBE';
var PUNSUBSCRIBE = 'PUNSUBSCRIBE';

var MESSAGE      = 'MESSAGE';
var PMESSAGE     = 'PMESSAGE';

/**
 * @constructor
 * @param {Object} options
 */
function Connection(options) {
  this.host = options.host || '127.0.0.1';
  this.port = options.port || 3388;
  this.timeout = options.timeout || 0;

  this.sock = null;
  this.commands = [];
  this.callbacks = [];
  this._hrreader = new hiredis.Reader();
}
util.inherits(Connection, events.EventEmitter);

/**
 * Connect to kids
 *
 * @param {Function} callback
 */
Connection.prototype.connect = function(callback) {
  this.sock = net.Socket();
  this.sock.setTimeout(this.timeout);
  this.sock.setEncoding('utf8');
  this.sock.setNoDelay(true);
  this.sock.setKeepAlive(true);
  this.sock.connect(this.port, this.host, callback);

  // on data
  var self = this;
  this.sock.on('data', function(buf) {
    return self.recv(buf);
  });
};

/**
 * Send request to kids server over redis protocol (v2)
 *
 * @param {Array} args
 * @param {Function} callback
 */
Connection.prototype.send = function(args, callback) {
  var self = this;

  if (!this.sock) {
    // lazy connect
    return this.connect(function() {
      // resend on frist-connected
      self.send(args, callback);
    });
  } else {
    var args_ = [util.format('*%d\r\n', args.length)];

    for (var i = 0; i < args.length; i++) {
      var arg = util.format('%s', args[i]);
      var len = Buffer.byteLength(arg);
      args_.push(util.format('$%d\r\n', len));
      args_.push(arg);
      args_.push('\r\n');
    }
    var buf = new Buffer(args_.join(''));
    return this.sock.write(buf, function(){
      self.commands.push(args[0]);
      self.callbacks.push(callback);
    });
  }
};

/**
 * Recv response from kids server over redis protocol
 *
 * @param {Buffer/String} buf
 */
Connection.prototype.recv = function(buf) {
  this._hrreader.feed(buf);

  var res;

  while ((res = this._hrreader.get()) !== undefined) {
    this._routeResp(res);
  }
};

/**
 * Routing recv data to sub/pub
 * @private
 * @param {String} res
 */
Connection.prototype._routeResp = function(res) {
  var cmd = this.commands.shift();

  if (typeof cmd !== 'undefined') {
    switch(cmd) {
      /* jshint ignore: start */
      case PUBLISH:
      case SUBSCRIBE:
      case PSUBSCRIBE:
      case UNSUBSCRIBE:
      case PUNSUBSCRIBE:
        var err;
        var data;
        var callback = this.callbacks.shift();
        if (res.constructor === Error) err = res;
        else data = res;
        callback && callback(err, data);
        break;
      /* jshint ignore: end */
    }
  } else if (util.isArray(res) && res.length) {
    switch(res[0].toUpperCase()) {
      case MESSAGE:
      case PMESSAGE:
        this.emit('data', {topic: res[1], message: res[2]});
        break;
      default:
        // drop
    }
  }
};

/**
 * @constructor
 * @param {Object} options
 *
 * options
 *
 *   host    string, kids server host, default: '127.0.0.1'
 *   port    number, kids server port, default: 3388
 *   timeout number, ms timeout to connect
 */
function Client(options) {
  this.conn = new Connection(options);
  // register event listener
  var self = this;
  this.conn.on('data', function(data) {
    return self.emit('data', data);
  });
}
util.inherits(Client, events.EventEmitter);

/**
 * Send signle log message to kids server
 *
 * @public
 * @param {String} topic
 * @param {Mixed} args..
 * @param {Function} callback // error, data (0 or 1)
 */
Client.prototype.publish = function() {
  var callback;
  var topic = arguments[0];
  var args_ = [].slice.call(arguments, 1, -1);
  var argsl = [].slice.call(arguments, -1)[0];

  if (typeof argsl === 'function') {
    callback = argsl;
  } else {
    args_.push(argsl);
  }

  var data = util.format.apply(null, args_);
  return this.conn.send([PUBLISH, topic, data], callback);
};

/**
 * Log Alias
 */
Client.prototype.log = Client.prototype.publish;

/**
 * Subscribe topic from kids server
 *
 * @public
 * @param {String} topic
 * @param {Function} callback  // error, data (0 or 1)
 */
Client.prototype.subscribe = function(topic, callback) {
  return this.conn.send([SUBSCRIBE, topic], callback);
};

/**
 * PSubscribe topic from kids server
 *
 * @public
 * @param {String} topic
 * @param {Function} callback  // error, data (0 or 1)
 */
Client.prototype.psubscribe = function(topic, callback) {
  return this.conn.send([PSUBSCRIBE, topic], callback);
};

/**
 * UnSubscribe topic from kids server
 *
 * @public
 * @param {String} topic
 * @param {Function} callback
 */
Client.prototype.unsubscribe = function(topic, callback) {
  return this.conn.unsubscribe([UNSUBSCRIBE, topic], callback);
};

/**
 * PUnSubscribe topic from kids server
 *
 * @public
 * @param {String} topic
 * @param {Function} callback
 */
Client.prototype.punsubscribe = function(topic, callback) {
  return this.conn.unsubscribe([PUNSUBSCRIBE, topic], callback);
};

/**
 * @exports
 * @param {Object} options
 * @return {Client}
 */
exports.createClient = function(options) {
  return new Client(options || {});
};
<commit_msg>Fix typo<commit_after>/**
 * Nodejs client for github.com/zhihu/kids.git
 * 2014 <hit9 hit9@icloud.com>
 *
 * Requires:
 *
 *   - Nodejs 0.8+
 *   - hiredis-node
 *
 * Subscribe:
 *
 *   var client = kids.createClient();
 *   client.subscribe('topic');
 *   client.on('data', function(error, data) {
 *     console.log(data);  // data: {topic:.., message: ..}
 *   });
 *
 * Publish (or Log):
 *
 *   var client = kids.createClient();
 *   client.log('topic', 'hello %s!', 'Mr.Developer');
 */

var events = require('events');
var net = require('net');
var util = require('util');
var hiredis = require('hiredis');

var PUBLISH      = 'PUBLISH';
var SUBSCRIBE    = 'SUBSCRIBE';
var PSUBSCRIBE   = 'PSUBSCRIBE';
var UNSUBSCRIBE  = 'UNSUBSCRIBE';
var PUNSUBSCRIBE = 'PUNSUBSCRIBE';

var MESSAGE      = 'MESSAGE';
var PMESSAGE     = 'PMESSAGE';

/**
 * @constructor
 * @param {Object} options
 */
function Connection(options) {
  this.host = options.host || '127.0.0.1';
  this.port = options.port || 3388;
  this.timeout = options.timeout || 0;

  this.sock = null;
  this.commands = [];
  this.callbacks = [];
  this._hrreader = new hiredis.Reader();
}
util.inherits(Connection, events.EventEmitter);

/**
 * Connect to kids
 *
 * @param {Function} callback
 */
Connection.prototype.connect = function(callback) {
  this.sock = net.Socket();
  this.sock.setTimeout(this.timeout);
  this.sock.setEncoding('utf8');
  this.sock.setNoDelay(true);
  this.sock.setKeepAlive(true);
  this.sock.connect(this.port, this.host, callback);

  // on data
  var self = this;
  this.sock.on('data', function(buf) {
    return self.recv(buf);
  });
};

/**
 * Send request to kids server over redis protocol (v2)
 *
 * @param {Array} args
 * @param {Function} callback
 */
Connection.prototype.send = function(args, callback) {
  var self = this;

  if (!this.sock) {
    // lazy connect
    return this.connect(function() {
      // resend on frist-connected
      self.send(args, callback);
    });
  } else {
    var args_ = [util.format('*%d\r\n', args.length)];

    for (var i = 0; i < args.length; i++) {
      var arg = util.format('%s', args[i]);
      var len = Buffer.byteLength(arg);
      args_.push(util.format('$%d\r\n', len));
      args_.push(arg);
      args_.push('\r\n');
    }
    var buf = new Buffer(args_.join(''));
    return this.sock.write(buf, function(){
      self.commands.push(args[0]);
      self.callbacks.push(callback);
    });
  }
};

/**
 * Recv response from kids server over redis protocol
 *
 * @param {Buffer/String} buf
 */
Connection.prototype.recv = function(buf) {
  this._hrreader.feed(buf);

  var res;

  while ((res = this._hrreader.get()) !== undefined) {
    this._routeResp(res);
  }
};

/**
 * Routing recv data to sub/pub
 * @private
 * @param {String} res
 */
Connection.prototype._routeResp = function(res) {
  var cmd = this.commands.shift();

  if (typeof cmd !== 'undefined') {
    switch(cmd) {
      /* jshint ignore: start */
      case PUBLISH:
      case SUBSCRIBE:
      case PSUBSCRIBE:
      case UNSUBSCRIBE:
      case PUNSUBSCRIBE:
        var err;
        var data;
        var callback = this.callbacks.shift();
        if (res.constructor === Error) err = res;
        else data = res;
        callback && callback(err, data);
        break;
      /* jshint ignore: end */
    }
  } else if (util.isArray(res) && res.length) {
    switch(res[0].toUpperCase()) {
      case MESSAGE:
      case PMESSAGE:
        this.emit('data', {topic: res[1], message: res[2]});
        break;
      default:
        // drop
    }
  }
};

/**
 * @constructor
 * @param {Object} options
 *
 * options
 *
 *   host    string, kids server host, default: '127.0.0.1'
 *   port    number, kids server port, default: 3388
 *   timeout number, ms timeout to connect
 */
function Client(options) {
  this.conn = new Connection(options);
  // register event listener
  var self = this;
  this.conn.on('data', function(data) {
    return self.emit('data', data);
  });
}
util.inherits(Client, events.EventEmitter);

/**
 * Send signle log message to kids server
 *
 * @public
 * @param {String} topic
 * @param {Mixed} args..
 * @param {Function} callback // error, data (0 or 1)
 */
Client.prototype.publish = function() {
  var callback;
  var topic = arguments[0];
  var args_ = [].slice.call(arguments, 1, -1);
  var argsl = [].slice.call(arguments, -1)[0];

  if (typeof argsl === 'function') {
    callback = argsl;
  } else {
    args_.push(argsl);
  }

  var data = util.format.apply(null, args_);
  return this.conn.send([PUBLISH, topic, data], callback);
};

/**
 * Log Alias
 */
Client.prototype.log = Client.prototype.publish;

/**
 * Subscribe topic from kids server
 *
 * @public
 * @param {String} topic
 * @param {Function} callback  // error, data (0 or 1)
 */
Client.prototype.subscribe = function(topic, callback) {
  return this.conn.send([SUBSCRIBE, topic], callback);
};

/**
 * PSubscribe topic from kids server
 *
 * @public
 * @param {String} topic
 * @param {Function} callback  // error, data (0 or 1)
 */
Client.prototype.psubscribe = function(topic, callback) {
  return this.conn.send([PSUBSCRIBE, topic], callback);
};

/**
 * UnSubscribe topic from kids server
 *
 * @public
 * @param {String} topic
 * @param {Function} callback
 */
Client.prototype.unsubscribe = function(topic, callback) {
  return this.conn.send([UNSUBSCRIBE, topic], callback);
};

/**
 * PUnSubscribe topic from kids server
 *
 * @public
 * @param {String} topic
 * @param {Function} callback
 */
Client.prototype.punsubscribe = function(topic, callback) {
  return this.conn.send([PUNSUBSCRIBE, topic], callback);
};

/**
 * @exports
 * @param {Object} options
 * @return {Client}
 */
exports.createClient = function(options) {
  return new Client(options || {});
};
<|endoftext|>


<commit_before>// Copyright (c) IPython Development Team.
// Distributed under the terms of the Modified BSD License.

define([
    'jquery',
    'base/js/namespace',
    'base/js/dialog',
    'base/js/utils',
    'notebook/js/tour',
    'bootstrap',
    'moment',
], function($, IPython, dialog, utils, tour, bootstrap, moment) {
    "use strict";

    var MenuBar = function (selector, options) {
        /**
         * Constructor
         *
         * A MenuBar Class to generate the menubar of IPython notebook
         *
         * Parameters:
         *  selector: string
         *  options: dictionary
         *      Dictionary of keyword arguments.
         *          notebook: Notebook instance
         *          contents: ContentManager instance
         *          events: $(Events) instance
         *          save_widget: SaveWidget instance
         *          quick_help: QuickHelp instance
         *          base_url : string
         *          notebook_path : string
         *          notebook_name : string
         */
        options = options || {};
        this.base_url = options.base_url || utils.get_body_data("baseUrl");
        this.selector = selector;
        this.notebook = options.notebook;
        this.contents = options.contents;
        this.events = options.events;
        this.save_widget = options.save_widget;
        this.quick_help = options.quick_help;

        try {
            this.tour = new tour.Tour(this.notebook, this.events);
        } catch (e) {
            this.tour = undefined;
            console.log("Failed to instantiate Notebook Tour", e);
        }

        if (this.selector !== undefined) {
            this.element = $(selector);
            this.style();
            this.bind_events();
        }
    };

    // TODO: This has definitively nothing to do with style ...
    MenuBar.prototype.style = function () {
        var that = this;
        this.element.find("li").click(function (event, ui) {
                // The selected cell loses focus when the menu is entered, so we
                // re-select it upon selection.
                var i = that.notebook.get_selected_index();
                that.notebook.select(i);
            }
        );
    };

    MenuBar.prototype._nbconvert = function (format, download) {
        download = download || false;
        var notebook_path = this.notebook.notebook_path;
        var url = utils.url_join_encode(
            this.base_url,
            'nbconvert',
            format,
            notebook_path
        ) + "?download=" + download.toString();

        var w = window.open();
        if (this.notebook.dirty) {
            this.notebook.save_notebook().then(function() {
                w.location = url;
            });
        } else {
            w.location = url;
        }
    };

    MenuBar.prototype._size_header = function() {
        /**
         * Update header spacer size.
         */
        this.events.trigger('resize-header.Page');
    };

    MenuBar.prototype.bind_events = function () {
        /**
         *  File
         */
        var that = this;

        this.element.find('#open_notebook').click(function () {
            var parent = utils.url_path_split(that.notebook.notebook_path)[0];
            window.open(utils.url_join_encode(that.base_url, 'tree', parent));
        });
        this.element.find('#copy_notebook').click(function () {
            that.notebook.copy_notebook();
            return false;
        });
        this.element.find('#download_ipynb').click(function () {
            var base_url = that.notebook.base_url;
            var notebook_path = that.notebook.notebook_path;
            if (that.notebook.dirty) {
                that.notebook.save_notebook({async : false});
            }

            var url = utils.url_join_encode(base_url, 'files', notebook_path);
            window.open(url + '?download=1');
        });

        this.element.find('#print_preview').click(function () {
            that._nbconvert('html', false);
        });

        this.element.find('#download_html').click(function () {
            that._nbconvert('html', true);
        });

        this.element.find('#download_rst').click(function () {
            that._nbconvert('rst', true);
        });

        this.element.find('#download_pdf').click(function () {
            that._nbconvert('pdf', true);
        });

        this.element.find('#download_script').click(function () {
            that._nbconvert('script', true);
        });

        this.element.find('#rename_notebook').click(function () {
            that.save_widget.rename_notebook({notebook: that.notebook});
        });

        this.element.find('#save_checkpoint').click(function () {
            that.notebook.save_checkpoint();
        });

        this.element.find('#restore_checkpoint').click(function () {
        });

        this.element.find('#trust_notebook').click(function () {
            that.notebook.trust_notebook();
        });
        this.events.on('trust_changed.Notebook', function (event, trusted) {
            if (trusted) {
                that.element.find('#trust_notebook')
                    .addClass("disabled").off('click')
                    .find("a").text("Trusted Notebook");
            } else {
                that.element.find('#trust_notebook')
                    .removeClass("disabled").on('click', function () {
                        that.notebook.trust_notebook();
                    })
                    .find("a").text("Trust Notebook");
            }
        });

        this.element.find('#kill_and_exit').click(function () {
            var close_window = function () {
                /**
                 * allow closing of new tabs in Chromium, impossible in FF
                 */
                window.open('', '_self', '');
                window.close();
            };
            // finish with close on success or failure
            that.notebook.session.delete(close_window, close_window);
        });

        // Edit
        this.element.find('#cut_cell').click(function () {
            that.notebook.cut_cell();
        });
        this.element.find('#copy_cell').click(function () {
            that.notebook.copy_cell();
        });
        this.element.find('#delete_cell').click(function () {
            that.notebook.delete_cell();
        });
        this.element.find('#undelete_cell').click(function () {
            that.notebook.undelete_cell();
        });
        this.element.find('#split_cell').click(function () {
            that.notebook.split_cell();
        });
        this.element.find('#merge_cell_above').click(function () {
            that.notebook.merge_cell_above();
        });
        this.element.find('#merge_cell_below').click(function () {
            that.notebook.merge_cell_below();
        });
        this.element.find('#move_cell_up').click(function () {
            that.notebook.move_cell_up();
        });
        this.element.find('#move_cell_down').click(function () {
            that.notebook.move_cell_down();
        });
        this.element.find('#edit_nb_metadata').click(function () {
            that.notebook.edit_metadata({
                notebook: that.notebook,
                keyboard_manager: that.notebook.keyboard_manager});
        });

        // View
        this.element.find('#toggle_header').click(function () {
            $('#header-container').toggle();
            $('.header-bar').toggle();
            that._size_header();
        });
        this.element.find('#toggle_toolbar').click(function () {
            $('div#maintoolbar').toggle();
            that._size_header();
        });
        // Insert
        this.element.find('#insert_cell_above').click(function () {
            that.notebook.insert_cell_above('code');
            that.notebook.select_prev();
        });
        this.element.find('#insert_cell_below').click(function () {
            that.notebook.insert_cell_below('code');
            that.notebook.select_next();
        });
        // Cell
        this.element.find('#run_cell').click(function () {
            that.notebook.execute_cell();
        });
        this.element.find('#run_cell_select_below').click(function () {
            that.notebook.execute_cell_and_select_below();
        });
        this.element.find('#run_cell_insert_below').click(function () {
            that.notebook.execute_cell_and_insert_below();
        });
        this.element.find('#run_all_cells').click(function () {
            that.notebook.execute_all_cells();
        });
        this.element.find('#run_all_cells_above').click(function () {
            that.notebook.execute_cells_above();
        });
        this.element.find('#run_all_cells_below').click(function () {
            that.notebook.execute_cells_below();
        });
        this.element.find('#to_code').click(function () {
            that.notebook.to_code();
        });
        this.element.find('#to_markdown').click(function () {
            that.notebook.to_markdown();
        });
        this.element.find('#to_raw').click(function () {
            that.notebook.to_raw();
        });

        this.element.find('#toggle_current_output').click(function () {
            that.notebook.toggle_output();
        });
        this.element.find('#toggle_current_output_scroll').click(function () {
            that.notebook.toggle_output_scroll();
        });
        this.element.find('#clear_current_output').click(function () {
            that.notebook.clear_output();
        });

        this.element.find('#toggle_all_output').click(function () {
            that.notebook.toggle_all_output();
        });
        this.element.find('#toggle_all_output_scroll').click(function () {
            that.notebook.toggle_all_output_scroll();
        });
        this.element.find('#clear_all_output').click(function () {
            that.notebook.clear_all_output();
        });

        // Kernel
        this.element.find('#int_kernel').click(function () {
            that.notebook.kernel.interrupt();
        });
        this.element.find('#restart_kernel').click(function () {
            that.notebook.restart_kernel();
        });
        this.element.find('#reconnect_kernel').click(function () {
            that.notebook.kernel.reconnect();
        });
        // Help
        if (this.tour) {
            this.element.find('#notebook_tour').click(function () {
                that.tour.start();
            });
        } else {
            this.element.find('#notebook_tour').addClass("disabled");
        }
        this.element.find('#keyboard_shortcuts').click(function () {
            that.quick_help.show_keyboard_shortcuts();
        });

        this.update_restore_checkpoint(null);

        this.events.on('checkpoints_listed.Notebook', function (event, data) {
            that.update_restore_checkpoint(that.notebook.checkpoints);
        });

        this.events.on('checkpoint_created.Notebook', function (event, data) {
            that.update_restore_checkpoint(that.notebook.checkpoints);
        });

        this.events.on('notebook_loaded.Notebook', function() {
            var langinfo = that.notebook.metadata.language_info || {};
            that.update_nbconvert_script(langinfo);
        });

        this.events.on('kernel_ready.Kernel', function(event, data) {
            var langinfo = data.kernel.info_reply.language_info || {};
            that.update_nbconvert_script(langinfo);
            that.add_kernel_help_links(data.kernel.info_reply.help_links || []);
        });
    };

    MenuBar.prototype.update_restore_checkpoint = function(checkpoints) {
        var ul = this.element.find("#restore_checkpoint").find("ul");
        ul.empty();
        if (!checkpoints || checkpoints.length === 0) {
            ul.append(
                $("<li/>")
                .addClass("disabled")
                .append(
                    $("<a/>")
                    .text("No checkpoints")
                )
            );
            return;
        }

        var that = this;
        checkpoints.map(function (checkpoint) {
            var d = new Date(checkpoint.last_modified);
            ul.append(
                $("<li/>").append(
                    $("<a/>")
                    .attr("href", "#")
                    .text(moment(d).format("LLLL"))
                    .click(function () {
                        that.notebook.restore_checkpoint_dialog(checkpoint);
                    })
                )
            );
        });
    };

    MenuBar.prototype.update_nbconvert_script = function(langinfo) {
        /**
         * Set the 'Download as foo' menu option for the relevant language.
         */
        var el = this.element.find('#download_script');

        // Set menu entry text to e.g. "Python (.py)"
        var langname = (langinfo.name || 'Script');
        langname = langname.charAt(0).toUpperCase()+langname.substr(1); // Capitalise
        el.find('a').text(langname + ' ('+(langinfo.file_extension || 'txt')+')');
    };

    MenuBar.prototype.add_kernel_help_links = function(help_links) {
        /** add links from kernel_info to the help menu */
        var divider = $("#kernel-help-links");
        if (divider.length === 0) {
            // insert kernel help section above about link
            var about = $("#notebook_about").parent();
            divider = $("<li>")
                .attr('id', "kernel-help-links")
                .addClass('divider');
            about.prev().before(divider);
        }
        // remove previous entries
        while (!divider.next().hasClass('divider')) {
            divider.next().remove();
        }
        if (help_links.length === 0) {
            // no help links, remove the divider
            divider.remove();
            return;
        }
        var cursor = divider;
        help_links.map(function (link) {
            cursor.after($("<li>")
                .append($("<a>")
                    .attr('target', '_blank')
                    .attr('title', 'Opens in a new window')
                    .attr('href', link.url)
                    .text(link.text)
                    .append($("<i>")
                        .addClass("fa fa-external-link menu-icon pull-right")
                    )
                )
            );
            cursor = cursor.next();
        });

    };

    // Backwards compatability.
    IPython.MenuBar = MenuBar;

    return {'MenuBar': MenuBar};
});
<commit_msg>fix help-links on Firefox<commit_after>// Copyright (c) IPython Development Team.
// Distributed under the terms of the Modified BSD License.

define([
    'jquery',
    'base/js/namespace',
    'base/js/dialog',
    'base/js/utils',
    'notebook/js/tour',
    'bootstrap',
    'moment',
], function($, IPython, dialog, utils, tour, bootstrap, moment) {
    "use strict";

    var MenuBar = function (selector, options) {
        /**
         * Constructor
         *
         * A MenuBar Class to generate the menubar of IPython notebook
         *
         * Parameters:
         *  selector: string
         *  options: dictionary
         *      Dictionary of keyword arguments.
         *          notebook: Notebook instance
         *          contents: ContentManager instance
         *          events: $(Events) instance
         *          save_widget: SaveWidget instance
         *          quick_help: QuickHelp instance
         *          base_url : string
         *          notebook_path : string
         *          notebook_name : string
         */
        options = options || {};
        this.base_url = options.base_url || utils.get_body_data("baseUrl");
        this.selector = selector;
        this.notebook = options.notebook;
        this.contents = options.contents;
        this.events = options.events;
        this.save_widget = options.save_widget;
        this.quick_help = options.quick_help;

        try {
            this.tour = new tour.Tour(this.notebook, this.events);
        } catch (e) {
            this.tour = undefined;
            console.log("Failed to instantiate Notebook Tour", e);
        }

        if (this.selector !== undefined) {
            this.element = $(selector);
            this.style();
            this.bind_events();
        }
    };

    // TODO: This has definitively nothing to do with style ...
    MenuBar.prototype.style = function () {
        var that = this;
        this.element.find("li").click(function (event, ui) {
                // The selected cell loses focus when the menu is entered, so we
                // re-select it upon selection.
                var i = that.notebook.get_selected_index();
                that.notebook.select(i);
            }
        );
    };

    MenuBar.prototype._nbconvert = function (format, download) {
        download = download || false;
        var notebook_path = this.notebook.notebook_path;
        var url = utils.url_join_encode(
            this.base_url,
            'nbconvert',
            format,
            notebook_path
        ) + "?download=" + download.toString();

        var w = window.open();
        if (this.notebook.dirty) {
            this.notebook.save_notebook().then(function() {
                w.location = url;
            });
        } else {
            w.location = url;
        }
    };

    MenuBar.prototype._size_header = function() {
        /**
         * Update header spacer size.
         */
        this.events.trigger('resize-header.Page');
    };

    MenuBar.prototype.bind_events = function () {
        /**
         *  File
         */
        var that = this;

        this.element.find('#open_notebook').click(function () {
            var parent = utils.url_path_split(that.notebook.notebook_path)[0];
            window.open(utils.url_join_encode(that.base_url, 'tree', parent));
        });
        this.element.find('#copy_notebook').click(function () {
            that.notebook.copy_notebook();
            return false;
        });
        this.element.find('#download_ipynb').click(function () {
            var base_url = that.notebook.base_url;
            var notebook_path = that.notebook.notebook_path;
            if (that.notebook.dirty) {
                that.notebook.save_notebook({async : false});
            }

            var url = utils.url_join_encode(base_url, 'files', notebook_path);
            window.open(url + '?download=1');
        });

        this.element.find('#print_preview').click(function () {
            that._nbconvert('html', false);
        });

        this.element.find('#download_html').click(function () {
            that._nbconvert('html', true);
        });

        this.element.find('#download_rst').click(function () {
            that._nbconvert('rst', true);
        });

        this.element.find('#download_pdf').click(function () {
            that._nbconvert('pdf', true);
        });

        this.element.find('#download_script').click(function () {
            that._nbconvert('script', true);
        });

        this.element.find('#rename_notebook').click(function () {
            that.save_widget.rename_notebook({notebook: that.notebook});
        });

        this.element.find('#save_checkpoint').click(function () {
            that.notebook.save_checkpoint();
        });

        this.element.find('#restore_checkpoint').click(function () {
        });

        this.element.find('#trust_notebook').click(function () {
            that.notebook.trust_notebook();
        });
        this.events.on('trust_changed.Notebook', function (event, trusted) {
            if (trusted) {
                that.element.find('#trust_notebook')
                    .addClass("disabled").off('click')
                    .find("a").text("Trusted Notebook");
            } else {
                that.element.find('#trust_notebook')
                    .removeClass("disabled").on('click', function () {
                        that.notebook.trust_notebook();
                    })
                    .find("a").text("Trust Notebook");
            }
        });

        this.element.find('#kill_and_exit').click(function () {
            var close_window = function () {
                /**
                 * allow closing of new tabs in Chromium, impossible in FF
                 */
                window.open('', '_self', '');
                window.close();
            };
            // finish with close on success or failure
            that.notebook.session.delete(close_window, close_window);
        });

        // Edit
        this.element.find('#cut_cell').click(function () {
            that.notebook.cut_cell();
        });
        this.element.find('#copy_cell').click(function () {
            that.notebook.copy_cell();
        });
        this.element.find('#delete_cell').click(function () {
            that.notebook.delete_cell();
        });
        this.element.find('#undelete_cell').click(function () {
            that.notebook.undelete_cell();
        });
        this.element.find('#split_cell').click(function () {
            that.notebook.split_cell();
        });
        this.element.find('#merge_cell_above').click(function () {
            that.notebook.merge_cell_above();
        });
        this.element.find('#merge_cell_below').click(function () {
            that.notebook.merge_cell_below();
        });
        this.element.find('#move_cell_up').click(function () {
            that.notebook.move_cell_up();
        });
        this.element.find('#move_cell_down').click(function () {
            that.notebook.move_cell_down();
        });
        this.element.find('#edit_nb_metadata').click(function () {
            that.notebook.edit_metadata({
                notebook: that.notebook,
                keyboard_manager: that.notebook.keyboard_manager});
        });

        // View
        this.element.find('#toggle_header').click(function () {
            $('#header-container').toggle();
            $('.header-bar').toggle();
            that._size_header();
        });
        this.element.find('#toggle_toolbar').click(function () {
            $('div#maintoolbar').toggle();
            that._size_header();
        });
        // Insert
        this.element.find('#insert_cell_above').click(function () {
            that.notebook.insert_cell_above('code');
            that.notebook.select_prev();
        });
        this.element.find('#insert_cell_below').click(function () {
            that.notebook.insert_cell_below('code');
            that.notebook.select_next();
        });
        // Cell
        this.element.find('#run_cell').click(function () {
            that.notebook.execute_cell();
        });
        this.element.find('#run_cell_select_below').click(function () {
            that.notebook.execute_cell_and_select_below();
        });
        this.element.find('#run_cell_insert_below').click(function () {
            that.notebook.execute_cell_and_insert_below();
        });
        this.element.find('#run_all_cells').click(function () {
            that.notebook.execute_all_cells();
        });
        this.element.find('#run_all_cells_above').click(function () {
            that.notebook.execute_cells_above();
        });
        this.element.find('#run_all_cells_below').click(function () {
            that.notebook.execute_cells_below();
        });
        this.element.find('#to_code').click(function () {
            that.notebook.to_code();
        });
        this.element.find('#to_markdown').click(function () {
            that.notebook.to_markdown();
        });
        this.element.find('#to_raw').click(function () {
            that.notebook.to_raw();
        });

        this.element.find('#toggle_current_output').click(function () {
            that.notebook.toggle_output();
        });
        this.element.find('#toggle_current_output_scroll').click(function () {
            that.notebook.toggle_output_scroll();
        });
        this.element.find('#clear_current_output').click(function () {
            that.notebook.clear_output();
        });

        this.element.find('#toggle_all_output').click(function () {
            that.notebook.toggle_all_output();
        });
        this.element.find('#toggle_all_output_scroll').click(function () {
            that.notebook.toggle_all_output_scroll();
        });
        this.element.find('#clear_all_output').click(function () {
            that.notebook.clear_all_output();
        });

        // Kernel
        this.element.find('#int_kernel').click(function () {
            that.notebook.kernel.interrupt();
        });
        this.element.find('#restart_kernel').click(function () {
            that.notebook.restart_kernel();
        });
        this.element.find('#reconnect_kernel').click(function () {
            that.notebook.kernel.reconnect();
        });
        // Help
        if (this.tour) {
            this.element.find('#notebook_tour').click(function () {
                that.tour.start();
            });
        } else {
            this.element.find('#notebook_tour').addClass("disabled");
        }
        this.element.find('#keyboard_shortcuts').click(function () {
            that.quick_help.show_keyboard_shortcuts();
        });

        this.update_restore_checkpoint(null);

        this.events.on('checkpoints_listed.Notebook', function (event, data) {
            that.update_restore_checkpoint(that.notebook.checkpoints);
        });

        this.events.on('checkpoint_created.Notebook', function (event, data) {
            that.update_restore_checkpoint(that.notebook.checkpoints);
        });

        this.events.on('notebook_loaded.Notebook', function() {
            var langinfo = that.notebook.metadata.language_info || {};
            that.update_nbconvert_script(langinfo);
        });

        this.events.on('kernel_ready.Kernel', function(event, data) {
            var langinfo = data.kernel.info_reply.language_info || {};
            that.update_nbconvert_script(langinfo);
            that.add_kernel_help_links(data.kernel.info_reply.help_links || []);
        });
    };

    MenuBar.prototype.update_restore_checkpoint = function(checkpoints) {
        var ul = this.element.find("#restore_checkpoint").find("ul");
        ul.empty();
        if (!checkpoints || checkpoints.length === 0) {
            ul.append(
                $("<li/>")
                .addClass("disabled")
                .append(
                    $("<a/>")
                    .text("No checkpoints")
                )
            );
            return;
        }

        var that = this;
        checkpoints.map(function (checkpoint) {
            var d = new Date(checkpoint.last_modified);
            ul.append(
                $("<li/>").append(
                    $("<a/>")
                    .attr("href", "#")
                    .text(moment(d).format("LLLL"))
                    .click(function () {
                        that.notebook.restore_checkpoint_dialog(checkpoint);
                    })
                )
            );
        });
    };

    MenuBar.prototype.update_nbconvert_script = function(langinfo) {
        /**
         * Set the 'Download as foo' menu option for the relevant language.
         */
        var el = this.element.find('#download_script');

        // Set menu entry text to e.g. "Python (.py)"
        var langname = (langinfo.name || 'Script');
        langname = langname.charAt(0).toUpperCase()+langname.substr(1); // Capitalise
        el.find('a').text(langname + ' ('+(langinfo.file_extension || 'txt')+')');
    };

    MenuBar.prototype.add_kernel_help_links = function(help_links) {
        /** add links from kernel_info to the help menu */
        var divider = $("#kernel-help-links");
        if (divider.length === 0) {
            // insert kernel help section above about link
            var about = $("#notebook_about").parent();
            divider = $("<li>")
                .attr('id', "kernel-help-links")
                .addClass('divider');
            about.prev().before(divider);
        }
        // remove previous entries
        while (!divider.next().hasClass('divider')) {
            divider.next().remove();
        }
        if (help_links.length === 0) {
            // no help links, remove the divider
            divider.remove();
            return;
        }
        var cursor = divider;
        help_links.map(function (link) {
            cursor.after($("<li>")
                .append($("<a>")
                    .attr('target', '_blank')
                    .attr('title', 'Opens in a new window')
                    .attr('href', link.url)
                    .append($("<i>")
                        .addClass("fa fa-external-link menu-icon pull-right")
                    )
                    .append($("<span>")
                        .text(link.text)
                    )
                )
            );
            cursor = cursor.next();
        });

    };

    // Backwards compatability.
    IPython.MenuBar = MenuBar;

    return {'MenuBar': MenuBar};
});
<|endoftext|>