tez-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rbalamo...@apache.org
Subject tez git commit: TEZ-1987. Tez UI non-standalone mode uses invalid protocol (Sreenath Somarajapuram via rbalamohan)
Date Wed, 28 Jan 2015 12:05:51 GMT
Repository: tez
Updated Branches:
  refs/heads/branch-0.6 c20622364 -> 1d561799d


TEZ-1987. Tez UI non-standalone mode uses invalid protocol (Sreenath Somarajapuram via rbalamohan)

(cherry picked from commit 713bfb1351f9a81e1a7f8c35ef4423bbc943754d)

Conflicts:
	CHANGES.txt


Project: http://git-wip-us.apache.org/repos/asf/tez/repo
Commit: http://git-wip-us.apache.org/repos/asf/tez/commit/1d561799
Tree: http://git-wip-us.apache.org/repos/asf/tez/tree/1d561799
Diff: http://git-wip-us.apache.org/repos/asf/tez/diff/1d561799

Branch: refs/heads/branch-0.6
Commit: 1d561799d325ed99f7dee15f38485f236ad4569b
Parents: c206223
Author: Rajesh Balamohan <rbalamohan@hortonworks.com>
Authored: Wed Jan 28 17:31:11 2015 +0530
Committer: Rajesh Balamohan <rbalamohan@hortonworks.com>
Committed: Wed Jan 28 17:35:07 2015 +0530

----------------------------------------------------------------------
 CHANGES.txt                                     |   1 +
 tez-ui/src/main/webapp/Gruntfile.js             |   3 +-
 .../app/scripts/controllers/dags_controller.js  |  12 ---
 .../controllers/vertex_tasks_controller.js      |   2 +-
 .../main/webapp/app/scripts/default-configs.js  |   7 +-
 .../app/scripts/helpers/handlebarHelpers.js     |   9 ++
 .../src/main/webapp/app/scripts/helpers/misc.js |   4 +-
 .../main/webapp/app/scripts/helpers/number.js   |  14 +++
 .../app/scripts/mixins/paginated_content.js     | 101 +++++++++++--------
 tez-ui/src/main/webapp/app/scripts/router.js    |   3 +
 tez-ui/src/main/webapp/app/styles/main.less     |   2 +-
 .../app/templates/components/counter-table.hbs  |   2 +-
 .../app/templates/components/kv-table.hbs       |   2 +-
 .../main/webapp/app/templates/dag/vertices.hbs  |   2 +-
 tez-ui/src/main/webapp/app/templates/dags.hbs   |  11 +-
 .../app/templates/partials/table-controls.hbs   |  26 +++--
 16 files changed, 115 insertions(+), 86 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 6ccc9d7..589281e 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -6,6 +6,7 @@ Release 0.6.1: Unreleased
 INCOMPATIBLE CHANGES
 
 ALL CHANGES:
