<commit_before>"use strict";

define(['js/Decorators/DecoratorBase',
    './SnapEditor/SVGDecorator.SnapEditorWidget',
    './DiagramDesigner/SVGDecorator.DiagramDesignerWidget',
    './PartBrowser/SVGDecorator.PartBrowserWidget'], function (
                                                           DecoratorBase,
                                                           SVGDecoratorSnapEditorWidget,
                                                           SVGDecoratorDiagramDesignerWidget,
                                                           SVGDecoratorPartBrowserWidget) {

    var SVGDecorator,
        DECORATOR_ID = "SVGDecorator";

    SVGDecorator = function (params) {
        var opts = _.extend( {"loggerName": this.DECORATORID}, params);

        DecoratorBase.apply(this, [opts]);

        this.logger.debug("SVGDecorator ctor");
    };

    _.extend(SVGDecorator.prototype, DecoratorBase.prototype);
    SVGDecorator.prototype.DECORATORID = DECORATOR_ID;

    /*********************** OVERRIDE DecoratorBase MEMBERS **************************/

    SVGDecorator.prototype.initializeSupportedWidgetMap = function () {

        this.supportedWidgetMap = {
            'DiagramDesigner': SVGDecoratorDiagramDesignerWidget,
            'PartBrowser': SVGDecoratorPartBrowserWidget,
            'SnapEditor': SVGDecoratorSnapEditorWidget};

    };

    return SVGDecorator;
});
<commit_msg>Added authorship info<commit_after>/*globals define,_*/
/*
 * @author rkereskenyi / https://github/rkereskenyi
 * @author brollb / https://github/brollb
 */
define(['js/Decorators/DecoratorBase',
    './SnapEditor/SVGDecorator.SnapEditorWidget',
    './DiagramDesigner/SVGDecorator.DiagramDesignerWidget',
    './PartBrowser/SVGDecorator.PartBrowserWidget'], function (
                                                           DecoratorBase,
                                                           SVGDecoratorSnapEditorWidget,
                                                           SVGDecoratorDiagramDesignerWidget,
                                                           SVGDecoratorPartBrowserWidget) {

    "use strict";

    var SVGDecorator,
        DECORATOR_ID = "SVGDecorator";

    SVGDecorator = function (params) {
        var opts = _.extend( {"loggerName": this.DECORATORID}, params);

        DecoratorBase.apply(this, [opts]);

        this.logger.debug("SVGDecorator ctor");
    };

    _.extend(SVGDecorator.prototype, DecoratorBase.prototype);
    SVGDecorator.prototype.DECORATORID = DECORATOR_ID;

    /*********************** OVERRIDE DecoratorBase MEMBERS **************************/

    SVGDecorator.prototype.initializeSupportedWidgetMap = function () {

        this.supportedWidgetMap = {
            'DiagramDesigner': SVGDecoratorDiagramDesignerWidget,
            'PartBrowser': SVGDecoratorPartBrowserWidget,
            'SnapEditor': SVGDecoratorSnapEditorWidget};

    };

    return SVGDecorator;
});
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var TypedError = require('error/typed');
var inherits = require('util').inherits;
var Transform = require('stream').Transform;
var hex = require('hexer');

var BrokenReaderStateError = TypedError({
    type: 'tchannel.broken-reader-state',
    message: 'reader in invalid state {state}',
    state: null
});

module.exports = ChunkSpy;

var States = {
    PendingLength: 0,
    Seeking: 1
};

function ChunkSpy(sink, options) {
    if (!(this instanceof ChunkSpy)) {
        return new ChunkSpy(sink, options);
    }
    options = options || {};
    Transform.call(this, options);
    var self = this;
    self.hex = hex.Transform(options);
    self.frameLengthSize = options.frameLengthSize || 2;
    self.buffer = Buffer(0);
    self.expecting = self.frameLengthSize;
    self.state = States.PendingLength;
    self.hex.pipe(sink);
    switch (self.frameLengthSize) {
        case 1:
            self._readLength = Buffer.prototype.readUInt8;
            break;
        case 2:
            self._readLength = Buffer.prototype.readUInt16BE;
            break;
        case 4:
            self._readLength = Buffer.prototype.readUInt32BE;
            break;
        default:
            throw new Error('unsupported frame length size');
    }
}

inherits(ChunkSpy, Transform);

ChunkSpy.prototype._transform = function _transform(chunk, encoding, callback) {
    var self = this;
    if (!callback) {
        callback = emitIt;
    }
    if (self.buffer.length) {
        self.buffer = Buffer.concat([self.buffer, chunk], self.buffer.length + chunk.length);
    } else {
        self.buffer = chunk;
    }
    while (self.buffer.length) {
        switch (self.state) {
            case States.PendingLength:
                if (self.buffer.length >= self.expecting) {
                    self.expecting = self._readLength.call(self.buffer, 0);
                    self.state = States.Seeking;
                    self.hex.reset();
                }
                break;
            case States.Seeking:
                if (self.buffer.length >= self.expecting) {
                    chunk = self.buffer.slice(0, self.expecting);
                    self.push(chunk);
                    self.hex.write(chunk);
                    self.buffer = self.buffer.slice(self.expecting);
                    self.expecting = self.frameLengthSize;
                    self.state = States.PendingLength;
                } else {
                    self.expecting -= self.buffer.length;
                    self.push(self.buffer);
                    self.hex.write(self.buffer);
                    self.buffer = Buffer(0);
                }
                break;
            default:
                callback(BrokenReaderStateError({state: self.state}));
                return;
        }
    }
    callback();

    function emitIt(err) {
        self.emit('error', err);
    }
};

ChunkSpy.prototype._flush = function _flush(callback) {
    var self = this;
    if (self.buffer.length) {
        self.push(self.buffer);
        self.hex.write(self.buffer);
        self.buffer = Buffer(0);
        self.expecting = 4;
        self.state = States.PendingLength;
    }
    callback();
};
<commit_msg>Be sure to end the hex stream in chunkSpy.flush<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

'use strict';

var TypedError = require('error/typed');
var inherits = require('util').inherits;
var Transform = require('stream').Transform;
var hex = require('hexer');

var BrokenReaderStateError = TypedError({
    type: 'tchannel.broken-reader-state',
    message: 'reader in invalid state {state}',
    state: null
});

module.exports = ChunkSpy;

var States = {
    PendingLength: 0,
    Seeking: 1
};

function ChunkSpy(sink, options) {
    if (!(this instanceof ChunkSpy)) {
        return new ChunkSpy(sink, options);
    }
    options = options || {};
    Transform.call(this, options);
    var self = this;
    self.hex = hex.Transform(options);
    self.frameLengthSize = options.frameLengthSize || 2;
    self.buffer = Buffer(0);
    self.expecting = self.frameLengthSize;
    self.state = States.PendingLength;
    self.hex.pipe(sink);
    switch (self.frameLengthSize) {
        case 1:
            self._readLength = Buffer.prototype.readUInt8;
            break;
        case 2:
            self._readLength = Buffer.prototype.readUInt16BE;
            break;
        case 4:
            self._readLength = Buffer.prototype.readUInt32BE;
            break;
        default:
            throw new Error('unsupported frame length size');
    }
}

inherits(ChunkSpy, Transform);

ChunkSpy.prototype._transform = function _transform(chunk, encoding, callback) {
    var self = this;
    if (!callback) {
        callback = emitIt;
    }
    if (self.buffer.length) {
        self.buffer = Buffer.concat([self.buffer, chunk], self.buffer.length + chunk.length);
    } else {
        self.buffer = chunk;
    }
    while (self.buffer.length) {
        switch (self.state) {
            case States.PendingLength:
                if (self.buffer.length >= self.expecting) {
                    self.expecting = self._readLength.call(self.buffer, 0);
                    self.state = States.Seeking;
                    self.hex.reset();
                }
                break;
            case States.Seeking:
                if (self.buffer.length >= self.expecting) {
                    chunk = self.buffer.slice(0, self.expecting);
                    self.push(chunk);
                    self.hex.write(chunk);
                    self.buffer = self.buffer.slice(self.expecting);
                    self.expecting = self.frameLengthSize;
                    self.state = States.PendingLength;
                } else {
                    self.expecting -= self.buffer.length;
                    self.push(self.buffer);
                    self.hex.write(self.buffer);
                    self.buffer = Buffer(0);
                }
                break;
            default:
                callback(BrokenReaderStateError({state: self.state}));
                return;
        }
    }
    callback();

    function emitIt(err) {
        self.emit('error', err);
    }
};

ChunkSpy.prototype._flush = function _flush(callback) {
    var self = this;
    if (self.buffer.length) {
        self.push(self.buffer);
        self.hex.end(self.buffer);
        self.buffer = Buffer(0);
        self.expecting = 4;
        self.state = States.PendingLength;
    } else {
        self.hex.end();
    }
    callback();
};
<|endoftext|>


<commit_before>require('core-upgrade');
var HTML5 = require('html5');
var sys = require('sys');
var assert = require('assert');
var DOM = require('dom'); // Use env-js dom

HTML5.TreeBuilder = b = function TreeBuilder() {
	this.open_elements = [];
	this.document = new DOM.Document(DOM.DOMImplementation);
	this.activeFormattingElements = [];
}

b.prototype.reset = function() {

}

b.prototype.createElement = function (name, attributes, namespace) {
	var el = this.document.createElement(name)
	if(attributes) for(var i = 0; i < attributes.length; i++) {
		el.setAttribute(attributes[i].nodeName, attributes[i].nodeValue);
	}
	return el;
}

b.prototype.insert_element = function(name, attributes, namespace) {
	HTML5.debug('treebuilder.insert_element', name)
	if(this.insert_from_table) {
		return this.insert_element_from_table(name, attributes, namespace)
	} else {
		return this.insert_element_normal(name, attributes, namespace)
	}
}

b.prototype.insert_element_normal = function(name, attributes, namespace) {
	HTML5.debug('treebuilder.insert_element_normal', name)
	var element = this.createElement(name, attributes, namespace);
	this.open_elements.last().appendChild(element);
	this.open_elements.push(element);
	return element;
}

