From 76443612f3a3ac52635e6cc9d57b2071bf91b507 Mon Sep 17 00:00:00 2001
From: nelo <nelo@verdnatura.es>
Date: Thu, 17 Nov 2016 15:00:06 +0100
Subject: [PATCH] =?UTF-8?q?Cuadro=20de=20iconos=20com=C3=BAn=20a=20toda=20?=
 =?UTF-8?q?la=20aplicaci=C3=B3n.=20Barra=20superior.=20Opciones=20del=20cl?=
 =?UTF-8?q?iente.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../node_modules/yamljs/test/spec/YamlSpec.js | 757 ++++++++++++++++++
 @salix-services/customer/npm-debug.log        |  47 ++
 @salix-services/salix/client/index.ejs        |   8 +-
 @salix/app/src/mainmenu/mainmenu.html         |   1 -
 @salix/app/src/mainmenu/mainmenu.js           |   8 -
 @salix/client/.gitignore                      |   1 +
 @salix/client/index.js                        |   1 +
 @salix/client/package.json                    |  17 +
 @salix/client/src/client.js                   |   0
 @salix/client/src/leftmenu/actions.html       |   7 +
 @salix/client/src/leftmenu/actions.js         |   9 +
 @salix/client/src/leftmenu/descriptor.html    |   3 +
 @salix/client/src/leftmenu/descriptor.js      |   9 +
 @salix/client/src/leftmenu/leftmenu.html      |   4 +
 @salix/client/src/leftmenu/leftmenu.js        |   9 +
 @salix/client/src/module.js                   |   6 +
 @salix/client/src/topbar/topbar.html          |   6 +
 @salix/client/src/topbar/topbar.js            |   9 +
 @salix/core/src/core.js                       |   3 +
 @salix/core/src/mainmenu/mainmenu.html        |   5 +
 @salix/core/src/mainmenu/mainmenu.js          |  10 +
 @salix/vendor/src/vendor.js                   |   2 +
 22 files changed, 910 insertions(+), 12 deletions(-)
 create mode 100644 @salix-services/customer/node_modules/yamljs/test/spec/YamlSpec.js
 create mode 100644 @salix-services/customer/npm-debug.log
 delete mode 100644 @salix/app/src/mainmenu/mainmenu.html
 delete mode 100644 @salix/app/src/mainmenu/mainmenu.js
 create mode 100644 @salix/client/.gitignore
 create mode 100644 @salix/client/index.js
 create mode 100644 @salix/client/package.json
 create mode 100644 @salix/client/src/client.js
 create mode 100644 @salix/client/src/leftmenu/actions.html
 create mode 100644 @salix/client/src/leftmenu/actions.js
 create mode 100644 @salix/client/src/leftmenu/descriptor.html
 create mode 100644 @salix/client/src/leftmenu/descriptor.js
 create mode 100644 @salix/client/src/leftmenu/leftmenu.html
 create mode 100644 @salix/client/src/leftmenu/leftmenu.js
 create mode 100644 @salix/client/src/module.js
 create mode 100644 @salix/client/src/topbar/topbar.html
 create mode 100644 @salix/client/src/topbar/topbar.js
 create mode 100644 @salix/core/src/mainmenu/mainmenu.html
 create mode 100644 @salix/core/src/mainmenu/mainmenu.js

