<commit_before>/**
 * This file is part of Superdesk.
 *
 * Copyright 2013, 2014 Sourcefabric z.u. and contributors.
 *
 * For the full copyright and license information, please see the
 * AUTHORS and LICENSE files distributed with this source code, or
 * at https://www.sourcefabric.org/superdesk/license
 */
(function() {

'use strict';

var TEXT_TYPE = 3;

function EditorService() {

    this.clear = function() {
        this.elem = null;
        this.editor = null;
        this.readOnly = false;
    };

    function preventEditing(event) {
        event.preventDefault();
        return false;
    }

    this.disableEditorToolbar = function disableEditorToolbar() {
        this.editor.toolbar.classList.add('ng-hide');
    };

    this.enableEditorToolbar = function enableEditorToolbar() {
        this.editor.toolbar.classList.remove('ng-hide');
    };

    /**
     * Start a command for an active editor
     */
    this.startCommand = function() {
        this.readOnly = true;
        this.command = new FindReplaceCommand(this.elem);
        angular.element(this.elem).on('keydown', preventEditing);
        this.disableEditorToolbar();
    };

    /**
     * Stop active command
     */
    this.stopCommand = function() {
        this.command.finish();
        this.command = null;
        this.readOnly = false;
        angular.element(this.elem).off('keydown', preventEditing);
        this.enableEditorToolbar();
        this.triggerModelUpdate();
    };

    this.triggerModelUpdate = function() {
        _.defer(function(elem) {
            angular.element(elem).blur();
        }, this.elem);
    };

    this.clear(); // init
}

function FindReplaceCommand(rootNode) {
    var matches = 0, current, needle, replacements, html = angular.element(rootNode).html();

    /**
     * Find a given string within editor
     */
    this.find = function(_needle) {
        clearHighlights();
        needle = _needle;
        matches = 0;
        current = 0;
        replacements = {};
        if (needle) {
            find(rootNode);
        }

        return matches;
    };

    /**
     * Highlight next match
     */
    this.next = function() {
        clearHighlights();
        current = (current + 1) % matches;
        matches = 0;
        find(rootNode);
    };

    /**
     * Highlight previous match
     */
    this.prev = function() {
        clearHighlights();
        current = current === 0 ? matches - 1 : current - 1;
        matches = 0;
        find(rootNode);
    };

    /**
     * Replace current match with given string
     */
    this.replace = function(replaceWith) {
        if (current != null) {
            var oldMatches = matches;

            // do replacement
            clearHighlights();
            matches = 0;
            replacements[current] = replaceWith || '';
            find(rootNode, true);
            html = angular.element(rootNode).html();

            // highlight rest
            matches = 0;
            current = current % (oldMatches - 1);
            replacements = {};
            find(rootNode);
            return matches;
        }
    };

    /**
     * Replace all matches with given string
     */
    this.replaceAll = function(replaceWith) {
        for (var i = 0; i < matches; i++) {
            replacements[i] = replaceWith || '';
        }

        clearHighlights();
        matches = 0;
        find(rootNode, true);
        html = angular.element(rootNode).html();
    };

    /**
     * Remove any left hightlights - called on exit
     */
    this.finish = function() {
        clearHighlights();
    };

    function find(node, stopHighlight) {
        if (node.nodeType === TEXT_TYPE) {
            var color,
                selection = document.getSelection(),
                index = node.wholeText.indexOf(needle),
                offset = 0;
            while (index > -1) {
                color = getColor(current != null ? current === matches : matches === 0);
                offset = index + needle.length;

                var range = document.createRange();
                range.setStart(node, index);
                range.setEnd(node, index + needle.length);
                selection.removeAllRanges();
                selection.addRange(range);

                if (replacements[matches] != null) {
                    document.execCommand('insertText', false, replacements[matches]);
                } else if (!stopHighlight) {
                    var oldLength = node.wholeText.length;
                    document.execCommand('hiliteColor', false, color);
                    if (oldLength > node.wholeText.length) {
                        offset = 0; // hilite split node text so do lookup from 0
                    }
                }

                matches++; // do the count now so we can use it as 0-based index
                index = node.wholeText.indexOf(needle, offset);
            }

            selection.removeAllRanges();
        } else {
            angular.forEach(node.childNodes, function(node) {
                find(node, stopHighlight);
            });
        }
    }

    function getColor(isCurrent) {
        return isCurrent ? '#edd400' : '#d3d7cf';
    }

    function clearHighlights() {
        angular.element(rootNode).html(html);
    }
}

angular.module('superdesk.editor', [])

    .service('editor', EditorService)

    .directive('sdTextEditor', ['editor', function (editor) {

        var config = {
            buttons: ['bold', 'italic', 'underline', 'quote', 'anchor'],
            anchorInputPlaceholder: gettext('Paste or type a full link')
        };

        /**
         * Get number of lines for all p nodes before given node withing same parent.
         */
        function getLinesBeforeNode(p) {

            function getLineCount(text) {
                return text.split('\n').length;
            }

            var lines = 0;
            while (p) {
                if (p.childNodes.length && p.childNodes[0].nodeType === TEXT_TYPE) {
                    lines += getLineCount(p.childNodes[0].wholeText);
                } else if (p.childNodes.length) {
                    lines += 1; // empty paragraph
                }
                p = p.previousSibling;
            }

            return lines;
        }

        /**
         * Get line/column coordinates for given cursor position.
         */
        function getLineColumn() {
            var column, lines,
                selection = window.getSelection();
            if (selection.anchorNode.nodeType === TEXT_TYPE) {
                var text = selection.anchorNode.wholeText.substring(0, selection.anchorOffset);
                var node = selection.anchorNode;
                column = text.length + 1;
                while (node.nodeName !== 'P') {
                    if (node.previousSibling) {
                        column += node.previousSibling.wholeText ?
                            node.previousSibling.wholeText.length :
                            node.previousSibling.textContent.length;
                        node = node.previousSibling;
                    } else {
                        node = node.parentNode;
                    }
                }

                lines = 0 + getLinesBeforeNode(node);
            } else {
                lines = 0 + getLinesBeforeNode(selection.anchorNode);
                column = 1;
            }

            return {
                line: lines,
                column: column
            };
        }

        return {
            scope: {type: '='},
            require: 'ngModel',
            templateUrl: 'scripts/superdesk/editor/views/editor.html',
            link: function(scope, elem, attrs, ngModel) {

                var editorElem;

                function updateModel() {
                    if (editor.readOnly) {
                        return;
                    }

                    scope.$apply(function editorModelUpdate() {
                        ngModel.$setViewValue(editorElem.html());
                    });
                }

                ngModel.$render = function renderEditor() {
                    editorElem = elem.find(scope.type === 'preformatted' ?  '.editor-type-text' : '.editor-type-html');
                    editorElem.empty();
                    editorElem.html(ngModel.$viewValue || '

');

                    editor.elem = editorElem[0];
                    editor.editor = new window.MediumEditor(editor.elem, config);

                    editorElem.on('blur', updateModel);
                    editorElem.on('input', updateModel);

                    if (scope.type === 'preformatted') {
                        editorElem.on('keydown keyup click', function() {
                            scope.$apply(function() {
                                angular.extend(scope.cursor, getLineColumn());
                            });
                        });
                    }

                    scope.$on('$destroy', function() {
                        editorElem.off();
                        editor.clear();
                    });

                    scope.cursor = {};
                };
            }
        };
    }]);

})();
<commit_msg>fix(authoring): Fixed closing authoring when find/replace is open.<commit_after>/**
 * This file is part of Superdesk.
 *
 * Copyright 2013, 2014 Sourcefabric z.u. and contributors.
 *
 * For the full copyright and license information, please see the
 * AUTHORS and LICENSE files distributed with this source code, or
 * at https://www.sourcefabric.org/superdesk/license
 */
(function() {

'use strict';

var TEXT_TYPE = 3;

function EditorService() {

    this.clear = function() {
        this.elem = null;
        this.editor = null;
        this.readOnly = false;
    };

    function preventEditing(event) {
        event.preventDefault();
        return false;
    }

    this.disableEditorToolbar = function disableEditorToolbar() {
        this.editor.toolbar.classList.add('ng-hide');
    };

    this.enableEditorToolbar = function enableEditorToolbar() {
        if (this.editor) {
            this.editor.toolbar.classList.remove('ng-hide');
        }
    };

    /**
     * Start a command for an active editor
     */
    this.startCommand = function() {
        this.readOnly = true;
        this.command = new FindReplaceCommand(this.elem);
        angular.element(this.elem).on('keydown', preventEditing);
        this.disableEditorToolbar();
    };

    /**
     * Stop active command
     */
    this.stopCommand = function() {
        this.command.finish();
        this.command = null;
        this.readOnly = false;
        angular.element(this.elem).off('keydown', preventEditing);
        this.enableEditorToolbar();
        this.triggerModelUpdate();
    };

    this.triggerModelUpdate = function() {
        _.defer(function(elem) {
            angular.element(elem).blur();
        }, this.elem);
    };

    this.clear(); // init
}

function FindReplaceCommand(rootNode) {
    var matches = 0, current, needle, replacements, html = angular.element(rootNode).html();

    /**
     * Find a given string within editor
     */
    this.find = function(_needle) {
        clearHighlights();
        needle = _needle;
        matches = 0;
        current = 0;
        replacements = {};
        if (needle) {
            find(rootNode);
        }

        return matches;
    };

    /**
     * Highlight next match
     */
    this.next = function() {
        clearHighlights();
        current = (current + 1) % matches;
        matches = 0;
        find(rootNode);
    };

    /**
     * Highlight previous match
     */
    this.prev = function() {
        clearHighlights();
        current = current === 0 ? matches - 1 : current - 1;
        matches = 0;
        find(rootNode);
    };

    /**
     * Replace current match with given string
     */
    this.replace = function(replaceWith) {
        if (current != null) {
            var oldMatches = matches;

            // do replacement
            clearHighlights();
            matches = 0;
            replacements[current] = replaceWith || '';
            find(rootNode, true);
            html = angular.element(rootNode).html();

            // highlight rest
            matches = 0;
            current = current % (oldMatches - 1);
            replacements = {};
            find(rootNode);
            return matches;
        }
    };

    /**
     * Replace all matches with given string
     */
    this.replaceAll = function(replaceWith) {
        for (var i = 0; i < matches; i++) {
            replacements[i] = replaceWith || '';
        }

        clearHighlights();
        matches = 0;
        find(rootNode, true);
        html = angular.element(rootNode).html();
    };

    /**
     * Remove any left hightlights - called on exit
     */
    this.finish = function() {
        clearHighlights();
    };

    function find(node, stopHighlight) {
        if (node.nodeType === TEXT_TYPE) {
            var color,
                selection = document.getSelection(),
                index = node.wholeText.indexOf(needle),
                offset = 0;
            while (index > -1) {
                color = getColor(current != null ? current === matches : matches === 0);
                offset = index + needle.length;

                var range = document.createRange();
                range.setStart(node, index);
                range.setEnd(node, index + needle.length);
                selection.removeAllRanges();
                selection.addRange(range);

                if (replacements[matches] != null) {
                    document.execCommand('insertText', false, replacements[matches]);
                } else if (!stopHighlight) {
                    var oldLength = node.wholeText.length;
                    document.execCommand('hiliteColor', false, color);
                    if (oldLength > node.wholeText.length) {
                        offset = 0; // hilite split node text so do lookup from 0
                    }
                }

                matches++; // do the count now so we can use it as 0-based index
                index = node.wholeText.indexOf(needle, offset);
            }

            selection.removeAllRanges();
        } else {
            angular.forEach(node.childNodes, function(node) {
                find(node, stopHighlight);
            });
        }
    }

    function getColor(isCurrent) {
        return isCurrent ? '#edd400' : '#d3d7cf';
    }

    function clearHighlights() {
        angular.element(rootNode).html(html);
    }
}

angular.module('superdesk.editor', [])

    .service('editor', EditorService)

    .directive('sdTextEditor', ['editor', function (editor) {

        var config = {
            buttons: ['bold', 'italic', 'underline', 'quote', 'anchor'],
            anchorInputPlaceholder: gettext('Paste or type a full link')
        };

        /**
         * Get number of lines for all p nodes before given node withing same parent.
         */
        function getLinesBeforeNode(p) {

            function getLineCount(text) {
                return text.split('\n').length;
            }

            var lines = 0;
            while (p) {
                if (p.childNodes.length && p.childNodes[0].nodeType === TEXT_TYPE) {
                    lines += getLineCount(p.childNodes[0].wholeText);
                } else if (p.childNodes.length) {
                    lines += 1; // empty paragraph
                }
                p = p.previousSibling;
            }

            return lines;
        }

        /**
         * Get line/column coordinates for given cursor position.
         */
        function getLineColumn() {
            var column, lines,
                selection = window.getSelection();
            if (selection.anchorNode.nodeType === TEXT_TYPE) {
                var text = selection.anchorNode.wholeText.substring(0, selection.anchorOffset);
                var node = selection.anchorNode;
                column = text.length + 1;
                while (node.nodeName !== 'P') {
                    if (node.previousSibling) {
                        column += node.previousSibling.wholeText ?
                            node.previousSibling.wholeText.length :
                            node.previousSibling.textContent.length;
                        node = node.previousSibling;
                    } else {
                        node = node.parentNode;
                    }
                }

                lines = 0 + getLinesBeforeNode(node);
            } else {
                lines = 0 + getLinesBeforeNode(selection.anchorNode);
                column = 1;
            }

            return {
                line: lines,
                column: column
            };
        }

        return {
            scope: {type: '='},
            require: 'ngModel',
            templateUrl: 'scripts/superdesk/editor/views/editor.html',
            link: function(scope, elem, attrs, ngModel) {

                var editorElem;

                function updateModel() {
                    if (editor.readOnly) {
                        return;
                    }

                    scope.$apply(function editorModelUpdate() {
                        ngModel.$setViewValue(editorElem.html());
                    });
                }

                ngModel.$render = function renderEditor() {
                    editorElem = elem.find(scope.type === 'preformatted' ?  '.editor-type-text' : '.editor-type-html');
                    editorElem.empty();
                    editorElem.html(ngModel.$viewValue || '

');

                    editor.elem = editorElem[0];
                    editor.editor = new window.MediumEditor(editor.elem, config);

                    editorElem.on('blur', updateModel);
                    editorElem.on('input', updateModel);

                    if (scope.type === 'preformatted') {
                        editorElem.on('keydown keyup click', function() {
                            scope.$apply(function() {
                                angular.extend(scope.cursor, getLineColumn());
                            });
                        });
                    }

                    scope.$on('$destroy', function() {
                        editorElem.off();
                        editor.clear();
                    });

                    scope.cursor = {};
                };
            }
        };
    }]);

})();
<|endoftext|>


<commit_before>(function($){
  var el, widget, button, input;

  function getVisible() {
    return widget.find(".ui-multiselect-checkboxes input:visible");
  }

  function getChecked() {
    return el.multiselect("getChecked");
  }

  function getSelected() {
    return el.children(":selected");
  }

  function searchFor(term) {
    input.val(term).trigger("keyup");
  }

  function triggerClick() {
    this.click();
  }

  function searchTest( term, expected, message ) {
    message || (message = "searching for '#'");
    message = message.replace("#", term);
    searchFor(term);
    equals( getVisible().length, expected, message );
  }

  module("filter widget - multiple select", {
    setup: function() {
      el = $('<select multiple>' +
        '<option></option>' +
        '<option value="foo">testffoooo</option>' +
        '<option value="bar">testbbaarr</option>' +
        '<option value=" baz ">testbbaazz</option>' +
        '<option value="qux">testquxtest</option>' +
        '<option value="10">ten</option>' +
        '<option value="100">one hundred</option>' +
        '<option value="5">five</option>' +
        '<option>a test with word boundaries</option>' +
        '<option>special regex !^$()//-|{}/: characters</option>' +
        '</option>');

      el.appendTo(document.body);
      el.multiselect();
      el.multiselectfilter();
      el.multiselect("open");

      widget = el.multiselect("widget");
      input = widget.find(".ui-multiselect-filter input");
      button = el.next();
    },

    teardown: function() {
      el.multiselectfilter("destroy");
      el.multiselect("destroy");
      el.remove();
    }
  });

  test("defaults", function(){
    expect(1);
    ok( input.is(":visible"), "Filter input box is visible" );
  });

  test("filtering by node text", function(){
    searchTest( "bbaa", 2);
    searchTest( "bbaarr", 1);
    searchTest( "  bbaa  ", 2, "searching for '#' with whitespace");
    searchTest( " ", el.children().length, "searching for an empty string");
    searchTest( "test", 5);
    searchTest( "one hundred", 1);
    searchTest( "with wor", 1);
    searchTest( " with wor  ", 1);

    $.each("$ ^ / : // { } | -".split(" "), function( i, char ){
      searchTest( char, 1 );
    });
  });

  test("filtering by node value", function(){
    // searchTest( "100", 1);
    // searchTest( "baz", 1);
  });

  test("filtering & checking", function(){
    searchFor("ba");

    getVisible().each(triggerClick);
    equals(getChecked().length, 2, "Two checkboxes are selected");
    equals(getSelected().length, 2, "Two option tags are selected");

    getVisible().each(triggerClick);
    equals(getChecked().length, 0, "After clicking again, no checkboxes are selected");
    equals(getSelected().length, 0, "After clicking again, no tags are selected");
  });

  test("checkAll / uncheckAll", function(){
    searchFor("ba");

    el.multiselect("checkAll");
    equals(getChecked().length, 2, "checkAll: two checkboxes are selected");
    equals(getSelected().length, 2, "checkAll: two option tags are selected");

    el.multiselect("uncheckAll");
    equals(getChecked().length, 0, "uncheckAll: no checkboxes are selected");
    equals(getSelected().length, 0, "uncheckAll: no option tags are selected");
  });

  test("combination of filtering/methods/click events", function(){
    searchFor("ba");

    getVisible().first().each(triggerClick);
    equals(getChecked().length, 1, "selecting 1 of multiple results (checked)");
    equals(getSelected().length, 1, "selecting 1 of multiple results (selected)");

    searchFor(" ");
    equals(getChecked().length, 1, "clearing search, only 1 is still selected");
    el.multiselect("uncheckAll");
    equals(getChecked().length, 0, "uncheckAll, nothing is selected (checked)");
    equals(getSelected().length, 0, "uncheckedAll, nothing is selected (selected)");

    searchFor("one hundred")
    el.multiselect("checkAll");
    equals(getChecked().length, 1, "checkAll on one matching result (checked)");
    equals(getSelected().length, 1, "checkAll on one matching result (selected)");

    searchFor("foo");
    el.multiselect("checkAll");
    equals(getChecked().length, 2, "checkAll on one matching result (checked)");
    equals(getSelected().length, 2, "checkAll on one matching result (selected)");
  });
})(jQuery);
<commit_msg>adding getUnChecked() filter.js<commit_after>(function($){
  var el, widget, button, input;

  function getVisible() {
    return widget.find(".ui-multiselect-checkboxes input:visible");
  }

  function getChecked() {
    return el.multiselect("getChecked");
  }

  function getUnChecked() {
    return el.multiselect("getUnChecked");
  }

  function getSelected() {
    return el.children(":selected");
  }

  function searchFor(term) {
    input.val(term).trigger("keyup");
  }

  function triggerClick() {
    this.click();
  }

  function searchTest( term, expected, message ) {
    message || (message = "searching for '#'");
    message = message.replace("#", term);
    searchFor(term);
    equals( getVisible().length, expected, message );
  }

  module("filter widget - multiple select", {
    setup: function() {
      el = $('<select multiple>' +
        '<option></option>' +
        '<option value="foo">testffoooo</option>' +
        '<option value="bar">testbbaarr</option>' +
        '<option value=" baz ">testbbaazz</option>' +
        '<option value="qux">testquxtest</option>' +
        '<option value="10">ten</option>' +
        '<option value="100">one hundred</option>' +
        '<option value="5">five</option>' +
        '<option>a test with word boundaries</option>' +
        '<option>special regex !^$()//-|{}/: characters</option>' +
        '</option>');

      el.appendTo(document.body);
      el.multiselect();
      el.multiselectfilter();
      el.multiselect("open");

      widget = el.multiselect("widget");
      input = widget.find(".ui-multiselect-filter input");
      button = el.next();
    },

    teardown: function() {
      el.multiselectfilter("destroy");
      el.multiselect("destroy");
      el.remove();
    }
  });

  test("defaults", function(){
    expect(1);
    ok( input.is(":visible"), "Filter input box is visible" );
  });

  test("filtering by node text", function(){
    searchTest( "bbaa", 2);
    searchTest( "bbaarr", 1);
    searchTest( "  bbaa  ", 2, "searching for '#' with whitespace");
    searchTest( " ", el.children().length, "searching for an empty string");
    searchTest( "test", 5);
    searchTest( "one hundred", 1);
    searchTest( "with wor", 1);
    searchTest( " with wor  ", 1);

    $.each("$ ^ / : // { } | -".split(" "), function( i, char ){
      searchTest( char, 1 );
    });
  });

  test("filtering by node value", function(){
    // searchTest( "100", 1);
    // searchTest( "baz", 1);
  });

  test("filtering & checking", function(){
    searchFor("ba");

    getVisible().each(triggerClick);
    equals(getChecked().length, 2, "Two checkboxes are selected");
    equals(getSelected().length, 2, "Two option tags are selected");

    getVisible().each(triggerClick);
    equals(getChecked().length, 0, "After clicking again, no checkboxes are selected");
    equals(getSelected().length, 0, "After clicking again, no tags are selected");
  });

  test("checkAll / uncheckAll", function(){
    searchFor("ba");

    el.multiselect("checkAll");
    equals(getChecked().length, 2, "checkAll: two checkboxes are selected");
    equals(getSelected().length, 2, "checkAll: two option tags are selected");

    el.multiselect("uncheckAll");
    equals(getChecked().length, 0, "uncheckAll: no checkboxes are selected");
    equals(getSelected().length, 0, "uncheckAll: no option tags are selected");
  });

  test("combination of filtering/methods/click events", function(){
    searchFor("ba");

    getVisible().first().each(triggerClick);
    equals(getChecked().length, 1, "selecting 1 of multiple results (checked)");
    equals(getSelected().length, 1, "selecting 1 of multiple results (selected)");

    searchFor(" ");
    equals(getChecked().length, 1, "clearing search, only 1 is still selected");
    el.multiselect("uncheckAll");
    equals(getChecked().length, 0, "uncheckAll, nothing is selected (checked)");
    equals(getSelected().length, 0, "uncheckedAll, nothing is selected (selected)");

    searchFor("one hundred")
    el.multiselect("checkAll");
    equals(getChecked().length, 1, "checkAll on one matching result (checked)");
    equals(getSelected().length, 1, "checkAll on one matching result (selected)");

    searchFor("foo");
    el.multiselect("checkAll");
    equals(getChecked().length, 2, "checkAll on one matching result (checked)");
    equals(getSelected().length, 2, "checkAll on one matching result (selected)");
  });
})(jQuery);
<|endoftext|>


<commit_before>/**
 * Manage the blocks
 */
Blocks = function()
{
    var self = this;

    // View center & scale
    this.center = {};
    this.scale = 1.0;
    this.redrawTimeout = null;

    // Is the user dragging the view ?
    this.moving = null;

    // Is the system ready ?
    this.isReady = false;

    // Compact mode
    this.compactMode = false;

    // Context menu
    this.menu;

    // Mouse
    this.mouseX = 0;
    this.mouseY = 0;

    // Linking ?
    this.linking = null;

    // Selected items
    this.selectedLink = null;
    this.selectedSide = null;
    this.selectedBlock = null;

    // BLocks division
    this.div = null;

    // Context for drawingc
    this.context = null;

    // Blocks types
    this.blockTypes = [];

    // Instances
    this.blocks = [];

    // Edges
    this.edges = [];

    /**
     * Next block id
     */
    this.id = 1;

    /**
     * Runs the blocks editor
     */
    this.run = function(selector)
    {
        $(document).ready(function() {
            self.div = $(selector);

            if (!self.div.size()) {
                alert('blocks.js: Unable to find ' + selector);
            }

            // Inject the initial editor
            self.div.html(
                  '
'
		+ '

'
                + '

'
                + '<svg xmlns="http://www.w3.org/2000/svg" version="1.1"></svg>'
                + '

'
                + '
'
            );

            self.div.find('svg').attr('width',(self.div.width()));
            self.div.find('svg').attr('height',(self.div.height()));
            self.div.find('svg').width(self.div.width());
            self.div.find('svg').height(self.div.height());
            self.context = self.div.find('svg');

            // Setting up default viewer center
            self.center.x = self.div.width()/2;
            self.center.y = self.div.height()/2;

            // Run the menu
            self.menu = new BlocksMenu(self);

	    // Create the message handler
	    self.messages = new BlocksMessages(self.div.find('.messages'), self.div.width());

            // Listen for mouse position
            self.div[0].addEventListener('mousemove', function(evt) {
                self.mouseX = evt.pageX - self.div.offset().left;
                self.mouseY = evt.pageY - self.div.offset().top;
                self.move(evt);
            });

            $('html').mouseup(function(event) {
                if (event.which == 1) {
                    self.release();
                }
            });

            // Detect clicks on the canvas
            self.div.mousedown(function(evt) {
                if (self.canvasClicked()) {
                    evt.preventDefault();
                }
            });

            self.div.mousedown(function(event) {
                if (event.which == 2) {
                    self.moving = [self.mouseX, self.mouseY];
                }
            });

            self.div.mouseup(function(event) {
                if (event.which == 2) {
                    self.moving = null;
                }
            });

            // Initializing canvas
            self.context.svg();

            // Detecting key press
            $(document).keydown(function(e){
                if ($('input').is(':focus')) {
                    return;
                }

                // "del" will delete a selected link
                if (e.keyCode == 46) {
                    self.deleteEvent();
                }
            });

            // Binding the mouse wheel
            self.div.bind('mousewheel', function(event, delta, deltaX, deltaY) {
                var dX = self.mouseX - self.center.x;
                var dY = self.mouseY - self.center.y;
                var deltaScale = Math.pow(1.1, deltaY);
                self.center.x -= dX*(deltaScale-1);
                self.center.y -= dY*(deltaScale-1);
                self.scale *= deltaScale;
                self.redraw();
            });

	    self.postReady();
        });
    };

    /**
     * Tell the system is ready
     */
    this.postReady = function()
    {
	this.isReady = true;
	if (this.readyQueue != undefined) {
	    for (k in this.readyQueue) {
		this.readyQueue[k]();
	    }
	}
    };

    /**
     * Callback when ready
     */
    this.ready = function(callback)
    {
	if (this.isReady) {
	    callback();
	} else {
	    var queue = [];
	    if (this.readyQueue != undefined) {
		queue = this.readyQueue;
	    }
	    queue.push(callback);
	    this.readyQueue = queue;
	}
    };

    /**
     * Gets the mouse position
     */
    this.getPosition = function()
    {
        var position = {};
        position.x = (self.mouseX-self.center.x)/self.scale;
        position.y = (self.mouseY-self.center.y)/self.scale;

        return position;
    };

    /**
     * Adds a block
     */
    this.addBlock = function(name, x, y)
    {
        for (k in self.blockTypes) {
            var type = self.blockTypes[k];

            if (type.name == name) {
                var block = new Block(self, self.blockTypes[k], this.id);
                block.x = x;
                block.y = y;
                block.create(self.div.find('.blocks'));
                this.blocks.push(block);
                this.id++;
            }
        }
    };

    /**
     * Registers a new block type
     */
    this.register = function(type)
    {
        self.blockTypes.push(new BlockType(type));
    };

    /**
     * Begin to draw an edge
     */
    this.beginLink = function(block, io)
    {
        this.linking = [block, io];
    };

    /**
     * The mouse has moved
     */
    this.move = function()
    {
        if (self.selectedSide) {
            var distance = Math.sqrt(Math.pow(this.mouseX-this.selectedSide[1],2)+Math.pow(this.mouseY-this.selectedSide[2],2));
            if (distance > 15) {
                var edge = this.edges[this.selectedLink];
                if (this.selectedSide[0] == 2) {
                    this.linking = [edge.block1, edge.io1];
                } else {
                    this.linking = [edge.block2, edge.io2];
                }

                this.removeEdge(this.selectedLink);
                this.selectedSide = null;
                this.selectedLink = null;
                this.redraw();
            }
        }

        if (self.moving) {
            self.center.x += (self.mouseX-self.moving[0]);
            self.center.y += (self.mouseY-self.moving[1]);
            self.moving = [self.mouseX, self.mouseY];
            self.redraw();
        }

        if (self.linking) {
            self.redraw();
        }
    };

    /**
     * Clicks the canvas
     */
    this.canvasClicked = function()
    {
        var prevent = false;
        this.selectedBlock = null;
        this.selectedLink = null;
        this.selectedSide = null;

        for (k in this.blocks) {
            var block = this.blocks[k];
            if (block.hasFocus) {
                this.selectedBlock = k;
            }
        }

        if (!this.selectedBlock) {
            for (k in this.edges) {
                var collide = this.edges[k].collide(this.mouseX, this.mouseY);
                if (collide != false) {
                    if (collide < 0.2) {
                        this.selectedSide = [1, this.mouseX, this.mouseY];
                    } else if (collide > 0.8) {
                        this.selectedSide = [2, this.mouseX, this.mouseY];
                    }
                    this.selectedLink = k;
                    prevent = true;
                    break;
                }
            }
        }

        this.redraw();
        return prevent;
    };

    /**
     * Edge to remove
     */
    this.removeEdge = function(edge)
    {
        this.edges[edge].erase();
        arrayRemove(this.edges, edge);
    };

    /**
     * Returns an edge id
     */
    this.getEdgeId = function(edge)
    {
	for (k in this.edges) {
	    if (edge == this.edges[k]) {
		return k;
	    }
	}

	return false;
    };

    /**
     * Remove a block
     */
    this.removeBlock = function(key)
    {
        var block = this.blocks[key];

        var newEdges = [];
        for (k in self.edges) {
            var edge = self.edges[k];
            if (edge.block1 == block || edge.block2 == block) {
                edge.erase();
            } else {
                newEdges.push(edge);
            }
        }
        this.edges = newEdges;

        block.erase();
        arrayRemove(this.blocks, this.selectedBlock);

        this.redraw();
    };

    /**
     * Get a block id
     */
    this.getBlockId = function(block)
    {
        for (k in self.blocks) {
            if (self.blocks[k] == block) {
                return k;
            }
        }

        return null;
    };

    /**
     * Retreive a block by ID
     */
    this.getBlockById = function (blockId)
    {
	for (k in self.blocks) {
	    if (self.blocks[k].id == blockId) {
		return self.blocks[k];
	    }
	}

	return null;
    };

    /**
     * Delete the current link
     */
    this.deleteEvent = function()
    {
        // Remove a block and its edges
        if (this.selectedBlock != null) {
            this.removeBlock(this.selectedBlock);
            this.selectedBlock = null;
        }

        // Remove an edge
        if (this.selectedLink != null) {
            this.removeEdge(this.selectedLink);
            this.selectedLink = null;
            this.redraw();
        }
    };

    /**
     * Do the redraw
     */
    this.doRedraw = function()
    {
        // Set the position for blocks
        for (k in self.blocks) {
            self.blocks[k].redraw(self.selectedBlock == k);
        }

        // Redraw edges
        var svg = self.context.svg('get');
        svg.clear();

        for (k in self.edges) {
            self.edges[k].draw(svg, self.selectedLink == k);
        }

        if (self.linking) {
            var position = this.linking[0].linkPositionFor(this.linking[1]);

            svg.line(position.x, position.y, self.mouseX, self.mouseY, {
                stroke: 'rgba(0,0,0,0.4)',
                strokeWidth: 3*self.scale
            });
        }

        self.redrawTimeout = null;
    };

    /**
     *  Draw the edges
     */
    this.redraw = function()
    {
        if (!this.redrawTimeout) {
            this.redrawTimeout = setTimeout(function() { self.doRedraw(); }, 50);
        }
    };

    /**
     * Release the mouse
     */
    this.release = function()
    {
        if (self.linking) {
            self.tryEndLink();
            self.linking=null;
        }
        self.redraw();
    };

    /**
     * Tries to end a link
     */
    this.tryEndLink = function()
    {
        for (k in self.blocks) {
            var block = self.blocks[k];
            if (block.hasFocus && block.focusedIo) {
                self.endLink(block, block.focusedIo);
                break;
            }
        }
    };

    /**
     * End drawing an edge
     */
    this.endLink = function(block, io)
    {
        try {
            var edge = new Edge(this.linking[0], this.linking[1], block, io, self);

            for (k in self.edges) {
                var other = self.edges[k];
                if (other.same(edge)) {
                    throw 'This edge already exists';
                }
            }

            var fromTo = edge.fromTo();
            if (fromTo[1].allSuccessors().indexOf(fromTo[0].id) != -1) {
                throw 'You can not create a loop';
            }

            edge.create();
            this.edges.push(edge);
        } catch (error) {
            this.messages.show('Unable to create this edge :' + "\n" + error, {'class': 'error'});
        }
        this.linking = null;
        this.selectedBlock = null;
        this.redraw();
    };

    /**
     * Changing the compact mode
     */
    this.toggleCompact = function()
    {
        this.compactMode = !this.compactMode;
        for (k in this.blocks) {
            this.blocks[k].render();
        }
        this.redraw();
    };

    /**
     * Export the scene
     */
    this.exportData = function()
    {
	var blocks = [];
	var edges = [];

	for (k in this.blocks) {
	    blocks.push(this.blocks[k].exportData());
	}

	for (k in this.edges) {
	    edges.push(this.edges[k].exportData());
	}

	return {
	    edges: edges,
	    blocks: blocks
	};
    };

    /**
     * Loads the scene
     */
    this.load = function(scene)
    {
	self.ready(function() {
		var errors = [];
		self.id = 1;

		for (k in scene.blocks) {
		    try {
			var data = scene.blocks[k];
			var block = BlockImport(self, data);
			self.id = Math.max(self.id, block.id+1);
			block.create(self.div.find('.blocks'));
			self.blocks.push(block);
		    } catch (error) {
			errors.push('Block #'+k+ ':'+error);
		    }
		}

		for (k in scene.edges) {
		    try {
			var data = scene.edges[k];
			var edge = EdgeImport(self, data);
			edge.create();
			self.edges.push(edge);
		    } catch (error) {
			errors.push('Edge #'+k+' :'+error);
		    }
		}

		if (errors.length) {
		    var text = errors.length + " loading errors :
";
		    text += '
';
		    for (k in errors) {
			text += '
' + errors[k] + '
';
		    }
		    text += '
';
		    self.messages.show(text, {'class': 'error'});
		}

		self.redraw();
		self.perfectScale();
	});
    };

    /**
     * Go to the perfect scale
     */
    this.perfectScale = function()
    {
	var xMin = null, xMax = null;
	var yMin = null, yMax = null;

	for (k in this.blocks) {
	    var block = this.blocks[k];
	    if (xMin == null) {
		xMin = xMax = block.x;
		yMin = yMax = block.y;
	    } else {
		xMin = Math.min(xMin, block.x);
		xMax = Math.max(xMax, block.x);
		yMin = Math.min(yMin, block.y);
		yMax = Math.max(yMax, block.y);
	    }
	}
	xMin -= 15;
	yMin -= 15;
	xMax += 200;
	yMax += 150;
	var scaleA = this.div.width()/(xMax-xMin);
	var scaleB = this.div.height()/(yMax-yMin);
	var scale = Math.min(scaleA, scaleB);

	this.scale = scale;
	this.center.x = this.div.width()/2 - scale*(xMin+xMax)/2.0;
	this.center.y = this.div.height()/2 - scale*(yMin+yMax)/2.0;

	this.redraw();
    }
};

<commit_msg>Preventing default on mouse wheel<commit_after>/**
 * Manage the blocks
 */
Blocks = function()
{
    var self = this;

    // View center & scale
    this.center = {};
    this.scale = 1.0;
    this.redrawTimeout = null;

    // Is the user dragging the view ?
    this.moving = null;

    // Is the system ready ?
    this.isReady = false;

    // Compact mode
    this.compactMode = false;

    // Context menu
    this.menu;

    // Mouse
    this.mouseX = 0;
    this.mouseY = 0;

    // Linking ?
    this.linking = null;

    // Selected items
    this.selectedLink = null;
    this.selectedSide = null;
    this.selectedBlock = null;

    // BLocks division
    this.div = null;

    // Context for drawingc
    this.context = null;

    // Blocks types
    this.blockTypes = [];

    // Instances
    this.blocks = [];

    // Edges
    this.edges = [];

    /**
     * Next block id
     */
    this.id = 1;

    /**
     * Runs the blocks editor
     */
    this.run = function(selector)
    {
        $(document).ready(function() {
            self.div = $(selector);

            if (!self.div.size()) {
                alert('blocks.js: Unable to find ' + selector);
            }

            // Inject the initial editor
            self.div.html(
                  '
'
		+ '

'
                + '

'
                + '<svg xmlns="http://www.w3.org/2000/svg" version="1.1"></svg>'
                + '

'
                + '
'
            );

            self.div.find('svg').attr('width',(self.div.width()));
            self.div.find('svg').attr('height',(self.div.height()));
            self.div.find('svg').width(self.div.width());
            self.div.find('svg').height(self.div.height());
            self.context = self.div.find('svg');

            // Setting up default viewer center
            self.center.x = self.div.width()/2;
            self.center.y = self.div.height()/2;

            // Run the menu
            self.menu = new BlocksMenu(self);

	    // Create the message handler
	    self.messages = new BlocksMessages(self.div.find('.messages'), self.div.width());

            // Listen for mouse position
            self.div[0].addEventListener('mousemove', function(evt) {
                self.mouseX = evt.pageX - self.div.offset().left;
                self.mouseY = evt.pageY - self.div.offset().top;
                self.move(evt);
            });

            $('html').mouseup(function(event) {
                if (event.which == 1) {
                    self.release();
                }
            });

            // Detect clicks on the canvas
            self.div.mousedown(function(evt) {
                if (self.canvasClicked()) {
                    evt.preventDefault();
                }
            });

            self.div.mousedown(function(event) {
                if (event.which == 2) {
                    self.moving = [self.mouseX, self.mouseY];
                }
            });

            self.div.mouseup(function(event) {
                if (event.which == 2) {
                    self.moving = null;
                }
            });

            // Initializing canvas
            self.context.svg();

            // Detecting key press
            $(document).keydown(function(e){
                if ($('input').is(':focus')) {
                    return;
                }

                // "del" will delete a selected link
                if (e.keyCode == 46) {
                    self.deleteEvent();
                }
            });

            // Binding the mouse wheel
            self.div.bind('mousewheel', function(event, delta, deltaX, deltaY) {
                var dX = self.mouseX - self.center.x;
                var dY = self.mouseY - self.center.y;
                var deltaScale = Math.pow(1.1, deltaY);
                self.center.x -= dX*(deltaScale-1);
                self.center.y -= dY*(deltaScale-1);
                self.scale *= deltaScale;
                self.redraw();
                event.preventDefault();
            });

	    self.postReady();
        });
    };

    /**
     * Tell the system is ready
     */
    this.postReady = function()
    {
	this.isReady = true;
	if (this.readyQueue != undefined) {
	    for (k in this.readyQueue) {
		this.readyQueue[k]();
	    }
	}
    };

    /**
     * Callback when ready
     */
    this.ready = function(callback)
    {
	if (this.isReady) {
	    callback();
	} else {
	    var queue = [];
	    if (this.readyQueue != undefined) {
		queue = this.readyQueue;
	    }
	    queue.push(callback);
	    this.readyQueue = queue;
	}
    };

    /**
     * Gets the mouse position
     */
    this.getPosition = function()
    {
        var position = {};
        position.x = (self.mouseX-self.center.x)/self.scale;
        position.y = (self.mouseY-self.center.y)/self.scale;

        return position;
    };

    /**
     * Adds a block
     */
    this.addBlock = function(name, x, y)
    {
        for (k in self.blockTypes) {
            var type = self.blockTypes[k];

            if (type.name == name) {
                var block = new Block(self, self.blockTypes[k], this.id);
                block.x = x;
                block.y = y;
                block.create(self.div.find('.blocks'));
                this.blocks.push(block);
                this.id++;
            }
        }
    };

    /**
     * Registers a new block type
     */
    this.register = function(type)
    {
        self.blockTypes.push(new BlockType(type));
    };

    /**
     * Begin to draw an edge
     */
    this.beginLink = function(block, io)
    {
        this.linking = [block, io];
    };

    /**
     * The mouse has moved
     */
    this.move = function()
    {
        if (self.selectedSide) {
            var distance = Math.sqrt(Math.pow(this.mouseX-this.selectedSide[1],2)+Math.pow(this.mouseY-this.selectedSide[2],2));
            if (distance > 15) {
                var edge = this.edges[this.selectedLink];
                if (this.selectedSide[0] == 2) {
                    this.linking = [edge.block1, edge.io1];
                } else {
                    this.linking = [edge.block2, edge.io2];
                }

                this.removeEdge(this.selectedLink);
                this.selectedSide = null;
                this.selectedLink = null;
                this.redraw();
            }
        }

        if (self.moving) {
            self.center.x += (self.mouseX-self.moving[0]);
            self.center.y += (self.mouseY-self.moving[1]);
            self.moving = [self.mouseX, self.mouseY];
            self.redraw();
        }

        if (self.linking) {
            self.redraw();
        }
    };

    /**
     * Clicks the canvas
     */
    this.canvasClicked = function()
    {
        var prevent = false;
        this.selectedBlock = null;
        this.selectedLink = null;
        this.selectedSide = null;

        for (k in this.blocks) {
            var block = this.blocks[k];
            if (block.hasFocus) {
                this.selectedBlock = k;
            }
        }

        if (!this.selectedBlock) {
            for (k in this.edges) {
                var collide = this.edges[k].collide(this.mouseX, this.mouseY);
                if (collide != false) {
                    if (collide < 0.2) {
                        this.selectedSide = [1, this.mouseX, this.mouseY];
                    } else if (collide > 0.8) {
                        this.selectedSide = [2, this.mouseX, this.mouseY];
                    }
                    this.selectedLink = k;
                    prevent = true;
                    break;
                }
            }
        }

        this.redraw();
        return prevent;
    };

    /**
     * Edge to remove
     */
    this.removeEdge = function(edge)
    {
        this.edges[edge].erase();
        arrayRemove(this.edges, edge);
    };

    /**
     * Returns an edge id
     */
    this.getEdgeId = function(edge)
    {
	for (k in this.edges) {
	    if (edge == this.edges[k]) {
		return k;
	    }
	}

	return false;
    };

    /**
     * Remove a block
     */
    this.removeBlock = function(key)
    {
        var block = this.blocks[key];

        var newEdges = [];
        for (k in self.edges) {
            var edge = self.edges[k];
            if (edge.block1 == block || edge.block2 == block) {
                edge.erase();
            } else {
                newEdges.push(edge);
            }
        }
        this.edges = newEdges;

        block.erase();
        arrayRemove(this.blocks, this.selectedBlock);

        this.redraw();
    };

    /**
     * Get a block id
     */
    this.getBlockId = function(block)
    {
        for (k in self.blocks) {
            if (self.blocks[k] == block) {
                return k;
            }
        }

        return null;
    };

    /**
     * Retreive a block by ID
     */
    this.getBlockById = function (blockId)
    {
	for (k in self.blocks) {
	    if (self.blocks[k].id == blockId) {
		return self.blocks[k];
	    }
	}

	return null;
    };

    /**
     * Delete the current link
     */
    this.deleteEvent = function()
    {
        // Remove a block and its edges
        if (this.selectedBlock != null) {
            this.removeBlock(this.selectedBlock);
            this.selectedBlock = null;
        }

        // Remove an edge
        if (this.selectedLink != null) {
            this.removeEdge(this.selectedLink);
            this.selectedLink = null;
            this.redraw();
        }
    };

    /**
     * Do the redraw
     */
    this.doRedraw = function()
    {
        // Set the position for blocks
        for (k in self.blocks) {
            self.blocks[k].redraw(self.selectedBlock == k);
        }

        // Redraw edges
        var svg = self.context.svg('get');
        svg.clear();

        for (k in self.edges) {
            self.edges[k].draw(svg, self.selectedLink == k);
        }

        if (self.linking) {
            var position = this.linking[0].linkPositionFor(this.linking[1]);

            svg.line(position.x, position.y, self.mouseX, self.mouseY, {
                stroke: 'rgba(0,0,0,0.4)',
                strokeWidth: 3*self.scale
            });
        }

        self.redrawTimeout = null;
    };

    /**
     *  Draw the edges
     */
    this.redraw = function()
    {
        if (!this.redrawTimeout) {
            this.redrawTimeout = setTimeout(function() { self.doRedraw(); }, 50);
        }
    };

    /**
     * Release the mouse
     */
    this.release = function()
    {
        if (self.linking) {
            self.tryEndLink();
            self.linking=null;
        }
        self.redraw();
    };

    /**
     * Tries to end a link
     */
    this.tryEndLink = function()
    {
        for (k in self.blocks) {
            var block = self.blocks[k];
            if (block.hasFocus && block.focusedIo) {
                self.endLink(block, block.focusedIo);
                break;
            }
        }
    };

    /**
     * End drawing an edge
     */
    this.endLink = function(block, io)
    {
        try {
            var edge = new Edge(this.linking[0], this.linking[1], block, io, self);

            for (k in self.edges) {
                var other = self.edges[k];
                if (other.same(edge)) {
                    throw 'This edge already exists';
                }
            }

            var fromTo = edge.fromTo();
            if (fromTo[1].allSuccessors().indexOf(fromTo[0].id) != -1) {
                throw 'You can not create a loop';
            }

            edge.create();
            this.edges.push(edge);
        } catch (error) {
            this.messages.show('Unable to create this edge :' + "\n" + error, {'class': 'error'});
        }
        this.linking = null;
        this.selectedBlock = null;
        this.redraw();
    };

    /**
     * Changing the compact mode
     */
    this.toggleCompact = function()
    {
        this.compactMode = !this.compactMode;
        for (k in this.blocks) {
            this.blocks[k].render();
        }
        this.redraw();
    };

    /**
     * Export the scene
     */
    this.exportData = function()
    {
	var blocks = [];
	var edges = [];

	for (k in this.blocks) {
	    blocks.push(this.blocks[k].exportData());
	}

	for (k in this.edges) {
	    edges.push(this.edges[k].exportData());
	}

	return {
	    edges: edges,
	    blocks: blocks
	};
    };

    /**
     * Loads the scene
     */
    this.load = function(scene)
    {
	self.ready(function() {
		var errors = [];
		self.id = 1;

		for (k in scene.blocks) {
		    try {
			var data = scene.blocks[k];
			var block = BlockImport(self, data);
			self.id = Math.max(self.id, block.id+1);
			block.create(self.div.find('.blocks'));
			self.blocks.push(block);
		    } catch (error) {
			errors.push('Block #'+k+ ':'+error);
		    }
		}

		for (k in scene.edges) {
		    try {
			var data = scene.edges[k];
			var edge = EdgeImport(self, data);
			edge.create();
			self.edges.push(edge);
		    } catch (error) {
			errors.push('Edge #'+k+' :'+error);
		    }
		}

		if (errors.length) {
		    var text = errors.length + " loading errors :
";
		    text += '
';
		    for (k in errors) {
			text += '
' + errors[k] + '
';
		    }
		    text += '
';
		    self.messages.show(text, {'class': 'error'});
		}

		self.redraw();
		self.perfectScale();
	});
    };

    /**
     * Go to the perfect scale
     */
    this.perfectScale = function()
    {
	var xMin = null, xMax = null;
	var yMin = null, yMax = null;

	for (k in this.blocks) {
	    var block = this.blocks[k];
	    if (xMin == null) {
		xMin = xMax = block.x;
		yMin = yMax = block.y;
	    } else {
		xMin = Math.min(xMin, block.x);
		xMax = Math.max(xMax, block.x);
		yMin = Math.min(yMin, block.y);
		yMax = Math.max(yMax, block.y);
	    }
	}
	xMin -= 15;
	yMin -= 15;
	xMax += 200;
	yMax += 150;
	var scaleA = this.div.width()/(xMax-xMin);
	var scaleB = this.div.height()/(yMax-yMin);
	var scale = Math.min(scaleA, scaleB);

	this.scale = scale;
	this.center.x = this.div.width()/2 - scale*(xMin+xMax)/2.0;
	this.center.y = this.div.height()/2 - scale*(yMin+yMax)/2.0;

	this.redraw();
    }
};

<|endoftext|>


<commit_before>import React from "react";
import Flex from "./flex";
import { titleColors, titleBarHeight } from "../../util/globals";
import { titleFont, darkGrey, medGrey, lightGrey, brandColor } from "../../globalStyles";
import Radium from "radium";
import Title from "./title";
import { Link } from "react-router-dom";

/*
This titlebar is not great, mostly becuase I'm no expert at flexbox.
You have free reign to make this titlebar great again.
*/
@Radium
class TitleBar extends React.Component {
  constructor(props) {
    super(props);
  }
  static propTypes = {
    dataName: React.PropTypes.string
  }
  getStyles() {
    return {
      title: {
        fontFamily: titleFont,
        fontSize: 48,
        lineHeight: "28px",
        marginTop: 0,
        marginBottom: 2,
        fontWeight: 500,
        color: medGrey,
        padding: "8px"
      },
      main: {
        height: titleBarHeight,
        justifyContent: "space-between",
        backgroundColor: "#eaebeb",
        marginBottom: 5,
        boxShadow: "0px -1px 1px 1px rgba(215,215,215,0.85) inset" // from card
      },
      link: {
        alignSelf: "center",
        padding: "8px",
        color: brandColor,
        textDecoration: "none",
        cursor: "pointer"
      },
      alerts: {
        textAlign: "center",
        verticalAlign: "middle",
        width: 70,
        color: brandColor
      },
      dataName: {
        textAlign: "center",
        verticalAlign: "text-bottom",
        color: darkGrey,
        fontSize: 18
      }
    };
  }
  render() {
    const styles = this.getStyles();
    const dataName = this.props.dataName ?

{this.props.dataName}
 : null;
    return (

        <Flex style={styles.main}>

          <Link style={styles.link} to="/">
            <Title style={styles.title}/>
          </Link>
          {dataName}

          <Link style={styles.link} to="/about">About</Link>
          <Link style={styles.link} to="/methods">Methods</Link>
          <Link style={styles.link} to="/help">Help</Link>

        </Flex>

    );
  }
}

export default TitleBar;
<commit_msg>titlebar displays current page<commit_after>import React from "react";
import Flex from "./flex";
import { titleColors, titleBarHeight } from "../../util/globals";
import { titleFont, darkGrey, medGrey, lightGrey, brandColor } from "../../globalStyles";
import Radium from "radium";
import Title from "./title";
import { Link } from "react-router-dom";

/*
This titlebar is not great, mostly becuase I'm no expert at flexbox.
You have free reign to make this titlebar great again.
*/
@Radium
class TitleBar extends React.Component {
  constructor(props) {
    super(props);
  }
  // static propTypes = {
  //   dataName: React.PropTypes.string
  // }
  static contextTypes = {
    router: React.PropTypes.object.isRequired
  }
  getStyles() {
    return {
      title: {
        fontFamily: titleFont,
        fontSize: 48,
        lineHeight: "28px",
        marginTop: 0,
        marginBottom: 2,
        fontWeight: 500,
        color: medGrey,
        padding: "8px"
      },
      main: {
        height: titleBarHeight,
        justifyContent: "space-between",
        backgroundColor: "#eaebeb",
        marginBottom: 5,
        boxShadow: "0px -1px 1px 1px rgba(215,215,215,0.85) inset" // from card
      },
      link: {
        alignSelf: "center",
        padding: "8px",
        color: brandColor,
        textDecoration: "none",
        cursor: "pointer"
      },
      alerts: {
        textAlign: "center",
        verticalAlign: "middle",
        width: 70,
        color: brandColor
      },
      dataName: {
        letterSpacing: "3px",
        color: darkGrey,
        fontSize: 24,
        fontWeight: 400,
        marginBottom: -7
      }
    };
  }
  render() {
    const styles = this.getStyles();
    // const dataName = this.props.dataName ?
    //
{this.props.dataName}
 : null;
    let dataName = this.context.router.location.pathname;
    if (dataName.length === 1) {dataName = "";}
    return (

        <Flex style={styles.main}>

          <Link style={styles.link} to="/">
            <Title style={styles.title}/>
          </Link>
          {/*{dataName}*/}

            {dataName}

          <Link style={styles.link} to="/about">About</Link>
          <Link style={styles.link} to="/methods">Methods</Link>
          <Link style={styles.link} to="/help">Help</Link>

        </Flex>

    );
  }
}

export default TitleBar;
<|endoftext|>


<commit_before>import { bindable, LogManager } from 'aurelia-framework';

const logger = LogManager.getLogger('HueLight');

export class HueLight {
  @bindable light;

  bind() {
    logger.info('Binding light', this.light);

    const rgb = this.light.state.rgb;
    this.lightStyle = {
      'background-color': `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`
    };
  }
}
<commit_msg>(WIP) Trying to render color opacity<commit_after>import { bindable, LogManager } from 'aurelia-framework';

const logger = LogManager.getLogger('HueLight');

export class HueLight {
  @bindable light;

  bind() {
    logger.info('Binding light', this.light);

    const state = this.light.state;
    const rgb = state.rgb;
    const bri = (state.bri / 255).toFixed(1);

    logger.info(`rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${bri})`);
    this.lightStyle = {
      'background-color': `rgba(${rgb[0]}, ${rgb[1]}, ${rgb[2]}, ${bri})`
    };
  }
}
<|endoftext|>


<commit_before>import { LitElement, html } from '@polymer/lit-element/lit-element.js'
import { repeat } from 'lit-html/directives/repeat.js'
import { shared } from '../../styles/shared.js'

/*
 * Show keyframes in a grid
 */
class KeyframeGrid extends LitElement {
  static get properties() {
    return { keyframes: { type: Object } }
  }

  _toArray(object) {
    const array = []

    for (const step in object) {
      array.push({
        step: parseFloat(step),
        value: object[step]
      })
    }

    array.sort((a, b) => a.step - b.step)

    return array
  }

  render() {
    const { keyframes } = this

    return html`
      ${shared}

        ${repeat(this._toArray(keyframes), keyframe => html`

${keyframe.step}: ${JSON.stringify(keyframe.value)}

        `)}

    `
  }

}

customElements.define('keyframe-grid', KeyframeGrid)
<commit_msg>fix(keyframe-grid): Make all keyframes visible via scroll<commit_after>import { LitElement, html } from '@polymer/lit-element/lit-element.js'
import { repeat } from 'lit-html/directives/repeat.js'
import { shared } from '../../styles/shared.js'

/*
 * Show keyframes in a grid
 */
class KeyframeGrid extends LitElement {
  static get properties() {
    return { keyframes: { type: Object } }
  }

  _toArray(object) {
    const array = []

    for (const step in object) {
      array.push({
        step: parseFloat(step),
        value: object[step]
      })
    }

    array.sort((a, b) => a.step - b.step)

    return array
  }

  render() {
    const { keyframes } = this

    return html`
      ${shared}

        ${repeat(this._toArray(keyframes), keyframe => html`

${keyframe.step}: ${JSON.stringify(keyframe.value, null, '\t')}

        `)}

    `
  }

}

customElements.define('keyframe-grid', KeyframeGrid)
<|endoftext|>


<commit_before>(function() {

var checkVersion = Dagaz.Model.checkVersion;

Dagaz.Model.checkVersion = function(design, name, value) {
  if (name != "walhall-extension") {
      checkVersion(design, name, value);
  }
}

Dagaz.Model.checkGoals = function(design, board, player) {
  var all = 0;
  var goal = 0;
  _.each(design.allPositions(), function(pos) {
      var piece = board.getPiece(pos);
      if ((piece !== null) && (piece.player == 2)) {
          if (piece.type == 2) {
              goal++;
          }
          all++;
      }
  });
  if (goal >= 4) {
      if (player == 2) {
          return 1;
      } else {
          return -1;
      }
  }
  if (all < 4) {
      if (player == 1) {
          return 1;
      } else {
          return -1;
      }
  }
  return 0;
}

var CheckInvariants = Dagaz.Model.CheckInvariants;

Dagaz.Model.CheckInvariants = function(board) {
  var design = Dagaz.Model.design;
  _.chain(board.moves)
   .filter(function(move) {
        if (move.actions.length != 1) return false;
        return (move.actions[0][0] !== null) && (move.actions[0][1] !== null);
    })
   .each(function(move) {
        var from  = move.actions[0][0][0];
        var to    = move.actions[0][1][0];
        var dir   = design.findDirection(from, to);
        var piece = board.getPiece(from);
        if ((dir !== null) && (piece !== null) && (piece.type <= 2)) {
             var pos = design.navigate(0, from, dir);
             while (pos !== null) {
                 var p = board.getPiece(pos);
                 if ((p === null) || (p.player == piece.player)) break;
                 move.capturePiece(pos);
                 pos = design.navigate(0, pos, dir);
             }
             pos = design.navigate(board.player, to, dir);
             while (pos !== null) {
                 var p = board.getPiece(pos);
                 if ((p === null) || (p.player == piece.player)) break;
                 move.capturePiece(pos);
                 pos = design.navigate(board.player, pos, dir);
             }
        }
    });
  CheckInvariants(board);
}

})();
<commit_msg>Valkyrie's shields<commit_after>(function() {

var checkVersion = Dagaz.Model.checkVersion;

Dagaz.Model.checkVersion = function(design, name, value) {
  if (name != "walhall-extension") {
      checkVersion(design, name, value);
  }
}

Dagaz.Model.checkGoals = function(design, board, player) {
  var all = 0;
  var goal = 0;
  _.each(design.allPositions(), function(pos) {
      var piece = board.getPiece(pos);
      if ((piece !== null) && (piece.player == 2)) {
          if (piece.type == 2) {
              goal++;
          }
          all++;
      }
  });
  if (goal >= 4) {
      if (player == 2) {
          return 1;
      } else {
          return -1;
      }
  }
  if (all < 4) {
      if (player == 1) {
          return 1;
      } else {
          return -1;
      }
  }
  return 0;
}

var isDefendedDir = function(design, board, pos, dir, type) {
  var pos = design.navigate(board.player, pos, dir);
  if (pos === null) return false;
  var piece = board.getPiece(pos);
  if (piece === null) return false;
  return piece.type == type;
}

var isDefended = function(design, board, pos) {
  return isDefendedDir(design, board, pos, design.getDirection("n"), design.getPieceType("ValkyrieA")) || isDefendedDir(design, board, pos, design.getDirection("nw"), design.getPieceType("ValkyrieR")) ||
         isDefendedDir(design, board, pos, design.getDirection("s"), design.getPieceType("ValkyrieA")) || isDefendedDir(design, board, pos, design.getDirection("se"), design.getPieceType("ValkyrieR")) ||
         isDefendedDir(design, board, pos, design.getDirection("w"), design.getPieceType("ValkyrieA")) || isDefendedDir(design, board, pos, design.getDirection("sw"), design.getPieceType("ValkyrieR")) ||
         isDefendedDir(design, board, pos, design.getDirection("e"), design.getPieceType("ValkyrieA")) || isDefendedDir(design, board, pos, design.getDirection("ne"), design.getPieceType("ValkyrieR"));
}

var CheckInvariants = Dagaz.Model.CheckInvariants;

Dagaz.Model.CheckInvariants = function(board) {
  var design = Dagaz.Model.design;
  _.chain(board.moves)
   .filter(function(move) {
        if (move.actions.length != 1) return false;
        return (move.actions[0][0] !== null) && (move.actions[0][1] !== null);
    })
   .each(function(move) {
        var from  = move.actions[0][0][0];
        var to    = move.actions[0][1][0];
        var dir   = design.findDirection(from, to);
        var piece = board.getPiece(from);
        if ((dir !== null) && (piece !== null) && (piece.type <= 2)) {
             var pos = design.navigate(0, from, dir);
             while (pos !== null) {
                 if (isDefended(design, board, pos)) break;
                 var p = board.getPiece(pos);
                 if ((p === null) || (p.player == piece.player)) break;
                 move.capturePiece(pos);
                 pos = design.navigate(0, pos, dir);
             }
             pos = design.navigate(board.player, to, dir);
             while (pos !== null) {
                 if (isDefended(design, board, pos)) break;
                 var p = board.getPiece(pos);
                 if ((p === null) || (p.player == piece.player)) break;
                 move.capturePiece(pos);
                 pos = design.navigate(board.player, pos, dir);
             }
        }
    });
  CheckInvariants(board);
}

})();
<|endoftext|>