b.prototype.insert_element_from_table = function(name, attributes, namespace) {
	HTML5.debug('treebuilder.insert_element_from_table', name)
	var element = this.createElement(name, attributes, namespace)
	if(HTML5.TABLE_INSERT_MODE_ELEMENTS.indexOf(this.open_elements.last().tagName) != -1) {
		// We should be in the InTable mode. This means we want to do
		// special magic element rearranging
		var t = this.getTableMisnestedNodePosition()
		if(!t.insertBefore) {
			t.parent.appendChild(element)
		} else {
			t.parent.insertBefore(element, t.insertBefore)
		}
		this.open_elements.push(element)
	} else {
		return this.insert_element_normal(name, attributes, namespace);
	}
	return element;
}

b.prototype.insert_comment = function(data, parent) {
	var c = this.document.createComment(data);
	HTML5.debug('treebuilder', 'open elements at insert_comment are: ' + require('sys').inspect(this.open_elements.map(function(e) { return e.nodeName })));
	if(!parent) parent = this.open_elements.last();
	parent.appendChild(c);
}

b.prototype.insert_doctype = function (name, publicId, systemId) {
	// var dt = this.document.implementation.createDocumentType(name, publicId, systemId);
	var doctype = new DOM.DocumentType();
        doctype.nodeName = name?name:'';
        doctype.publicId = publicId?publicId:null;
        doctype.systemId = systemId?systemId:null;
	this.document.appendChild(doctype);
}

b.prototype.insert_text = function(data, parent) {
	HTML5.debug('treebuilder.insert_text', data)
	if(!parent) parent = this.open_elements.last();
	if(!this.insert_from_table || HTML5.TABLE_INSERT_MODE_ELEMENTS.indexOf(this.open_elements.last().tagName) == -1) {
		if(parent.lastChild && parent.lastChild.nodeType == DOM.Node.TEXT_NODE) {
			parent.lastChild.appendData(data);
		} else {
			var tn = this.document.createTextNode(data);
			parent.appendChild(tn);
		}
	} else {
		HTML5.debug('treebuilder.insert_text', 'voodoo invoked')
		// We should be in the inTable phase. This means we want to do special
		// magic element rearranging.
		var t = this.getTableMisnestedNodePosition();
		insertText(t.parent, data, t.insertBefore)
	}
}

function insertText(node, data, before) {
	var t = node.ownerDocument.createTextNode(data)
	if(before) {
		if(before.previousSibling.nodeType == DOM.Node.TEXT_NODE) {
			before.previousSibling.nodeValue += data;
		} else {
			node.insertBefore(t, before)
		}
	} else {
		node.appendChild(t)
	}
}

b.prototype.getTableMisnestedNodePosition = function() {
	// The foster parent element is the one which comes before the most
	// recently opened table element
	// XXX - this is really inelegant
	var lastTable, fosterParent, insertBefore

	for(var i = this.open_elements.length - 1; i >= 0; i--) {
		var element = this.open_elements[i]
		if(element.tagName == 'table') {
			lastTable = element
			break
		}
	}

	if(lastTable) {
		// XXX - we should check that the parent really is a node here
		if(lastTable.parentNode) {
			fosterParent = lastTable.parentNode
			insertBefore = lastTable
		} else {
			fosterParent = this.open_elements[this.open_elements.indexOf(lastTable) - 1]
		}
	} else {
		fosterParent = this.open_elements[0]
	}

	return {parent: fosterParent, insertBefore: insertBefore}
}

b.prototype.elementInScope = function(name, tableVariant) {
	HTML5.debug('treebuilder.elementInScope', name, tableVariant)
	if(this.open_elements.length == 0) return false
	if(this.open_elements.last().tagName == name) return true
	for(var i = this.open_elements.length - 1; i >= 0; i--) {
		if(this.open_elements[i].tagName == name) return true
		else if(this.open_elements[i].tagName == 'table') return false
		else if(!tableVariant && HTML5.SCOPING_ELEMENTS.indexOf(this.open_elements[i].tagName) != -1) return false
		else if(this.open_elements[i].tagName == 'html') return false;
	}
	return false;
}

b.prototype.generateImpliedEndTags = function (exclude) {
	//HTML5.debug('implied end tags with ' + sys.inspect(this.open_elements.map(function(el) { return el.tagName })));
	var name = this.open_elements.last().tagName;
	if(['dd', 'dt', 'li', 'p', 'td', 'th', 'tr'].indexOf(name) != -1 && name != exclude) {
		var p  = this.open_elements.pop();
		this.generateImpliedEndTags(exclude);
	}
}

b.prototype.reconstructActiveFormattingElements = function() {
	HTML5.debug('treebuilder.reconstructActiveFormattingElements', 'before', HTML5.dumpTagStack(this.activeFormattingElements))
	// Within this algorithm the order of steps decribed in the specification
	// is not quite the same as the order of steps in the code. It should still
	// do the same though.

	// Step 1: stop if there's nothing to do
	if(this.activeFormattingElements.length == 0) return;

	// Step 2 and 3: start with the last element
	var i = this.activeFormattingElements.length - 1;
	var entry = this.activeFormattingElements[i];
	if(entry == HTML5.Marker || this.open_elements.indexOf(entry) != -1) return;

	while(entry != HTML5.Marker && this.open_elements.indexOf(entry) == -1) {
		i -= 1;
		entry = this.activeFormattingElements[i];
		if(!entry) break;
	}

	while(true) {
		i += 1;
		var clone = this.activeFormattingElements[i].cloneNode();
		HTML5.debug('treebuilder.reconstructActiveFormattingElements', 'cloneNode', clone.tagName)

		var element = this.insert_element(clone.tagName, clone.attributes);

		this.activeFormattingElements[i] = element;

		if(element == this.activeFormattingElements.last()) break;
	}

	HTML5.debug('treebuilder.reconstructActiveFormattingElements', 'open tags are ' + HTML5.dumpTagStack(this.open_elements));
}

b.prototype.elementInActiveFormattingElements = function(name) {
	var els = this.activeFormattingElements;
	for(var i = els.length - 1; i >= 0; i--) {
		if(els[i] == HTML5.Marker) break;
		if(els[i].tagName == name) return els[i];
	}
	return false;
}

b.prototype.reparentChildren = function(o, n) {
	while(o.childNodes.length > 0) {
		var el = o.removeChild(o.childNodes[0]);
		n.appendChild(el);
	}
}

b.prototype.clearActiveFormattingElements = function() {
	HTML5.debug('treebuilder.clearActiveFormattingElements', 'before', HTML5.dumpTagStack(this.activeFormattingElements))
	while(!(this.activeFormattingElements.length == 0 || this.activeFormattingElements.pop() == HTML5.Marker));
	HTML5.debug('treebuilder.clearActiveFormattingElements', 'after', HTML5.dumpTagStack(this.activeFormattingElements))
}

b.prototype.getFragment = function() {
	// assert.ok(this.parser.inner_html)
	var fragment = this.document.createDocumentFragment()
	this.reparentChildren(this.open_elements[0], fragment)
	return fragment
}
<commit_msg>- fix text node before element with no previous sibling<commit_after>require('core-upgrade');
var HTML5 = require('html5');
var sys = require('sys');
var assert = require('assert');
var DOM = require('dom'); // Use env-js dom

HTML5.TreeBuilder = b = function TreeBuilder() {
	this.open_elements = [];
	this.document = new DOM.Document(DOM.DOMImplementation);
	this.activeFormattingElements = [];
}

b.prototype.reset = function() {

}

b.prototype.createElement = function (name, attributes, namespace) {
	var el = this.document.createElement(name)
	if(attributes) for(var i = 0; i < attributes.length; i++) {
		el.setAttribute(attributes[i].nodeName, attributes[i].nodeValue);
	}
	return el;
}

b.prototype.insert_element = function(name, attributes, namespace) {
	HTML5.debug('treebuilder.insert_element', name)
	if(this.insert_from_table) {
		return this.insert_element_from_table(name, attributes, namespace)
	} else {
		return this.insert_element_normal(name, attributes, namespace)
	}
}

b.prototype.insert_element_normal = function(name, attributes, namespace) {
	HTML5.debug('treebuilder.insert_element_normal', name)
	var element = this.createElement(name, attributes, namespace);
	this.open_elements.last().appendChild(element);
	this.open_elements.push(element);
	return element;
}

b.prototype.insert_element_from_table = function(name, attributes, namespace) {
	HTML5.debug('treebuilder.insert_element_from_table', name)
	var element = this.createElement(name, attributes, namespace)
	if(HTML5.TABLE_INSERT_MODE_ELEMENTS.indexOf(this.open_elements.last().tagName) != -1) {
		// We should be in the InTable mode. This means we want to do
		// special magic element rearranging
		var t = this.getTableMisnestedNodePosition()
		if(!t.insertBefore) {
			t.parent.appendChild(element)
		} else {
			t.parent.insertBefore(element, t.insertBefore)
		}
		this.open_elements.push(element)
	} else {
		return this.insert_element_normal(name, attributes, namespace);
	}
	return element;
}

b.prototype.insert_comment = function(data, parent) {
	var c = this.document.createComment(data);
	HTML5.debug('treebuilder', 'open elements at insert_comment are: ' + require('sys').inspect(this.open_elements.map(function(e) { return e.nodeName })));
	if(!parent) parent = this.open_elements.last();
	parent.appendChild(c);
}

b.prototype.insert_doctype = function (name, publicId, systemId) {
	// var dt = this.document.implementation.createDocumentType(name, publicId, systemId);
	var doctype = new DOM.DocumentType();
        doctype.nodeName = name?name:'';
        doctype.publicId = publicId?publicId:null;
        doctype.systemId = systemId?systemId:null;
	this.document.appendChild(doctype);
}