diff --git a/@salix-services/customer/node_modules/yamljs/test/spec/YamlSpec.js b/@salix-services/customer/node_modules/yamljs/test/spec/YamlSpec.js
new file mode 100644
index 0000000000..feac4145a6
--- /dev/null
+++ b/@salix-services/customer/node_modules/yamljs/test/spec/YamlSpec.js
@@ -0,0 +1,757 @@
+// Generated by CoffeeScript 1.10.0
+var YAML, examplePath, ref, url;
+
+if (typeof YAML === "undefined" || YAML === null) {
+  YAML = require('../../src/Yaml');
+}
+
+describe('Parsed YAML Collections', function() {
+  it('can be simple sequence', function() {
+    return expect(YAML.parse("- apple\n- banana\n- carrot")).toEqual(['apple', 'banana', 'carrot']);
+  });
+  it('can be nested sequences', function() {
+    return expect(YAML.parse("-\n - foo\n - bar\n - baz")).toEqual([['foo', 'bar', 'baz']]);
+  });
+  it('can be mixed sequences', function() {
+    return expect(YAML.parse("- apple\n-\n - foo\n - bar\n - x123\n- banana\n- carrot")).toEqual(['apple', ['foo', 'bar', 'x123'], 'banana', 'carrot']);
+  });
+  it('can be deeply nested sequences', function() {
+    return expect(YAML.parse("-\n -\n  - uno\n  - dos")).toEqual([[['uno', 'dos']]]);
+  });
+  it('can be simple mapping', function() {
+    return expect(YAML.parse("foo: whatever\nbar: stuff")).toEqual({
+      foo: 'whatever',
+      bar: 'stuff'
+    });
+  });
+  it('can be sequence in a mapping', function() {
+    return expect(YAML.parse("foo: whatever\nbar:\n - uno\n - dos")).toEqual({
+      foo: 'whatever',
+      bar: ['uno', 'dos']
+    });
+  });
+  it('can be nested mappings', function() {
+    return expect(YAML.parse("foo: whatever\nbar:\n fruit: apple\n name: steve\n sport: baseball")).toEqual({
+      foo: 'whatever',
+      bar: {
+        fruit: 'apple',
+        name: 'steve',
+        sport: 'baseball'
+      }
+    });
+  });
+  it('can be mixed mapping', function() {
+    return expect(YAML.parse("foo: whatever\nbar:\n -\n   fruit: apple\n   name: steve\n   sport: baseball\n - more\n -\n   python: rocks\n   perl: papers\n   ruby: scissorses")).toEqual({
+      foo: 'whatever',
+      bar: [
+        {
+          fruit: 'apple',
+          name: 'steve',
+          sport: 'baseball'
+        }, 'more', {
+          python: 'rocks',
+          perl: 'papers',
+          ruby: 'scissorses'
+        }
+      ]
+    });
+  });
+  it('can have mapping-in-sequence shortcut', function() {
+    return expect(YAML.parse("- work on YAML.py:\n   - work on Store")).toEqual([
+      {
+        'work on YAML.py': ['work on Store']
+      }
+    ]);
+  });
+  it('can have unindented sequence-in-mapping shortcut', function() {
+    return expect(YAML.parse("allow:\n- 'localhost'\n- '%.sourceforge.net'\n- '%.freepan.org'")).toEqual({
+      allow: ['localhost', '%.sourceforge.net', '%.freepan.org']
+    });
+  });
+  it('can merge key', function() {
+    return expect(YAML.parse("mapping:\n  name: Joe\n  job: Accountant\n  <<:\n    age: 38")).toEqual({
+      mapping: {
+        name: 'Joe',
+        job: 'Accountant',
+        age: 38
+      }
+    });
+  });
+  return it('can ignore trailing empty lines for smallest indent', function() {
+    return expect(YAML.parse(" trailing: empty lines\n")).toEqual({
+      trailing: 'empty lines'
+    });
+  });
+});
+
+describe('Parsed YAML Inline Collections', function() {
+  it('can be simple inline array', function() {
+    return expect(YAML.parse("---\nseq: [ a, b, c ]")).toEqual({
+      seq: ['a', 'b', 'c']
+    });
+  });
+  it('can be simple inline hash', function() {
+    return expect(YAML.parse("---\nhash: { name: Steve, foo: bar }")).toEqual({
+      hash: {
+        name: 'Steve',
+        foo: 'bar'
+      }
+    });
+  });
+  it('can be nested inline hash', function() {
+    return expect(YAML.parse("---\nhash: { val1: \"string\", val2: { v2k1: \"v2k1v\" } }")).toEqual({
+      hash: {
+        val1: 'string',
+        val2: {
+          v2k1: 'v2k1v'
+        }
+      }
+    });
+  });
+  return it('can be multi-line inline collections', function() {
+    return expect(YAML.parse("languages: [ Ruby,\n             Perl,\n             Python ]\nwebsites: { YAML: yaml.org,\n            Ruby: ruby-lang.org,\n            Python: python.org,\n            Perl: use.perl.org }")).toEqual({
+      languages: ['Ruby', 'Perl', 'Python'],
+      websites: {
+        YAML: 'yaml.org',
+        Ruby: 'ruby-lang.org',
+        Python: 'python.org',
+        Perl: 'use.perl.org'
+      }
+    });
+  });
+});
+
+describe('Parsed YAML Basic Types', function() {
+  it('can be strings', function() {
+    return expect(YAML.parse("---\nString")).toEqual('String');
+  });
+  it('can be double-quoted strings with backslashes', function() {
+    return expect(YAML.parse("str:\n    \"string with \\\\ inside\"")).toEqual({
+      str: 'string with \\ inside'
+    });
+  });
+  it('can be single-quoted strings with backslashes', function() {
+    return expect(YAML.parse("str:\n    'string with \\\\ inside'")).toEqual({
+      str: 'string with \\\\ inside'
+    });
+  });
+  it('can be double-quoted strings with line breaks', function() {
+    return expect(YAML.parse("str:\n    \"string with \\n inside\"")).toEqual({
+      str: 'string with \n inside'
+    });
+  });
+  it('can be single-quoted strings with escaped line breaks', function() {
+    return expect(YAML.parse("str:\n    'string with \\n inside'")).toEqual({
+      str: 'string with \\n inside'
+    });
+  });
+  it('can be double-quoted strings with line breaks and backslashes', function() {
+    return expect(YAML.parse("str:\n    \"string with \\n inside and \\\\ also\"")).toEqual({
+      str: 'string with \n inside and \\ also'
+    });
+  });
+  it('can be single-quoted strings with line breaks and backslashes', function() {
+    return expect(YAML.parse("str:\n    'string with \\n inside and \\\\ also'")).toEqual({
+      str: 'string with \\n inside and \\\\ also'
+    });
+  });
+  it('can have string characters in sequences', function() {
+    return expect(YAML.parse("- What's Yaml?\n- It's for writing data structures in plain text.\n- And?\n- And what? That's not good enough for you?\n- No, I mean, \"And what about Yaml?\"\n- Oh, oh yeah. Uh.. Yaml for JavaScript.")).toEqual(["What's Yaml?", "It's for writing data structures in plain text.", "And?", "And what? That's not good enough for you?", "No, I mean, \"And what about Yaml?\"", "Oh, oh yeah. Uh.. Yaml for JavaScript."]);
+  });
+  it('can have indicators in strings', function() {
+    return expect(YAML.parse("the colon followed by space is an indicator: but is a string:right here\nsame for the pound sign: here we have it#in a string\nthe comma can, honestly, be used in most cases: [ but not in, inline collections ]")).toEqual({
+      'the colon followed by space is an indicator': 'but is a string:right here',
+      'same for the pound sign': 'here we have it#in a string',
+      'the comma can, honestly, be used in most cases': ['but not in', 'inline collections']
+    });
+  });
+  it('can force strings', function() {
+    return expect(YAML.parse("date string: !str 2001-08-01\nnumber string: !str 192\ndate string 2: !!str 2001-08-01\nnumber string 2: !!str 192")).toEqual({
+      'date string': '2001-08-01',
+      'number string': '192',
+      'date string 2': '2001-08-01',
+      'number string 2': '192'
+    });
+  });
+  it('can be single-quoted strings', function() {
+    return expect(YAML.parse("all my favorite symbols: '#:!/%.)'\na few i hate: '&(*'\nwhy do i hate them?: 'it''s very hard to explain'")).toEqual({
+      'all my favorite symbols': '#:!/%.)',
+      'a few i hate': '&(*',
+      'why do i hate them?': 'it\'s very hard to explain'
+    });
+  });
+  it('can be double-quoted strings', function() {
+    return expect(YAML.parse("i know where i want my line breaks: \"one here\\nand another here\\n\"")).toEqual({
+      'i know where i want my line breaks': "one here\nand another here\n"
+    });
+  });
+  it('can be null', function() {
+    return expect(YAML.parse("name: Mr. Show\nhosted by: Bob and David\ndate of next season: ~")).toEqual({
+      'name': 'Mr. Show',
+      'hosted by': 'Bob and David',
+      'date of next season': null
+    });
+  });
+  it('can be boolean', function() {
+    return expect(YAML.parse("Is Gus a Liar?: true\nDo I rely on Gus for Sustenance?: false")).toEqual({
+      'Is Gus a Liar?': true,
+      'Do I rely on Gus for Sustenance?': false
+    });
+  });
+  it('can be integers', function() {
+    return expect(YAML.parse("zero: 0\nsimple: 12\none-thousand: 1,000\nnegative one-thousand: -1,000")).toEqual({
+      'zero': 0,
+      'simple': 12,
+      'one-thousand': 1000,
+      'negative one-thousand': -1000
+    });
+  });
+  it('can be integers as map keys', function() {
+    return expect(YAML.parse("1: one\n2: two\n3: three")).toEqual({
+      1: 'one',
+      2: 'two',
+      3: 'three'
+    });
+  });
+  it('can be floats', function() {
+    return expect(YAML.parse("a simple float: 2.00\nlarger float: 1,000.09\nscientific notation: 1.00009e+3")).toEqual({
+      'a simple float': 2.0,
+      'larger float': 1000.09,
+      'scientific notation': 1000.09
+    });
+  });
+  it('can be time', function() {
+    var iso8601Date, spaceSeparatedDate, withDatesToTime;
+    iso8601Date = new Date(Date.UTC(2001, 12 - 1, 14, 21, 59, 43, 10));
+    iso8601Date.setTime(iso8601Date.getTime() - 5 * 3600 * 1000);
+    spaceSeparatedDate = new Date(Date.UTC(2001, 12 - 1, 14, 21, 59, 43, 10));
+    spaceSeparatedDate.setTime(spaceSeparatedDate.getTime() - 5 * 3600 * 1000);
+    withDatesToTime = function(input) {
+      var key, res, val;
+      res = {};
+      for (key in input) {
+        val = input[key];
+        res[key] = Math.round(val.getTime() / 1000) * 1000;
+      }
+      return res;
+    };
+    return expect(withDatesToTime(YAML.parse("iso8601: 2001-12-14t21:59:43.10-05:00\nspace seperated: 2001-12-14 21:59:43.10 -05:00"))).toEqual(withDatesToTime({
+      'iso8601': iso8601Date,
+      'space seperated': spaceSeparatedDate
+    }));
+  });
+  return it('can be date', function() {
+    var aDate, withDatesToTime;
+    aDate = new Date(Date.UTC(1976, 7 - 1, 31, 0, 0, 0, 0));
+    withDatesToTime = function(input) {
+      var key, res, val;
+      return input;
+      res = {};
+      for (key in input) {
+        val = input[key];
+        res[key] = Math.round(val.getTime() / 1000) * 1000;
+      }
+      return res;
+    };
+    return expect(withDatesToTime(YAML.parse("date: 1976-07-31"))).toEqual(withDatesToTime({
+      'date': aDate
+    }));
+  });
+});
+
+describe('Parsed YAML Blocks', function() {
+  it('can be single ending newline', function() {
+    return expect(YAML.parse("---\nthis: |\n    Foo\n    Bar")).toEqual({
+      'this': "Foo\nBar\n"
+    });
+  });
+  it('can be single ending newline with \'+\' indicator', function() {
+    return expect(YAML.parse("normal: |\n  extra new lines not kept\n\npreserving: |+\n  extra new lines are kept\n\n\ndummy: value")).toEqual({
+      'normal': "extra new lines not kept\n",
+      'preserving': "extra new lines are kept\n\n\n",
+      'dummy': 'value'
+    });
+  });
+  it('can be multi-line block handling trailing newlines in function of \'+\', \'-\' indicators', function() {
+    return expect(YAML.parse("clipped: |\n    This has one newline.\n\n\n\nsame as \"clipped\" above: \"This has one newline.\\n\"\n\nstripped: |-\n    This has no newline.\n\n\n\nsame as \"stripped\" above: \"This has no newline.\"\n\nkept: |+\n    This has four newlines.\n\n\n\nsame as \"kept\" above: \"This has four newlines.\\n\\n\\n\\n\"")).toEqual({
+      'clipped': "This has one newline.\n",
+      'same as "clipped" above': "This has one newline.\n",
+      'stripped': 'This has no newline.',
+      'same as "stripped" above': 'This has no newline.',
+      'kept': "This has four newlines.\n\n\n\n",
+      'same as "kept" above': "This has four newlines.\n\n\n\n"
+    });
+  });
+  it('can be folded block in a sequence', function() {
+    return expect(YAML.parse("---\n- apple\n- banana\n- >\n    can't you see\n    the beauty of yaml?\n    hmm\n- dog")).toEqual(['apple', 'banana', "can't you see the beauty of yaml? hmm\n", 'dog']);
+  });
+  it('can be folded block as a mapping value', function() {
+    return expect(YAML.parse("---\nquote: >\n    Mark McGwire's\n    year was crippled\n    by a knee injury.\nsource: espn")).toEqual({
+      'quote': "Mark McGwire's year was crippled by a knee injury.\n",
+      'source': 'espn'
+    });
+  });
+  it('can be folded block handling trailing newlines in function of \'+\', \'-\' indicators', function() {
+    return expect(YAML.parse("clipped: >\n    This has one newline.\n\n\n\nsame as \"clipped\" above: \"This has one newline.\\n\"\n\nstripped: >-\n    This has no newline.\n\n\n\nsame as \"stripped\" above: \"This has no newline.\"\n\nkept: >+\n    This has four newlines.\n\n\n\nsame as \"kept\" above: \"This has four newlines.\\n\\n\\n\\n\"")).toEqual({
+      'clipped': "This has one newline.\n",
+      'same as "clipped" above': "This has one newline.\n",
+      'stripped': 'This has no newline.',
+      'same as "stripped" above': 'This has no newline.',
+      'kept': "This has four newlines.\n\n\n\n",
+      'same as "kept" above': "This has four newlines.\n\n\n\n"
+    });
+  });
+  return it('can be the whole document as intented block', function() {
+    return expect(YAML.parse("---\n  foo: \"bar\"\n  baz:\n    - \"qux\"\n    - \"quxx\"\n  corge: null")).toEqual({
+      'foo': "bar",
+      'baz': ['qux', 'quxx'],
+      'corge': null
+    });
+  });
+});
+
+describe('Parsed YAML Comments', function() {
+  it('can begin the document', function() {
+    return expect(YAML.parse("# This is a comment\nhello: world")).toEqual({
+      hello: 'world'
+    });
+  });
+  it('can be less indented in mapping', function() {
+    return expect(YAML.parse("parts:\n    a: 'b'\n    # normally indented comment\n    c: 'd'\n# less indented comment\n    e: 'f'")).toEqual({
+      parts: {
+        a: 'b',
+        c: 'd',
+        e: 'f'
+      }
+    });
+  });
+  it('can be less indented in sequence', function() {
+    return expect(YAML.parse("list-header:\n  - item1\n#  - item2\n  - item3\n  # - item4")).toEqual({
+      'list-header': ['item1', 'item3']
+    });
+  });
+  it('can finish a line', function() {
+    return expect(YAML.parse("hello: world # This is a comment")).toEqual({
+      hello: 'world'
+    });
+  });
+  return it('can end the document', function() {
+    return expect(YAML.parse("hello: world\n# This is a comment")).toEqual({
+      hello: 'world'
+    });
+  });
+});
+
+describe('Parsed YAML Aliases and Anchors', function() {
+  it('can be simple alias', function() {
+    return expect(YAML.parse("- &showell Steve\n- Clark\n- Brian\n- Oren\n- *showell")).toEqual(['Steve', 'Clark', 'Brian', 'Oren', 'Steve']);
+  });
+  return it('can be alias of a mapping', function() {
+    return expect(YAML.parse("- &hello\n    Meat: pork\n    Starch: potato\n- banana\n- *hello")).toEqual([
+      {
+        Meat: 'pork',
+        Starch: 'potato'
+      }, 'banana', {
+        Meat: 'pork',
+        Starch: 'potato'
+      }
+    ]);
+  });
+});
+
+describe('Parsed YAML Documents', function() {
+  it('can have YAML header', function() {
+    return expect(YAML.parse("--- %YAML:1.0\nfoo: 1\nbar: 2")).toEqual({
+      foo: 1,
+      bar: 2
+    });
+  });
+  it('can have leading document separator', function() {
+    return expect(YAML.parse("---\n- foo: 1\n  bar: 2")).toEqual([
+      {
+        foo: 1,
+        bar: 2
+      }
+    ]);
+  });
+  return it('can have multiple document separators in block', function() {
+    return expect(YAML.parse("foo: |\n    ---\n    foo: bar\n    ---\n    yo: baz\nbar: |\n    fooness")).toEqual({
+      foo: "---\nfoo: bar\n---\nyo: baz\n",
+      bar: "fooness\n"
+    });
+  });
+});
+
+describe('Dumped YAML Collections', function() {
+  it('can be simple sequence', function() {
+    return expect(YAML.parse("- apple\n- banana\n- carrot")).toEqual(YAML.parse(YAML.dump(['apple', 'banana', 'carrot'])));
+  });
+  it('can be nested sequences', function() {
+    return expect(YAML.parse("-\n - foo\n - bar\n - baz")).toEqual(YAML.parse(YAML.dump([['foo', 'bar', 'baz']])));
+  });
+  it('can be mixed sequences', function() {
+    return expect(YAML.parse("- apple\n-\n - foo\n - bar\n - x123\n- banana\n- carrot")).toEqual(YAML.parse(YAML.dump(['apple', ['foo', 'bar', 'x123'], 'banana', 'carrot'])));
+  });
+  it('can be deeply nested sequences', function() {
+    return expect(YAML.parse("-\n -\n  - uno\n  - dos")).toEqual(YAML.parse(YAML.dump([[['uno', 'dos']]])));
+  });
+  it('can be simple mapping', function() {
+    return expect(YAML.parse("foo: whatever\nbar: stuff")).toEqual(YAML.parse(YAML.dump({
+      foo: 'whatever',
+      bar: 'stuff'
+    })));
+  });
+  it('can be sequence in a mapping', function() {
+    return expect(YAML.parse("foo: whatever\nbar:\n - uno\n - dos")).toEqual(YAML.parse(YAML.dump({
+      foo: 'whatever',
+      bar: ['uno', 'dos']
+    })));
+  });
+  it('can be nested mappings', function() {
+    return expect(YAML.parse("foo: whatever\nbar:\n fruit: apple\n name: steve\n sport: baseball")).toEqual(YAML.parse(YAML.dump({
+      foo: 'whatever',
+      bar: {
+        fruit: 'apple',
+        name: 'steve',
+        sport: 'baseball'
+      }
+    })));
+  });
+  it('can be mixed mapping', function() {
+    return expect(YAML.parse("foo: whatever\nbar:\n -\n   fruit: apple\n   name: steve\n   sport: baseball\n - more\n -\n   python: rocks\n   perl: papers\n   ruby: scissorses")).toEqual(YAML.parse(YAML.dump({
+      foo: 'whatever',
+      bar: [
+        {
+          fruit: 'apple',
+          name: 'steve',
+          sport: 'baseball'
+        }, 'more', {
+          python: 'rocks',
+          perl: 'papers',
+          ruby: 'scissorses'
+        }
+      ]
+    })));
+  });
+  it('can have mapping-in-sequence shortcut', function() {
+    return expect(YAML.parse("- work on YAML.py:\n   - work on Store")).toEqual(YAML.parse(YAML.dump([
+      {
+        'work on YAML.py': ['work on Store']
+      }
+    ])));
+  });
+  it('can have unindented sequence-in-mapping shortcut', function() {
+    return expect(YAML.parse("allow:\n- 'localhost'\n- '%.sourceforge.net'\n- '%.freepan.org'")).toEqual(YAML.parse(YAML.dump({
+      allow: ['localhost', '%.sourceforge.net', '%.freepan.org']
+    })));
+  });
+  return it('can merge key', function() {
+    return expect(YAML.parse("mapping:\n  name: Joe\n  job: Accountant\n  <<:\n    age: 38")).toEqual(YAML.parse(YAML.dump({
+      mapping: {
+        name: 'Joe',
+        job: 'Accountant',
+        age: 38
+      }
+    })));
+  });
+});
+
+describe('Dumped YAML Inline Collections', function() {
+  it('can be simple inline array', function() {
+    return expect(YAML.parse("---\nseq: [ a, b, c ]")).toEqual(YAML.parse(YAML.dump({
+      seq: ['a', 'b', 'c']
+    })));
+  });
+  it('can be simple inline hash', function() {
+    return expect(YAML.parse("---\nhash: { name: Steve, foo: bar }")).toEqual(YAML.parse(YAML.dump({
+      hash: {
+        name: 'Steve',
+        foo: 'bar'
+      }
+    })));
+  });
+  it('can be multi-line inline collections', function() {
+    return expect(YAML.parse("languages: [ Ruby,\n             Perl,\n             Python ]\nwebsites: { YAML: yaml.org,\n            Ruby: ruby-lang.org,\n            Python: python.org,\n            Perl: use.perl.org }")).toEqual(YAML.parse(YAML.dump({
+      languages: ['Ruby', 'Perl', 'Python'],
+      websites: {
+        YAML: 'yaml.org',
+        Ruby: 'ruby-lang.org',
+        Python: 'python.org',
+        Perl: 'use.perl.org'
+      }
+    })));
+  });
+  return it('can be dumped empty sequences in mappings', function() {
+    return expect(YAML.parse(YAML.dump({
+      key: []
+    }))).toEqual({
+      key: []
+    });
+  });
+});
+
+describe('Dumped YAML Basic Types', function() {
+  it('can be strings', function() {
+    return expect(YAML.parse("---\nString")).toEqual(YAML.parse(YAML.dump('String')));
+  });
+  it('can be double-quoted strings with backslashes', function() {
+    return expect(YAML.parse("str:\n    \"string with \\\\ inside\"")).toEqual(YAML.parse(YAML.dump({
+      str: 'string with \\ inside'
+    })));
+  });
+  it('can be single-quoted strings with backslashes', function() {
+    return expect(YAML.parse("str:\n    'string with \\\\ inside'")).toEqual(YAML.parse(YAML.dump({
+      str: 'string with \\\\ inside'
+    })));
+  });
+  it('can be double-quoted strings with line breaks', function() {
+    return expect(YAML.parse("str:\n    \"string with \\n inside\"")).toEqual(YAML.parse(YAML.dump({
+      str: 'string with \n inside'
+    })));
+  });
+  it('can be double-quoted strings with line breaks and backslashes', function() {
+    return expect(YAML.parse("str:\n    \"string with \\n inside and \\\\ also\"")).toEqual(YAML.parse(YAML.dump({
+      str: 'string with \n inside and \\ also'
+    })));
+  });
+  it('can be single-quoted strings with line breaks and backslashes', function() {
+    return expect(YAML.parse("str:\n    'string with \\n inside and \\\\ also'")).toEqual(YAML.parse(YAML.dump({
+      str: 'string with \\n inside and \\\\ also'
+    })));
+  });
+  it('can be single-quoted strings with escaped line breaks', function() {
+    return expect(YAML.parse("str:\n    'string with \\n inside'")).toEqual(YAML.parse(YAML.dump({
+      str: 'string with \\n inside'
+    })));
+  });
+  it('can have string characters in sequences', function() {
+    return expect(YAML.parse("- What's Yaml?\n- It's for writing data structures in plain text.\n- And?\n- And what? That's not good enough for you?\n- No, I mean, \"And what about Yaml?\"\n- Oh, oh yeah. Uh.. Yaml for JavaScript.")).toEqual(YAML.parse(YAML.dump(["What's Yaml?", "It's for writing data structures in plain text.", "And?", "And what? That's not good enough for you?", "No, I mean, \"And what about Yaml?\"", "Oh, oh yeah. Uh.. Yaml for JavaScript."])));
+  });
+  it('can have indicators in strings', function() {
+    return expect(YAML.parse("the colon followed by space is an indicator: but is a string:right here\nsame for the pound sign: here we have it#in a string\nthe comma can, honestly, be used in most cases: [ but not in, inline collections ]")).toEqual(YAML.parse(YAML.dump({
+      'the colon followed by space is an indicator': 'but is a string:right here',
+      'same for the pound sign': 'here we have it#in a string',
+      'the comma can, honestly, be used in most cases': ['but not in', 'inline collections']
+    })));
+  });
+  it('can force strings', function() {
+    return expect(YAML.parse("date string: !str 2001-08-01\nnumber string: !str 192\ndate string 2: !!str 2001-08-01\nnumber string 2: !!str 192")).toEqual(YAML.parse(YAML.dump({
+      'date string': '2001-08-01',
+      'number string': '192',
+      'date string 2': '2001-08-01',
+      'number string 2': '192'
+    })));
+  });
+  it('can be single-quoted strings', function() {
+    return expect(YAML.parse("all my favorite symbols: '#:!/%.)'\na few i hate: '&(*'\nwhy do i hate them?: 'it''s very hard to explain'")).toEqual(YAML.parse(YAML.dump({
+      'all my favorite symbols': '#:!/%.)',
+      'a few i hate': '&(*',
+      'why do i hate them?': 'it\'s very hard to explain'
+    })));
+  });
+  it('can be double-quoted strings', function() {
+    return expect(YAML.parse("i know where i want my line breaks: \"one here\\nand another here\\n\"")).toEqual(YAML.parse(YAML.dump({
+      'i know where i want my line breaks': "one here\nand another here\n"
+    })));
+  });
+  it('can be null', function() {
+    return expect(YAML.parse("name: Mr. Show\nhosted by: Bob and David\ndate of next season: ~")).toEqual(YAML.parse(YAML.dump({
+      'name': 'Mr. Show',
+      'hosted by': 'Bob and David',
+      'date of next season': null
+    })));
+  });
+  it('can be boolean', function() {
+    return expect(YAML.parse("Is Gus a Liar?: true\nDo I rely on Gus for Sustenance?: false")).toEqual(YAML.parse(YAML.dump({
+      'Is Gus a Liar?': true,
+      'Do I rely on Gus for Sustenance?': false
+    })));
+  });
+  it('can be integers', function() {
+    return expect(YAML.parse("zero: 0\nsimple: 12\none-thousand: 1,000\nnegative one-thousand: -1,000")).toEqual(YAML.parse(YAML.dump({
+      'zero': 0,
+      'simple': 12,
+      'one-thousand': 1000,
+      'negative one-thousand': -1000
+    })));
+  });
+  it('can be integers as map keys', function() {
+    return expect(YAML.parse("1: one\n2: two\n3: three")).toEqual(YAML.parse(YAML.dump({
+      1: 'one',
+      2: 'two',
+      3: 'three'
+    })));
+  });
+  it('can be floats', function() {
+    return expect(YAML.parse("a simple float: 2.00\nlarger float: 1,000.09\nscientific notation: 1.00009e+3")).toEqual(YAML.parse(YAML.dump({
+      'a simple float': 2.0,
+      'larger float': 1000.09,
+      'scientific notation': 1000.09
+    })));
+  });
+  it('can be time', function() {
+    var iso8601Date, spaceSeparatedDate, withDatesToTime;
+    iso8601Date = new Date(Date.UTC(2001, 12 - 1, 14, 21, 59, 43, 10));
+    iso8601Date.setTime(iso8601Date.getTime() - 5 * 3600 * 1000);
+    spaceSeparatedDate = new Date(Date.UTC(2001, 12 - 1, 14, 21, 59, 43, 10));
+    spaceSeparatedDate.setTime(spaceSeparatedDate.getTime() - 5 * 3600 * 1000);
+    withDatesToTime = function(input) {
+      var key, res, val;
+      res = {};
+      for (key in input) {
+        val = input[key];
+        res[key] = Math.round(val.getTime() / 1000) * 1000;
+      }
+      return res;
+    };
+    return expect(withDatesToTime(YAML.parse("iso8601: 2001-12-14t21:59:43.10-05:00\nspace seperated: 2001-12-14 21:59:43.10 -05:00"))).toEqual(YAML.parse(YAML.dump(withDatesToTime({
+      'iso8601': iso8601Date,
+      'space seperated': spaceSeparatedDate
+    }))));
+  });
+  return it('can be date', function() {
+    var aDate, withDatesToTime;
+    aDate = new Date(Date.UTC(1976, 7 - 1, 31, 0, 0, 0, 0));
+    withDatesToTime = function(input) {
+      var key, res, val;
+      return input;
+      res = {};
+      for (key in input) {
+        val = input[key];
+        res[key] = Math.round(val.getTime() / 1000) * 1000;
+      }
+      return res;
+    };
+    return expect(withDatesToTime(YAML.parse("date: 1976-07-31"))).toEqual(YAML.parse(YAML.dump(withDatesToTime({
+      'date': aDate
+    }))));
+  });
+});
+
+describe('Dumped YAML Blocks', function() {
+  it('can be single ending newline', function() {
+    return expect(YAML.parse("---\nthis: |\n    Foo\n    Bar")).toEqual(YAML.parse(YAML.dump({
+      'this': "Foo\nBar\n"
+    })));
+  });
+  it('can be single ending newline with \'+\' indicator', function() {
+    return expect(YAML.parse("normal: |\n  extra new lines not kept\n\npreserving: |+\n  extra new lines are kept\n\n\ndummy: value")).toEqual(YAML.parse(YAML.dump({
+      'normal': "extra new lines not kept\n",
+      'preserving': "extra new lines are kept\n\n\n",
+      'dummy': 'value'
+    })));
+  });
+  it('can be multi-line block handling trailing newlines in function of \'+\', \'-\' indicators', function() {
+    return expect(YAML.parse("clipped: |\n    This has one newline.\n\n\n\nsame as \"clipped\" above: \"This has one newline.\\n\"\n\nstripped: |-\n    This has no newline.\n\n\n\nsame as \"stripped\" above: \"This has no newline.\"\n\nkept: |+\n    This has four newlines.\n\n\n\nsame as \"kept\" above: \"This has four newlines.\\n\\n\\n\\n\"")).toEqual(YAML.parse(YAML.dump({
+      'clipped': "This has one newline.\n",
+      'same as "clipped" above': "This has one newline.\n",
+      'stripped': 'This has no newline.',
+      'same as "stripped" above': 'This has no newline.',
+      'kept': "This has four newlines.\n\n\n\n",
+      'same as "kept" above': "This has four newlines.\n\n\n\n"
+    })));
+  });
+  it('can be folded block in a sequence', function() {
+    return expect(YAML.parse("---\n- apple\n- banana\n- >\n    can't you see\n    the beauty of yaml?\n    hmm\n- dog")).toEqual(YAML.parse(YAML.dump(['apple', 'banana', "can't you see the beauty of yaml? hmm\n", 'dog'])));
+  });
+  it('can be folded block as a mapping value', function() {
+    return expect(YAML.parse("---\nquote: >\n    Mark McGwire's\n    year was crippled\n    by a knee injury.\nsource: espn")).toEqual(YAML.parse(YAML.dump({
+      'quote': "Mark McGwire's year was crippled by a knee injury.\n",
+      'source': 'espn'
+    })));
+  });
+  return it('can be folded block handling trailing newlines in function of \'+\', \'-\' indicators', function() {
+    return expect(YAML.parse("clipped: >\n    This has one newline.\n\n\n\nsame as \"clipped\" above: \"This has one newline.\\n\"\n\nstripped: >-\n    This has no newline.\n\n\n\nsame as \"stripped\" above: \"This has no newline.\"\n\nkept: >+\n    This has four newlines.\n\n\n\nsame as \"kept\" above: \"This has four newlines.\\n\\n\\n\\n\"")).toEqual(YAML.parse(YAML.dump({
+      'clipped': "This has one newline.\n",
+      'same as "clipped" above': "This has one newline.\n",
+      'stripped': 'This has no newline.',
+      'same as "stripped" above': 'This has no newline.',
+      'kept': "This has four newlines.\n\n\n\n",
+      'same as "kept" above': "This has four newlines.\n\n\n\n"
+    })));
+  });
+});
+
+describe('Dumped YAML Comments', function() {
+  it('can begin the document', function() {
+    return expect(YAML.parse("# This is a comment\nhello: world")).toEqual(YAML.parse(YAML.dump({
+      hello: 'world'
+    })));
+  });
+  it('can finish a line', function() {
+    return expect(YAML.parse("hello: world # This is a comment")).toEqual(YAML.parse(YAML.dump({
+      hello: 'world'
+    })));
+  });
+  return it('can end the document', function() {
+    return expect(YAML.parse("hello: world\n# This is a comment")).toEqual(YAML.parse(YAML.dump({
+      hello: 'world'
+    })));
+  });
+});
+
+describe('Dumped YAML Aliases and Anchors', function() {
+  it('can be simple alias', function() {
+    return expect(YAML.parse("- &showell Steve\n- Clark\n- Brian\n- Oren\n- *showell")).toEqual(YAML.parse(YAML.dump(['Steve', 'Clark', 'Brian', 'Oren', 'Steve'])));
+  });
+  return it('can be alias of a mapping', function() {
+    return expect(YAML.parse("- &hello\n    Meat: pork\n    Starch: potato\n- banana\n- *hello")).toEqual(YAML.parse(YAML.dump([
+      {
+        Meat: 'pork',
+        Starch: 'potato'
+      }, 'banana', {
+        Meat: 'pork',
+        Starch: 'potato'
+      }
+    ])));
+  });
+});
+
+describe('Dumped YAML Documents', function() {
+  it('can have YAML header', function() {
+    return expect(YAML.parse("--- %YAML:1.0\nfoo: 1\nbar: 2")).toEqual(YAML.parse(YAML.dump({
+      foo: 1,
+      bar: 2
+    })));
+  });
+  it('can have leading document separator', function() {
+    return expect(YAML.parse("---\n- foo: 1\n  bar: 2")).toEqual(YAML.parse(YAML.dump([
+      {
+        foo: 1,
+        bar: 2
+      }
+    ])));
+  });
+  return it('can have multiple document separators in block', function() {
+    return expect(YAML.parse("foo: |\n    ---\n    foo: bar\n    ---\n    yo: baz\nbar: |\n    fooness")).toEqual(YAML.parse(YAML.dump({
+      foo: "---\nfoo: bar\n---\nyo: baz\n",
+      bar: "fooness\n"
+    })));
+  });
+});
+
+url = typeof document !== "undefined" && document !== null ? (ref = document.location) != null ? ref.href : void 0 : void 0;
+
+if (!(url != null) || url.indexOf('file://') === -1) {
+  examplePath = 'spec/example.yml';
+  if (typeof __dirname !== "undefined" && __dirname !== null) {
+    examplePath = __dirname + '/example.yml';
+  }
+  describe('YAML loading', function() {
+    it('can be done synchronously', function() {
+      return expect(YAML.load(examplePath)).toEqual({
+        "this": 'is',
+        a: ['YAML', 'example']
+      });
+    });
+    return it('can be done asynchronously', function(done) {
+      return YAML.load(examplePath, function(result) {
+        expect(result).toEqual({
+          "this": 'is',
+          a: ['YAML', 'example']
+        });
+        return done();
+      });
+    });
+  });
+}
diff --git a/@salix-services/customer/npm-debug.log b/@salix-services/customer/npm-debug.log
new file mode 100644
index 0000000000..8d22a93045
--- /dev/null
+++ b/@salix-services/customer/npm-debug.log
@@ -0,0 +1,47 @@
+0 info it worked if it ends with ok
+1 verbose cli [ '/usr/local/Cellar/node/6.3.1/bin/node',
+1 verbose cli   '/usr/local/bin/npm',
+1 verbose cli   'start' ]
+2 info using npm@3.10.3
+3 info using node@v6.3.1
+4 verbose run-script [ 'prestart', 'start', 'poststart' ]
+5 info lifecycle customer@1.0.0~prestart: customer@1.0.0
+6 silly lifecycle customer@1.0.0~prestart: no script for prestart, continuing
+7 info lifecycle customer@1.0.0~start: customer@1.0.0
+8 verbose lifecycle customer@1.0.0~start: unsafe-perm in lifecycle true
+9 verbose lifecycle customer@1.0.0~start: PATH: /usr/local/lib/node_modules/npm/bin/node-gyp-bin:/Users/nelo/Documents/node/customer/node_modules/.bin:/usr/local/Cellar/node/6.3.1/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
+10 verbose lifecycle customer@1.0.0~start: CWD: /Users/nelo/Documents/node/customer
+11 silly lifecycle customer@1.0.0~start: Args: [ '-c', 'node .' ]
+12 silly lifecycle customer@1.0.0~start: Returned: code: 1  signal: null
+13 info lifecycle customer@1.0.0~start: Failed to exec start script
+14 verbose stack Error: customer@1.0.0 start: `node .`
+14 verbose stack Exit status 1
+14 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:242:16)
+14 verbose stack     at emitTwo (events.js:106:13)
+14 verbose stack     at EventEmitter.emit (events.js:191:7)
+14 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:40:14)
+14 verbose stack     at emitTwo (events.js:106:13)
+14 verbose stack     at ChildProcess.emit (events.js:191:7)
+14 verbose stack     at maybeClose (internal/child_process.js:852:16)
+14 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:215:5)
+15 verbose pkgid customer@1.0.0
+16 verbose cwd /Users/nelo/Documents/node/customer
+17 error Darwin 16.0.0
+18 error argv "/usr/local/Cellar/node/6.3.1/bin/node" "/usr/local/bin/npm" "start"
+19 error node v6.3.1
+20 error npm  v3.10.3
+21 error code ELIFECYCLE
+22 error customer@1.0.0 start: `node .`
+22 error Exit status 1
+23 error Failed at the customer@1.0.0 start script 'node .'.
+23 error Make sure you have the latest version of node.js and npm installed.
+23 error If you do, this is most likely a problem with the customer package,
+23 error not with npm itself.
+23 error Tell the author that this fails on your system:
+23 error     node .
+23 error You can get information on how to open an issue for this project with:
+23 error     npm bugs customer
+23 error Or if that isn't available, you can get their info via:
+23 error     npm owner ls customer
+23 error There is likely additional logging output above.
+24 verbose exit [ 1, true ]
diff --git a/@salix-services/salix/client/index.ejs b/@salix-services/salix/client/index.ejs
index 5a7c56fb54..cf331d85ae 100644
--- a/@salix-services/salix/client/index.ejs
+++ b/@salix-services/salix/client/index.ejs
@@ -6,9 +6,11 @@
 			<link rel="stylesheet" href="layout.css"/>    
 	</head>
 	<body>