<commit_before>'use strict';

const Feplet = require('feplet');
const fs = require('fs-extra');

const objectFactory = require('./object-factory');

module.exports = class {
  #patternlab;

  constructor(patternlab) {
    this.#patternlab = patternlab;

    this.config = patternlab.config;
    this.ingredients = patternlab.ingredients;
    this.isViewallValid = false;
    this.public = patternlab.config.paths.public;
    this.source = patternlab.config.paths.source;
    this.utils = patternlab.utils;
  }

  /* GETTERS for patternlab instance props in case they are undefined at instantiation. */

  get patternBuilder() {
    return this.#patternlab.patternBuilder;
  }

  get viewallBuilder() {
    return this.#patternlab.viewallBuilder;
  }

  /* METHODS */

  processAllPatterns() {
    const dateNow = Date.now();

    let patternsToExport;

    if (Array.isArray(this.config.patternExportPatternPartials) && this.config.patternExportPatternPartials.length) {
      patternsToExport = this.config.patternExportPatternPartials;
    }

    this.viewallBuilder.preParseViewallMarkup();
    this.viewallBuilder.processViewallData();

    this.isViewallValid = this.viewallBuilder.isViewallValid;

    // Need to process the first pattern in this.ingredients.patternTypes array in order to build viewall output.
    // Need to do this before the nested for loop.
    let isFirstPatternSubType;
    let firstPattern;

    if (this.ingredients.patternTypes.length && this.isViewallValid) {
      if (
        this.ingredients.patternTypes[0].patternTypeItems.length &&
        this.ingredients.patternTypes[0].patternTypeItems[0].patternName !== 'View All'
      ) {
        isFirstPatternSubType = false;
        firstPattern = this.ingredients.patternTypes[0].patternTypeItems[0].pattern;

        this.patternBuilder.processPattern(firstPattern);
      }
      else if (
        this.ingredients.patternTypes[0].patternSubTypes.length &&
        this.ingredients.patternTypes[0].patternSubTypes[0].patternSubTypeItems.length
      ) {
        isFirstPatternSubType = true;
        firstPattern = this.ingredients.patternTypes[0].patternSubTypes[0].patternSubTypeItems[0].pattern;

        this.patternBuilder.processPattern(firstPattern);
      }

      this.viewallBuilder.viewallPageHead = firstPattern.header +
        Feplet.render(this.viewallBuilder.viewallTemplateHead, this.ingredients.data);

      this.ingredients.viewallPatterns.viewall = new objectFactory.PatternViewall(
        // Naming the HTML file viewall.html instead of index.html to allow naming a Type "viewall" however unlikely.
        `${this.public.patterns}/viewall/viewall.html`,
        this.viewallBuilder.viewallPageHead
      );
    }

    // Omit scrape directory from viewalls.
    const scrapeTypeName = this.source.scrape.replace(`${this.source.patterns}/`, '').replace(/^\d*-/, '');

    // Process patterns and viewall in the same nested loop.
    // This way, memory can be freed for both at the end of each loop.
    /* 0 FOR-LOOP LEVELS IN. */
    for (let in0 = 0, le0 = this.ingredients.patternTypes.length; in0 < le0; in0++) {
      const patternType = this.ingredients.patternTypes[in0];

      if (this.isViewallValid && patternType.patternTypeLC !== scrapeTypeName) {
        this.ingredients.viewallPatterns[patternType.flatPatternPath] = new objectFactory.PatternViewall(
          `${this.public.patterns}/${patternType.flatPatternPath}/index.html`,
          this.viewallBuilder.viewallPageHead
        );
        this.viewallBuilder.buildViewallTypeHead(patternType);
      }

      // Iterate through this type's items.
      /* 1 FOR-LOOP LEVELS IN. */
      for (let in1 = 0, le1 = patternType.patternTypeItems.length; in1 < le1; in1++) {
        const patternTypeItem = patternType.patternTypeItems[in1];

        if (patternTypeItem.patternName === 'View All') {
          continue;
        }

        const pattern = patternTypeItem.pattern;

        // Process pattern.
        // Always process Type if 1st pattern is subType.
        // Otherwise, skip if both in0 === 0 and in1 === 0.
        if (isFirstPatternSubType || in0 > 0 || in1 > 0) {
          this.patternBuilder.processPattern(pattern);
        }

        // Write pattern.
        if (!pattern.isHidden) {
          this.patternBuilder.writePattern(pattern, dateNow);
        }

        // Export pattern.
        if (patternsToExport && patternsToExport.indexOf(pattern.patternPartial) > -1) {
          const patternPartialCode = this.utils.beautifyTemplate(pattern.templateExtended);

          fs.outputFileSync(
            `${this.config.patternExportDirectory}/${pattern.patternPartial}.html`,
            patternPartialCode
          );
        }

        // Build viewall body.
        if (this.isViewallValid) {
          if (pattern.isHidden) {
            // If this pattern is hidden, mark for deletion from nav.
            patternType.patternTypeItems[in1] = null;
          }
          else if (patternType.patternTypeLC !== scrapeTypeName) {
            this.viewallBuilder.buildViewallTypeBody(patternTypeItem, patternType);
          }
        }

        this.patternBuilder.freePattern(pattern);
      }

      /* 1 FOR-LOOP LEVELS IN. */
      for (let in1 = 0, le1 = patternType.patternSubTypes.length; in1 < le1; in1++) {
        const patternSubType = patternType.patternSubTypes[in1];

        // Build viewall head for this subType.
        if (this.isViewallValid) {
          this.ingredients.viewallPatterns[patternSubType.flatPatternPath] = new objectFactory.PatternViewall(
            `${this.public.patterns}/${patternSubType.flatPatternPath}/index.html`,
            this.viewallBuilder.viewallPageHead
          );
          this.viewallBuilder.buildViewallSubTypeHead(patternSubType, patternType);
        }

        // Iterate through this subType's items.
        /* 2 FOR-LOOP LEVELS IN. */
        for (let in2 = 0, le2 = patternSubType.patternSubTypeItems.length; in2 < le2; in2++) {
          const patternSubTypeItem = patternSubType.patternSubTypeItems[in2];

          if (patternSubTypeItem.patternName === 'View All') {
            continue;
          }

          const pattern = patternSubTypeItem.pattern;

          // Process pattern.
          // Always process subType if 1st pattern is not subType.
          // Otherwise, skip if in0 === 0, in1 === 0, and in2 === 0.
          if (!isFirstPatternSubType || in0 > 0 || in1 > 0 || in2 > 0) {
            this.patternBuilder.processPattern(pattern);
          }

          // Write pattern.
          if (!pattern.isHidden) {
            this.patternBuilder.writePattern(pattern, dateNow);
          }

          // Export pattern.
          if (patternsToExport && patternsToExport.indexOf(pattern.patternPartial) > -1) {
            const patternPartialCode = this.utils.beautifyTemplate(pattern.templateExtended);

            fs.outputFileSync(
              `${this.config.patternExportDirectory}/${pattern.patternPartial}.html`,
              patternPartialCode
            );
          }

          // Build viewall body.
          if (this.isViewallValid) {
            if (pattern.isHidden) {
              // If this pattern is hidden, mark for deletion from nav.
              patternSubType.patternSubTypeItems[in2] = null;
            }
            else {
              this.viewallBuilder.buildViewallSubTypeBody(patternSubTypeItem, patternSubType, patternType);
            }
          }

          this.patternBuilder.freePattern(pattern);
        }

        // Finish building subType viewall.
        if (this.isViewallValid) {
          this.viewallBuilder.buildViewallFooter(
            patternSubType.patternPartial,
            patternSubType.flatPatternPath
          );
        }
      }

      // Finish building type viewall.
      if (this.isViewallValid && patternType.patternTypeLC !== scrapeTypeName) {
        this.viewallBuilder.buildViewallFooter(patternType.patternPartial, patternType.flatPatternPath);
      }
    }

    // Finish building viewall.
    if (this.isViewallValid) {
      this.viewallBuilder.buildViewallFooter('viewall', 'viewall');
    }

    // Fully remove no longer needed data from patternTypes array so we don't write a huge ui/data.js file.
    /* 0 FOR-LOOP LEVELS IN. */
    for (let in0 = 0, le0 = this.ingredients.patternTypes.length; in0 < le0; in0++) {
      const patternType = this.ingredients.patternTypes[in0];

      delete patternType.pathsPublic;

      /* 1 FOR-LOOP LEVELS IN. */
      // Must reevaluate length each iteration so we cannot cache le1.
      for (let in1 = 0; in1 < patternType.patternTypeItems.length; in1++) {
        const patternTypeItem = patternType.patternTypeItems[in1];

        if (!patternTypeItem) {
          patternType.patternTypeItems.splice(in1, 1);
          in1--;
        }
        else {
          delete patternTypeItem.pathsPublic;
          delete patternTypeItem.pattern;
        }
      }

      /* 1 FOR-LOOP LEVELS IN. */
      for (let in1 = 0, le1 = patternType.patternSubTypes.length; in1 < le1; in1++) {
        const patternSubType = patternType.patternSubTypes[in1];

        delete patternSubType.pathsPublic;

        /* 2 FOR-LOOP LEVELS IN. */
        // Must reevaluate length each iteration so we cannot cache le2.
        for (let in2 = 0; in2 < patternSubType.patternSubTypeItems.length; in2++) {
          const patternSubTypeItem = patternSubType.patternSubTypeItems[in2];

          if (!patternSubTypeItem) {
            patternSubType.patternSubTypeItems.splice(in2, 1);
            in2--;
          }
          else {
            delete patternSubTypeItem.pathsPublic;
            delete patternSubTypeItem.pattern;
          }
        }
      }
    }

    // Write hashes file.
    if (Object.keys(this.ingredients.hashesNew).length) {
      fs.writeJsonSync(`${this.config.paths.public.patterns}/hashes.json`, this.ingredients.hashesNew);
    }
  }

  writePatternlabData() {
    // Temporarily dereference .paths from the config object because we don't want absolute paths on the client.
    const configPaths = this.config.paths;
    delete this.config.paths;

    // Build the data into text output.
    let output = '';
    output += 'export const config = ' + JSON.stringify(this.config) + ';\n';
    output += 'export const ishControls = {"ishControlsHide":' + JSON.stringify(this.config.ishControlsHide) +
      '};\n';
    output += 'export const navItems = {"patternTypes": ' + JSON.stringify(this.ingredients.patternTypes) + '};\n';
    output += 'export const patternPaths = ' + JSON.stringify(this.ingredients.patternPaths) + ';\n';
    output += 'export const viewallPaths = ' + JSON.stringify(this.ingredients.viewallPaths) + ';\n';

    // Re-add .paths to the config object.
    this.config.paths = configPaths;

    // Write the output.
    fs.outputFileSync(`${this.public.styleguide}/scripts/ui/data.js`, output);
  }
};
<commit_msg>more i18n<commit_after>'use strict';