b.prototype.insert_text = function(data, parent) {
	HTML5.debug('treebuilder.insert_text', data)
	if(!parent) parent = this.open_elements.last();
	if(!this.insert_from_table || HTML5.TABLE_INSERT_MODE_ELEMENTS.indexOf(this.open_elements.last().tagName) == -1) {
		if(parent.lastChild && parent.lastChild.nodeType == DOM.Node.TEXT_NODE) {
			parent.lastChild.appendData(data);
		} else {
			var tn = this.document.createTextNode(data);
			parent.appendChild(tn);
		}
	} else {
		HTML5.debug('treebuilder.insert_text', 'voodoo invoked')
		// We should be in the inTable phase. This means we want to do special
		// magic element rearranging.
		var t = this.getTableMisnestedNodePosition();
		insertText(t.parent, data, t.insertBefore)
	}
}

function insertText(node, data, before) {
	var t = node.ownerDocument.createTextNode(data)
	if(before) {
		if(before.previousSibling && before.previousSibling.nodeType == DOM.Node.TEXT_NODE) {
			before.previousSibling.nodeValue += data;
		} else {
			node.insertBefore(t, before)
		}
	} else {
		node.appendChild(t)
	}
}

b.prototype.getTableMisnestedNodePosition = function() {
	// The foster parent element is the one which comes before the most
	// recently opened table element
	// XXX - this is really inelegant
	var lastTable, fosterParent, insertBefore

	for(var i = this.open_elements.length - 1; i >= 0; i--) {
		var element = this.open_elements[i]
		if(element.tagName == 'table') {
			lastTable = element
			break
		}
	}

	if(lastTable) {
		// XXX - we should check that the parent really is a node here
		if(lastTable.parentNode) {
			fosterParent = lastTable.parentNode
			insertBefore = lastTable
		} else {
			fosterParent = this.open_elements[this.open_elements.indexOf(lastTable) - 1]
		}
	} else {
		fosterParent = this.open_elements[0]
	}

	return {parent: fosterParent, insertBefore: insertBefore}
}

b.prototype.elementInScope = function(name, tableVariant) {
	HTML5.debug('treebuilder.elementInScope', name, tableVariant)
	if(this.open_elements.length == 0) return false
	if(this.open_elements.last().tagName == name) return true
	for(var i = this.open_elements.length - 1; i >= 0; i--) {
		if(this.open_elements[i].tagName == name) return true
		else if(this.open_elements[i].tagName == 'table') return false
		else if(!tableVariant && HTML5.SCOPING_ELEMENTS.indexOf(this.open_elements[i].tagName) != -1) return false
		else if(this.open_elements[i].tagName == 'html') return false;
	}
	return false;
}

b.prototype.generateImpliedEndTags = function (exclude) {
	//HTML5.debug('implied end tags with ' + sys.inspect(this.open_elements.map(function(el) { return el.tagName })));
	var name = this.open_elements.last().tagName;
	if(['dd', 'dt', 'li', 'p', 'td', 'th', 'tr'].indexOf(name) != -1 && name != exclude) {
		var p  = this.open_elements.pop();
		this.generateImpliedEndTags(exclude);
	}
}

b.prototype.reconstructActiveFormattingElements = function() {
	HTML5.debug('treebuilder.reconstructActiveFormattingElements', 'before', HTML5.dumpTagStack(this.activeFormattingElements))
	// Within this algorithm the order of steps decribed in the specification
	// is not quite the same as the order of steps in the code. It should still
	// do the same though.

	// Step 1: stop if there's nothing to do
	if(this.activeFormattingElements.length == 0) return;

	// Step 2 and 3: start with the last element
	var i = this.activeFormattingElements.length - 1;
	var entry = this.activeFormattingElements[i];
	if(entry == HTML5.Marker || this.open_elements.indexOf(entry) != -1) return;

	while(entry != HTML5.Marker && this.open_elements.indexOf(entry) == -1) {
		i -= 1;
		entry = this.activeFormattingElements[i];
		if(!entry) break;
	}

	while(true) {
		i += 1;
		var clone = this.activeFormattingElements[i].cloneNode();
		HTML5.debug('treebuilder.reconstructActiveFormattingElements', 'cloneNode', clone.tagName)

		var element = this.insert_element(clone.tagName, clone.attributes);

		this.activeFormattingElements[i] = element;

		if(element == this.activeFormattingElements.last()) break;
	}

	HTML5.debug('treebuilder.reconstructActiveFormattingElements', 'open tags are ' + HTML5.dumpTagStack(this.open_elements));
}

b.prototype.elementInActiveFormattingElements = function(name) {
	var els = this.activeFormattingElements;
	for(var i = els.length - 1; i >= 0; i--) {
		if(els[i] == HTML5.Marker) break;
		if(els[i].tagName == name) return els[i];
	}
	return false;
}

b.prototype.reparentChildren = function(o, n) {
	while(o.childNodes.length > 0) {
		var el = o.removeChild(o.childNodes[0]);
		n.appendChild(el);
	}
}

b.prototype.clearActiveFormattingElements = function() {
	HTML5.debug('treebuilder.clearActiveFormattingElements', 'before', HTML5.dumpTagStack(this.activeFormattingElements))
	while(!(this.activeFormattingElements.length == 0 || this.activeFormattingElements.pop() == HTML5.Marker));
	HTML5.debug('treebuilder.clearActiveFormattingElements', 'after', HTML5.dumpTagStack(this.activeFormattingElements))
}

b.prototype.getFragment = function() {
	// assert.ok(this.parser.inner_html)
	var fragment = this.document.createDocumentFragment()
	this.reparentChildren(this.open_elements[0], fragment)
	return fragment
}
<|endoftext|>


<commit_before>function launch(prefix, containerId) {
    var deps = [
        "element-factory.js",
        "preset-manager.js"
    ];
    var loaded = 0;
    for (var i = 0; i < deps.length; i++) {
        var elem = document.createElement('script');
        elem.src = prefix + deps[i];
        elem.onload = function() {
            if (++loaded == deps.length) {
                var container = document.getElementById(containerId);

                var canvas = yoob.makeCanvas(container, 600, 600);

                var gewgaw = new BezierKnots().init({
                    canvas: canvas,
                    lineWidth: 10,
                });

                var panel = yoob.makeDiv(container);
                var thicknessControl = yoob.makeRangeControl(panel, {
                    label: 'Line thickness:',
                    min: 1,
                    max: 20,
                    value: 5,
                    callback: function(v) {
                        gewgaw.lineWidth = v;
                        gewgaw.reset();
                    }
                });
                yoob.makeLineBreak(panel);
                var numSidesControl = yoob.makeRangeControl(panel, {
                    label: 'Number of nodes:',
                    min: 1,
                    max: 20,
                    value: 6,
                    callback: function(v) {
                        gewgaw.numSides = v;
                        gewgaw.reset();
                    }
                });
                yoob.makeLineBreak(panel);
                var numRadiiControl = yoob.makeRangeControl(panel, {
                    label: 'Number of rings:',
                    min: 1,
                    max: 20,
                    value: 6,
                    callback: function(v) {
                        gewgaw.numRadii = v;
                        gewgaw.reset();
                    }
                });
                yoob.makeLineBreak(panel);
                var resetButton = yoob.makeButton(panel, 'Reset', function() { gewgaw.reset(); });
            }
        };
        document.body.appendChild(elem);
    }
}

var QUADRANT = Math.PI / 2;
var TWO_PI = Math.PI * 2;

