Repository: incubator-ignite
Updated Branches:
  refs/heads/ignite-843 6f91bb827 -> 36063e133


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/routes/generator/xml.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/routes/generator/xml.js 
b/modules/web-control-center/nodejs/routes/generator/xml.js
new file mode 100644
index 0000000..500a7e7
--- /dev/null
+++ b/modules/web-control-center/nodejs/routes/generator/xml.js
@@ -0,0 +1,559 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var _ = require('lodash');
+
+var generatorUtils = require("./common");
+var dataStructures = require("../../helpers/data-structures.js");
+
+exports.generateClusterConfiguration = function(cluster) {
+    var res = generatorUtils.builder();
+
+    res.datasources = [];
+    res.deep = 1;
+
+    // Generate Ignite Configuration.
+    res.startBlock('<bean 
class="org.apache.ignite.configuration.IgniteConfiguration">');
+
+    // Generate discovery.
+    if (cluster.discovery) {
+        res.startBlock('<property name="discoverySpi">');
+        res.startBlock('<bean 
class="org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi">');
+        res.startBlock('<property name="ipFinder">');
+
+        var d = cluster.discovery;
+
+        switch (d.kind) {
+            case 'Multicast':
+                res.startBlock('<bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder">');
+
+                addProperty(res, d.Multicast, 'multicastGroup');
+                addProperty(res, d.Multicast, 'multicastPort');
+                addProperty(res, d.Multicast, 'responseWaitTime');
+                addProperty(res, d.Multicast, 'addressRequestAttempts');
+                addProperty(res, d.Multicast, 'localAddress');
+
+                res.endBlock('</bean>');
+
+                break;
+
+            case 'Vm':
+                if (d.Vm.addresses.length > 0) {
+                    res.startBlock('<bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder">');
+
+                    addListProperty(res, d.Vm, 'addresses');
+
+                    res.endBlock('</bean>');
+                }
+                else {
+                    res.line('<bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder"/>');
+                }
+
+                break;
+
+            case 'S3':
+                res.startBlock('<bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.s3.TcpDiscoveryS3IpFinder">');
+
+                if (d.S3 && d.S3.bucketName)
+                    res.line('<property name="bucketName" value="' + 
escapeAttr(d.S3.bucketName) + '" />');
+
+                res.endBlock('</bean>');
+
+                break;
+
+            case 'Cloud':
+                res.startBlock('<bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.cloud.TcpDiscoveryCloudIpFinder">');
+
+                addProperty(res, d.Cloud, 'credential');
+                addProperty(res, d.Cloud, 'credentialPath');
+                addProperty(res, d.Cloud, 'identity');
+                addProperty(res, d.Cloud, 'provider');
+                addListProperty(res, d.Cloud, 'regions');
+                addListProperty(res, d.Cloud, 'zones');
+
+                res.endBlock('</bean>');
+
+                break;
+
+            case 'GoogleStorage':
+                res.startBlock('<bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.gce.TcpDiscoveryGoogleStorageIpFinder">');
+
+                addProperty(res, d.GoogleStorage, 'projectName');
+                addProperty(res, d.GoogleStorage, 'bucketName');
+                addProperty(res, d.GoogleStorage, 'serviceAccountP12FilePath');
+
+                //if (d.GoogleStorage.addrReqAttempts) todo ????
+                //    res.line('<property name="serviceAccountP12FilePath" 
value="' + escapeAttr(d.GoogleStorage.addrReqAttempts) + '"/>');
+
+                res.endBlock('</bean>');
+
+                break;
+
+            case 'Jdbc':
+                res.startBlock('<bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.jdbc.TcpDiscoveryJdbcIpFinder">');
+                res.line('<property name="initSchema" value="' + 
(d.Jdbc.initSchema != null || d.Jdbc.initSchema) + '"/>');
+                res.endBlock('</bean>');
+
+                break;
+
+            case 'SharedFs':
+                if (d.SharedFs.path) {
+                    res.startBlock('<bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.sharedfs.TcpDiscoverySharedFsIpFinder">');
+                    addProperty(res, d.SharedFs, 'path');
+                    res.endBlock('</bean>');
+                }
+                else {
+                    res.line('<bean 
class="org.apache.ignite.spi.discovery.tcp.ipfinder.sharedfs.TcpDiscoverySharedFsIpFinder"/>');
+                }
+
+                break;
+
+            default:
+                throw "Unknown discovery kind: " + d.kind;
+        }
+
+        res.endBlock('</property>');
+        res.endBlock('</bean>');
+        res.endBlock('</property>');
+
+        res.needEmptyLine = true
+    }
+
+    // Generate atomics group.
+    addBeanWithProperties(res, cluster.atomicConfiguration, 
'atomicConfiguration',
+        generatorUtils.atomicConfiguration.className, 
generatorUtils.atomicConfiguration.fields);
+    res.needEmptyLine = true;
+
+    // Generate communication group.
+    addProperty(res, cluster, 'networkTimeout');
+    addProperty(res, cluster, 'networkSendRetryDelay');
+    addProperty(res, cluster, 'networkSendRetryCount');
+    addProperty(res, cluster, 'segmentCheckFrequency');
+    addProperty(res, cluster, 'waitForSegmentOnStart');
+    addProperty(res, cluster, 'discoveryStartupDelay');
+    res.needEmptyLine = true;
+
+    // Generate deployment group.
+    addProperty(res, cluster, 'deploymentMode');
+    res.needEmptyLine = true;
+
+    // Generate events group.
+    if (cluster.includeEventTypes && cluster.includeEventTypes.length > 0) {
+        res.emptyLineIfNeeded();
+        
+        res.startBlock('<property name="includeEventTypes">');
+        
+        if (cluster.includeEventTypes.length == 1) {
+            res.line('<util:constant 
static-field="org.apache.ignite.events.EventType.' + 
cluster.includeEventTypes[0] + '"/>')
+        }
+        else {
+            res.startBlock('<array>');
+
+            for (i = 0; i < cluster.includeEventTypes.length; i++) {
+                if (i > 0)
+                    res.line();
+
+                var eventGroup = cluster.includeEventTypes[i];
+
+                res.line('<!-- EventType.' + eventGroup + ' -->');
+
+                var eventList = dataStructures.eventGroups[eventGroup];
+
+                for (var k = 0; k < eventList.length; k++) {
+                    res.line('<util:constant 
static-field="org.apache.ignite.events.EventType.' + eventList[k] + '"/>')
+                }
+            }
+
+            res.endBlock('</array>');
+        }
+        
+        res.endBlock('</property>');
+
+        res.needEmptyLine = true;
+    }
+
+    // Generate marshaller group.
+    addProperty(res, cluster, 'marshalLocalJobs');
+    addProperty(res, cluster, 'marshCacheKeepAliveTime');
+    addProperty(res, cluster, 'marshCachePoolSize');
+    res.needEmptyLine = true;
+
+    // Generate metrics group.
+    addProperty(res, cluster, 'metricsExpireTime');
+    addProperty(res, cluster, 'metricsHistorySize');
+    addProperty(res, cluster, 'metricsLogFrequency');
+    addProperty(res, cluster, 'metricsUpdateFrequency');
+    res.needEmptyLine = true;
+
+    // Generate PeerClassLoading group.
+    addProperty(res, cluster, 'peerClassLoadingEnabled');
+    addListProperty(res, cluster, 'peerClassLoadingLocalClassPathExclude');
+    addProperty(res, cluster, 'peerClassLoadingMissedResourcesCacheSize');
+    addProperty(res, cluster, 'peerClassLoadingThreadPoolSize');
+    res.needEmptyLine = true;
+
+    // Generate swap group.
+    if (cluster.swapSpaceSpi && cluster.swapSpaceSpi.kind == 
'FileSwapSpaceSpi') {
+        addBeanWithProperties(res, cluster.swapSpaceSpi.FileSwapSpaceSpi, 
'swapSpaceSpi',
+            generatorUtils.swapSpaceSpi.className, 
generatorUtils.swapSpaceSpi.fields, true);
+
+        res.needEmptyLine = true;
+    }
+
+    // Generate time group.
+    addProperty(res, cluster, 'clockSyncSamples');
+    addProperty(res, cluster, 'clockSyncFrequency');
+    addProperty(res, cluster, 'timeServerPortBase');
+    addProperty(res, cluster, 'timeServerPortRange');
+    res.needEmptyLine = true;
+
+    // Generate thread pools group.
+    addProperty(res, cluster, 'publicThreadPoolSize');
+    addProperty(res, cluster, 'systemThreadPoolSize');
+    addProperty(res, cluster, 'managementThreadPoolSize');
+    addProperty(res, cluster, 'igfsThreadPoolSize');
+    res.needEmptyLine = true;
+
+    // Generate transactions group.
+    addBeanWithProperties(res, cluster.transactionConfiguration, 
'transactionConfiguration',
+        generatorUtils.transactionConfiguration.className, 
generatorUtils.transactionConfiguration.fields);
+    res.needEmptyLine = true;
+
+    // Generate utility group.
+    addProperty(res, cluster, 'utilityCacheKeepAliveTime');
+    addProperty(res, cluster, 'utilityCachePoolSize');
+
+    // Generate caches configs.
+    if (cluster.caches && cluster.caches.length > 0) {
+        res.emptyLineIfNeeded();
+
+        res.startBlock('<property name="cacheConfiguration">');
+        res.startBlock('<list>');
+
+        for (var i = 0; i < cluster.caches.length; i++) {
+            if (i > 0)
+                res.line();
+
+            generateCacheConfiguration(cluster.caches[i], res);
+        }
+
+        res.endBlock('</list>');
+        res.endBlock('</property>');
+
+        res.needEmptyLine = true;
+    }
+
+    res.endBlock('</bean>');
+
+    // Build final XML:
+    // 1. Add header.
+    var xml = '<?xml version="1.0" encoding="UTF-8"?>\n\n';
+
+    xml += '<!-- ' + generatorUtils.mainComment() + ' -->\n';
+    xml += '<beans xmlns="http://www.springframework.org/schema/beans"\n';
+    xml += '       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n';
+    xml += '       xmlns:util="http://www.springframework.org/schema/util"\n';
+    xml += '       
xsi:schemaLocation="http://www.springframework.org/schema/beans\n';
+    xml += '                           
http://www.springframework.org/schema/beans/spring-beans.xsd\n';
+    xml += '                           
http://www.springframework.org/schema/util\n';
+    xml += '                           
http://www.springframework.org/schema/util/spring-util.xsd";>\n';
+
+    // 2. Add external property file and all data sources.
+    if (res.datasources.length > 0) {
+        xml += '    <!-- Load external properties file. -->\n';
+        xml += '    <bean id="placeholderConfig" 
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">\n';
+        xml += '        <property name="location" 
value="classpath:ignite.properties"/>\n';
+        xml += '    </bean>\n\n';
+
+        xml += '    <!-- Data source beans will be initialized from external 
properties file. -->\n';
+
+        _.forEach(res.datasources, function(item) {
+            var beanId = item.dataSourceBean;
+
+            xml += '    <bean id= "' + beanId + '" class="' + item.className + 
'">\n';
+            xml += '        <property name="URL" value="${' + beanId + 
'.jdbc.url}" />\n';
+            xml += '        <property name="user" value="${' + beanId + 
'.jdbc.username}" />\n';
+            xml += '        <property name="password" value="${' + beanId + 
'.jdbc.password}" />\n';
+            xml += '    </bean>\n\n';
+        });
+    }
+
+    // 3. Add main content.
+    xml += res.join('');
+
+    // 4. Add footer.
+    xml += '</beans>\n';
+
+    return xml;
+};
+
+function createEvictionPolicy(res, evictionPolicy, propertyName) {
+    if (evictionPolicy && evictionPolicy.kind) {
+        var e = generatorUtils.evictionPolicies[evictionPolicy.kind];
+
+        var obj = evictionPolicy[evictionPolicy.kind.toUpperCase()];
+
+        addBeanWithProperties(res, obj, propertyName, e.className, e.fields, 
true);
+    }
+}
+
+function generateCacheConfiguration(cacheCfg, res) {
+    if (!res)
+        res = generatorUtils.builder();
+
+    res.startBlock('<bean 
class="org.apache.ignite.configuration.CacheConfiguration">');
+
+    addProperty(res, cacheCfg, 'name');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'mode', 'cacheMode');
+
+    addProperty(res, cacheCfg, 'atomicityMode');
+    addProperty(res, cacheCfg, 'backups');
+    addProperty(res, cacheCfg, 'startSize');
+    addProperty(res, cacheCfg, 'readFromBackup');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'memoryMode');
+    addProperty(res, cacheCfg, 'offHeapMaxMemory');
+    addProperty(res, cacheCfg, 'swapEnabled');
+    addProperty(res, cacheCfg, 'copyOnRead');
+
+    res.needEmptyLine = true;
+
+    createEvictionPolicy(res, cacheCfg.evictionPolicy, 'evictionPolicy');
+
+    res.needEmptyLine = true;
+
+    if (cacheCfg.nearCacheEnabled) {
+        res.emptyLineIfNeeded();
+
+        res.startBlock('<property name="nearConfiguration">');
+        res.startBlock('<bean 
class="org.apache.ignite.configuration.NearCacheConfiguration">');
+
+        if (cacheCfg.nearConfiguration && 
cacheCfg.nearConfiguration.nearStartSize)
+            addProperty(res, cacheCfg.nearConfiguration, 'nearStartSize');
+
+        if (cacheCfg.nearConfiguration && 
cacheCfg.nearConfiguration.nearEvictionPolicy.kind)
+            createEvictionPolicy(res, 
cacheCfg.nearConfiguration.nearEvictionPolicy, 'nearEvictionPolicy');
+
+        res.endBlock('</bean>');
+        res.endBlock('</property>');
+    }
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'sqlEscapeAll');
+    addProperty(res, cacheCfg, 'sqlOnheapRowCacheSize');
+    addProperty(res, cacheCfg, 'longQueryWarningTimeout');
+
+    if (cacheCfg.indexedTypes && cacheCfg.indexedTypes.length > 0) {
+        res.startBlock('<property name="indexedTypes">');
+        res.startBlock('<array>');
+
+        for (var i = 0; i < cacheCfg.indexedTypes.length; i++) {
+            var pair = cacheCfg.indexedTypes[i];
+
+            res.line('<value>' + escape(pair.keyClass) + '</value>');
+            res.line('<value>' + escape(pair.valueClass) + '</value>');
+        }
+
+        res.endBlock('</array>');
+        res.endBlock('</property>');
+    }
+
+    addListProperty(res, cacheCfg, 'sqlFunctionClasses', 'array');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'rebalanceMode');
+    addProperty(res, cacheCfg, 'rebalanceThreadPoolSize');
+    addProperty(res, cacheCfg, 'rebalanceBatchSize');
+    addProperty(res, cacheCfg, 'rebalanceOrder');
+    addProperty(res, cacheCfg, 'rebalanceDelay');
+    addProperty(res, cacheCfg, 'rebalanceTimeout');
+    addProperty(res, cacheCfg, 'rebalanceThrottle');
+
+    res.needEmptyLine = true;
+
+    if (cacheCfg.cacheStoreFactory && cacheCfg.cacheStoreFactory.kind) {
+        var storeFactory = 
cacheCfg.cacheStoreFactory[cacheCfg.cacheStoreFactory.kind];
+        var data = 
generatorUtils.storeFactories[cacheCfg.cacheStoreFactory.kind];
+
+        addBeanWithProperties(res, storeFactory, 'cacheStoreFactory', 
data.className, data.fields, true);
+
+        if (storeFactory.dialect) {
+            if (_.findIndex(res.datasources, function (ds) {
+                    return ds.dataSourceBean == storeFactory.dataSourceBean;
+                }) < 0) {
+                res.datasources.push({
+                    dataSourceBean: storeFactory.dataSourceBean,
+                    className: generatorUtils.dataSources[storeFactory.dialect]
+                });
+            }
+        }
+    }
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'loadPreviousValue');
+    addProperty(res, cacheCfg, 'readThrough');
+    addProperty(res, cacheCfg, 'writeThrough');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'invalidate');
+    addProperty(res, cacheCfg, 'defaultLockTimeout');
+    addProperty(res, cacheCfg, 'transactionManagerLookupClassName');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'writeBehindEnabled');
+    addProperty(res, cacheCfg, 'writeBehindBatchSize');
+    addProperty(res, cacheCfg, 'writeBehindFlushSize');
+    addProperty(res, cacheCfg, 'writeBehindFlushFrequency');
+    addProperty(res, cacheCfg, 'writeBehindFlushThreadCount');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'statisticsEnabled');
+    addProperty(res, cacheCfg, 'managementEnabled');
+
+    res.needEmptyLine = true;
+
+    addProperty(res, cacheCfg, 'maxConcurrentAsyncOperations');
+    
+    res.endBlock('</bean>');
+
+    return res;
+}
+
+exports.generateCacheConfiguration = generateCacheConfiguration;
+
+function addProperty(res, obj, propName, setterName) {
+    var val = obj[propName];
+
+    if (val) {
+        res.emptyLineIfNeeded();
+
+        res.line('<property name="' + (setterName ? setterName : propName) + 
'" value="' + escapeAttr(val) + '"/>');
+    }
+}
+
+function addBeanWithProperties(res, bean, beanPropName, beanClass, props, 
createBeanAlthoughNoProps) {
+    if (!bean)
+        return;
+
+    if (generatorUtils.hasProperty(bean, props)) {
+        res.emptyLineIfNeeded();
+        res.startBlock('<property name="' + beanPropName + '">');
+        res.startBlock('<bean class="' + beanClass + '">');
+
+        for (var propName in props) {
+            if (props.hasOwnProperty(propName)) {
+                var descr = props[propName];
+
+                if (descr) {
+                    if (descr.type == 'list') {
+                        addListProperty(res, bean, propName, descr.setterName);
+                    }
+                    else if (descr.type == 'className') {
+                        if (bean[propName]) {
+                            res.startBlock('<property name="' + propName + 
'">');
+                            res.line('<bean class="' + 
generatorUtils.knownClasses[bean[propName]].className + '"/>');
+                            res.endBlock('</property>');
+                        }
+                    }
+                    else if (descr.type == 'propertiesAsList') {
+                        var val = bean[propName];
+
+                        if (val && val.length > 0) {
+                            res.startBlock('<property name="' + propName + 
'">');
+                            res.startBlock('<props>');
+
+                            for (var i = 0; i < val.length; i++) {
+                                var nameAndValue = val[i];
+
+                                var eqIndex = nameAndValue.indexOf('=');
+                                if (eqIndex >= 0) {
+                                    res.line('<prop key="' + 
escapeAttr(nameAndValue.substring(0, eqIndex)) + '">' +
+                                            + 
escape(nameAndValue.substr(eqIndex + 1)) + '</prop>');
+                                }
+                            }
+
+                            res.endBlock('</props>');
+                            res.endBlock('</property>');
+                        }
+                    }
+                    else {
+                        addProperty(res, bean, propName, descr.setterName);
+                    }
+                }
+                else {
+                    addProperty(res, bean, propName);
+                }
+            }
+        }
+
+        res.endBlock('</bean>');
+        res.endBlock('</property>');
+    }
+    else if (createBeanAlthoughNoProps) {
+        res.emptyLineIfNeeded();
+        res.line('<property name="' + beanPropName + '">');
+        res.line('    <bean class="' + beanClass + '"/>');
+        res.line('</property>');
+    }
+}
+function addListProperty(res, obj, propName, listType, rowFactory) {
+    var val = obj[propName];
+
+    if (val && val.length > 0) {
+        res.emptyLineIfNeeded();
+
+        if (!listType)
+            listType = 'list';
+
+        if (!rowFactory)
+            rowFactory = function(val) { return '<value>' + escape(val) + 
'</value>' };
+
+        res.startBlock('<property name="' + propName + '">');
+        res.startBlock('<' + listType + '>');
+
+        for (var i = 0; i < val.length; i++)
+            res.line(rowFactory(val[i]));
+
+        res.endBlock('</' + listType + '>');
+        res.endBlock('</property>');
+    }
+}
+
+function escapeAttr(s) {
+    if (typeof(s) != 'string')
+        return s;
+
+    return s.replace(/&/g, '&amp;').replace(/"/g, '&quot;');
+}
+
+function escape(s) {
+    if (typeof(s) != 'string')
+        return s;
+
+    return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, 
'&gt;');
+}

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/routes/persistences.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/routes/persistences.js 
b/modules/web-control-center/nodejs/routes/persistences.js
index a3bb1d2..1f0fc24 100644
--- a/modules/web-control-center/nodejs/routes/persistences.js
+++ b/modules/web-control-center/nodejs/routes/persistences.js
@@ -17,7 +17,7 @@
 
 var router = require('express').Router();
 var db = require('../db');