const Feplet = require('feplet');
const fs = require('fs-extra');

const objectFactory = require('./object-factory');

module.exports = class {
  #patternlab;

  constructor(patternlab) {
    this.#patternlab = patternlab;

    this.config = patternlab.config;
    this.ingredients = patternlab.ingredients;
    this.isViewallValid = false;
    this.public = patternlab.config.paths.public;
    this.source = patternlab.config.paths.source;
    this.utils = patternlab.utils;
  }

  /* GETTERS for patternlab instance props in case they are undefined at instantiation. */

  get patternBuilder() {
    return this.#patternlab.patternBuilder;
  }

  get viewallBuilder() {
    return this.#patternlab.viewallBuilder;
  }

  /* METHODS */

  processAllPatterns() {
    const dateNow = Date.now();

    let patternsToExport;

    if (Array.isArray(this.config.patternExportPatternPartials) && this.config.patternExportPatternPartials.length) {
      patternsToExport = this.config.patternExportPatternPartials;
    }

    this.viewallBuilder.preParseViewallMarkup();
    this.viewallBuilder.processViewallData();

    this.isViewallValid = this.viewallBuilder.isViewallValid;

    // Need to process the first pattern in this.ingredients.patternTypes array in order to build viewall output.
    // Need to do this before the nested for loop.
    let isFirstPatternSubType;
    let firstPattern;

    if (this.ingredients.patternTypes.length && this.isViewallValid) {
      if (
        this.ingredients.patternTypes[0].patternTypeItems.length &&
        this.ingredients.patternTypes[0].patternTypeItems[0].patternName !== t('View All')
      ) {
        isFirstPatternSubType = false;
        firstPattern = this.ingredients.patternTypes[0].patternTypeItems[0].pattern;

        this.patternBuilder.processPattern(firstPattern);
      }
      else if (
        this.ingredients.patternTypes[0].patternSubTypes.length &&
        this.ingredients.patternTypes[0].patternSubTypes[0].patternSubTypeItems.length
      ) {
        isFirstPatternSubType = true;
        firstPattern = this.ingredients.patternTypes[0].patternSubTypes[0].patternSubTypeItems[0].pattern;

        this.patternBuilder.processPattern(firstPattern);
      }

      this.viewallBuilder.viewallPageHead = firstPattern.header +
        Feplet.render(this.viewallBuilder.viewallTemplateHead, this.ingredients.data);

      this.ingredients.viewallPatterns.viewall = new objectFactory.PatternViewall(
        // Naming the HTML file viewall.html instead of index.html to allow naming a Type "viewall" however unlikely.
        `${this.public.patterns}/viewall/viewall.html`,
        this.viewallBuilder.viewallPageHead
      );
    }

    // Omit scrape directory from viewalls.
    const scrapeTypeName = this.source.scrape.replace(`${this.source.patterns}/`, '').replace(/^\d*-/, '');

    // Process patterns and viewall in the same nested loop.
    // This way, memory can be freed for both at the end of each loop.
    /* 0 FOR-LOOP LEVELS IN. */
    for (let in0 = 0, le0 = this.ingredients.patternTypes.length; in0 < le0; in0++) {
      const patternType = this.ingredients.patternTypes[in0];

      if (this.isViewallValid && patternType.patternTypeLC !== scrapeTypeName) {
        this.ingredients.viewallPatterns[patternType.flatPatternPath] = new objectFactory.PatternViewall(
          `${this.public.patterns}/${patternType.flatPatternPath}/index.html`,
          this.viewallBuilder.viewallPageHead
        );
        this.viewallBuilder.buildViewallTypeHead(patternType);
      }

      // Iterate through this type's items.
      /* 1 FOR-LOOP LEVELS IN. */
      for (let in1 = 0, le1 = patternType.patternTypeItems.length; in1 < le1; in1++) {
        const patternTypeItem = patternType.patternTypeItems[in1];

        if (patternTypeItem.patternName === t('View All')) {
          continue;
        }

        const pattern = patternTypeItem.pattern;

        // Process pattern.
        // Always process Type if 1st pattern is subType.
        // Otherwise, skip if both in0 === 0 and in1 === 0.
        if (isFirstPatternSubType || in0 > 0 || in1 > 0) {
          this.patternBuilder.processPattern(pattern);
        }

        // Write pattern.
        if (!pattern.isHidden) {
          this.patternBuilder.writePattern(pattern, dateNow);
        }

        // Export pattern.
        if (patternsToExport && patternsToExport.indexOf(pattern.patternPartial) > -1) {
          const patternPartialCode = this.utils.beautifyTemplate(pattern.templateExtended);

          fs.outputFileSync(
            `${this.config.patternExportDirectory}/${pattern.patternPartial}.html`,
            patternPartialCode
          );
        }

        // Build viewall body.
        if (this.isViewallValid) {
          if (pattern.isHidden) {
            // If this pattern is hidden, mark for deletion from nav.
            patternType.patternTypeItems[in1] = null;
          }
          else if (patternType.patternTypeLC !== scrapeTypeName) {
            this.viewallBuilder.buildViewallTypeBody(patternTypeItem, patternType);
          }
        }

        this.patternBuilder.freePattern(pattern);
      }

      /* 1 FOR-LOOP LEVELS IN. */
      for (let in1 = 0, le1 = patternType.patternSubTypes.length; in1 < le1; in1++) {
        const patternSubType = patternType.patternSubTypes[in1];

        // Build viewall head for this subType.
        if (this.isViewallValid) {
          this.ingredients.viewallPatterns[patternSubType.flatPatternPath] = new objectFactory.PatternViewall(
            `${this.public.patterns}/${patternSubType.flatPatternPath}/index.html`,
            this.viewallBuilder.viewallPageHead
          );
          this.viewallBuilder.buildViewallSubTypeHead(patternSubType, patternType);
        }

        // Iterate through this subType's items.
        /* 2 FOR-LOOP LEVELS IN. */
        for (let in2 = 0, le2 = patternSubType.patternSubTypeItems.length; in2 < le2; in2++) {
          const patternSubTypeItem = patternSubType.patternSubTypeItems[in2];

          if (patternSubTypeItem.patternName === t('View All')) {
            continue;
          }

          const pattern = patternSubTypeItem.pattern;

          // Process pattern.
          // Always process subType if 1st pattern is not subType.
          // Otherwise, skip if in0 === 0, in1 === 0, and in2 === 0.
          if (!isFirstPatternSubType || in0 > 0 || in1 > 0 || in2 > 0) {
            this.patternBuilder.processPattern(pattern);
          }

          // Write pattern.
          if (!pattern.isHidden) {
            this.patternBuilder.writePattern(pattern, dateNow);
          }

          // Export pattern.
          if (patternsToExport && patternsToExport.indexOf(pattern.patternPartial) > -1) {
            const patternPartialCode = this.utils.beautifyTemplate(pattern.templateExtended);

            fs.outputFileSync(
              `${this.config.patternExportDirectory}/${pattern.patternPartial}.html`,
              patternPartialCode
            );
          }

          // Build viewall body.
          if (this.isViewallValid) {
            if (pattern.isHidden) {
              // If this pattern is hidden, mark for deletion from nav.
              patternSubType.patternSubTypeItems[in2] = null;
            }
            else {
              this.viewallBuilder.buildViewallSubTypeBody(patternSubTypeItem, patternSubType, patternType);
            }
          }

          this.patternBuilder.freePattern(pattern);
        }

        // Finish building subType viewall.
        if (this.isViewallValid) {
          this.viewallBuilder.buildViewallFooter(
            patternSubType.patternPartial,
            patternSubType.flatPatternPath
          );
        }
      }

      // Finish building type viewall.
      if (this.isViewallValid && patternType.patternTypeLC !== scrapeTypeName) {
        this.viewallBuilder.buildViewallFooter(patternType.patternPartial, patternType.flatPatternPath);
      }
    }

    // Finish building viewall.
    if (this.isViewallValid) {
      this.viewallBuilder.buildViewallFooter('viewall', 'viewall');
    }

    // Fully remove no longer needed data from patternTypes array so we don't write a huge ui/data.js file.
    /* 0 FOR-LOOP LEVELS IN. */
    for (let in0 = 0, le0 = this.ingredients.patternTypes.length; in0 < le0; in0++) {
      const patternType = this.ingredients.patternTypes[in0];

      delete patternType.pathsPublic;

      /* 1 FOR-LOOP LEVELS IN. */
      // Must reevaluate length each iteration so we cannot cache le1.
      for (let in1 = 0; in1 < patternType.patternTypeItems.length; in1++) {
        const patternTypeItem = patternType.patternTypeItems[in1];

        if (!patternTypeItem) {
          patternType.patternTypeItems.splice(in1, 1);
          in1--;
        }
        else {
          delete patternTypeItem.pathsPublic;
          delete patternTypeItem.pattern;
        }
      }

      /* 1 FOR-LOOP LEVELS IN. */
      for (let in1 = 0, le1 = patternType.patternSubTypes.length; in1 < le1; in1++) {
        const patternSubType = patternType.patternSubTypes[in1];

        delete patternSubType.pathsPublic;

        /* 2 FOR-LOOP LEVELS IN. */
        // Must reevaluate length each iteration so we cannot cache le2.
        for (let in2 = 0; in2 < patternSubType.patternSubTypeItems.length; in2++) {
          const patternSubTypeItem = patternSubType.patternSubTypeItems[in2];

          if (!patternSubTypeItem) {
            patternSubType.patternSubTypeItems.splice(in2, 1);
            in2--;
          }
          else {
            delete patternSubTypeItem.pathsPublic;
            delete patternSubTypeItem.pattern;
          }
        }
      }
    }

    // Write hashes file.
    if (Object.keys(this.ingredients.hashesNew).length) {
      fs.writeJsonSync(`${this.config.paths.public.patterns}/hashes.json`, this.ingredients.hashesNew);
    }
  }

  writePatternlabData() {
    // Temporarily dereference .paths from the config object because we don't want absolute paths on the client.
    const configPaths = this.config.paths;
    delete this.config.paths;

    // Build the data into text output.
    let output = '';
    output += 'export const config = ' + JSON.stringify(this.config) + ';\n';
    output += 'export const ishControls = {"ishControlsHide":' + JSON.stringify(this.config.ishControlsHide) +
      '};\n';
    output += 'export const navItems = {"patternTypes": ' + JSON.stringify(this.ingredients.patternTypes) + '};\n';
    output += 'export const patternPaths = ' + JSON.stringify(this.ingredients.patternPaths) + ';\n';
    output += 'export const viewallPaths = ' + JSON.stringify(this.ingredients.viewallPaths) + ';\n';

    // Re-add .paths to the config object.
    this.config.paths = configPaths;

    // Write the output.
    fs.outputFileSync(`${this.public.styleguide}/scripts/ui/data.js`, output);
  }
};
<|endoftext|>