BezierKnots = function() {
    this.init = function(cfg) {
        this.canvas = cfg.canvas;
        this.ctx = this.canvas.getContext('2d');
        this.lineWidth = cfg.lineWidth;
        this.numSides = cfg.numSides || 6;
        this.numRadii = cfg.numRadii || 6;

        this.reset();

        return this;
    };

    this.reset = function() {
        this.ctx.fillStyle = "black";
        this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);

        this.draw();
    };

    /* Utilities */

    this.shuffled = function(a) {
        var b = [];
        while (a.length > 0) {
            b.push(a.splice(Math.random() * a.length, 1)[0]);
        }
        return b;
    };

    this.pathSegment = function(ctx, cx, cy, r1, r2, th1, th2) {
        ctx.arc(cx, cy, r1, th1, th2, false);
        ctx.arc(cx, cy, r2, th2, th1, true);
    };

    this.fillSegment = function(ctx, cx, cy, r1, r2, th1, th2) {
        ctx.beginPath();
        this.pathSegment(ctx, cx, cy, r1, r2, th1, th2);
        ctx.fill();
    };

    this.setFillColour = function(r, g, b) {
        this.ctx.fillStyle = 'rgb(' + r + ',' + g + ',' + b + ')';
    };

    this.setFillHSL = function(h, s, l) {
        if (l === -1) {
            l = 0.5 + (Math.random() - 0.5) * this.scale;
        }
        h = Math.floor(h) % 360;
        s = '' + (s * 100) + '%';
        l = '' + (l * 100) + '%';
        this.ctx.fillStyle = 'hsl(' + h + ',' + s + ',' + l + ')';
    };

    this.bezierConnect = function(x1, y1, x2, y2, x3, y3, x4, y4) {
        // the arguments represent 2 lines, (x1,y1)-(x2,y2) and (x3,y3)-(x4,y4)

        // find their midpoints:
        var xm1 = (x1 + x2) / 2;
        var ym1 = (y1 + y2) / 2;

        var xm2 = (x3 + x4) / 2;
        var ym2 = (y3 + y4) / 2;

        this.ctx.moveTo(xm1, ym1);
        this.ctx.bezierCurveTo(
            x2, y2,
            x3, y3,
            xm2, ym2);
    };

    this.bezierConnectLines = function(l1, l2) {
        // the arguments represent 2 lines, (x1,y1)-(x2,y2) and (x3,y3)-(x4,y4)

        var x1 = l1[0][0];
        var y1 = l1[0][1];

        var x2 = l1[1][0];
        var y2 = l1[1][1];

        var x3 = l2[0][0];
        var y3 = l2[0][1];

        var x4 = l2[1][0];
        var y4 = l2[1][1];

        this.bezierConnect(x1, y1, x2, y2, x3, y3, x4, y4);
    };

    this.createRandomLine = function() {
        var x1 = Math.floor(Math.random() * this.canvas.width);
        var y1 = Math.floor(Math.random() * this.canvas.height);
        var x2 = Math.floor(Math.random() * this.canvas.width);
        var y2 = Math.floor(Math.random() * this.canvas.height);
        return [[x1, y1], [x2, y2]];
    };

    this.createLine = function(cx, cy, radius, angle1, angle2) {
        var x1 = cx + Math.cos(angle1) * radius;
        var y1 = cy + Math.sin(angle1) * radius;
        var x2 = cx + Math.cos(angle2) * radius;
        var y2 = cy + Math.sin(angle2) * radius;
        return [[x1, y1], [x2, y2]];
    };

    this.createLineSets = function(cx, cy, numSides, numRadii) {
        var sets = [];

        for (var i = 0; i < numSides; i++) {
            var lines = [];

            for (var pos = 0; pos < numRadii; pos++) {
                radius = (cx / numRadii) * (pos + 1);
                lines.push(this.createLine(
                    cx, cy, radius,
                    (i / numSides) * TWO_PI - Math.PI/2,
                    ((i + 1) / numSides) * TWO_PI - Math.PI/2
                ));
            }

            sets.push(lines);
        }

        // Now shuffle the sets.
        for (var i = 0; i < sets.length; i++) {
            sets[i] = this.shuffled(sets[i]);
        }

        return sets;
    };

    this.drawLines = function(lines) {
        for (var i = 0; i < lines.length; i++) {
            var l1 = lines[i];
            var l2;

            if (i + 1 >= lines.length) {
                l2 = lines[0];
            } else {
                l2 = lines[i+1];
            }

            this.ctx.beginPath();
            this.bezierConnectLines(l1, l2);
            this.ctx.stroke();
        }
    };

    this.draw = function() {
        var cx = this.canvas.width / 2;
        var cy = this.canvas.height / 2;

        var lineSets = this.createLineSets(cx, cy, this.numSides, this.numRadii);

        var colours = ['red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'orange'];

        for (var j = 0; j < lineSets.length; j++) {

            // shuffle the indexes so we don't always draw the same colours over other colours
            var indexes = [];
            for (var i = 0; i < lineSets[j].length; i++) {
                indexes.push(i);
            }
            indexes = this.shuffled(indexes);

            for (var n = 0; n < lineSets[j].length; n++) {

                i = indexes[n];

                var l1 = lineSets[j][i];
                var l2;

                if (j + 1 >= lineSets.length) {
                    l2 = lineSets[0][i];
                } else {
                    l2 = lineSets[j+1][i];
                }

                this.ctx.strokeStyle = 'black';
                this.ctx.lineWidth = this.lineWidth + 3;

                this.ctx.beginPath();
                this.bezierConnectLines(l1, l2);
                this.ctx.stroke();

                this.ctx.strokeStyle = colours[i % colours.length];
                this.ctx.lineWidth = this.lineWidth;

                this.ctx.beginPath();
                this.bezierConnectLines(l1, l2);
                this.ctx.stroke();
            }
        }
    };
};
<commit_msg>Clean up a little bit.<commit_after>function launch(prefix, containerId) {
    var deps = [
        "element-factory.js",
        "preset-manager.js"
    ];
    var loaded = 0;
    for (var i = 0; i < deps.length; i++) {
        var elem = document.createElement('script');
        elem.src = prefix + deps[i];
        elem.onload = function() {
            if (++loaded == deps.length) {
                var container = document.getElementById(containerId);

                var canvas = yoob.makeCanvas(container, 600, 600);

                var gewgaw = new BezierKnots().init({
                    canvas: canvas,
                    lineWidth: 10,
                });

                var panel = yoob.makeDiv(container);
                var thicknessControl = yoob.makeRangeControl(panel, {
                    label: 'Line thickness:',
                    min: 1,
                    max: 30,
                    value: 10,
                    callback: function(v) {
                        gewgaw.lineWidth = v;
                        gewgaw.reset();
                    }
                });
                yoob.makeLineBreak(panel);
                var numSidesControl = yoob.makeRangeControl(panel, {
                    label: 'Number of nodes:',
                    min: 1,
                    max: 20,
                    value: 6,
                    callback: function(v) {
                        gewgaw.numSides = v;
                        gewgaw.reset();
                    }
                });
                yoob.makeLineBreak(panel);
                var numRadiiControl = yoob.makeRangeControl(panel, {
                    label: 'Number of rings:',
                    min: 1,
                    max: 20,
                    value: 6,
                    callback: function(v) {
                        gewgaw.numRadii = v;
                        gewgaw.reset();
                    }
                });
                yoob.makeLineBreak(panel);
                var resetButton = yoob.makeButton(panel, 'Reset', function() { gewgaw.reset(); });
            }
        };
        document.body.appendChild(elem);
    }
}

var QUADRANT = Math.PI / 2;
var TWO_PI = Math.PI * 2;

BezierKnots = function() {
    this.init = function(cfg) {
        this.canvas = cfg.canvas;
        this.ctx = this.canvas.getContext('2d');
        this.lineWidth = cfg.lineWidth;
        this.numSides = cfg.numSides || 6;
        this.numRadii = cfg.numRadii || 6;

        this.reset();

        return this;
    };

    this.reset = function() {
        this.ctx.fillStyle = "black";
        this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);

        this.draw();
    };

    /* Utilities */

    this.shuffled = function(a) {
        var b = [];
        while (a.length > 0) {
            b.push(a.splice(Math.random() * a.length, 1)[0]);
        }
        return b;
    };

    this.pathSegment = function(ctx, cx, cy, r1, r2, th1, th2) {
        ctx.arc(cx, cy, r1, th1, th2, false);
        ctx.arc(cx, cy, r2, th2, th1, true);
    };

    this.fillSegment = function(ctx, cx, cy, r1, r2, th1, th2) {
        ctx.beginPath();
        this.pathSegment(ctx, cx, cy, r1, r2, th1, th2);
        ctx.fill();
    };

    this.setFillColour = function(r, g, b) {
        this.ctx.fillStyle = 'rgb(' + r + ',' + g + ',' + b + ')';
    };

    this.setFillHSL = function(h, s, l) {
        if (l === -1) {
            l = 0.5 + (Math.random() - 0.5) * this.scale;
        }
        h = Math.floor(h) % 360;
        s = '' + (s * 100) + '%';
        l = '' + (l * 100) + '%';
        this.ctx.fillStyle = 'hsl(' + h + ',' + s + ',' + l + ')';
    };

    this.bezierConnect = function(x1, y1, x2, y2, x3, y3, x4, y4) {
        // the arguments represent 2 lines, (x1,y1)-(x2,y2) and (x3,y3)-(x4,y4)

        // find their midpoints:
        var xm1 = (x1 + x2) / 2;
        var ym1 = (y1 + y2) / 2;

        var xm2 = (x3 + x4) / 2;
        var ym2 = (y3 + y4) / 2;

        this.ctx.moveTo(xm1, ym1);
        this.ctx.bezierCurveTo(
            x2, y2,
            x3, y3,
            xm2, ym2);
    };

    this.bezierConnectLines = function(l1, l2) {
        // the arguments represent 2 lines, (x1,y1)-(x2,y2) and (x3,y3)-(x4,y4)

        var x1 = l1[0][0];
        var y1 = l1[0][1];

        var x2 = l1[1][0];
        var y2 = l1[1][1];

        var x3 = l2[0][0];
        var y3 = l2[0][1];

        var x4 = l2[1][0];
        var y4 = l2[1][1];

        this.bezierConnect(x1, y1, x2, y2, x3, y3, x4, y4);
    };

    this.createRandomLine = function() {
        var x1 = Math.floor(Math.random() * this.canvas.width);
        var y1 = Math.floor(Math.random() * this.canvas.height);
        var x2 = Math.floor(Math.random() * this.canvas.width);
        var y2 = Math.floor(Math.random() * this.canvas.height);
        return [[x1, y1], [x2, y2]];
    };

    this.createLine = function(cx, cy, radius, angle1, angle2) {
        var x1 = cx + Math.cos(angle1) * radius;
        var y1 = cy + Math.sin(angle1) * radius;
        var x2 = cx + Math.cos(angle2) * radius;
        var y2 = cy + Math.sin(angle2) * radius;
        return [[x1, y1], [x2, y2]];
    };

    this.createLineSets = function(cx, cy, numSides, numRadii) {
        var sets = [];

        for (var i = 0; i < numSides; i++) {
            var lines = [];

            for (var pos = 0; pos < numRadii; pos++) {
                radius = (cx / numRadii) * (pos + 1);
                lines.push(this.createLine(
                    cx, cy, radius,
                    (i / numSides) * TWO_PI - Math.PI/2,
                    ((i + 1) / numSides) * TWO_PI - Math.PI/2
                ));
            }

            sets.push(lines);
        }

        // Now shuffle the sets.
        for (var i = 0; i < sets.length; i++) {
            sets[i] = this.shuffled(sets[i]);
        }

        return sets;
    };

    this.draw = function() {
        var cx = this.canvas.width / 2;
        var cy = this.canvas.height / 2;

        var lineSets = this.createLineSets(cx, cy, this.numSides, this.numRadii);

        var colours = ['red', 'green', 'blue', 'cyan', 'magenta', 'yellow', 'orange'];

        for (var j = 0; j < lineSets.length; j++) {

            // shuffle the indexes so we don't always draw the same colours over other colours
            var indexes = [];
            for (var i = 0; i < lineSets[j].length; i++) {
                indexes.push(i);
            }
            indexes = this.shuffled(indexes);

            for (var n = 0; n < lineSets[j].length; n++) {

                i = indexes[n];

                var l1 = lineSets[j][i];
                var l2;

                if (j + 1 >= lineSets.length) {
                    l2 = lineSets[0][i];
                } else {
                    l2 = lineSets[j+1][i];
                }

                this.ctx.strokeStyle = 'black';
                this.ctx.lineWidth = this.lineWidth + 3;

                this.ctx.beginPath();
                this.bezierConnectLines(l1, l2);
                this.ctx.stroke();

                this.ctx.strokeStyle = colours[i % colours.length];
                this.ctx.lineWidth = this.lineWidth;

                this.ctx.beginPath();
                this.bezierConnectLines(l1, l2);
                this.ctx.stroke();
            }
        }
    };
};
<|endoftext|>