-		<div style="position:fixed; top:0; right:0; height:6em; width:10em; background-color:red;"></div>
-
-		<vn-vertical id="app" class="full-height" ui-view scrollable>
+		<vn-vertical id="app" class="full-height">
+			<vn-mainmenu></vn-mainmenu>	
+			<vn-vertical ui-view scrollable>
+		
+			</vn-vertical>
 		</vn-vertical>
 		<script
 			type="text/javascript"
diff --git a/@salix/app/src/mainmenu/mainmenu.html b/@salix/app/src/mainmenu/mainmenu.html
deleted file mode 100644
index 81797d6e1b..0000000000
--- a/@salix/app/src/mainmenu/mainmenu.html
+++ /dev/null
@@ -1 +0,0 @@
-<!-- por definir -->
\ No newline at end of file
diff --git a/@salix/app/src/mainmenu/mainmenu.js b/@salix/app/src/mainmenu/mainmenu.js
deleted file mode 100644
index cc2a526d3a..0000000000
--- a/@salix/app/src/mainmenu/mainmenu.js
+++ /dev/null
@@ -1,8 +0,0 @@
-import template from './{name}.html';
-import {module} from '../../module';
-
-export const NAME = '';
-export const COMPONENT = {
-    template: template
-};
-module.component(NAME, COMPONENT);
diff --git a/@salix/client/.gitignore b/@salix/client/.gitignore
new file mode 100644
index 0000000000..b512c09d47
--- /dev/null
+++ b/@salix/client/.gitignore
@@ -0,0 +1 @@
+node_modules
\ No newline at end of file
diff --git a/@salix/client/index.js b/@salix/client/index.js
new file mode 100644
index 0000000000..8c2e02b728
--- /dev/null
+++ b/@salix/client/index.js
@@ -0,0 +1 @@
+export * from './src/client';
\ No newline at end of file
diff --git a/@salix/client/package.json b/@salix/client/package.json
new file mode 100644
index 0000000000..485d4f8dce
--- /dev/null
+++ b/@salix/client/package.json
@@ -0,0 +1,17 @@
+{
+  "name": "@salix/client",
+  "version": "1.0.0",
+  "description": "",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "repository": {
+    "type": "git",
+    "url": "ssh://repository@git.verdnatura.es:/var/lib/git/salix-client"
+  },
+  "author": "",
+  "license": "ISC",
+  "dependencies": {
+  }
+}
diff --git a/@salix/client/src/client.js b/@salix/client/src/client.js
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/@salix/client/src/leftmenu/actions.html b/@salix/client/src/leftmenu/actions.html
new file mode 100644
index 0000000000..d029f8b17c
--- /dev/null
+++ b/@salix/client/src/leftmenu/actions.html
@@ -0,0 +1,7 @@
+<vn-horizontal>
+    <ul>
+        <li>Datos fiscales y facturaciĆ³n</li>
+        <li>Consignatarios</li>
+        <li>Acceso web</li>
+    </ul>
+</vn-horizontal>
diff --git a/@salix/client/src/leftmenu/actions.js b/@salix/client/src/leftmenu/actions.js
new file mode 100644
index 0000000000..c1215fee30
--- /dev/null
+++ b/@salix/client/src/leftmenu/actions.js
@@ -0,0 +1,9 @@
+import template from './actions.html';
+import {module} from '../module';
+
+const _NAME = 'actions';
+export const NAME = module.core.util.getName(_NAME);
+export const COMPONENT = {
+    template: template
+};
+module.component(NAME, COMPONENT);
diff --git a/@salix/client/src/leftmenu/descriptor.html b/@salix/client/src/leftmenu/descriptor.html
new file mode 100644
index 0000000000..34d2702cfd
--- /dev/null
+++ b/@salix/client/src/leftmenu/descriptor.html
@@ -0,0 +1,3 @@
+<vn-horizontal>
+    descriptor
+</vn-horizontal>
\ No newline at end of file
diff --git a/@salix/client/src/leftmenu/descriptor.js b/@salix/client/src/leftmenu/descriptor.js
new file mode 100644
index 0000000000..96fe948b3f
--- /dev/null
+++ b/@salix/client/src/leftmenu/descriptor.js
@@ -0,0 +1,9 @@
+import template from './descriptor.html';
+import {module} from '../module';
+
+const _NAME = 'descriptor';
+export const NAME = module.core.util.getName(_NAME);
+export const COMPONENT = {
+    template: template
+};
+module.component(NAME, COMPONENT);
diff --git a/@salix/client/src/leftmenu/leftmenu.html b/@salix/client/src/leftmenu/leftmenu.html
new file mode 100644
index 0000000000..1e6fc14a70
--- /dev/null
+++ b/@salix/client/src/leftmenu/leftmenu.html
@@ -0,0 +1,4 @@
+<vn-vertical>
+    <vn-descriptor></vn-descriptor>
+    <vn-actions></vn-actions>
+</vn-vertical>
\ No newline at end of file
diff --git a/@salix/client/src/leftmenu/leftmenu.js b/@salix/client/src/leftmenu/leftmenu.js
new file mode 100644
index 0000000000..6901b25976
--- /dev/null
+++ b/@salix/client/src/leftmenu/leftmenu.js
@@ -0,0 +1,9 @@
+import template from './leftmenu.html';
+import {module} from '../module';
+
+const _NAME = 'leftmenu';
+export const NAME = module.core.util.getName(_NAME);
+export const COMPONENT = {
+    template: template
+};
+module.component(NAME, COMPONENT);
diff --git a/@salix/client/src/module.js b/@salix/client/src/module.js
new file mode 100644
index 0000000000..51815597bf
--- /dev/null
+++ b/@salix/client/src/module.js
@@ -0,0 +1,6 @@
+import {ng} from '@salix/vendor';
+import * as core from 'core';
+
+const DEPENDENCIES = [];
+export const NAME = core.util.getModuleName('client');
+export const  module = ng.module(NAME,DEPENDENCIES);
\ No newline at end of file
diff --git a/@salix/client/src/topbar/topbar.html b/@salix/client/src/topbar/topbar.html
new file mode 100644
index 0000000000..a18f9fae1e
--- /dev/null
+++ b/@salix/client/src/topbar/topbar.html
@@ -0,0 +1,6 @@
+<vn-horizonal>
+    <vn-one>
+        <vn-label text="Client"></vn-label>
+        <vn-searchbar></vn-searchbar>
+    </vn-one>
+</vn-horizonal>
\ No newline at end of file
diff --git a/@salix/client/src/topbar/topbar.js b/@salix/client/src/topbar/topbar.js
new file mode 100644
index 0000000000..bad3d73855
--- /dev/null
+++ b/@salix/client/src/topbar/topbar.js
@@ -0,0 +1,9 @@
+import template from './topbar.html';
+import {module} from '../module';
+
+const _NAME = 'topbar';
+export const NAME = module.core.util.getName(_NAME);
+export const COMPONENT = {
+    template: template
+};
+module.component(NAME, COMPONENT);
diff --git a/@salix/core/src/core.js b/@salix/core/src/core.js
index 056068caa7..c17b014810 100644
--- a/@salix/core/src/core.js
+++ b/@salix/core/src/core.js
@@ -37,3 +37,6 @@ export {NAME as SNACKBARMT,factory as snackbarmt} from './snackbar/snackbar.mt'
 export {NAME as SPINNER,directive as SpinnerDirective} from './spinner/spinner'
 export {NAME as SPINNERMT,factory as spinnermt} from './spinner/spinner.mt'
 