+  TEZ-1987. Tez UI non-standalone mode uses invalid protocol.
   TEZ-1983. Tez UI swimlane task attempt link is broken
 
 Release 0.6.0: Unreleased

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/Gruntfile.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/Gruntfile.js b/tez-ui/src/main/webapp/Gruntfile.js
index b096fca..95e57da 100644
--- a/tez-ui/src/main/webapp/Gruntfile.js
+++ b/tez-ui/src/main/webapp/Gruntfile.js
@@ -49,7 +49,7 @@ module.exports = function (grunt) {
         tasks: ['emberTemplates']
       },
       neuter: {
-        files: ['<%= yeoman.app %>/scripts/{,*/}*.js'],
+        files: ['<%= yeoman.app %>/scripts/{,*/,*/*/}*.js'],
         tasks: ['neuter']
       },
       less: {
@@ -203,7 +203,6 @@ module.exports = function (grunt) {
           '<%= yeoman.dist %>/styles/main.css': [
             '.tmp/styles/{,*/}*.css',
             '<%= yeoman.app %>/styles/{,*/}*.css',
-            '<%= yeoman.app %>/bower_components/bootstrap/dist/css/bootstrap.css',
             '<%= yeoman.app %>/bower_components/ember-table/dist/ember-table.css',
             '<%= yeoman.app %>/bower_components/font-awesome/css/font-awesome.css',
             '<%= yeoman.app %>/bower_components/jquery-ui/themes/smoothness/jquery-ui.css'

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js
index 4dab2a9..e26ada5 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/dags_controller.js
@@ -28,7 +28,6 @@ App.DagsController = Em.ObjectController.extend(App.PaginatedContentMixin,
App.C
   // query parameters supported through url. The same named variables in this controller
get
   // bound automatically to the ones defined in the route.
   queryParams: {
-    count: true,
     fromID: true,
     status_filter: 'status',
     user_filter: 'user',
@@ -36,10 +35,6 @@ App.DagsController = Em.ObjectController.extend(App.PaginatedContentMixin,
App.C
     dagName_filter: 'dag_name'
   },
 
-  // paging related values. These are bound automatically to the values in url. via the queryParams
-  // defined in the route. 
-  count: 10,
-
   fromID: null,
 
   status_filter: null,
@@ -52,9 +47,6 @@ App.DagsController = Em.ObjectController.extend(App.PaginatedContentMixin,
App.C
 
   fields: 'events,primaryfilters,otherinfo',
 
-  // The dropdown contents for number of items to show.
-  countOptions: [5, 10, 25, 50],
-
   loadData: function() {
     var filters = {
       primary: {
@@ -108,10 +100,6 @@ App.DagsController = Em.ObjectController.extend(App.PaginatedContentMixin,
App.C
     });
   },
 
-  countUpdated: function() {
-    this.loadData();
-  }.observes('count'),
-
   actions : {
     filterUpdated: function(filterID, value) {
       // any validations required goes here.

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/scripts/controllers/vertex_tasks_controller.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_tasks_controller.js b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_tasks_controller.js
index 5b440f7..dc05ac1 100644
--- a/tez-ui/src/main/webapp/app/scripts/controllers/vertex_tasks_controller.js
+++ b/tez-ui/src/main/webapp/app/scripts/controllers/vertex_tasks_controller.js
@@ -113,7 +113,7 @@ App.VertexTasksController = Em.ObjectController.extend(App.PaginatedContentMixin
       },
       {
         id: 'duration',
-        headerCellName: 'duration',
+        headerCellName: 'Duration',
         getCellContent: function(row) {
           var st = row.get('startTime');
           var et = row.get('endTime');

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/scripts/default-configs.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/default-configs.js b/tez-ui/src/main/webapp/app/scripts/default-configs.js
index fc7f28a..48da014 100644
--- a/tez-ui/src/main/webapp/app/scripts/default-configs.js
+++ b/tez-ui/src/main/webapp/app/scripts/default-configs.js
@@ -18,21 +18,21 @@
 
 var getDefaultTimelineUrl = function() {
   var location = window.location;
-  var protocol = App.env.isStandalone ? location.protocol : 'http';
+  var protocol = App.env.isStandalone ? location.protocol : 'http:';
   var hostname = App.env.isStandalone ? location.hostname : 'localhost';
   return '%@//%@:8188'.fmt(protocol, hostname);
 };
 
 var getDefaultRMWebUrl = function() {
   var location = window.location;
-  var protocol = App.env.isStandalone ? location.protocol : 'http';
+  var protocol = App.env.isStandalone ? location.protocol : 'http:';
   var hostname = App.env.isStandalone ? location.hostname : 'localhost';
   return '%@//%@:8088'.fmt(protocol, hostname);
 };
 
 $.extend(true, App.Configs, {
   envDefaults: {
-    version: "0.6.0",
+    version: "0.7.0",
 
     timelineBaseUrl: getDefaultTimelineUrl(),
     RMWebUrl: getDefaultRMWebUrl(),
@@ -44,6 +44,7 @@ $.extend(true, App.Configs, {
   },
 
   defaultCounters: [
+    // File System Counters
     {
       counterId: 'FILE_BYTES_READ',
       groupId: 'org.apache.tez.common.counters.FileSystemCounter',

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/scripts/helpers/handlebarHelpers.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/helpers/handlebarHelpers.js b/tez-ui/src/main/webapp/app/scripts/helpers/handlebarHelpers.js
index 3639d28..f9a2a56 100644
--- a/tez-ui/src/main/webapp/app/scripts/helpers/handlebarHelpers.js
+++ b/tez-ui/src/main/webapp/app/scripts/helpers/handlebarHelpers.js
@@ -31,6 +31,15 @@ Em.Handlebars.helper('formatUnixTimestamp', function(timestamp) {
 	return '';
 });
 
+/**
+ * Format value with US style thousands separator
+ * @param {string/number} value to be formatted
+ * @returns {string} Formatted string
+ */
+Em.Handlebars.helper('formatNumThousands', function (value) {
+  return App.Helpers.number.formatNumThousands(value);
+});
+
 /*
  * formats the duration.
  *

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/scripts/helpers/misc.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/helpers/misc.js b/tez-ui/src/main/webapp/app/scripts/helpers/misc.js
index d2ac9ef..07de80a 100644
--- a/tez-ui/src/main/webapp/app/scripts/helpers/misc.js
+++ b/tez-ui/src/main/webapp/app/scripts/helpers/misc.js
@@ -81,7 +81,7 @@ App.Helpers.misc = {
    */
   normalizeCounterConfigs: function (counterConfigs) {
     return counterConfigs.map(function (configuration) {
-      configuration.headerCellName = configuration.headerCellName || configuration.headerText;
+      configuration.headerCellName = configuration.headerCellName || configuration.counterId;
       configuration.id = '%@/%@'.fmt(configuration.groupId, configuration.counterId),
       configuration.getCellContent = App.Helpers.misc.getCounterCellContent;
       return configuration;
@@ -126,7 +126,7 @@ App.Helpers.misc = {
           get('value');
     }catch(e){}
 
-    return value;
+    return App.Helpers.number.formatNumThousands(value);
   },
 
   /* 

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/scripts/helpers/number.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/helpers/number.js b/tez-ui/src/main/webapp/app/scripts/helpers/number.js
index 66b3e8e..c72edb3 100644
--- a/tez-ui/src/main/webapp/app/scripts/helpers/number.js
+++ b/tez-ui/src/main/webapp/app/scripts/helpers/number.js
@@ -88,6 +88,20 @@ App.Helpers.number = {
   },
 
   /**
+   * Format value with US style thousands separator
+   * @param {string/number} value to be formatted
+   * @returns {string} Formatted string
+   */
+  formatNumThousands: function (value) {
+    if(/^[\d\.]+$/.test(value)) {
+      var parts = value.toString().split(".");
+      parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
+      return parts.join(".");
+    }
+    return value;
+  },
+
+  /**
    * Checks if the value is an integer or can be converted to an integer.
    * a value of NaN returns false.
    * @method: isValidInt

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/scripts/mixins/paginated_content.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/mixins/paginated_content.js b/tez-ui/src/main/webapp/app/scripts/mixins/paginated_content.js
index bc11c27..07c34b0 100644
--- a/tez-ui/src/main/webapp/app/scripts/mixins/paginated_content.js
+++ b/tez-ui/src/main/webapp/app/scripts/mixins/paginated_content.js
@@ -17,11 +17,16 @@
  */
 
 App.PaginatedContentMixin = Em.Mixin.create({
-	count: 10,
-	
-	fromID: null,
+  // paging related values. These are bound automatically to the values in url. via the queryParams
+  // defined in the route.
+  count: 10,
 
-	/* There is currently no efficient way in ATS to get pagination data, so we fake one.
+  fromID: null,
+
+  // The dropdown contents for number of items to show.
+  countOptions: [5, 10, 25, 50],
+
+  /* There is currently no efficient way in ATS to get pagination data, so we fake one.
    * store the first dag id on a page so that we can navigate back and store the last one

    * (not shown on page to get the id where next page starts)
    */
@@ -31,9 +36,17 @@ App.PaginatedContentMixin = Em.Mixin.create({
     nextID: undefined
   },
 
+  queryParams: {
+    count: true,
+  },
+
   entities: [],
   _paginationFilters: {},
-	loading: true,
+  loading: true,
+
+  countUpdated: function() {
+    this.loadData();
+  }.observes('count'),
 
   sortedContent: function() {
     // convert to a ArrayController. we do not sort at this point as the data is
@@ -66,20 +79,20 @@ App.PaginatedContentMixin = Em.Mixin.create({
     });
   },
 
-	setFiltersAndLoadEntities: function(filters) {
-		this._paginationFilters = filters;
-		this.resetNavigation();
-		this.loadEntities();
-	},
+  setFiltersAndLoadEntities: function(filters) {
+    this._paginationFilters = filters;
+    this.resetNavigation();
+    this.loadEntities();
+  },
 
-	resetNavigation: function() {
-		this.set('navIDs.prevIDs', []);
-		this.set('navIDs.currentID', '');
-		this.set('navIDs.nextID', '');
-		this.set('fromID', null);
-	},
+  resetNavigation: function() {
+    this.set('navIDs.prevIDs', []);
+    this.set('navIDs.currentID', '');
+    this.set('navIDs.nextID', '');
+    this.set('fromID', null);
+  },
 
-	updatePagination: function(dataArray) {
+  updatePagination: function(dataArray) {
     if (!!dataArray && dataArray.get('length') > 0) {
       this.set('navIDs.currentID', dataArray.objectAt(0).get('id'));
       var nextID = undefined;
@@ -127,40 +140,40 @@ App.PaginatedContentMixin = Em.Mixin.create({
   },
 
   _concatFilters: function(obj) {
-  	var p = [];
-		for(var k in obj) {
-			if (!Em.empty(obj[k])) {
-				p.push(k + ':' + obj[k]);
-			}
-		}
-		return p.join(',');
+    var p = [];
+    for(var k in obj) {
+      if (!Em.empty(obj[k])) {
+        p.push(k + ':' + obj[k]);
+      }
+    }
+    return p.join(',');
   },
 
-	getFilterProperties: function() {
-		var params = {
-			limit: this.count + 1
-		};
+  getFilterProperties: function() {
+    var params = {
+      limit: this.count + 1
+    };
 
-		var f = this._paginationFilters;
-		var primary = f.primary;
-		var secondary = f.secondary || {};
+    var f = this._paginationFilters;
+    var primary = f.primary;
+    var secondary = f.secondary || {};
 
-		primary = this._concatFilters(primary);
+    primary = this._concatFilters(primary);
 
-		secondary = this._concatFilters(secondary);
+    secondary = this._concatFilters(secondary);
 
-		if (!Em.empty(primary)) {
-			params['primaryFilter'] = primary;
-		}
+    if (!Em.empty(primary)) {
+      params['primaryFilter'] = primary;
+    }
 
-		if (!Em.empty(secondary)) {
-			params['secondaryFilter'] = secondary;
-		}
+    if (!Em.empty(secondary)) {
+      params['secondaryFilter'] = secondary;
+    }
 
-		if (!Em.empty(this.fromID)) {
-			params['fromId'] = this.fromID;
-		}
+    if (!Em.empty(this.fromID)) {
+      params['fromId'] = this.fromID;
+    }
 
-		return params;
-	},
+    return params;
+  },
 });

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/scripts/router.js
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/scripts/router.js b/tez-ui/src/main/webapp/app/scripts/router.js
index 0dbdb84..f33bcca 100644
--- a/tez-ui/src/main/webapp/app/scripts/router.js
+++ b/tez-ui/src/main/webapp/app/scripts/router.js
@@ -160,6 +160,7 @@ App.TaskRoute = Em.Route.extend({
 
 App.TasksRoute = Em.Route.extend({
   queryParams: {
+    count: App.Helpers.misc.defaultQueryParamsConfig,
     status: App.Helpers.misc.defaultQueryParamsConfig,
     parentType: App.Helpers.misc.defaultQueryParamsConfig,
     parentID: App.Helpers.misc.defaultQueryParamsConfig
@@ -215,6 +216,7 @@ App.VertexSwimlaneRoute = Em.Route.extend({
 App.TaskAttemptsRoute = Em.Route.extend({
   renderTemplate: renderTableWithSpinner,
   queryParams: {
+    count: App.Helpers.misc.defaultQueryParamsConfig,
     status: App.Helpers.misc.defaultQueryParamsConfig 
   },
   setupController: setupControllerFactory('Task Attempt: %@', 'id')
@@ -261,6 +263,7 @@ App.DagTasksRoute =
     Em.Route.extend({
       renderTemplate: renderTableWithSpinner,
       queryParams: {
+        count: App.Helpers.misc.defaultQueryParamsConfig,
         status: App.Helpers.misc.defaultQueryParamsConfig
       },
       setupController: setupControllerFactory()

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/styles/main.less
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/styles/main.less b/tez-ui/src/main/webapp/app/styles/main.less
index 930d2fd..0f95485 100644
--- a/tez-ui/src/main/webapp/app/styles/main.less
+++ b/tez-ui/src/main/webapp/app/styles/main.less
@@ -401,7 +401,7 @@ div.indent {
     border: 1px solid #dcdcdc;
     padding: 5px 5px;
     width: 50%;
-    overflow: scroll;
+    word-wrap:break-word;
   }
 
   th, td.filter {

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/templates/components/counter-table.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/components/counter-table.hbs b/tez-ui/src/main/webapp/app/templates/components/counter-table.hbs
index fbd7616..e8d12b1 100644
--- a/tez-ui/src/main/webapp/app/templates/components/counter-table.hbs
+++ b/tez-ui/src/main/webapp/app/templates/components/counter-table.hbs
@@ -34,7 +34,7 @@
         {{#each counter in counterGroup.counters}}
           <tr>
             <td>{{unbound counter.displayName}}</td>
-            <td>{{unbound counter.value}}</td>
+            <td>{{unbound formatNumThousands counter.value}}</td>
           </tr>
         {{/each}}
       {{/each}}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/templates/components/kv-table.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/components/kv-table.hbs b/tez-ui/src/main/webapp/app/templates/components/kv-table.hbs
index 0a8c110..ae2ad17 100644
--- a/tez-ui/src/main/webapp/app/templates/components/kv-table.hbs
+++ b/tez-ui/src/main/webapp/app/templates/components/kv-table.hbs
@@ -31,7 +31,7 @@
       {{#each kv in filteredKVs}}
         <tr>
           <td>{{unbound kv.key}}</td>
-          <td>{{unbound kv.value}}</td>
+          <td>{{unbound formatNumThousands kv.value}}</td>
         </tr>
       {{/each}}
     </tbody>

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/templates/dag/vertices.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/dag/vertices.hbs b/tez-ui/src/main/webapp/app/templates/dag/vertices.hbs
index 6d3e765..28a4305 100644
--- a/tez-ui/src/main/webapp/app/templates/dag/vertices.hbs
+++ b/tez-ui/src/main/webapp/app/templates/dag/vertices.hbs
@@ -45,5 +45,5 @@
   }}
   </div>
 {{else}}
-  {{partial 'utils/loadingSpinner'}}
+  {{partial 'partials/loading-spinner'}}
 {{/unless}}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/templates/dags.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/dags.hbs b/tez-ui/src/main/webapp/app/templates/dags.hbs
index 980e84b..69c5cf8 100644
--- a/tez-ui/src/main/webapp/app/templates/dags.hbs
+++ b/tez-ui/src/main/webapp/app/templates/dags.hbs
@@ -21,16 +21,7 @@
 </ul>
 
 {{#unless loading}}
-  <div class='margin-small'>
-    <div class="horizontal-half align-children-left">
-      Number of Dags to Show
-      {{view Ember.Select 
-        content=countOptions 
-        value=count
-      }}
-    </div><div class="horizontal-half align-children-right">
-      {{partial 'partials/table-controls'}}
-    </div>
+  {{partial 'partials/table-controls'}}
   </div>
   {{partial 'partials/table'}}
 {{else}}

http://git-wip-us.apache.org/repos/asf/tez/blob/1d561799/tez-ui/src/main/webapp/app/templates/partials/table-controls.hbs
----------------------------------------------------------------------
diff --git a/tez-ui/src/main/webapp/app/templates/partials/table-controls.hbs b/tez-ui/src/main/webapp/app/templates/partials/table-controls.hbs
index 62a8606..0525dea 100644
--- a/tez-ui/src/main/webapp/app/templates/partials/table-controls.hbs
+++ b/tez-ui/src/main/webapp/app/templates/partials/table-controls.hbs
@@ -16,11 +16,21 @@
 * limitations under the License.
 }}
 
-{{page-nav-component
-  hasPrev=hasPrev
-  hasNext=hasNext
-  navNext='navigateNext'
-  navPrev='navigatePrev'
-  navFirst='navigateFirst'
-}}
-<i {{bind-attr class=':fa-action :fa-cog :left-divider'}} {{action 'selectColumns'}}></i>
+<div class='margin-small'>
+  <div class="horizontal-half align-children-left">
+    Number of rows
+    {{view Ember.Select
+      content=countOptions
+      value=count
+    }}
+  </div><div class="horizontal-half align-children-right">
+    {{page-nav-component
+      hasPrev=hasPrev
+      hasNext=hasNext
+      navNext='navigateNext'
+      navPrev='navigatePrev'
+      navFirst='navigateFirst'
+    }}
+    <i {{bind-attr class=':fa-action :fa-cog :left-divider'}} {{action 'selectColumns'}}></i>
+  </div>
+</div>
\ No newline at end of file


Mime
View raw message