<commit_before>/*!
 * file upload
 * xiewulong <xiewulong@vip.qq.com>
 * create: 2015/2/27
 * version: 0.0.1
 */

(function($, window, document, undefined){
	var fileupload	= function(input, fn, prop){
			prop = prop || {};
			this.input = input;
			this.name = input.name;
			this.$input = $(input);
			this.$parent = this.$input.parent();
			this.action = prop.action || this.$input.attr('data-action');
			this.min = prop.min || this.$input.attr('data-min');
			this.max = prop.max || this.$input.attr('data-max');
			this.type = prop.type || this.$input.attr('data-type');
			this.sizes = prop.sizes || this.$input.attr('data-sizes');
			this.oss = prop.oss || this.$input.attr('data-oss');
			this.csrf = prop.csrf || this.$input.attr('data-csrf');
			this.pre = prop.pre || 'xFileupload';
			this.before = prop.before || function(){};
			this.fn = fn;

			this.input.value && this.action && this.fn && this.upload();
		};

	fileupload.prototype = {
		upload: function(){
			var _this = this;
			this.setName();
			this.createElements();
			window[_this.input.name] = function(d){_this.callback(d);};
			this.before && this.before.call(this.input, this.name);
			this.$form.submit();
		},
		createElements: function(){
			this.$iframe = $('').appendTo('body');
			this.$form = $('<form style="display:none;" action="' + this.action + '" target="' + this.input.name + '" method="post" enctype="multipart/form-data"></form>').appendTo('body');
			this.min && this.$form.append('<input type="hidden" name="min" value="' + this.min + '" />');
			this.max && this.$form.append('<input type="hidden" name="max" value="' + this.max + '" />');
			this.type && this.$form.append('<input type="hidden" name="type" value="' + this.type + '" />');
			this.sizes && this.$form.append('<input type="hidden" name="sizes" value="' + this.sizes + '" />');
			this.oss && this.$form.append('<input type="hidden" name="oss" value="' + this.oss + '" />');
			this.csrf && this.$form.append('<input type="hidden" name="_csrf" value="' + this.csrf + '" />');
			this.$form.append('<input type="hidden" name="name" value="' + this.input.name + '" />');
			this.$form.append(this.input);
		},
		setName: function(){
			var random = (+ new Date()).toString() + Math.floor(Math.random() * 899 + 100).toString();
			this.input.name = this.pre + random;
		},
		callback: function(d){
			this.input.name = this.name;
			this.input.value = '';
			this.$parent.append(this.input);
			this.$form.remove();
			this.$iframe.remove();
			this.fn.call(this.input, d);
		}
	}

	$(document).on('change', '[data-fileupload]', function(){
		new fileupload(this, function(d){
			$(this).trigger('uploaded.x.file', d);
		}, {'before': function(name){
			$(this).trigger('upload.x.file', name);
		}});
	});

	$.fn.fileupload = function(fn, prop){
		return this.on('change', function(){
			new fileupload(this, fn, prop);
		});
	};
})(jQuery, window, document);<commit_msg>fileupload<commit_after>/*!
 * file upload
 * xiewulong <xiewulong@vip.qq.com>
 * create: 2015/2/27
 * version: 0.0.1
 */

(function($, window, document, undefined){
	var fileupload	= function(input, fn, prop){
			prop = prop || {};
			this.input = input;
			this.name = input.name;
			this.$input = $(input);
			this.$parent = this.$input.parent();
			this.action = prop.action || this.$input.attr('data-action');
			this.min = prop.min || this.$input.attr('data-min');
			this.max = prop.max || this.$input.attr('data-max');
			this.type = prop.type || this.$input.attr('data-type');
			this.sizes = prop.sizes || this.$input.attr('data-sizes');
			this.oss = prop.oss || this.$input.attr('data-oss');
			this.csrf = prop.csrf || this.$input.attr('data-csrf');
			this.pre = prop.pre || 'xFileupload';
			this.before = prop.before || function(){};
			this.fn = fn;

			this.input.value && this.action && this.fn && this.upload();
		};

	fileupload.prototype = {
		upload: function(){
			var _this = this;
			this.before && this.before.call(this.input);
			this.setName();
			this.createElements();
			window[_this.input.name] = function(d){_this.callback(d);};
			this.$form.submit();
		},
		createElements: function(){
			this.$iframe = $('').appendTo('body');
			this.$form = $('<form style="display:none;" action="' + this.action + '" target="' + this.input.name + '" method="post" enctype="multipart/form-data"></form>').appendTo('body');
			this.min && this.$form.append('<input type="hidden" name="min" value="' + this.min + '" />');
			this.max && this.$form.append('<input type="hidden" name="max" value="' + this.max + '" />');
			this.type && this.$form.append('<input type="hidden" name="type" value="' + this.type + '" />');
			this.sizes && this.$form.append('<input type="hidden" name="sizes" value="' + this.sizes + '" />');
			this.oss && this.$form.append('<input type="hidden" name="oss" value="' + this.oss + '" />');
			this.csrf && this.$form.append('<input type="hidden" name="_csrf" value="' + this.csrf + '" />');
			this.$form.append('<input type="hidden" name="name" value="' + this.input.name + '" />');
			this.$form.append(this.input);
		},
		setName: function(){
			var random = (+ new Date()).toString() + Math.floor(Math.random() * 899 + 100).toString();
			this.input.name = this.pre + random;
		},
		callback: function(d){
			this.input.name = this.name;
			this.input.value = '';
			this.$parent.append(this.input);
			this.$form.remove();
			this.$iframe.remove();
			this.fn.call(this.input, d);
		}
	}

	$(document).on('change', '[data-fileupload]', function(){
		new fileupload(this, function(d){
			$(this).trigger('uploaded.x.file', d);
		}, {'before': function(name){
			$(this).trigger('upload.x.file');
		}});
	});

	$.fn.fileupload = function(fn, prop){
		return this.on('change', function(){
			new fileupload(this, fn, prop);
		});
	};
})(jQuery, window, document);<|endoftext|>


<commit_before>/**
 * ViewOnlyMenu > Service component.
 *
 * Site Kit by Google, Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';

/**
 * WordPress dependencies
 */
import { createInterpolateElement } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import { CORE_MODULES } from '../../googlesitekit/modules/datastore/constants';
import {
	CORE_USER,
	PERMISSION_AUTHENTICATE,
} from '../../googlesitekit/datastore/user/constants';
const { useSelect } = Data;

export default function Service( { module } ) {
	const canAuthenticate = useSelect( ( select ) =>
		select( CORE_USER ).hasCapability( PERMISSION_AUTHENTICATE )
	);

	const { name, owner } = useSelect( ( select ) =>
		select( CORE_MODULES ).getModule( module )
	);

	const Icon = useSelect( ( select ) =>
		select( CORE_MODULES ).getModuleIcon( module )
	);

	return (

				<Icon />

				{ name }

			{ canAuthenticate && owner?.login && (

					{ createInterpolateElement(
						sprintf(
							/* translators: %s: module owner Google Account email address */
							__(
								'Shared by %s',
								'google-site-kit'
							),
							owner.login
						),
						{
							strong: ,
						}
					) }

			) }

	);
}

Service.propTypes = {
	module: PropTypes.string.isRequired,
};
<commit_msg>Fix Idea Hub icon in View Only menu.<commit_after>/**
 * ViewOnlyMenu > Service component.
 *
 * Site Kit by Google, Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';

/**
 * WordPress dependencies
 */
import { createInterpolateElement } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';

/**
 * Internal dependencies
 */
import Data from 'googlesitekit-data';
import { CORE_MODULES } from '../../googlesitekit/modules/datastore/constants';
import {
	CORE_USER,
	PERMISSION_AUTHENTICATE,
} from '../../googlesitekit/datastore/user/constants';
const { useSelect } = Data;

export default function Service( { module } ) {
	const canAuthenticate = useSelect( ( select ) =>
		select( CORE_USER ).hasCapability( PERMISSION_AUTHENTICATE )
	);

	const { name, owner } = useSelect( ( select ) =>
		select( CORE_MODULES ).getModule( module )
	);

	const Icon = useSelect( ( select ) =>
		select( CORE_MODULES ).getModuleIcon( module )
	);

	return (

				<Icon height={ 26 } />

				{ name }

			{ canAuthenticate && owner?.login && (

					{ createInterpolateElement(
						sprintf(
							/* translators: %s: module owner Google Account email address */
							__(
								'Shared by %s',
								'google-site-kit'
							),
							owner.login
						),
						{
							strong: ,
						}
					) }

			) }

	);
}

Service.propTypes = {
	module: PropTypes.string.isRequired,
};
<|endoftext|>


<commit_before>var compassModule = angular.module("Compass", ['ui','oblique.directives','oblique.filters'])

compassModule.value('ui.config', {
   select2: {
      allowClear: true,
      width: "element",
   }
});

compassModule.controller('CompassCtrl',function CompassCtrl($scope,$http,$location) {

  $scope.state = "hidden"
  $scope.query = {
    exit_filter:"all_relays",
    links:true,
    sort:'cw',
    country: null
  }

  /** Watch the location bar to allow us to load saved searches **/
  $scope.$watch($location.search(), function(newv, oldv, scope) {
    if ($location.search().top) {
      $scope.query=$location.search()
      $scope.request()
    }
  })

  /** Make a sorting request
   *
   * Call 'success_cb' if the request is successful
   */
  $scope.ajax_sort = function(sortBy, invert, success_cb) {
    $scope.query.sort = sortBy
    $scope.query.sort_reverse = invert

    //Update the location bar to track sorting
    $location.search($scope.query)

    $http.get('result.json',{"params":$scope.query})
      .success(function(data) {
        if (data.results.length > 0) {
          $scope.data = data

          if (success_cb !== null){
            success_cb()
          }

          $('body').animate({scrollTop:$("div#result_table").offset().top},500)
        }
        else {
          $scope.state = "result_empty"
        }
      })

  }

  /**  Make a data request from the form
   *
   * Call 'success_cb' if the request is successful
   */
  $scope.request = function(success_cb) {
    $scope.state = 'loading'

    //Set the location bar for this search
    $location.search($scope.query)

    $http.get('result.json',{"params":$scope.query})
      .success(function(data) {
        if (data.results.length > 0) {
          $scope.data = data
          $scope.state = "loaded"
          if (success_cb != null){
            success_cb()
          }
          $('body').animate({scrollTop:$("div#result_table").offset().top},500)
        }
        else {
          $scope.state = "result_empty"
        }
      })
  };

  $scope.reset = function() {
    $scope.state="hidden"
  }

  $http.get("static/data/cc.json").success(function(data) {
    $scope.cc_data = data
  })

  $scope.country_select = {
    allowClear: true,
    width: "element",
  }

})
<commit_msg>Fixed a bug in initial sorting<commit_after>var compassModule = angular.module("Compass", ['ui','oblique.directives','oblique.filters'])