<commit_before>

;(function(exports, require){
	var canvas = document.getElementsByTagName('canvas')[0];
	var context = canvas.getContext('2d');
	var ajax = require.ajax;
	var addEvent = require.addEvent;

	//缩放比例
	var SCALE_BIG = 1;
	var SCALE_SML = 0.25;

	//颜色对应表
	var COLOR_LIST = {
		BODY: '#63CEF6',
		DUPI: '#FFF',
		EYE: '#034E68',
		ZUIBA: '#0089B5',
		TOUQUAN: '#BDF9FB',
		JIUWO: '#FFBFE3',
		QIPAO: '#C9E8FB',
		BISHANG: '#46BEEF',
		BIXIA: '#54C5F2',
		GO: '#B1DBF2'
	};

	if(!context){
		return;
	}

	if(!window.requestAnimationFrame){
		return window.requestAnimationFrame = (function(){
			window.webkitRequestAnimationFrame
			|| window.mozRequestAnimationFrame
			|| window.oRequestAnimationFrame
			|| window.msRequestAnimationFrame
			|| function(callback, el){
				window.setTimeout(callback, 1000/ 60);
			};
		})();
	}

	context.scale(SCALE_SML, SCALE_SML);
	//draw polygon
	function drawPolygon(data, part, color){
		var xys = data[part];
		context.beginPath();
		context.fillStyle = color;

		context.moveTo(xys[0], xys[1]);
		for(var i = 2; i < xys.length; i++){
			if(i % 2 !== 0){
				context.lineTo(xys[i-1], xys[i]);
			}
		}

		context.fill();
		context.closePath();
	}

	//draw eye
	function drawEye(data, part, color){
		var xys = data[part];
		context.beginPath();
		context.fillStyle = color;

		//变形
	 	context.save();
		context.scale(1.5, 2);
		context.arc(xys[0]/1.5, xys[1]/2, 6, 0, Math.PI * 2, false);
		context.restore();

		context.fill();
		context.closePath();

	}

	//drawCircle
	function drawCircle(data, part, color, radius){
		var xys = data[part];
		context.beginPath();
		context.fillStyle = color;

		context.arc(xys[0], xys[1], radius, 0, Math.PI * 2, false);

		context.fill();
		context.closePath();
	}

	//draw line
	function drawLine(data, part, color, width){
		var xys = data[part];
		context.beginPath();
		context.strokeStyle = color;
		context.lineWidth = width;
		context.moveTo(xys[0], xys[1]);
		for(var i = 0; i < xys.length; i++){
			if(i % 2 !== 0){
				context.lineTo(xys[i-1], xys[i]);
			}
		}
		context.stroke();
		context.closePath();
	}

	//draw text
	function drawText(x, y){
		context.beginPath();
		context.fillStyle = '#FFFFFF';
		context.font = '40px arial,sans-serif';
		context.fillText('go...', x, y)
		context.fill();
		context.closePath();
	}

	//绘制
	function draw(fileName){
		var url = 'http://127.0.0.1:3000/get?dirName=dist&fileName=' + fileName;
		ajax({method: 'GET', url: url}, function(data){
			data = data.data;
			drawPolygon(data, 'polygon_body', COLOR_LIST.BODY);
			drawPolygon(data, 'polygon_dupi', COLOR_LIST.DUPI);
			drawPolygon(data, 'polygon_touquan', COLOR_LIST.TOUQUAN);
			drawPolygon(data, 'polygon_jiuwo1', COLOR_LIST.JIUWO);
			drawPolygon(data, 'polygon_jiuwo2', COLOR_LIST.JIUWO);
			drawPolygon(data, 'polygon_go', COLOR_LIST.GO);

			drawEye(data, 'circle_eye1', COLOR_LIST.EYE);
			drawEye(data, 'circle_eye2', COLOR_LIST.EYE);

			drawLine(data, 'line_zui', COLOR_LIST.ZUIBA, 4);
			drawLine(data, 'line_bishang', COLOR_LIST.BISHANG, 8);
			drawLine(data, 'line_bixia', COLOR_LIST.BIXIA, 5);

			drawCircle(data, 'circle_qipao1', COLOR_LIST.QIPAO, 30);
			drawCircle(data, 'circle_qipao2', COLOR_LIST.QIPAO, 25);
			drawCircle(data, 'circle_qipao3', COLOR_LIST.QIPAO, 15);
			drawCircle(data, 'circle_qipao4', COLOR_LIST.QIPAO, 20);
			drawCircle(data, 'circle_qipao5', COLOR_LIST.QIPAO, 15);
			drawCircle(data, 'circle_qipao6', COLOR_LIST.QIPAO, 10);
			drawCircle(data, 'circle_qipao7', COLOR_LIST.QIPAO, 16);

			drawText(320, 69);
		});
	}

	//执行流程
	draw('dist_3');

})(window, window);
<commit_msg>add Animation<commit_after>