+export {NAME as VN_MAINMENU,
+	COMPONENT as VN_MAINMENU_COMPONENT} from './mainmenu/mainmenu';
+
diff --git a/@salix/core/src/mainmenu/mainmenu.html b/@salix/core/src/mainmenu/mainmenu.html
new file mode 100644
index 0000000000..eb08fac4d6
--- /dev/null
+++ b/@salix/core/src/mainmenu/mainmenu.html
@@ -0,0 +1,5 @@
+<div style="position:fixed; top:0; right:0; height:6em; width:10em; background-color:red;">
+    <i class="material-icons">apps</i>
+    <i class="material-icons">notification</i>
+    <i class="material-icons">account_circle</i>
+</div>
\ No newline at end of file
diff --git a/@salix/core/src/mainmenu/mainmenu.js b/@salix/core/src/mainmenu/mainmenu.js
new file mode 100644
index 0000000000..50d6c07559
--- /dev/null
+++ b/@salix/core/src/mainmenu/mainmenu.js
@@ -0,0 +1,10 @@
+import template from './mainmenu.html';
+import {module} from '../module';
+import * as util from '../util';
+
+const _NAME = 'mainmenu';
+export const NAME = util.getName(_NAME);
+export const COMPONENT = {
+    template: template
+};
+module.component(NAME, COMPONENT);
diff --git a/@salix/vendor/src/vendor.js b/@salix/vendor/src/vendor.js
index 364b9c1bd6..e8601c647a 100644
--- a/@salix/vendor/src/vendor.js
+++ b/@salix/vendor/src/vendor.js
@@ -2,3 +2,5 @@ export * from './angular-vendor';
 export * from './oclazyload-vendor';
 export * from './uirouter-vendor';
 export * from './materialdesignlite-vendor';
+
+export * from './materialDesignIcons-vendor';
\ No newline at end of file