compassModule.value('ui.config', {
   select2: {
      allowClear: true,
      width: "element",
   }
});

compassModule.controller('CompassCtrl',function CompassCtrl($scope,$http,$location) {

  $scope.state = "hidden"
  $scope.query = {
    exit_filter:"all_relays",
    links:true,
    sort:'cw',
    sort_reverse: true,
    country: null
  }

  /** Watch the location bar to allow us to load saved searches **/
  $scope.$watch($location.search(), function(newv, oldv, scope) {
    if ($location.search().top) {
      $scope.query=$location.search()
      $scope.request()
    }
  })

  /** Make a sorting request
   *
   * Call 'success_cb' if the request is successful
   */
  $scope.ajax_sort = function(sortBy, invert, success_cb) {
    $scope.query.sort = sortBy
    $scope.query.sort_reverse = invert

    //Update the location bar to track sorting
    $location.search($scope.query)

    $http.get('result.json',{"params":$scope.query})
      .success(function(data) {
        if (data.results.length > 0) {
          $scope.data = data

          if (success_cb !== null){
            success_cb()
          }

          $('body').animate({scrollTop:$("div#result_table").offset().top},500)
        }
        else {
          $scope.state = "result_empty"
        }
      })

  }

  /**  Make a data request from the form
   *
   * Call 'success_cb' if the request is successful
   */
  $scope.request = function(success_cb) {
    $scope.state = 'loading'

    //Set the location bar for this search
    $location.search($scope.query)

    $http.get('result.json',{"params":$scope.query})
      .success(function(data) {
        if (data.results.length > 0) {
          $scope.data = data
          $scope.state = "loaded"
          if (success_cb != null){
            success_cb()
          }
          $('body').animate({scrollTop:$("div#result_table").offset().top},500)
        }
        else {
          $scope.state = "result_empty"
        }
      })
  };

  $scope.reset = function() {
    $scope.state="hidden"
  }

  $http.get("static/data/cc.json").success(function(data) {
    $scope.cc_data = data
  })

  $scope.country_select = {
    allowClear: true,
    width: "element",
  }

})
<|endoftext|>


<commit_before>/* jshint strict: true, undef: true, browser: true, jquery: true */