;(function(exports, require){
	var canvas = document.getElementsByTagName('canvas')[0];
	var context = canvas.getContext('2d');
	var ajax = require.ajax;
	var addEvent = require.addEvent;

	//缩放比例
	var SCALE_BIG = 1;
	var SCALE_SML = 0.25;

	if(!context){
		return;
	}

	if(!window.requestAnimationFrame){
		return window.requestAnimationFrame = (function(){
			window.webkitRequestAnimationFrame
			|| window.mozRequestAnimationFrame
			|| window.oRequestAnimationFrame
			|| window.msRequestAnimationFrame
			|| function(callback, el){
				window.setTimeout(callback, 1000/ 60);
			};
		})();
	}

	var Vector = function(data){
		this.data = data;
		Vector._context.scale(SCALE_SML, SCALE_SML);
	};

	Vector._context = canvas.getContext('2d');
	//颜色对应表
	Vector._COLOR_LIST = {
		BODY: '#63CEF6',
		DUPI: '#FFF',
		EYE: '#034E68',
		ZUIBA: '#0089B5',
		TOUQUAN: '#BDF9FB',
		JIUWO: '#FFBFE3',
		QIPAO: '#C9E8FB',
		BISHANG: '#46BEEF',
		BIXIA: '#54C5F2',
		GO: '#B1DBF2'
	};

	Vector._drawPolygon = function(xys, color){
		context.beginPath();
		context.fillStyle = color;
		context.moveTo(xys[0], xys[1]);
		for(var i = 2; i < xys.length; i++){
			if(i % 2 !== 0){
				context.lineTo(xys[i-1], xys[i]);
			}
		}

		context.fill();
		context.closePath();
	};

	Vector._drawCircle = function(xys, color, radius){
		context.beginPath();
		context.fillStyle = color;
		context.arc(xys[0], xys[1], radius, 0, Math.PI * 2, false);
		context.fill();
		context.closePath();
	};

	Vector._drawEye = function(xys, color, radius){
		context.beginPath();
		context.fillStyle = color;
	 	context.save();
		context.scale(1.5, 2);
		context.arc(xys[0]/1.5, xys[1]/2, radius, 0, Math.PI * 2, false);
		context.restore();
		context.fill();
		context.closePath();
	};

	Vector._drawLine = function(xys, color, width){
		context.beginPath();
		context.strokeStyle = color;
		context.lineWidth = width;
		context.moveTo(xys[0], xys[1]);
		for(var i = 0; i < xys.length; i++){
			if(i % 2 !== 0){
				context.lineTo(xys[i-1], xys[i]);
			}
		}
		context.stroke();
		context.closePath();
	};

	Vector._drawText = function(text, x, y, color){
		context.beginPath();
		context.fillStyle = color;
		context.font = '40px arial,sans-serif';
		context.fillText(text, x, y)
		context.fill();
		context.closePath();
	};

	Vector.prototype = {
		draw: function(){
			var data = this.data;
			var qipaoPos = 0;
			var handle = setInterval(function(){
				context.clearRect(0, 0, canvas.width, canvas.height);
				console.log(qipaoPos);
				Vector._drawPolygon(data['polygon_body'], Vector._COLOR_LIST.BODY);
				Vector._drawPolygon(data['polygon_dupi'], Vector._COLOR_LIST.DUPI);
				Vector._drawPolygon(data['polygon_touquan'], Vector._COLOR_LIST.TOUQUAN);
				Vector._drawPolygon(data['polygon_jiuwo1'], Vector._COLOR_LIST.JIUWO);
				Vector._drawPolygon(data['polygon_jiuwo2'], Vector._COLOR_LIST.JIUWO);
				Vector._drawPolygon(data['polygon_go'], Vector._COLOR_LIST.GO);

				var eye_1 = [
						parseInt(data['circle_eye1'][0]),
						parseInt(data['circle_eye1'][1])
					];

					var eye_2 = [
						parseInt(data['circle_eye2'][0]),
						parseInt(data['circle_eye2'][1])
					];
				if(qipaoPos % 2 === 0){
					Vector._drawEye(eye_1, Vector._COLOR_LIST.EYE, 6);
					Vector._drawEye(eye_2, Vector._COLOR_LIST.EYE, 6);

					eye_1[0] += 3;
					eye_1[1] -= 5;

					eye_2[0] += 3;
					eye_2[1] -= 5;

					Vector._drawEye(eye_1, '#EFEFEF', 3);
					Vector._drawEye(eye_2, '#EFEFEF', 3);
				}else{
					//‿
					Vector._drawText('‿', eye_1[0] + 26 , eye_1[1] - 42, '#099FDE');
					Vector._drawText('‿', eye_2[0] - 36 , eye_2[1] - 25, '#099FDE');
					//><
					Vector._drawText('>', eye_1[0] - 16 , eye_1[1] + 16, '#099FDE');
					Vector._drawText('<', eye_2[0] - 16 , eye_2[1] + 16, '#099FDE');
				}

				Vector._drawLine(data['line_zui'], Vector._COLOR_LIST.ZUIBA, 4);
				Vector._drawLine(data['line_bishang'], Vector._COLOR_LIST.BISHANG, 8);
				Vector._drawLine(data['line_bixia'], Vector._COLOR_LIST.BIXIA, 5);

				data['circle_qipao1'][1] -= qipaoPos;
				data['circle_qipao2'][1] -= qipaoPos;
				data['circle_qipao3'][1] -= qipaoPos;
				data['circle_qipao4'][1] -= qipaoPos;
				data['circle_qipao5'][1] -= qipaoPos;
				data['circle_qipao6'][1] -= qipaoPos;
				data['circle_qipao7'][1] -= qipaoPos;

				Vector._drawCircle(data['circle_qipao1'], Vector._COLOR_LIST.QIPAO, 30);
				Vector._drawCircle(data['circle_qipao2'], Vector._COLOR_LIST.QIPAO, 25);
				Vector._drawCircle(data['circle_qipao3'], Vector._COLOR_LIST.QIPAO, 15);
				Vector._drawCircle(data['circle_qipao4'], Vector._COLOR_LIST.QIPAO, 20);
				Vector._drawCircle(data['circle_qipao5'], Vector._COLOR_LIST.QIPAO, 15);
				Vector._drawCircle(data['circle_qipao6'], Vector._COLOR_LIST.QIPAO, 10);
				Vector._drawCircle(data['circle_qipao7'], Vector._COLOR_LIST.QIPAO, 16);

				Vector._drawText('go...', 320, 69, '#fff');
				qipaoPos += 3;
			}, 130);
		}
	};

	var url = 'http://127.0.0.1:3000/get?dirName=dist&fileName=' + 'dist_3';
	ajax({method: 'GET', url: url}, function(data){
		data = data.data;
		new Vector(data).draw();
	});

})(window, window);
<|endoftext|>