<commit_before>'use strict';
var yeoman   = require('yeoman-generator');
var chalk    = require('chalk');
//var yosay    = require('yosay');
var inquirer = require('inquirer');
var clone    = require('git-clone');

module.exports = yeoman.generators.Base.extend({
    initializing: function () {
        this.pkg = require('../package.json');
    },

    prompting: function () {
        var done = this.async();

        // Have Yeoman greet the user.
        var logo =
            +'\n '
            +'\n      _            _ _ _ _____  '
            +'\n  _ _|_|___ ___   | | | |  _  | '
            +'\n | | | |   |- _|  | | | |   __| '
            +'\n  \\_/|_|_|_|___|  \\_____|__|    '
            +'\n';
        this.log( logo );

        var prompts = [
            {
                name: 'NombreTema',
                message: 'Nombre del tema',
                default: 'temaWP'
            },
            {
                name: 'ThemeURI',
                message: 'URL del tema',
                default: 'http://www.' + this.NombreTema + '.com'
            },
            {
                name: 'Autor',
                message: 'Autor',
                default: 'Autor'
            },
            {
                name: 'AuthorURI',
                message: 'URL del Autor',
                default: 'http://www.' + this.Autor + '.com'
            },
            {
                name: 'Descripcion',
                message: 'Descripción',
                default: 'El mejor tema del mundo entero!'
            },
            {
                name: 'VersionTema',
                message: 'Versión',
                default: '1.0'
            },
            {
                name: 'TagsTema',
                message: 'Tags',
                default: ''
            },
            {
                type: 'list',
                name: 'jqueryVersion',
                message: 'Version de jQuery (Se carga desde el CDN de Google)',
                choices: [ 'jQuery 1.11.0', 'jQuery 2.1.0' ],
                filter: function( val ) {
                    if ( val.slice(8) === 1 ) {
                        return val = '1.11.0';
                    } else {
                        return val = '2.1.0';
                    }
                }
            },
            {
            type: 'checkbox',
                message: 'Archivos de la plantilla:',
                name: 'Template',
                choices: [
                    new inquirer.Separator('Basico:'),

                        { name: 'Index.php',   checked: true },
                        { name: 'Header.php',  checked: true },
                        { name: 'Footer.php',  checked: true },
                        { name: 'Sidebar.php', checked: true },
                        { name: 'Single.php',  checked: true },
                        { name: 'Page.php',    checked: true },

                    new inquirer.Separator('Ocional:'),

                        { name: '404.php' },
                        { name: 'Archive.php' },
                        { name: 'Author.php' },
                        { name: 'Category.php' },
                        { name: 'Comments.php' },
                        { name: 'Search.php' },
                        { name: 'Tag.php' },
                        { name: 'Taxonomy.php' },
                ],
                validate: function( answer ) {
                  if ( answer.length < 0) {
                    return 'You must choose at least one topping.';
                  }
                  return true;
                }
            },
            {
                type: 'confirm',
                name: 'CustomMetaboxes',
                message: '¿Usar Custom Metaboxes?',
                default: true
            },
            {
                type: 'confirm',
                name: 'ReduxFramework',
                message: '¿Usar Panel de control? (Redux Framework)',
                default: true
            },
            {
                type: 'checkbox',
                message: 'Incluir Plugins:',
                name: 'Plugins',
                choices: [
                    { name: 'Developer' },
                    { name: 'WP Sync DB' },
                    { name: 'WordPress SEO by Yoast' },
                    { name: 'Contact Form 7' },
                ],
                validate: function( answer ) {
                  if ( answer.length < 0) {
                    return 'Selecciona al menos un plugin.';
                  }
                  return true;
                }
            }
        ];

        this.prompt(prompts, function (props) {

            this.NombreTema      = props.NombreTema;
            this.ThemeURI        = props.ThemeURI;
            this.Autor           = props.Autor;
            this.AuthorURI       = props.AuthorURI;
            this.Descripcion     = props.Descripcion;
            this.VersionTema     = props.VersionTema;
            this.TagsTema        = props.TagsTema;
            this.jqueryVersion   = props.jqueryVersion;
            this.Template        = props.Template;
            this.CustomMetaboxes = props.CustomMetaboxes;
            this.ReduxFramework  = props.ReduxFramework;
            this.Plugins         = props.Plugins;

            done();
        }.bind(this));
    },

    writing: {

        app: function () {
            this.fs.copy(
                this.templatePath('_package.json'),
                this.destinationPath('package.json')
            );
            this.fs.copyTpl(
                this.templatePath('_bowerrc'),
                this.destinationPath('.bowerrc'),
                { NombreTema: this.NombreTema }
            );
            this.fs.copyTpl(
                this.templatePath('_bower.json'),
                this.destinationPath('bower.json'),
                { NombreTema: this.NombreTema,
                  VersionTema: this.VersionTema,
                  Autor: this.Autor,
                  ThemeURI: this.ThemeURI,
                  AuthorURI: this.AuthorURI }
            );
        },

        projectfiles: function () {
            this.fs.copy(
                this.templatePath('editorconfig'),
                this.destinationPath('.editorconfig')
            );
            this.fs.copy(
                this.templatePath('jshintrc'),
                this.destinationPath('.jshintrc')
            );

            // Archivo de traducción
            this.fs.copy(
                this.templatePath('languages/_lang.pot'),
                this.destinationPath(this.NombreTema+'/languages/'+this.NombreTema+'.pot')
            );

            // Miniatura del tema
            this.fs.copy(
                this.templatePath('screenshot.png'),
                this.destinationPath(this.NombreTema+'.png')
            );

            this.template('_functions.php', this.NombreTema+'/functions.php');
            this.template('_style.css', this.NombreTema+'/style.css');

            // Copiar plantillas php
            if ( this.Template.indexOf('Index.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_index.php'),
                    this.destinationPath(this.NombreTema+'/index.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Header.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_header.php'),
                    this.destinationPath(this.NombreTema+'/header.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Footer.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_footer.php'),
                    this.destinationPath(this.NombreTema+'/footer.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Sidebar.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_sidebar.php'),
                    this.destinationPath(this.NombreTema+'/sidebar.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Single.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_single.php'),
                    this.destinationPath(this.NombreTema+'/single.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Page.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_page.php'),
                    this.destinationPath(this.NombreTema+'/page.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }

            // plantillas opcionales
            if ( this.Template.indexOf('404.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_404.php'),
                    this.destinationPath(this.NombreTema+'/404.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Archive.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_archive.php'),
                    this.destinationPath(this.NombreTema+'/archive.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Author.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_author.php'),
                    this.destinationPath(this.NombreTema+'/author.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Category.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_category.php'),
                    this.destinationPath(this.NombreTema+'/category.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Comments.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_comments.php'),
                    this.destinationPath(this.NombreTema+'/comments.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Search.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_search.php'),
                    this.destinationPath(this.NombreTema+'/search.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Tag.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_tag.php'),
                    this.destinationPath(this.NombreTema+'/tag.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Taxonomy.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_taxonomy.php'),
                    this.destinationPath(this.NombreTema+'/taxonomy.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }

        },

        // Instalar Custom Metaboxes si se necesita
        instalarCustomMetaboxes: function() {

            if (this.CustomMetaboxes) {
                var cb = this.async();

                this.log.writeln(chalk.yellow('Descargando Custom Metaboxes and Fields for WordPress 2')),

                clone( 'https://github.com/WebDevStudios/CMB2.git', this.NombreTema+'/lib/cmb2', cb );
            }
        },

        // Instalar Custom Metaboxes si se necesita
        instalarReduxFramework: function() {

            if (this.ReduxFramework) {

                this.fs.copy(
                    this.templatePath('lib/admin'),
                    this.destinationPath(this.NombreTema+'/lib/admin')
                );

                var cb = this.async();

                this.log.writeln(chalk.yellow('Descargando Redux Framework')),

                clone( 'https://github.com/ReduxFramework/redux-framework.git', this.NombreTema+'/lib/admin/redux-framework', cb );
            }
        },

        // Instalar dependencias de plugins
        instalarTGMPlugins: function() {

            if ( this.Plugins.length > 0 ) {
                var cb = this.async();

                this.log.writeln(chalk.yellow('Descargando TGM Plugin Activation')),

                clone( 'https://github.com/thomasgriffin/TGM-Plugin-Activation.git', this.NombreTema+'/lib/tgm-plugin-activation', cb );

                this.template('functions/_plugin_dependencies.php', this.NombreTema+'/lib/tgm-plugin-activation/plugin_dependencies.php');
            }

        }

    },

    install: function () {
        this.installDependencies({
            skipInstall: this.options['skip-install']
         });
    }
});
<commit_msg>fix varios<commit_after>'use strict';
var yeoman   = require('yeoman-generator');
var chalk    = require('chalk');
//var yosay    = require('yosay');
var inquirer = require('inquirer');
var clone    = require('git-clone');

module.exports = yeoman.generators.Base.extend({
    initializing: function () {
        this.pkg = require('../package.json');
    },

    prompting: function () {
        var done = this.async();

        // Have Yeoman greet the user.
        var logo =
            +'\n '
            +'\n      _            _ _ _ _____  '
            +'\n  _ _|_|___ ___   | | | |  _  | '
            +'\n | | | |   |- _|  | | | |   __| '
            +'\n  \\_/|_|_|_|___|  \\_____|__|    '
            +'\n';
        this.log( logo );

        var prompts = [
            {
                name: 'NombreTema',
                message: 'Nombre del tema',
                default: 'temaWP'
            },
            {
                name: 'ThemeURI',
                message: 'URL del tema',
                default: ''
            },
            {
                name: 'Autor',
                message: 'Autor',
                default: 'Autor'
            },
            {
                name: 'AuthorURI',
                message: 'URL del Autor',
                default: ''
            },
            {
                name: 'Descripcion',
                message: 'Descripción',
                default: 'El mejor tema del mundo entero!'
            },
            {
                name: 'VersionTema',
                message: 'Versión',
                default: '1.0'
            },
            {
                name: 'TagsTema',
                message: 'Tags',
                default: ''
            },
            {
                type: 'list',
                name: 'jqueryVersion',
                message: 'Version de jQuery (Se carga desde el CDN de Google)',
                choices: [ 'jQuery 1.11.0', 'jQuery 2.1.0' ],
                filter: function( val ) {
                    if ( val.slice(8) === 1 ) {
                        return val = '1.11.0';
                    } else {
                        return val = '2.1.0';
                    }
                }
            },
            {
            type: 'checkbox',
                message: 'Archivos de la plantilla:',
                name: 'Template',
                choices: [
                    new inquirer.Separator('Basico:'),

                        { name: 'Index.php',   checked: true },
                        { name: 'Header.php',  checked: true },
                        { name: 'Footer.php',  checked: true },
                        { name: 'Sidebar.php', checked: true },
                        { name: 'Single.php',  checked: true },
                        { name: 'Page.php',    checked: true },

                    new inquirer.Separator('Ocional:'),

                        { name: '404.php' },
                        { name: 'Archive.php' },
                        { name: 'Author.php' },
                        { name: 'Category.php' },
                        { name: 'Comments.php' },
                        { name: 'Search.php' },
                        { name: 'Tag.php' },
                        { name: 'Taxonomy.php' },
                ],
                validate: function( answer ) {
                  if ( answer.length < 0) {
                    return 'You must choose at least one topping.';
                  }
                  return true;
                }
            },
            {
                type: 'confirm',
                name: 'CustomMetaboxes',
                message: '¿Usar Custom Metaboxes?',
                default: true
            },
            {
                type: 'confirm',
                name: 'ReduxFramework',
                message: '¿Usar Panel de control? (Redux Framework)',
                default: true
            },
            {
                type: 'checkbox',
                message: 'Incluir Plugins:',
                name: 'Plugins',
                choices: [
                    { name: 'Developer' },
                    { name: 'WP Sync DB' },
                    { name: 'WordPress SEO by Yoast' },
                    { name: 'Contact Form 7' },
                ],
                validate: function( answer ) {
                  if ( answer.length < 0) {
                    return 'Selecciona al menos un plugin.';
                  }
                  return true;
                }
            }
        ];

        this.prompt(prompts, function (props) {

            this.NombreTema      = props.NombreTema;
            this.ThemeURI        = props.ThemeURI;
            this.Autor           = props.Autor;
            this.AuthorURI       = props.AuthorURI;
            this.Descripcion     = props.Descripcion;
            this.VersionTema     = props.VersionTema;
            this.TagsTema        = props.TagsTema;
            this.jqueryVersion   = props.jqueryVersion;
            this.Template        = props.Template;
            this.CustomMetaboxes = props.CustomMetaboxes;
            this.ReduxFramework  = props.ReduxFramework;
            this.Plugins         = props.Plugins;

            done();
        }.bind(this));
    },

    writing: {

        app: function () {
            this.fs.copy(
                this.templatePath('_package.json'),
                this.destinationPath('package.json')
            );
            this.fs.copyTpl(
                this.templatePath('_bowerrc'),
                this.destinationPath('.bowerrc'),
                { NombreTema: this.NombreTema }
            );
            this.fs.copyTpl(
                this.templatePath('_bower.json'),
                this.destinationPath('bower.json'),
                { NombreTema: this.NombreTema,
                  VersionTema: this.VersionTema,
                  Autor: this.Autor,
                  ThemeURI: this.ThemeURI,
                  AuthorURI: this.AuthorURI }
            );
        },

        projectfiles: function () {
            this.fs.copy(
                this.templatePath('editorconfig'),
                this.destinationPath('.editorconfig')
            );
            this.fs.copy(
                this.templatePath('jshintrc'),
                this.destinationPath('.jshintrc')
            );

            // Archivo de traducción
            this.fs.copy(
                this.templatePath('languages/_lang.pot'),
                this.destinationPath(this.NombreTema+'/languages/'+this.NombreTema+'.pot')
            );

            // Miniatura del tema
            this.fs.copy(
                this.templatePath('screenshot.png'),
                this.destinationPath(this.NombreTema+'/screenshot.png')
            );

            this.template('_functions.php', this.NombreTema+'/functions.php');
            this.template('_style.css', this.NombreTema+'/style.css');

            // Copiar plantillas php
            if ( this.Template.indexOf('Index.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_index.php'),
                    this.destinationPath(this.NombreTema+'/index.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Header.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_header.php'),
                    this.destinationPath(this.NombreTema+'/header.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Footer.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_footer.php'),
                    this.destinationPath(this.NombreTema+'/footer.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Sidebar.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_sidebar.php'),
                    this.destinationPath(this.NombreTema+'/sidebar.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Single.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_single.php'),
                    this.destinationPath(this.NombreTema+'/single.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Page.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_page.php'),
                    this.destinationPath(this.NombreTema+'/page.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }

            // plantillas opcionales
            if ( this.Template.indexOf('404.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_404.php'),
                    this.destinationPath(this.NombreTema+'/404.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Archive.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_archive.php'),
                    this.destinationPath(this.NombreTema+'/archive.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Author.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_author.php'),
                    this.destinationPath(this.NombreTema+'/author.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Category.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_category.php'),
                    this.destinationPath(this.NombreTema+'/category.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Comments.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_comments.php'),
                    this.destinationPath(this.NombreTema+'/comments.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Search.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_search.php'),
                    this.destinationPath(this.NombreTema+'/search.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Tag.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_tag.php'),
                    this.destinationPath(this.NombreTema+'/tag.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }
            if ( this.Template.indexOf('Taxonomy.php') !== -1 ) {
                this.fs.copyTpl(
                    this.templatePath('Base-Hierarchy/_taxonomy.php'),
                    this.destinationPath(this.NombreTema+'/taxonomy.php'),
                    { NombreTema: this.NombreTema,
                      VersionTema: this.VersionTema }
                );
            }

        },

        // Instalar Custom Metaboxes si se necesita
        instalarCustomMetaboxes: function() {

            if (this.CustomMetaboxes) {
                var cb = this.async();

                this.log.writeln(chalk.yellow('Descargando Custom Metaboxes and Fields for WordPress 2')),

                clone( 'https://github.com/WebDevStudios/CMB2.git', this.NombreTema+'/lib/cmb2', cb );
            }
        },

        // Instalar Custom Metaboxes si se necesita
        instalarReduxFramework: function() {

            if (this.ReduxFramework) {

                this.fs.copy(
                    this.templatePath('lib/admin'),
                    this.destinationPath(this.NombreTema+'/lib/admin')
                );

                var cb = this.async();

                this.log.writeln(chalk.yellow('Descargando Redux Framework')),

                clone( 'https://github.com/ReduxFramework/redux-framework.git', this.NombreTema+'/lib/admin/redux-framework', cb );
            }
        },

        // Instalar dependencias de plugins
        instalarTGMPlugins: function() {

            if ( this.Plugins.length > 0 ) {
                var cb = this.async();

                this.log.writeln(chalk.yellow('Descargando TGM Plugin Activation')),

                clone( 'https://github.com/thomasgriffin/TGM-Plugin-Activation.git', this.NombreTema+'/lib/tgm-plugin-activation', cb );

                this.template('functions/_plugin_dependencies.php', this.NombreTema+'/lib/tgm-plugin-activation/plugin_dependencies.php');
            }

        }

    },

    install: function () {
        this.installDependencies({
            skipInstall: this.options['skip-install']
         });
    }
});
<|endoftext|>


<commit_before>var controllers = angular.module('controllers', []);

controllers.controller('HomeController', ['$scope',
  function ($scope) {
    $('.navbar-nav>li').removeClass('active');
    $('.navbar-nav>li#nav-home').addClass('active');
  }
]);

controllers.controller('ProjectsController', ['$scope',
  function ($scope) {
    $('.navbar-nav>li').removeClass('active');
    $('.navbar-nav>li#nav-projects').addClass('active');
  }
]);

controllers.controller('ResumeController', ['$scope',
  function ($scope) {
    $('.navbar-nav>li').removeClass('active');
    $('.navbar-nav>li#nav-resume').addClass('active');
  }
]);

controllers.controller('AboutController', ['$scope',
  function ($scope) {
    $('.navbar-nav>li').removeClass('active');
    $('.navbar-nav>li#nav-about').addClass('active');
  }
])

controllers.controller('MissingPageController', ['$scope',
  function ($scope) {
    $('.navbar-nav>li').removeClass('active');
  }
]);

controllers.controller('GameController', ['$scope',
  function ($scope) {
    $('#begin-game-btn').click(function() {
      $('.main-site').hide();
      document.body.scrollTop = 0; // pull the page back up to the top
      $('body').addClass('game-mode');
      $('#game-container').show();

      var cursorX;
      var cursorY;

      document.onmousemove = function(e) {
        cursorX = e.pageX;
        cursorY = e.pageY;
      }

      document.onmouseenter = function(e) {
        cursorX = e.pageX;
        cursorY = e.pageY;
      }

      var canvas = document.getElementById('game-canvas')
      var isSupported = !!canvas.getContext;
      var ctx = canvas.getContext('2d');

      // Generic helper functions
      function tripleToColour(triple) {
        return 'rgb(' + (triple[0] | 0) + ',' + (triple[1] | 0) + ',' + (triple[2] | 0) + ')';
      }

      // Constants
      var bgColour = '#000000';

      var gemSize = 0.01;
      var gemLineThickness = 1 / 750;
      var gemSizeInnerFactor = 0.6;
      var gemColour = [255, 255, 255];
      var gemShadeFactor = 0.6;
      var gemShadedColour = gemColour.map(function(c) { return (c * gemShadeFactor) | 0});

      var wallDistance = 0.03;
      var wallHalfWidth = 2 * Math.PI * 0.15;
      var wallColour = '#ffffff';
      var wallThickness = 1 / 500;

      var bgSegments = 16;

      // Must have 2 elements, if a constant function is desired
      // put the constant value twice
      var bgColourFunction = [
        [0,   0,   0],
        [255, 0,   0],
        [255, 255, 0],
        [0,   255, 0],
        [0,   255, 255],
        [0,   0,   255],
        [255, 0,   255],
        [255, 255, 255]
      ];

      function bgColourCalculation(progress) {
        progress = Math.max(Math.min(1, progress), 0);

        if (progress == 1) {
          return bgColourFunction[bgColourFunction.length - 1];
        }

        var ix = Math.floor(progress * (bgColourFunction.length - 1));
        var frac = progress * (bgColourFunction.length - 1) - ix;

        return tripleToColour([
          bgColourFunction[ix][0] * (1 - frac) + bgColourFunction[ix + 1][0] * frac,
          bgColourFunction[ix][1] * (1 - frac) + bgColourFunction[ix + 1][1] * frac,
          bgColourFunction[ix][2] * (1 - frac) + bgColourFunction[ix + 1][2] * frac,
        ]);
      }

      var dotSpawnChance = 1 / 60;
      var dotMinSpeed = 1 / 600;
      var dotMaxSpeed = 1 / 600;
      var dotSize = 1 / 400;
      var dotColour = '#ffffff';

      // Semi-constants for stuff that only changes sometimes (e.f=g. on screen resize)
      var width;
      var height;
      var midX;
      var midY;
      var scale;

      var bgSegmentPaths = [];
      for (var i = 0; i < bgSegments; i++) {
        bgSegmentPaths.push(null);
      }

      var gemInnerPath = null;
      var gemOuterPath = null;

      // Variable declarations
      var wallAngle;
      var bgProgress = [];
      for (var i = 0; i < bgSegments; i++) {
        bgProgress.push(0);
      }
      var idCounter = 0;
      var dots = {};

      function step() {
        wallAngle = Math.atan2(cursorY - midY, cursorX - midX);

        for (var dotId in dots) {
          var dot = dots[dotId];

          dot.distance -= dot.speed;

          if (dot.distance <= 0) {
            delete dots[dot.id];
          }
        }

        if (Math.random() < dotSpawnChance) {
          var dot = {};

          dot.speed = Math.random() * (dotMaxSpeed - dotMinSpeed) + dotMinSpeed;
          dot.direction = 2 * Math.PI * Math.random();
          dot.id = idCounter++;
          dot.distance = 1;

          dots[dot.id] = dot;
        }
      }

      function screenResize() {
        // Update certain semi-constants after the screen size changes
        width  = ctx.canvas.width  = window.innerWidth;
        height = ctx.canvas.height = window.innerHeight;
        midX = width / 2;
        midY = height / 2;
        scale = Math.sqrt(width*width + height*height);

        // Bg updates
        for (var i = 0; i < bgSegments; i++) {
          bgSegmentPaths[i] = new Path2D();

          bgSegmentPaths[i].moveTo(midX, midY);
          bgSegmentPaths[i].lineTo(midX + scale * Math.cos(2 * Math.PI / bgSegments * i), midY + scale * Math.sin(2 * Math.PI / bgSegments * i));
          bgSegmentPaths[i].lineTo(midX + scale * Math.cos(2 * Math.PI / bgSegments * (i + 1)), midY + scale * Math.sin(2 * Math.PI / bgSegments * (i + 1)));
        }

        // Gem updates
        gemInnerPath = new Path2D();

        gemInnerPath.moveTo(midX + scale * gemSize, midY);
        gemInnerPath.lineTo(midX, midY + scale * gemSize);
        gemInnerPath.lineTo(midX - scale * gemSize, midY);
        gemInnerPath.lineTo(midX, midY - scale * gemSize);
        gemInnerPath.lineTo(midX + scale * gemSize, midY);

        gemOuterPath = new Path2D();

        gemOuterPath.moveTo(midX + scale * gemSize, midY);
        gemOuterPath.lineTo(midX, midY + scale * gemSize);
        gemOuterPath.lineTo(midX - scale * gemSize, midY);
        gemOuterPath.lineTo(midX, midY - scale * gemSize);
        gemOuterPath.lineTo(midX + scale * gemSize, midY);

        gemOuterPath.lineTo(midX + scale * gemSize * gemSizeInnerFactor, midY);
        gemOuterPath.lineTo(midX, midY + scale * gemSize * gemSizeInnerFactor);
        gemOuterPath.lineTo(midX, midY + scale * gemSize);
        gemOuterPath.lineTo(midX, midY + scale * gemSize * gemSizeInnerFactor);
        gemOuterPath.lineTo(midX - scale * gemSize * gemSizeInnerFactor, midY);
        gemOuterPath.lineTo(midX - scale * gemSize, midY);
        gemOuterPath.lineTo(midX - scale * gemSize * gemSizeInnerFactor, midY);
        gemOuterPath.lineTo(midX, midY - scale * gemSize * gemSizeInnerFactor);
        gemOuterPath.lineTo(midX, midY - scale * gemSize);
        gemOuterPath.lineTo(midX, midY - scale * gemSize * gemSizeInnerFactor);
        gemOuterPath.lineTo(midX + scale * gemSize * gemSizeInnerFactor, midY);
      }

      function draw() {
        // Draw bg
        for (var i = 0; i < bgSegments; i++) {
          ctx.fillStyle = bgColourCalculation(bgProgress[i]);
          ctx.fill(bgSegmentPaths[i]);
        }

        // Draw gem
        ctx.fillStyle = tripleToColour(gemShadedColour);
        ctx.fill(gemInnerPath);

        ctx.lineWidth = scale * gemLineThickness;
        ctx.strokeStyle = tripleToColour(gemColour);
        ctx.stroke(gemOuterPath);

        // Draw wall
        var path = new Path2D();
        path.arc(midX, midY, scale * wallDistance, wallAngle - wallHalfWidth, wallAngle + wallHalfWidth, false);

        ctx.lineWidth = scale * wallThickness;
        ctx.strokeStyle = wallColour;
        ctx.stroke(path);

        // Draw dots
        for (var dotId in dots) {
          var dot = dots[dotId];

          path = new Path2D();
          path.arc(midX + scale * dot.distance * Math.cos(dot.direction), midY + scale * dot.distance * Math.sin(dot.direction), scale * dotSize, 0, 2 * Math.PI);

          ctx.fillStyle = dotColour;
          ctx.fill(path);
        }
      }

      function gameLoop() {
        if (width !== window.innerWidth || height !== window.innerHeight) {
          screenResize();
        }

        step();
        draw();
      }

      if (isSupported) {
        setInterval(gameLoop, 16);
      } else {
        // TODO: Make user aware that the game isn't available to them
      }
    });
  }
]);
<commit_msg>Implemented wall blocking the dots and adding progress to the background<commit_after>var controllers = angular.module('controllers', []);

controllers.controller('HomeController', ['$scope',
  function ($scope) {
    $('.navbar-nav>li').removeClass('active');
    $('.navbar-nav>li#nav-home').addClass('active');
  }
]);

controllers.controller('ProjectsController', ['$scope',
  function ($scope) {
    $('.navbar-nav>li').removeClass('active');
    $('.navbar-nav>li#nav-projects').addClass('active');
  }
]);

controllers.controller('ResumeController', ['$scope',
  function ($scope) {
    $('.navbar-nav>li').removeClass('active');
    $('.navbar-nav>li#nav-resume').addClass('active');
  }
]);

controllers.controller('AboutController', ['$scope',
  function ($scope) {
    $('.navbar-nav>li').removeClass('active');
    $('.navbar-nav>li#nav-about').addClass('active');
  }
])

controllers.controller('MissingPageController', ['$scope',
  function ($scope) {
    $('.navbar-nav>li').removeClass('active');
  }
]);

controllers.controller('GameController', ['$scope',
  function ($scope) {
    $('#begin-game-btn').click(function() {
      $('.main-site').hide();
      document.body.scrollTop = 0; // pull the page back up to the top
      $('body').addClass('game-mode');
      $('#game-container').show();

      var cursorX;
      var cursorY;

      document.onmousemove = function(e) {
        cursorX = e.pageX;
        cursorY = e.pageY;
      }

      document.onmouseenter = function(e) {
        cursorX = e.pageX;
        cursorY = e.pageY;
      }

      var canvas = document.getElementById('game-canvas')
      var isSupported = !!canvas.getContext;
      var ctx = canvas.getContext('2d');

      // Generic helper functions
      function tripleToColour(triple) {
        return 'rgb(' + (triple[0] | 0) + ',' + (triple[1] | 0) + ',' + (triple[2] | 0) + ')';
      }

      function angleDifference(x, y) {
        return Math.atan2(Math.sin(y - x), Math.cos(y - x));
      }

      // Constants
      var bgColour = '#000000';

      var gemSize = 0.01;
      var gemLineThickness = 1 / 750;
      var gemSizeInnerFactor = 0.6;
      var gemColour = [255, 255, 255];
      var gemShadeFactor = 0.8;
      var gemShadedColour = gemColour.map(function(c) { return (c * gemShadeFactor) | 0});

      var wallDistance = 0.03;
      var wallHalfWidth = 2 * Math.PI * 0.15;
      var wallColour = '#ffffff';
      var wallThickness = 1 / 500;

      var bgSegments = 16;

      // Must have 2 elements, if a constant function is desired
      // put the constant value twice
      var bgColourFunction = [
        [0,   0,   0],
        [255, 0,   0],
        [255, 255, 0],
        [0,   255, 0],
        [0,   255, 255],
        [0,   0,   255],
        [255, 0,   255],
        [255, 255, 255]
      ];

      function bgColourCalculation(progress) {
        progress = Math.max(Math.min(1, progress), 0);

        if (progress == 1) {
          return tripleToColour(bgColourFunction[bgColourFunction.length - 1]);
        }

        var ix = Math.floor(progress * (bgColourFunction.length - 1));
        var frac = progress * (bgColourFunction.length - 1) - ix;

        return tripleToColour([
          bgColourFunction[ix][0] * (1 - frac) + bgColourFunction[ix + 1][0] * frac,
          bgColourFunction[ix][1] * (1 - frac) + bgColourFunction[ix + 1][1] * frac,
          bgColourFunction[ix][2] * (1 - frac) + bgColourFunction[ix + 1][2] * frac,
        ]);
      }

      var dotSpawnChance = 1 / 60;
      var dotMinSpeed = 1 / 600;
      var dotMaxSpeed = 1 / 600;
      var dotSize = 1 / 400;
      var dotColour = '#ffffff';

      var dotProgress = 0.02;

      var wallBBoxHalfWidth = wallHalfWidth + dotSize / wallDistance;

      // Semi-constants for stuff that only changes sometimes (e.f=g. on screen resize)
      var width;
      var height;
      var midX;
      var midY;
      var scale;

      var bgSegmentPaths = [];
      for (var i = 0; i < bgSegments; i++) {
        bgSegmentPaths.push(null);
      }

      var gemInnerPath = null;
      var gemOuterPath = null;

      // Variable declarations
      var wallAngle;
      var bgProgress = [];
      for (var i = 0; i < bgSegments; i++) {
        bgProgress.push(0);
      }
      var idCounter = 0;
      var dots = {};

      function step() {
        wallAngle = Math.atan2(cursorY - midY, cursorX - midX);

        for (var dotId in dots) {
          var dot = dots[dotId];

          dot.previousDistance = dot.distance;
          dot.distance -= dot.speed;
        }

        for (var dotId in dots) {
          var dot = dots[dotId];

          if (dot.previousDistance + dotSize >= wallDistance - wallThickness / 2 && dot.distance - dotSize <= wallDistance + wallThickness / 2) {
            if (Math.abs(angleDifference(wallAngle, dot.direction)) <= wallBBoxHalfWidth) {
              var segmentIx = (dot.direction * bgSegments / (2 * Math.PI)) | 0;
              bgProgress[segmentIx] += dotProgress;

              delete dots[dot.id];
            }
          } else if (dot.distance <= 0) {
            delete dots[dot.id];
          }
        }

        if (Math.random() < dotSpawnChance) {
          var dot = {};

          dot.speed = Math.random() * (dotMaxSpeed - dotMinSpeed) + dotMinSpeed;
          dot.direction = 2 * Math.PI * Math.random();
          dot.id = idCounter++;
          dot.distance = 1;

          dots[dot.id] = dot;
        }
      }

      function screenResize() {
        // Update certain semi-constants after the screen size changes
        width  = ctx.canvas.width  = window.innerWidth;
        height = ctx.canvas.height = window.innerHeight;
        midX = width / 2;
        midY = height / 2;
        scale = Math.sqrt(width*width + height*height);

        // Bg updates
        for (var i = 0; i < bgSegments; i++) {
          bgSegmentPaths[i] = new Path2D();

          bgSegmentPaths[i].moveTo(midX, midY);
          bgSegmentPaths[i].lineTo(midX + scale * Math.cos(2 * Math.PI / bgSegments * i), midY + scale * Math.sin(2 * Math.PI / bgSegments * i));
          bgSegmentPaths[i].lineTo(midX + scale * Math.cos(2 * Math.PI / bgSegments * (i + 1)), midY + scale * Math.sin(2 * Math.PI / bgSegments * (i + 1)));
        }

        // Gem updates
        gemInnerPath = new Path2D();

        gemInnerPath.moveTo(midX + scale * gemSize, midY);
        gemInnerPath.lineTo(midX, midY + scale * gemSize);
        gemInnerPath.lineTo(midX - scale * gemSize, midY);
        gemInnerPath.lineTo(midX, midY - scale * gemSize);
        gemInnerPath.lineTo(midX + scale * gemSize, midY);

        gemOuterPath = new Path2D();

        gemOuterPath.moveTo(midX + scale * gemSize, midY);
        gemOuterPath.lineTo(midX, midY + scale * gemSize);
        gemOuterPath.lineTo(midX - scale * gemSize, midY);
        gemOuterPath.lineTo(midX, midY - scale * gemSize);
        gemOuterPath.lineTo(midX + scale * gemSize, midY);

        gemOuterPath.lineTo(midX + scale * gemSize * gemSizeInnerFactor, midY);
        gemOuterPath.lineTo(midX, midY + scale * gemSize * gemSizeInnerFactor);
        gemOuterPath.lineTo(midX, midY + scale * gemSize);
        gemOuterPath.lineTo(midX, midY + scale * gemSize * gemSizeInnerFactor);
        gemOuterPath.lineTo(midX - scale * gemSize * gemSizeInnerFactor, midY);
        gemOuterPath.lineTo(midX - scale * gemSize, midY);
        gemOuterPath.lineTo(midX - scale * gemSize * gemSizeInnerFactor, midY);
        gemOuterPath.lineTo(midX, midY - scale * gemSize * gemSizeInnerFactor);
        gemOuterPath.lineTo(midX, midY - scale * gemSize);
        gemOuterPath.lineTo(midX, midY - scale * gemSize * gemSizeInnerFactor);
        gemOuterPath.lineTo(midX + scale * gemSize * gemSizeInnerFactor, midY);
      }

      function draw() {
        // Draw bg
        for (var i = 0; i < bgSegments; i++) {
          ctx.fillStyle = bgColourCalculation(bgProgress[i]);
          ctx.fill(bgSegmentPaths[i]);
        }

        // Draw gem
        ctx.fillStyle = tripleToColour(gemShadedColour);
        ctx.fill(gemInnerPath);

        ctx.lineWidth = scale * gemLineThickness;
        ctx.strokeStyle = tripleToColour(gemColour);
        ctx.stroke(gemOuterPath);

        // Draw wall
        var path = new Path2D();
        path.arc(midX, midY, scale * wallDistance, wallAngle - wallHalfWidth, wallAngle + wallHalfWidth, false);

        ctx.lineWidth = scale * wallThickness;
        ctx.strokeStyle = wallColour;
        ctx.stroke(path);

        // Draw dots
        for (var dotId in dots) {
          var dot = dots[dotId];

          path = new Path2D();
          path.arc(midX + scale * dot.distance * Math.cos(dot.direction), midY + scale * dot.distance * Math.sin(dot.direction), scale * dotSize, 0, 2 * Math.PI);

          ctx.fillStyle = dotColour;
          ctx.fill(path);
        }
      }

      function gameLoop() {
        if (width !== window.innerWidth || height !== window.innerHeight) {
          screenResize();
        }

        step();
        draw();
      }

      if (isSupported) {
        setInterval(gameLoop, 16);
      } else {
        // TODO: Make user aware that the game isn't available to them
      }
    });
  }
]);
<|endoftext|>


<commit_before>/* (c) Copyright 2002-2012 by authors of the Tiki Wiki CMS Groupware Project
 *
 * All Rights Reserved. See copyright.txt for details and a complete list of authors.
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
 * $Id$
 *
 * Tiki plugin integration plugin.
 *
 * Based on ckeditor flash plugin
 */

(function() {

	var protectTikiPluginsRegexp = /<(?:div|span)[^>]*syntax="([^"]*)"[\s\S]*?end tiki_plugin -->\s*?<\/(?:div|span)>/mig;

	CKEDITOR.plugins.add( 'tikiplugin', {

		init : function(editor) {

			var asplugin = this;

			editor.config.protectedSource.push( protectTikiPluginsRegexp );

			this.command = new CKEDITOR.command( editor , {
				modes: { wysiwyg:1 },
				exec: function(editor, data) {	// odd? elem param disappears from doubleclick
					var sel = editor.getSelection(), r;
					// Selection will be unavailable after context menu shows up - in IE, lock it now.
					if ( CKEDITOR.env.ie ) {
						if (sel) { sel.lock(); }
					}
					if (data === editor) {
						r = sel.getRanges();
						data = r[0].startContainer;
					}
					var args = {};
					var str = $('
').html(data.getAttribute("args")).text();	// decode html entities
					var pairs = str.split("&");
					for (var i = 0; i < pairs.length; i++) {
						if (pairs[i].indexOf("=") > -1) {
							args[pairs[i].substring(0, pairs[i].indexOf("="))] = pairs[i].substring((pairs[i].indexOf("=") + 1));
						}
					}
					sel.selectElement( data );
					popupPluginForm( editor.name, data.getAttribute("plugin"), 0, '', args, data.getAttribute("body"), '');
				},
				canUndo: false
			});

			editor.addCommand('tikiplugin', this.command);

			editor.addCss('.tiki_plugin'
							+ '{'
							+ 'display: inline-block;'
							+ 'background-color: #eee;'
							+ 'border: 1px solid #666;'
							+ '}'
							+ ' div.tiki_plugin { width: 100%; }'
						);

			// If the "menu" plugin is loaded, register the menu items.
			if (editor.addMenuItems) {
                editor.addMenuGroup("tiki", 999);
				editor.addMenuItems( {
					tikiplugin : {
						label : 'Tiki Plugin',
						command : 'tikiplugin',
						group : 'tiki',
						icon : CKEDITOR.config._TikiRoot + 'img/icons/plugin_edit.png'
					}
				});
			}

			editor.on('contentDom', function() {	// re-apply the events etc when wysiwyg mode happens

				$(".tiki_plugin", editor.document.$).each(function() {
					var parentPlugin = new CKEDITOR.dom.element(this);
					$(this).find("*").each(function(){
						$(this).mousedown(function(){
							var sel = editor.getSelection();
							if (sel) {
								sel.selectElement(parentPlugin);
							}
							return false;
						}); //.attr("contenteditable", "false");
					});
				});

				editor.on( 'doubleclick', function(evt) {
					var element = evt.data.element;

					element = asplugin.getPluginParent( element );

					if (element) {
						evt.cancel();
						evt.stop();
						evt.data.dialog = null;
						this.plugins.tikiplugin.command.exec(element);
					}
				});
			});

			// If the "contextmenu" plugin is loaded, register the listeners.
			if (editor.contextMenu) {
				editor.contextMenu.addListener(function(element, selection) {

					element = asplugin.getPluginParent( element );

					if (element) {
						return {
							tikiplugin : CKEDITOR.TRISTATE_OFF
						};
					}
				});
			}
			if (jqueryTiki.autosave) {	// pref check
				if (typeof editor.plugins["tikiwiki"] === "undefined") {	// also defined in tikiwiki plugin
					this.ckToHtml = editor.dataProcessor.toHtml;		// reference to original ckeditor dataProcessor
					editor.dataProcessor.toHtml			= function ( data, fixForBody ) { return asplugin.toHtmlFormat( editor, data, fixForBody ); };
				}
				this.ckToData = editor.dataProcessor.toDataFormat;
				editor.dataProcessor.toDataFormat 	= function ( html, fixForBody ) { return asplugin.toHTMLSource( editor, html, fixForBody ); };
			}
		},			// end of init()

		afterInit : function( editor ) {
			// Register a filter to displaying placeholders after mode change. (taken from pagebreak plugin)

			var asplugin = this;

			var dataProcessor = editor.dataProcessor,
				dataFilter = dataProcessor && dataProcessor.dataFilter;

			if ( dataFilter ) {
				dataFilter.addRules( {
					elements : {
						div : function( element ) {
							return asplugin.processTikiPlugin( element, 'div', editor);
						},
						span : function( element ) {
							return asplugin.processTikiPlugin( element, 'span', editor);
						}
					}
				});
			}
		},

		requires : [ 'fakeobjects' ],

		// variation on CKEDITOR.editor.createFakeParserElement set up by fakeobject plugin
		processTikiPlugin : function ( element, tag, editor ) {
			var name = element.attributes && element.attributes.plugin;

			if (name) {	// a tiki plugin
				var html;

				var writer = new CKEDITOR.htmlParser.basicWriter();
				element.writeHtml( writer );
				html = writer.getHtml();

				element.attributes._cke_realelement = tiki_encodeURIComponent( html );
				element.attributes._cke_real_node_type = tag;

				element.attributes._cke_real_element_type = tag;
				element.attributes.contenteditable = false;

				if (name === 'img') {
					element.attributes._cke_resizable = true;
				} else {
					element.attributes._cke_resizable = false;
				}

				// Set onclick for the contents
				for ( var i = 0 ; i < element.children.length ; i++ ) {
					if ( element.children[ i ].attributes ) {
						element.children[ i ].attributes.contenteditable = false;
					} else {
						// seems to make the whole editor readonly
						//element.children[ i ].attributes = { contenteditable: false};
					}
				}

				return element;
			}
			return null;
		},

		getPluginParent: function ( element ) {
			while (element && element.getParent()) {
				if (element.getAttribute('plugin')) {
					return element;
				}
				element = element.getParent();
			}
			return null;
		},

		toHTMLSource: function( editor, html, fixForBody ) {
			// de-protect ck_protected comments
			var output = html;

			output = this.ckToData.call( editor.dataProcessor, output, fixForBody );

			if (typeof editor.plugins["tikiwiki"] === "undefined") {
				output = output.replace(/
([\s\S]*?)<\/pre>/ig, "$1");
			}
			output = output.replace(//ig, "");
			// replace visual plugins with syntax
			output = output.replace( protectTikiPluginsRegexp, function() {
				if (arguments.length > 0) {
					var plugCode = $("").html(arguments[1]).text();
					if (typeof editor.plugins["tikiwiki"] !== "undefined") {	// also defined in tikiwiki plugin
						plugCode = plugCode.replace(/\n/g, "
");
					}
					return plugCode;	// decode html entities
				} else {
					alert("ckeditor: error parsing to html source");
					return "";
				}
			});
			output = output.replace(/\s*
[\s]*<\/p>\s*/mgi, "");	// strip out empty
 tags

			return output;
		},

		toHtmlFormat: function( editor, data, fixForBody ) {
			if (!jqueryTiki.autosave) {
				alert(tr("AJAX Autosave preference not enabled. Please go to admin/features/interface to enable it."));
			}
			var output = "";
			var asplugin = this;
			var orig_data = $("#editwiki").val();	// just in case
			var isHtml = $("#allowhtml:checked").length || $("#allowhtml[type=hidden]").val();

			ajaxLoadingShow( "cke_contents_" + editor.name);
			$("#ajaxLoading").show();		// FIXME safari/chrome refuse to show until ajax finished
			jQuery.ajax({
				async: false, // wait for this one
				url: CKEDITOR.config.ajaxAutoSaveTargetUrl,
				type: "POST",
				data: {
					referer: editor.config.autoSaveSelf,
					editor_id: editor.name,
					data: tiki_encodeURIComponent(data),
					command: "toHtmlFormat",
					allowhtml: isHtml
				},
				// good callback
				success: function(data) {
					ajaxLoadingHide();
					try {
					    output = tiki_decodeURIComponent(jQuery(data).find('data').text());
					} catch (err) {
					    // Maybe it used escape to encode it? Try unescape
					    output = unescape(jQuery(data).find('data').text());
					}
					output = asplugin.ckToHtml.call(editor.dataProcessor, output, fixForBody);
					if (output.indexOf("") === -1) {
						output += ""; 	// workaround for cke 3.4 / tiki 6.0 FIXME
					}
				},
				// bad callback - no good info in the params :(
				error: function(req, status, error) {
					ajaxLoadingHide();
					output = orig_data;	//"ajax error";
					alert(tr("AJAX Error") + "\n" + tr("It may not be possible to edit this page reliably in WYSIWYG mode in this browser.") + "\n\n" + error.message);
				}
			});
			return output;
		},

		requires : [ '' ]	// TODO check req - autosave? (really)
	});

	if (typeof CKEDITOR.editor.prototype.reParse != 'function') {
		CKEDITOR.editor.prototype.reParse = function() {

			// send the whole source off to the server to get reparsed?
			var myoutput = "";
			var mydata = this.getData();
			myoutput = this.dataProcessor.toHtml(mydata);

			this.setData(myoutput);
		};
	}
})();
<commit_msg>[FIX] wysiwyg: Catch strange edge case on IE where plugin container element not selected properly<commit_after>/* (c) Copyright 2002-2012 by authors of the Tiki Wiki CMS Groupware Project
 *
 * All Rights Reserved. See copyright.txt for details and a complete list of authors.
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
 * $Id$
 *
 * Tiki plugin integration plugin.
 *
 * Based on ckeditor flash plugin
 */

(function() {

	var protectTikiPluginsRegexp = /<(?:div|span)[^>]*syntax="([^"]*)"[\s\S]*?end tiki_plugin -->\s*?<\/(?:div|span)>/mig;

	CKEDITOR.plugins.add( 'tikiplugin', {

		init : function(editor) {

			var asplugin = this;

			editor.config.protectedSource.push( protectTikiPluginsRegexp );

			this.command = new CKEDITOR.command( editor , {
				modes: { wysiwyg:1 },
				exec: function(editor, data) {	// odd? elem param disappears from doubleclick
					var sel = editor.getSelection(), r;
					// Selection will be unavailable after context menu shows up - in IE, lock it now.
					if ( CKEDITOR.env.ie ) {
						if (sel) { sel.lock(); }
					}
					if (data === editor) {
						r = sel.getRanges();
						data = r[0].startContainer;
					}
					if (!$(data.$).hasClass("tiki_plugin")) {
						// problem here - wrong element sent in?
						debugger;		// intentionally left in to catch occasional IE edge cases
						return;
					}
					var args = {};
					var str = $('
').html(data.getAttribute("args")).text();	// decode html entities
					var pairs = str.split("&");
					for (var i = 0; i < pairs.length; i++) {
						if (pairs[i].indexOf("=") > -1) {
							args[pairs[i].substring(0, pairs[i].indexOf("="))] = pairs[i].substring((pairs[i].indexOf("=") + 1));
						}
					}
					sel.selectElement( data );
					popupPluginForm( editor.name, data.getAttribute("plugin"), 0, '', args, data.getAttribute("body"), '');
				},
				canUndo: false
			});

			editor.addCommand('tikiplugin', this.command);

			editor.addCss('.tiki_plugin'
							+ '{'
							+ 'display: inline-block;'
							+ 'background-color: #eee;'
							+ 'border: 1px solid #666;'
							+ '}'
							+ ' div.tiki_plugin { width: 100%; }'
						);

			// If the "menu" plugin is loaded, register the menu items.
			if (editor.addMenuItems) {
                editor.addMenuGroup("tiki", 999);
				editor.addMenuItems( {
					tikiplugin : {
						label : 'Tiki Plugin',
						command : 'tikiplugin',
						group : 'tiki',
						icon : CKEDITOR.config._TikiRoot + 'img/icons/plugin_edit.png'
					}
				});
			}

			editor.on('contentDom', function() {	// re-apply the events etc when wysiwyg mode happens

				$(".tiki_plugin", editor.document.$).each(function() {
					var parentPlugin = new CKEDITOR.dom.element(this);
					$(this).find("*").each(function(){
						$(this).mousedown(function(){
							var sel = editor.getSelection();
							if (sel) {
								sel.selectElement(parentPlugin);
							}
							return false;
						}); //.attr("contenteditable", "false");
					});
				});

				editor.on( 'doubleclick', function(evt) {
					var element = evt.data.element;

					element = asplugin.getPluginParent( element );

					if (element) {
						evt.cancel();
						evt.stop();
						evt.data.dialog = null;
						this.plugins.tikiplugin.command.exec(element);
					}
				});
			});

			// If the "contextmenu" plugin is loaded, register the listeners.
			if (editor.contextMenu) {
				editor.contextMenu.addListener(function(element, selection) {

					element = asplugin.getPluginParent( element );

					if (element) {
						return {
							tikiplugin : CKEDITOR.TRISTATE_OFF
						};
					}
				});
			}
			if (jqueryTiki.autosave) {	// pref check
				if (typeof editor.plugins["tikiwiki"] === "undefined") {	// also defined in tikiwiki plugin
					this.ckToHtml = editor.dataProcessor.toHtml;		// reference to original ckeditor dataProcessor
					editor.dataProcessor.toHtml			= function ( data, fixForBody ) { return asplugin.toHtmlFormat( editor, data, fixForBody ); };
				}
				this.ckToData = editor.dataProcessor.toDataFormat;
				editor.dataProcessor.toDataFormat 	= function ( html, fixForBody ) { return asplugin.toHTMLSource( editor, html, fixForBody ); };
			}
		},			// end of init()

		afterInit : function( editor ) {
			// Register a filter to displaying placeholders after mode change. (taken from pagebreak plugin)

			var asplugin = this;

			var dataProcessor = editor.dataProcessor,
				dataFilter = dataProcessor && dataProcessor.dataFilter;

			if ( dataFilter ) {
				dataFilter.addRules( {
					elements : {
						div : function( element ) {
							return asplugin.processTikiPlugin( element, 'div', editor);
						},
						span : function( element ) {
							return asplugin.processTikiPlugin( element, 'span', editor);
						}
					}
				});
			}
		},

		requires : [ 'fakeobjects' ],

		// variation on CKEDITOR.editor.createFakeParserElement set up by fakeobject plugin
		processTikiPlugin : function ( element, tag, editor ) {
			var name = element.attributes && element.attributes.plugin;

			if (name) {	// a tiki plugin
				var html;

				var writer = new CKEDITOR.htmlParser.basicWriter();
				element.writeHtml( writer );
				html = writer.getHtml();

				element.attributes._cke_realelement = tiki_encodeURIComponent( html );
				element.attributes._cke_real_node_type = tag;

				element.attributes._cke_real_element_type = tag;
				element.attributes.contenteditable = false;

				if (name === 'img') {
					element.attributes._cke_resizable = true;
				} else {
					element.attributes._cke_resizable = false;
				}

				// Set onclick for the contents
				for ( var i = 0 ; i < element.children.length ; i++ ) {
					if ( element.children[ i ].attributes ) {
						element.children[ i ].attributes.contenteditable = false;
					} else {
						// seems to make the whole editor readonly
						//element.children[ i ].attributes = { contenteditable: false};
					}
				}

				return element;
			}
			return null;
		},

		getPluginParent: function ( element ) {
			while (element && element.getParent()) {
				if (element.getAttribute('plugin')) {
					return element;
				}
				element = element.getParent();
			}
			return null;
		},

		toHTMLSource: function( editor, html, fixForBody ) {
			// de-protect ck_protected comments
			var output = html;

			output = this.ckToData.call( editor.dataProcessor, output, fixForBody );

			if (typeof editor.plugins["tikiwiki"] === "undefined") {
				output = output.replace(/
([\s\S]*?)<\/pre>/ig, "$1");
			}
			output = output.replace(//ig, "");
			// replace visual plugins with syntax
			output = output.replace( protectTikiPluginsRegexp, function() {
				if (arguments.length > 0) {
					var plugCode = $("").html(arguments[1]).text();
					if (typeof editor.plugins["tikiwiki"] !== "undefined") {	// also defined in tikiwiki plugin
						plugCode = plugCode.replace(/\n/g, "
");
					}
					return plugCode;	// decode html entities
				} else {
					alert("ckeditor: error parsing to html source");
					return "";
				}
			});
			output = output.replace(/\s*
[\s]*<\/p>\s*/mgi, "");	// strip out empty
 tags

			return output;
		},

		toHtmlFormat: function( editor, data, fixForBody ) {
			if (!jqueryTiki.autosave) {
				alert(tr("AJAX Autosave preference not enabled. Please go to admin/features/interface to enable it."));
			}
			var output = "";
			var asplugin = this;
			var orig_data = $("#editwiki").val();	// just in case
			var isHtml = $("#allowhtml:checked").length || $("#allowhtml[type=hidden]").val();

			ajaxLoadingShow( "cke_contents_" + editor.name);
			$("#ajaxLoading").show();		// FIXME safari/chrome refuse to show until ajax finished
			jQuery.ajax({
				async: false, // wait for this one
				url: CKEDITOR.config.ajaxAutoSaveTargetUrl,
				type: "POST",
				data: {
					referer: editor.config.autoSaveSelf,
					editor_id: editor.name,
					data: tiki_encodeURIComponent(data),
					command: "toHtmlFormat",
					allowhtml: isHtml
				},
				// good callback
				success: function(data) {
					ajaxLoadingHide();
					try {
					    output = tiki_decodeURIComponent(jQuery(data).find('data').text());
					} catch (err) {
					    // Maybe it used escape to encode it? Try unescape
					    output = unescape(jQuery(data).find('data').text());
					}
					output = asplugin.ckToHtml.call(editor.dataProcessor, output, fixForBody);
					if (output.indexOf("") === -1) {
						output += ""; 	// workaround for cke 3.4 / tiki 6.0 FIXME
					}
				},
				// bad callback - no good info in the params :(
				error: function(req, status, error) {
					ajaxLoadingHide();
					output = orig_data;	//"ajax error";
					alert(tr("AJAX Error") + "\n" + tr("It may not be possible to edit this page reliably in WYSIWYG mode in this browser.") + "\n\n" + error.message);
				}
			});
			return output;
		},

		requires : [ '' ]	// TODO check req - autosave? (really)
	});

	if (typeof CKEDITOR.editor.prototype.reParse != 'function') {
		CKEDITOR.editor.prototype.reParse = function() {

			// send the whole source off to the server to get reparsed?
			var myoutput = "";
			var mydata = this.getData();
			myoutput = this.dataProcessor.toHtml(mydata);

			this.setData(myoutput);
		};
	}
})();
<|endoftext|>


<commit_before>var util = require( '../../../util' );
var math = require( '../../../math' );

var CRp = {};

CRp.eleTextBiggerThanMin = function( ele, scale ){
  if( !scale ){
    var zoom = ele.cy().zoom();
    var pxRatio = this.getPixelRatio();
    var lvl = Math.ceil( math.log2( zoom * pxRatio ) ); // the effective texture level

    scale = Math.pow( 2, lvl );
  }

  var computedSize = ele.pstyle( 'font-size' ).pfValue * scale;
  var minSize = ele.pstyle( 'min-zoomed-font-size' ).pfValue;

  if( computedSize < minSize ){
    return false;
  }

  return true;
};

CRp.drawElementText = function( context, ele, force ){
  var r = this;

  if( force === undefined ){
    if( !r.eleTextBiggerThanMin( ele ) ){ return; }
  } else {
    if( !force ){ return; }
  }

  if( ele.isNode() ){
    var label = ele.pstyle( 'label' );

    if( !label || !label.value ){ return; }

    var textHalign = ele.pstyle( 'text-halign' ).strValue;
    var textValign = ele.pstyle( 'text-valign' ).strValue;

    switch( textHalign ){
      case 'left':
        context.textAlign = 'right';
        break;

      case 'right':
        context.textAlign = 'left';
        break;

      default: // e.g. center
        context.textAlign = 'center';
    }

    context.textBaseline = 'bottom';
  } else {
    var label = ele.pstyle( 'label' );
    var srcLabel = ele.pstyle( 'source-label' );
    var tgtLabel = ele.pstyle( 'target-label' );

    if(
      ( !label || !label.value )
      && ( !srcLabel || !srcLabel.value )
      && ( !tgtLabel || !tgtLabel.value )
    ){
      return;
    }

    context.textAlign = 'center';
    context.textBaseline = 'bottom';
  }

  r.drawText( context, ele );

  if( ele.isEdge() ){
    r.drawText( context, ele, 'source' );

    r.drawText( context, ele, 'target' );
  }
};

CRp.drawNodeText = CRp.drawEdgeText = CRp.drawElementText;

CRp.getFontCache = function( context ){
  var cache;

  this.fontCaches = this.fontCaches || [];

  for( var i = 0; i < this.fontCaches.length; i++ ){
    cache = this.fontCaches[ i ];

    if( cache.context === context ){
      return cache;
    }
  }

  cache = {
    context: context
  };
  this.fontCaches.push( cache );

  return cache;
};

// set up canvas context with font
// returns transformed text string
CRp.setupTextStyle = function( context, ele ){
  // Font style
  var parentOpacity = ele.effectiveOpacity();
  var labelStyle = ele.pstyle( 'font-style' ).strValue;
  var labelSize = ele.pstyle( 'font-size' ).pfValue + 'px';
  var labelFamily = ele.pstyle( 'font-family' ).strValue;
  var labelWeight = ele.pstyle( 'font-weight' ).strValue;
  var opacity = ele.pstyle( 'text-opacity' ).value * ele.pstyle( 'opacity' ).value * parentOpacity;
  var outlineOpacity = ele.pstyle( 'text-outline-opacity' ).value * opacity;
  var color = ele.pstyle( 'color' ).value;
  var outlineColor = ele.pstyle( 'text-outline-color' ).value;

  var fontCacheKey = ele._private.fontKey;
  var cache = this.getFontCache( context );

  if( cache.key !== fontCacheKey ){
    context.font = labelStyle + ' ' + labelWeight + ' ' + labelSize + ' ' + labelFamily;

    cache.key = fontCacheKey;
  }

  // Calculate text draw position based on text alignment

  // so text outlines aren't jagged
  context.lineJoin = 'round';

  this.fillStyle( context, color[ 0 ], color[ 1 ], color[ 2 ], opacity );

  this.strokeStyle( context, outlineColor[ 0 ], outlineColor[ 1 ], outlineColor[ 2 ], outlineOpacity );
};

function roundRect( ctx, x, y, width, height, radius ){
  var radius = radius || 5;
  ctx.beginPath();
  ctx.moveTo( x + radius, y );
  ctx.lineTo( x + width - radius, y );
  ctx.quadraticCurveTo( x + width, y, x + width, y + radius );
  ctx.lineTo( x + width, y + height - radius );
  ctx.quadraticCurveTo( x + width, y + height, x + width - radius, y + height );
  ctx.lineTo( x + radius, y + height );
  ctx.quadraticCurveTo( x, y + height, x, y + height - radius );
  ctx.lineTo( x, y + radius );
  ctx.quadraticCurveTo( x, y, x + radius, y );
  ctx.closePath();
  ctx.fill();
}

// Draw text
CRp.drawText = function( context, ele, prefix ){
  var _p = ele._private;
  var rscratch = _p.rscratch;
  var parentOpacity = ele.effectiveOpacity();
  if( parentOpacity === 0 || ele.pstyle( 'text-opacity' ).value === 0 ){
    return;
  }

  var textX = util.getPrefixedProperty( rscratch, 'labelX', prefix );
  var textY = util.getPrefixedProperty( rscratch, 'labelY', prefix );
  var text = this.getLabelText( ele, prefix );

  if( text != null && text !== '' && !isNaN( textX ) && !isNaN( textY ) ){
    this.setupTextStyle( context, ele );

    var pdash = prefix ? prefix + '-' : '';
    var textW = util.getPrefixedProperty( rscratch, 'labelWidth', prefix );
    var textH = util.getPrefixedProperty( rscratch, 'labelHeight', prefix );
    var textAngle = util.getPrefixedProperty( rscratch, 'labelAngle', prefix );
    var marginX = ele.pstyle( pdash + 'text-margin-x' ).pfValue;
    var marginY = ele.pstyle( pdash + 'text-margin-y' ).pfValue;

    var isEdge = ele.isEdge();
    var isNode = ele.isNode();

    var halign = ele.pstyle( 'text-halign' ).value;
    var valign = ele.pstyle( 'text-valign' ).value;

    if( isEdge ){
      halign = 'center';
      valign = 'center';
    }

    textX += marginX;
    textY += marginY;

    var rotation = ele.pstyle( 'text-rotation' );
    var theta;

    if( rotation.strValue === 'autorotate' ){
      theta = isEdge ? textAngle : 0;
    } else if( rotation.strValue === 'none' ){
      theta = 0;
    } else {
      theta = rotation.pfValue;
    }

    if( theta !== 0 ){
      var orgTextX = textX;
      var orgTextY = textY;

      context.translate( orgTextX, orgTextY );
      context.rotate( theta );

      textX = 0;
      textY = 0;
    }

    switch( valign ){
      case 'top':
        break;
      case 'center':
        textY += textH / 2;
        break;
      case 'bottom':
        textY += textH;
        break;
    }

    var backgroundOpacity = ele.pstyle( 'text-background-opacity' ).value;
    var borderOpacity = ele.pstyle( 'text-border-opacity' ).value;
    var textBorderWidth = ele.pstyle( 'text-border-width' ).pfValue;
    var backgroundPadding = ele.pstyle( 'text-background-padding' ).pfValue;

    if( backgroundOpacity > 0 || ( textBorderWidth > 0 && borderOpacity > 0 ) ){
      var bgX = textX - backgroundPadding;

      switch( halign ){
        case 'left':
          bgX -= textW;
          break;
        case 'center':
          bgX -= textW / 2;
          break;
        case 'right':
          break;
      }

      var bgY = textY - textH - backgroundPadding;
      var bgW = textW + 2*backgroundPadding;
      var bgH = textH + 2*backgroundPadding;

      if( backgroundOpacity > 0 ){
        var textFill = context.fillStyle;
        var textBackgroundColor = ele.pstyle( 'text-background-color' ).value;

        context.fillStyle = 'rgba(' + textBackgroundColor[ 0 ] + ',' + textBackgroundColor[ 1 ] + ',' + textBackgroundColor[ 2 ] + ',' + backgroundOpacity * parentOpacity + ')';
        var styleShape = ele.pstyle( 'text-background-shape' ).strValue;
        if( styleShape == 'roundrectangle' ){
          roundRect( context, bgX, bgY, bgW, bgH, 2 );
        } else {
          context.fillRect( bgX, bgY, bgW, bgH );
        }
        context.fillStyle = textFill;
      }

      if( textBorderWidth > 0 && borderOpacity > 0 ){
        var textStroke = context.strokeStyle;
        var textLineWidth = context.lineWidth;
        var textBorderColor = ele.pstyle( 'text-border-color' ).value;
        var textBorderStyle = ele.pstyle( 'text-border-style' ).value;

        context.strokeStyle = 'rgba(' + textBorderColor[ 0 ] + ',' + textBorderColor[ 1 ] + ',' + textBorderColor[ 2 ] + ',' + borderOpacity * parentOpacity + ')';
        context.lineWidth = textBorderWidth;

        if( context.setLineDash ){ // for very outofdate browsers
          switch( textBorderStyle ){
            case 'dotted':
              context.setLineDash( [ 1, 1 ] );
              break;
            case 'dashed':
              context.setLineDash( [ 4, 2 ] );
              break;
            case 'double':
              context.lineWidth = textBorderWidth / 4; // 50% reserved for white between the two borders
              context.setLineDash( [] );
              break;
            case 'solid':
              context.setLineDash( [] );
              break;
          }
        }

        context.strokeRect( bgX, bgY, bgW, bgH );

        if( textBorderStyle === 'double' ){
          var whiteWidth = textBorderWidth / 2;

          context.strokeRect( bgX + whiteWidth, bgY + whiteWidth, bgW - whiteWidth * 2, bgH - whiteWidth * 2 );
        }

        if( context.setLineDash ){ // for very outofdate browsers
          context.setLineDash( [] );
        }
        context.lineWidth = textLineWidth;
        context.strokeStyle = textStroke;
      }

    }

    var lineWidth = 2 * ele.pstyle( 'text-outline-width' ).pfValue; // *2 b/c the stroke is drawn centred on the middle

    if( lineWidth > 0 ){
      context.lineWidth = lineWidth;
    }

    if( ele.pstyle( 'text-wrap' ).value === 'wrap' ){
      var lines = util.getPrefixedProperty( rscratch, 'labelWrapCachedLines', prefix );
      var lineHeight = textH / lines.length;

      switch( valign ){
        case 'top':
          textY -= ( lines.length - 1 ) * lineHeight;
          break;
        case 'center':
        case 'bottom':
          textY -= ( lines.length - 1 ) * lineHeight;
          break;
      }

      for( var l = 0; l < lines.length; l++ ){
        if( lineWidth > 0 ){
          context.strokeText( lines[ l ], textX, textY );
        }

        context.fillText( lines[ l ], textX, textY );

        textY += lineHeight;
      }

    } else {
      if( lineWidth > 0 ){
        context.strokeText( text, textX, textY );
      }

      context.fillText( text, textX, textY );
    }

    if( theta !== 0 ){
      context.rotate( -theta );
      context.translate( -orgTextX, -orgTextY );
    }
  }
};

module.exports = CRp;
<commit_msg>Fix `source-text-rotation` and `target-text-rotation` not being used for source and target labels.  Previously, `text-rotation` was erroneously applied to the display of source and target labels, but the correct properties were used for bounds calculations.<commit_after>var util = require( '../../../util' );
var math = require( '../../../math' );

var CRp = {};

CRp.eleTextBiggerThanMin = function( ele, scale ){
  if( !scale ){
    var zoom = ele.cy().zoom();
    var pxRatio = this.getPixelRatio();
    var lvl = Math.ceil( math.log2( zoom * pxRatio ) ); // the effective texture level

    scale = Math.pow( 2, lvl );
  }

  var computedSize = ele.pstyle( 'font-size' ).pfValue * scale;
  var minSize = ele.pstyle( 'min-zoomed-font-size' ).pfValue;

  if( computedSize < minSize ){
    return false;
  }

  return true;
};

CRp.drawElementText = function( context, ele, force ){
  var r = this;

  if( force === undefined ){
    if( !r.eleTextBiggerThanMin( ele ) ){ return; }
  } else {
    if( !force ){ return; }
  }

  if( ele.isNode() ){
    var label = ele.pstyle( 'label' );

    if( !label || !label.value ){ return; }

    var textHalign = ele.pstyle( 'text-halign' ).strValue;
    var textValign = ele.pstyle( 'text-valign' ).strValue;

    switch( textHalign ){
      case 'left':
        context.textAlign = 'right';
        break;

      case 'right':
        context.textAlign = 'left';
        break;

      default: // e.g. center
        context.textAlign = 'center';
    }

    context.textBaseline = 'bottom';
  } else {
    var label = ele.pstyle( 'label' );
    var srcLabel = ele.pstyle( 'source-label' );
    var tgtLabel = ele.pstyle( 'target-label' );

    if(
      ( !label || !label.value )
      && ( !srcLabel || !srcLabel.value )
      && ( !tgtLabel || !tgtLabel.value )
    ){
      return;
    }

    context.textAlign = 'center';
    context.textBaseline = 'bottom';
  }

  r.drawText( context, ele );

  if( ele.isEdge() ){
    r.drawText( context, ele, 'source' );

    r.drawText( context, ele, 'target' );
  }
};

CRp.drawNodeText = CRp.drawEdgeText = CRp.drawElementText;

CRp.getFontCache = function( context ){
  var cache;

  this.fontCaches = this.fontCaches || [];

  for( var i = 0; i < this.fontCaches.length; i++ ){
    cache = this.fontCaches[ i ];

    if( cache.context === context ){
      return cache;
    }
  }

  cache = {
    context: context
  };
  this.fontCaches.push( cache );

  return cache;
};

// set up canvas context with font
// returns transformed text string
CRp.setupTextStyle = function( context, ele ){
  // Font style
  var parentOpacity = ele.effectiveOpacity();
  var labelStyle = ele.pstyle( 'font-style' ).strValue;
  var labelSize = ele.pstyle( 'font-size' ).pfValue + 'px';
  var labelFamily = ele.pstyle( 'font-family' ).strValue;
  var labelWeight = ele.pstyle( 'font-weight' ).strValue;
  var opacity = ele.pstyle( 'text-opacity' ).value * ele.pstyle( 'opacity' ).value * parentOpacity;
  var outlineOpacity = ele.pstyle( 'text-outline-opacity' ).value * opacity;
  var color = ele.pstyle( 'color' ).value;
  var outlineColor = ele.pstyle( 'text-outline-color' ).value;

  var fontCacheKey = ele._private.fontKey;
  var cache = this.getFontCache( context );

  if( cache.key !== fontCacheKey ){
    context.font = labelStyle + ' ' + labelWeight + ' ' + labelSize + ' ' + labelFamily;

    cache.key = fontCacheKey;
  }

  // Calculate text draw position based on text alignment

  // so text outlines aren't jagged
  context.lineJoin = 'round';

  this.fillStyle( context, color[ 0 ], color[ 1 ], color[ 2 ], opacity );

  this.strokeStyle( context, outlineColor[ 0 ], outlineColor[ 1 ], outlineColor[ 2 ], outlineOpacity );
};

function roundRect( ctx, x, y, width, height, radius ){
  var radius = radius || 5;
  ctx.beginPath();
  ctx.moveTo( x + radius, y );
  ctx.lineTo( x + width - radius, y );
  ctx.quadraticCurveTo( x + width, y, x + width, y + radius );
  ctx.lineTo( x + width, y + height - radius );
  ctx.quadraticCurveTo( x + width, y + height, x + width - radius, y + height );
  ctx.lineTo( x + radius, y + height );
  ctx.quadraticCurveTo( x, y + height, x, y + height - radius );
  ctx.lineTo( x, y + radius );
  ctx.quadraticCurveTo( x, y, x + radius, y );
  ctx.closePath();
  ctx.fill();
}

// Draw text
CRp.drawText = function( context, ele, prefix ){
  var _p = ele._private;
  var rscratch = _p.rscratch;
  var parentOpacity = ele.effectiveOpacity();
  if( parentOpacity === 0 || ele.pstyle( 'text-opacity' ).value === 0 ){
    return;
  }

  var textX = util.getPrefixedProperty( rscratch, 'labelX', prefix );
  var textY = util.getPrefixedProperty( rscratch, 'labelY', prefix );
  var text = this.getLabelText( ele, prefix );

  if( text != null && text !== '' && !isNaN( textX ) && !isNaN( textY ) ){
    this.setupTextStyle( context, ele );

    var pdash = prefix ? prefix + '-' : '';
    var textW = util.getPrefixedProperty( rscratch, 'labelWidth', prefix );
    var textH = util.getPrefixedProperty( rscratch, 'labelHeight', prefix );
    var textAngle = util.getPrefixedProperty( rscratch, 'labelAngle', prefix );
    var marginX = ele.pstyle( pdash + 'text-margin-x' ).pfValue;
    var marginY = ele.pstyle( pdash + 'text-margin-y' ).pfValue;

    var isEdge = ele.isEdge();
    var isNode = ele.isNode();

    var halign = ele.pstyle( 'text-halign' ).value;
    var valign = ele.pstyle( 'text-valign' ).value;

    if( isEdge ){
      halign = 'center';
      valign = 'center';
    }

    textX += marginX;
    textY += marginY;

    var rotation = ele.pstyle( pdash + 'text-rotation' );
    var theta;

    if( rotation.strValue === 'autorotate' ){
      theta = isEdge ? textAngle : 0;
    } else if( rotation.strValue === 'none' ){
      theta = 0;
    } else {
      theta = rotation.pfValue;
    }

    if( theta !== 0 ){
      var orgTextX = textX;
      var orgTextY = textY;

      context.translate( orgTextX, orgTextY );
      context.rotate( theta );

      textX = 0;
      textY = 0;
    }

    switch( valign ){
      case 'top':
        break;
      case 'center':
        textY += textH / 2;
        break;
      case 'bottom':
        textY += textH;
        break;
    }

    var backgroundOpacity = ele.pstyle( 'text-background-opacity' ).value;
    var borderOpacity = ele.pstyle( 'text-border-opacity' ).value;
    var textBorderWidth = ele.pstyle( 'text-border-width' ).pfValue;
    var backgroundPadding = ele.pstyle( 'text-background-padding' ).pfValue;

    if( backgroundOpacity > 0 || ( textBorderWidth > 0 && borderOpacity > 0 ) ){
      var bgX = textX - backgroundPadding;

      switch( halign ){
        case 'left':
          bgX -= textW;
          break;
        case 'center':
          bgX -= textW / 2;
          break;
        case 'right':
          break;
      }

      var bgY = textY - textH - backgroundPadding;
      var bgW = textW + 2*backgroundPadding;
      var bgH = textH + 2*backgroundPadding;

      if( backgroundOpacity > 0 ){
        var textFill = context.fillStyle;
        var textBackgroundColor = ele.pstyle( 'text-background-color' ).value;

        context.fillStyle = 'rgba(' + textBackgroundColor[ 0 ] + ',' + textBackgroundColor[ 1 ] + ',' + textBackgroundColor[ 2 ] + ',' + backgroundOpacity * parentOpacity + ')';
        var styleShape = ele.pstyle( 'text-background-shape' ).strValue;
        if( styleShape == 'roundrectangle' ){
          roundRect( context, bgX, bgY, bgW, bgH, 2 );
        } else {
          context.fillRect( bgX, bgY, bgW, bgH );
        }
        context.fillStyle = textFill;
      }

      if( textBorderWidth > 0 && borderOpacity > 0 ){
        var textStroke = context.strokeStyle;
        var textLineWidth = context.lineWidth;
        var textBorderColor = ele.pstyle( 'text-border-color' ).value;
        var textBorderStyle = ele.pstyle( 'text-border-style' ).value;

        context.strokeStyle = 'rgba(' + textBorderColor[ 0 ] + ',' + textBorderColor[ 1 ] + ',' + textBorderColor[ 2 ] + ',' + borderOpacity * parentOpacity + ')';
        context.lineWidth = textBorderWidth;

        if( context.setLineDash ){ // for very outofdate browsers
          switch( textBorderStyle ){
            case 'dotted':
              context.setLineDash( [ 1, 1 ] );
              break;
            case 'dashed':
              context.setLineDash( [ 4, 2 ] );
              break;
            case 'double':
              context.lineWidth = textBorderWidth / 4; // 50% reserved for white between the two borders
              context.setLineDash( [] );
              break;
            case 'solid':
              context.setLineDash( [] );
              break;
          }
        }

        context.strokeRect( bgX, bgY, bgW, bgH );

        if( textBorderStyle === 'double' ){
          var whiteWidth = textBorderWidth / 2;

          context.strokeRect( bgX + whiteWidth, bgY + whiteWidth, bgW - whiteWidth * 2, bgH - whiteWidth * 2 );
        }

        if( context.setLineDash ){ // for very outofdate browsers
          context.setLineDash( [] );
        }
        context.lineWidth = textLineWidth;
        context.strokeStyle = textStroke;
      }

    }

    var lineWidth = 2 * ele.pstyle( 'text-outline-width' ).pfValue; // *2 b/c the stroke is drawn centred on the middle

    if( lineWidth > 0 ){
      context.lineWidth = lineWidth;
    }

    if( ele.pstyle( 'text-wrap' ).value === 'wrap' ){
      var lines = util.getPrefixedProperty( rscratch, 'labelWrapCachedLines', prefix );
      var lineHeight = textH / lines.length;

      switch( valign ){
        case 'top':
          textY -= ( lines.length - 1 ) * lineHeight;
          break;
        case 'center':
        case 'bottom':
          textY -= ( lines.length - 1 ) * lineHeight;
          break;
      }

      for( var l = 0; l < lines.length; l++ ){
        if( lineWidth > 0 ){
          context.strokeText( lines[ l ], textX, textY );
        }

        context.fillText( lines[ l ], textX, textY );

        textY += lineHeight;
      }

    } else {
      if( lineWidth > 0 ){
        context.strokeText( text, textX, textY );
      }

      context.fillText( text, textX, textY );
    }

    if( theta !== 0 ){
      context.rotate( -theta );
      context.translate( -orgTextX, -orgTextY );
    }
  }
};

module.exports = CRp;
<|endoftext|>