(function () {
    'use strict';

    $.ajax({
        type: 'get',
        url: '/challenges',
        success: function (msg) {
            render(msg);
        }
    });

    // Render links
    function render (challenges) {
        var $challengesList = $('#challengesList').empty();
        Object.keys(challenges).forEach(function (name, index) {
            var $li = $('
');
            var $a = $('')
                        .attr('href', '#')
                        .attr('data-challenge', name);
            var $h4 = $('
')
                        .text(challenges[name].title);

            $h4.appendTo($a);
            $a.appendTo($li);
            $challengesList.append($li);
        });

        // Events
        var $links          = $('[data-challenge]');
        var $allChallenges  = $('#allChallenges');
        var $oneChallenge   = $('#oneChallenge');
        var $challengeId    = $('#challengeId');
        var $challengeTitle = $('#challengeTitle');
        var $challengeDescr = $('#challengeDescr');

        $links.off('click').click(function (e) {
            e.preventDefault();

            var $self = $(this);
            var link = $self.attr('data-challenge');

            if (!link || !challenges.hasOwnProperty(link)) {
                return;
            }

            var challenge = challenges[link];

            $challengeId.val(link);
            $challengeTitle.text(challenge.title);
            $challengeDescr.text(challenge.description);

            if (challenge.id === 1) {
                $challengeDescr.html('Une page cachée ? Où ça ?');
                bindLinks();
            }

            $allChallenges.hide();
            $oneChallenge.show();
        });
    }

    render({});

    $('#checkToken').off('submit').submit(function (e) {
        e.preventDefault();
        var id = $('#challengeId').val();
        var token = $('#challengeToken').val();
        $('button[type=submit]').attr('disabled', '');
        $.ajax({
            type: 'delete',
            url: '/challenges/' + id + '/check/' + token,
            success: function (msg) {
                alert('Token validé. Points crédités : ' + msg.value);
                $('button[type=submit]').removeAttr('disabled');
            },
            error: function () {
                alert('Le token n\'est pas valide');
                $('button[type=submit]').removeAttr('disabled');
            }
        });
    });
}());
<commit_msg>Reload page on token validation<commit_after>/* jshint strict: true, undef: true, browser: true, jquery: true */

(function () {
    'use strict';

    $.ajax({
        type: 'get',
        url: '/challenges',
        success: function (msg) {
            render(msg);
        }
    });

    // Render links
    function render (challenges) {
        var $challengesList = $('#challengesList').empty();
        Object.keys(challenges).forEach(function (name, index) {
            var $li = $('
');
            var $a = $('')
                        .attr('href', '#')
                        .attr('data-challenge', name);
            var $h4 = $('
')
                        .text(challenges[name].title);

            $h4.appendTo($a);
            $a.appendTo($li);
            $challengesList.append($li);
        });

        // Events
        var $links          = $('[data-challenge]');
        var $allChallenges  = $('#allChallenges');
        var $oneChallenge   = $('#oneChallenge');
        var $challengeId    = $('#challengeId');
        var $challengeTitle = $('#challengeTitle');
        var $challengeDescr = $('#challengeDescr');

        $links.off('click').click(function (e) {
            e.preventDefault();

            var $self = $(this);
            var link = $self.attr('data-challenge');

            if (!link || !challenges.hasOwnProperty(link)) {
                return;
            }

            var challenge = challenges[link];

            $challengeId.val(link);
            $challengeTitle.text(challenge.title);
            $challengeDescr.text(challenge.description);

            if (challenge.id === 1) {
                $challengeDescr.html('Une page cachée ? Où ça ?');
                bindLinks();
            }

            $allChallenges.hide();
            $oneChallenge.show();
        });
    }

    render({});

    $('#checkToken').off('submit').submit(function (e) {
        e.preventDefault();
        var id = $('#challengeId').val();
        var token = $('#challengeToken').val();
        $('button[type=submit]').attr('disabled', '');
        $.ajax({
            type: 'delete',
            url: '/challenges/' + id + '/check/' + token,
            success: function (msg) {
                alert('Token validé. Points crédités : ' + msg.value);
                $('button[type=submit]').removeAttr('disabled');
                location.reload();
            },
            error: function () {
                alert('Le token n\'est pas valide');
                $('button[type=submit]').removeAttr('disabled');
            }
        });
    });
}());
<|endoftext|>


<commit_before>/*
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { useRef, useEffect } from 'react';

/**
 * Internal dependencies
 */
import getCaretCharacterOffsetWithin from '../../utils/getCaretCharacterOffsetWithin';
import { useStory } from '../../app';
import { useCanvas } from '../../components/canvas';
import { useUnits } from '../../units';
import {
  elementFillContent,
  elementWithFont,
  elementWithTextParagraphStyle,
} from '../shared';
import StoryPropTypes from '../../types';
import { generateParagraphTextStyle } from './util';

const Element = styled.p`
  ${elementFillContent}
  ${elementWithFont}
  ${elementWithTextParagraphStyle}

	opacity: 0;
  user-select: none;
`;

function TextFrame({ element: { id, content, ...rest }, wrapperRef }) {
  const {
    actions: { dataToEditorX, dataToEditorY },
  } = useUnits();
  const props = generateParagraphTextStyle(rest, dataToEditorX, dataToEditorY);
  const {
    state: { selectedElementIds },
  } = useStory();

  const {
    actions: { setEditingElementWithState },
  } = useCanvas();
  const isElementSelected = selectedElementIds.includes(id);
  const isElementOnlySelection =
    isElementSelected && selectedElementIds.length === 1;

  const elementRef = useRef();

  useEffect(() => {
    if (!isElementOnlySelection) {
      return undefined;
    }

    const wrapper = wrapperRef.current;
    const element = elementRef.current;

    let clickTime = 0;

    const handleKeyDown = (evt) => {
      if (evt.metaKey || evt.altKey || evt.ctrlKey) {
        // Some modifier (except shift) was pressed. Ignore and bubble
        return;
      }

      if (evt.key === 'Enter') {
        // Enter editing without writing or selecting anything
        setEditingElementWithState(id, { selectAll: true });
        evt.stopPropagation();
        // Make sure no actual Enter is pressed
        evt.preventDefault();
      } else if (/^\w$/.test(evt.key)) {
        // TODO: in above check all printable characters across alphabets, no just a-z0-9 as \w is
        // Enter editing and clear content (first letter will be correctly inserted from keyup)
        setEditingElementWithState(id, { clearContent: true });
        evt.stopPropagation();
      }
    };

    const handleMouseDown = () => {
      clickTime = window.performance.now();
    };

    const handleMouseUp = (evt) => {
      const timingDifference = window.performance.now() - clickTime;

      if (timingDifference > 300) {
        // Only short clicks count.
        return;
      }

      // Enter editing mode and place cursor at current selection offset
      evt.stopPropagation();
      setEditingElementWithState(id, {
        offset: getCaretCharacterOffsetWithin(
          elementRef.current,
          evt.clientX,
          evt.clientY
        ),
      });
    };

    wrapper.addEventListener('keydown', handleKeyDown);
    element.addEventListener('mousedown', handleMouseDown);
    element.addEventListener('mouseup', handleMouseUp);
    return () => {
      wrapper.removeEventListener('keydown', handleKeyDown);
      element.removeEventListener('mousedown', handleMouseDown);
      element.removeEventListener('mouseup', handleMouseUp);
    };
  }, [id, wrapperRef, isElementOnlySelection, setEditingElementWithState]);

  return (
    <Element
      ref={elementRef}
      dangerouslySetInnerHTML={{ __html: content }}
      {...props}
    />
  );
}

TextFrame.propTypes = {
  element: StoryPropTypes.elements.text.isRequired,
  wrapperRef: PropTypes.object.isRequired,
};

export default TextFrame;
<commit_msg>Reduce timing difference for entering edit mode. (#829)<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { useRef, useEffect } from 'react';

/**
 * Internal dependencies
 */
import getCaretCharacterOffsetWithin from '../../utils/getCaretCharacterOffsetWithin';
import { useStory } from '../../app';
import { useCanvas } from '../../components/canvas';
import { useUnits } from '../../units';
import {
  elementFillContent,
  elementWithFont,
  elementWithTextParagraphStyle,
} from '../shared';
import StoryPropTypes from '../../types';
import { generateParagraphTextStyle } from './util';

const Element = styled.p`
  ${elementFillContent}
  ${elementWithFont}
  ${elementWithTextParagraphStyle}

	opacity: 0;
  user-select: none;
`;

function TextFrame({ element: { id, content, ...rest }, wrapperRef }) {
  const {
    actions: { dataToEditorX, dataToEditorY },
  } = useUnits();
  const props = generateParagraphTextStyle(rest, dataToEditorX, dataToEditorY);
  const {
    state: { selectedElementIds },
  } = useStory();

  const {
    actions: { setEditingElementWithState },
  } = useCanvas();
  const isElementSelected = selectedElementIds.includes(id);
  const isElementOnlySelection =
    isElementSelected && selectedElementIds.length === 1;

  const elementRef = useRef();

  useEffect(() => {
    if (!isElementOnlySelection) {
      return undefined;
    }

    const wrapper = wrapperRef.current;
    const element = elementRef.current;

    let clickTime = 0;

    const handleKeyDown = (evt) => {
      if (evt.metaKey || evt.altKey || evt.ctrlKey) {
        // Some modifier (except shift) was pressed. Ignore and bubble
        return;
      }

      if (evt.key === 'Enter') {
        // Enter editing without writing or selecting anything
        setEditingElementWithState(id, { selectAll: true });
        evt.stopPropagation();
        // Make sure no actual Enter is pressed
        evt.preventDefault();
      } else if (/^\w$/.test(evt.key)) {
        // TODO: in above check all printable characters across alphabets, no just a-z0-9 as \w is
        // Enter editing and clear content (first letter will be correctly inserted from keyup)
        setEditingElementWithState(id, { clearContent: true });
        evt.stopPropagation();
      }
    };

    const handleMouseDown = () => {
      clickTime = window.performance.now();
    };

    const handleMouseUp = (evt) => {
      const timingDifference = window.performance.now() - clickTime;

      if (timingDifference > 150) {
        // Only short clicks count.
        return;
      }

      // Enter editing mode and place cursor at current selection offset
      evt.stopPropagation();
      setEditingElementWithState(id, {
        offset: getCaretCharacterOffsetWithin(
          elementRef.current,
          evt.clientX,
          evt.clientY
        ),
      });
    };

    wrapper.addEventListener('keydown', handleKeyDown);
    element.addEventListener('mousedown', handleMouseDown);
    element.addEventListener('mouseup', handleMouseUp);
    return () => {
      wrapper.removeEventListener('keydown', handleKeyDown);
      element.removeEventListener('mousedown', handleMouseDown);
      element.removeEventListener('mouseup', handleMouseUp);
    };
  }, [id, wrapperRef, isElementOnlySelection, setEditingElementWithState]);

  return (
    <Element
      ref={elementRef}
      dangerouslySetInnerHTML={{ __html: content }}
      {...props}
    />
  );
}

TextFrame.propTypes = {
  element: StoryPropTypes.elements.text.isRequired,
  wrapperRef: PropTypes.object.isRequired,
};

export default TextFrame;
<|endoftext|>


<commit_before>/*function for moving characters (class interviewee, ids:interviewee1,interviewee2,interviewee3)*/
var quotes = [
    "The main problem I have with my job is that IT support is terrible. It used to be the case that the department was in the same building, and you knew you could walk in or call them up and speak to the same people you spoke to last time. A bottle of wine at Christmas kept them happy and I always got things fixed in time. Now it is some random person half the world away that doesn't know me from Adam. Not having that personal relationship makes things more difficult and everything takes twice as long to get fixed. This can be a real problem when the boss is under pressure and the latest round of password changes has locked me out of his email account.",
    "I have been re-hired to do the same job, at the same level of pay, but without benefits. It doesn't make me happy but there are no other decent IT jobs going in this area, so I have to do it. Unfortunately they know this too and so we don’t get treated like we did when I worked here properly. It doesn't help that with all the shuffling around no-one knows each other anymore. We all have to wear badges now, use passwords everywhere, walk through checkpoints like we are at the airport every time we want to go to the toilet. That’s what it seems like to me anyway. I walk all over the building fixing computers and stuff and the atmosphere really has changed.",
    "My job sounds fancier than it is, I don’t really manage anyone, just look after some clients. Have the mergers affected me? I suppose so. It got pretty confusing for a while, who was working on what and who was allowed to see the info I have on our customers. It seemed to take ages to get any changes made to permissions but we have always had a few tricks to deal with that. The merger didn’t make that side of things worse, but for a while you never know who you would be working with from one week to the next. I am glad it has settled down now, I am starting to get friendly with my new team and that makes work go a little easier."
];

charactersModel = {
    currentQuote: ko.observable(0),
    interviewee1DeviceImage: ko.observable('static/img/laptop.png'),
    interviewee2DeviceImage: ko.observable('static/img/desktop.png'),
    interviewee3DeviceImage: ko.observable('static/img/phone.png'),
    quote1: ko.observable(''),
    quote2: ko.observable(''),
    quote3: ko.observable(''),
    interviewee1Location: ko.observable(''),
    interviewee2Location: ko.observable(''),
    interviewee3Location: ko.observable('')
};

var coordinates = {};
coordinates.interviewee1 = {}; //Susie
coordinates.interviewee2 = {}; //Kevin
coordinates.interviewee3 = {}; //Iza

coordinates.interviewee1.home = [40, 55, 55];
coordinates.interviewee1.public = [55, 40, 20];
coordinates.interviewee1.office = [15, 80, 20];

coordinates.interviewee2.home = [47.5, 47.5, 55];
coordinates.interviewee2.public = [62.5, 32.5, 20];
coordinates.interviewee2.office = [22.5, 72.5, 20];

coordinates.interviewee3.home = [55, 40, 55];
coordinates.interviewee3.public = [70, 25, 20];
coordinates.interviewee3.office = [30, 65, 20];

function placeDiv(div_id, l_pos, r_pos, b_pos) {
    var d = document.getElementById(div_id);
    d.style.left = (l_pos) + '%';
    d.style.right = (r_pos) + '%';
    d.style.bottom = (b_pos) + '%';

    if ($('#' + div_id).attr('id').substr(0, 5) === 'quote') {
        var t_pos = 100 - b_pos - 20;
        d.style.top = (t_pos) + '%';
    }
}

function placeAt(div_id, place) {
    var l = coordinates[div_id][place][0];
    var r = coordinates[div_id][place][1];
    var b = coordinates[div_id][place][2];
    placeDiv(div_id, l, r, b);                                        //update character position
    placeDiv('quote' + div_id.substr(div_id.length - 1), l - 12.5, r + 12.5, b + 18);  //update position of his speech bubble
}

function giveDevice(div_id, device) {
    charactersModel[div_id + 'DeviceImage']('static/img/' + device + '.png');
}

function updateCharacters(date) { //data: interviewee1 - location, device; interviewee2 - loc, dev; interviewee3 - loc, dev
    $.ajax({
        url: "api/characters",
        type: "POST",
        data: JSON.stringify({date:date}),
        success: function (data) {
            $.each(data, function (key, value) {
                placeAt(key, value[0]);       //e.g.: placeAt('interviewee2', 'office');
                giveDevice(key, value[1]);    //e.g.: giveDevice('interviewee1, 'phone');
                charactersModel[key + 'Location'](value[0]); //e.g. charactersModel.interviewee1Location(office)

                var charSet= ['executives','desk','road'];
                for (var k in timelineModel.calendar()){
                    var event = timelineModel.calendar()[k]['events'];
                    for (var ev in event){
                        for (var em in charSet){
                            var i = parseFloat(em)+1;
                            //assign event for each character's quote from the calendar
                            if((event[ev].employee==charSet[em])){
                               if(event[ev].device + '.png'== (charactersModel['interviewee'+i+ 'DeviceImage']()).replace("static/img/","") ){
                                   if(event[ev].location == charactersModel['interviewee'+i+ 'Location']()){
                                        $.ajax({
                                        url: "api/incident/"+event[ev].incdt_id,
                                        type: "GET",
                                        success: function (incidnt) {
                                            charactersModel['quote'+i](incidnt.description); //executive, road or desk
                                            $('#interviewee'+i).click();
                                        },
                                        error: function (response) {
                                            console.log("fail: " + response.responseText);
                                        }
                                        });
                                   }
                               }
                            }
                        }
                    }
                }
            });
        },
        error: function (response) {
            console.log("fail: " + response.responseText);
        }
    });
}

$("#interviewee1").click(function () {
    if (charactersModel.currentQuote() === 1) {
        charactersModel.currentQuote(0);
    } else {
        charactersModel.currentQuote(1);
    }
});
$("#interviewee2").click(function () {
    if (charactersModel.currentQuote() === 2) {
        charactersModel.currentQuote(0);
    } else {
        charactersModel.currentQuote(2);
    }
});
$("#interviewee3").click(function () {
    if (charactersModel.currentQuote() === 3) {
        charactersModel.currentQuote(0);
    } else {
        charactersModel.currentQuote(3);
    }
});

$(document).click(function (e) {
    if (e.target.className !== 'interviewee') {
        charactersModel.currentQuote(0);
    }
});

$(function () {
    charactersModel.quote1(quotes[0]);
    charactersModel.quote2(quotes[1]);
    charactersModel.quote3(quotes[2]);
});<commit_msg>characters quotes as incidents update<commit_after>/*function for moving characters (class interviewee, ids:interviewee1,interviewee2,interviewee3)*/
var quotes = [
    "The main problem I have with my job is that IT support is terrible. It used to be the case that the department was in the same building, and you knew you could walk in or call them up and speak to the same people you spoke to last time. A bottle of wine at Christmas kept them happy and I always got things fixed in time. Now it is some random person half the world away that doesn't know me from Adam. Not having that personal relationship makes things more difficult and everything takes twice as long to get fixed. This can be a real problem when the boss is under pressure and the latest round of password changes has locked me out of his email account.",
    "I have been re-hired to do the same job, at the same level of pay, but without benefits. It doesn't make me happy but there are no other decent IT jobs going in this area, so I have to do it. Unfortunately they know this too and so we don’t get treated like we did when I worked here properly. It doesn't help that with all the shuffling around no-one knows each other anymore. We all have to wear badges now, use passwords everywhere, walk through checkpoints like we are at the airport every time we want to go to the toilet. That’s what it seems like to me anyway. I walk all over the building fixing computers and stuff and the atmosphere really has changed.",
    "My job sounds fancier than it is, I don’t really manage anyone, just look after some clients. Have the mergers affected me? I suppose so. It got pretty confusing for a while, who was working on what and who was allowed to see the info I have on our customers. It seemed to take ages to get any changes made to permissions but we have always had a few tricks to deal with that. The merger didn’t make that side of things worse, but for a while you never know who you would be working with from one week to the next. I am glad it has settled down now, I am starting to get friendly with my new team and that makes work go a little easier."
];

charactersModel = {
    currentQuote: ko.observable(0),
    interviewee1DeviceImage: ko.observable('static/img/laptop.png'),
    interviewee2DeviceImage: ko.observable('static/img/desktop.png'),
    interviewee3DeviceImage: ko.observable('static/img/phone.png'),
    quote1: ko.observable(''),
    quote2: ko.observable(''),
    quote3: ko.observable(''),
    interviewee1Location: ko.observable(''),
    interviewee2Location: ko.observable(''),
    interviewee3Location: ko.observable('')
};

var coordinates = {};
coordinates.interviewee1 = {}; //Susie
coordinates.interviewee2 = {}; //Kevin
coordinates.interviewee3 = {}; //Iza

coordinates.interviewee1.home = [40, 55, 55];
coordinates.interviewee1.public = [55, 40, 20];
coordinates.interviewee1.office = [15, 80, 20];

coordinates.interviewee2.home = [47.5, 47.5, 55];
coordinates.interviewee2.public = [62.5, 32.5, 20];
coordinates.interviewee2.office = [22.5, 72.5, 20];

coordinates.interviewee3.home = [55, 40, 55];
coordinates.interviewee3.public = [70, 25, 20];
coordinates.interviewee3.office = [30, 65, 20];

function placeDiv(div_id, l_pos, r_pos, b_pos) {
    var d = document.getElementById(div_id);
    d.style.left = (l_pos) + '%';
    d.style.right = (r_pos) + '%';
    d.style.bottom = (b_pos) + '%';

    if ($('#' + div_id).attr('id').substr(0, 5) === 'quote') {
        var t_pos = 100 - b_pos - 20;
        d.style.top = (t_pos) + '%';
    }
}

function placeAt(div_id, place) {
    var l = coordinates[div_id][place][0];
    var r = coordinates[div_id][place][1];
    var b = coordinates[div_id][place][2];
    placeDiv(div_id, l, r, b);                                        //update character position
    placeDiv('quote' + div_id.substr(div_id.length - 1), l - 12.5, r + 12.5, b + 18);  //update position of his speech bubble
}

function giveDevice(div_id, device) {
    charactersModel[div_id + 'DeviceImage']('static/img/' + device + '.png');
}

function updateCharacters(date) { //data: interviewee1 - location, device; interviewee2 - loc, dev; interviewee3 - loc, dev
    $.ajax({
        url: "api/characters",
        type: "POST",
        data: JSON.stringify({date:date}),
        success: function (data) {
            $.each(data, function (key, value) {
                placeAt(key, value[0]);       //e.g.: placeAt('interviewee2', 'office');
                giveDevice(key, value[1]);    //e.g.: giveDevice('interviewee1, 'phone');
                charactersModel[key + 'Location'](value[0]); //e.g. charactersModel.interviewee1Location(office)

                var charSet= ['executives','desk','road'];
                for (var k in timelineModel.calendar()){
                    var event = timelineModel.calendar()[k]['events'];
                    for (var ev in event){
                        for (var em in charSet){
                            var i = parseFloat(em)+1;
                            //assign event for each character's quote from the calendar
                            if((event[ev].employee==charSet[em])){
                               if(event[ev].device + '.png'== (charactersModel['interviewee'+i+ 'DeviceImage']()).replace("static/img/","") ){
                                   if(event[ev].location == charactersModel['interviewee'+i+ 'Location']()){
                                        $.ajax({
                                        url: "api/incident/"+event[ev].incdt_id,
                                        type: "GET",
                                        async:false, //had to set to async:false, as if it is async, em and i variable keep incrementing while the request is sent
                                        success: function (incidnt) {
                                            charactersModel['quote'+i](incidnt.description); //executive, road or desk
                                            $('#interviewee'+i).click();
                                        },
                                        error: function (response) {
                                            console.log("fail: " + response.responseText);
                                        }
                                        });
                                   }
                               }
                            }
                        }
                    }
                }
            });
        },
        error: function (response) {
            console.log("fail: " + response.responseText);
        }
    });
}

$("#interviewee1").click(function () {
    if (charactersModel.currentQuote() === 1) {
        charactersModel.currentQuote(0);
    } else {
        charactersModel.currentQuote(1);
    }
});
$("#interviewee2").click(function () {
    if (charactersModel.currentQuote() === 2) {
        charactersModel.currentQuote(0);
    } else {
        charactersModel.currentQuote(2);
    }
});
$("#interviewee3").click(function () {
    if (charactersModel.currentQuote() === 3) {
        charactersModel.currentQuote(0);
    } else {
        charactersModel.currentQuote(3);
    }
});

$(document).click(function (e) {
    if (e.target.className !== 'interviewee') {
        charactersModel.currentQuote(0);
    }
});

$(function () {
    charactersModel.quote1(quotes[0]);
    charactersModel.quote2(quotes[1]);
    charactersModel.quote3(quotes[2]);
});<|endoftext|>


<commit_before>/*
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Internal dependencies
 */
import { FULLBLEED_RATIO, PAGE_RATIO } from '../../constants';
import theme from '../../theme';

function CustomStyles() {
  const safeToFullRatio = PAGE_RATIO / FULLBLEED_RATIO;
  const fullToSafeRatio = 1 / safeToFullRatio;
  // Match page background color to the workspace background color.
  const pageBackgroundColor = theme.colors.bg.workspace;
  return (
    <style
      amp-custom=""
      dangerouslySetInnerHTML={{
        __html: `
              amp-story-page {
                background-color: ${pageBackgroundColor};
              }

              amp-story-grid-layer {
                overflow: visible;
              }

              .page-fullbleed-area,
              .page-background-overlay-area {
                position: absolute;
                overflow: hidden;
                width: 100%;
                left: 0;
                height: calc(${safeToFullRatio} * 100%);
                top: calc((1 - ${safeToFullRatio}) * 100% / 2);
              }

              .page-safe-area {
                overflow: visible;
                position: absolute;
                top: 0;
                bottom: 0;
                left: 0;
                right: 0;
                width: 100%;
                height: calc(${fullToSafeRatio} * 100%);
                margin: auto 0;
              }

              .mask {
                position: absolute;
                overflow: hidden;
              }

              .fill {
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                margin: 0;
              }
              `,
      }}
    />
  );
}

export default CustomStyles;
<commit_msg>Add overkill XSS protection.<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Internal dependencies
 */
import { FULLBLEED_RATIO, PAGE_RATIO } from '../../constants';
import theme from '../../theme';

const HEX_CHARS = '1234567890ABCDEF';

function isHexColorString(s) {
  return (
    s[0] == '#' &&
    s
      .substr(1)
      .split('')
      .every((char) => HEX_CHARS.includes(char))
  );
}

function CustomStyles() {
  const safeToFullRatio = PAGE_RATIO / FULLBLEED_RATIO;
  const fullToSafeRatio = 1 / safeToFullRatio;

  // Match page background color to the workspace background color.
  // Validate since we're using dangerouslySetInnerHTML with imported variable.
  const workspaceColor = theme.colors.bg.workspace;
  let pageBackgroundColor = isHexColorString(workspaceColor)
    ? workspaceColor
    : '#1B1D1C';

  return (
    <style
      amp-custom=""
      dangerouslySetInnerHTML={{
        __html: `
              amp-story-page {
                background-color: ${pageBackgroundColor};
              }

              amp-story-grid-layer {
                overflow: visible;
              }

              .page-fullbleed-area,
              .page-background-overlay-area {
                position: absolute;
                overflow: hidden;
                width: 100%;
                left: 0;
                height: calc(${safeToFullRatio} * 100%);
                top: calc((1 - ${safeToFullRatio}) * 100% / 2);
              }

              .page-safe-area {
                overflow: visible;
                position: absolute;
                top: 0;
                bottom: 0;
                left: 0;
                right: 0;
                width: 100%;
                height: calc(${fullToSafeRatio} * 100%);
                margin: auto 0;
              }

              .mask {
                position: absolute;
                overflow: hidden;
              }

              .fill {
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                margin: 0;
              }
              `,
      }}
    />
  );
}

export default CustomStyles;
<|endoftext|>