aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Embedded_SW
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Embedded_SW')
-rw-r--r--Software/Embedded_SW/.jxbrowser-data/Cache/data_0bin45056 -> 45056 bytes
-rw-r--r--Software/Embedded_SW/.jxbrowser-data/Cache/data_1bin270336 -> 270336 bytes
-rw-r--r--Software/Embedded_SW/.jxbrowser-data/Cache/data_2bin1056768 -> 1056768 bytes
-rw-r--r--Software/Embedded_SW/.jxbrowser-data/Cache/data_3bin4202496 -> 4202496 bytes
-rw-r--r--Software/Embedded_SW/.jxbrowser-data/Cache/f_00000a4662
-rw-r--r--Software/Embedded_SW/.jxbrowser-data/Cache/f_00000e599
-rw-r--r--Software/Embedded_SW/.jxbrowser-data/Cache/f_00000f536
-rw-r--r--Software/Embedded_SW/.jxbrowser-data/Cache/indexbin524656 -> 524656 bytes
-rw-r--r--Software/Embedded_SW/.jxbrowser-data/GPUCache/data_1bin270336 -> 270336 bytes
-rw-r--r--Software/Embedded_SW/.jxbrowser-data/Historybin110592 -> 94208 bytes
-rw-r--r--Software/Embedded_SW/.jxbrowser-data/Local Storage - EXT/http_127.0.0.1.localstorage6
-rw-r--r--Software/Embedded_SW/.jxbrowser-data/Login Databin24576 -> 18432 bytes
-rw-r--r--Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c1
-rw-r--r--Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c2
-rw-r--r--Software/Embedded_SW/Embedded/DataDef.h6
-rw-r--r--Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c52
-rw-r--r--Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_GPIO/FPGA_GPIO.c2
-rw-r--r--Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.c38
-rw-r--r--Software/Embedded_SW/Embedded/Drivers/FPGA/Moters_Driver/PowerSTEP01.h168
-rw-r--r--Software/Embedded_SW/Embedded/Drivers/I2C_Communication/ADC_MUX/ADC_MUX.c44
-rw-r--r--Software/Embedded_SW/Embedded/Drivers/I2C_Communication/ADC_MUX/ADC_MUX.h5
-rw-r--r--Software/Embedded_SW/Embedded/Drivers/SPI/SPI_Comm.c3
-rw-r--r--Software/Embedded_SW/Embedded/Drivers/SSI_Comm/Dancer/Dancer.c4
-rw-r--r--Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c29
-rw-r--r--Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.h4
-rw-r--r--Software/Embedded_SW/Embedded/Embedded.cfg2
-rw-r--r--Software/Embedded_SW/Embedded/Main.c4
-rw-r--r--Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c31
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c169
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.h8
-rw-r--r--Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c12
-rw-r--r--Software/Embedded_SW/Embedded/Modules/General/process.c21
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_ex.h1
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c4
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c191
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c33
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h1
-rw-r--r--Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c16
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.c7
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Thread/Thread_init.c10
-rw-r--r--Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c17
-rw-r--r--Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c19
42 files changed, 6555 insertions, 152 deletions
diff --git a/Software/Embedded_SW/.jxbrowser-data/Cache/data_0 b/Software/Embedded_SW/.jxbrowser-data/Cache/data_0
index 72da15f27..2695bfe60 100644
--- a/Software/Embedded_SW/.jxbrowser-data/Cache/data_0
+++ b/Software/Embedded_SW/.jxbrowser-data/Cache/data_0
Binary files differ
diff --git a/Software/Embedded_SW/.jxbrowser-data/Cache/data_1 b/Software/Embedded_SW/.jxbrowser-data/Cache/data_1
index d09ddd8f9..a837bff36 100644
--- a/Software/Embedded_SW/.jxbrowser-data/Cache/data_1
+++ b/Software/Embedded_SW/.jxbrowser-data/Cache/data_1
Binary files differ
diff --git a/Software/Embedded_SW/.jxbrowser-data/Cache/data_2 b/Software/Embedded_SW/.jxbrowser-data/Cache/data_2
index f77d1a73c..e3d7d7fe8 100644
--- a/Software/Embedded_SW/.jxbrowser-data/Cache/data_2
+++ b/Software/Embedded_SW/.jxbrowser-data/Cache/data_2
Binary files differ
diff --git a/Software/Embedded_SW/.jxbrowser-data/Cache/data_3 b/Software/Embedded_SW/.jxbrowser-data/Cache/data_3
index e128b103c..dd5978d30 100644
--- a/Software/Embedded_SW/.jxbrowser-data/Cache/data_3
+++ b/Software/Embedded_SW/.jxbrowser-data/Cache/data_3
Binary files differ
diff --git a/Software/Embedded_SW/.jxbrowser-data/Cache/f_00000a b/Software/Embedded_SW/.jxbrowser-data/Cache/f_00000a
new file mode 100644
index 000000000..b7a05571e
--- /dev/null
+++ b/Software/Embedded_SW/.jxbrowser-data/Cache/f_00000a
@@ -0,0 +1,4662 @@
+<!--
+@license
+Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+--><link rel="import" href="polymer-mini.html">
+
+
+
+<script>Polymer.nar = [];
+Polymer.Annotations = {
+parseAnnotations: function (template) {
+var list = [];
+var content = template._content || template.content;
+this._parseNodeAnnotations(content, list, template.hasAttribute('strip-whitespace'));
+return list;
+},
+_parseNodeAnnotations: function (node, list, stripWhiteSpace) {
+return node.nodeType === Node.TEXT_NODE ? this._parseTextNodeAnnotation(node, list) : this._parseElementAnnotations(node, list, stripWhiteSpace);
+},
+_bindingRegex: function () {
+var IDENT = '(?:' + '[a-zA-Z_$][\\w.:$-*]*' + ')';
+var NUMBER = '(?:' + '[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?' + ')';
+var SQUOTE_STRING = '(?:' + '\'(?:[^\'\\\\]|\\\\.)*\'' + ')';
+var DQUOTE_STRING = '(?:' + '"(?:[^"\\\\]|\\\\.)*"' + ')';
+var STRING = '(?:' + SQUOTE_STRING + '|' + DQUOTE_STRING + ')';
+var ARGUMENT = '(?:' + IDENT + '|' + NUMBER + '|' + STRING + '\\s*' + ')';
+var ARGUMENTS = '(?:' + ARGUMENT + '(?:,\\s*' + ARGUMENT + ')*' + ')';
+var ARGUMENT_LIST = '(?:' + '\\(\\s*' + '(?:' + ARGUMENTS + '?' + ')' + '\\)\\s*' + ')';
+var BINDING = '(' + IDENT + '\\s*' + ARGUMENT_LIST + '?' + ')';
+var OPEN_BRACKET = '(\\[\\[|{{)' + '\\s*';
+var CLOSE_BRACKET = '(?:]]|}})';
+var NEGATE = '(?:(!)\\s*)?';
+var EXPRESSION = OPEN_BRACKET + NEGATE + BINDING + CLOSE_BRACKET;
+return new RegExp(EXPRESSION, 'g');
+}(),
+_parseBindings: function (text) {
+var re = this._bindingRegex;
+var parts = [];
+var lastIndex = 0;
+var m;
+while ((m = re.exec(text)) !== null) {
+if (m.index > lastIndex) {
+parts.push({ literal: text.slice(lastIndex, m.index) });
+}
+var mode = m[1][0];
+var negate = Boolean(m[2]);
+var value = m[3].trim();
+var customEvent, notifyEvent, colon;
+if (mode == '{' && (colon = value.indexOf('::')) > 0) {
+notifyEvent = value.substring(colon + 2);
+value = value.substring(0, colon);
+customEvent = true;
+}
+parts.push({
+compoundIndex: parts.length,
+value: value,
+mode: mode,
+negate: negate,
+event: notifyEvent,
+customEvent: customEvent
+});
+lastIndex = re.lastIndex;
+}
+if (lastIndex && lastIndex < text.length) {
+var literal = text.substring(lastIndex);
+if (literal) {
+parts.push({ literal: literal });
+}
+}
+if (parts.length) {
+return parts;
+}
+},
+_literalFromParts: function (parts) {
+var s = '';
+for (var i = 0; i < parts.length; i++) {
+var literal = parts[i].literal;
+s += literal || '';
+}
+return s;
+},
+_parseTextNodeAnnotation: function (node, list) {
+var parts = this._parseBindings(node.textContent);
+if (parts) {
+node.textContent = this._literalFromParts(parts) || ' ';
+var annote = {
+bindings: [{
+kind: 'text',
+name: 'textContent',
+parts: parts,
+isCompound: parts.length !== 1
+}]
+};
+list.push(annote);
+return annote;
+}
+},
+_parseElementAnnotations: function (element, list, stripWhiteSpace) {
+var annote = {
+bindings: [],
+events: []
+};
+if (element.localName === 'content') {
+list._hasContent = true;
+}
+this._parseChildNodesAnnotations(element, annote, list, stripWhiteSpace);
+if (element.attributes) {
+this._parseNodeAttributeAnnotations(element, annote, list);
+if (this.prepElement) {
+this.prepElement(element);
+}
+}
+if (annote.bindings.length || annote.events.length || annote.id) {
+list.push(annote);
+}
+return annote;
+},
+_parseChildNodesAnnotations: function (root, annote, list, stripWhiteSpace) {
+if (root.firstChild) {
+var node = root.firstChild;
+var i = 0;
+while (node) {
+var next = node.nextSibling;
+if (node.localName === 'template' && !node.hasAttribute('preserve-content')) {
+this._parseTemplate(node, i, list, annote);
+}
+if (node.nodeType === Node.TEXT_NODE) {
+var n = next;
+while (n && n.nodeType === Node.TEXT_NODE) {
+node.textContent += n.textContent;
+next = n.nextSibling;
+root.removeChild(n);
+n = next;
+}
+if (stripWhiteSpace && !node.textContent.trim()) {
+root.removeChild(node);
+i--;
+}
+}
+if (node.parentNode) {
+var childAnnotation = this._parseNodeAnnotations(node, list, stripWhiteSpace);
+if (childAnnotation) {
+childAnnotation.parent = annote;
+childAnnotation.index = i;
+}
+}
+node = next;
+i++;
+}
+}
+},
+_parseTemplate: function (node, index, list, parent) {
+var content = document.createDocumentFragment();
+content._notes = this.parseAnnotations(node);
+content.appendChild(node.content);
+list.push({
+bindings: Polymer.nar,
+events: Polymer.nar,
+templateContent: content,
+parent: parent,
+index: index
+});
+},
+_parseNodeAttributeAnnotations: function (node, annotation) {
+var attrs = Array.prototype.slice.call(node.attributes);
+for (var i = attrs.length - 1, a; a = attrs[i]; i--) {
+var n = a.name;
+var v = a.value;
+var b;
+if (n.slice(0, 3) === 'on-') {
+node.removeAttribute(n);
+annotation.events.push({
+name: n.slice(3),
+value: v
+});
+} else if (b = this._parseNodeAttributeAnnotation(node, n, v)) {
+annotation.bindings.push(b);
+} else if (n === 'id') {
+annotation.id = v;
+}
+}
+},
+_parseNodeAttributeAnnotation: function (node, name, value) {
+var parts = this._parseBindings(value);
+if (parts) {
+var origName = name;
+var kind = 'property';
+if (name[name.length - 1] == '$') {
+name = name.slice(0, -1);
+kind = 'attribute';
+}
+var literal = this._literalFromParts(parts);
+if (literal && kind == 'attribute') {
+node.setAttribute(name, literal);
+}
+if (node.localName === 'input' && origName === 'value') {
+node.setAttribute(origName, '');
+}
+node.removeAttribute(origName);
+if (kind === 'property') {
+name = Polymer.CaseMap.dashToCamelCase(name);
+}
+return {
+kind: kind,
+name: name,
+parts: parts,
+literal: literal,
+isCompound: parts.length !== 1
+};
+}
+},
+findAnnotatedNode: function (root, annote) {
+var parent = annote.parent && Polymer.Annotations.findAnnotatedNode(root, annote.parent);
+if (parent) {
+for (var n = parent.firstChild, i = 0; n; n = n.nextSibling) {
+if (annote.index === i++) {
+return n;
+}
+}
+} else {
+return root;
+}
+}
+};
+(function () {
+function resolveCss(cssText, ownerDocument) {
+return cssText.replace(CSS_URL_RX, function (m, pre, url, post) {
+return pre + '\'' + resolve(url.replace(/["']/g, ''), ownerDocument) + '\'' + post;
+});
+}
+function resolveAttrs(element, ownerDocument) {
+for (var name in URL_ATTRS) {
+var a$ = URL_ATTRS[name];
+for (var i = 0, l = a$.length, a, at, v; i < l && (a = a$[i]); i++) {
+if (name === '*' || element.localName === name) {
+at = element.attributes[a];
+v = at && at.value;
+if (v && v.search(BINDING_RX) < 0) {
+at.value = a === 'style' ? resolveCss(v, ownerDocument) : resolve(v, ownerDocument);
+}
+}
+}
+}
+}
+function resolve(url, ownerDocument) {
+if (url && url[0] === '#') {
+return url;
+}
+var resolver = getUrlResolver(ownerDocument);
+resolver.href = url;
+return resolver.href || url;
+}
+var tempDoc;
+var tempDocBase;
+function resolveUrl(url, baseUri) {
+if (!tempDoc) {
+tempDoc = document.implementation.createHTMLDocument('temp');
+tempDocBase = tempDoc.createElement('base');
+tempDoc.head.appendChild(tempDocBase);
+}
+tempDocBase.href = baseUri;
+return resolve(url, tempDoc);
+}
+function getUrlResolver(ownerDocument) {
+return ownerDocument.__urlResolver || (ownerDocument.__urlResolver = ownerDocument.createElement('a'));
+}
+var CSS_URL_RX = /(url\()([^)]*)(\))/g;
+var URL_ATTRS = {
+'*': [
+'href',
+'src',
+'style',
+'url'
+],
+form: ['action']
+};
+var BINDING_RX = /\{\{|\[\[/;
+Polymer.ResolveUrl = {
+resolveCss: resolveCss,
+resolveAttrs: resolveAttrs,
+resolveUrl: resolveUrl
+};
+}());
+Polymer.Base._addFeature({
+_prepAnnotations: function () {
+if (!this._template) {
+this._notes = [];
+} else {
+var self = this;
+Polymer.Annotations.prepElement = function (element) {
+self._prepElement(element);
+};
+if (this._template._content && this._template._content._notes) {
+this._notes = this._template._content._notes;
+} else {
+this._notes = Polymer.Annotations.parseAnnotations(this._template);
+this._processAnnotations(this._notes);
+}
+Polymer.Annotations.prepElement = null;
+}
+},
+_processAnnotations: function (notes) {
+for (var i = 0; i < notes.length; i++) {
+var note = notes[i];
+for (var j = 0; j < note.bindings.length; j++) {
+var b = note.bindings[j];
+for (var k = 0; k < b.parts.length; k++) {
+var p = b.parts[k];
+if (!p.literal) {
+p.signature = this._parseMethod(p.value);
+if (!p.signature) {
+p.model = this._modelForPath(p.value);
+}
+}
+}
+}
+if (note.templateContent) {
+this._processAnnotations(note.templateContent._notes);
+var pp = note.templateContent._parentProps = this._discoverTemplateParentProps(note.templateContent._notes);
+var bindings = [];
+for (var prop in pp) {
+bindings.push({
+index: note.index,
+kind: 'property',
+name: '_parent_' + prop,
+parts: [{
+mode: '{',
+model: prop,
+value: prop
+}]
+});
+}
+note.bindings = note.bindings.concat(bindings);
+}
+}
+},
+_discoverTemplateParentProps: function (notes) {
+var pp = {};
+for (var i = 0, n; i < notes.length && (n = notes[i]); i++) {
+for (var j = 0, b$ = n.bindings, b; j < b$.length && (b = b$[j]); j++) {
+for (var k = 0, p$ = b.parts, p; k < p$.length && (p = p$[k]); k++) {
+if (p.signature) {
+var args = p.signature.args;
+for (var kk = 0; kk < args.length; kk++) {
+var model = args[kk].model;
+if (model) {
+pp[model] = true;
+}
+}
+} else {
+if (p.model) {
+pp[p.model] = true;
+}
+}
+}
+}
+if (n.templateContent) {
+var tpp = n.templateContent._parentProps;
+Polymer.Base.mixin(pp, tpp);
+}
+}
+return pp;
+},
+_prepElement: function (element) {
+Polymer.ResolveUrl.resolveAttrs(element, this._template.ownerDocument);
+},
+_findAnnotatedNode: Polymer.Annotations.findAnnotatedNode,
+_marshalAnnotationReferences: function () {
+if (this._template) {
+this._marshalIdNodes();
+this._marshalAnnotatedNodes();
+this._marshalAnnotatedListeners();
+}
+},
+_configureAnnotationReferences: function (config) {
+var notes = this._notes;
+var nodes = this._nodes;
+for (var i = 0; i < notes.length; i++) {
+var note = notes[i];
+var node = nodes[i];
+this._configureTemplateContent(note, node);
+this._configureCompoundBindings(note, node);
+}
+},
+_configureTemplateContent: function (note, node) {
+if (note.templateContent) {
+node._content = note.templateContent;
+}
+},
+_configureCompoundBindings: function (note, node) {
+var bindings = note.bindings;
+for (var i = 0; i < bindings.length; i++) {
+var binding = bindings[i];
+if (binding.isCompound) {
+var storage = node.__compoundStorage__ || (node.__compoundStorage__ = {});
+var parts = binding.parts;
+var literals = new Array(parts.length);
+for (var j = 0; j < parts.length; j++) {
+literals[j] = parts[j].literal;
+}
+var name = binding.name;
+storage[name] = literals;
+if (binding.literal && binding.kind == 'property') {
+if (node._configValue) {
+node._configValue(name, binding.literal);
+} else {
+node[name] = binding.literal;
+}
+}
+}
+}
+},
+_marshalIdNodes: function () {
+this.$ = {};
+for (var i = 0, l = this._notes.length, a; i < l && (a = this._notes[i]); i++) {
+if (a.id) {
+this.$[a.id] = this._findAnnotatedNode(this.root, a);
+}
+}
+},
+_marshalAnnotatedNodes: function () {
+if (this._notes && this._notes.length) {
+var r = new Array(this._notes.length);
+for (var i = 0; i < this._notes.length; i++) {
+r[i] = this._findAnnotatedNode(this.root, this._notes[i]);
+}
+this._nodes = r;
+}
+},
+_marshalAnnotatedListeners: function () {
+for (var i = 0, l = this._notes.length, a; i < l && (a = this._notes[i]); i++) {
+if (a.events && a.events.length) {
+var node = this._findAnnotatedNode(this.root, a);
+for (var j = 0, e$ = a.events, e; j < e$.length && (e = e$[j]); j++) {
+this.listen(node, e.name, e.value);
+}
+}
+}
+}
+});
+Polymer.Base._addFeature({
+listeners: {},
+_listenListeners: function (listeners) {
+var node, name, eventName;
+for (eventName in listeners) {
+if (eventName.indexOf('.') < 0) {
+node = this;
+name = eventName;
+} else {
+name = eventName.split('.');
+node = this.$[name[0]];
+name = name[1];
+}
+this.listen(node, name, listeners[eventName]);
+}
+},
+listen: function (node, eventName, methodName) {
+var handler = this._recallEventHandler(this, eventName, node, methodName);
+if (!handler) {
+handler = this._createEventHandler(node, eventName, methodName);
+}
+if (handler._listening) {
+return;
+}
+this._listen(node, eventName, handler);
+handler._listening = true;
+},
+_boundListenerKey: function (eventName, methodName) {
+return eventName + ':' + methodName;
+},
+_recordEventHandler: function (host, eventName, target, methodName, handler) {
+var hbl = host.__boundListeners;
+if (!hbl) {
+hbl = host.__boundListeners = new WeakMap();
+}
+var bl = hbl.get(target);
+if (!bl) {
+bl = {};
+hbl.set(target, bl);
+}
+var key = this._boundListenerKey(eventName, methodName);
+bl[key] = handler;
+},
+_recallEventHandler: function (host, eventName, target, methodName) {
+var hbl = host.__boundListeners;
+if (!hbl) {
+return;
+}
+var bl = hbl.get(target);
+if (!bl) {
+return;
+}
+var key = this._boundListenerKey(eventName, methodName);
+return bl[key];
+},
+_createEventHandler: function (node, eventName, methodName) {
+var host = this;
+var handler = function (e) {
+if (host[methodName]) {
+host[methodName](e, e.detail);
+} else {
+host._warn(host._logf('_createEventHandler', 'listener method `' + methodName + '` not defined'));
+}
+};
+handler._listening = false;
+this._recordEventHandler(host, eventName, node, methodName, handler);
+return handler;
+},
+unlisten: function (node, eventName, methodName) {
+var handler = this._recallEventHandler(this, eventName, node, methodName);
+if (handler) {
+this._unlisten(node, eventName, handler);
+handler._listening = false;
+}
+},
+_listen: function (node, eventName, handler) {
+node.addEventListener(eventName, handler);
+},
+_unlisten: function (node, eventName, handler) {
+node.removeEventListener(eventName, handler);
+}
+});
+(function () {
+'use strict';
+var wrap = Polymer.DomApi.wrap;
+var HAS_NATIVE_TA = typeof document.head.style.touchAction === 'string';
+var GESTURE_KEY = '__polymerGestures';
+var HANDLED_OBJ = '__polymerGesturesHandled';
+var TOUCH_ACTION = '__polymerGesturesTouchAction';
+var TAP_DISTANCE = 25;
+var TRACK_DISTANCE = 5;
+var TRACK_LENGTH = 2;
+var MOUSE_TIMEOUT = 2500;
+var MOUSE_EVENTS = [
+'mousedown',
+'mousemove',
+'mouseup',
+'click'
+];
+var MOUSE_WHICH_TO_BUTTONS = [
+0,
+1,
+4,
+2
+];
+var MOUSE_HAS_BUTTONS = function () {
+try {
+return new MouseEvent('test', { buttons: 1 }).buttons === 1;
+} catch (e) {
+return false;
+}
+}();
+var IS_TOUCH_ONLY = navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);
+var mouseCanceller = function (mouseEvent) {
+mouseEvent[HANDLED_OBJ] = { skip: true };
+if (mouseEvent.type === 'click') {
+var path = Polymer.dom(mouseEvent).path;
+for (var i = 0; i < path.length; i++) {
+if (path[i] === POINTERSTATE.mouse.target) {
+return;
+}
+}
+mouseEvent.preventDefault();
+mouseEvent.stopPropagation();
+}
+};
+function setupTeardownMouseCanceller(setup) {
+for (var i = 0, en; i < MOUSE_EVENTS.length; i++) {
+en = MOUSE_EVENTS[i];
+if (setup) {
+document.addEventListener(en, mouseCanceller, true);
+} else {
+document.removeEventListener(en, mouseCanceller, true);
+}
+}
+}
+function ignoreMouse() {
+if (IS_TOUCH_ONLY) {
+return;
+}
+if (!POINTERSTATE.mouse.mouseIgnoreJob) {
+setupTeardownMouseCanceller(true);
+}
+var unset = function () {
+setupTeardownMouseCanceller();
+POINTERSTATE.mouse.target = null;
+POINTERSTATE.mouse.mouseIgnoreJob = null;
+};
+POINTERSTATE.mouse.mouseIgnoreJob = Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob, unset, MOUSE_TIMEOUT);
+}
+function hasLeftMouseButton(ev) {
+var type = ev.type;
+if (MOUSE_EVENTS.indexOf(type) === -1) {
+return false;
+}
+if (type === 'mousemove') {
+var buttons = ev.buttons === undefined ? 1 : ev.buttons;
+if (ev instanceof window.MouseEvent && !MOUSE_HAS_BUTTONS) {
+buttons = MOUSE_WHICH_TO_BUTTONS[ev.which] || 0;
+}
+return Boolean(buttons & 1);
+} else {
+var button = ev.button === undefined ? 0 : ev.button;
+return button === 0;
+}
+}
+function isSyntheticClick(ev) {
+if (ev.type === 'click') {
+if (ev.detail === 0) {
+return true;
+}
+var t = Gestures.findOriginalTarget(ev);
+var bcr = t.getBoundingClientRect();
+var x = ev.pageX, y = ev.pageY;
+return !(x >= bcr.left && x <= bcr.right && (y >= bcr.top && y <= bcr.bottom));
+}
+return false;
+}
+var POINTERSTATE = {
+mouse: {
+target: null,
+mouseIgnoreJob: null
+},
+touch: {
+x: 0,
+y: 0,
+id: -1,
+scrollDecided: false
+}
+};
+function firstTouchAction(ev) {
+var path = Polymer.dom(ev).path;
+var ta = 'auto';
+for (var i = 0, n; i < path.length; i++) {
+n = path[i];
+if (n[TOUCH_ACTION]) {
+ta = n[TOUCH_ACTION];
+break;
+}
+}
+return ta;
+}
+function trackDocument(stateObj, movefn, upfn) {
+stateObj.movefn = movefn;
+stateObj.upfn = upfn;
+document.addEventListener('mousemove', movefn);
+document.addEventListener('mouseup', upfn);
+}
+function untrackDocument(stateObj) {
+document.removeEventListener('mousemove', stateObj.movefn);
+document.removeEventListener('mouseup', stateObj.upfn);
+stateObj.movefn = null;
+stateObj.upfn = null;
+}
+var Gestures = {
+gestures: {},
+recognizers: [],
+deepTargetFind: function (x, y) {
+var node = document.elementFromPoint(x, y);
+var next = node;
+while (next && next.shadowRoot) {
+next = next.shadowRoot.elementFromPoint(x, y);
+if (next) {
+node = next;
+}
+}
+return node;
+},
+findOriginalTarget: function (ev) {
+if (ev.path) {
+return ev.path[0];
+}
+return ev.target;
+},
+handleNative: function (ev) {
+var handled;
+var type = ev.type;
+var node = wrap(ev.currentTarget);
+var gobj = node[GESTURE_KEY];
+if (!gobj) {
+return;
+}
+var gs = gobj[type];
+if (!gs) {
+return;
+}
+if (!ev[HANDLED_OBJ]) {
+ev[HANDLED_OBJ] = {};
+if (type.slice(0, 5) === 'touch') {
+var t = ev.changedTouches[0];
+if (type === 'touchstart') {
+if (ev.touches.length === 1) {
+POINTERSTATE.touch.id = t.identifier;
+}
+}
+if (POINTERSTATE.touch.id !== t.identifier) {
+return;
+}
+if (!HAS_NATIVE_TA) {
+if (type === 'touchstart' || type === 'touchmove') {
+Gestures.handleTouchAction(ev);
+}
+}
+if (type === 'touchend') {
+POINTERSTATE.mouse.target = Polymer.dom(ev).rootTarget;
+ignoreMouse(true);
+}
+}
+}
+handled = ev[HANDLED_OBJ];
+if (handled.skip) {
+return;
+}
+var recognizers = Gestures.recognizers;
+for (var i = 0, r; i < recognizers.length; i++) {
+r = recognizers[i];
+if (gs[r.name] && !handled[r.name]) {
+if (r.flow && r.flow.start.indexOf(ev.type) > -1) {
+if (r.reset) {
+r.reset();
+}
+}
+}
+}
+for (var i = 0, r; i < recognizers.length; i++) {
+r = recognizers[i];
+if (gs[r.name] && !handled[r.name]) {
+handled[r.name] = true;
+r[type](ev);
+}
+}
+},
+handleTouchAction: function (ev) {
+var t = ev.changedTouches[0];
+var type = ev.type;
+if (type === 'touchstart') {
+POINTERSTATE.touch.x = t.clientX;
+POINTERSTATE.touch.y = t.clientY;
+POINTERSTATE.touch.scrollDecided = false;
+} else if (type === 'touchmove') {
+if (POINTERSTATE.touch.scrollDecided) {
+return;
+}
+POINTERSTATE.touch.scrollDecided = true;
+var ta = firstTouchAction(ev);
+var prevent = false;
+var dx = Math.abs(POINTERSTATE.touch.x - t.clientX);
+var dy = Math.abs(POINTERSTATE.touch.y - t.clientY);
+if (!ev.cancelable) {
+} else if (ta === 'none') {
+prevent = true;
+} else if (ta === 'pan-x') {
+prevent = dy > dx;
+} else if (ta === 'pan-y') {
+prevent = dx > dy;
+}
+if (prevent) {
+ev.preventDefault();
+} else {
+Gestures.prevent('track');
+}
+}
+},
+add: function (node, evType, handler) {
+node = wrap(node);
+var recognizer = this.gestures[evType];
+var deps = recognizer.deps;
+var name = recognizer.name;
+var gobj = node[GESTURE_KEY];
+if (!gobj) {
+node[GESTURE_KEY] = gobj = {};
+}
+for (var i = 0, dep, gd; i < deps.length; i++) {
+dep = deps[i];
+if (IS_TOUCH_ONLY && MOUSE_EVENTS.indexOf(dep) > -1) {
+continue;
+}
+gd = gobj[dep];
+if (!gd) {
+gobj[dep] = gd = { _count: 0 };
+}
+if (gd._count === 0) {
+node.addEventListener(dep, this.handleNative);
+}
+gd[name] = (gd[name] || 0) + 1;
+gd._count = (gd._count || 0) + 1;
+}
+node.addEventListener(evType, handler);
+if (recognizer.touchAction) {
+this.setTouchAction(node, recognizer.touchAction);
+}
+},
+remove: function (node, evType, handler) {
+node = wrap(node);
+var recognizer = this.gestures[evType];
+var deps = recognizer.deps;
+var name = recognizer.name;
+var gobj = node[GESTURE_KEY];
+if (gobj) {
+for (var i = 0, dep, gd; i < deps.length; i++) {
+dep = deps[i];
+gd = gobj[dep];
+if (gd && gd[name]) {
+gd[name] = (gd[name] || 1) - 1;
+gd._count = (gd._count || 1) - 1;
+if (gd._count === 0) {
+node.removeEventListener(dep, this.handleNative);
+}
+}
+}
+}
+node.removeEventListener(evType, handler);
+},
+register: function (recog) {
+this.recognizers.push(recog);
+for (var i = 0; i < recog.emits.length; i++) {
+this.gestures[recog.emits[i]] = recog;
+}
+},
+findRecognizerByEvent: function (evName) {
+for (var i = 0, r; i < this.recognizers.length; i++) {
+r = this.recognizers[i];
+for (var j = 0, n; j < r.emits.length; j++) {
+n = r.emits[j];
+if (n === evName) {
+return r;
+}
+}
+}
+return null;
+},
+setTouchAction: function (node, value) {
+if (HAS_NATIVE_TA) {
+node.style.touchAction = value;
+}
+node[TOUCH_ACTION] = value;
+},
+fire: function (target, type, detail) {
+var ev = Polymer.Base.fire(type, detail, {
+node: target,
+bubbles: true,
+cancelable: true
+});
+if (ev.defaultPrevented) {
+var se = detail.sourceEvent;
+if (se && se.preventDefault) {
+se.preventDefault();
+}
+}
+},
+prevent: function (evName) {
+var recognizer = this.findRecognizerByEvent(evName);
+if (recognizer.info) {
+recognizer.info.prevent = true;
+}
+}
+};
+Gestures.register({
+name: 'downup',
+deps: [
+'mousedown',
+'touchstart',
+'touchend'
+],
+flow: {
+start: [
+'mousedown',
+'touchstart'
+],
+end: [
+'mouseup',
+'touchend'
+]
+},
+emits: [
+'down',
+'up'
+],
+info: {
+movefn: null,
+upfn: null
+},
+reset: function () {
+untrackDocument(this.info);
+},
+mousedown: function (e) {
+if (!hasLeftMouseButton(e)) {
+return;
+}
+var t = Gestures.findOriginalTarget(e);
+var self = this;
+var movefn = function movefn(e) {
+if (!hasLeftMouseButton(e)) {
+self.fire('up', t, e);
+untrackDocument(self.info);
+}
+};
+var upfn = function upfn(e) {
+if (hasLeftMouseButton(e)) {
+self.fire('up', t, e);
+}
+untrackDocument(self.info);
+};
+trackDocument(this.info, movefn, upfn);
+this.fire('down', t, e);
+},
+touchstart: function (e) {
+this.fire('down', Gestures.findOriginalTarget(e), e.changedTouches[0]);
+},
+touchend: function (e) {
+this.fire('up', Gestures.findOriginalTarget(e), e.changedTouches[0]);
+},
+fire: function (type, target, event) {
+Gestures.fire(target, type, {
+x: event.clientX,
+y: event.clientY,
+sourceEvent: event,
+prevent: function (e) {
+return Gestures.prevent(e);
+}
+});
+}
+});
+Gestures.register({
+name: 'track',
+touchAction: 'none',
+deps: [
+'mousedown',
+'touchstart',
+'touchmove',
+'touchend'
+],
+flow: {
+start: [
+'mousedown',
+'touchstart'
+],
+end: [
+'mouseup',
+'touchend'
+]
+},
+emits: ['track'],
+info: {
+x: 0,
+y: 0,
+state: 'start',
+started: false,
+moves: [],
+addMove: function (move) {
+if (this.moves.length > TRACK_LENGTH) {
+this.moves.shift();
+}
+this.moves.push(move);
+},
+movefn: null,
+upfn: null,
+prevent: false
+},
+reset: function () {
+this.info.state = 'start';
+this.info.started = false;
+this.info.moves = [];
+this.info.x = 0;
+this.info.y = 0;
+this.info.prevent = false;
+untrackDocument(this.info);
+},
+hasMovedEnough: function (x, y) {
+if (this.info.prevent) {
+return false;
+}
+if (this.info.started) {
+return true;
+}
+var dx = Math.abs(this.info.x - x);
+var dy = Math.abs(this.info.y - y);
+return dx >= TRACK_DISTANCE || dy >= TRACK_DISTANCE;
+},
+mousedown: function (e) {
+if (!hasLeftMouseButton(e)) {
+return;
+}
+var t = Gestures.findOriginalTarget(e);
+var self = this;
+var movefn = function movefn(e) {
+var x = e.clientX, y = e.clientY;
+if (self.hasMovedEnough(x, y)) {
+self.info.state = self.info.started ? e.type === 'mouseup' ? 'end' : 'track' : 'start';
+self.info.addMove({
+x: x,
+y: y
+});
+if (!hasLeftMouseButton(e)) {
+self.info.state = 'end';
+untrackDocument(self.info);
+}
+self.fire(t, e);
+self.info.started = true;
+}
+};
+var upfn = function upfn(e) {
+if (self.info.started) {
+Gestures.prevent('tap');
+movefn(e);
+}
+untrackDocument(self.info);
+};
+trackDocument(this.info, movefn, upfn);
+this.info.x = e.clientX;
+this.info.y = e.clientY;
+},
+touchstart: function (e) {
+var ct = e.changedTouches[0];
+this.info.x = ct.clientX;
+this.info.y = ct.clientY;
+},
+touchmove: function (e) {
+var t = Gestures.findOriginalTarget(e);
+var ct = e.changedTouches[0];
+var x = ct.clientX, y = ct.clientY;
+if (this.hasMovedEnough(x, y)) {
+this.info.addMove({
+x: x,
+y: y
+});
+this.fire(t, ct);
+this.info.state = 'track';
+this.info.started = true;
+}
+},
+touchend: function (e) {
+var t = Gestures.findOriginalTarget(e);
+var ct = e.changedTouches[0];
+if (this.info.started) {
+Gestures.prevent('tap');
+this.info.state = 'end';
+this.info.addMove({
+x: ct.clientX,
+y: ct.clientY
+});
+this.fire(t, ct);
+}
+},
+fire: function (target, touch) {
+var secondlast = this.info.moves[this.info.moves.length - 2];
+var lastmove = this.info.moves[this.info.moves.length - 1];
+var dx = lastmove.x - this.info.x;
+var dy = lastmove.y - this.info.y;
+var ddx, ddy = 0;
+if (secondlast) {
+ddx = lastmove.x - secondlast.x;
+ddy = lastmove.y - secondlast.y;
+}
+return Gestures.fire(target, 'track', {
+state: this.info.state,
+x: touch.clientX,
+y: touch.clientY,
+dx: dx,
+dy: dy,
+ddx: ddx,
+ddy: ddy,
+sourceEvent: touch,
+hover: function () {
+return Gestures.deepTargetFind(touch.clientX, touch.clientY);
+}
+});
+}
+});
+Gestures.register({
+name: 'tap',
+deps: [
+'mousedown',
+'click',
+'touchstart',
+'touchend'
+],
+flow: {
+start: [
+'mousedown',
+'touchstart'
+],
+end: [
+'click',
+'touchend'
+]
+},
+emits: ['tap'],
+info: {
+x: NaN,
+y: NaN,
+prevent: false
+},
+reset: function () {
+this.info.x = NaN;
+this.info.y = NaN;
+this.info.prevent = false;
+},
+save: function (e) {
+this.info.x = e.clientX;
+this.info.y = e.clientY;
+},
+mousedown: function (e) {
+if (hasLeftMouseButton(e)) {
+this.save(e);
+}
+},
+click: function (e) {
+if (hasLeftMouseButton(e)) {
+this.forward(e);
+}
+},
+touchstart: function (e) {
+this.save(e.changedTouches[0]);
+},
+touchend: function (e) {
+this.forward(e.changedTouches[0]);
+},
+forward: function (e) {
+var dx = Math.abs(e.clientX - this.info.x);
+var dy = Math.abs(e.clientY - this.info.y);
+var t = Gestures.findOriginalTarget(e);
+if (isNaN(dx) || isNaN(dy) || dx <= TAP_DISTANCE && dy <= TAP_DISTANCE || isSyntheticClick(e)) {
+if (!this.info.prevent) {
+Gestures.fire(t, 'tap', {
+x: e.clientX,
+y: e.clientY,
+sourceEvent: e
+});
+}
+}
+}
+});
+var DIRECTION_MAP = {
+x: 'pan-x',
+y: 'pan-y',
+none: 'none',
+all: 'auto'
+};
+Polymer.Base._addFeature({
+_setupGestures: function () {
+this.__polymerGestures = null;
+},
+_listen: function (node, eventName, handler) {
+if (Gestures.gestures[eventName]) {
+Gestures.add(node, eventName, handler);
+} else {
+node.addEventListener(eventName, handler);
+}
+},
+_unlisten: function (node, eventName, handler) {
+if (Gestures.gestures[eventName]) {
+Gestures.remove(node, eventName, handler);
+} else {
+node.removeEventListener(eventName, handler);
+}
+},
+setScrollDirection: function (direction, node) {
+node = node || this;
+Gestures.setTouchAction(node, DIRECTION_MAP[direction] || 'auto');
+}
+});
+Polymer.Gestures = Gestures;
+}());
+Polymer.Base._addFeature({
+$$: function (slctr) {
+return Polymer.dom(this.root).querySelector(slctr);
+},
+toggleClass: function (name, bool, node) {
+node = node || this;
+if (arguments.length == 1) {
+bool = !node.classList.contains(name);
+}
+if (bool) {
+Polymer.dom(node).classList.add(name);
+} else {
+Polymer.dom(node).classList.remove(name);
+}
+},
+toggleAttribute: function (name, bool, node) {
+node = node || this;
+if (arguments.length == 1) {
+bool = !node.hasAttribute(name);
+}
+if (bool) {
+Polymer.dom(node).setAttribute(name, '');
+} else {
+Polymer.dom(node).removeAttribute(name);
+}
+},
+classFollows: function (name, toElement, fromElement) {
+if (fromElement) {
+Polymer.dom(fromElement).classList.remove(name);
+}
+if (toElement) {
+Polymer.dom(toElement).classList.add(name);
+}
+},
+attributeFollows: function (name, toElement, fromElement) {
+if (fromElement) {
+Polymer.dom(fromElement).removeAttribute(name);
+}
+if (toElement) {
+Polymer.dom(toElement).setAttribute(name, '');
+}
+},
+getEffectiveChildNodes: function () {
+return Polymer.dom(this).getEffectiveChildNodes();
+},
+getEffectiveChildren: function () {
+var list = Polymer.dom(this).getEffectiveChildNodes();
+return list.filter(function (n) {
+return n.nodeType === Node.ELEMENT_NODE;
+});
+},
+getEffectiveTextContent: function () {
+var cn = this.getEffectiveChildNodes();
+var tc = [];
+for (var i = 0, c; c = cn[i]; i++) {
+if (c.nodeType !== Node.COMMENT_NODE) {
+tc.push(Polymer.dom(c).textContent);
+}
+}
+return tc.join('');
+},
+queryEffectiveChildren: function (slctr) {
+var e$ = Polymer.dom(this).queryDistributedElements(slctr);
+return e$ && e$[0];
+},
+queryAllEffectiveChildren: function (slctr) {
+return Polymer.dom(this).queryDistributedElements(slctr);
+},
+getContentChildNodes: function (slctr) {
+var content = Polymer.dom(this.root).querySelector(slctr || 'content');
+return content ? Polymer.dom(content).getDistributedNodes() : [];
+},
+getContentChildren: function (slctr) {
+return this.getContentChildNodes(slctr).filter(function (n) {
+return n.nodeType === Node.ELEMENT_NODE;
+});
+},
+fire: function (type, detail, options) {
+options = options || Polymer.nob;
+var node = options.node || this;
+var detail = detail === null || detail === undefined ? {} : detail;
+var bubbles = options.bubbles === undefined ? true : options.bubbles;
+var cancelable = Boolean(options.cancelable);
+var useCache = options._useCache;
+var event = this._getEvent(type, bubbles, cancelable, useCache);
+event.detail = detail;
+if (useCache) {
+this.__eventCache[type] = null;
+}
+node.dispatchEvent(event);
+if (useCache) {
+this.__eventCache[type] = event;
+}
+return event;
+},
+__eventCache: {},
+_getEvent: function (type, bubbles, cancelable, useCache) {
+var event = useCache && this.__eventCache[type];
+if (!event || (event.bubbles != bubbles || event.cancelable != cancelable)) {
+event = new Event(type, {
+bubbles: Boolean(bubbles),
+cancelable: cancelable
+});
+}
+return event;
+},
+async: function (callback, waitTime) {
+var self = this;
+return Polymer.Async.run(function () {
+callback.call(self);
+}, waitTime);
+},
+cancelAsync: function (handle) {
+Polymer.Async.cancel(handle);
+},
+arrayDelete: function (path, item) {
+var index;
+if (Array.isArray(path)) {
+index = path.indexOf(item);
+if (index >= 0) {
+return path.splice(index, 1);
+}
+} else {
+var arr = this._get(path);
+index = arr.indexOf(item);
+if (index >= 0) {
+return this.splice(path, index, 1);
+}
+}
+},
+transform: function (transform, node) {
+node = node || this;
+node.style.webkitTransform = transform;
+node.style.transform = transform;
+},
+translate3d: function (x, y, z, node) {
+node = node || this;
+this.transform('translate3d(' + x + ',' + y + ',' + z + ')', node);
+},
+importHref: function (href, onload, onerror, optAsync) {
+var l = document.createElement('link');
+l.rel = 'import';
+l.href = href;
+optAsync = Boolean(optAsync);
+if (optAsync) {
+l.setAttribute('async', '');
+}
+var self = this;
+if (onload) {
+l.onload = function (e) {
+return onload.call(self, e);
+};
+}
+if (onerror) {
+l.onerror = function (e) {
+return onerror.call(self, e);
+};
+}
+document.head.appendChild(l);
+return l;
+},
+create: function (tag, props) {
+var elt = document.createElement(tag);
+if (props) {
+for (var n in props) {
+elt[n] = props[n];
+}
+}
+return elt;
+},
+isLightDescendant: function (node) {
+return this !== node && this.contains(node) && Polymer.dom(this).getOwnerRoot() === Polymer.dom(node).getOwnerRoot();
+},
+isLocalDescendant: function (node) {
+return this.root === Polymer.dom(node).getOwnerRoot();
+}
+});
+Polymer.Bind = {
+_dataEventCache: {},
+prepareModel: function (model) {
+Polymer.Base.mixin(model, this._modelApi);
+},
+_modelApi: {
+_notifyChange: function (source, event, value) {
+value = value === undefined ? this[source] : value;
+event = event || Polymer.CaseMap.camelToDashCase(source) + '-changed';
+this.fire(event, { value: value }, {
+bubbles: false,
+cancelable: false,
+_useCache: true
+});
+},
+_propertySetter: function (property, value, effects, fromAbove) {
+var old = this.__data__[property];
+if (old !== value && (old === old || value === value)) {
+this.__data__[property] = value;
+if (typeof value == 'object') {
+this._clearPath(property);
+}
+if (this._propertyChanged) {
+this._propertyChanged(property, value, old);
+}
+if (effects) {
+this._effectEffects(property, value, effects, old, fromAbove);
+}
+}
+return old;
+},
+__setProperty: function (property, value, quiet, node) {
+node = node || this;
+var effects = node._propertyEffects && node._propertyEffects[property];
+if (effects) {
+node._propertySetter(property, value, effects, quiet);
+} else {
+node[property] = value;
+}
+},
+_effectEffects: function (property, value, effects, old, fromAbove) {
+for (var i = 0, l = effects.length, fx; i < l && (fx = effects[i]); i++) {
+fx.fn.call(this, property, value, fx.effect, old, fromAbove);
+}
+},
+_clearPath: function (path) {
+for (var prop in this.__data__) {
+if (prop.indexOf(path + '.') === 0) {
+this.__data__[prop] = undefined;
+}
+}
+}
+},
+ensurePropertyEffects: function (model, property) {
+if (!model._propertyEffects) {
+model._propertyEffects = {};
+}
+var fx = model._propertyEffects[property];
+if (!fx) {
+fx = model._propertyEffects[property] = [];
+}
+return fx;
+},
+addPropertyEffect: function (model, property, kind, effect) {
+var fx = this.ensurePropertyEffects(model, property);
+var propEffect = {
+kind: kind,
+effect: effect,
+fn: Polymer.Bind['_' + kind + 'Effect']
+};
+fx.push(propEffect);
+return propEffect;
+},
+createBindings: function (model) {
+var fx$ = model._propertyEffects;
+if (fx$) {
+for (var n in fx$) {
+var fx = fx$[n];
+fx.sort(this._sortPropertyEffects);
+this._createAccessors(model, n, fx);
+}
+}
+},
+_sortPropertyEffects: function () {
+var EFFECT_ORDER = {
+'compute': 0,
+'annotation': 1,
+'computedAnnotation': 2,
+'reflect': 3,
+'notify': 4,
+'observer': 5,
+'complexObserver': 6,
+'function': 7
+};
+return function (a, b) {
+return EFFECT_ORDER[a.kind] - EFFECT_ORDER[b.kind];
+};
+}(),
+_createAccessors: function (model, property, effects) {
+var defun = {
+get: function () {
+return this.__data__[property];
+}
+};
+var setter = function (value) {
+this._propertySetter(property, value, effects);
+};
+var info = model.getPropertyInfo && model.getPropertyInfo(property);
+if (info && info.readOnly) {
+if (!info.computed) {
+model['_set' + this.upper(property)] = setter;
+}
+} else {
+defun.set = setter;
+}
+Object.defineProperty(model, property, defun);
+},
+upper: function (name) {
+return name[0].toUpperCase() + name.substring(1);
+},
+_addAnnotatedListener: function (model, index, property, path, event) {
+if (!model._bindListeners) {
+model._bindListeners = [];
+}
+var fn = this._notedListenerFactory(property, path, this._isStructured(path));
+var eventName = event || Polymer.CaseMap.camelToDashCase(property) + '-changed';
+model._bindListeners.push({
+index: index,
+property: property,
+path: path,
+changedFn: fn,
+event: eventName
+});
+},
+_isStructured: function (path) {
+return path.indexOf('.') > 0;
+},
+_isEventBogus: function (e, target) {
+return e.path && e.path[0] !== target;
+},
+_notedListenerFactory: function (property, path, isStructured) {
+return function (target, value, targetPath) {
+if (targetPath) {
+this._notifyPath(this._fixPath(path, property, targetPath), value);
+} else {
+value = target[property];
+if (!isStructured) {
+this[path] = value;
+} else {
+if (this.__data__[path] != value) {
+this.set(path, value);
+}
+}
+}
+};
+},
+prepareInstance: function (inst) {
+inst.__data__ = Object.create(null);
+},
+setupBindListeners: function (inst) {
+var b$ = inst._bindListeners;
+for (var i = 0, l = b$.length, info; i < l && (info = b$[i]); i++) {
+var node = inst._nodes[info.index];
+this._addNotifyListener(node, inst, info.event, info.changedFn);
+}
+;
+},
+_addNotifyListener: function (element, context, event, changedFn) {
+element.addEventListener(event, function (e) {
+return context._notifyListener(changedFn, e);
+});
+}
+};
+Polymer.Base.extend(Polymer.Bind, {
+_shouldAddListener: function (effect) {
+return effect.name && effect.kind != 'attribute' && effect.kind != 'text' && !effect.isCompound && effect.parts[0].mode === '{' && !effect.parts[0].negate;
+},
+_annotationEffect: function (source, value, effect) {
+if (source != effect.value) {
+value = this._get(effect.value);
+this.__data__[effect.value] = value;
+}
+var calc = effect.negate ? !value : value;
+if (!effect.customEvent || this._nodes[effect.index][effect.name] !== calc) {
+return this._applyEffectValue(effect, calc);
+}
+},
+_reflectEffect: function (source, value, effect) {
+this.reflectPropertyToAttribute(source, effect.attribute, value);
+},
+_notifyEffect: function (source, value, effect, old, fromAbove) {
+if (!fromAbove) {
+this._notifyChange(source, effect.event, value);
+}
+},
+_functionEffect: function (source, value, fn, old, fromAbove) {
+fn.call(this, source, value, old, fromAbove);
+},
+_observerEffect: function (source, value, effect, old) {
+var fn = this[effect.method];
+if (fn) {
+fn.call(this, value, old);
+} else {
+this._warn(this._logf('_observerEffect', 'observer method `' + effect.method + '` not defined'));
+}
+},
+_complexObserverEffect: function (source, value, effect) {
+var fn = this[effect.method];
+if (fn) {
+var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
+if (args) {
+fn.apply(this, args);
+}
+} else {
+this._warn(this._logf('_complexObserverEffect', 'observer method `' + effect.method + '` not defined'));
+}
+},
+_computeEffect: function (source, value, effect) {
+var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
+if (args) {
+var fn = this[effect.method];
+if (fn) {
+this.__setProperty(effect.name, fn.apply(this, args));
+} else {
+this._warn(this._logf('_computeEffect', 'compute method `' + effect.method + '` not defined'));
+}
+}
+},
+_annotatedComputationEffect: function (source, value, effect) {
+var computedHost = this._rootDataHost || this;
+var fn = computedHost[effect.method];
+if (fn) {
+var args = Polymer.Bind._marshalArgs(this.__data__, effect, source, value);
+if (args) {
+var computedvalue = fn.apply(computedHost, args);
+if (effect.negate) {
+computedvalue = !computedvalue;
+}
+this._applyEffectValue(effect, computedvalue);
+}
+} else {
+computedHost._warn(computedHost._logf('_annotatedComputationEffect', 'compute method `' + effect.method + '` not defined'));
+}
+},
+_marshalArgs: function (model, effect, path, value) {
+var values = [];
+var args = effect.args;
+for (var i = 0, l = args.length; i < l; i++) {
+var arg = args[i];
+var name = arg.name;
+var v;
+if (arg.literal) {
+v = arg.value;
+} else if (arg.structured) {
+v = Polymer.Base._get(name, model);
+} else {
+v = model[name];
+}
+if (args.length > 1 && v === undefined) {
+return;
+}
+if (arg.wildcard) {
+var baseChanged = name.indexOf(path + '.') === 0;
+var matches = effect.trigger.name.indexOf(name) === 0 && !baseChanged;
+values[i] = {
+path: matches ? path : name,
+value: matches ? value : v,
+base: v
+};
+} else {
+values[i] = v;
+}
+}
+return values;
+}
+});
+Polymer.Base._addFeature({
+_addPropertyEffect: function (property, kind, effect) {
+var prop = Polymer.Bind.addPropertyEffect(this, property, kind, effect);
+prop.pathFn = this['_' + prop.kind + 'PathEffect'];
+},
+_prepEffects: function () {
+Polymer.Bind.prepareModel(this);
+this._addAnnotationEffects(this._notes);
+},
+_prepBindings: function () {
+Polymer.Bind.createBindings(this);
+},
+_addPropertyEffects: function (properties) {
+if (properties) {
+for (var p in properties) {
+var prop = properties[p];
+if (prop.observer) {
+this._addObserverEffect(p, prop.observer);
+}
+if (prop.computed) {
+prop.readOnly = true;
+this._addComputedEffect(p, prop.computed);
+}
+if (prop.notify) {
+this._addPropertyEffect(p, 'notify', { event: Polymer.CaseMap.camelToDashCase(p) + '-changed' });
+}
+if (prop.reflectToAttribute) {
+this._addPropertyEffect(p, 'reflect', { attribute: Polymer.CaseMap.camelToDashCase(p) });
+}
+if (prop.readOnly) {
+Polymer.Bind.ensurePropertyEffects(this, p);
+}
+}
+}
+},
+_addComputedEffect: function (name, expression) {
+var sig = this._parseMethod(expression);
+for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) {
+this._addPropertyEffect(arg.model, 'compute', {
+method: sig.method,
+args: sig.args,
+trigger: arg,
+name: name
+});
+}
+},
+_addObserverEffect: function (property, observer) {
+this._addPropertyEffect(property, 'observer', {
+method: observer,
+property: property
+});
+},
+_addComplexObserverEffects: function (observers) {
+if (observers) {
+for (var i = 0, o; i < observers.length && (o = observers[i]); i++) {
+this._addComplexObserverEffect(o);
+}
+}
+},
+_addComplexObserverEffect: function (observer) {
+var sig = this._parseMethod(observer);
+if (!sig) {
+throw new Error('Malformed observer expression \'' + observer + '\'');
+}
+for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) {
+this._addPropertyEffect(arg.model, 'complexObserver', {
+method: sig.method,
+args: sig.args,
+trigger: arg
+});
+}
+},
+_addAnnotationEffects: function (notes) {
+for (var i = 0, note; i < notes.length && (note = notes[i]); i++) {
+var b$ = note.bindings;
+for (var j = 0, binding; j < b$.length && (binding = b$[j]); j++) {
+this._addAnnotationEffect(binding, i);
+}
+}
+},
+_addAnnotationEffect: function (note, index) {
+if (Polymer.Bind._shouldAddListener(note)) {
+Polymer.Bind._addAnnotatedListener(this, index, note.name, note.parts[0].value, note.parts[0].event);
+}
+for (var i = 0; i < note.parts.length; i++) {
+var part = note.parts[i];
+if (part.signature) {
+this._addAnnotatedComputationEffect(note, part, index);
+} else if (!part.literal) {
+this._addPropertyEffect(part.model, 'annotation', {
+kind: note.kind,
+index: index,
+name: note.name,
+value: part.value,
+isCompound: note.isCompound,
+compoundIndex: part.compoundIndex,
+event: part.event,
+customEvent: part.customEvent,
+negate: part.negate
+});
+}
+}
+},
+_addAnnotatedComputationEffect: function (note, part, index) {
+var sig = part.signature;
+if (sig.static) {
+this.__addAnnotatedComputationEffect('__static__', index, note, part, null);
+} else {
+for (var i = 0, arg; i < sig.args.length && (arg = sig.args[i]); i++) {
+if (!arg.literal) {
+this.__addAnnotatedComputationEffect(arg.model, index, note, part, arg);
+}
+}
+}
+},
+__addAnnotatedComputationEffect: function (property, index, note, part, trigger) {
+this._addPropertyEffect(property, 'annotatedComputation', {
+index: index,
+isCompound: note.isCompound,
+compoundIndex: part.compoundIndex,
+kind: note.kind,
+name: note.name,
+negate: part.negate,
+method: part.signature.method,
+args: part.signature.args,
+trigger: trigger
+});
+},
+_parseMethod: function (expression) {
+var m = expression.match(/([^\s]+?)\((.*)\)/);
+if (m) {
+var sig = {
+method: m[1],
+static: true
+};
+if (m[2].trim()) {
+var args = m[2].replace(/\\,/g, '&comma;').split(',');
+return this._parseArgs(args, sig);
+} else {
+sig.args = Polymer.nar;
+return sig;
+}
+}
+},
+_parseArgs: function (argList, sig) {
+sig.args = argList.map(function (rawArg) {
+var arg = this._parseArg(rawArg);
+if (!arg.literal) {
+sig.static = false;
+}
+return arg;
+}, this);
+return sig;
+},
+_parseArg: function (rawArg) {
+var arg = rawArg.trim().replace(/&comma;/g, ',').replace(/\\(.)/g, '$1');
+var a = { name: arg };
+var fc = arg[0];
+if (fc === '-') {
+fc = arg[1];
+}
+if (fc >= '0' && fc <= '9') {
+fc = '#';
+}
+switch (fc) {
+case '\'':
+case '"':
+a.value = arg.slice(1, -1);
+a.literal = true;
+break;
+case '#':
+a.value = Number(arg);
+a.literal = true;
+break;
+}
+if (!a.literal) {
+a.model = this._modelForPath(arg);
+a.structured = arg.indexOf('.') > 0;
+if (a.structured) {
+a.wildcard = arg.slice(-2) == '.*';
+if (a.wildcard) {
+a.name = arg.slice(0, -2);
+}
+}
+}
+return a;
+},
+_marshalInstanceEffects: function () {
+Polymer.Bind.prepareInstance(this);
+if (this._bindListeners) {
+Polymer.Bind.setupBindListeners(this);
+}
+},
+_applyEffectValue: function (info, value) {
+var node = this._nodes[info.index];
+var property = info.name;
+if (info.isCompound) {
+var storage = node.__compoundStorage__[property];
+storage[info.compoundIndex] = value;
+value = storage.join('');
+}
+if (info.kind == 'attribute') {
+this.serializeValueToAttribute(value, property, node);
+} else {
+if (property === 'className') {
+value = this._scopeElementClass(node, value);
+}
+if (property === 'textContent' || node.localName == 'input' && property == 'value') {
+value = value == undefined ? '' : value;
+}
+var pinfo;
+if (!node._propertyInfo || !(pinfo = node._propertyInfo[property]) || !pinfo.readOnly) {
+this.__setProperty(property, value, false, node);
+}
+}
+},
+_executeStaticEffects: function () {
+if (this._propertyEffects && this._propertyEffects.__static__) {
+this._effectEffects('__static__', null, this._propertyEffects.__static__);
+}
+}
+});
+Polymer.Base._addFeature({
+_setupConfigure: function (initialConfig) {
+this._config = {};
+this._handlers = [];
+this._aboveConfig = null;
+if (initialConfig) {
+for (var i in initialConfig) {
+if (initialConfig[i] !== undefined) {
+this._config[i] = initialConfig[i];
+}
+}
+}
+},
+_marshalAttributes: function () {
+this._takeAttributesToModel(this._config);
+},
+_attributeChangedImpl: function (name) {
+var model = this._clientsReadied ? this : this._config;
+this._setAttributeToProperty(model, name);
+},
+_configValue: function (name, value) {
+var info = this._propertyInfo[name];
+if (!info || !info.readOnly) {
+this._config[name] = value;
+}
+},
+_beforeClientsReady: function () {
+this._configure();
+},
+_configure: function () {
+this._configureAnnotationReferences();
+this._aboveConfig = this.mixin({}, this._config);
+var config = {};
+for (var i = 0; i < this.behaviors.length; i++) {
+this._configureProperties(this.behaviors[i].properties, config);
+}
+this._configureProperties(this.properties, config);
+this.mixin(config, this._aboveConfig);
+this._config = config;
+if (this._clients && this._clients.length) {
+this._distributeConfig(this._config);
+}
+},
+_configureProperties: function (properties, config) {
+for (var i in properties) {
+var c = properties[i];
+if (c.value !== undefined) {
+var value = c.value;
+if (typeof value == 'function') {
+value = value.call(this, this._config);
+}
+config[i] = value;
+}
+}
+},
+_distributeConfig: function (config) {
+var fx$ = this._propertyEffects;
+if (fx$) {
+for (var p in config) {
+var fx = fx$[p];
+if (fx) {
+for (var i = 0, l = fx.length, x; i < l && (x = fx[i]); i++) {
+if (x.kind === 'annotation' && !x.isCompound) {
+var node = this._nodes[x.effect.index];
+if (node._configValue) {
+var value = p === x.effect.value ? config[p] : this._get(x.effect.value, config);
+node._configValue(x.effect.name, value);
+}
+}
+}
+}
+}
+}
+},
+_afterClientsReady: function () {
+this._executeStaticEffects();
+this._applyConfig(this._config, this._aboveConfig);
+this._flushHandlers();
+},
+_applyConfig: function (config, aboveConfig) {
+for (var n in config) {
+if (this[n] === undefined) {
+this.__setProperty(n, config[n], n in aboveConfig);
+}
+}
+},
+_notifyListener: function (fn, e) {
+if (!Polymer.Bind._isEventBogus(e, e.target)) {
+var value, path;
+if (e.detail) {
+value = e.detail.value;
+path = e.detail.path;
+}
+if (!this._clientsReadied) {
+this._queueHandler([
+fn,
+e.target,
+value,
+path
+]);
+} else {
+return fn.call(this, e.target, value, path);
+}
+}
+},
+_queueHandler: function (args) {
+this._handlers.push(args);
+},
+_flushHandlers: function () {
+var h$ = this._handlers;
+for (var i = 0, l = h$.length, h; i < l && (h = h$[i]); i++) {
+h[0].call(this, h[1], h[2], h[3]);
+}
+this._handlers = [];
+}
+});
+(function () {
+'use strict';
+Polymer.Base._addFeature({
+notifyPath: function (path, value, fromAbove) {
+var info = {};
+this._get(path, this, info);
+if (info.path) {
+this._notifyPath(info.path, value, fromAbove);
+}
+},
+_notifyPath: function (path, value, fromAbove) {
+var old = this._propertySetter(path, value);
+if (old !== value && (old === old || value === value)) {
+this._pathEffector(path, value);
+if (!fromAbove) {
+this._notifyPathUp(path, value);
+}
+return true;
+}
+},
+_getPathParts: function (path) {
+if (Array.isArray(path)) {
+var parts = [];
+for (var i = 0; i < path.length; i++) {
+var args = path[i].toString().split('.');
+for (var j = 0; j < args.length; j++) {
+parts.push(args[j]);
+}
+}
+return parts;
+} else {
+return path.toString().split('.');
+}
+},
+set: function (path, value, root) {
+var prop = root || this;
+var parts = this._getPathParts(path);
+var array;
+var last = parts[parts.length - 1];
+if (parts.length > 1) {
+for (var i = 0; i < parts.length - 1; i++) {
+var part = parts[i];
+if (array && part[0] == '#') {
+prop = Polymer.Collection.get(array).getItem(part);
+} else {
+prop = prop[part];
+if (array && parseInt(part, 10) == part) {
+parts[i] = Polymer.Collection.get(array).getKey(prop);
+}
+}
+if (!prop) {
+return;
+}
+array = Array.isArray(prop) ? prop : null;
+}
+if (array) {
+var coll = Polymer.Collection.get(array);
+if (last[0] == '#') {
+var key = last;
+var old = coll.getItem(key);
+last = array.indexOf(old);
+coll.setItem(key, value);
+} else if (parseInt(last, 10) == last) {
+var old = prop[last];
+var key = coll.getKey(old);
+parts[i] = key;
+coll.setItem(key, value);
+}
+}
+prop[last] = value;
+if (!root) {
+this._notifyPath(parts.join('.'), value);
+}
+} else {
+prop[path] = value;
+}
+},
+get: function (path, root) {
+return this._get(path, root);
+},
+_get: function (path, root, info) {
+var prop = root || this;
+var parts = this._getPathParts(path);
+var array;
+for (var i = 0; i < parts.length; i++) {
+if (!prop) {
+return;
+}
+var part = parts[i];
+if (array && part[0] == '#') {
+prop = Polymer.Collection.get(array).getItem(part);
+} else {
+prop = prop[part];
+if (info && array && parseInt(part, 10) == part) {
+parts[i] = Polymer.Collection.get(array).getKey(prop);
+}
+}
+array = Array.isArray(prop) ? prop : null;
+}
+if (info) {
+info.path = parts.join('.');
+}
+return prop;
+},
+_pathEffector: function (path, value) {
+var model = this._modelForPath(path);
+var fx$ = this._propertyEffects && this._propertyEffects[model];
+if (fx$) {
+for (var i = 0, fx; i < fx$.length && (fx = fx$[i]); i++) {
+var fxFn = fx.pathFn;
+if (fxFn) {
+fxFn.call(this, path, value, fx.effect);
+}
+}
+}
+if (this._boundPaths) {
+this._notifyBoundPaths(path, value);
+}
+},
+_annotationPathEffect: function (path, value, effect) {
+if (effect.value === path || effect.value.indexOf(path + '.') === 0) {
+Polymer.Bind._annotationEffect.call(this, path, value, effect);
+} else if (path.indexOf(effect.value + '.') === 0 && !effect.negate) {
+var node = this._nodes[effect.index];
+if (node && node._notifyPath) {
+var p = this._fixPath(effect.name, effect.value, path);
+node._notifyPath(p, value, true);
+}
+}
+},
+_complexObserverPathEffect: function (path, value, effect) {
+if (this._pathMatchesEffect(path, effect)) {
+Polymer.Bind._complexObserverEffect.call(this, path, value, effect);
+}
+},
+_computePathEffect: function (path, value, effect) {
+if (this._pathMatchesEffect(path, effect)) {
+Polymer.Bind._computeEffect.call(this, path, value, effect);
+}
+},
+_annotatedComputationPathEffect: function (path, value, effect) {
+if (this._pathMatchesEffect(path, effect)) {
+Polymer.Bind._annotatedComputationEffect.call(this, path, value, effect);
+}
+},
+_pathMatchesEffect: function (path, effect) {
+var effectArg = effect.trigger.name;
+return effectArg == path || effectArg.indexOf(path + '.') === 0 || effect.trigger.wildcard && path.indexOf(effectArg) === 0;
+},
+linkPaths: function (to, from) {
+this._boundPaths = this._boundPaths || {};
+if (from) {
+this._boundPaths[to] = from;
+} else {
+this.unlinkPaths(to);
+}
+},
+unlinkPaths: function (path) {
+if (this._boundPaths) {
+delete this._boundPaths[path];
+}
+},
+_notifyBoundPaths: function (path, value) {
+for (var a in this._boundPaths) {
+var b = this._boundPaths[a];
+if (path.indexOf(a + '.') == 0) {
+this._notifyPath(this._fixPath(b, a, path), value);
+} else if (path.indexOf(b + '.') == 0) {
+this._notifyPath(this._fixPath(a, b, path), value);
+}
+}
+},
+_fixPath: function (property, root, path) {
+return property + path.slice(root.length);
+},
+_notifyPathUp: function (path, value) {
+var rootName = this._modelForPath(path);
+var dashCaseName = Polymer.CaseMap.camelToDashCase(rootName);
+var eventName = dashCaseName + this._EVENT_CHANGED;
+this.fire(eventName, {
+path: path,
+value: value
+}, {
+bubbles: false,
+_useCache: true
+});
+},
+_modelForPath: function (path) {
+var dot = path.indexOf('.');
+return dot < 0 ? path : path.slice(0, dot);
+},
+_EVENT_CHANGED: '-changed',
+notifySplices: function (path, splices) {
+var info = {};
+var array = this._get(path, this, info);
+this._notifySplices(array, info.path, splices);
+},
+_notifySplices: function (array, path, splices) {
+var change = {
+keySplices: Polymer.Collection.applySplices(array, splices),
+indexSplices: splices
+};
+if (!array.hasOwnProperty('splices')) {
+Object.defineProperty(array, 'splices', {
+configurable: true,
+writable: true
+});
+}
+array.splices = change;
+this._notifyPath(path + '.splices', change);
+this._notifyPath(path + '.length', array.length);
+change.keySplices = null;
+change.indexSplices = null;
+},
+_notifySplice: function (array, path, index, added, removed) {
+this._notifySplices(array, path, [{
+index: index,
+addedCount: added,
+removed: removed,
+object: array,
+type: 'splice'
+}]);
+},
+push: function (path) {
+var info = {};
+var array = this._get(path, this, info);
+var args = Array.prototype.slice.call(arguments, 1);
+var len = array.length;
+var ret = array.push.apply(array, args);
+if (args.length) {
+this._notifySplice(array, info.path, len, args.length, []);
+}
+return ret;
+},
+pop: function (path) {
+var info = {};
+var array = this._get(path, this, info);
+var hadLength = Boolean(array.length);
+var args = Array.prototype.slice.call(arguments, 1);
+var ret = array.pop.apply(array, args);
+if (hadLength) {
+this._notifySplice(array, info.path, array.length, 0, [ret]);
+}
+return ret;
+},
+splice: function (path, start, deleteCount) {
+var info = {};
+var array = this._get(path, this, info);
+if (start < 0) {
+start = array.length - Math.floor(-start);
+} else {
+start = Math.floor(start);
+}
+if (!start) {
+start = 0;
+}
+var args = Array.prototype.slice.call(arguments, 1);
+var ret = array.splice.apply(array, args);
+var addedCount = Math.max(args.length - 2, 0);
+if (addedCount || ret.length) {
+this._notifySplice(array, info.path, start, addedCount, ret);
+}
+return ret;
+},
+shift: function (path) {
+var info = {};
+var array = this._get(path, this, info);
+var hadLength = Boolean(array.length);
+var args = Array.prototype.slice.call(arguments, 1);
+var ret = array.shift.apply(array, args);
+if (hadLength) {
+this._notifySplice(array, info.path, 0, 0, [ret]);
+}
+return ret;
+},
+unshift: function (path) {
+var info = {};
+var array = this._get(path, this, info);
+var args = Array.prototype.slice.call(arguments, 1);
+var ret = array.unshift.apply(array, args);
+if (args.length) {
+this._notifySplice(array, info.path, 0, args.length, []);
+}
+return ret;
+},
+prepareModelNotifyPath: function (model) {
+this.mixin(model, {
+fire: Polymer.Base.fire,
+_getEvent: Polymer.Base._getEvent,
+__eventCache: Polymer.Base.__eventCache,
+notifyPath: Polymer.Base.notifyPath,
+_get: Polymer.Base._get,
+_EVENT_CHANGED: Polymer.Base._EVENT_CHANGED,
+_notifyPath: Polymer.Base._notifyPath,
+_notifyPathUp: Polymer.Base._notifyPathUp,
+_pathEffector: Polymer.Base._pathEffector,
+_annotationPathEffect: Polymer.Base._annotationPathEffect,
+_complexObserverPathEffect: Polymer.Base._complexObserverPathEffect,
+_annotatedComputationPathEffect: Polymer.Base._annotatedComputationPathEffect,
+_computePathEffect: Polymer.Base._computePathEffect,
+_modelForPath: Polymer.Base._modelForPath,
+_pathMatchesEffect: Polymer.Base._pathMatchesEffect,
+_notifyBoundPaths: Polymer.Base._notifyBoundPaths,
+_getPathParts: Polymer.Base._getPathParts
+});
+}
+});
+}());
+Polymer.Base._addFeature({
+resolveUrl: function (url) {
+var module = Polymer.DomModule.import(this.is);
+var root = '';
+if (module) {
+var assetPath = module.getAttribute('assetpath') || '';
+root = Polymer.ResolveUrl.resolveUrl(assetPath, module.ownerDocument.baseURI);
+}
+return Polymer.ResolveUrl.resolveUrl(url, root);
+}
+});
+Polymer.CssParse = function () {
+return {
+parse: function (text) {
+text = this._clean(text);
+return this._parseCss(this._lex(text), text);
+},
+_clean: function (cssText) {
+return cssText.replace(this._rx.comments, '').replace(this._rx.port, '');
+},
+_lex: function (text) {
+var root = {
+start: 0,
+end: text.length
+};
+var n = root;
+for (var i = 0, l = text.length; i < l; i++) {
+switch (text[i]) {
+case this.OPEN_BRACE:
+if (!n.rules) {
+n.rules = [];
+}
+var p = n;
+var previous = p.rules[p.rules.length - 1];
+n = {
+start: i + 1,
+parent: p,
+previous: previous
+};
+p.rules.push(n);
+break;
+case this.CLOSE_BRACE:
+n.end = i + 1;
+n = n.parent || root;
+break;
+}
+}
+return root;
+},
+_parseCss: function (node, text) {
+var t = text.substring(node.start, node.end - 1);
+node.parsedCssText = node.cssText = t.trim();
+if (node.parent) {
+var ss = node.previous ? node.previous.end : node.parent.start;
+t = text.substring(ss, node.start - 1);
+t = this._expandUnicodeEscapes(t);
+t = t.replace(this._rx.multipleSpaces, ' ');
+t = t.substring(t.lastIndexOf(';') + 1);
+var s = node.parsedSelector = node.selector = t.trim();
+node.atRule = s.indexOf(this.AT_START) === 0;
+if (node.atRule) {
+if (s.indexOf(this.MEDIA_START) === 0) {
+node.type = this.types.MEDIA_RULE;
+} else if (s.match(this._rx.keyframesRule)) {
+node.type = this.types.KEYFRAMES_RULE;
+}
+} else {
+if (s.indexOf(this.VAR_START) === 0) {
+node.type = this.types.MIXIN_RULE;
+} else {
+node.type = this.types.STYLE_RULE;
+}
+}
+}
+var r$ = node.rules;
+if (r$) {
+for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
+this._parseCss(r, text);
+}
+}
+return node;
+},
+_expandUnicodeEscapes: function (s) {
+return s.replace(/\\([0-9a-f]{1,6})\s/gi, function () {
+var code = arguments[1], repeat = 6 - code.length;
+while (repeat--) {
+code = '0' + code;
+}
+return '\\' + code;
+});
+},
+stringify: function (node, preserveProperties, text) {
+text = text || '';
+var cssText = '';
+if (node.cssText || node.rules) {
+var r$ = node.rules;
+if (r$ && (preserveProperties || !this._hasMixinRules(r$))) {
+for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
+cssText = this.stringify(r, preserveProperties, cssText);
+}
+} else {
+cssText = preserveProperties ? node.cssText : this.removeCustomProps(node.cssText);
+cssText = cssText.trim();
+if (cssText) {
+cssText = ' ' + cssText + '\n';
+}
+}
+}
+if (cssText) {
+if (node.selector) {
+text += node.selector + ' ' + this.OPEN_BRACE + '\n';
+}
+text += cssText;
+if (node.selector) {
+text += this.CLOSE_BRACE + '\n\n';
+}
+}
+return text;
+},
+_hasMixinRules: function (rules) {
+return rules[0].selector.indexOf(this.VAR_START) === 0;
+},
+removeCustomProps: function (cssText) {
+cssText = this.removeCustomPropAssignment(cssText);
+return this.removeCustomPropApply(cssText);
+},
+removeCustomPropAssignment: function (cssText) {
+return cssText.replace(this._rx.customProp, '').replace(this._rx.mixinProp, '');
+},
+removeCustomPropApply: function (cssText) {
+return cssText.replace(this._rx.mixinApply, '').replace(this._rx.varApply, '');
+},
+types: {
+STYLE_RULE: 1,
+KEYFRAMES_RULE: 7,
+MEDIA_RULE: 4,
+MIXIN_RULE: 1000
+},
+OPEN_BRACE: '{',
+CLOSE_BRACE: '}',
+_rx: {
+comments: /\/\*[^*]*\*+([^\/*][^*]*\*+)*\//gim,
+port: /@import[^;]*;/gim,
+customProp: /(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?(?:[;\n]|$)/gim,
+mixinProp: /(?:^[^;\-\s}]+)?--[^;{}]*?:[^{};]*?{[^}]*?}(?:[;\n]|$)?/gim,
+mixinApply: /@apply[\s]*\([^)]*?\)[\s]*(?:[;\n]|$)?/gim,
+varApply: /[^;:]*?:[^;]*?var\([^;]*\)(?:[;\n]|$)?/gim,
+keyframesRule: /^@[^\s]*keyframes/,
+multipleSpaces: /\s+/g
+},
+VAR_START: '--',
+MEDIA_START: '@media',
+AT_START: '@'
+};
+}();
+Polymer.StyleUtil = function () {
+return {
+MODULE_STYLES_SELECTOR: 'style, link[rel=import][type~=css], template',
+INCLUDE_ATTR: 'include',
+toCssText: function (rules, callback, preserveProperties) {
+if (typeof rules === 'string') {
+rules = this.parser.parse(rules);
+}
+if (callback) {
+this.forEachStyleRule(rules, callback);
+}
+return this.parser.stringify(rules, preserveProperties);
+},
+forRulesInStyles: function (styles, callback) {
+if (styles) {
+for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {
+this.forEachStyleRule(this.rulesForStyle(s), callback);
+}
+}
+},
+rulesForStyle: function (style) {
+if (!style.__cssRules && style.textContent) {
+style.__cssRules = this.parser.parse(style.textContent);
+}
+return style.__cssRules;
+},
+forEachStyleRule: function (node, callback) {
+if (!node) {
+return;
+}
+var skipRules = false;
+if (node.type === this.ruleTypes.STYLE_RULE) {
+callback(node);
+} else if (node.type === this.ruleTypes.KEYFRAMES_RULE || node.type === this.ruleTypes.MIXIN_RULE) {
+skipRules = true;
+}
+var r$ = node.rules;
+if (r$ && !skipRules) {
+for (var i = 0, l = r$.length, r; i < l && (r = r$[i]); i++) {
+this.forEachStyleRule(r, callback);
+}
+}
+},
+applyCss: function (cssText, moniker, target, afterNode) {
+var style = document.createElement('style');
+if (moniker) {
+style.setAttribute('scope', moniker);
+}
+style.textContent = cssText;
+target = target || document.head;
+if (!afterNode) {
+var n$ = target.querySelectorAll('style[scope]');
+afterNode = n$[n$.length - 1];
+}
+target.insertBefore(style, afterNode && afterNode.nextSibling || target.firstChild);
+return style;
+},
+cssFromModules: function (moduleIds, warnIfNotFound) {
+var modules = moduleIds.trim().split(' ');
+var cssText = '';
+for (var i = 0; i < modules.length; i++) {
+cssText += this.cssFromModule(modules[i], warnIfNotFound);
+}
+return cssText;
+},
+cssFromModule: function (moduleId, warnIfNotFound) {
+var m = Polymer.DomModule.import(moduleId);
+if (m && !m._cssText) {
+m._cssText = this.cssFromElement(m);
+}
+if (!m && warnIfNotFound) {
+console.warn('Could not find style data in module named', moduleId);
+}
+return m && m._cssText || '';
+},
+cssFromElement: function (element) {
+var cssText = '';
+var content = element.content || element;
+var e$ = Polymer.TreeApi.arrayCopy(content.querySelectorAll(this.MODULE_STYLES_SELECTOR));
+for (var i = 0, e; i < e$.length; i++) {
+e = e$[i];
+if (e.localName === 'template') {
+cssText += this.cssFromElement(e);
+} else {
+if (e.localName === 'style') {
+var include = e.getAttribute(this.INCLUDE_ATTR);
+if (include) {
+cssText += this.cssFromModules(include, true);
+}
+e = e.__appliedElement || e;
+e.parentNode.removeChild(e);
+cssText += this.resolveCss(e.textContent, element.ownerDocument);
+} else if (e.import && e.import.body) {
+cssText += this.resolveCss(e.import.body.textContent, e.import);
+}
+}
+}
+return cssText;
+},
+resolveCss: Polymer.ResolveUrl.resolveCss,
+parser: Polymer.CssParse,
+ruleTypes: Polymer.CssParse.types
+};
+}();
+Polymer.StyleTransformer = function () {
+var nativeShadow = Polymer.Settings.useNativeShadow;
+var styleUtil = Polymer.StyleUtil;
+var api = {
+dom: function (node, scope, useAttr, shouldRemoveScope) {
+this._transformDom(node, scope || '', useAttr, shouldRemoveScope);
+},
+_transformDom: function (node, selector, useAttr, shouldRemoveScope) {
+if (node.setAttribute) {
+this.element(node, selector, useAttr, shouldRemoveScope);
+}
+var c$ = Polymer.dom(node).childNodes;
+for (var i = 0; i < c$.length; i++) {
+this._transformDom(c$[i], selector, useAttr, shouldRemoveScope);
+}
+},
+element: function (element, scope, useAttr, shouldRemoveScope) {
+if (useAttr) {
+if (shouldRemoveScope) {
+element.removeAttribute(SCOPE_NAME);
+} else {
+element.setAttribute(SCOPE_NAME, scope);
+}
+} else {
+if (scope) {
+if (element.classList) {
+if (shouldRemoveScope) {
+element.classList.remove(SCOPE_NAME);
+element.classList.remove(scope);
+} else {
+element.classList.add(SCOPE_NAME);
+element.classList.add(scope);
+}
+} else if (element.getAttribute) {
+var c = element.getAttribute(CLASS);
+if (shouldRemoveScope) {
+if (c) {
+element.setAttribute(CLASS, c.replace(SCOPE_NAME, '').replace(scope, ''));
+}
+} else {
+element.setAttribute(CLASS, (c ? c + ' ' : '') + SCOPE_NAME + ' ' + scope);
+}
+}
+}
+}
+},
+elementStyles: function (element, callback) {
+var styles = element._styles;
+var cssText = '';
+for (var i = 0, l = styles.length, s; i < l && (s = styles[i]); i++) {
+var rules = styleUtil.rulesForStyle(s);
+cssText += nativeShadow ? styleUtil.toCssText(rules, callback) : this.css(rules, element.is, element.extends, callback, element._scopeCssViaAttr) + '\n\n';
+}
+return cssText.trim();
+},
+css: function (rules, scope, ext, callback, useAttr) {
+var hostScope = this._calcHostScope(scope, ext);
+scope = this._calcElementScope(scope, useAttr);
+var self = this;
+return styleUtil.toCssText(rules, function (rule) {
+if (!rule.isScoped) {
+self.rule(rule, scope, hostScope);
+rule.isScoped = true;
+}
+if (callback) {
+callback(rule, scope, hostScope);
+}
+});
+},
+_calcElementScope: function (scope, useAttr) {
+if (scope) {
+return useAttr ? CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX : CSS_CLASS_PREFIX + scope;
+} else {
+return '';
+}
+},
+_calcHostScope: function (scope, ext) {
+return ext ? '[is=' + scope + ']' : scope;
+},
+rule: function (rule, scope, hostScope) {
+this._transformRule(rule, this._transformComplexSelector, scope, hostScope);
+},
+_transformRule: function (rule, transformer, scope, hostScope) {
+var p$ = rule.selector.split(COMPLEX_SELECTOR_SEP);
+for (var i = 0, l = p$.length, p; i < l && (p = p$[i]); i++) {
+p$[i] = transformer.call(this, p, scope, hostScope);
+}
+rule.selector = rule.transformedSelector = p$.join(COMPLEX_SELECTOR_SEP);
+},
+_transformComplexSelector: function (selector, scope, hostScope) {
+var stop = false;
+var hostContext = false;
+var self = this;
+selector = selector.replace(SIMPLE_SELECTOR_SEP, function (m, c, s) {
+if (!stop) {
+var info = self._transformCompoundSelector(s, c, scope, hostScope);
+stop = stop || info.stop;
+hostContext = hostContext || info.hostContext;
+c = info.combinator;
+s = info.value;
+} else {
+s = s.replace(SCOPE_JUMP, ' ');
+}
+return c + s;
+});
+if (hostContext) {
+selector = selector.replace(HOST_CONTEXT_PAREN, function (m, pre, paren, post) {
+return pre + paren + ' ' + hostScope + post + COMPLEX_SELECTOR_SEP + ' ' + pre + hostScope + paren + post;
+});
+}
+return selector;
+},
+_transformCompoundSelector: function (selector, combinator, scope, hostScope) {
+var jumpIndex = selector.search(SCOPE_JUMP);
+var hostContext = false;
+if (selector.indexOf(HOST_CONTEXT) >= 0) {
+hostContext = true;
+} else if (selector.indexOf(HOST) >= 0) {
+selector = selector.replace(HOST_PAREN, function (m, host, paren) {
+return hostScope + paren;
+});
+selector = selector.replace(HOST, hostScope);
+} else if (jumpIndex !== 0) {
+selector = scope ? this._transformSimpleSelector(selector, scope) : selector;
+}
+if (selector.indexOf(CONTENT) >= 0) {
+combinator = '';
+}
+var stop;
+if (jumpIndex >= 0) {
+selector = selector.replace(SCOPE_JUMP, ' ');
+stop = true;
+}
+return {
+value: selector,
+combinator: combinator,
+stop: stop,
+hostContext: hostContext
+};
+},
+_transformSimpleSelector: function (selector, scope) {
+var p$ = selector.split(PSEUDO_PREFIX);
+p$[0] += scope;
+return p$.join(PSEUDO_PREFIX);
+},
+documentRule: function (rule) {
+rule.selector = rule.parsedSelector;
+this.normalizeRootSelector(rule);
+if (!nativeShadow) {
+this._transformRule(rule, this._transformDocumentSelector);
+}
+},
+normalizeRootSelector: function (rule) {
+if (rule.selector === ROOT) {
+rule.selector = 'body';
+}
+},
+_transformDocumentSelector: function (selector) {
+return selector.match(SCOPE_JUMP) ? this._transformComplexSelector(selector, SCOPE_DOC_SELECTOR) : this._transformSimpleSelector(selector.trim(), SCOPE_DOC_SELECTOR);
+},
+SCOPE_NAME: 'style-scope'
+};
+var SCOPE_NAME = api.SCOPE_NAME;
+var SCOPE_DOC_SELECTOR = ':not([' + SCOPE_NAME + '])' + ':not(.' + SCOPE_NAME + ')';
+var COMPLEX_SELECTOR_SEP = ',';
+var SIMPLE_SELECTOR_SEP = /(^|[\s>+~]+)([^\s>+~]+)/g;
+var HOST = ':host';
+var ROOT = ':root';
+var HOST_PAREN = /(\:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;
+var HOST_CONTEXT = ':host-context';
+var HOST_CONTEXT_PAREN = /(.*)(?::host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/;
+var CONTENT = '::content';
+var SCOPE_JUMP = /::content|::shadow|\/deep\//;
+var CSS_CLASS_PREFIX = '.';
+var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~=';
+var CSS_ATTR_SUFFIX = ']';
+var PSEUDO_PREFIX = ':';
+var CLASS = 'class';
+return api;
+}();
+Polymer.StyleExtends = function () {
+var styleUtil = Polymer.StyleUtil;
+return {
+hasExtends: function (cssText) {
+return Boolean(cssText.match(this.rx.EXTEND));
+},
+transform: function (style) {
+var rules = styleUtil.rulesForStyle(style);
+var self = this;
+styleUtil.forEachStyleRule(rules, function (rule) {
+var map = self._mapRule(rule);
+if (rule.parent) {
+var m;
+while (m = self.rx.EXTEND.exec(rule.cssText)) {
+var extend = m[1];
+var extendor = self._findExtendor(extend, rule);
+if (extendor) {
+self._extendRule(rule, extendor);
+}
+}
+}
+rule.cssText = rule.cssText.replace(self.rx.EXTEND, '');
+});
+return styleUtil.toCssText(rules, function (rule) {
+if (rule.selector.match(self.rx.STRIP)) {
+rule.cssText = '';
+}
+}, true);
+},
+_mapRule: function (rule) {
+if (rule.parent) {
+var map = rule.parent.map || (rule.parent.map = {});
+var parts = rule.selector.split(',');
+for (var i = 0, p; i < parts.length; i++) {
+p = parts[i];
+map[p.trim()] = rule;
+}
+return map;
+}
+},
+_findExtendor: function (extend, rule) {
+return rule.parent && rule.parent.map && rule.parent.map[extend] || this._findExtendor(extend, rule.parent);
+},
+_extendRule: function (target, source) {
+if (target.parent !== source.parent) {
+this._cloneAndAddRuleToParent(source, target.parent);
+}
+target.extends = target.extends || [];
+target.extends.push(source);
+source.selector = source.selector.replace(this.rx.STRIP, '');
+source.selector = (source.selector && source.selector + ',\n') + target.selector;
+if (source.extends) {
+source.extends.forEach(function (e) {
+this._extendRule(target, e);
+}, this);
+}
+},
+_cloneAndAddRuleToParent: function (rule, parent) {
+rule = Object.create(rule);
+rule.parent = parent;
+if (rule.extends) {
+rule.extends = rule.extends.slice();
+}
+parent.rules.push(rule);
+},
+rx: {
+EXTEND: /@extends\(([^)]*)\)\s*?;/gim,
+STRIP: /%[^,]*$/
+}
+};
+}();
+(function () {
+var prepElement = Polymer.Base._prepElement;
+var nativeShadow = Polymer.Settings.useNativeShadow;
+var styleUtil = Polymer.StyleUtil;
+var styleTransformer = Polymer.StyleTransformer;
+var styleExtends = Polymer.StyleExtends;
+Polymer.Base._addFeature({
+_prepElement: function (element) {
+if (this._encapsulateStyle) {
+styleTransformer.element(element, this.is, this._scopeCssViaAttr);
+}
+prepElement.call(this, element);
+},
+_prepStyles: function () {
+if (this._encapsulateStyle === undefined) {
+this._encapsulateStyle = !nativeShadow && Boolean(this._template);
+}
+if (this._template) {
+this._styles = this._collectStyles();
+var cssText = styleTransformer.elementStyles(this);
+if (cssText) {
+var style = styleUtil.applyCss(cssText, this.is, nativeShadow ? this._template.content : null);
+if (!nativeShadow) {
+this._scopeStyle = style;
+}
+}
+} else {
+this._styles = [];
+}
+},
+_collectStyles: function () {
+var styles = [];
+var cssText = '', m$ = this.styleModules;
+if (m$) {
+for (var i = 0, l = m$.length, m; i < l && (m = m$[i]); i++) {
+cssText += styleUtil.cssFromModule(m);
+}
+}
+cssText += styleUtil.cssFromModule(this.is);
+var p = this._template && this._template.parentNode;
+if (this._template && (!p || p.id.toLowerCase() !== this.is)) {
+cssText += styleUtil.cssFromElement(this._template);
+}
+if (cssText) {
+var style = document.createElement('style');
+style.textContent = cssText;
+if (styleExtends.hasExtends(style.textContent)) {
+cssText = styleExtends.transform(style);
+}
+styles.push(style);
+}
+return styles;
+},
+_elementAdd: function (node) {
+if (this._encapsulateStyle) {
+if (node.__styleScoped) {
+node.__styleScoped = false;
+} else {
+styleTransformer.dom(node, this.is, this._scopeCssViaAttr);
+}
+}
+},
+_elementRemove: function (node) {
+if (this._encapsulateStyle) {
+styleTransformer.dom(node, this.is, this._scopeCssViaAttr, true);
+}
+},
+scopeSubtree: function (container, shouldObserve) {
+if (nativeShadow) {
+return;
+}
+var self = this;
+var scopify = function (node) {
+if (node.nodeType === Node.ELEMENT_NODE) {
+var className = node.getAttribute('class');
+node.setAttribute('class', self._scopeElementClass(node, className));
+var n$ = node.querySelectorAll('*');
+for (var i = 0, n; i < n$.length && (n = n$[i]); i++) {
+className = n.getAttribute('class');
+n.setAttribute('class', self._scopeElementClass(n, className));
+}
+}
+};
+scopify(container);
+if (shouldObserve) {
+var mo = new MutationObserver(function (mxns) {
+for (var i = 0, m; i < mxns.length && (m = mxns[i]); i++) {
+if (m.addedNodes) {
+for (var j = 0; j < m.addedNodes.length; j++) {
+scopify(m.addedNodes[j]);
+}
+}
+}
+});
+mo.observe(container, {
+childList: true,
+subtree: true
+});
+return mo;
+}
+}
+});
+}());
+Polymer.StyleProperties = function () {
+'use strict';
+var nativeShadow = Polymer.Settings.useNativeShadow;
+var matchesSelector = Polymer.DomApi.matchesSelector;
+var styleUtil = Polymer.StyleUtil;
+var styleTransformer = Polymer.StyleTransformer;
+return {
+decorateStyles: function (styles) {
+var self = this, props = {};
+styleUtil.forRulesInStyles(styles, function (rule) {
+self.decorateRule(rule);
+self.collectPropertiesInCssText(rule.propertyInfo.cssText, props);
+});
+var names = [];
+for (var i in props) {
+names.push(i);
+}
+return names;
+},
+decorateRule: function (rule) {
+if (rule.propertyInfo) {
+return rule.propertyInfo;
+}
+var info = {}, properties = {};
+var hasProperties = this.collectProperties(rule, properties);
+if (hasProperties) {
+info.properties = properties;
+rule.rules = null;
+}
+info.cssText = this.collectCssText(rule);
+rule.propertyInfo = info;
+return info;
+},
+collectProperties: function (rule, properties) {
+var info = rule.propertyInfo;
+if (info) {
+if (info.properties) {
+Polymer.Base.mixin(properties, info.properties);
+return true;
+}
+} else {
+var m, rx = this.rx.VAR_ASSIGN;
+var cssText = rule.parsedCssText;
+var any;
+while (m = rx.exec(cssText)) {
+properties[m[1]] = (m[2] || m[3]).trim();
+any = true;
+}
+return any;
+}
+},
+collectCssText: function (rule) {
+var customCssText = '';
+var cssText = rule.parsedCssText;
+cssText = cssText.replace(this.rx.BRACKETED, '').replace(this.rx.VAR_ASSIGN, '');
+var parts = cssText.split(';');
+for (var i = 0, p; i < parts.length; i++) {
+p = parts[i];
+if (p.match(this.rx.MIXIN_MATCH) || p.match(this.rx.VAR_MATCH)) {
+customCssText += p + ';\n';
+}
+}
+return customCssText;
+},
+collectPropertiesInCssText: function (cssText, props) {
+var m;
+while (m = this.rx.VAR_CAPTURE.exec(cssText)) {
+props[m[1]] = true;
+var def = m[2];
+if (def && def.match(this.rx.IS_VAR)) {
+props[def] = true;
+}
+}
+},
+reify: function (props) {
+var names = Object.getOwnPropertyNames(props);
+for (var i = 0, n; i < names.length; i++) {
+n = names[i];
+props[n] = this.valueForProperty(props[n], props);
+}
+},
+valueForProperty: function (property, props) {
+if (property) {
+if (property.indexOf(';') >= 0) {
+property = this.valueForProperties(property, props);
+} else {
+var self = this;
+var fn = function (all, prefix, value, fallback) {
+var propertyValue = self.valueForProperty(props[value], props) || (props[fallback] ? self.valueForProperty(props[fallback], props) : fallback);
+return prefix + (propertyValue || '');
+};
+property = property.replace(this.rx.VAR_MATCH, fn);
+}
+}
+return property && property.trim() || '';
+},
+valueForProperties: function (property, props) {
+var parts = property.split(';');
+for (var i = 0, p, m; i < parts.length; i++) {
+if (p = parts[i]) {
+m = p.match(this.rx.MIXIN_MATCH);
+if (m) {
+p = this.valueForProperty(props[m[1]], props);
+} else {
+var pp = p.split(':');
+if (pp[1]) {
+pp[1] = pp[1].trim();
+pp[1] = this.valueForProperty(pp[1], props) || pp[1];
+}
+p = pp.join(':');
+}
+parts[i] = p && p.lastIndexOf(';') === p.length - 1 ? p.slice(0, -1) : p || '';
+}
+}
+return parts.join(';');
+},
+applyProperties: function (rule, props) {
+var output = '';
+if (!rule.propertyInfo) {
+this.decorateRule(rule);
+}
+if (rule.propertyInfo.cssText) {
+output = this.valueForProperties(rule.propertyInfo.cssText, props);
+}
+rule.cssText = output;
+},
+propertyDataFromStyles: function (styles, element) {
+var props = {}, self = this;
+var o = [], i = 0;
+styleUtil.forRulesInStyles(styles, function (rule) {
+if (!rule.propertyInfo) {
+self.decorateRule(rule);
+}
+if (element && rule.propertyInfo.properties && matchesSelector.call(element, rule.transformedSelector || rule.parsedSelector)) {
+self.collectProperties(rule, props);
+addToBitMask(i, o);
+}
+i++;
+});
+return {
+properties: props,
+key: o
+};
+},
+scopePropertiesFromStyles: function (styles) {
+if (!styles._scopeStyleProperties) {
+styles._scopeStyleProperties = this.selectedPropertiesFromStyles(styles, this.SCOPE_SELECTORS);
+}
+return styles._scopeStyleProperties;
+},
+hostPropertiesFromStyles: function (styles) {
+if (!styles._hostStyleProperties) {
+styles._hostStyleProperties = this.selectedPropertiesFromStyles(styles, this.HOST_SELECTORS);
+}
+return styles._hostStyleProperties;
+},
+selectedPropertiesFromStyles: function (styles, selectors) {
+var props = {}, self = this;
+styleUtil.forRulesInStyles(styles, function (rule) {
+if (!rule.propertyInfo) {
+self.decorateRule(rule);
+}
+for (var i = 0; i < selectors.length; i++) {
+if (rule.parsedSelector === selectors[i]) {
+self.collectProperties(rule, props);
+return;
+}
+}
+});
+return props;
+},
+transformStyles: function (element, properties, scopeSelector) {
+var self = this;
+var hostSelector = styleTransformer._calcHostScope(element.is, element.extends);
+var rxHostSelector = element.extends ? '\\' + hostSelector.slice(0, -1) + '\\]' : hostSelector;
+var hostRx = new RegExp(this.rx.HOST_PREFIX + rxHostSelector + this.rx.HOST_SUFFIX);
+return styleTransformer.elementStyles(element, function (rule) {
+self.applyProperties(rule, properties);
+if (rule.cssText && !nativeShadow) {
+self._scopeSelector(rule, hostRx, hostSelector, element._scopeCssViaAttr, scopeSelector);
+}
+});
+},
+_scopeSelector: function (rule, hostRx, hostSelector, viaAttr, scopeId) {
+rule.transformedSelector = rule.transformedSelector || rule.selector;
+var selector = rule.transformedSelector;
+var scope = viaAttr ? '[' + styleTransformer.SCOPE_NAME + '~=' + scopeId + ']' : '.' + scopeId;
+var parts = selector.split(',');
+for (var i = 0, l = parts.length, p; i < l && (p = parts[i]); i++) {
+parts[i] = p.match(hostRx) ? p.replace(hostSelector, hostSelector + scope) : scope + ' ' + p;
+}
+rule.selector = parts.join(',');
+},
+applyElementScopeSelector: function (element, selector, old, viaAttr) {
+var c = viaAttr ? element.getAttribute(styleTransformer.SCOPE_NAME) : element.getAttribute('class') || '';
+var v = old ? c.replace(old, selector) : (c ? c + ' ' : '') + this.XSCOPE_NAME + ' ' + selector;
+if (c !== v) {
+if (viaAttr) {
+element.setAttribute(styleTransformer.SCOPE_NAME, v);
+} else {
+element.setAttribute('class', v);
+}
+}
+},
+applyElementStyle: function (element, properties, selector, style) {
+var cssText = style ? style.textContent || '' : this.transformStyles(element, properties, selector);
+var s = element._customStyle;
+if (s && !nativeShadow && s !== style) {
+s._useCount--;
+if (s._useCount <= 0 && s.parentNode) {
+s.parentNode.removeChild(s);
+}
+}
+if (nativeShadow || (!style || !style.parentNode)) {
+if (nativeShadow && element._customStyle) {
+element._customStyle.textContent = cssText;
+style = element._customStyle;
+} else if (cssText) {
+style = styleUtil.applyCss(cssText, selector, nativeShadow ? element.root : null, element._scopeStyle);
+}
+}
+if (style) {
+style._useCount = style._useCount || 0;
+if (element._customStyle != style) {
+style._useCount++;
+}
+element._customStyle = style;
+}
+return style;
+},
+mixinCustomStyle: function (props, customStyle) {
+var v;
+for (var i in customStyle) {
+v = customStyle[i];
+if (v || v === 0) {
+props[i] = v;
+}
+}
+},
+rx: {
+VAR_ASSIGN: /(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}])|$)/gi,
+MIXIN_MATCH: /(?:^|\W+)@apply[\s]*\(([^)]*)\)/i,
+VAR_MATCH: /(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,)]*)|(?:[^;]*\([^;)]*\)))[\s]*?\)/gi,
+VAR_CAPTURE: /\([\s]*(--[^,\s)]*)(?:,[\s]*(--[^,\s)]*))?(?:\)|,)/gi,
+IS_VAR: /^--/,
+BRACKETED: /\{[^}]*\}/g,
+HOST_PREFIX: '(?:^|[^.#[:])',
+HOST_SUFFIX: '($|[.:[\\s>+~])'
+},
+HOST_SELECTORS: [':host'],
+SCOPE_SELECTORS: [':root'],
+XSCOPE_NAME: 'x-scope'
+};
+function addToBitMask(n, bits) {
+var o = parseInt(n / 32);
+var v = 1 << n % 32;
+bits[o] = (bits[o] || 0) | v;
+}
+}();
+(function () {
+Polymer.StyleCache = function () {
+this.cache = {};
+};
+Polymer.StyleCache.prototype = {
+MAX: 100,
+store: function (is, data, keyValues, keyStyles) {
+data.keyValues = keyValues;
+data.styles = keyStyles;
+var s$ = this.cache[is] = this.cache[is] || [];
+s$.push(data);
+if (s$.length > this.MAX) {
+s$.shift();
+}
+},
+retrieve: function (is, keyValues, keyStyles) {
+var cache = this.cache[is];
+if (cache) {
+for (var i = cache.length - 1, data; i >= 0; i--) {
+data = cache[i];
+if (keyStyles === data.styles && this._objectsEqual(keyValues, data.keyValues)) {
+return data;
+}
+}
+}
+},
+clear: function () {
+this.cache = {};
+},
+_objectsEqual: function (target, source) {
+var t, s;
+for (var i in target) {
+t = target[i], s = source[i];
+if (!(typeof t === 'object' && t ? this._objectsStrictlyEqual(t, s) : t === s)) {
+return false;
+}
+}
+if (Array.isArray(target)) {
+return target.length === source.length;
+}
+return true;
+},
+_objectsStrictlyEqual: function (target, source) {
+return this._objectsEqual(target, source) && this._objectsEqual(source, target);
+}
+};
+}());
+Polymer.StyleDefaults = function () {
+var styleProperties = Polymer.StyleProperties;
+var styleUtil = Polymer.StyleUtil;
+var StyleCache = Polymer.StyleCache;
+var api = {
+_styles: [],
+_properties: null,
+customStyle: {},
+_styleCache: new StyleCache(),
+addStyle: function (style) {
+this._styles.push(style);
+this._properties = null;
+},
+get _styleProperties() {
+if (!this._properties) {
+styleProperties.decorateStyles(this._styles);
+this._styles._scopeStyleProperties = null;
+this._properties = styleProperties.scopePropertiesFromStyles(this._styles);
+styleProperties.mixinCustomStyle(this._properties, this.customStyle);
+styleProperties.reify(this._properties);
+}
+return this._properties;
+},
+_needsStyleProperties: function () {
+},
+_computeStyleProperties: function () {
+return this._styleProperties;
+},
+updateStyles: function (properties) {
+this._properties = null;
+if (properties) {
+Polymer.Base.mixin(this.customStyle, properties);
+}
+this._styleCache.clear();
+for (var i = 0, s; i < this._styles.length; i++) {
+s = this._styles[i];
+s = s.__importElement || s;
+s._apply();
+}
+}
+};
+return api;
+}();
+(function () {
+'use strict';
+var serializeValueToAttribute = Polymer.Base.serializeValueToAttribute;
+var propertyUtils = Polymer.StyleProperties;
+var styleTransformer = Polymer.StyleTransformer;
+var styleUtil = Polymer.StyleUtil;
+var styleDefaults = Polymer.StyleDefaults;
+var nativeShadow = Polymer.Settings.useNativeShadow;
+Polymer.Base._addFeature({
+_prepStyleProperties: function () {
+this._ownStylePropertyNames = this._styles ? propertyUtils.decorateStyles(this._styles) : null;
+},
+customStyle: null,
+getComputedStyleValue: function (property) {
+return this._styleProperties && this._styleProperties[property] || getComputedStyle(this).getPropertyValue(property);
+},
+_setupStyleProperties: function () {
+this.customStyle = {};
+this._styleCache = null;
+this._styleProperties = null;
+this._scopeSelector = null;
+this._ownStyleProperties = null;
+this._customStyle = null;
+},
+_needsStyleProperties: function () {
+return Boolean(this._ownStylePropertyNames && this._ownStylePropertyNames.length);
+},
+_beforeAttached: function () {
+if (!this._scopeSelector && this._needsStyleProperties()) {
+this._updateStyleProperties();
+}
+},
+_findStyleHost: function () {
+var e = this, root;
+while (root = Polymer.dom(e).getOwnerRoot()) {
+if (Polymer.isInstance(root.host)) {
+return root.host;
+}
+e = root.host;
+}
+return styleDefaults;
+},
+_updateStyleProperties: function () {
+var info, scope = this._findStyleHost();
+if (!scope._styleCache) {
+scope._styleCache = new Polymer.StyleCache();
+}
+var scopeData = propertyUtils.propertyDataFromStyles(scope._styles, this);
+scopeData.key.customStyle = this.customStyle;
+info = scope._styleCache.retrieve(this.is, scopeData.key, this._styles);
+var scopeCached = Boolean(info);
+if (scopeCached) {
+this._styleProperties = info._styleProperties;
+} else {
+this._computeStyleProperties(scopeData.properties);
+}
+this._computeOwnStyleProperties();
+if (!scopeCached) {
+info = styleCache.retrieve(this.is, this._ownStyleProperties, this._styles);
+}
+var globalCached = Boolean(info) && !scopeCached;
+var style = this._applyStyleProperties(info);
+if (!scopeCached) {
+style = style && nativeShadow ? style.cloneNode(true) : style;
+info = {
+style: style,
+_scopeSelector: this._scopeSelector,
+_styleProperties: this._styleProperties
+};
+scopeData.key.customStyle = {};
+this.mixin(scopeData.key.customStyle, this.customStyle);
+scope._styleCache.store(this.is, info, scopeData.key, this._styles);
+if (!globalCached) {
+styleCache.store(this.is, Object.create(info), this._ownStyleProperties, this._styles);
+}
+}
+},
+_computeStyleProperties: function (scopeProps) {
+var scope = this._findStyleHost();
+if (!scope._styleProperties) {
+scope._computeStyleProperties();
+}
+var props = Object.create(scope._styleProperties);
+this.mixin(props, propertyUtils.hostPropertiesFromStyles(this._styles));
+scopeProps = scopeProps || propertyUtils.propertyDataFromStyles(scope._styles, this).properties;
+this.mixin(props, scopeProps);
+this.mixin(props, propertyUtils.scopePropertiesFromStyles(this._styles));
+propertyUtils.mixinCustomStyle(props, this.customStyle);
+propertyUtils.reify(props);
+this._styleProperties = props;
+},
+_computeOwnStyleProperties: function () {
+var props = {};
+for (var i = 0, n; i < this._ownStylePropertyNames.length; i++) {
+n = this._ownStylePropertyNames[i];
+props[n] = this._styleProperties[n];
+}
+this._ownStyleProperties = props;
+},
+_scopeCount: 0,
+_applyStyleProperties: function (info) {
+var oldScopeSelector = this._scopeSelector;
+this._scopeSelector = info ? info._scopeSelector : this.is + '-' + this.__proto__._scopeCount++;
+var style = propertyUtils.applyElementStyle(this, this._styleProperties, this._scopeSelector, info && info.style);
+if (!nativeShadow) {
+propertyUtils.applyElementScopeSelector(this, this._scopeSelector, oldScopeSelector, this._scopeCssViaAttr);
+}
+return style;
+},
+serializeValueToAttribute: function (value, attribute, node) {
+node = node || this;
+if (attribute === 'class' && !nativeShadow) {
+var host = node === this ? this.domHost || this.dataHost : this;
+if (host) {
+value = host._scopeElementClass(node, value);
+}
+}
+node = this.shadyRoot && this.shadyRoot._hasDistributed ? Polymer.dom(node) : node;
+serializeValueToAttribute.call(this, value, attribute, node);
+},
+_scopeElementClass: function (element, selector) {
+if (!nativeShadow && !this._scopeCssViaAttr) {
+selector += (selector ? ' ' : '') + SCOPE_NAME + ' ' + this.is + (element._scopeSelector ? ' ' + XSCOPE_NAME + ' ' + element._scopeSelector : '');
+}
+return selector;
+},
+updateStyles: function (properties) {
+if (this.isAttached) {
+if (properties) {
+this.mixin(this.customStyle, properties);
+}
+if (this._needsStyleProperties()) {
+this._updateStyleProperties();
+} else {
+this._styleProperties = null;
+}
+if (this._styleCache) {
+this._styleCache.clear();
+}
+this._updateRootStyles();
+}
+},
+_updateRootStyles: function (root) {
+root = root || this.root;
+var c$ = Polymer.dom(root)._query(function (e) {
+return e.shadyRoot || e.shadowRoot;
+});
+for (var i = 0, l = c$.length, c; i < l && (c = c$[i]); i++) {
+if (c.updateStyles) {
+c.updateStyles();
+}
+}
+}
+});
+Polymer.updateStyles = function (properties) {
+styleDefaults.updateStyles(properties);
+Polymer.Base._updateRootStyles(document);
+};
+var styleCache = new Polymer.StyleCache();
+Polymer.customStyleCache = styleCache;
+var SCOPE_NAME = styleTransformer.SCOPE_NAME;
+var XSCOPE_NAME = propertyUtils.XSCOPE_NAME;
+}());
+Polymer.Base._addFeature({
+_registerFeatures: function () {
+this._prepIs();
+this._prepConstructor();
+this._prepTemplate();
+this._prepStyles();
+this._prepStyleProperties();
+this._prepAnnotations();
+this._prepEffects();
+this._prepBehaviors();
+this._prepPropertyInfo();
+this._prepBindings();
+this._prepShady();
+},
+_prepBehavior: function (b) {
+this._addPropertyEffects(b.properties);
+this._addComplexObserverEffects(b.observers);
+this._addHostAttributes(b.hostAttributes);
+},
+_initFeatures: function () {
+this._setupGestures();
+this._setupConfigure();
+this._setupStyleProperties();
+this._setupDebouncers();
+this._setupShady();
+this._registerHost();
+if (this._template) {
+this._poolContent();
+this._beginHosting();
+this._stampTemplate();
+this._endHosting();
+this._marshalAnnotationReferences();
+}
+this._marshalInstanceEffects();
+this._marshalBehaviors();
+this._marshalHostAttributes();
+this._marshalAttributes();
+this._tryReady();
+},
+_marshalBehavior: function (b) {
+if (b.listeners) {
+this._listenListeners(b.listeners);
+}
+}
+});
+(function () {
+var nativeShadow = Polymer.Settings.useNativeShadow;
+var propertyUtils = Polymer.StyleProperties;
+var styleUtil = Polymer.StyleUtil;
+var cssParse = Polymer.CssParse;
+var styleDefaults = Polymer.StyleDefaults;
+var styleTransformer = Polymer.StyleTransformer;
+Polymer({
+is: 'custom-style',
+extends: 'style',
+_template: null,
+properties: { include: String },
+ready: function () {
+this._tryApply();
+},
+attached: function () {
+this._tryApply();
+},
+_tryApply: function () {
+if (!this._appliesToDocument) {
+if (this.parentNode && this.parentNode.localName !== 'dom-module') {
+this._appliesToDocument = true;
+var e = this.__appliedElement || this;
+styleDefaults.addStyle(e);
+if (e.textContent || this.include) {
+this._apply(true);
+} else {
+var self = this;
+var observer = new MutationObserver(function () {
+observer.disconnect();
+self._apply(true);
+});
+observer.observe(e, { childList: true });
+}
+}
+}
+},
+_apply: function (deferProperties) {
+var e = this.__appliedElement || this;
+if (this.include) {
+e.textContent = styleUtil.cssFromModules(this.include, true) + e.textContent;
+}
+if (e.textContent) {
+styleUtil.forEachStyleRule(styleUtil.rulesForStyle(e), function (rule) {
+styleTransformer.documentRule(rule);
+});
+var self = this;
+var fn = function fn() {
+self._applyCustomProperties(e);
+};
+if (this._pendingApplyProperties) {
+cancelAnimationFrame(this._pendingApplyProperties);
+this._pendingApplyProperties = null;
+}
+if (deferProperties) {
+this._pendingApplyProperties = requestAnimationFrame(fn);
+} else {
+fn();
+}
+}
+},
+_applyCustomProperties: function (element) {
+this._computeStyleProperties();
+var props = this._styleProperties;
+var rules = styleUtil.rulesForStyle(element);
+element.textContent = styleUtil.toCssText(rules, function (rule) {
+var css = rule.cssText = rule.parsedCssText;
+if (rule.propertyInfo && rule.propertyInfo.cssText) {
+css = cssParse.removeCustomPropAssignment(css);
+rule.cssText = propertyUtils.valueForProperties(css, props);
+}
+});
+}
+});
+}());
+Polymer.Templatizer = {
+properties: { __hideTemplateChildren__: { observer: '_showHideChildren' } },
+_instanceProps: Polymer.nob,
+_parentPropPrefix: '_parent_',
+templatize: function (template) {
+this._templatized = template;
+if (!template._content) {
+template._content = template.content;
+}
+if (template._content._ctor) {
+this.ctor = template._content._ctor;
+this._prepParentProperties(this.ctor.prototype, template);
+return;
+}
+var archetype = Object.create(Polymer.Base);
+this._customPrepAnnotations(archetype, template);
+this._prepParentProperties(archetype, template);
+archetype._prepEffects();
+this._customPrepEffects(archetype);
+archetype._prepBehaviors();
+archetype._prepPropertyInfo();
+archetype._prepBindings();
+archetype._notifyPathUp = this._notifyPathUpImpl;
+archetype._scopeElementClass = this._scopeElementClassImpl;
+archetype.listen = this._listenImpl;
+archetype._showHideChildren = this._showHideChildrenImpl;
+archetype.__setPropertyOrig = this.__setProperty;
+archetype.__setProperty = this.__setPropertyImpl;
+var _constructor = this._constructorImpl;
+var ctor = function TemplateInstance(model, host) {
+_constructor.call(this, model, host);
+};
+ctor.prototype = archetype;
+archetype.constructor = ctor;
+template._content._ctor = ctor;
+this.ctor = ctor;
+},
+_getRootDataHost: function () {
+return this.dataHost && this.dataHost._rootDataHost || this.dataHost;
+},
+_showHideChildrenImpl: function (hide) {
+var c = this._children;
+for (var i = 0; i < c.length; i++) {
+var n = c[i];
+if (Boolean(hide) != Boolean(n.__hideTemplateChildren__)) {
+if (n.nodeType === Node.TEXT_NODE) {
+if (hide) {
+n.__polymerTextContent__ = n.textContent;
+n.textContent = '';
+} else {
+n.textContent = n.__polymerTextContent__;
+}
+} else if (n.style) {
+if (hide) {
+n.__polymerDisplay__ = n.style.display;
+n.style.display = 'none';
+} else {
+n.style.display = n.__polymerDisplay__;
+}
+}
+}
+n.__hideTemplateChildren__ = hide;
+}
+},
+__setPropertyImpl: function (property, value, fromAbove, node) {
+if (node && node.__hideTemplateChildren__ && property == 'textContent') {
+property = '__polymerTextContent__';
+}
+this.__setPropertyOrig(property, value, fromAbove, node);
+},
+_debounceTemplate: function (fn) {
+Polymer.dom.addDebouncer(this.debounce('_debounceTemplate', fn));
+},
+_flushTemplates: function (debouncerExpired) {
+Polymer.dom.flush();
+},
+_customPrepEffects: function (archetype) {
+var parentProps = archetype._parentProps;
+for (var prop in parentProps) {
+archetype._addPropertyEffect(prop, 'function', this._createHostPropEffector(prop));
+}
+for (var prop in this._instanceProps) {
+archetype._addPropertyEffect(prop, 'function', this._createInstancePropEffector(prop));
+}
+},
+_customPrepAnnotations: function (archetype, template) {
+archetype._template = template;
+var c = template._content;
+if (!c._notes) {
+var rootDataHost = archetype._rootDataHost;
+if (rootDataHost) {
+Polymer.Annotations.prepElement = function () {
+rootDataHost._prepElement();
+};
+}
+c._notes = Polymer.Annotations.parseAnnotations(template);
+Polymer.Annotations.prepElement = null;
+this._processAnnotations(c._notes);
+}
+archetype._notes = c._notes;
+archetype._parentProps = c._parentProps;
+},
+_prepParentProperties: function (archetype, template) {
+var parentProps = this._parentProps = archetype._parentProps;
+if (this._forwardParentProp && parentProps) {
+var proto = archetype._parentPropProto;
+var prop;
+if (!proto) {
+for (prop in this._instanceProps) {
+delete parentProps[prop];
+}
+proto = archetype._parentPropProto = Object.create(null);
+if (template != this) {
+Polymer.Bind.prepareModel(proto);
+Polymer.Base.prepareModelNotifyPath(proto);
+}
+for (prop in parentProps) {
+var parentProp = this._parentPropPrefix + prop;
+var effects = [
+{
+kind: 'function',
+effect: this._createForwardPropEffector(prop),
+fn: Polymer.Bind._functionEffect
+},
+{
+kind: 'notify',
+fn: Polymer.Bind._notifyEffect,
+effect: { event: Polymer.CaseMap.camelToDashCase(parentProp) + '-changed' }
+}
+];
+Polymer.Bind._createAccessors(proto, parentProp, effects);
+}
+}
+var self = this;
+if (template != this) {
+Polymer.Bind.prepareInstance(template);
+template._forwardParentProp = function (source, value) {
+self._forwardParentProp(source, value);
+};
+}
+this._extendTemplate(template, proto);
+template._pathEffector = function (path, value, fromAbove) {
+return self._pathEffectorImpl(path, value, fromAbove);
+};
+}
+},
+_createForwardPropEffector: function (prop) {
+return function (source, value) {
+this._forwardParentProp(prop, value);
+};
+},
+_createHostPropEffector: function (prop) {
+var prefix = this._parentPropPrefix;
+return function (source, value) {
+this.dataHost._templatized[prefix + prop] = value;
+};
+},
+_createInstancePropEffector: function (prop) {
+return function (source, value, old, fromAbove) {
+if (!fromAbove) {
+this.dataHost._forwardInstanceProp(this, prop, value);
+}
+};
+},
+_extendTemplate: function (template, proto) {
+var n$ = Object.getOwnPropertyNames(proto);
+for (var i = 0, n; i < n$.length && (n = n$[i]); i++) {
+var val = template[n];
+var pd = Object.getOwnPropertyDescriptor(proto, n);
+Object.defineProperty(template, n, pd);
+if (val !== undefined) {
+template._propertySetter(n, val);
+}
+}
+},
+_showHideChildren: function (hidden) {
+},
+_forwardInstancePath: function (inst, path, value) {
+},
+_forwardInstanceProp: function (inst, prop, value) {
+},
+_notifyPathUpImpl: function (path, value) {
+var dataHost = this.dataHost;
+var dot = path.indexOf('.');
+var root = dot < 0 ? path : path.slice(0, dot);
+dataHost._forwardInstancePath.call(dataHost, this, path, value);
+if (root in dataHost._parentProps) {
+dataHost._templatized.notifyPath(dataHost._parentPropPrefix + path, value);
+}
+},
+_pathEffectorImpl: function (path, value, fromAbove) {
+if (this._forwardParentPath) {
+if (path.indexOf(this._parentPropPrefix) === 0) {
+var subPath = path.substring(this._parentPropPrefix.length);
+var model = this._modelForPath(subPath);
+if (model in this._parentProps) {
+this._forwardParentPath(subPath, value);
+}
+}
+}
+Polymer.Base._pathEffector.call(this._templatized, path, value, fromAbove);
+},
+_constructorImpl: function (model, host) {
+this._rootDataHost = host._getRootDataHost();
+this._setupConfigure(model);
+this._registerHost(host);
+this._beginHosting();
+this.root = this.instanceTemplate(this._template);
+this.root.__noContent = !this._notes._hasContent;
+this.root.__styleScoped = true;
+this._endHosting();
+this._marshalAnnotatedNodes();
+this._marshalInstanceEffects();
+this._marshalAnnotatedListeners();
+var children = [];
+for (var n = this.root.firstChild; n; n = n.nextSibling) {
+children.push(n);
+n._templateInstance = this;
+}
+this._children = children;
+if (host.__hideTemplateChildren__) {
+this._showHideChildren(true);
+}
+this._tryReady();
+},
+_listenImpl: function (node, eventName, methodName) {
+var model = this;
+var host = this._rootDataHost;
+var handler = host._createEventHandler(node, eventName, methodName);
+var decorated = function (e) {
+e.model = model;
+handler(e);
+};
+host._listen(node, eventName, decorated);
+},
+_scopeElementClassImpl: function (node, value) {
+var host = this._rootDataHost;
+if (host) {
+return host._scopeElementClass(node, value);
+}
+},
+stamp: function (model) {
+model = model || {};
+if (this._parentProps) {
+var templatized = this._templatized;
+for (var prop in this._parentProps) {
+model[prop] = templatized[this._parentPropPrefix + prop];
+}
+}
+return new this.ctor(model, this);
+},
+modelForElement: function (el) {
+var model;
+while (el) {
+if (model = el._templateInstance) {
+if (model.dataHost != this) {
+el = model.dataHost;
+} else {
+return model;
+}
+} else {
+el = el.parentNode;
+}
+}
+}
+};
+Polymer({
+is: 'dom-template',
+extends: 'template',
+_template: null,
+behaviors: [Polymer.Templatizer],
+ready: function () {
+this.templatize(this);
+}
+});
+Polymer._collections = new WeakMap();
+Polymer.Collection = function (userArray) {
+Polymer._collections.set(userArray, this);
+this.userArray = userArray;
+this.store = userArray.slice();
+this.initMap();
+};
+Polymer.Collection.prototype = {
+constructor: Polymer.Collection,
+initMap: function () {
+var omap = this.omap = new WeakMap();
+var pmap = this.pmap = {};
+var s = this.store;
+for (var i = 0; i < s.length; i++) {
+var item = s[i];
+if (item && typeof item == 'object') {
+omap.set(item, i);
+} else {
+pmap[item] = i;
+}
+}
+},
+add: function (item) {
+var key = this.store.push(item) - 1;
+if (item && typeof item == 'object') {
+this.omap.set(item, key);
+} else {
+this.pmap[item] = key;
+}
+return '#' + key;
+},
+removeKey: function (key) {
+if (key = this._parseKey(key)) {
+this._removeFromMap(this.store[key]);
+delete this.store[key];
+}
+},
+_removeFromMap: function (item) {
+if (item && typeof item == 'object') {
+this.omap.delete(item);
+} else {
+delete this.pmap[item];
+}
+},
+remove: function (item) {
+var key = this.getKey(item);
+this.removeKey(key);
+return key;
+},
+getKey: function (item) {
+var key;
+if (item && typeof item == 'object') {
+key = this.omap.get(item);
+} else {
+key = this.pmap[item];
+}
+if (key != undefined) {
+return '#' + key;
+}
+},
+getKeys: function () {
+return Object.keys(this.store).map(function (key) {
+return '#' + key;
+});
+},
+_parseKey: function (key) {
+if (key && key[0] == '#') {
+return key.slice(1);
+}
+},
+setItem: function (key, item) {
+if (key = this._parseKey(key)) {
+var old = this.store[key];
+if (old) {
+this._removeFromMap(old);
+}
+if (item && typeof item == 'object') {
+this.omap.set(item, key);
+} else {
+this.pmap[item] = key;
+}
+this.store[key] = item;
+}
+},
+getItem: function (key) {
+if (key = this._parseKey(key)) {
+return this.store[key];
+}
+},
+getItems: function () {
+var items = [], store = this.store;
+for (var key in store) {
+items.push(store[key]);
+}
+return items;
+},
+_applySplices: function (splices) {
+var keyMap = {}, key;
+for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
+s.addedKeys = [];
+for (var j = 0; j < s.removed.length; j++) {
+key = this.getKey(s.removed[j]);
+keyMap[key] = keyMap[key] ? null : -1;
+}
+for (var j = 0; j < s.addedCount; j++) {
+var item = this.userArray[s.index + j];
+key = this.getKey(item);
+key = key === undefined ? this.add(item) : key;
+keyMap[key] = keyMap[key] ? null : 1;
+s.addedKeys.push(key);
+}
+}
+var removed = [];
+var added = [];
+for (var key in keyMap) {
+if (keyMap[key] < 0) {
+this.removeKey(key);
+removed.push(key);
+}
+if (keyMap[key] > 0) {
+added.push(key);
+}
+}
+return [{
+removed: removed,
+added: added
+}];
+}
+};
+Polymer.Collection.get = function (userArray) {
+return Polymer._collections.get(userArray) || new Polymer.Collection(userArray);
+};
+Polymer.Collection.applySplices = function (userArray, splices) {
+var coll = Polymer._collections.get(userArray);
+return coll ? coll._applySplices(splices) : null;
+};
+Polymer({
+is: 'dom-repeat',
+extends: 'template',
+_template: null,
+properties: {
+items: { type: Array },
+as: {
+type: String,
+value: 'item'
+},
+indexAs: {
+type: String,
+value: 'index'
+},
+sort: {
+type: Function,
+observer: '_sortChanged'
+},
+filter: {
+type: Function,
+observer: '_filterChanged'
+},
+observe: {
+type: String,
+observer: '_observeChanged'
+},
+delay: Number,
+renderedItemCount: {
+type: Number,
+notify: true,
+readOnly: true
+},
+initialCount: {
+type: Number,
+observer: '_initializeChunking'
+},
+targetFramerate: {
+type: Number,
+value: 20
+},
+_targetFrameTime: {
+type: Number,
+computed: '_computeFrameTime(targetFramerate)'
+}
+},
+behaviors: [Polymer.Templatizer],
+observers: ['_itemsChanged(items.*)'],
+created: function () {
+this._instances = [];
+this._pool = [];
+this._limit = Infinity;
+var self = this;
+this._boundRenderChunk = function () {
+self._renderChunk();
+};
+},
+detached: function () {
+this.__isDetached = true;
+for (var i = 0; i < this._instances.length; i++) {
+this._detachInstance(i);
+}
+},
+attached: function () {
+if (this.__isDetached) {
+this.__isDetached = false;
+var parent = Polymer.dom(Polymer.dom(this).parentNode);
+for (var i = 0; i < this._instances.length; i++) {
+this._attachInstance(i, parent);
+}
+}
+},
+ready: function () {
+this._instanceProps = { __key__: true };
+this._instanceProps[this.as] = true;
+this._instanceProps[this.indexAs] = true;
+if (!this.ctor) {
+this.templatize(this);
+}
+},
+_sortChanged: function (sort) {
+var dataHost = this._getRootDataHost();
+this._sortFn = sort && (typeof sort == 'function' ? sort : function () {
+return dataHost[sort].apply(dataHost, arguments);
+});
+this._needFullRefresh = true;
+if (this.items) {
+this._debounceTemplate(this._render);
+}
+},
+_filterChanged: function (filter) {
+var dataHost = this._getRootDataHost();
+this._filterFn = filter && (typeof filter == 'function' ? filter : function () {
+return dataHost[filter].apply(dataHost, arguments);
+});
+this._needFullRefresh = true;
+if (this.items) {
+this._debounceTemplate(this._render);
+}
+},
+_computeFrameTime: function (rate) {
+return Math.ceil(1000 / rate);
+},
+_initializeChunking: function () {
+if (this.initialCount) {
+this._limit = this.initialCount;
+this._chunkCount = this.initialCount;
+this._lastChunkTime = performance.now();
+}
+},
+_tryRenderChunk: function () {
+if (this.items && this._limit < this.items.length) {
+this.debounce('renderChunk', this._requestRenderChunk);
+}
+},
+_requestRenderChunk: function () {
+requestAnimationFrame(this._boundRenderChunk);
+},
+_renderChunk: function () {
+var currChunkTime = performance.now();
+var ratio = this._targetFrameTime / (currChunkTime - this._lastChunkTime);
+this._chunkCount = Math.round(this._chunkCount * ratio) || 1;
+this._limit += this._chunkCount;
+this._lastChunkTime = currChunkTime;
+this._debounceTemplate(this._render);
+},
+_observeChanged: function () {
+this._observePaths = this.observe && this.observe.replace('.*', '.').split(' ');
+},
+_itemsChanged: function (change) {
+if (change.path == 'items') {
+if (Array.isArray(this.items)) {
+this.collection = Polymer.Collection.get(this.items);
+} else if (!this.items) {
+this.collection = null;
+} else {
+this._error(this._logf('dom-repeat', 'expected array for `items`,' + ' found', this.items));
+}
+this._keySplices = [];
+this._indexSplices = [];
+this._needFullRefresh = true;
+this._initializeChunking();
+this._debounceTemplate(this._render);
+} else if (change.path == 'items.splices') {
+this._keySplices = this._keySplices.concat(change.value.keySplices);
+this._indexSplices = this._indexSplices.concat(change.value.indexSplices);
+this._debounceTemplate(this._render);
+} else {
+var subpath = change.path.slice(6);
+this._forwardItemPath(subpath, change.value);
+this._checkObservedPaths(subpath);
+}
+},
+_checkObservedPaths: function (path) {
+if (this._observePaths) {
+path = path.substring(path.indexOf('.') + 1);
+var paths = this._observePaths;
+for (var i = 0; i < paths.length; i++) {
+if (path.indexOf(paths[i]) === 0) {
+this._needFullRefresh = true;
+if (this.delay) {
+this.debounce('render', this._render, this.delay);
+} else {
+this._debounceTemplate(this._render);
+}
+return;
+}
+}
+}
+},
+render: function () {
+this._needFullRefresh = true;
+this._debounceTemplate(this._render);
+this._flushTemplates();
+},
+_render: function () {
+var c = this.collection;
+if (this._needFullRefresh) {
+this._applyFullRefresh();
+this._needFullRefresh = false;
+} else if (this._keySplices.length) {
+if (this._sortFn) {
+this._applySplicesUserSort(this._keySplices);
+} else {
+if (this._filterFn) {
+this._applyFullRefresh();
+} else {
+this._applySplicesArrayOrder(this._indexSplices);
+}
+}
+} else {
+}
+this._keySplices = [];
+this._indexSplices = [];
+var keyToIdx = this._keyToInstIdx = {};
+for (var i = this._instances.length - 1; i >= 0; i--) {
+var inst = this._instances[i];
+if (inst.isPlaceholder && i < this._limit) {
+inst = this._insertInstance(i, inst.__key__);
+} else if (!inst.isPlaceholder && i >= this._limit) {
+inst = this._downgradeInstance(i, inst.__key__);
+}
+keyToIdx[inst.__key__] = i;
+if (!inst.isPlaceholder) {
+inst.__setProperty(this.indexAs, i, true);
+}
+}
+this._pool.length = 0;
+this._setRenderedItemCount(this._instances.length);
+this.fire('dom-change');
+this._tryRenderChunk();
+},
+_applyFullRefresh: function () {
+var c = this.collection;
+var keys;
+if (this._sortFn) {
+keys = c ? c.getKeys() : [];
+} else {
+keys = [];
+var items = this.items;
+if (items) {
+for (var i = 0; i < items.length; i++) {
+keys.push(c.getKey(items[i]));
+}
+}
+}
+var self = this;
+if (this._filterFn) {
+keys = keys.filter(function (a) {
+return self._filterFn(c.getItem(a));
+});
+}
+if (this._sortFn) {
+keys.sort(function (a, b) {
+return self._sortFn(c.getItem(a), c.getItem(b));
+});
+}
+for (var i = 0; i < keys.length; i++) {
+var key = keys[i];
+var inst = this._instances[i];
+if (inst) {
+inst.__key__ = key;
+if (!inst.isPlaceholder && i < this._limit) {
+inst.__setProperty(this.as, c.getItem(key), true);
+}
+} else if (i < this._limit) {
+this._insertInstance(i, key);
+} else {
+this._insertPlaceholder(i, key);
+}
+}
+for (var j = this._instances.length - 1; j >= i; j--) {
+this._detachAndRemoveInstance(j);
+}
+},
+_numericSort: function (a, b) {
+return a - b;
+},
+_applySplicesUserSort: function (splices) {
+var c = this.collection;
+var instances = this._instances;
+var keyMap = {};
+for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
+for (var j = 0; j < s.removed.length; j++) {
+var key = s.removed[j];
+keyMap[key] = keyMap[key] ? null : -1;
+}
+for (var j = 0; j < s.added.length; j++) {
+var key = s.added[j];
+keyMap[key] = keyMap[key] ? null : 1;
+}
+}
+var removedIdxs = [];
+var addedKeys = [];
+for (var key in keyMap) {
+if (keyMap[key] === -1) {
+removedIdxs.push(this._keyToInstIdx[key]);
+}
+if (keyMap[key] === 1) {
+addedKeys.push(key);
+}
+}
+if (removedIdxs.length) {
+removedIdxs.sort(this._numericSort);
+for (var i = removedIdxs.length - 1; i >= 0; i--) {
+var idx = removedIdxs[i];
+if (idx !== undefined) {
+this._detachAndRemoveInstance(idx);
+}
+}
+}
+var self = this;
+if (addedKeys.length) {
+if (this._filterFn) {
+addedKeys = addedKeys.filter(function (a) {
+return self._filterFn(c.getItem(a));
+});
+}
+addedKeys.sort(function (a, b) {
+return self._sortFn(c.getItem(a), c.getItem(b));
+});
+var start = 0;
+for (var i = 0; i < addedKeys.length; i++) {
+start = this._insertRowUserSort(start, addedKeys[i]);
+}
+}
+},
+_insertRowUserSort: function (start, key) {
+var c = this.collection;
+var item = c.getItem(key);
+var end = this._instances.length - 1;
+var idx = -1;
+while (start <= end) {
+var mid = start + end >> 1;
+var midKey = this._instances[mid].__key__;
+var cmp = this._sortFn(c.getItem(midKey), item);
+if (cmp < 0) {
+start = mid + 1;
+} else if (cmp > 0) {
+end = mid - 1;
+} else {
+idx = mid;
+break;
+}
+}
+if (idx < 0) {
+idx = end + 1;
+}
+this._insertPlaceholder(idx, key);
+return idx;
+},
+_applySplicesArrayOrder: function (splices) {
+var c = this.collection;
+for (var i = 0, s; i < splices.length && (s = splices[i]); i++) {
+for (var j = 0; j < s.removed.length; j++) {
+this._detachAndRemoveInstance(s.index);
+}
+for (var j = 0; j < s.addedKeys.length; j++) {
+this._insertPlaceholder(s.index + j, s.addedKeys[j]);
+}
+}
+},
+_detachInstance: function (idx) {
+var inst = this._instances[idx];
+if (!inst.isPlaceholder) {
+for (var i = 0; i < inst._children.length; i++) {
+var el = inst._children[i];
+Polymer.dom(inst.root).appendChild(el);
+}
+return inst;
+}
+},
+_attachInstance: function (idx, parent) {
+var inst = this._instances[idx];
+if (!inst.isPlaceholder) {
+parent.insertBefore(inst.root, this);
+}
+},
+_detachAndRemoveInstance: function (idx) {
+var inst = this._detachInstance(idx);
+if (inst) {
+this._pool.push(inst);
+}
+this._instances.splice(idx, 1);
+},
+_insertPlaceholder: function (idx, key) {
+this._instances.splice(idx, 0, {
+isPlaceholder: true,
+__key__: key
+});
+},
+_stampInstance: function (idx, key) {
+var model = { __key__: key };
+model[this.as] = this.collection.getItem(key);
+model[this.indexAs] = idx;
+return this.stamp(model);
+},
+_insertInstance: function (idx, key) {
+var inst = this._pool.pop();
+if (inst) {
+inst.__setProperty(this.as, this.collection.getItem(key), true);
+inst.__setProperty('__key__', key, true);
+} else {
+inst = this._stampInstance(idx, key);
+}
+var beforeRow = this._instances[idx + 1];
+var beforeNode = beforeRow && !beforeRow.isPlaceholder ? beforeRow._children[0] : this;
+var parentNode = Polymer.dom(this).parentNode;
+Polymer.dom(parentNode).insertBefore(inst.root, beforeNode);
+this._instances[idx] = inst;
+return inst;
+},
+_downgradeInstance: function (idx, key) {
+var inst = this._detachInstance(idx);
+if (inst) {
+this._pool.push(inst);
+}
+inst = {
+isPlaceholder: true,
+__key__: key
+};
+this._instances[idx] = inst;
+return inst;
+},
+_showHideChildren: function (hidden) {
+for (var i = 0; i < this._instances.length; i++) {
+this._instances[i]._showHideChildren(hidden);
+}
+},
+_forwardInstanceProp: function (inst, prop, value) {
+if (prop == this.as) {
+var idx;
+if (this._sortFn || this._filterFn) {
+idx = this.items.indexOf(this.collection.getItem(inst.__key__));
+} else {
+idx = inst[this.indexAs];
+}
+this.set('items.' + idx, value);
+}
+},
+_forwardInstancePath: function (inst, path, value) {
+if (path.indexOf(this.as + '.') === 0) {
+this._notifyPath('items.' + inst.__key__ + '.' + path.slice(this.as.length + 1), value);
+}
+},
+_forwardParentProp: function (prop, value) {
+var i$ = this._instances;
+for (var i = 0, inst; i < i$.length && (inst = i$[i]); i++) {
+if (!inst.isPlaceholder) {
+inst.__setProperty(prop, value, true);
+}
+}
+},
+_forwardParentPath: function (path, value) {
+var i$ = this._instances;
+for (var i = 0, inst; i < i$.length && (inst = i$[i]); i++) {
+if (!inst.isPlaceholder) {
+inst._notifyPath(path, value, true);
+}
+}
+},
+_forwardItemPath: function (path, value) {
+if (this._keyToInstIdx) {
+var dot = path.indexOf('.');
+var key = path.substring(0, dot < 0 ? path.length : dot);
+var idx = this._keyToInstIdx[key];
+var inst = this._instances[idx];
+if (inst && !inst.isPlaceholder) {
+if (dot >= 0) {
+path = this.as + '.' + path.substring(dot + 1);
+inst._notifyPath(path, value, true);
+} else {
+inst.__setProperty(this.as, value, true);
+}
+}
+}
+},
+itemForElement: function (el) {
+var instance = this.modelForElement(el);
+return instance && instance[this.as];
+},
+keyForElement: function (el) {
+var instance = this.modelForElement(el);
+return instance && instance.__key__;
+},
+indexForElement: function (el) {
+var instance = this.modelForElement(el);
+return instance && instance[this.indexAs];
+}
+});
+Polymer({
+is: 'array-selector',
+_template: null,
+properties: {
+items: {
+type: Array,
+observer: 'clearSelection'
+},
+multi: {
+type: Boolean,
+value: false,
+observer: 'clearSelection'
+},
+selected: {
+type: Object,
+notify: true
+},
+selectedItem: {
+type: Object,
+notify: true
+},
+toggle: {
+type: Boolean,
+value: false
+}
+},
+clearSelection: function () {
+if (Array.isArray(this.selected)) {
+for (var i = 0; i < this.selected.length; i++) {
+this.unlinkPaths('selected.' + i);
+}
+} else {
+this.unlinkPaths('selected');
+this.unlinkPaths('selectedItem');
+}
+if (this.multi) {
+if (!this.selected || this.selected.length) {
+this.selected = [];
+this._selectedColl = Polymer.Collection.get(this.selected);
+}
+} else {
+this.selected = null;
+this._selectedColl = null;
+}
+this.selectedItem = null;
+},
+isSelected: function (item) {
+if (this.multi) {
+return this._selectedColl.getKey(item) !== undefined;
+} else {
+return this.selected == item;
+}
+},
+deselect: function (item) {
+if (this.multi) {
+if (this.isSelected(item)) {
+var skey = this._selectedColl.getKey(item);
+this.arrayDelete('selected', item);
+this.unlinkPaths('selected.' + skey);
+}
+} else {
+this.selected = null;
+this.selectedItem = null;
+this.unlinkPaths('selected');
+this.unlinkPaths('selectedItem');
+}
+},
+select: function (item) {
+var icol = Polymer.Collection.get(this.items);
+var key = icol.getKey(item);
+if (this.multi) {
+if (this.isSelected(item)) {
+if (this.toggle) {
+this.deselect(item);
+}
+} else {
+this.push('selected', item);
+var skey = this._selectedColl.getKey(item);
+this.linkPaths('selected.' + skey, 'items.' + key);
+}
+} else {
+if (this.toggle && item == this.selected) {
+this.deselect();
+} else {
+this.selected = item;
+this.selectedItem = item;
+this.linkPaths('selected', 'items.' + key);
+this.linkPaths('selectedItem', 'items.' + key);
+}
+}
+}
+});
+Polymer({
+is: 'dom-if',
+extends: 'template',
+_template: null,
+properties: {
+'if': {
+type: Boolean,
+value: false,
+observer: '_queueRender'
+},
+restamp: {
+type: Boolean,
+value: false,
+observer: '_queueRender'
+}
+},
+behaviors: [Polymer.Templatizer],
+_queueRender: function () {
+this._debounceTemplate(this._render);
+},
+detached: function () {
+if (!this.parentNode || this.parentNode.nodeType == Node.DOCUMENT_FRAGMENT_NODE && (!Polymer.Settings.hasShadow || !(this.parentNode instanceof ShadowRoot))) {
+this._teardownInstance();
+}
+},
+attached: function () {
+if (this.if && this.ctor) {
+this.async(this._ensureInstance);
+}
+},
+render: function () {
+this._flushTemplates();
+},
+_render: function () {
+if (this.if) {
+if (!this.ctor) {
+this.templatize(this);
+}
+this._ensureInstance();
+this._showHideChildren();
+} else if (this.restamp) {
+this._teardownInstance();
+}
+if (!this.restamp && this._instance) {
+this._showHideChildren();
+}
+if (this.if != this._lastIf) {
+this.fire('dom-change');
+this._lastIf = this.if;
+}
+},
+_ensureInstance: function () {
+var parentNode = Polymer.dom(this).parentNode;
+if (parentNode) {
+var parent = Polymer.dom(parentNode);
+if (!this._instance) {
+this._instance = this.stamp();
+var root = this._instance.root;
+parent.insertBefore(root, this);
+} else {
+var c$ = this._instance._children;
+if (c$ && c$.length) {
+var lastChild = Polymer.dom(this).previousSibling;
+if (lastChild !== c$[c$.length - 1]) {
+for (var i = 0, n; i < c$.length && (n = c$[i]); i++) {
+parent.insertBefore(n, this);
+}
+}
+}
+}
+}
+},
+_teardownInstance: function () {
+if (this._instance) {
+var c$ = this._instance._children;
+if (c$ && c$.length) {
+var parent = Polymer.dom(Polymer.dom(c$[0]).parentNode);
+for (var i = 0, n; i < c$.length && (n = c$[i]); i++) {
+parent.removeChild(n);
+}
+}
+this._instance = null;
+}
+},
+_showHideChildren: function () {
+var hidden = this.__hideTemplateChildren__ || !this.if;
+if (this._instance) {
+this._instance._showHideChildren(hidden);
+}
+},
+_forwardParentProp: function (prop, value) {
+if (this._instance) {
+this._instance[prop] = value;
+}
+},
+_forwardParentPath: function (path, value) {
+if (this._instance) {
+this._instance._notifyPath(path, value, true);
+}
+}
+});
+Polymer({
+is: 'dom-bind',
+extends: 'template',
+_template: null,
+created: function () {
+var self = this;
+Polymer.RenderStatus.whenReady(function () {
+self._markImportsReady();
+});
+},
+_ensureReady: function () {
+if (!this._readied) {
+this._readySelf();
+}
+},
+_markImportsReady: function () {
+this._importsReady = true;
+this._ensureReady();
+},
+_registerFeatures: function () {
+this._prepConstructor();
+},
+_insertChildren: function () {
+var parentDom = Polymer.dom(Polymer.dom(this).parentNode);
+parentDom.insertBefore(this.root, this);
+},
+_removeChildren: function () {
+if (this._children) {
+for (var i = 0; i < this._children.length; i++) {
+this.root.appendChild(this._children[i]);
+}
+}
+},
+_initFeatures: function () {
+},
+_scopeElementClass: function (element, selector) {
+if (this.dataHost) {
+return this.dataHost._scopeElementClass(element, selector);
+} else {
+return selector;
+}
+},
+_prepConfigure: function () {
+var config = {};
+for (var prop in this._propertyEffects) {
+config[prop] = this[prop];
+}
+var setupConfigure = this._setupConfigure;
+this._setupConfigure = function () {
+setupConfigure.call(this, config);
+};
+},
+attached: function () {
+if (this._importsReady) {
+this.render();
+}
+},
+detached: function () {
+this._removeChildren();
+},
+render: function () {
+this._ensureReady();
+if (!this._children) {
+this._template = this;
+this._prepAnnotations();
+this._prepEffects();
+this._prepBehaviors();
+this._prepConfigure();
+this._prepBindings();
+this._prepPropertyInfo();
+Polymer.Base._initFeatures.call(this);
+this._children = Polymer.TreeApi.arrayCopyChildNodes(this.root);
+}
+this._insertChildren();
+this.fire('dom-change');
+}
+});</script>
diff --git a/Software/Embedded_SW/.jxbrowser-data/Cache/f_00000e b/Software/Embedded_SW/.jxbrowser-data/Cache/f_00000e
new file mode 100644
index 000000000..1a981f34a
--- /dev/null
+++ b/Software/Embedded_SW/.jxbrowser-data/Cache/f_00000e
@@ -0,0 +1,599 @@
+<!--
+@license
+Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
+This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
+The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
+The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
+Code distributed by Google as part of the polymer project is also
+subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
+-->
+
+<link rel="import" href="../polymer/polymer.html">
+<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="../paper-styles/color.html">
+<link rel="import" href="../paper-styles/default-theme.html">
+<link rel="import" href="../paper-styles/typography.html">
+
+<!--
+`<paper-input-container>` is a container for a `<label>`, an `<input is="iron-input">` or
+`<iron-autogrow-textarea>` and optional add-on elements such as an error message or character
+counter, used to implement Material Design text fields.
+
+For example:
+
+ <paper-input-container>
+ <label>Your name</label>
+ <input is="iron-input">
+ </paper-input-container>
+
+### Listening for input changes
+
+By default, it listens for changes on the `bind-value` attribute on its children nodes and perform
+tasks such as auto-validating and label styling when the `bind-value` changes. You can configure
+the attribute it listens to with the `attr-for-value` attribute.
+
+### Using a custom input element
+
+You can use a custom input element in a `<paper-input-container>`, for example to implement a
+compound input field like a social security number input. The custom input element should have the
+`paper-input-input` class, have a `notify:true` value property and optionally implements
+`Polymer.IronValidatableBehavior` if it is validatable.
+
+ <paper-input-container attr-for-value="ssn-value">
+ <label>Social security number</label>
+ <ssn-input class="paper-input-input"></ssn-input>
+ </paper-input-container>
+
+### Validation
+
+If the `auto-validate` attribute is set, the input container will validate the input and update
+the container styling when the input value changes.
+
+### Add-ons
+
+Add-ons are child elements of a `<paper-input-container>` with the `add-on` attribute and
+implements the `Polymer.PaperInputAddonBehavior` behavior. They are notified when the input value
+or validity changes, and may implement functionality such as error messages or character counters.
+They appear at the bottom of the input.
+
+### Prefixes and suffixes
+These are child elements of a `<paper-input-container>` with the `prefix`
+or `suffix` attribute, and are displayed inline with the input, before or after.
+
+ <paper-input-container>
+ <div prefix>$</div>
+ <label>Total</label>
+ <input is="iron-input">
+ <paper-icon-button suffix icon="clear"></paper-icon-button>
+ </paper-input-container>
+
+### Styling
+
+The following custom properties and mixins are available for styling:
+
+Custom property | Description | Default
+----------------|-------------|----------
+`--paper-input-container-color` | Label and underline color when the input is not focused | `--secondary-text-color`
+`--paper-input-container-focus-color` | Label and underline color when the input is focused | `--default-primary-color`
+`--paper-input-container-invalid-color` | Label and underline color when the input is is invalid | `--google-red-500`
+`--paper-input-container-input-color` | Input foreground color | `--primary-text-color`
+`--paper-input-container` | Mixin applied to the container | `{}`
+`--paper-input-container-disabled` | Mixin applied to the container when it's disabled | `{}`
+`--paper-input-container-label` | Mixin applied to the label | `{}`
+`--paper-input-container-label-focus` | Mixin applied to the label when the input is focused | `{}`
+`--paper-input-container-label-floating` | Mixin applied to the label when floating | `{}`
+`--paper-input-container-input` | Mixin applied to the input | `{}`
+`--paper-input-container-underline` | Mixin applied to the underline | `{}`
+`--paper-input-container-underline-focus` | Mixin applied to the underline when the input is focused | `{}`
+`--paper-input-container-underline-disabled` | Mixin applied to the underline when the input is disabled | `{}`
+`--paper-input-prefix` | Mixin applied to the input prefix | `{}`
+`--paper-input-suffix` | Mixin applied to the input suffix | `{}`
+
+This element is `display:block` by default, but you can set the `inline` attribute to make it
+`display:inline-block`.
+-->
+
+<dom-module id="paper-input-container">
+ <template>
+ <style>
+ :host {
+ display: block;
+ padding: 8px 0;
+
+ @apply(--paper-input-container);
+ }
+
+ :host[inline] {
+ display: inline-block;
+ }
+
+ :host([disabled]) {
+ pointer-events: none;
+ opacity: 0.33;
+
+ @apply(--paper-input-container-disabled);
+ }
+
+ .floated-label-placeholder {
+ @apply(--paper-font-caption);
+ }
+
+ .underline {
+ position: relative;
+ }
+
+ .focused-line {
+ @apply(--layout-fit);
+
+ background: var(--paper-input-container-focus-color, --default-primary-color);
+ height: 2px;
+ -webkit-transform-origin: center center;
+ transform-origin: center center;
+ -webkit-transform: scale3d(0,1,1);
+ transform: scale3d(0,1,1);
+
+ @apply(--paper-input-container-underline-focus);
+ }
+
+ .underline.is-highlighted .focused-line {
+ -webkit-transform: none;
+ transform: none;
+ -webkit-transition: -webkit-transform 0.25s;
+ transition: transform 0.25s;
+
+ @apply(--paper-transition-easing);
+ }
+
+ .underline.is-invalid .focused-line {
+ background: var(--paper-input-container-invalid-color, --google-red-500);
+ -webkit-transform: none;
+ transform: none;
+ -webkit-transition: -webkit-transform 0.25s;
+ transition: transform 0.25s;
+
+ @apply(--paper-transition-easing);
+ }
+
+ .unfocused-line {
+ @apply(--layout-fit);
+
+ height: 1px;
+ background: var(--paper-input-container-color, --secondary-text-color);
+
+ @apply(--paper-input-container-underline);
+ }
+
+ :host([disabled]) .unfocused-line {
+ border-bottom: 1px dashed;
+ border-color: var(--paper-input-container-color, --secondary-text-color);
+ background: transparent;
+
+ @apply(--paper-input-container-underline-disabled);
+ }
+
+ .label-and-input-container {
+ @apply(--layout-flex);
+ @apply(--layout-relative);
+ }
+
+ .input-content {
+ @apply(--layout-horizontal);
+ @apply(--layout-center);
+
+ position: relative;
+ }
+
+ .input-content ::content label,
+ .input-content ::content .paper-input-label {
+ position: absolute;
+ top: 0;
+ right: 0;
+ left: 0;
+ font: inherit;
+ color: var(--paper-input-container-color, --secondary-text-color);
+
+ @apply(--paper-font-common-nowrap);
+ @apply(--paper-font-subhead);
+ @apply(--paper-input-container-label);
+ }
+
+ .input-content.label-is-floating ::content label,
+ .input-content.label-is-floating ::content .paper-input-label {
+ -webkit-transform: translateY(-75%) scale(0.75);
+ transform: translateY(-75%) scale(0.75);
+ -webkit-transition: -webkit-transform 0.25s;
+ transition: transform 0.25s;
+ -webkit-transform-origin: left top;
+ transform-origin: left top;
+
+ /* Since we scale to 75/100 of the size, we actually have 100/75 of the
+ original space now available */
+ width: 133%;
+
+ @apply(--paper-transition-easing);
+ @apply(--paper-input-container-label-floating);
+ }
+
+ :host-context([dir="rtl"]) .input-content.label-is-floating ::content label,
+ :host-context([dir="rtl"]) .input-content.label-is-floating ::content .paper-input-label {
+ /* TODO(noms): Figure out why leaving the width at 133% before the animation
+ * actually makes
+ * it wider on the right side, not left side, as you would expect in RTL */
+ width: 100%;
+ -webkit-transform-origin: right top;
+ transform-origin: right top;
+ }
+
+ .input-content.label-is-highlighted ::content label,
+ .input-content.label-is-highlighted ::content .paper-input-label {
+ color: var(--paper-input-container-focus-color, --default-primary-color);
+
+ @apply(--paper-input-container-label-focus);
+ }
+
+ .input-content.is-invalid ::content label,
+ .input-content.is-invalid ::content .paper-input-label {
+ color: var(--paper-input-container-invalid-color, --google-red-500);
+ }
+
+ .input-content.label-is-hidden ::content label,
+ .input-content.label-is-hidden ::content .paper-input-label {
+ visibility: hidden;
+ }
+
+ .input-content ::content input,
+ .input-content ::content textarea,
+ .input-content ::content iron-autogrow-textarea,
+ .input-content ::content .paper-input-input {
+ position: relative; /* to make a stacking context */
+ outline: none;
+ box-shadow: none;
+ padding: 0;
+ width: 100%;
+ background: transparent;
+ border: none;
+ color: var(--paper-input-container-input-color, --primary-text-color);
+ -webkit-appearance: none;
+ text-align: inherit;
+
+ @apply(--paper-font-subhead);
+ @apply(--paper-input-container-input);
+ }
+
+ ::content [prefix] {
+ @apply(--paper-font-subhead);
+ @apply(--paper-input-prefix);
+ }
+
+ ::content [suffix] {
+ @apply(--paper-font-subhead);
+ @apply(--paper-input-suffix);
+ }
+
+ /* Firefox sets a min-width on the input, which can cause layout issues */
+ .input-content ::content input {
+ min-width: 0;
+ }
+
+ .input-content ::content textarea {
+ resize: none;
+ }
+
+ .add-on-content {
+ position: relative;
+ }
+
+ .add-on-content.is-invalid ::content * {
+ color: var(--paper-input-container-invalid-color, --google-red-500);
+ }
+
+ .add-on-content.is-highlighted ::content * {
+ color: var(--paper-input-container-focus-color, --default-primary-color);
+ }
+ </style>
+
+ <template is="dom-if" if="[[!noLabelFloat]]">
+ <div class="floated-label-placeholder">&nbsp;</div>
+ </template>
+
+ <div class$="[[_computeInputContentClass(noLabelFloat,alwaysFloatLabel,focused,invalid,_inputHasContent)]]">
+ <content select="[prefix]" id="prefix"></content>
+
+ <div class="label-and-input-container" id="labelAndInputContainer">
+ <content select=":not([add-on]):not([prefix]):not([suffix])"></content>
+ </div>
+
+ <content select="[suffix]"></content>
+ </div>
+
+ <div class$="[[_computeUnderlineClass(focused,invalid)]]">
+ <div class="unfocused-line"></div>
+ <div class="focused-line"></div>
+ </div>
+
+ <div class$="[[_computeAddOnContentClass(focused,invalid)]]">
+ <content id="addOnContent" select="[add-on]"></content>
+ </div>
+ </template>
+</dom-module>
+
+<script>
+ Polymer({
+ is: 'paper-input-container',
+
+ properties: {
+ /**
+ * Set to true to disable the floating label. The label disappears when the input value is
+ * not null.
+ */
+ noLabelFloat: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * Set to true to always float the floating label.
+ */
+ alwaysFloatLabel: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * The attribute to listen for value changes on.
+ */
+ attrForValue: {
+ type: String,
+ value: 'bind-value'
+ },
+
+ /**
+ * Set to true to auto-validate the input value when it changes.
+ */
+ autoValidate: {
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * True if the input is invalid. This property is set automatically when the input value
+ * changes if auto-validating, or when the `iron-input-validate` event is heard from a child.
+ */
+ invalid: {
+ observer: '_invalidChanged',
+ type: Boolean,
+ value: false
+ },
+
+ /**
+ * True if the input has focus.
+ */
+ focused: {
+ readOnly: true,
+ type: Boolean,
+ value: false,
+ notify: true
+ },
+
+ _addons: {
+ type: Array
+ // do not set a default value here intentionally - it will be initialized lazily when a
+ // distributed child is attached, which may occur before configuration for this element
+ // in polyfill.
+ },
+
+ _inputHasContent: {
+ type: Boolean,
+ value: false
+ },
+
+ _inputSelector: {
+ type: String,
+ value: 'input,textarea,.paper-input-input'
+ },
+
+ _boundOnFocus: {
+ type: Function,
+ value: function() {
+ return this._onFocus.bind(this);
+ }
+ },
+
+ _boundOnBlur: {
+ type: Function,
+ value: function() {
+ return this._onBlur.bind(this);
+ }
+ },
+
+ _boundOnInput: {
+ type: Function,
+ value: function() {
+ return this._onInput.bind(this);
+ }
+ },
+
+ _boundValueChanged: {
+ type: Function,
+ value: function() {
+ return this._onValueChanged.bind(this);
+ }
+ }
+ },
+
+ listeners: {
+ 'addon-attached': '_onAddonAttached',
+ 'iron-input-validate': '_onIronInputValidate'
+ },
+
+ get _valueChangedEvent() {
+ return this.attrForValue + '-changed';
+ },
+
+ get _propertyForValue() {
+ return Polymer.CaseMap.dashToCamelCase(this.attrForValue);
+ },
+
+ get _inputElement() {
+ return Polymer.dom(this).querySelector(this._inputSelector);
+ },
+
+ get _inputElementValue() {
+ return this._inputElement[this._propertyForValue] || this._inputElement.value;
+ },
+
+ ready: function() {
+ if (!this._addons) {
+ this._addons = [];
+ }
+ this.addEventListener('focus', this._boundOnFocus, true);
+ this.addEventListener('blur', this._boundOnBlur, true);
+ if (this.attrForValue) {
+ this._inputElement.addEventListener(this._valueChangedEvent, this._boundValueChanged);
+ } else {
+ this.addEventListener('input', this._onInput);
+ }
+ },
+
+ attached: function() {
+ // Only validate when attached if the input already has a value.
+ if (this._inputElementValue != '') {
+ this._handleValueAndAutoValidate(this._inputElement);
+ } else {
+ this._handleValue(this._inputElement);
+ }
+ },
+
+ _onAddonAttached: function(event) {
+ if (!this._addons) {
+ this._addons = [];
+ }
+ var target = event.target;
+ if (this._addons.indexOf(target) === -1) {
+ this._addons.push(target);
+ if (this.isAttached) {
+ this._handleValue(this._inputElement);
+ }
+ }
+ },
+
+ _onFocus: function() {
+ this._setFocused(true);
+ },
+
+ _onBlur: function() {
+ this._setFocused(false);
+ this._handleValueAndAutoValidate(this._inputElement);
+ },
+
+ _onInput: function(event) {
+ this._handleValueAndAutoValidate(event.target);
+ },
+
+ _onValueChanged: function(event) {
+ this._handleValueAndAutoValidate(event.target);
+ },
+
+ _handleValue: function(inputElement) {
+ var value = this._inputElementValue;
+
+ // type="number" hack needed because this.value is empty until it's valid
+ if (value || value === 0 || (inputElement.type === 'number' && !inputElement.checkValidity())) {
+ this._inputHasContent = true;
+ } else {
+ this._inputHasContent = false;
+ }
+
+ this.updateAddons({
+ inputElement: inputElement,
+ value: value,
+ invalid: this.invalid
+ });
+ },
+
+ _handleValueAndAutoValidate: function(inputElement) {
+ if (this.autoValidate) {
+ var valid;
+ if (inputElement.validate) {
+ valid = inputElement.validate(this._inputElementValue);
+ } else {
+ valid = inputElement.checkValidity();
+ }
+ this.invalid = !valid;
+ }
+
+ // Call this last to notify the add-ons.
+ this._handleValue(inputElement);
+ },
+
+ _onIronInputValidate: function(event) {
+ this.invalid = this._inputElement.invalid;
+ },
+
+ _invalidChanged: function() {
+ if (this._addons) {
+ this.updateAddons({invalid: this.invalid});
+ }
+ },
+
+ /**
+ * Call this to update the state of add-ons.
+ * @param {Object} state Add-on state.
+ */
+ updateAddons: function(state) {
+ for (var addon, index = 0; addon = this._addons[index]; index++) {
+ addon.update(state);
+ }
+ },
+
+ _computeInputContentClass: function(noLabelFloat, alwaysFloatLabel, focused, invalid, _inputHasContent) {
+ var cls = 'input-content';
+ if (!noLabelFloat) {
+ var label = this.querySelector('label');
+
+ if (alwaysFloatLabel || _inputHasContent) {
+ cls += ' label-is-floating';
+ // If the label is floating, ignore any offsets that may have been
+ // applied from a prefix element.
+ this.$.labelAndInputContainer.style.position = 'static';
+
+ if (invalid) {
+ cls += ' is-invalid';
+ } else if (focused) {
+ cls += " label-is-highlighted";
+ }
+ } else {
+ // When the label is not floating, it should overlap the input element.
+ if (label) {
+ this.$.labelAndInputContainer.style.position = 'relative';
+ }
+ }
+ } else {
+ if (_inputHasContent) {
+ cls += ' label-is-hidden';
+ }
+ }
+ return cls;
+ },
+
+ _computeUnderlineClass: function(focused, invalid) {
+ var cls = 'underline';
+ if (invalid) {
+ cls += ' is-invalid';
+ } else if (focused) {
+ cls += ' is-highlighted'
+ }
+ return cls;
+ },
+
+ _computeAddOnContentClass: function(focused, invalid) {
+ var cls = 'add-on-content';
+ if (invalid) {
+ cls += ' is-invalid';
+ } else if (focused) {
+ cls += ' is-highlighted'
+ }
+ return cls;
+ }
+ });
+</script>
diff --git a/Software/Embedded_SW/.jxbrowser-data/Cache/f_00000f b/Software/Embedded_SW/.jxbrowser-data/Cache/f_00000f
new file mode 100644
index 000000000..e7bb11c06
--- /dev/null
+++ b/Software/Embedded_SW/.jxbrowser-data/Cache/f_00000f
@@ -0,0 +1,536 @@
+<link rel="import" href="../../components/polymer/polymer.html">
+<link rel="import" href="../../components/paper-radio-group/paper-radio-group.html">
+<link rel="import" href="../../components/paper-radio-button/paper-radio-button.html">
+<link rel="import" href="../../components/paper-dropdown-menu/paper-dropdown-menu.html">
+<link rel="import" href="../../components/paper-button/paper-button.html">
+<link rel="import" href="../../components/paper-dialog/paper-dialog.html">
+<link rel="import" href="../../components/paper-checkbox/paper-checkbox.html">
+<link rel="import" href="../../components/iron-flex-layout/iron-flex-layout.html">
+<link rel="import" href="../../components/iron-fit-behavior/iron-fit-behavior.html">
+<link rel="import" href="../../components/paper-styles/paper-styles.html">
+
+<dom-module id="ti-rov-table">
+ <template>
+ <!-- include global rov styles -->
+ <style include="ti-rov-styles"></style>
+ <style is="custom-style">
+ :host {
+ display:block;
+ }
+ paper-checkbox {
+ --paper-checkbox-unchecked-background-color: white;
+ --paper-checkbox-unchecked-color: white;
+ --paper-checkbox-unchecked-ink-color: white;
+ --paper-checkbox-checked-color: white;
+ --paper-checkbox-checked-ink-color: white;
+ --paper-checkbox-checkmark-color: black;
+ --paper-checkbox-label-color: white;
+ }
+ #messageLabel {
+ margin-left: 15px;
+ margin-right: 15px;
+ font-family: var(--rovFontFamily);
+ font-size: var(--rovContentFontSize);
+ }
+ .rawNode {
+ display: table-cell;
+ padding: 3px 25px 0px 2px;
+ font-weight: normal;
+ cursor: pointer;
+ background-color: var(--rovTableBackgroundColor);
+ font-family: var(--rovTableFontFamily);
+ font-size: var(--rovContentFontSize);
+ }
+ .treeTableNode {
+ padding: 3px 50px 0px 2px;
+ font-weight: normal;
+ background-color: rgb(0, 0, 0);
+ color: #ffffff;
+ cursor: pointer;
+ }
+ .treeNodeIcon {
+ padding-right:8px;
+ }
+ .treeCell {
+ padding: 3px 50px 2px 7px;
+ }
+ .rawNodeIcon {
+ width: 18px;
+ height: 18px;
+ padding-right:8px;
+ }
+ .rawCell {
+ padding: 3px 50px 2px 7px;
+ }
+ .ttChildCell {
+ padding-left: 35px;
+ }
+ .childCell {
+ padding-left: 35px;
+ display: table-cell;
+ background-color: var(--rovTableBackgroundColor);
+ font-family: var(--rovTableFontFamily);
+ font-size: var(--rovContentFontSize);
+ }
+ .rovTableStyleCell {
+ background-color: var(--rovTableBackgroundColor);
+ font-family: var(--rovTableFontFamily);
+ font-size: var(--rovContentFontSize);
+ }
+ #columnsSelector {
+ font-family: var(--rovFontFamily);
+ font-size: var(--rovColumnsSelectorFontSize);
+ position: fixed;
+ @apply(--layout-vertical);
+ @apply(--layout-self-stretch);
+ background-color: var(--rovTitleToolbarBackground);
+ overflow-y: auto;
+ margin: 0;
+ }
+ .columnSelectCheckbox {
+ --paper-checkbox-size: 14px;
+ --paper-checkbox-unchecked-color: var(--rovTitleToolbarColor);
+ --paper-checkbox-unchecked-ink-color: transparent;
+ --paper-checkbox-checked-color: var(--rovTitleToolbarColor);
+ --paper-checkbox-checked-ink-color: transparent;
+ --paper-checkbox-checkmark-color: var(--rovTitleToolbarBackground);
+ --paper-checkbox-label-color: var(--rovTitleToolbarColor);
+ }
+ .columnSortIcon {
+ width: 16px;
+ height: 16px;
+ background-color: var(--rovTableHeaderBackground);
+ color: var(--rovTableHeaderColor);
+ float: right;
+ }
+ .cellList {
+ display: none;
+ margin-top: -18px;
+ margin-left: -4px;
+ padding: 0px;
+ border-width: 2px;
+ border-style: solid;
+ position: fixed;
+ list-style-type: none;
+ padding-bottom: 3px;
+ z-index: 9000;
+ background-color: var(--rovTableBackgroundColor);
+ }
+ .cellListItem {
+ margin-left: 2px;
+ margin-right: 5px;
+ margin-bottom: 3px;
+ background-color: var(--rovTableBackgroundColor);
+ font-family: var(--rovTableFontFamily);
+ font-size: var(--rovContentFontSize);
+ }
+ .cellDropIcon {
+ width: 16px;
+ height: 16px;
+ float: right;
+ color: lightslategray;
+ }
+ .columnSelectTd {
+ display: table-cell;
+ padding-left: 10px;
+ padding-top: 4px;
+ }
+ .columnSelectTh {
+ display: table-cell;
+ color: var(--rovTitleToolbarColor);
+ font-weight: normal;
+ text-align: center;
+ padding-top: 0px;
+ }
+ #columnConfigTable {
+ margin-top: 2px;
+ margin-bottom: 2px;
+ padding-left: 0px;
+ padding-right: 12px;
+ }
+ .instSelectIcon {
+ width: 24px;
+ height: 24px;
+ background-color: transparent;
+ color: black;
+ cursor: pointer;
+ }
+ #instSelectDiv {
+ margin-left: 14px;
+ margin-top: 0px;
+ margin-bottom: 5px;
+ white-space: nowrap;
+ font-family: var(--rovFontFamily);
+ font-size: var(--rovContentFontSize);
+ }
+ #selectInstanceDialog {
+ position: fixed;
+ margin-top: 0px;
+ --paper-dialog-background-color: white;
+ --paper-dialog-color: black;
+ @apply(--layout-vertical);
+ @apply(--layout-self-stretch);
+ }
+ #selectInstanceMenu {
+ padding-left: 0px;
+ margin-top: 2px;
+ margin-bottom: 2px;
+ }
+ .selectInstanceMenuItem {
+ font-family: var(--rovFontFamily);
+ font-size: var(--rovContentFontSize);
+ --paper-item-min-height: 24px;
+ cursor: pointer;
+ padding-left: 8px;
+ padding-right: 8px;
+ }
+ .rovTh {
+ display: table-cell;
+ border-right: 1px solid var(--rovTableBackgroundColor);
+ border-top: 1px solid var(--rovTableBackgroundColor);
+ border-bottom: 1px solid var(--rovTableBackgroundColor);
+ border-left: 1px solid var(--rovTableBackgroundColor);
+ padding: 2px 5px 3px 3px;
+ text-align: left;
+ background-color: var(--rovTableHeaderBackground);
+ color: var(--rovTableHeaderColor);
+ font-family: var(--rovFontFamily);
+ font-size: var(--rovContentFontSize);
+ font-weight: normal;
+ }
+ .rovTbody {
+ display: table-row-group;
+ }
+ .rovTd {
+ display: table-cell;
+ text-align:left;
+ padding-left: 4px;
+ padding-right: 5px;
+ white-space: nowrap;
+ background-color: var(--rovTableBackgroundColor);
+ font-family: var(--rovFontFamily);
+ font-size: var(--rovContentFontSize);
+ }
+ .treeNode {
+ display: table-cell;
+ padding: 3px 50px 0px 2px;
+ font-weight: normal;
+ cursor: pointer;
+ background-color: var(--rovTableBackgroundColor);
+ font-family: var(--rovTableFontFamily);
+ font-size: var(--rovContentFontSize);
+ }
+ .rovThead {
+ display: table-header-group;
+ }
+ .rovTr {
+ display:table-row;
+ }
+ .rovTdDropdownCell {
+ background-color: var(--rovTableBackgroundColor);
+ font-family: var(--rovFontFamily);
+ font-size: var(--rovContentFontSize);
+ }
+ .rovTdDropdownCell:hover .cellList {
+ display: block;
+ }
+ .formatMenu {
+ margin-left: 0px;
+ margin-top: 0px;
+ --paper-menu-button: {
+ padding-top: 0px;
+ padding-bottom: 4px;
+ };
+ --paper-input-container: {
+ padding-top: 0px;
+ padding-bottom: 0px;
+ };
+ --paper-input-container-input: {
+ font-family: var(--rovFontFamily);
+ font-size: var(--rovColumnsSelectorFontSize);
+ color: var(--rovTitleToolbarColor);
+ };
+ --paper-input-container-label: {
+ font-family: var(--rovFontFamily);
+ font-size: var(--rovColumnsSelectorFontSize);
+ color: var(--rovTitleToolbarColor);
+ };
+ }
+ #formatListbox {
+ background-color: white;
+ padding-top: 4px;
+ padding-bottom: 2px;
+ }
+ .formatItem {
+ --paper-item-min-height: 20px;
+ height: 20px;
+ font-family: var(--rovFontFamily);
+ font-size: var(--rovColumnsSelectorFontSize);
+ color: black;
+ background-color: white;
+ }
+ #closeColumnsButton {
+ width: 18px;
+ height: 18px;
+ position: absolute;
+ right: 4px;
+ top: 4px;
+ padding: 0;
+ color: var(--rovTitleToolbarColor);
+ }
+ </style>
+ <span>
+ <paper-dialog id="columnsSelector" on-iron-overlay-closed="columnsSelectorClosed" on-keypress="columnsSelectorKeyPress">
+ <div><paper-icon-button id="closeColumnsButton" title="Close" on-click="closeColumnsSelector" icon="close" role="button" tabindex="0"></paper-icon-button></div>
+ <div style="display:table" id="columnConfigTable">
+ <div class="rovThead">
+ <div class="columnSelectTh">Columns</div>
+ <template is="dom-if" if="{{hasFormats}}">
+ <div class="columnSelectTh">Format</div>
+ </template>
+ </div>
+ <div class="rovTbody">
+ <template is="dom-repeat" items="{{columnStates}}" as="col">
+ <div class="rovTr">
+ <div class="columnSelectTd"><paper-checkbox class="columnSelectCheckbox" id$="{{col.name}}" on-click="colsChanged" checked$="{{col.checked}}">{{col.name}}</paper-checkbox></div>
+ <template is="dom-if" if="{{hasFormats}}" restamp="true">
+ <template is="dom-if" if="{{col.hasFormat}}">
+ <div class="columnSelectTd">
+ <paper-dropdown-menu class="formatMenu" label="{{col.format}}" no-label-float no-animations on-iron-select="colFormatChanged" disabled="{{!col.checked}}">
+ <paper-listbox id="formatListbox" class="dropdown-content" selected="{{col.format}}">
+ <paper-item class="formatItem">Decimal</paper-item>
+ <paper-item class="formatItem">Hex</paper-item>
+ <paper-item class="formatItem">Scientific</paper-item>
+ </paper-listbox>
+ </paper-dropdown-menu>
+ </div>
+ </template>
+ <template is="dom-if" if="{{!col.hasFormat}}" restamp="true">
+ <div style="display:table-cell;"></div>
+ </template>
+ </template>
+ </div>
+ </template>
+ </div>
+ </div>
+ </paper-dialog>
+ <paper-dialog id="selectInstanceDialog" alwaysOnTop>
+ <paper-menu id="selectInstanceMenu" on-iron-select="instanceSelected" class="attachedMenu">
+ <template is="dom-repeat" items="{{instanceDataTable.instNames}}" as="inst">
+ <paper-item class="selectInstanceMenuItem" role="menuitem">{{inst}}</paper-item>
+ </template>
+ </paper-menu>
+ </paper-dialog>
+ </span>
+ <template is="dom-if" if="{{showDataMessage}}">
+ <div style="margin-top:20px;margin-bottom:20px;"><label id="messageLabel">{{dataMessage}}</label></div>
+ </template>
+ <div style="display:table" id="rovInstanceTable" hidden$="{{!isInstanceView}}">
+ <div class="rovThead">
+ <div class="rovTr">
+ <template is="dom-repeat" items="{{instanceTable.displayColumns}}" as="colObj">
+ <template is="dom-if" if="{{colObj.isSortCol}}" restamp="true">
+ <div class="rovTh" draggable="{{colsDraggable}}" on-click="onColumnClick" on-dragstart="columnDragStart" on-dragover="columnDragOver" on-drop="columnDrop">{{colObj.name}}<iron-icon class="columnSortIcon" icon$="{{colObj.icon}}"></iron-icon></div>
+ </template>
+ <template is="dom-if" if="{{!colObj.isSortCol}}" restamp="true">
+ <div class="rovTh" draggable="{{colsDraggable}}" on-click="onColumnClick" on-dragstart="columnDragStart" on-dragover="columnDragOver" on-drop="columnDrop">{{colObj.name}}</div>
+ </template>
+ </template>
+ </div>
+ </div>
+ <div class="rovTbody">
+ <template id="rovInstanceTemplate" is="dom-repeat" items="{{instanceTable.rows}}" as="row">
+ <div class="rovTr">
+ <template is="dom-repeat" items="{{row}}" as="rowObj">
+ <template is="dom-if" if="{{rowObj.isArray}}" restamp="true">
+ <div class="rovTdDropdownCell" style$="{{rowObj.style}}" title$="{{rowObj.title}}" on-mouseover="cellDropMouseOver">{{rowObj.val}}<iron-icon class="cellDropIcon" icon="more-vert"></iron-icon>
+ <ul class="cellList">
+ <template is="dom-repeat" items="{{rowObj.arrVals}}" as="arrVal">
+ <li class="cellListItem">{{arrVal}}</li>
+ </template>
+ </ul>
+ </div>
+ </template>
+ <template is="dom-if" if="{{!rowObj.isArray}}" restamp="true">
+ <div class="rovTd" style$="{{rowObj.style}}" title$="{{rowObj.title}}">{{rowObj.val}}</div>
+ </template>
+ </template>
+ </div>
+ </template>
+ </div>
+ </div>
+ <span hidden$="{{!isInstanceDataView}}">
+ <template is="dom-if" if="{{instanceDataTable.showInstSelect}}" restamp="true">
+ <div id="instSelectDiv">{{instanceDataTable.currentInst}}<iron-icon class="instSelectIcon" icon="arrow-drop-down" on-click="selectInstanceDialog"></iron-icon></div>
+ </template>
+ <div style="display:table" id="rovInstanceDataTable">
+ <div class="rovThead">
+ <div class="rovTr">
+ <template is="dom-repeat" items="{{instanceDataTable.displayColumns}}" as="colObj">
+ <template is="dom-if" if="{{colObj.isSortCol}}" restamp="true">
+ <div class="rovTh" draggable="{{colsDraggable}}" on-click="onColumnClick" on-dragstart="columnDragStart" on-dragover="columnDragOver" on-drop="columnDrop">{{colObj.name}}<iron-icon class="columnSortIcon" icon$="{{colObj.icon}}"></iron-icon></div>
+ </template>
+ <template is="dom-if" if="{{!colObj.isSortCol}}" restamp="true">
+ <div class="rovTh" draggable="{{colsDraggable}}" on-click="onColumnClick" on-dragstart="columnDragStart" on-dragover="columnDragOver" on-drop="columnDrop">{{colObj.name}}</div>
+ </template>
+ </template>
+ </div>
+ </div>
+ <div class="rovTbody">
+ <template id="rovInstanceDataTemplate" is="dom-repeat" items="{{instanceDataTable.rows}}" as="rowItem">
+ <template is="dom-if" if="{{rowItem.expanded}}" restamp="true">
+ <template is="dom-repeat" items="{{rowItem.rowVals}}" as="rowVals">
+ <div class="rovTr" style="padding-bottom:10px;">
+ <template is="dom-repeat" items="{{rowVals}}" as="rowValObj">
+ <template is="dom-if" if="{{rowValObj.isArray}}" restamp="true">
+ <div class="rovTdDropdownCell" style$="{{rowValObj.style}}" title$="{{rowValObj.title}}" on-mouseover="cellDropMouseOver">{{rowValObj.val}}<iron-icon class="cellDropIcon" icon="more-vert"></iron-icon>
+ <ul class="cellList">
+ <template is="dom-repeat" items="{{rowValObj.arrVals}}" as="arrVal">
+ <li class="cellListItem">{{arrVal}}</li>
+ </template>
+ </ul>
+ </div>
+ </template>
+ <template is="dom-if" if="{{!rowValObj.isArray}}" restamp="true">
+ <div class="rovTableStyleCell" style$="{{rowValObj.style}}" title$="{{rowValObj.title}}">{{rowValObj.val}}</div>
+ </template>
+ </template>
+ </div>
+ </template>
+ </template>
+ </template>
+ </div>
+ </div>
+ </span>
+ <div style="display:table" id="rovTreeTable" hidden$="{{!isTreeView}}">
+ <div class="rovThead">
+ <div class="rovTr">
+ <template is="dom-repeat" items="{{treeTable.columns}}">
+ <div class="rovTh">{{item}}</div>
+ </template>
+ </div>
+ </div>
+ <div style="display:table-row-group;">
+ <template id="rovTreeTemplate" is="dom-repeat" items="{{treeTable}}" as="treeItem">
+ <template is="dom-if" if="{{treeItem.expanded}}">
+ <div class="rovTr">
+ <div class="treeNode" style$="{{treeItem.style}}" id$="{{treeItem.parentNode}}" on-tap="treeNodeTapped"><iron-icon class="treeNodeIcon" icon="remove"></iron-icon>{{treeItem.parentNode}}</div>
+ <div class="rovTd"></div>
+ </div>
+ <template is="dom-repeat" items="{{treeItem.childRows}}" as="row">
+ <div class="rovTr">
+ <div class="childCell" style$="{{row.0.style}}">{{row.0.val}}</div>
+ <div class="rovTd" style$="{{row.1.style}}">{{row.1.val}}</div>
+ </div>
+ </template>
+ </template>
+ <template is="dom-if" if="{{!treeItem.expanded}}">
+ <div class="rovTr">
+ <div class="treeNode" style$="{{treeItem.style}}" id$="{{treeItem.parentNode}}" on-tap="treeNodeTapped"><iron-icon class="treeNodeIcon" icon="add"></iron-icon>{{treeItem.parentNode}}</div>
+ <div class="rovTd"></div>
+ </div>
+ </template>
+ </template>
+ </div>
+ </div>
+ <div style="display:table" id="rovTreeTableTable" hidden$="{{!isTreeTableView}}">
+ <div class="rovThead">
+ <div class="rovTr">
+ <div class="rovTh"></div>
+ <template is="dom-repeat" items="{{treeTableTable.columns}}">
+ <div class="rovTh" draggable="{{colsDraggable}}" on-dragstart="columnDragStart" on-dragover="columnDragOver" on-drop="columnDrop">{{item}}</div>
+ </template>
+ </div>
+ </div>
+ <div style="display:table-row-group;">
+ <template id="rovTreeTableTemplate" is="dom-repeat" items="{{treeTableTable}}" as="ttItem">
+ <template is="dom-if" if="{{ttItem.expanded}}" restamp="true">
+ <div class="rovTr">
+ <div class="rawNode" id$="{{ttItem.parentNode}}" on-tap="ttNodeTapped"><iron-icon class="rawNodeIcon" icon="remove"></iron-icon>{{ttItem.parentNode}}</div>
+ </div>
+ <template is="dom-repeat" items="{{ttItem.childRows}}" as="row">
+ <template is="dom-if" if="{{row.hasIcon}}" restamp="true">
+ <div class="rovTr">
+ <div class="rovTableStyleCell" style$="{{row.style}}" id$="{{row.id}}" on-tap="chttNodeTapped"><iron-icon class="rawNodeIcon" icon$="{{row.icon}}"></iron-icon>{{row.name}}</div>
+ </div>
+ </template>
+ <template is="dom-if" if="{{!row.hasIcon}}" restamp="true">
+ <template is="dom-if" if="{{row.atMax}}">
+ <div class="rovTr">
+ <div class="rovTableStyleCell" style$="{{row.style}}">{{row.name}}</div>
+ <div class="rovTd">Max depth</div>
+ </div>
+ </template>
+ <template is="dom-if" if="{{!row.atMax}}">
+ <div class="rovTr">
+ <div class="rovTableStyleCell" style$="{{row.style}}"></div>
+ <template is="dom-repeat" items="{{row.cells}}" as="cellObj">
+ <template is="dom-if" if="{{cellObj.isArray}}" restamp="true">
+ <div class="rovTdDropdownCell" style$="{{cellObj.style}}" title$="{{cellObj.title}}" on-mouseover="cellDropMouseOver">{{cellObj.val}}<iron-icon class="cellDropIcon" icon="more-vert"></iron-icon>
+ <ul class="cellList">
+ <template is="dom-repeat" items="{{cellObj.arrVals}}" as="arrVal">
+ <li class="cellListItem">{{arrVal}}</li>
+ </template>
+ </ul>
+ </div>
+ </template>
+ <template is="dom-if" if="{{!cellObj.isArray}}" restamp="true">
+ <div class="rovTd" style$="{{cellObj.style}}" title$="{{cellObj.title}}">{{cellObj.val}}</div>
+ </template>
+ </template>
+ </div>
+ </template>
+ </template>
+ </template>
+ </template>
+ <template is="dom-if" if="{{!ttItem.expanded}}">
+ <div class="rovTr">
+ <div class="rawNode" id$="{{ttItem.parentNode}}" on-tap="ttNodeTapped"><iron-icon class="rawNodeIcon" icon="add"></iron-icon>{{ttItem.parentNode}}</div>
+ </div>
+ </template>
+ </template>
+ </div>
+ </div>
+ <div style="display:table" id="rovRawTable" hidden$="{{!isRawView}}">
+ <div class="rovThead">
+ <div class="rovTr">
+ <template is="dom-repeat" items="{{rawTable.columns}}">
+ <div class="rovTh">{{item}}</div>
+ </template>
+ </div>
+ </div>
+ <div style="display:table-row-group;">
+ <template id="rovRawTemplate" is="dom-repeat" items="{{rawTable}}" as="rawItem">
+ <template is="dom-if" if="{{rawItem.expanded}}" restamp="true">
+ <div class="rovTr">
+ <div class="rawNode" id$="{{rawItem.parentNode}}" style$="{{rawItem.style}}" on-tap="rawNodeTapped"><iron-icon class="rawNodeIcon" icon="remove"></iron-icon>{{rawItem.parentNode}}</div>
+ <div class="rovTd"></div>
+ </div>
+ <template is="dom-repeat" items="{{rawItem.childRows}}" as="row">
+ <template is="dom-if" if="{{row.hasIcon}}">
+ <div class="rovTr">
+ <div class="rovTableStyleCell" style$="{{row.style}}" id$="{{row.id}}" on-tap="chRawNodeTapped"><iron-icon class="rawNodeIcon" icon$="{{row.icon}}"></iron-icon>{{row.property}}</div>
+ <div class="rovTd"></div>
+ </div>
+ </template>
+ <template is="dom-if" if="{{!row.hasIcon}}">
+ <div class="rovTr">
+ <div class="rovTableStyleCell" style$="{{row.style}}">{{row.property}}</div>
+ <div class="rovTableStyleCell" style$="{{row.valStyle}}" title$="{{row.valTitle}}">{{row.value}}</div>
+ </div>
+ </template>
+ </template>
+ </template>
+ <template is="dom-if" if="{{!rawItem.expanded}}">
+ <div class="rovTr">
+ <div class="rawNode" id$="{{rawItem.parentNode}}" style$="{{rawItem.style}}" on-tap="rawNodeTapped"><iron-icon class="rawNodeIcon" icon="add"></iron-icon>{{rawItem.parentNode}}</div>
+ <div class="rovTd"></div>
+ </div>
+ </template>
+ </template>
+ </div>
+ </div>
+ </template>
+ <script src="ti-rov-table.js"></script>
+</dom-module>
+
diff --git a/Software/Embedded_SW/.jxbrowser-data/Cache/index b/Software/Embedded_SW/.jxbrowser-data/Cache/index
index ed6acc445..5f65aef8c 100644
--- a/Software/Embedded_SW/.jxbrowser-data/Cache/index
+++ b/Software/Embedded_SW/.jxbrowser-data/Cache/index
Binary files differ
diff --git a/Software/Embedded_SW/.jxbrowser-data/GPUCache/data_1 b/Software/Embedded_SW/.jxbrowser-data/GPUCache/data_1
index 6c622e353..3514501b2 100644
--- a/Software/Embedded_SW/.jxbrowser-data/GPUCache/data_1
+++ b/Software/Embedded_SW/.jxbrowser-data/GPUCache/data_1
Binary files differ
diff --git a/Software/Embedded_SW/.jxbrowser-data/History b/Software/Embedded_SW/.jxbrowser-data/History
index 19d66f71f..094d1825b 100644
--- a/Software/Embedded_SW/.jxbrowser-data/History
+++ b/Software/Embedded_SW/.jxbrowser-data/History
Binary files differ
diff --git a/Software/Embedded_SW/.jxbrowser-data/Local Storage - EXT/http_127.0.0.1.localstorage b/Software/Embedded_SW/.jxbrowser-data/Local Storage - EXT/http_127.0.0.1.localstorage
index c7f8a57ab..7bafbe7cd 100644
--- a/Software/Embedded_SW/.jxbrowser-data/Local Storage - EXT/http_127.0.0.1.localstorage
+++ b/Software/Embedded_SW/.jxbrowser-data/Local Storage - EXT/http_127.0.0.1.localstorage
@@ -1,4 +1,4 @@
-#Mon Feb 04 13:00:42 IST 2019
-viewsData-storage={"ti.sysbios.knl.Task.Basic"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"priority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"mode","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"fxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"arg0","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"arg1","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"stackSize","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"stackBase","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"curCoreId","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"affinity","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:true},"ti.sysbios.knl.Task"\:{"defaultViewName"\:"CallStacks"},"ti.sysbios.family.arm.m3.Hwi.Basic"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"halHwiHandle","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"type","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"intNum","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"priority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"group","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"subPriority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"fxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"arg","checked"\:true,"hasFormat"\:true,"format"\:"Hex"}],"hasFormats"\:true},"ti.sysbios.family.arm.m3.Hwi"\:{"defaultViewName"\:"Exception"},"ti.sysbios.knl.Task.Detailed"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"priority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"mode","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"fxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"arg0","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"arg1","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"stackPeak","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"stackSize","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"stackBase","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"curCoreId","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"affinity","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"blockedOn","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:true},"ti.sysbios.family.arm.m3.Hwi.Detailed"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"halHwiHandle","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"type","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"intNum","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"priority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"group","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"subPriority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"fxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"arg","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"irp","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"status","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"coreId","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"}],"hasFormats"\:true},"ti.sysbios.heaps.HeapMem.Basic"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"buf","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"minBlockAlign","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"sectionName","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:true},"ti.sysbios.knl.Event"\:{"defaultViewName"\:"Basic"},"ti.sysbios.knl.Event.Raw"\:{},"ti.catalog.arm.cortexm4.tiva.ce.Boot.Module"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"configureClock","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"sysClockDivEnable","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"sysClockDiv","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"pwmClockDivEnable","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"pwmClockDiv","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"xtal","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"oscSrc","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"pllBypass","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"pllOutEnable","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"ioscDisable","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"moscDisable","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:false},"ti.sysbios.knl.Swi.Basic"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"state","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"priority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"fxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"arg0","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"arg1","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"initTrigger","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"curTrigger","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"}],"hasFormats"\:true},"xdc.runtime.System.XDCROOT"\:{"columnStates"\:[{"name"\:"entry","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:false},"xdc.runtime.System"\:{"defaultViewName"\:"Raw"},"xdc.runtime.System.Raw"\:{},"ti.sysbios.family.arm.m3.Hwi.Raw"\:{},"xdc.runtime.Startup.Module"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"rtsStartupDone","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"startupBegun","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"resetFxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"firstFxns","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"lastFxns","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:true},"ti.sysbios.knl.Semaphore.Basic"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"event","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"eventId","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"mode","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"count","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"pendedTasks","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:true},"ti.sysbios.family.arm.lm4.Timer.Basic"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"halTimerHandle","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"id","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"device","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"startMode","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"runMode","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"period","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"periodType","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"intNum","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"tickFxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"arg","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"extFreq","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"hwiHandle","checked"\:true,"hasFormat"\:true,"format"\:"Hex"}],"hasFormats"\:true},"xdc.runtime.SysMin.Module"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"outBuf","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"outBufIndex","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"wrapped","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:true}}
+#Sun Mar 03 10:14:42 IST 2019
+viewsData-storage={"ti.sysbios.knl.Task.Basic"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"priority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"mode","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"fxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"arg0","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"arg1","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"stackSize","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"stackBase","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"curCoreId","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"affinity","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:true},"ti.sysbios.knl.Task"\:{"defaultViewName"\:"CallStacks"},"ti.sysbios.family.arm.m3.Hwi.Basic"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"halHwiHandle","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"type","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"intNum","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"priority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"group","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"subPriority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"fxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"arg","checked"\:true,"hasFormat"\:true,"format"\:"Hex"}],"hasFormats"\:true},"ti.sysbios.family.arm.m3.Hwi"\:{"defaultViewName"\:"Basic"},"ti.sysbios.knl.Task.Detailed"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"priority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"mode","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"fxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"arg0","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"arg1","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"stackPeak","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"stackSize","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"stackBase","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"curCoreId","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"affinity","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"blockedOn","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:true},"ti.sysbios.family.arm.m3.Hwi.Detailed"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"halHwiHandle","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"type","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"intNum","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"priority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"group","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"subPriority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"fxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"arg","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"irp","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"status","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"coreId","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"}],"hasFormats"\:true},"ti.sysbios.heaps.HeapMem.Basic"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"buf","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"minBlockAlign","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"sectionName","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:true},"ti.sysbios.knl.Event"\:{"defaultViewName"\:"Basic"},"ti.sysbios.knl.Event.Raw"\:{},"ti.catalog.arm.cortexm4.tiva.ce.Boot.Module"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"configureClock","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"sysClockDivEnable","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"sysClockDiv","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"pwmClockDivEnable","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"pwmClockDiv","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"xtal","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"oscSrc","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"pllBypass","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"pllOutEnable","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"ioscDisable","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"moscDisable","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:false},"ti.sysbios.knl.Swi.Basic"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"state","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"priority","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"fxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"arg0","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"arg1","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"initTrigger","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"curTrigger","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"}],"hasFormats"\:true},"xdc.runtime.System.XDCROOT"\:{"columnStates"\:[{"name"\:"entry","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:false},"xdc.runtime.System"\:{"defaultViewName"\:"Raw"},"xdc.runtime.System.Raw"\:{},"ti.sysbios.family.arm.m3.Hwi.Raw"\:{},"xdc.runtime.Startup.Module"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"rtsStartupDone","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"startupBegun","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"resetFxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"firstFxns","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"lastFxns","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:true},"ti.sysbios.knl.Semaphore.Basic"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"event","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"eventId","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"mode","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"count","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"pendedTasks","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:true},"ti.sysbios.family.arm.lm4.Timer.Basic"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"halTimerHandle","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"label","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"id","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"device","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"startMode","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"runMode","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"period","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"periodType","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"intNum","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"tickFxn","checked"\:true,"hasFormat"\:false,"format"\:null},{"name"\:"arg","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"extFreq","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"hwiHandle","checked"\:true,"hasFormat"\:true,"format"\:"Hex"}],"hasFormats"\:true},"xdc.runtime.SysMin.Module"\:{"columnStates"\:[{"name"\:"address","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"outBuf","checked"\:true,"hasFormat"\:true,"format"\:"Hex"},{"name"\:"outBufIndex","checked"\:true,"hasFormat"\:true,"format"\:"Decimal"},{"name"\:"wrapped","checked"\:true,"hasFormat"\:false,"format"\:null}],"hasFormats"\:true}}
rovSettings-storage={"exeMrus"\:["C\:/Tango/Software/Embedded_SW/Embedded/Debug/Embedded.out","C\:/Tango/Software/Embedded_SW/Embedded/debug_w_pmr/Embedded.out"]}
-rovInit-storage={"progressInfo"\:{"min"\:0,"max"\:7,"step"\:1,"notifyCount"\:6,"average"\:6,"numLoads"\:21},"autoConnectChecked"\:false,"exe"\:"C\:/Tango/Software/Embedded_SW/Embedded/Debug/Embedded.out","commLink"\:"Debugger","autoConnect"\:false,"noExe"\:false,"showIntro"\:true}
+rovInit-storage={"progressInfo"\:{"min"\:0,"max"\:7,"step"\:1,"notifyCount"\:6,"average"\:6,"numLoads"\:22},"autoConnectChecked"\:false,"exe"\:"C\:/Tango/Software/Embedded_SW/Embedded/Debug/Embedded.out","commLink"\:"Debugger","autoConnect"\:false,"noExe"\:false,"showIntro"\:true}
diff --git a/Software/Embedded_SW/.jxbrowser-data/Login Data b/Software/Embedded_SW/.jxbrowser-data/Login Data
index 0f9e99815..a930d764b 100644
--- a/Software/Embedded_SW/.jxbrowser-data/Login Data
+++ b/Software/Embedded_SW/.jxbrowser-data/Login Data
Binary files differ
diff --git a/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c b/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c
index 60873243c..c311e9787 100644
--- a/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c
+++ b/Software/Embedded_SW/Embedded/Common/SWUpdate/FileSystem.c
@@ -428,6 +428,7 @@ uint32_t DeleteRequestFunc(MessageContainer* requestContainer)
Fresult = f_unlink(request->path);
+ REPORT_MSG(Fresult, "File Delete");
responseContainer = createContainer(MESSAGE_TYPE__DeleteResponse, requestContainer->token, false, &response, &delete_response__pack, &delete_response__get_packed_size);
if (Fresult!= OK)
{
diff --git a/Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c b/Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c
index de3f9288d..c4f04254d 100644
--- a/Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c
+++ b/Software/Embedded_SW/Embedded/Common/SW_Info/SW_Info.c
@@ -20,7 +20,7 @@ typedef struct
} TangoVersion_t;
-TangoVersion_t _gTangoVersion = {1,3,7,7};
+TangoVersion_t _gTangoVersion = {1,3,7,81};
#define BUILD_DATE __DATE__
char Dat[50] = BUILD_DATE;
char _gTangoName [MAX_STRING_LEN] = "Tango01 ";//d
diff --git a/Software/Embedded_SW/Embedded/DataDef.h b/Software/Embedded_SW/Embedded/DataDef.h
index ec2def5a7..cf137a00a 100644
--- a/Software/Embedded_SW/Embedded/DataDef.h
+++ b/Software/Embedded_SW/Embedded/DataDef.h
@@ -16,6 +16,7 @@
#define HIZ_TIMEOUT 1000
//#define DEMO_TEMPERATURE
//#define TEST_LONGER_PID_THREAD
+//#define HUNDRED_MICROSECONDS_DANCER_READ
#define MAX_STRING_LEN 255 //Embedded version + filter.c
@@ -48,8 +49,9 @@ enum
#define Cartridge_MidTank_OFF 0
#define Atm_MidTank_ON 1
#define Atm_MidTank_OFF 0
-#define Mixer_Head 0
-#define Mixer_Waste 1
+//waste valve reversed
+#define Mixer_Head 1
+#define Mixer_Waste 0
#define NEW 0
diff --git a/Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c b/Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c
index 8bd38a698..ce84d7eb6 100644
--- a/Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c
+++ b/Software/Embedded_SW/Embedded/Drivers/ADC_Sampling/ADC.c
@@ -107,8 +107,8 @@ void ADCAcquireStop(void) //MillisecStop
#define CHAN_LEFT_DANCER_1 ADC_CTL_CH13
#define CHAN_LEFT_DANCER_2 ADC_CTL_CH14
#define CHAN_RIGHT_DANCER ADC_CTL_CH15
-#define CHAN_DRYER_CURRENT_1 ADC_CTL_CH16
-#define CHAN_DRYER_CURRENT_2 ADC_CTL_CH17
+#define CHAN_DRYER_CURRENT_1 ADC_CTL_CH16 //Dryer Heater 2
+#define CHAN_DRYER_CURRENT_2 ADC_CTL_CH17 //Dryer Heater 1
#define CHAN_DRYER_CURRENT_3 ADC_CTL_CH18
#define CHAN_3V3_FPGA ADC_CTL_CH19
/*
@@ -212,7 +212,7 @@ uint32_t ADC_TriggerCollection(void) // (called by MillisecLoop)
uint32_t ADC_GetReading(int DataItemId) // // ADC Data get for a single data read
{
int bufnotinuse;
- assert (DataItemId<MAX_ADC_DEVICES);
+ //assert (DataItemId<MAX_ADC_DEVICES);
if (bufferFlipFlop == 0) bufnotinuse = 1;
else bufnotinuse = 0;
@@ -547,11 +547,35 @@ uint8_t Calculate_Gas_Power_Consumption() // WHS
uint32_t Read_Dryer_Heaters_Current(HEATERS_CURRENT Heater_ID) //
{
+
+ /*
+ * On Dryer have two heaters , 4*220w and 2*220w that work on 220Vac.
+
+ Current transformer convert (thru resistor ) the Current of load to Voltage then convert from RMS to DC and connect to A2D pin of Tiva.
+ A2D is 12 bits and his reference is 3.3V (VDDA) or 3V(VREFA+) (depend on s/w).
+ I=A2D bits *K *VREF *N /(4096*R)
+ Where : K= K factor of transformer (less than 1 )
+ VREF 3 or 3.3v depended of s/w
+ N turns ratio (800 in our case )
+
+
+
+
+ Heater_No. Heater_SSR Resistor Power Current AIN#
+ Heater_1 4 SSR_1 50 ohm 880W 8A 17
+ Heater_2 2 SSR_2 100 ohm 440W 4A 16
+ *
+ */
uint32_t Status = OK;
uint32_t temp;
- uint32_t TBD1 = 1;//TODO
- uint32_t TBD2 = 1;//TODO
+
+ uint32_t Vref = 3; // External 3V reference using - ADC_REF_EXT_3V
+
+ uint8_t K = 95; //0.95; //See graph in data sheet of CTL-6
+ uint32_t N = 800; //See data sheet of CTL-6
+ uint8_t R; //
+
if (Heaters_Current_Read_Enable[Heater_ID] == false)
return Heaters_Current[Heater_ID];
@@ -559,22 +583,26 @@ uint32_t Read_Dryer_Heaters_Current(HEATERS_CURRENT Heater_ID) //
switch(Heater_ID)
{
case DRYER_CURRENT_1:
- temp = ADC_GetReading(CHAN_DRYER_CURRENT_1);
+ temp = ADC_GetReading(CHAN_DRYER_CURRENT_2);//ADC_CTL_CH17
+ R = 50;//50 Ohm
+ //Expected 8A
break;
case DRYER_CURRENT_2:
- temp = ADC_GetReading(CHAN_DRYER_CURRENT_2);
- break;
- case DRYER_CURRENT_3:
- temp = ADC_GetReading(CHAN_DRYER_CURRENT_3);
+ temp = ADC_GetReading(CHAN_DRYER_CURRENT_1);//ADC_CTL_CH16
+ R = 100;//100 Ohm
+ //Expected 4A
break;
+// case DRYER_CURRENT_3:
+// temp = ADC_GetReading(CHAN_DRYER_CURRENT_3);//Not in use
+// break;
default:
Status = ERROR;
break;
}
Heaters_Current_Bits[Heater_ID] = temp;
- #warning after updating the hardware need to add the correct formula
- Heaters_Current[Heater_ID] = temp*TBD1/TBD2;
+
+ Heaters_Current[Heater_ID] = (temp * K/100 * Vref * N) / (4096 * R);// [Amper]
return Status;
diff --git a/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_GPIO/FPGA_GPIO.c b/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_GPIO/FPGA_GPIO.c
index dc34cbd2d..06d35772e 100644
--- a/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_GPIO/FPGA_GPIO.c
+++ b/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_GPIO/FPGA_GPIO.c
@@ -580,7 +580,7 @@ bool WHS_GPI_WCONTAINER_WARN()//waste tank empty
return F3_GPI_01_Reg.bits.F3_GPI_WCONTAINER_WARN;
}
-bool WHS_GPI_WASTE_FLOW_SWITCH()
+bool WHS_GPI_WASTE_FLOW_SWITCH()// DRyer air
{
return F2_GPI_Reg.bits.F2_WASTE_FLOW_SW_NO;
}
diff --git a/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.c b/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.c
index 594b3d1a4..e8b46084c 100644
--- a/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.c
+++ b/Software/Embedded_SW/Embedded/Drivers/FPGA/FPGA_SPI_Comm.c
@@ -5,6 +5,7 @@
#include <DataDef.h>
#include "FPGA_SPI_Comm.h"
#include "drivers/FPGA/Moters_Driver/L6470.h"
+#include "drivers/FPGA/Moters_Driver/PowerSTEP01.h"
#include "Drivers/Motors/Motor.h"
#include "modules/control/millisecTask.h"
#include "modules/thread/thread.h"
@@ -405,6 +406,8 @@ typedef enum
MOTOR_CONFIG_STALL_TH,
MOTOR_CONFIG_K_THERM,
MOTOR_CONFIG_FS_SPD,
+ MOTOR_CONFIG_GATECFG1,
+ MOTOR_CONFIG_GATECFG2,
MOTOR_CONFIG_END
}MOTOR_CONFIG_STAGES_ENUM;
MOTOR_CONFIG_STAGES_ENUM ConfigStages[NUM_OF_MOTORS] = {MOTOR_CONFIG_INIT};
@@ -458,7 +461,7 @@ uint32_t FPGA_MotorConfig_callback(TimerMotors_t _motorId, uint32_t ReadValue)
switch (ConfigStages[_motorId])
{
- case MOTOR_CONFIG_READ_ADC:
+ case MOTOR_CONFIG_READ_ADC:
ConfigStages[_motorId]++;
Read_Motors_Driver_Type(_motorId);
//intentional fall through
@@ -548,7 +551,16 @@ uint32_t FPGA_MotorConfig_callback(TimerMotors_t _motorId, uint32_t ReadValue)
ConfigStages[_motorId]++;
if(MotorsCfg[_motorId].configword!=0)
{
- temp = x_SET_PARAM | x_CONFIG;
+ //temp = x_SET_PARAM | x_CONFIG;
+ if(MotorDriverResponse[_motorId].DriverType == VoltageCombinedMotDriver)
+ {
+ temp = x_SET_PARAM | x_POWERSTEP01_CONFIG;
+ }
+ else
+ {
+ temp = x_SET_PARAM | x_CONFIG;
+ }
+
temp = temp << 24;
temp |= MotorsCfg[_motorId].configword<<8;
MillisecWriteToMotor(_motorId, temp, 4, FPGA_MotorConfig_callback);
@@ -674,7 +686,29 @@ uint32_t FPGA_MotorConfig_callback(TimerMotors_t _motorId, uint32_t ReadValue)
if( MillisecWriteToMotor(_motorId, temp, 4, FPGA_MotorConfig_callback) < 0 ) return ERROR;
break;
}
+ case MOTOR_CONFIG_GATECFG1:
+ ConfigStages[_motorId]++;
+ if(MotorDriverResponse[_motorId].DriverType == VoltageCombinedMotDriver)
+ {
+ temp = x_SET_PARAM | x_POWERSTEP01_GATECFG1;
+ temp = temp << 24;
+ //Gate Current of 8mA for 2000 ns (boost: 125 ns) Clock watchdog disabled
+ temp |= (POWERSTEP01_TCC_2000ns | POWERSTEP01_IGATE_16mA | POWERSTEP01_TBOOST_125ns | POWERSTEP01_WD_EN_DISABLE)<<8;
+ if( MillisecWriteToMotor(_motorId, temp, 4, FPGA_MotorConfig_callback) < 0 ) return ERROR;
break;
+ }
+ case MOTOR_CONFIG_GATECFG2:
+ ConfigStages[_motorId]++;
+ if(MotorDriverResponse[_motorId].DriverType == VoltageCombinedMotDriver)
+ {
+ temp = x_SET_PARAM | x_POWERSTEP01_GATECFG2;
+ temp = temp << 24;
+ //Blanking time: 125 ns, dead time: 125 ns
+ temp |= (POWERSTEP01_TBLANK_125ns | POWERSTEP01_TDT_125ns)<<16;
+ if( MillisecWriteToMotor(_motorId, temp, 4, FPGA_MotorConfig_callback) < 0 ) return ERROR;
+ break;
+ }
+ break;
default:
return ERROR;
}
diff --git a/Software/Embedded_SW/Embedded/Drivers/FPGA/Moters_Driver/PowerSTEP01.h b/Software/Embedded_SW/Embedded/Drivers/FPGA/Moters_Driver/PowerSTEP01.h
new file mode 100644
index 000000000..bf1fe91d5
--- /dev/null
+++ b/Software/Embedded_SW/Embedded/Drivers/FPGA/Moters_Driver/PowerSTEP01.h
@@ -0,0 +1,168 @@
+/*
+ * PowerSTEP01.h
+ * //Based on:
+ * //https://os.mbed.com/teams/ST/code/X_NUCLEO_IHM03A1/file/2fbfe0cd8d4d/Components/powerstep01/powerstep01.h/
+ *
+ * Created on: Mar 5, 2019
+ * Author: avi
+ */
+
+#ifndef DRIVERS_FPGA_MOTERS_DRIVER_POWERSTEP01_H_
+#define DRIVERS_FPGA_MOTERS_DRIVER_POWERSTEP01_H_
+
+
+//powerSTEP01
+#define x_POWERSTEP01_GATECFG1 0x18 //Gate driver configuration 11 bit
+#define x_POWERSTEP01_GATECFG2 0x19 //Gate driver configuration 8 bit
+#define x_POWERSTEP01_STATUS 0x1B //x_GET_STATUS is the same as in L6470
+#define x_POWERSTEP01_CONFIG 0x1A
+
+#define x_KVAL_TVAL_HOLD 0x09
+#define x_KVAL_TVAL_RUN 0x0A
+#define x_KVAL_TVAL_ACC 0x0B
+#define x_KVAL_TVAL_DEC 0x0C
+#define x_ST_SLP_T_FAST 0x0E
+#define x_FN_SLP_ACC_TON_MIN 0x0F
+#define x_FN_SLP_DEC_TOFF_MIN 0x10
+
+///Shift of TCC field in GATECFG1 register
+#define POWERSTEP01_TCC_SHIFT (0)
+///Shift of IGATE field in GATECFG1 register
+#define POWERSTEP01_IGATE_SHIFT (5)
+///Shift of TBOOST field in GATECFG1 register
+#define POWERSTEP01_TBOOST_SHIFT (8)
+
+///Shift of TBLANK field in GATECFG2 register
+#define POWERSTEP01_TBLANK_SHIFT (5)
+///Shift of TDT field in GATECFG2 register
+#define POWERSTEP01_TDT_SHIFT (0)
+
+/// masks for GATECFG1 register of PowerStep01
+typedef enum {
+ POWERSTEP01_GATECFG1_TCC_MASK = ((uint16_t)0x001F),
+ POWERSTEP01_GATECFG1_IGATE_MASK = ((uint16_t)0x00E0),
+ POWERSTEP01_GATECFG1_TBOOST_MASK = ((uint16_t)0x0700),
+ POWERSTEP01_GATECFG1_WD_EN = ((uint16_t)0x0800)
+} powerstep01_GateCfg1Masks_t;
+
+/// Control current Time (field TCC of GATECFG1 register of PowerStep01)
+typedef enum {
+ POWERSTEP01_TCC_125ns = (((uint8_t)0x00)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_250ns = (((uint8_t)0x01)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_375ns = (((uint8_t)0x02)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_500ns = (((uint8_t)0x03)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_625ns = (((uint8_t)0x04)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_750ns = (((uint8_t)0x05)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_875ns = (((uint8_t)0x06)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_1000ns = (((uint8_t)0x07)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_1125ns = (((uint8_t)0x08)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_1250ns = (((uint8_t)0x09)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_1375ns = (((uint8_t)0x0A)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_1500ns = (((uint8_t)0x0B)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_1625ns = (((uint8_t)0x0C)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_1750ns = (((uint8_t)0x0D)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_1875ns = (((uint8_t)0x0E)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_2000ns = (((uint8_t)0x0F)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_2125ns = (((uint8_t)0x10)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_2250ns = (((uint8_t)0x11)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_2375ns = (((uint8_t)0x12)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_2500ns = (((uint8_t)0x13)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_2625ns = (((uint8_t)0x14)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_2750ns = (((uint8_t)0x15)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_2875ns = (((uint8_t)0x16)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_3000ns = (((uint8_t)0x17)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_3125ns = (((uint8_t)0x18)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_3250ns = (((uint8_t)0x19)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_3375ns = (((uint8_t)0x1A)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_3500ns = (((uint8_t)0x1B)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_3625ns = (((uint8_t)0x1C)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_3750ns = (((uint8_t)0x1D)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_3750ns_bis = (((uint8_t)0x1E)<<POWERSTEP01_TCC_SHIFT),
+ POWERSTEP01_TCC_3750ns_ter = (((uint8_t)0x1F)<<POWERSTEP01_TCC_SHIFT)
+} powerstep01_Tcc_t;
+
+/// Igate options (GATECFG1 register of PowerStep01)
+typedef enum {
+ POWERSTEP01_IGATE_4mA = (((uint8_t)0x00)<<POWERSTEP01_IGATE_SHIFT),
+ POWERSTEP01_IGATE_4mA_Bis = (((uint8_t)0x01)<<POWERSTEP01_IGATE_SHIFT),
+ POWERSTEP01_IGATE_8mA = (((uint8_t)0x02)<<POWERSTEP01_IGATE_SHIFT),
+ POWERSTEP01_IGATE_16mA = (((uint8_t)0x03)<<POWERSTEP01_IGATE_SHIFT),
+ POWERSTEP01_IGATE_24mA = (((uint8_t)0x04)<<POWERSTEP01_IGATE_SHIFT),
+ POWERSTEP01_IGATE_32mA = (((uint8_t)0x05)<<POWERSTEP01_IGATE_SHIFT),
+ POWERSTEP01_IGATE_64mA = (((uint8_t)0x06)<<POWERSTEP01_IGATE_SHIFT),
+ POWERSTEP01_IGATE_96mA = (((uint8_t)0x07)<<POWERSTEP01_IGATE_SHIFT),
+} powerstep01_Igate_t;
+
+/// Turn off boost time (TBOOST field of GATECFG1 register of PowerStep01)
+typedef enum {
+ POWERSTEP01_TBOOST_0ns = (((uint8_t)0x00)<<POWERSTEP01_TBOOST_SHIFT),
+ POWERSTEP01_TBOOST_62_5__83_3__125ns = (((uint8_t)0x01)<<POWERSTEP01_TBOOST_SHIFT),
+ POWERSTEP01_TBOOST_125ns = (((uint8_t)0x02)<<POWERSTEP01_TBOOST_SHIFT),
+ POWERSTEP01_TBOOST_250ns = (((uint8_t)0x03)<<POWERSTEP01_TBOOST_SHIFT),
+ POWERSTEP01_TBOOST_375ns = (((uint8_t)0x04)<<POWERSTEP01_TBOOST_SHIFT),
+ POWERSTEP01_TBOOST_500ns = (((uint8_t)0x05)<<POWERSTEP01_TBOOST_SHIFT),
+ POWERSTEP01_TBOOST_750ns = (((uint8_t)0x06)<<POWERSTEP01_TBOOST_SHIFT),
+ POWERSTEP01_TBOOST_1000ns = (((uint8_t)0x07)<<POWERSTEP01_TBOOST_SHIFT),
+} powerstep01_Tboost_t;
+
+/// External clock watchdog (WD_EN field of GATECFG1 register of PowerStep01)
+typedef enum {
+ POWERSTEP01_WD_EN_DISABLE = ((uint16_t)0x0000),
+ POWERSTEP01_WD_EN_ENABLE = ((uint16_t) ((0x1) << 11))
+} powerstep01_WdEn_t;
+
+/// masks for GATECFG2 register of PowerStep01
+typedef enum {
+ POWERSTEP01_GATECFG2_TDT = ((uint8_t)0x1F),
+ POWERSTEP01_GATECFG2_TBLANK = ((uint8_t)0xE0)
+} powerstep01_GateCfg2Masks_t;
+
+/// Blanking time (TBLANK field of GATECFG2 register of PowerStep01)
+typedef enum {
+ POWERSTEP01_TBLANK_125ns = (((uint8_t)0x00)<<POWERSTEP01_TBLANK_SHIFT),
+ POWERSTEP01_TBLANK_250ns = (((uint8_t)0x01)<<POWERSTEP01_TBLANK_SHIFT),
+ POWERSTEP01_TBLANK_375ns = (((uint8_t)0x02)<<POWERSTEP01_TBLANK_SHIFT),
+ POWERSTEP01_TBLANK_500ns = (((uint8_t)0x03)<<POWERSTEP01_TBLANK_SHIFT),
+ POWERSTEP01_TBLANK_625ns = (((uint8_t)0x04)<<POWERSTEP01_TBLANK_SHIFT),
+ POWERSTEP01_TBLANK_750ns = (((uint8_t)0x05)<<POWERSTEP01_TBLANK_SHIFT),
+ POWERSTEP01_TBLANK_875ns = (((uint8_t)0x06)<<POWERSTEP01_TBLANK_SHIFT),
+ POWERSTEP01_TBLANK_1000ns = (((uint8_t)0x07)<<POWERSTEP01_TBLANK_SHIFT),
+} powerstep01_TBlank_t;
+
+/// Dead time (TDT field of GATECFG2 register of PowerStep01)
+typedef enum {
+ POWERSTEP01_TDT_125ns = (((uint8_t)0x00)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_250ns = (((uint8_t)0x01)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_375ns = (((uint8_t)0x02)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_500ns = (((uint8_t)0x03)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_625ns = (((uint8_t)0x04)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_750ns = (((uint8_t)0x05)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_875ns = (((uint8_t)0x06)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_1000ns = (((uint8_t)0x07)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_1125ns = (((uint8_t)0x08)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_1250ns = (((uint8_t)0x09)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_1375ns = (((uint8_t)0x0A)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_1500ns = (((uint8_t)0x0B)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_1625ns = (((uint8_t)0x0C)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_1750ns = (((uint8_t)0x0D)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_1875ns = (((uint8_t)0x0E)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_2000ns = (((uint8_t)0x0F)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_2125ns = (((uint8_t)0x10)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_2250ns = (((uint8_t)0x11)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_2375ns = (((uint8_t)0x12)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_2500ns = (((uint8_t)0x13)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_2625ns = (((uint8_t)0x14)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_2750ns = (((uint8_t)0x15)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_2875ns = (((uint8_t)0x16)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_3000ns = (((uint8_t)0x17)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_3125ns = (((uint8_t)0x18)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_3250ns = (((uint8_t)0x19)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_3375ns = (((uint8_t)0x1A)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_3500ns = (((uint8_t)0x1B)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_3625ns = (((uint8_t)0x1C)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_3750ns = (((uint8_t)0x1D)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_3875ns = (((uint8_t)0x1E)<<POWERSTEP01_TDT_SHIFT),
+ POWERSTEP01_TDT_4000ns = (((uint8_t)0x1F)<<POWERSTEP01_TDT_SHIFT)
+} powerstep01_Tdt_t;
+
+#endif /* DRIVERS_FPGA_MOTERS_DRIVER_POWERSTEP01_H_ */
diff --git a/Software/Embedded_SW/Embedded/Drivers/I2C_Communication/ADC_MUX/ADC_MUX.c b/Software/Embedded_SW/Embedded/Drivers/I2C_Communication/ADC_MUX/ADC_MUX.c
index 96e42fc36..94db2e3f4 100644
--- a/Software/Embedded_SW/Embedded/Drivers/I2C_Communication/ADC_MUX/ADC_MUX.c
+++ b/Software/Embedded_SW/Embedded/Drivers/I2C_Communication/ADC_MUX/ADC_MUX.c
@@ -244,7 +244,7 @@ double Get_MidTank_Pressure_Sensor(MidTank_t MidTank_ID) //0-7
///////////////////////// Head_MixChip_Heaters_Current //////////////////////////////
-bool Heaters_Current_Read_Enable[9] = {true,true,true,true,true,true,true,true,true};
+bool Heaters_Current_Read_Enable[9] = {true,true,true,true,true,true,true,true,false};
double Heaters_Current[9];
@@ -282,50 +282,50 @@ uint32_t Read_Head_MixChip_Heaters_Current(HEATERS_CURRENT Heater_ID) //0-5
uint32_t Channel;
uint32_t VsampleInBits;
-/*
- * zone Heater No. Shunt Resistor Power Current I2C ID I2C Address I2C
- * Dyer_Head zone_2 3 0.025 ohm 45W 1.875A 2 0x40 4
- * Dyer_Head zone_3 3 0.025 ohm 45W 1.875A 2 0x40 5
- * Dyer_Head zone_4 5 0.025 ohm 75W 3.125A 2 0x44 0
- * Dyer_Head zone_5 5 0.025 ohm 75W 3.125A 2 0x44 1
- * Dyer_Head zone_6 3 0.025 ohm 45W 1.875A 2 0x40 3
- * Dyer_Head zone_1 2 0.05 ohm 30W 1.25A 2
- * MixChip 3 0.025 ohm 45W 1.875A 2 0x46 4
- *
- */
+ /*
+ * zone Heater No. Power Current Shunt Resistor I2C ID I2C Address I2C
+ * Dyer_Head zone_1 2 30W 1.25A 0.025 ohm 2 0x40 3
+ * Dyer_Head zone_2 3 45W 1.875A 0.025 ohm 2 0x40 4
+ * Dyer_Head zone_3 3 45W 1.875A 0.025 ohm 2 0x40 5
+ * Dyer_Head zone_4 5 75W 3.125A 0.025 ohm 2 0x44 0
+ * Dyer_Head zone_5 5 75W 3.125A 0.020 ohm 2 0x44 1 (5+6 Max 5A)
+ * Dyer_Head zone_6 3 45W 1.875A
+ * MixChip 3 45W 1.875A 0.025 ohm 2 0x46 4
+ *
+ */
assert (Heater_ID<NUM_OF_HEATERS);
- #warning to update all the Resistors to 0.025 Ohm after changing the hardware://there is overflow in Dyer Head zone 4 with resistor 0.05
- const double Resistor[NUM_OF_HEATERS] = {0.025, 0.025, 0.025, 0.05, 0.025, 0.025};
+ #warning need to change the hardware://there is overflow in Dyer Head zone 4 with resistor 0.05
+ const double Resistor[NUM_OF_HEATERS] = {0.025, 0.025, 0.025, 0.025, 0.020, 0.025};
if (Heaters_Current_Read_Enable[Heater_ID] == false)
return Heaters_Current[Heater_ID];
switch(Heater_ID)
{
- case HEAD_ZONE_1_6:
+ case HEAD_ZONE_1:
I2C_Slave_Add = 0x40;
- Channel = 0x08;
+ Channel = 0x10;
break;
case HEAD_ZONE_2:
I2C_Slave_Add = 0x40;
- Channel = 0x10;
+ Channel = 0x08;
break;
case HEAD_ZONE_3:
I2C_Slave_Add = 0x40;
- Channel = 0x20;
+ Channel = 0x04;
break;
case HEAD_ZONE_4:
I2C_Slave_Add = 0x44;
- Channel = 0x01;
+ Channel = 0x80;
break;
- case HEAD_ZONE_5:
+ case HEAD_ZONE_5_6:
I2C_Slave_Add = 0x44;
- Channel = 0x02;
+ Channel = 0x40;
break;
case MIXCHIP:
I2C_Slave_Add = 0x46;
- Channel = 0x20;
+ Channel = 0x08;
break;
default:
diff --git a/Software/Embedded_SW/Embedded/Drivers/I2C_Communication/ADC_MUX/ADC_MUX.h b/Software/Embedded_SW/Embedded/Drivers/I2C_Communication/ADC_MUX/ADC_MUX.h
index 1c5fb6dbd..f30f587b3 100644
--- a/Software/Embedded_SW/Embedded/Drivers/I2C_Communication/ADC_MUX/ADC_MUX.h
+++ b/Software/Embedded_SW/Embedded/Drivers/I2C_Communication/ADC_MUX/ADC_MUX.h
@@ -25,11 +25,11 @@ typedef enum
typedef enum
{
- HEAD_ZONE_1_6,//HEAD_ZONE_1,
+ HEAD_ZONE_1,
HEAD_ZONE_2,
HEAD_ZONE_3,
HEAD_ZONE_4,
- HEAD_ZONE_5,//HEAD_ZONE_5_6,
+ HEAD_ZONE_5_6,
MIXCHIP,
DRYER_CURRENT_1,
DRYER_CURRENT_2,
@@ -55,5 +55,6 @@ void Disable_Reading_Heaters_Current(HEATERS_CURRENT Heater_ID); //0-5
uint32_t Read_Head_MixChip_Heaters_Current(HEATERS_CURRENT Heater_ID);
double Get_Heaters_Current(HEATERS_CURRENT Heater_ID);
int Get_Heaters_Current_Integer(HEATERS_CURRENT Heater_ID); //0-8
+uint32_t Read_Heaters_Current(HEATERS_CURRENT Heater_ID);
#endif /* DRIVERS_I2C_COMMUNICATION_ADC_MUX_ADC_MUX_H_ */
diff --git a/Software/Embedded_SW/Embedded/Drivers/SPI/SPI_Comm.c b/Software/Embedded_SW/Embedded/Drivers/SPI/SPI_Comm.c
index 8f6728456..858fc01cb 100644
--- a/Software/Embedded_SW/Embedded/Drivers/SPI/SPI_Comm.c
+++ b/Software/Embedded_SW/Embedded/Drivers/SPI/SPI_Comm.c
@@ -14,6 +14,7 @@
//#include "graphics_adapter.h"
#include "drivers/FPGA/Moters_Driver/L6470.h"
+#include "drivers/FPGA/Moters_Driver/PowerSTEP01.h"
#include "PMR/Hardware/HardwareMotor.pb-c.h"
//#include "drivers/FPGA/FPGA_Comm.h"
@@ -1249,6 +1250,8 @@ uint32_t Get_Param(byte param)//OK
case x_INT_SPD: ;
case x_CONFIG: ;
case x_STATUS:
+ case x_POWERSTEP01_STATUS:
+ case x_POWERSTEP01_CONFIG:
//while(SSIBusy(SSI2_BASE)){};
//while(Check_SPI_Busy() == BUSY){};
temp = Write_Byte((uint8_t)(0x00));
diff --git a/Software/Embedded_SW/Embedded/Drivers/SSI_Comm/Dancer/Dancer.c b/Software/Embedded_SW/Embedded/Drivers/SSI_Comm/Dancer/Dancer.c
index 3cc8d0d9e..6c692ed10 100644
--- a/Software/Embedded_SW/Embedded/Drivers/SSI_Comm/Dancer/Dancer.c
+++ b/Software/Embedded_SW/Embedded/Drivers/SSI_Comm/Dancer/Dancer.c
@@ -41,13 +41,13 @@ typedef struct // 24bit
SSI_ENC SSI_enc;
+#ifndef HUNDRED_MICROSECONDS_DANCER_READ
uint32_t Control_Read_Dancer_Position(HardwareDancerType DancerId, uint32_t Parameter1)
{
return DANCER_ENC[DancerId].Position;
//return SSI_enc.Position;
}
-
-
+#endif
uint32_t Read_Dancer_Position (HardwareDancerType DancerId)
{
#ifdef EVALUATION_BOARD
diff --git a/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c b/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c
index c2b228ffb..637c91e7d 100644
--- a/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c
+++ b/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.c
@@ -42,7 +42,7 @@ uint32_t ReadAppAndProgram(uint32_t ui32FlashStart,uint32_t ui32FileSize,void* b
// by the amount of the reserved block.
//
ui32FlashEnd = ui32FlashStart + ui32FileSize;
-#warning check all addresses
+
//
// Check to make sure the file size is not too large to fit in the flash.
@@ -57,10 +57,10 @@ uint32_t ReadAppAndProgram(uint32_t ui32FlashStart,uint32_t ui32FileSize,void* b
// Enter a loop to erase all the requested flash pages beginning at the
// application start address (above the USB stick updater).
//
- for(ui32Idx = ui32FlashStart; ui32Idx < ui32FlashEnd; ui32Idx += 1024)
+ /*for(ui32Idx = ui32FlashStart; ui32Idx < ui32FlashEnd; ui32Idx += 1024)
{
ROM_FlashErase(ui32Idx);
- }
+ }*/
//
// Enter a loop to read sectors from the application image file and
@@ -108,4 +108,27 @@ uint32_t ReadAppAndProgram(uint32_t ui32FlashStart,uint32_t ui32FileSize,void* b
//
return(1);
}
+#warning flash erase is now done only in init. should consider adding before config changes
+uint32_t EraseFlashSection(uint32_t ui32FlashStart,uint32_t ui32FileSize)
+{
+ volatile uint32_t ui32Idx;
+ for(ui32Idx = ui32FlashStart; ui32Idx < ui32FlashStart+ui32FileSize; ui32Idx += 1024)
+ {
+ ROM_FlashErase(ui32Idx);
+ }
+ return OK;
+
+}
+//Each word may not be subject to more than a specific number of programming cycles before an
+//erase cycle is required. In other words, for any given word, FlashProgram can only be called
+//twice before FlashErase is called.
+void FlashInit(void)
+{
+ volatile uint32_t ui32Idx;
+ //FlashUsecSet(120);
+ for(ui32Idx = FLASH_RAM_BASE; ui32Idx < FLASH_RAM_BASE+FLASH_SIZE; ui32Idx += 1024)
+ {
+ ROM_FlashErase(ui32Idx);
+ }
+}
diff --git a/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.h b/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.h
index a21afd52b..411f812c1 100644
--- a/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.h
+++ b/Software/Embedded_SW/Embedded/Drivers/flash_ram/FlashProgram.h
@@ -15,7 +15,7 @@
#define JOB_MAP_IN_FLASH FLASH_RAM_BASE+0X4000
#define GENHWCFG_MAP_IN_FLASH FLASH_RAM_BASE+0X10000
#define OTHER_MAP_IN_FLASH FLASH_RAM_BASE+0X12000
-#define FLASH_SIZE 0X50000
+#define FLASH_SIZE 0X30000
//*****************************************************************************
//
@@ -26,6 +26,8 @@
//
//*****************************************************************************
uint32_t ReadAppAndProgram(uint32_t ui32FlashStart,uint32_t ui32FileSize,void* buffer);
+void FlashInit(void);
+uint32_t EraseFlashSection(uint32_t ui32FlashStart,uint32_t ui32FileSize);
diff --git a/Software/Embedded_SW/Embedded/Embedded.cfg b/Software/Embedded_SW/Embedded/Embedded.cfg
index b88b47cf0..ea7a370b8 100644
--- a/Software/Embedded_SW/Embedded/Embedded.cfg
+++ b/Software/Embedded_SW/Embedded/Embedded.cfg
@@ -55,7 +55,7 @@ Program.global.usb0 = Hwi.create(58, "&USBCDCD_hwiHandler", hwi5Params);*/
var hwi6Params = new Hwi.Params();
hwi6Params.instance.name = "timer1";
-Program.global.timer1 = Hwi.create(37, "&OneMilliSecondMillisecInterrupt", hwi6Params);
+Program.global.timer1 = Hwi.create(37, "&MillisecInterrupt", hwi6Params);
var hwi17Params = new Hwi.Params();
hwi17Params.instance.name = "timer3";
diff --git a/Software/Embedded_SW/Embedded/Main.c b/Software/Embedded_SW/Embedded/Main.c
index b23cf3fa1..f14ef8ff1 100644
--- a/Software/Embedded_SW/Embedded/Main.c
+++ b/Software/Embedded_SW/Embedded/Main.c
@@ -27,6 +27,8 @@
#include <drivers/Flash_Memory/Flash_Memory.h>
+#include "drivers/Flash_ram/FlashProgram.h"
+
#include <DataDef.h>
#include "Sys_PinOut_Config/MCU_MAIN_pinout.h"
@@ -139,6 +141,8 @@ int main(void)
ROM_SysTickIntEnable();
ROM_SysTickEnable();
+// FlashInit();
+
Calculateinit();
PortFunctionInit();
diff --git a/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c b/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c
index f4da887c7..94c7614d1 100644
--- a/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c
+++ b/Software/Embedded_SW/Embedded/Modules/AlarmHandling/AlarmHandling.c
@@ -124,8 +124,8 @@ AlarmStatusItem AlarmState[MAX_SYSTEM_ALARMS];
* or static variable whose declaration follows the pragma directive (only if using it without #define for example: #pragma location = MOTOR_MAP_IN_FLASH)
* The variables must be declared either __no_init or const!
*/
-//AlarmHandlingItemStruc *AlarmItem;
-const AlarmHandlingItemStruc AlarmItem[MAX_SYSTEM_ALARMS]={
+AlarmHandlingItemStruc *AlarmItem;
+const AlarmHandlingItemStruc HardCodedAlarmItem[MAX_SYSTEM_ALARMS]={
{eHundredMillisecond,LimitSwitchAlarm,LimitSwitchAlarmEmpty_1,0,false,true,DEBUG_LOG_CATEGORY__Error,0xFF,0,EVENT_TYPE__DISPENSER_1_EMPTY,"Dispenser 1 Empty"},
{eHundredMillisecond,LimitSwitchAlarm,LimitSwitchAlarmEmpty_2,1,false,true,DEBUG_LOG_CATEGORY__Error,0xFF,0,EVENT_TYPE__DISPENSER_2_EMPTY,"Dispenser 2 Empty"},
{eHundredMillisecond,LimitSwitchAlarm,LimitSwitchAlarmEmpty_3,2,false,true,DEBUG_LOG_CATEGORY__Error,0xFF,0,EVENT_TYPE__DISPENSER_3_EMPTY,"Dispenser 3 Empty"},
@@ -270,15 +270,15 @@ const AlarmHandlingItemStruc AlarmItem[MAX_SYSTEM_ALARMS]={
{ eOneSecond, MotorAlarm, HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANMECH , HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANMECH , x_STATUS_UVLO , FALSE , DEBUG_LOG_CATEGORY__Error , 0xFF , 2 , EVENT_TYPE__DYEING_HEAD_CLEANING_MECHANISM_MOTOR_UNDERVOLTAGE ," MotorDyeingHeadCleaningUnderVoltage " }, /* 5038 */
{ eOneSecond, MotorAlarm, HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANHEAD , HARDWARE_MOTOR_TYPE__MOTO_DH_CLEANHEAD , x_STATUS_UVLO , FALSE , DEBUG_LOG_CATEGORY__Error , 0xFF , 2 , EVENT_TYPE__DYEING_HEAD_CLEANING_HEAD_MOTOR_UNDERVOLTAGE ," MotorDyeingHeadCleaningHeadUnderVoltage " }, /* 5042 */
- { eOneSecond, CurrentAlarm, HEAD_ZONE_1_6 , HEAD_ZONE_1_6 , 312 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DYEING_HEAD_ZONE_1_CURRENT_OUT_OF_RANGE ," Head Zone 1 Heater Current Out Of Range " }, /* 5018 */
- { eOneSecond, CurrentAlarm, HEAD_ZONE_2 , HEAD_ZONE_2 , 187 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DYEING_HEAD_ZONE_2_CURRENT_OUT_OF_RANGE ," Head Zone 2 Heater Current Out Of Range " }, /* 5019 */
- { eOneSecond, CurrentAlarm, HEAD_ZONE_3 , HEAD_ZONE_3 , 187 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DYEING_HEAD_ZONE_3_CURRENT_OUT_OF_RANGE ," Head Zone 3 Heater Current Out Of Range " }, /* 5020 */
- { eOneSecond, CurrentAlarm, HEAD_ZONE_4 , HEAD_ZONE_4 , 312 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DYEING_HEAD_ZONE_4_CURRENT_OUT_OF_RANGE ," Head Zone 4 Heater Current Out Of Range " }, /* 5021 */
- { eOneSecond, CurrentAlarm, HEAD_ZONE_5 , HEAD_ZONE_5 , 312 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DYEING_HEAD_ZONE_5_6_CURRENT_OUT_OF_RANGE ," Head Zone 5-6 Heater Current Out Of Range " }, /* 5022 */
- { eOneSecond, CurrentAlarm, MIXCHIP , MIXCHIP , 187 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__MIXER_CURRENT_OUT_OF_RANGE ," Mixer Heater Current Out Of Range " }, /* 6004 */
- { eOneSecond, CurrentAlarm, DRYER_CURRENT_1, DRYER_CURRENT_1, 1 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DRYER_HEATERS_ZONE_1_CURRENT_OUT_OF_RANGE ," Drier Heater 1 Current Out Of Range " }, /* 6004 */
- { eOneSecond, CurrentAlarm, DRYER_CURRENT_2, DRYER_CURRENT_2, 1 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DRYER_HEATERS_ZONE_2_CURRENT_OUT_OF_RANGE ," Drier Heater 2 Current Out Of Range " }, /* 6004 */
- {eOneSecond,DoNotPollAlarm,0,0,0,0,DEBUG_LOG_CATEGORY__Safety,0xFF,0,EVENT_TYPE__DYEING_HEAD_THERMAL_CUTOFF,"Dyeing head Thermal Cut-Off"},
+// { eOneSecond, CurrentAlarm, HEAD_ZONE_1 , HEAD_ZONE_1 , 312 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DYEING_HEAD_ZONE_1_CURRENT_OUT_OF_RANGE ," Head Zone 1 Heater Current Out Of Range " }, /* 5018 */
+// { eOneSecond, CurrentAlarm, HEAD_ZONE_2 , HEAD_ZONE_2 , 187 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DYEING_HEAD_ZONE_2_CURRENT_OUT_OF_RANGE ," Head Zone 2 Heater Current Out Of Range " }, /* 5019 */
+// { eOneSecond, CurrentAlarm, HEAD_ZONE_3 , HEAD_ZONE_3 , 187 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DYEING_HEAD_ZONE_3_CURRENT_OUT_OF_RANGE ," Head Zone 3 Heater Current Out Of Range " }, /* 5020 */
+// { eOneSecond, CurrentAlarm, HEAD_ZONE_4 , HEAD_ZONE_4 , 312 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DYEING_HEAD_ZONE_4_CURRENT_OUT_OF_RANGE ," Head Zone 4 Heater Current Out Of Range " }, /* 5021 */
+// { eOneSecond, CurrentAlarm, HEAD_ZONE_5_6 , HEAD_ZONE_5_6 , 312 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DYEING_HEAD_ZONE_5_6_CURRENT_OUT_OF_RANGE ," Head Zone 5-6 Heater Current Out Of Range " }, /* 5022 */
+// { eOneSecond, CurrentAlarm, MIXCHIP , MIXCHIP , 187 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__MIXER_CURRENT_OUT_OF_RANGE ," Mixer Heater Current Out Of Range " }, /* 6004 */
+// { eOneSecond, CurrentAlarm, DRYER_CURRENT_1, DRYER_CURRENT_1, 1 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DRYER_HEATERS_ZONE_1_CURRENT_OUT_OF_RANGE ," Drier Heater 1 Current Out Of Range " }, /* 6004 */
+// { eOneSecond, CurrentAlarm, DRYER_CURRENT_2, DRYER_CURRENT_2, 1 , FALSE , DEBUG_LOG_CATEGORY__Warning , 0xFF , 2 , EVENT_TYPE__DRYER_HEATERS_ZONE_2_CURRENT_OUT_OF_RANGE ," Drier Heater 2 Current Out Of Range " }, /* 6004 */
+// {eOneSecond,DoNotPollAlarm,0,0,0,0,DEBUG_LOG_CATEGORY__Safety,0xFF,0,EVENT_TYPE__DYEING_HEAD_THERMAL_CUTOFF,"Dyeing head Thermal Cut-Off"},
{eOneSecond,DoNotPollAlarm,0,0,0,0,DEBUG_LOG_CATEGORY__Warning,0xFF,0,EVENT_TYPE__THREAD_BREAK,"Thread Break"},
{eOneSecond,DoNotPollAlarm,0,0,0,0,DEBUG_LOG_CATEGORY__Warning,0xFF,0,EVENT_TYPE__THREAD_TENSION_CONTROL_FAILURE_FEEDER_DANCER,"Thread Feeder Tension Control Failure"},
@@ -330,9 +330,10 @@ void AlarmHandlingInit(void)
AlarmState[Alarm_i].EventPtr = NULL;
}
- //AlarmItem = (AlarmHandlingItemStruc *)MOTOR_MAP_IN_FLASH;
- //ReadAppAndProgram(AlarmItem, sizeof(AlarmHandlingItemStruc)*MAX_SYSTEM_ALARMS, HardCodedAlarmItem);
- //LOG_ERROR(AlarmItem[2].EventName,"Flash Test");
+ AlarmItem = (AlarmHandlingItemStruc *)ALARM_MAP_IN_FLASH;
+ EraseFlashSection(ALARM_MAP_IN_FLASH,sizeof(AlarmHandlingItemStruc)*MAX_SYSTEM_ALARMS);
+ ReadAppAndProgram(AlarmItem, sizeof(AlarmHandlingItemStruc)*MAX_SYSTEM_ALARMS, HardCodedAlarmItem);
+ LOG_ERROR(AlarmItem[2].EventName,"Flash Test");
return;
}
@@ -394,7 +395,7 @@ uint32_t AlarmHandlingConsequentActions(uint32_t AlarmId, DebugLogCategory Sever
case DEBUG_LOG_CATEGORY__Critical:
case DEBUG_LOG_CATEGORY__Safety:
- watchdogCriticalAlarm = true;
+// watchdogCriticalAlarm = true;
LOG_ERROR(AlarmId,"Critical Alarm - Watchdog activated to reset hardware");
/*
//stop all dispensers
diff --git a/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c b/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c
index 968e52d7d..db6624fd4 100644
--- a/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c
+++ b/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.c
@@ -40,6 +40,13 @@
#include "modules/thread/thread_ex.h"
#include "modules/ids/ids_ex.h"
+#include "drivers/Flash_Memory/Flash_Memory.h"
+#include "drivers/Flash_Memory/fatfs/ff.h"
+#include "drivers/Flash_ram/FlashProgram.h"
+
+#include "third_party/fatfs/src/ffconf.h"
+#include "Common/SWUpdate/FileSystem.h"
+
#include "Communication/Connection.h"
Task_Handle Millisecond_Task_Handle;
@@ -147,7 +154,11 @@ void MillisecStop(void)
MillisecRestart = false;
ADCAcquireStop();
}
+#ifdef HUNDRED_MICROSECONDS_DANCER_READ
+#define HIGH_TASK_FREQUENCY 12000
+#else
#define HIGH_TASK_FREQUENCY 120000
+#endif
void MillisecStart(void)
{
MillisecRestart = true;
@@ -164,6 +175,8 @@ void OneMilliSecondMillisecInterrupt(UArg arg0)
{
MillisecMessageStruc MillisecMessage;
uint32_t Tenmsec_millisecondCounter = 0;
+#ifndef HUNDRED_MICROSECONDS_DANCER_READ
+
ROM_IntMasterDisable();
ROM_TimerIntClear(Millisec_timerBase, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt
if (MillisecRestart == true)
@@ -176,6 +189,7 @@ void OneMilliSecondMillisecInterrupt(UArg arg0)
ROM_IntMasterEnable();
return;
}
+#endif
if (msec_millisecondCounter%10 == 0)
{
Tenmsec_millisecondCounter = msec_millisecondCounter;
@@ -420,10 +434,13 @@ uint32_t MillisecLoop(uint32_t tick)
}
}
}
+#ifdef HUNDRED_MICROSECONDS_DANCER_READ
+ SaveLogData();
+#else
Dancer_Data[FEEDER_DANCER] = Read_Dancer_Position(FEEDER_DANCER);
Dancer_Data[POOLER_DANCER] = Read_Dancer_Position(POOLER_DANCER);
Dancer_Data[WINDER_DANCER] = Read_Dancer_Position(WINDER_DANCER);
-
+#endif
return OK;
}
uint32_t MillisecLowLoop(uint32_t tick)
@@ -489,10 +506,10 @@ uint32_t MillisecLowLoop(uint32_t tick)
if (isMotorConfigured(Motor_i))
MotorGetStatusFromFPGA(Motor_i);
}
- /* for (Heater_i = 0;Heater_i < NUM_OF_HEATERS;Heater_i++)
+ for (Heater_i = 0;Heater_i < NUM_OF_HEATERS;Heater_i++)
{
- Read_Head_MixChip_Heaters_Current(Heater_i);
- }*/
+ Read_Heaters_Current(Heater_i);
+ }
}
if (OneMinute_Tick)
{
@@ -600,3 +617,147 @@ uint32_t getDrawerFansStatus(void)
{
return DrawerFansStatus;
}
+#ifdef HUNDRED_MICROSECONDS_DANCER_READ
+uint32_t DancerData[NUM_OF_DANCERS];
+uint32_t Control_Read_Dancer_Position(HardwareDancerType DancerId, uint32_t Parameter1, uint32_t Parameter2)
+{
+ return DancerData[DancerId];
+}
+uint32_t dancer1;
+uint32_t dancer2;
+uint32_t dancer3;
+uint32_t dancer1sum;
+uint32_t dancer2sum;
+uint32_t dancer3sum;
+uint32_t dancer_count;
+/*-----------------------*/
+uint32_t StoreBuffer[2][128];
+//char * StoreBuffer[2][512];
+/*-----------------------*/
+int StoreBufferId = 0;
+int StoreBufferCounter=0;
+uint32_t BufferCounter=0xEEEEEEEE;
+bool storeData=false;
+uint8_t len=0;
+void HundredMicroTimerInterrupt(int ARG0)
+{
+ ROM_IntMasterDisable();
+ ROM_TimerIntClear(Millisec_timerBase, TIMER_TIMA_TIMEOUT); // Clear the timer interrupt
+ if (MillisecRestart == true)
+ {
+ ROM_TimerLoadSet(Millisec_timerBase, TIMER_A,HIGH_TASK_FREQUENCY);
+ }
+ else
+ {
+ ROM_TimerDisable(Millisec_timerBase,TIMER_A);
+ ROM_IntMasterEnable();
+ return;
+ }
+ dancer1 = Read_Dancer_Position(WINDER_DANCER);
+ dancer2 = Read_Dancer_Position(POOLER_DANCER);
+ dancer3 = Read_Dancer_Position(FEEDER_DANCER);
+//data store - logging
+//double buffer switch
+ /*-----------------------*/
+ if (StoreBufferCounter>125)
+ //if (StoreBufferCounter>490)
+ /*-----------------------*/
+ {
+ StoreBufferId = 1-StoreBufferId;//switch buffer
+ StoreBufferCounter=0;
+ storeData = true;
+ }
+//double buffer initialize
+ /*-----------------------*/
+ if (StoreBufferCounter==0)
+ {
+ StoreBuffer[StoreBufferId][StoreBufferCounter] = BufferCounter++;
+ StoreBufferCounter++;
+ }
+ /*-----------------------*/
+//store data
+ /*-----------------------*/
+ StoreBuffer[StoreBufferId][StoreBufferCounter++] = dancer1;
+ StoreBuffer[StoreBufferId][StoreBufferCounter++] = dancer2;
+ StoreBuffer[StoreBufferId][StoreBufferCounter++] = dancer3;
+ /*-----------------------*/
+ //len = usprintf(&StoreBuffer[StoreBufferId][StoreBufferCounter], "\r\n%d %d %d", dancer1[dancer_count],dancer2[dancer_count],dancer3[dancer_count]);
+ //StoreBufferCounter+=(len+1);
+ /*-----------------------*/
+ dancer1sum+=dancer1;
+ dancer2sum+=dancer2;
+ dancer3sum+=dancer3;
+ dancer_count++;
+
+
+ if (dancer_count == 10)
+ {
+ DancerData[WINDER_DANCER] = dancer1sum/dancer_count;
+ DancerData[POOLER_DANCER] = dancer2sum/dancer_count;
+ DancerData[FEEDER_DANCER] = dancer3sum/dancer_count;
+ dancer_count = 0;
+ dancer1sum = 0;
+ dancer2sum = 0;
+ dancer3sum = 0;
+ OneMilliSecondMillisecInterrupt(ARG0);
+ }
+ ROM_IntMasterEnable();
+ return ;
+
+}
+char MillisecPath[50] = "0://SysInfo//Millisec.txt";
+FIL *FileHandle;
+void SaveLogData(void)
+{
+ uint32_t WrittenBytes = 0;
+ int BufferID = 1- StoreBufferId;
+
+ if (storeData == true)
+ {
+ if (FileHandle)
+ {
+ f_write(FileHandle,StoreBuffer[BufferID],512,&WrittenBytes );
+ storeData = false;
+ }
+ }
+}
+void MillisecLogInit(void)
+{
+ FRESULT Fresult = FR_OK;
+ ROM_IntMasterDisable();
+ BufferCounter = 0;
+ FileHandle = my_malloc(sizeof(FIL));
+ if (FileHandle == 0)
+ Fresult = FR_DENIED;
+ else
+ Fresult = f_open(FileHandle,MillisecPath,FA_WRITE | FA_OPEN_ALWAYS);
+ ROM_IntMasterEnable();
+ return ;
+
+}
+void MillisecLogClose(void)
+{
+ FRESULT Fresult = FR_OK;
+ if (FileHandle == 0)
+ Fresult = FR_DENIED;
+ else
+ {
+ storeData = false;
+ ROM_IntMasterDisable();
+ Fresult = f_close(FileHandle);
+ my_free(FileHandle);
+ FileHandle = 0;
+ ROM_IntMasterEnable();
+ }
+ return ;
+
+}
+#endif
+void MillisecInterrupt(UArg arg0)
+{
+#ifdef HUNDRED_MICROSECONDS_DANCER_READ
+ HundredMicroTimerInterrupt(arg0);
+#else
+ OneMilliSecondMillisecInterrupt(arg0);
+#endif
+}
diff --git a/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.h b/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.h
index 517716c08..61c7df7ee 100644
--- a/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.h
+++ b/Software/Embedded_SW/Embedded/Modules/Control/MillisecTask.h
@@ -36,6 +36,14 @@ void MillisecInit(void);
void MillisecStop(void);
void MillisecStart(void);
+#ifdef HUNDRED_MICROSECONDS_DANCER_READ
+void SaveLogData(void);
+void MillisecLogInit(void);
+void MillisecLogClose(void);
+
+#endif
+
+
extern bool watchdogCriticalAlarm;
extern Task_Handle Millisecond_Task_Handle;
diff --git a/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c b/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c
index 580648842..97bb2e245 100644
--- a/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c
+++ b/Software/Embedded_SW/Embedded/Modules/General/GeneralHardware.c
@@ -60,7 +60,9 @@ uint32_t HWConfigurationInit(void)
uint32_t status = OK;
UploadHardwareConfigurationRequest* UploadRequest;
+ GeneralHwReady = false;
Control_WD(ENABLE,250);
+
Fresult = f_mkdir(SW_INFO_DIR);
if ((Fresult == FR_OK)||(Fresult == FR_EXIST))
{
@@ -85,6 +87,7 @@ uint32_t HWConfigurationInit(void)
if (status ==OK)
{
upload_hardware_configuration_request__free_unpacked(UploadRequest,NULL);
+ EraseFlashSection(GENHWCFG_MAP_IN_FLASH,Bytes);
ReadAppAndProgram(GENHWCFG_MAP_IN_FLASH, Bytes, buffer);
}
else
@@ -232,9 +235,11 @@ uint32_t HWConfiguration(UploadHardwareConfigurationRequest* UploadRequest)
if (request->n_winders == 1)
status += InternalWinderConfigMessage(request->winders);
status += MotorsInit();
-
+
if (request->n_motors < NUM_OF_MOTORS)
{
+ //EraseFlashSection(GENHWCFG_MAP_IN_FLASH + 0x2000,sizeof(HardwareMotor)*request->n_motors);
+
for (Motor_i = 0; Motor_i < request->n_motors ; Motor_i++)
status += MotorsConfigMessage(request->motors[Motor_i]);
}
@@ -259,6 +264,8 @@ uint32_t HWConfiguration(UploadHardwareConfigurationRequest* UploadRequest)
//StoreDancerConfigMessage();
if (request->n_pidcontrols <= HARDWARE_PID_CONTROL_TYPE__Dispenser8)
{
+ IDS_DispenserControlInit();
+
for (PID_i = 0; PID_i < request->n_pidcontrols ; PID_i++)
{
if (request->pidcontrols[PID_i]->hardwarepidcontroltype <= HARDWARE_PID_CONTROL_TYPE__MixerHeater)
@@ -338,6 +345,9 @@ uint32_t HWConfigurationFunc(MessageContainer* requestContainer)
UploadHardwareConfigurationRequest* UploadRequest = upload_hardware_configuration_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
+ GeneralHwReady = false;
+ Control_WD(ENABLE,250);
+
status = HWConfiguration(UploadRequest);
responseContainer = createContainer(MESSAGE_TYPE__UploadHardwareConfigurationResponse, requestContainer->token, true, &response, &upload_hardware_configuration_response__pack, &upload_hardware_configuration_response__get_packed_size);
diff --git a/Software/Embedded_SW/Embedded/Modules/General/process.c b/Software/Embedded_SW/Embedded/Modules/General/process.c
index dd9f8deae..458bb35f2 100644
--- a/Software/Embedded_SW/Embedded/Modules/General/process.c
+++ b/Software/Embedded_SW/Embedded/Modules/General/process.c
@@ -38,11 +38,29 @@ int32_t tableindex = 0;
char ProcessParamsConfigPath[50] = "0://SysInfo//ProcessP.cfg";
ProcessParameters ProcessParametersKeep;
+void HeatersStopControlOnHeatersOff(ProcessParameters* ProcessParams)
+{
+ uint32_t temp_sum = 0;
+ temp_sum += ProcessParams->dryerzone1temp;
+ temp_sum += ProcessParams->dryerzone2temp;
+ temp_sum += ProcessParams->dryerzone3temp;
+ temp_sum += ProcessParams->mixertemp;
+ temp_sum += ProcessParams->headzone1temp;
+ temp_sum += ProcessParams->headzone2temp;
+ temp_sum += ProcessParams->headzone3temp;
+ temp_sum += ProcessParams->headzone4temp;
+ temp_sum += ProcessParams->headzone5temp;
+ temp_sum += ProcessParams->headzone6temp;
+ if (temp_sum == 0)// heating off
+ {
+ HeatersControlStop();
+ REPORT_MSG(temp_sum,"Heating control off - temperatures off");
+ }
+}
uint32_t HandleProcessParameters(ProcessParameters* ProcessParams)
{
uint32_t status = 0;
-
if (ProcessParams==NULL)
{
status = ERROR_CODE__INVALID_PARAMETER;
@@ -145,6 +163,7 @@ uint32_t HandleProcessParameters(ProcessParameters* ProcessParams)
HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary, false,
ProcessParams->dryerzone3temp);
*/
+ HeatersStopControlOnHeatersOff(ProcessParams);
dyeingspeed = ProcessParams->dyeingspeed;
dryerbufferlength = ProcessParams->dryerbufferlength;
mininkuptake = ProcessParams->mininkuptake;
diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_ex.h b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_ex.h
index 8a77f98a2..0b65d9e5e 100644
--- a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_ex.h
+++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_ex.h
@@ -27,4 +27,5 @@ void Heaters_SetOperationLimits(int acheatersloweroperationlimit,int acheatersu
uint32_t HeatersEnd(void);
+void HeatersControlStop(void);
uint32_t Heaters_Init(void);
diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c
index 6fbfa5884..7c4bb1761 100644
--- a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c
+++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_init.c
@@ -29,7 +29,7 @@
/******************** STRUCTURES AND ENUMs ********************************************/
-typedef enum {
+/*typedef enum {
HeatersInitialState,
HeatersInit,
HeatersControlledOp,
@@ -43,7 +43,7 @@ typedef enum {
HeatersOverHeat,
HeatersOnTest
}HEATERS_EVENTS_ENUM;
-
+*/
/******************** GLOBAL PARAMETERS ********************************************/
HeaterPIDControlConfig HeaterControl[MAX_HEATERS_NUM] = {0,0,0,0,0,0,0,0,0,0,0,0};
bool AcHeaterConfigured[MAX_AC_HEATERS] = {0,0,0};
diff --git a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c
index bbf3822f0..3f62fc3b6 100644
--- a/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c
+++ b/Software/Embedded_SW/Embedded/Modules/Heaters/Heaters_print.c
@@ -17,12 +17,13 @@
#include "PMR/Diagnostics/HeaterType.pb-c.h"
#include "PMR/Diagnostics/HeaterState.pb-c.h"
#include "PMR/common/MessageContainer.pb-c.h"
-#include "PMR/Diagnostics/EventType.pb-c.h"
+#include "PMR/Diagnostics/EventType.pb-c.h"
#include "../AlarmHandling/AlarmHandling.h"
#include "../control/control.h"
#include "../control/pidalgo.h"
+#include <ti/sysbios/knl/Task.h>
#include <driverlib/timer.h>
#include <inc/hw_ints.h>
#include <inc/hw_memmap.h>
@@ -89,7 +90,7 @@ uint32_t SecondDryerHeaterMaxTempControl = 0xFF;
//old uint32_t HeaterId2PT100Id[MAX_HEATERS_NUM] = {DRYER_AIR_PT100,DRYER_MAIN_PT100,DRYER_SECONDARY_PT100,TEMP_SENSE_ANALOG_DYEINGH_TEMP1,TEMP_SENSE_ANALOG_DYEINGH_TEMP2,TEMP_SENSE_ANALOG_DYEINGH_TEMP3,TEMP_SENSE_ANALOG_DYEINGH_TEMP4,TEMP_SENSE_ANALOG_DYEINGH_TEMP5,TEMP_SENSE_ANALOG_MIXCHIP_TEMP,TEMP_SENSE_AN_ENCLOSURETEMP3};
uint32_t HeaterId2PT100Id[MAX_HEATERS_NUM] = {DRYER_AIR_PT100,DRYER_MAIN_PT100,DRYER_SECONDARY_PT100,TEMP_SENSE_ANALOG_DYEINGH_TEMP1,TEMP_SENSE_ANALOG_DYEINGH_TEMP2,TEMP_SENSE_ANALOG_DYEINGH_TEMP3,TEMP_SENSE_ANALOG_DYEINGH_TEMP4,TEMP_SENSE_ANALOG_DYEINGH_TEMP5,HEAD6_PT100,MIXER_PT100};
-HEATERS_CURRENT HeaterId2CurrentId[MAX_HEATERS_NUM] = {NUM_OF_HEATERS,DRYER_CURRENT_1,DRYER_CURRENT_2,HEAD_ZONE_1_6,HEAD_ZONE_2,HEAD_ZONE_3,HEAD_ZONE_4,HEAD_ZONE_5,HEAD_ZONE_1_6,MIXCHIP};
+HEATERS_CURRENT HeaterId2CurrentId[MAX_HEATERS_NUM] = {NUM_OF_HEATERS,DRYER_CURRENT_1,DRYER_CURRENT_2,HEAD_ZONE_1,HEAD_ZONE_2,HEAD_ZONE_3,HEAD_ZONE_4,HEAD_ZONE_5_6,HEAD_ZONE_5_6,MIXCHIP};
uint32_t DryerInternalPT100Id = DRYER_AIR_PT100;
bool HeatersRestart = false;
@@ -276,6 +277,9 @@ uint32_t HeatersSingleHeaterEnd(HardwarePidControlType HeaterId)
HeaterReady[HeaterId] = true;
}
+ AlarmHandlingSetAlarm(HeaterUnderEventType[HeaterId], false);
+ AlarmHandlingSetAlarm(HeaterUnderEventType_B[HeaterId], false);
+ AlarmHandlingSetAlarm(HeaterEventType[HeaterId], false);
return status;
}
@@ -308,6 +312,30 @@ void HeatersStartControlTimer (void)
Report("HeatersStartControlTimer ", __FILE__,__LINE__,0, RpMessage, 0, 0);
return;
}
+/***************************************************************************************************/
+int GetFilteredHeaterRead(int HeaterId)
+{
+#define MAX_FILTER 12
+ int i,maxread = -999999,minread = 999999,sum=0;
+ int FilteredRead[MAX_FILTER];
+ for (i = 0; i < MAX_FILTER;i++)
+ {
+ FilteredRead[i] = TemperatureSensorRead(HeaterId2PT100Id[HeaterId]);
+ Task_sleep(1);
+ }
+ for (i = 0; i < MAX_FILTER;i++)
+ {
+ if (FilteredRead[i]<minread)
+ minread = FilteredRead[i];
+ if (FilteredRead[i]>maxread)
+ maxread = FilteredRead[i];
+ sum+=FilteredRead[i];
+ }
+ sum -= minread;
+ sum -= maxread;
+ Report("GetFilteredHeaterRead ", __FILE__,HeaterId,sum, minread, maxread, 0);
+ return (sum/(MAX_FILTER-2));
+}
/**************************************************************************************
* HeaterCommandRequestMessage
* called by: Communication from host
@@ -364,11 +392,17 @@ uint32_t HeaterCommandRequestMessage(int HeaterId, bool OnOff, int Temperature)
}
else if ((HeaterState == HEATER_ON)&& (OnOff == HEATER_ON)) //set temperature
{
- if (abs(HeaterPIDConfig[HeaterId].m_SetParam - HeaterCmd[HeaterId].targettemperatue)>0.5) //#bug 221
+ HeaterPIDConfig[HeaterId].m_SetParam = HeaterCmd[HeaterId].targettemperatue;
+ /*/if (abs(HeaterPIDConfig[HeaterId].m_SetParam - HeaterCmd[HeaterId].targettemperatue)>0.5) //#bug 221
{
PrepareHeater(HeaterId,Temperature); //prepare the heaters control info
}
- HeaterPIDConfig[HeaterId].m_SetParam = HeaterCmd[HeaterId].targettemperatue;
+ else
+ {
+ HeaterPreviousRead[HeaterId] = GetFilteredHeaterRead(HeaterId);//
+ LOG_ERROR(HeaterId,"ReRead Heater Temp");
+ }*/
+ PrepareHeater(HeaterId,Temperature); //prepare the heaters control info
// if the heater is not on return (?).
//set the target operation temperature
//set the heater operation mode to fast heating - depended on the current temperature
@@ -392,6 +426,88 @@ uint32_t HeaterCommandRequestMessage(int HeaterId, bool OnOff, int Temperature)
* called by: Communication from host
* initialized all global data
*/
+void PrepareACHeater(int HeaterId,uint32_t Frequency, uint32_t SetTemperatue)
+{
+ if (ControlIdtoHeaterId [HeaterId] == 0xFF)
+ {
+ ControlIdtoHeaterId [HeaterId] = AddControlCallback( HeaterControlCBFunction, Frequency/*eOneSecond*/,TemperatureSensorRead,(IfTypeHeaters*0x100+HeaterId),DryerInternalPT100Id,0);
+ //HeaterPreviousRead[HeaterId] = TemperatureSensorRead(DryerInternalPT100Id);
+ HeaterPreviousRead[HeaterId] = GetFilteredHeaterRead(HeaterId);//
+ Report("PrepareHeater Read", __FILE__,__LINE__,HeaterId, SetTemperatue, HeaterPreviousRead[HeaterId], 0);
+ HeaterPreviousRead[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain] = GetFilteredHeaterRead(HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain);//TemperatureSensorRead(HeaterId2PT100Id[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain]);
+ HeaterPreviousRead[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary] = GetFilteredHeaterRead(HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary);// = TemperatureSensorRead(HeaterId2PT100Id[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary]);
+ }
+ //turn all alarms off
+ AlarmHandlingSetAlarm(HeaterUnderEventType[HeaterId], false);
+ AlarmHandlingSetAlarm(HeaterUnderEventType_B[HeaterId], false);
+ AlarmHandlingSetAlarm(HeaterEventType[HeaterId], false);
+
+ if (ControlIdtoMaxHeaterId [HeaterId] == 0xFF)
+ ControlIdtoMaxHeaterId [HeaterId] = AddControlCallback( DcHeaterMaxTempCBFunction, eOneSecond,TemperatureSensorRead,(IfTypeHeaters*0x100+HeaterId),HeaterId2PT100Id[HeaterId],0);
+
+ Enable_Reading_Heaters_Current(HeaterId2CurrentId[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain]);
+ Enable_Reading_Heaters_Current(HeaterId2CurrentId[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary]);
+
+ HeaterRecalculateSharedHeatersParams(HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain, 0);
+ HeaterRecalculateSharedHeatersParams(HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary, 0);
+ if (MainDryerHeaterMaxTempControl == 0xFF)
+ MainDryerHeaterMaxTempControl = AddControlCallback( HeaterMaxTempCBFunction, eHundredMillisecond,TemperatureSensorRead,(IfTypeHeaters*0x100+HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain),HeaterId2PT100Id[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain],0);
+ if (SecondDryerHeaterMaxTempControl == 0xFF)
+ SecondDryerHeaterMaxTempControl = AddControlCallback( HeaterMaxTempCBFunction, eHundredMillisecond,TemperatureSensorRead,(IfTypeHeaters*0x100+HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary),HeaterId2PT100Id[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary],0);
+ //InitialHeating = true;
+ HeaterReady[HeaterId] = false;
+ if (BlowerCfg.enabled == true)
+ {
+ Turn_the_Blower_On();//Turn on with the Default_Voltage
+ if (BlowerCfg.heatingvoltage)
+ Control_Voltage_To_Blower(BlowerCfg.heatingvoltage);
+ else
+ Control_Voltage_To_Blower(BlowerCfg.voltage-500);
+
+ }
+ if (SetTemperatue)
+ {
+ Control_Dryer_Fan(START,75);//use START or STOP, 0 - 100%
+ }
+}
+/*
+ * PrepareHeater
+ * called by: Communication from host
+ * initialized all global data
+ */
+int PrepareDCHeater(int HeaterId, uint32_t Frequency, uint32_t SetTemperatue)
+{
+ if (ControlIdtoHeaterId [HeaterId] == 0xFF)
+ ControlIdtoHeaterId [HeaterId] = AddControlCallback( DCHeaterControlCBFunction, Frequency/*eOneSecond*/,TemperatureSensorRead,(IfTypeHeaters*0x100+HeaterId),HeaterId2PT100Id[HeaterId],0);
+ //HeaterPIDConfig[HeaterId].m_params.dt *=10;
+ //DCInitialHeating[HeaterId] = true;
+ HeaterReady[HeaterId] = false;
+ HeaterRecalculateHeaterParams(HeaterId, 0);
+
+ //turn all alarms off
+ AlarmHandlingSetAlarm(HeaterUnderEventType[HeaterId], false);
+ AlarmHandlingSetAlarm(HeaterUnderEventType_B[HeaterId], false);
+ AlarmHandlingSetAlarm(HeaterEventType[HeaterId], false);
+
+ Enable_Reading_Heaters_Current(HeaterId2CurrentId[HeaterId]);
+
+ HeaterPreviousRead[HeaterId] = GetFilteredHeaterRead(HeaterId);//TemperatureSensorRead(HeaterId2PT100Id[HeaterId]);
+ if((abs(HeaterPreviousRead[HeaterId]-MINIMUM_HEATER_READ)<1)||(abs(MAXIMUM_HEATER_READ-HeaterPreviousRead[HeaterId])<10))
+ {
+ LOG_ERROR (HeaterId,"PT100 not working properly");
+ return ERROR;
+ }
+ Report("PrepareHeater Read", __FILE__,__LINE__,HeaterId, SetTemperatue, HeaterPreviousRead[HeaterId], 0);
+ if (ControlIdtoMaxHeaterId [HeaterId] == 0xFF)
+ ControlIdtoMaxHeaterId [HeaterId] = AddControlCallback( DcHeaterMaxTempCBFunction, eOneSecond,TemperatureSensorRead,(IfTypeHeaters*0x100+HeaterId),HeaterId2PT100Id[HeaterId],0);
+
+ return OK;
+}
+/*
+ * PrepareHeater
+ * called by: Communication from host
+ * initialized all global data
+ */
uint32_t PrepareHeater(int HeaterId, uint32_t SetTemperatue)
{
double temp ;
@@ -402,7 +518,7 @@ uint32_t PrepareHeater(int HeaterId, uint32_t SetTemperatue)
return ERROR;
}
- Report("PrepareHeater ", __FILE__,__LINE__,HeaterId, SetTemperatue, 0, 0);
+ //Report("PrepareHeater ", __FILE__,__LINE__,HeaterId, SetTemperatue, 0, 0);
//start thread control for all motors
HeaterPIDConfig[HeaterId].m_params.MAX = HeaterControl[HeaterId].outputproportionalpowerlimit*100;
@@ -436,60 +552,12 @@ uint32_t PrepareHeater(int HeaterId, uint32_t SetTemperatue)
}
if (HeaterId >= MAX_AC_HEATERS) //DC Heaters
{
- if (ControlIdtoHeaterId [HeaterId] == 0xFF)
- ControlIdtoHeaterId [HeaterId] = AddControlCallback( DCHeaterControlCBFunction, Frequency/*eOneSecond*/,TemperatureSensorRead,(IfTypeHeaters*0x100+HeaterId),HeaterId2PT100Id[HeaterId],0);
- //HeaterPIDConfig[HeaterId].m_params.dt *=10;
- //DCInitialHeating[HeaterId] = true;
- HeaterReady[HeaterId] = false;
-
- Enable_Reading_Heaters_Current(HeaterId2CurrentId[HeaterId]);
-
- HeaterPreviousRead[HeaterId] = TemperatureSensorRead(HeaterId2PT100Id[HeaterId]);
- if((abs(HeaterPreviousRead[HeaterId]-MINIMUM_HEATER_READ)<1)||(abs(MAXIMUM_HEATER_READ-HeaterPreviousRead[HeaterId])<10))
- {
- LOG_ERROR (HeaterId,"PT100 not working properly");
+ if (PrepareDCHeater(HeaterId,Frequency,SetTemperatue)!=OK)
return ERROR;
- }
- Report("PrepareHeater Read", __FILE__,__LINE__,HeaterId, SetTemperatue, HeaterPreviousRead[HeaterId], 0);
- if (ControlIdtoMaxHeaterId [HeaterId] == 0xFF)
- ControlIdtoMaxHeaterId [HeaterId] = AddControlCallback( DcHeaterMaxTempCBFunction, eOneSecond,TemperatureSensorRead,(IfTypeHeaters*0x100+HeaterId),HeaterId2PT100Id[HeaterId],0);
-
}
else if (HeaterId == HARDWARE_PID_CONTROL_TYPE__DryerAirTemperature) //AC Heaters
{
- if (ControlIdtoHeaterId [HeaterId] == 0xFF)
- {
- ControlIdtoHeaterId [HeaterId] = AddControlCallback( HeaterControlCBFunction, Frequency/*eOneSecond*/,TemperatureSensorRead,(IfTypeHeaters*0x100+HeaterId),DryerInternalPT100Id,0);
- HeaterPreviousRead[HeaterId] = TemperatureSensorRead(DryerInternalPT100Id);
- Report("PrepareHeater Read", __FILE__,__LINE__,HeaterId, SetTemperatue, HeaterPreviousRead[HeaterId], 0);
- HeaterPreviousRead[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain] = TemperatureSensorRead(HeaterId2PT100Id[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain]);
- HeaterPreviousRead[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary] = TemperatureSensorRead(HeaterId2PT100Id[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary]);
- }
- if (ControlIdtoMaxHeaterId [HeaterId] == 0xFF)
- ControlIdtoMaxHeaterId [HeaterId] = AddControlCallback( DcHeaterMaxTempCBFunction, eOneSecond,TemperatureSensorRead,(IfTypeHeaters*0x100+HeaterId),HeaterId2PT100Id[HeaterId],0);
-
- Enable_Reading_Heaters_Current(HeaterId2CurrentId[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain]);
- Enable_Reading_Heaters_Current(HeaterId2CurrentId[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary]);
-
- if (MainDryerHeaterMaxTempControl == 0xFF)
- MainDryerHeaterMaxTempControl = AddControlCallback( HeaterMaxTempCBFunction, eHundredMillisecond,TemperatureSensorRead,(IfTypeHeaters*0x100+HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain),HeaterId2PT100Id[HARDWARE_PID_CONTROL_TYPE__DryerHeaterMain],0);
- if (SecondDryerHeaterMaxTempControl == 0xFF)
- SecondDryerHeaterMaxTempControl = AddControlCallback( HeaterMaxTempCBFunction, eHundredMillisecond,TemperatureSensorRead,(IfTypeHeaters*0x100+HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary),HeaterId2PT100Id[HARDWARE_PID_CONTROL_TYPE__DryerHeaterSecondary],0);
- //InitialHeating = true;
- HeaterReady[HeaterId] = false;
- if (BlowerCfg.enabled == true)
- {
- Turn_the_Blower_On();//Turn on with the Default_Voltage
- if (BlowerCfg.heatingvoltage)
- Control_Voltage_To_Blower(BlowerCfg.heatingvoltage);
- else
- Control_Voltage_To_Blower(BlowerCfg.voltage-500);
-
- }
- if (SetTemperatue)
- {
- Control_Dryer_Fan(START,75);//use START or STOP, 0 - 100%
- }
+ PrepareACHeater(HeaterId,Frequency,SetTemperatue);
}
return OK;
}
@@ -659,7 +727,7 @@ uint32_t DcHeaterMaxTempCBFunction(uint32_t IfIndex, uint32_t eadValue)
return OK;
}
}
- else //temperature withing limits
+ else //temperature within limits
{
if(UnderHeatCounter[index] )
{
@@ -711,6 +779,10 @@ uint32_t HeaterControlCBFunction(uint32_t IfIndex, uint32_t readValue)
if (abs(readValue - HeaterPreviousRead[index])>2000)
{
Report("Temperature Spike",__FILE__,index,HeaterPreviousRead[index],RpWarning,readValue, index);
+ if (readValue > HeaterCmd[index].targettemperatue)
+ {
+ DeActivateHeater(index);
+ }
return ERROR;
}
HeaterPreviousRead[index] = readValue;
@@ -834,6 +906,11 @@ uint32_t DCHeaterControlCBFunction(uint32_t IfIndex, uint32_t readValue)
if (abs(readValue - HeaterPreviousRead[index])>2000)
{
Report("Temperature Spike",__FILE__,__LINE__,HeaterPreviousRead[index],RpWarning,readValue, index);
+ if (readValue > HeaterCmd[index].targettemperatue)
+ {
+ DeActivateHeater(index);
+ HeaterRecalculateHeaterParams(index, 0);
+ }
return ERROR;
}
HeaterPreviousRead[index] = readValue;
@@ -844,6 +921,7 @@ uint32_t DCHeaterControlCBFunction(uint32_t IfIndex, uint32_t readValue)
if (readValue > ((HeaterCmd[index].targettemperatue * (100+HeaterControl[index].outputproportionalband))/100))
{
DeActivateHeater(index);
+ HeaterRecalculateHeaterParams(index, 0);
//Heaters OFF until coming into the proportional band
//Report("DC HEATER Over temperature ", __FILE__,__LINE__,index, RpMessage, readValue, 0);
return OK;
@@ -851,6 +929,7 @@ uint32_t DCHeaterControlCBFunction(uint32_t IfIndex, uint32_t readValue)
if (readValue < ((HeaterCmd[index].targettemperatue * (100-HeaterControl[index].outputproportionalband))/100))
{
ActivateHeater(index);
+ //HeaterRecalculateHeaterParams(index, 100);
//Heaters OFF until coming into the proportional band
//Report("DC HEATER Under temperature ", __FILE__,__LINE__,index, RpMessage, readValue, 0);
return OK;
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c
index 417b4e536..1e33b99ca 100644
--- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_dispenser.c
@@ -169,17 +169,30 @@ uint32_t IDS_Dispenser_Start_Motor_and_Open_Valve(int DispenserId, int MotorSpee
DispenserCallback[DispenserId] = callback;
TimerMotors_t HW_Motor_Id = DispenserIdToMotorId[DispenserId];
- MotorSetSpeed(HW_Motor_Id, MotorSpeed);
- CurrentDispenserSpeed[DispenserId] = MotorSpeed;
- if (DispenserControlId[DispenserId] != 0xFF)
- Report("Cannot Add control callback",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);
- Report("IDS_Dispenser_Start_Motor_and_Open_Valve",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)msec_millisecondCounter,0);
-
- DispenserControlId[DispenserId] = AddControlCallback( IDS_Dispenser_OpenValveCallback, OpenValveTimeout, TemplateDataReadCBFunction,DispenserId, DispenserId, 0 );
- if (DispenserControlId[DispenserId] == 0xFF)
- Report("Add control callback failed",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);
+ if (CurrentDispenserSpeed[DispenserId]) //motor already running
+ {
+ MotorSetSpeed(HW_Motor_Id, MotorSpeed);
+ CurrentDispenserSpeed[DispenserId] = MotorSpeed;
+ if (DispenserCallback[DispenserId])
+ {
+ DispenserCallback[DispenserId](DispenserId,0);
+ DispenserCallback[DispenserId] = 0;
+ }
+ }
else
- Report("Add control callback",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);
+ {
+ MotorSetSpeed(HW_Motor_Id, MotorSpeed);
+ CurrentDispenserSpeed[DispenserId] = MotorSpeed;
+ if (DispenserControlId[DispenserId] != 0xFF)
+ Report("Cannot Add control callback",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);
+ Report("IDS_Dispenser_Start_Motor_and_Open_Valve",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)msec_millisecondCounter,0);
+
+ DispenserControlId[DispenserId] = AddControlCallback( IDS_Dispenser_OpenValveCallback, OpenValveTimeout, TemplateDataReadCBFunction,DispenserId, DispenserId, 0 );
+ if (DispenserControlId[DispenserId] == 0xFF)
+ Report("Add control callback failed",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);
+ else
+ Report("Add control callback",__FILE__,__LINE__,(int)DispenserId,RpWarning,(int)DispenserControlId[DispenserId],0);
+ }
return OK;
}
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h
index 8f58bac3e..bf73ed7fa 100644
--- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_ex.h
@@ -40,6 +40,7 @@ uint32_t IDSDistanceToSpoolState(void);
uint32_t IDSEndState(void *JobDetails);
uint32_t IDS_DispenserPidRequestMessage(HardwarePidControl* request);
+uint32_t IDS_DispenserControlInit();
uint32_t IDS_HomeDispenser (uint32_t deviceID, uint32_t speed , callback_fptr callback);
uint32_t IDS_StopHomeDispenser (uint32_t deviceID);
diff --git a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c
index d77d6f082..2be233962 100644
--- a/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c
+++ b/Software/Embedded_SW/Embedded/Modules/IDS/IDS_print.c
@@ -30,7 +30,7 @@ typedef struct
bool m_isReady;
PID_Config_Params m_params;
}DispenserControlConfig_t;
-HardwarePidControl DispensersControl[MAX_SYSTEM_DISPENSERS] = {0};
+HardwarePidControl *DispensersControl;// = (HardwarePidControl *)GENHWCFG_MAP_IN_FLASH + 0x4000;
int32_t DispenserSamples[MAX_SYSTEM_DISPENSERS][MAX_CONTROL_SAMPLES] = {0};
int DispenserSamplePointer[MAX_SYSTEM_DISPENSERS] = {0};
@@ -55,6 +55,13 @@ bool DispenserUsedInJob[MAX_SYSTEM_DISPENSERS] = {false,false,false,fals
bool DispensersAlarmState[ MAX_SYSTEM_DISPENSERS] = {false,false,false,false,false,false,false,false};
int JobBrushStopId = 0;
+uint32_t IDS_DispenserControlInit()
+{
+ DispensersControl = (void *)(GENHWCFG_MAP_IN_FLASH + 0x4000);
+ EraseFlashSection(DispensersControl,sizeof(HardwarePidControl)*MAX_SYSTEM_DISPENSERS);
+ return OK;
+}
+
uint32_t IDS_DispenserPidRequestMessage(HardwarePidControl* request)
{
int Dispenser_i,i;
@@ -67,9 +74,10 @@ uint32_t IDS_DispenserPidRequestMessage(HardwarePidControl* request)
break;
}
}
- memcpy (&DispensersControl[Dispenser_i],request,sizeof(HardwarePidControl));
- if (DispensersControl[Dispenser_i].pvinputfilterfactormode > MAX_CONTROL_SAMPLES)
- DispensersControl[Dispenser_i].pvinputfilterfactormode = MAX_CONTROL_SAMPLES;
+ if (request->pvinputfilterfactormode > MAX_CONTROL_SAMPLES)
+ request->pvinputfilterfactormode = MAX_CONTROL_SAMPLES;
+ ReadAppAndProgram(&DispensersControl[Dispenser_i], sizeof(HardwarePidControl), request);
+
for (i = 0;i < DispensersControl[Dispenser_i].pvinputfilterfactormode; i++)
DispenserSamples[Dispenser_i][i] = 0; //reset the samples value for control beginning
/*DispenserNormalizedErrorCoEfficient[Dispenser_i] = (2*PI*DancersCfg[ThreadDispenserIdToDancerId[Dispenser_i]].armlength);
diff --git a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.c b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.c
index 47e1bda34..7735c9955 100644
--- a/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.c
+++ b/Software/Embedded_SW/Embedded/Modules/Stubs_Handler/Stub_Heater.c
@@ -25,7 +25,7 @@
void Stub_HeaterRequest(MessageContainer* requestContainer)
{
- uint32_t status = NOT_SUPPORTED;
+ uint32_t status = PASSED;
MessageContainer responseContainer;
StubHeaterRequest* request = stub_heater_request__unpack(NULL, requestContainer->data.len, requestContainer->data.data);
@@ -35,6 +35,11 @@ void Stub_HeaterRequest(MessageContainer* requestContainer)
request->heatergroupon
*/
+ if((request->heatergroupid == 0xff) && (request->heatergroupon == false) && (request->heatertemperaturereq == 0))
+ {
+ HeatersEnd();
+ }
+ else
if (request->heatergroupon )
status = ActivateHeater(request->heatergroupid);
else
diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_init.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_init.c
index 435d7aef3..a1e91f6fc 100644
--- a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_init.c
+++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_init.c
@@ -17,6 +17,8 @@
#include "drivers/Flash_Memory/fatfs/ff.h"
#include "drivers/SSI_Comm/Dancer/Dancer.h"
+#include "drivers/FPGA/Moters_Driver/PowerSTEP01.h"
+
#include "thread.h"
MotorDriverConfigStruc MotorsCfg[NUM_OF_MOTORS]={0};
HardwarePidControl MotorsControl[MAX_THREAD_MOTORS_NUM] = {0};
@@ -52,6 +54,14 @@ uint32_t MotorsConfigMessage(HardwareMotor * request)
MotorsCfg[Motor_i].pulseperround = request->pulseperround;
MotorsCfg[Motor_i].pulleyradius = request->pulleyradius;
MotorsCfg[Motor_i].configword = request->configword;
+ if(MotorDriverResponse[Motor_i].DriverType == VoltageCombinedMotDriver)
+ {
+ MotorsCfg[Motor_i].directionthreadwize = !(request->directionthreadwize);//PowerSTEP01
+ }
+ else
+ {
+ MotorsCfg[Motor_i].directionthreadwize = request->directionthreadwize;//L6470 + L6472
+ }
MotorsCfg[Motor_i].directionthreadwize = request->directionthreadwize;
MotorsCfg[Motor_i].kvalhold = request->kvalhold;
MotorsCfg[Motor_i].kvalrun = request->kvalrun;
diff --git a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c
index ee49d56f3..6a8474438 100644
--- a/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c
+++ b/Software/Embedded_SW/Embedded/Modules/Thread/Thread_print.c
@@ -427,9 +427,9 @@ uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue)
JobEndReason = JOB_THREAD_BREAK;
ThreadControlActive = false;
SendJobProgress(0.0,0,false, TMessage);
- //SegmentReady(Module_Thread,ModuleFail);
- AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_BREAK,true);
- EndState(CurrentJob,"ReadBreakSensor Error" );
+ SegmentReady(Module_Thread,ModuleFail);
+ //AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_BREAK,true);
+ //EndState(CurrentJob,"ReadBreakSensor Error" );
LOG_ERROR(index, "ReadBreakSensor Error");
return OK;
} //passed limit
@@ -458,7 +458,7 @@ uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue)
SendJobProgress(0.0,0,false, TMessage);
//EndState(CurrentJob,TMessage );
SegmentReady(Module_Thread,ModuleFail);
- switch (index)
+ /*switch (index)
{
case POOLER_MOTOR:
AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_TENSION_CONTROL_FAILURE_PULLER_DANCER,true);
@@ -469,7 +469,7 @@ uint32_t ThreadControlCBFunction(uint32_t IfIndex, uint32_t ReadValue)
case WINDER_MOTOR:
AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_TENSION_CONTROL_FAILURE_WINDER_DANCER,true);
break;
- }
+ }*/
LOG_ERROR (DancerId, "Dancer Failure");
return OK;
}
@@ -694,6 +694,9 @@ uint32_t ThreadPreSegmentState(void *JobDetails, uint32_t SegmentId)
PrepareState = false;
// set the new speed in the dryer motor to the speed of the new segment
MotorSetSpeed(HARDWARE_MOTOR_TYPE__MOTO_DRYER_DRIVING, OriginalMotorSpd_2PPS[DRYER_MOTOR]);
+#ifdef HUNDRED_MICROSECONDS_DANCER_READ
+ MillisecLogInit();
+#endif
if (MotorsCfg[HARDWARE_MOTOR_TYPE__MOTO_RLOADING].maxfrequency > 0)
{
@@ -775,7 +778,9 @@ char Endstr[150];
ThreadUpdateProcessLength (0.0,(void *)NULL);
SetOriginMotorSpeed(0);
-
+#ifdef HUNDRED_MICROSECONDS_DANCER_READ
+ MillisecLogClose();
+#endif
if (SpeedControlId != 0xFF)
{
if(RemoveControlCallback(SpeedControlId,ThreadLengthCBFunction)!=OK)
diff --git a/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c b/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c
index 08233ce9a..e012dc020 100644
--- a/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c
+++ b/Software/Embedded_SW/Embedded/StateMachines/Printing/JobSTM.c
@@ -43,6 +43,8 @@
#include "PMR/Hardware/Hardwaremotor.pb-c.h"
#include "PMR/Hardware/HardwareWinder.pb-c.h"
#include "PMR/common/MessageContainer.pb-c.h"
+#include "PMR/Diagnostics/EventType.pb-c.h"
+
#include "Modules/General/process.h"
#include "modules/Diagnostics/Diagnostics.h"
@@ -748,6 +750,23 @@ void SendJobProgress(double ProcessedLength, int SegmentId, bool done, char *Mes
{
responseContainer.has_error = true;
responseContainer.error = JobError_to_ErrorCode[JobEndReason];
+ switch (JobEndReason)
+ {
+ case JOB_THREAD_BREAK:
+ AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_BREAK,true);
+ break;
+ case JOB_POOLER_DANCER_FAIL:
+ AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_TENSION_CONTROL_FAILURE_PULLER_DANCER,true);
+ break;
+ case JOB_FEEDER_DANCER_FAIL:
+ AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_TENSION_CONTROL_FAILURE_FEEDER_DANCER,true);
+ break;
+ case JOB_WINDER_DANCER_FAIL:
+ AlarmHandlingSetAlarm(EVENT_TYPE__THREAD_TENSION_CONTROL_FAILURE_WINDER_DANCER,true);
+ break;
+ default:
+ break;
+ }
}
if (JobAbortedByUser == true)
{