-var ds = require('../public/javascripts/dataStructures.js'), jdbcTypes = 
ds.jdbcTypes, javaTypes = ds.javaTypes;
+var ds = require('../helpers/data-structures.js'), jdbcTypes = ds.jdbcTypes, 
javaTypes = ds.javaTypes;
 
 /* GET persistence page. */
 router.get('/', function(req, res) {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/routes/profile.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/routes/profile.js 
b/modules/web-control-center/nodejs/routes/profile.js
index f9ba260..d19394b 100644
--- a/modules/web-control-center/nodejs/routes/profile.js
+++ b/modules/web-control-center/nodejs/routes/profile.js
@@ -17,7 +17,7 @@
 
 var router = require('express').Router();
 var db = require('../db');
-var uiUtils = require('../utils/ui-utils');
+var uiUtils = require('../helpers/ui-utils');
 
 /**
  * Get list of user accounts.

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/routes/summary.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/routes/summary.js 
b/modules/web-control-center/nodejs/routes/summary.js
index 7c3f9de..71c9489 100644
--- a/modules/web-control-center/nodejs/routes/summary.js
+++ b/modules/web-control-center/nodejs/routes/summary.js
@@ -19,8 +19,8 @@ var db = require('../db');
 
 var router = require('express').Router();
 
-var generatorXml = require('./../generator/xml');
-var generatorJava = require('./../generator/java');
+var generatorXml = require('./generator/xml');
+var generatorJava = require('./generator/java');
 
 /* GET summary page. */
 router.get('/', function(req, res) {

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/test/routes/persistence.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/test/routes/persistence.js 
b/modules/web-control-center/nodejs/test/routes/persistence.js
deleted file mode 100644
index e5d8390..0000000
--- a/modules/web-control-center/nodejs/test/routes/persistence.js
+++ /dev/null
@@ -1,32 +0,0 @@
-var request = require('supertest'),
-    should = require('should'),
-    express = require('express'),
-    persistenceRouter = require('../../routes/persistences');
-
-var app = express();
-
-app.use(require('body-parser').json());
-
-app.use('/rest/persistence', persistenceRouter);
-
-describe('request.persistence', function(){
-    var agent = request.agent(app);
-
-    it('should return 200', function(done){
-        agent
-            .post('/rest/persistence/pg')
-            .send({
-                    username: 'nva',
-                    password: 'nva.141',
-                    host: 'localhost',
-                    port: '5432',
-                    dbName: 'ggmonitor'
-                })
-            .end(function(err, res) {
-                if (err)
-                    throw err;
-
-                done();
-            });
-    });
-});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/tests/routes/persistence.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/tests/routes/persistence.js 
b/modules/web-control-center/nodejs/tests/routes/persistence.js
new file mode 100644
index 0000000..e5d8390
--- /dev/null
+++ b/modules/web-control-center/nodejs/tests/routes/persistence.js
@@ -0,0 +1,32 @@
+var request = require('supertest'),
+    should = require('should'),
+    express = require('express'),
+    persistenceRouter = require('../../routes/persistences');
+
+var app = express();
+
+app.use(require('body-parser').json());
+
+app.use('/rest/persistence', persistenceRouter);
+
+describe('request.persistence', function(){
+    var agent = request.agent(app);
+
+    it('should return 200', function(done){
+        agent
+            .post('/rest/persistence/pg')
+            .send({
+                    username: 'nva',
+                    password: 'nva.141',
+                    host: 'localhost',
+                    port: '5432',
+                    dbName: 'ggmonitor'
+                })
+            .end(function(err, res) {
+                if (err)
+                    throw err;
+
+                done();
+            });
+    });
+});
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/utils/ui-utils.js
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/utils/ui-utils.js 
b/modules/web-control-center/nodejs/utils/ui-utils.js
deleted file mode 100644
index e9e680b..0000000
--- a/modules/web-control-center/nodejs/utils/ui-utils.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-exports.filterUser = function (user) {
-    if (!user)
-        return null;
-
-    return {
-        _id: user._id,
-        username: user.username,
-        lastLogin: user.lastLogin,
-        admin: user.admin,
-        email: user.email
-    }
-};
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/admin/index.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/admin/index.jade 
b/modules/web-control-center/nodejs/views/admin/index.jade
new file mode 100644
index 0000000..f667976
--- /dev/null
+++ b/modules/web-control-center/nodejs/views/admin/index.jade
@@ -0,0 +1,21 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+         http://www.apache.org/licenses/LICENSE-2.0
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+extends ../templates/layout
+
+append scripts
+    script(src='/admin-controller.js')
+    
script(src='//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/js/bootstrap.min.js')
+
+block container
+    include userList_content.html

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/admin/userList.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/admin/userList.jade 
b/modules/web-control-center/nodejs/views/admin/userList.jade
deleted file mode 100644
index af2dbd4..0000000
--- a/modules/web-control-center/nodejs/views/admin/userList.jade
+++ /dev/null
@@ -1,21 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-         http://www.apache.org/licenses/LICENSE-2.0
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-extends ../layout
-
-append scripts
-    script(src='/javascripts/controllers/adminController.js')
-    
script(src='//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/js/bootstrap.min.js')
-
-block container
-    include userList_content.html

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/caches.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/caches.jade 
b/modules/web-control-center/nodejs/views/caches.jade
index 9fc8957..9ffcb29 100644
--- a/modules/web-control-center/nodejs/views/caches.jade
+++ b/modules/web-control-center/nodejs/views/caches.jade
@@ -14,10 +14,10 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-extends layout-sidebar
+extends templates/layout-sidebar
 
 append scripts
-    script(src='/javascripts/controllers/caches.js')
+    script(src='/caches-controller.js')
 
 include includes/controls
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/clients.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/clients.jade 
b/modules/web-control-center/nodejs/views/clients.jade
index 6b55449..87cfc10 100644
--- a/modules/web-control-center/nodejs/views/clients.jade
+++ b/modules/web-control-center/nodejs/views/clients.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-extends layout-sidebar
+extends templates/layout-sidebar
 block head
 block content
     .docs-header
@@ -23,4 +23,4 @@ block content
         hr
     .docs-body(ng-controller='clientsRouter')
 block body
-    script(src='/javascripts/controllers/clients.js')
\ No newline at end of file
+    script(src='/clients.js')
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/clusters.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/clusters.jade 
b/modules/web-control-center/nodejs/views/clusters.jade
index c654b4a..a6f5ab8 100644
--- a/modules/web-control-center/nodejs/views/clusters.jade
+++ b/modules/web-control-center/nodejs/views/clusters.jade
@@ -14,10 +14,10 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-extends layout-sidebar
+extends templates/layout-sidebar
 
 append scripts
-    script(src='/javascripts/controllers/clusters.js')
+    script(src='/clusters-controller.js')
 
 include includes/controls
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/error.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/error.jade 
b/modules/web-control-center/nodejs/views/error.jade
index cfa2ad1..b458fb7 100644
--- a/modules/web-control-center/nodejs/views/error.jade
+++ b/modules/web-control-center/nodejs/views/error.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-extends layout
+extends templates/layout
 
 block container
   h1= message

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/includes/header.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/includes/header.jade 
b/modules/web-control-center/nodejs/views/includes/header.jade
index b09525e..1be7acc 100644
--- a/modules/web-control-center/nodejs/views/includes/header.jade
+++ b/modules/web-control-center/nodejs/views/includes/header.jade
@@ -23,7 +23,7 @@ header.header(id='header')
                 li
                     a(ng-class="{active: isActive('/configuration')}" 
href='/configuration/clusters') Configuration
                 li(ng-if='loggedInUser && loggedInUser.admin')
-                    a(ng-class="{active: isActive('/admin')}" 
href='/admin/userList') Administration
+                    a(ng-class="{active: isActive('/admin')}" href='/admin') 
Administration
                 //li
                 //    a(ng-class="{active: isActive('/sql')}" href='/sql') SQL
             ul.nav.navbar-nav.pull-right

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/index.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/index.jade 
b/modules/web-control-center/nodejs/views/index.jade
index b913fb0..55fe816 100644
--- a/modules/web-control-center/nodejs/views/index.jade
+++ b/modules/web-control-center/nodejs/views/index.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-extends layout
+extends templates/layout
 block container
     .row
         .docs-content

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/layout-sidebar.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/layout-sidebar.jade 
b/modules/web-control-center/nodejs/views/layout-sidebar.jade
deleted file mode 100644
index 36c778b..0000000
--- a/modules/web-control-center/nodejs/views/layout-sidebar.jade
+++ /dev/null
@@ -1,37 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-extends layout
-
-block container
-    .row
-        .col-sm-2.border-right.section-left.greedy
-            .sidebar-nav
-                ul.menu(ng-controller='activeLink')
-                    li
-                        a(ng-class="{active: 
isActive('/configuration/clusters')}" href='/configuration/clusters') Clusters
-                    li
-                        a(ng-class="{active: 
isActive('/configuration/caches')}" href='/configuration/caches') Caches
-                    //li
-                    //    a(ng-class="{active: isActive('/persistence')}" 
href='/persistence') Persistence
-                    //li
-                    //    a(ng-class="{active: isActive('/clients')}" 
href='/clients') Clients
-                    li
-                        p
-                        a(ng-class="{active: 
isActive('/configuration/summary')}" href='/configuration/summary') Summary
-        .col-sm-10.border-left.section-right
-            .docs-content
-                block content
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/layout.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/layout.jade 
b/modules/web-control-center/nodejs/views/layout.jade
deleted file mode 100644
index 86d2bc7..0000000
--- a/modules/web-control-center/nodejs/views/layout.jade
+++ /dev/null
@@ -1,59 +0,0 @@
-//-
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-
-doctype html
-html(ng-app='ignite-web-control-center', ng-init='loggedInUser = 
#{JSON.stringify(filterUser(user))}; viewedUser = 
#{JSON.stringify(viewedUser)}')
-    head
-        title= title
-
-        block css
-            // Bootstrap
-            link(rel='stylesheet', 
href='//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.css')
-
-            // Font Awesome Icons
-            link(rel='stylesheet', 
href='//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.css')
-
-            // Font
-            link(rel='stylesheet', 
href='//fonts.googleapis.com/css?family=Roboto+Slab:700:serif|Roboto+Slab:400:serif')
-
-            link(rel='stylesheet', href='/stylesheets/style.css')
-
-        block scripts
-            
script(src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js')
-
-            
script(src='//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js')
-
-            
script(src='//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js')
-            
script(src='//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-sanitize.js')
-            
script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.2.2/angular-strap.js')
-            
script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.2.2/angular-strap.tpl.min.js')
-
-            
script(src='https://cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.0.3/smart-table.js')
-
-            script(src='/javascripts/controllers/common.js')
-            script(src='/javascripts/dataStructures.js')
-
-            script(src='/javascripts/bundle.js')
-    body.theme-line.body-overlap
-        .wrapper
-            include includes/header
-
-            .container.body-container
-                .main-content
-                    .main-head
-                        block container
-
-            include includes/footer

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/persistence.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/persistence.jade 
b/modules/web-control-center/nodejs/views/persistence.jade
index 84b1616..b456b17 100644
--- a/modules/web-control-center/nodejs/views/persistence.jade
+++ b/modules/web-control-center/nodejs/views/persistence.jade
@@ -14,10 +14,10 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-extends layout-sidebar
+extends templates/layout-sidebar
 
 append scripts
-    script(src='/javascripts/controllers/persistences.js')
+    script(src='/persistences-controller.js')
 
 include includes/controls
 

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/profile.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/profile.jade 
b/modules/web-control-center/nodejs/views/profile.jade
index 34e71f9..0e5268d 100644
--- a/modules/web-control-center/nodejs/views/profile.jade
+++ b/modules/web-control-center/nodejs/views/profile.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-extends layout-sidebar
+extends templates/layout-sidebar
 
 block content
     .docs-header(ng-init='editableUser = 
#{JSON.stringify(filterUser(editableUser))}')

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/sql.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/sql.jade 
b/modules/web-control-center/nodejs/views/sql.jade
index a816251..93e2893 100644
--- a/modules/web-control-center/nodejs/views/sql.jade
+++ b/modules/web-control-center/nodejs/views/sql.jade
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-extends layout
+extends templates/layout
 
 block container
     .docs-header

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/summary.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/summary.jade 
b/modules/web-control-center/nodejs/views/summary.jade
index a6ecd92..3762822 100644
--- a/modules/web-control-center/nodejs/views/summary.jade
+++ b/modules/web-control-center/nodejs/views/summary.jade
@@ -14,10 +14,11 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 
-extends layout-sidebar
+extends templates/layout-sidebar
 
 append scripts
-    script(src='/javascripts/controllers/summary.js')
+    script(src='/summary-controller.js')
+
     
script(src='//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.min.js')
    
     
script(src='//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushXml.js')
    
     
script(src='//cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushJava.js')

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/templates/layout-sidebar.jade
----------------------------------------------------------------------
diff --git 
a/modules/web-control-center/nodejs/views/templates/layout-sidebar.jade 
b/modules/web-control-center/nodejs/views/templates/layout-sidebar.jade
new file mode 100644
index 0000000..36c778b
--- /dev/null
+++ b/modules/web-control-center/nodejs/views/templates/layout-sidebar.jade
@@ -0,0 +1,37 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+extends layout
+
+block container
+    .row
+        .col-sm-2.border-right.section-left.greedy
+            .sidebar-nav
+                ul.menu(ng-controller='activeLink')
+                    li
+                        a(ng-class="{active: 
isActive('/configuration/clusters')}" href='/configuration/clusters') Clusters
+                    li
+                        a(ng-class="{active: 
isActive('/configuration/caches')}" href='/configuration/caches') Caches
+                    //li
+                    //    a(ng-class="{active: isActive('/persistence')}" 
href='/persistence') Persistence
+                    //li
+                    //    a(ng-class="{active: isActive('/clients')}" 
href='/clients') Clients
+                    li
+                        p
+                        a(ng-class="{active: 
isActive('/configuration/summary')}" href='/configuration/summary') Summary
+        .col-sm-10.border-left.section-right
+            .docs-content
+                block content
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/36063e13/modules/web-control-center/nodejs/views/templates/layout.jade
----------------------------------------------------------------------
diff --git a/modules/web-control-center/nodejs/views/templates/layout.jade 
b/modules/web-control-center/nodejs/views/templates/layout.jade
new file mode 100644
index 0000000..1bc75e4
--- /dev/null
+++ b/modules/web-control-center/nodejs/views/templates/layout.jade
@@ -0,0 +1,58 @@
+//-
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You under the Apache License, Version 2.0
+    (the "License"); you may not use this file except in compliance with
+    the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+doctype html
+html(ng-app='ignite-web-control-center', ng-init='loggedInUser = 
#{JSON.stringify(filterUser(user))}; viewedUser = 
#{JSON.stringify(viewedUser)}')
+    head
+        title= title
+
+        block css
+            // Bootstrap
+            link(rel='stylesheet', 
href='//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.4/css/bootstrap.css')
+
+            // Font Awesome Icons
+            link(rel='stylesheet', 
href='//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.css')
+
+            // Font
+            link(rel='stylesheet', 
href='//fonts.googleapis.com/css?family=Roboto+Slab:700:serif|Roboto+Slab:400:serif')
+
+            link(rel='stylesheet', href='/stylesheets/style.css')
+
+        block scripts
+            
script(src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js')
+
+            
script(src='//cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.min.js')
+
+            
script(src='//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.js')
+            
script(src='//cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-sanitize.js')
+            
script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.2.2/angular-strap.js')
+            
script(src='//cdnjs.cloudflare.com/ajax/libs/angular-strap/2.2.2/angular-strap.tpl.min.js')
+
+            
script(src='https://cdnjs.cloudflare.com/ajax/libs/angular-smart-table/2.0.3/smart-table.js')
+
+            script(src='/common-module.js')
+            script(src='/data-structures.js')
+
+    body.theme-line.body-overlap
+        .wrapper
+            include ../includes/header
+
+            .container.body-container
+                .main-content
+                    .main-head
+                        block container
+
+            include ../includes/footer

Reply via email to