From 0c30177082053ae126443045800d6253d5890de1 Mon Sep 17 00:00:00 2001 From: Steven Esser Date: Wed, 29 Aug 2018 11:35:04 -0700 Subject: [PATCH] Change ClueDataTable to ScanDataDataTable #268 * Change varible/class/ids in main.css * Change varible naming in aboutCodeBarChart.js * Change varible naming in aboutCodeDashboard.js * Change varible naming in aboutCodeJsTree.js * Change varible naming in renderer.js * Change varible/class/ids in index.html * Change aboutCodeClueDataTable.js to aboutCodeScanDataDataTable.js Signed-off-by: Steven Esser --- assets/app/css/main.css | 8 +- .../app/js/controllers/aboutCodeBarChart.js | 4 +- .../app/js/controllers/aboutCodeDashboard.js | 4 +- assets/app/js/controllers/aboutCodeJsTree.js | 4 +- ...Table.js => aboutCodeScanDataDataTable.js} | 114 +++++++++--------- assets/app/js/renderer.js | 48 ++++---- index.html | 8 +- 7 files changed, 95 insertions(+), 95 deletions(-) rename assets/app/js/controllers/{aboutCodeClueDataTable.js => aboutCodeScanDataDataTable.js} (86%) diff --git a/assets/app/css/main.css b/assets/app/css/main.css index 509cfffa..11db1d5e 100644 --- a/assets/app/css/main.css +++ b/assets/app/css/main.css @@ -140,7 +140,7 @@ body { fill: black; } -.clues rect { +.scandata rect { x: 0; y: -10; height: 20px; @@ -149,17 +149,17 @@ body { stroke-width:3 } -.clue-filename rect { +.scandata-filename rect { fill: gray; stroke: gray; } -.clue-license rect { +.scandata-license rect { fill: #3984b6; stroke: #3984b6; } -.clue-copyright rect { +.scandata-copyright rect { fill: #1d2e81; stroke: #1d2e81; } diff --git a/assets/app/js/controllers/aboutCodeBarChart.js b/assets/app/js/controllers/aboutCodeBarChart.js index a4d48cf2..ee0e707d 100644 --- a/assets/app/js/controllers/aboutCodeBarChart.js +++ b/assets/app/js/controllers/aboutCodeBarChart.js @@ -18,7 +18,7 @@ const Sequelize = require('sequelize'); const Progress = require('../helpers/progress'); const BarChart = require('../helpers/barChart'); const Utils = require('../helpers/utils'); -const AboutCodeClueDataTable = require('./aboutCodeClueDataTable'); +const AboutCodeScanDataDataTable = require('./aboutCodeScanDataDataTable'); const Controller = require('./controller'); // There must be an svg element within the container element with this class @@ -49,7 +49,7 @@ class AboutCodeBarChart extends Controller { this.chartAttributesSelect.select2({ placeholder: 'Select an attribute' }); // Populate bar chart summary select box values - $.each(AboutCodeClueDataTable.TABLE_COLUMNS, (i, column) => { + $.each(AboutCodeScanDataDataTable.TABLE_COLUMNS, (i, column) => { if (column.bar_chart_class) { this.chartAttributesSelect.append( ``); diff --git a/assets/app/js/controllers/aboutCodeDashboard.js b/assets/app/js/controllers/aboutCodeDashboard.js index 1f535a07..8c3b3db8 100644 --- a/assets/app/js/controllers/aboutCodeDashboard.js +++ b/assets/app/js/controllers/aboutCodeDashboard.js @@ -34,7 +34,7 @@ const LEGEND_LIMIT = 8; /** * The view responsible for displaying the summary information from ScanCode - * clue data + * Scan data */ class AboutCodeDashboard extends Controller { constructor(dashboardId, aboutCodeDB) { @@ -270,4 +270,4 @@ class AboutCodeDashboard extends Controller { } } -module.exports = AboutCodeDashboard; \ No newline at end of file +module.exports = AboutCodeDashboard; diff --git a/assets/app/js/controllers/aboutCodeJsTree.js b/assets/app/js/controllers/aboutCodeJsTree.js index e8111698..7324abeb 100644 --- a/assets/app/js/controllers/aboutCodeJsTree.js +++ b/assets/app/js/controllers/aboutCodeJsTree.js @@ -18,7 +18,7 @@ const Controller = require('./controller'); /** * The view responsible for displaying the jsTree representing file paths in the - * ScanCode clue data + * ScanCode Scan data */ class AboutCodeJsTree extends Controller { constructor(jsTreeId, aboutCodeDB) { @@ -109,4 +109,4 @@ class AboutCodeJsTree extends Controller { } } -module.exports = AboutCodeJsTree; \ No newline at end of file +module.exports = AboutCodeJsTree; diff --git a/assets/app/js/controllers/aboutCodeClueDataTable.js b/assets/app/js/controllers/aboutCodeScanDataDataTable.js similarity index 86% rename from assets/app/js/controllers/aboutCodeClueDataTable.js rename to assets/app/js/controllers/aboutCodeScanDataDataTable.js index 9db0edf3..691363f6 100644 --- a/assets/app/js/controllers/aboutCodeClueDataTable.js +++ b/assets/app/js/controllers/aboutCodeScanDataDataTable.js @@ -19,7 +19,7 @@ const Utils = require('../helpers/utils'); const Controller = require('./controller'); // There must be a table element within the container element with this class -const CLUES_TABLE = 'table.clues-table'; +const SCANDATA_TABLE = 'table.scandata-table'; const HAS_A_VALUE = 'about_code_data_table_has_a_value'; @@ -27,9 +27,9 @@ const NO_VALUE_DETECTED = 'about_code_data_table_no_value_detected'; /** * The view responsible for displaying the DataTable containing the ScanCode - * clue data + * Scan data */ -class AboutCodeClueDataTable extends Controller { +class AboutCodeScanDataDataTable extends Controller { constructor(containerId, aboutCodeDB) { super(containerId, aboutCodeDB); } @@ -59,8 +59,8 @@ class AboutCodeClueDataTable extends Controller { } clearColumnFilters() { - $.each(AboutCodeClueDataTable.TABLE_COLUMNS, (i, column) => { - const columnSelect = $(`select#clue-${column.name}`); + $.each(AboutCodeScanDataDataTable.TABLE_COLUMNS, (i, column) => { + const columnSelect = $(`select#scandata-${column.name}`); columnSelect.val(''); this.dataTable() .column(`${column.name}:name`) @@ -69,12 +69,12 @@ class AboutCodeClueDataTable extends Controller { } setColumnFilter(columnName, value) { - // Get the clue table column and make sure it's visible + // Get the ScanData table column and make sure it's visible const column = this.dataTable().column(`${columnName}:name`); column.visible(true); // Get the column's filter select box - const select = $(`select#clue-${columnName}`); + const select = $(`select#scandata-${columnName}`); select.empty().append(``); // Add the chart value options and select it. @@ -87,7 +87,7 @@ class AboutCodeClueDataTable extends Controller { } dataTableSelector() { - return `${this.id()} ${CLUES_TABLE}`; + return `${this.id()} ${SCANDATA_TABLE}`; } dataTable() { @@ -97,7 +97,7 @@ class AboutCodeClueDataTable extends Controller { // Adds a footer for each column. This needs to be done before creating // the DataTable - const cells = $.map(AboutCodeClueDataTable.TABLE_COLUMNS, () => '').join(''); + const cells = $.map(AboutCodeScanDataDataTable.TABLE_COLUMNS, () => '').join(''); $(this.dataTableSelector()).append('' + cells + ''); this._dataTable = $(this.dataTableSelector()).DataTable({ @@ -105,7 +105,7 @@ class AboutCodeClueDataTable extends Controller { processing: true, ajax: (dataTablesInput, dataTablesCallback) => this._query(dataTablesInput, dataTablesCallback), - columns: AboutCodeClueDataTable.TABLE_COLUMNS, + columns: AboutCodeScanDataDataTable.TABLE_COLUMNS, fixedColumns: { leftColumns: 1 }, colResize: true, scrollX: true, @@ -132,50 +132,50 @@ class AboutCodeClueDataTable extends Controller { // Hide all columns except Path extend: 'colvisGroup', text: 'Hide all', - show: AboutCodeClueDataTable.LOCATION_COLUMN + show: AboutCodeScanDataDataTable.LOCATION_COLUMN .map((column) => `${column.name}:name`), - hide: AboutCodeClueDataTable.TABLE_COLUMNS - .filter((column) => AboutCodeClueDataTable.LOCATION_COLUMN.indexOf(column) < 0) + hide: AboutCodeScanDataDataTable.TABLE_COLUMNS + .filter((column) => AboutCodeScanDataDataTable.LOCATION_COLUMN.indexOf(column) < 0) .map((column) => `${column.name}:name`) }, { // Show only origin columns extend: 'colvisGroup', text: 'Origin info', - show: AboutCodeClueDataTable.ORIGIN_GROUP + show: AboutCodeScanDataDataTable.ORIGIN_GROUP .map((column) => `${column.name}:name`), - hide: AboutCodeClueDataTable.TABLE_COLUMNS - .filter((column) => AboutCodeClueDataTable.ORIGIN_GROUP.indexOf(column) < 0) + hide: AboutCodeScanDataDataTable.TABLE_COLUMNS + .filter((column) => AboutCodeScanDataDataTable.ORIGIN_GROUP.indexOf(column) < 0) .map((column) => `${column.name}:name`) }, { // Show only copyright columns extend: 'colvisGroup', text: 'Copyright info', - show: AboutCodeClueDataTable.COPYRIGHT_GROUP + show: AboutCodeScanDataDataTable.COPYRIGHT_GROUP .map((column) => `${column.name}:name`), - hide: AboutCodeClueDataTable.TABLE_COLUMNS - .filter((column) => AboutCodeClueDataTable.COPYRIGHT_GROUP.indexOf(column) < 0) + hide: AboutCodeScanDataDataTable.TABLE_COLUMNS + .filter((column) => AboutCodeScanDataDataTable.COPYRIGHT_GROUP.indexOf(column) < 0) .map((column) => `${column.name}:name`) }, { // Show only license columns extend: 'colvisGroup', text: 'License info', - show: AboutCodeClueDataTable.LICENSE_GROUP + show: AboutCodeScanDataDataTable.LICENSE_GROUP .map((column) => `${column.name}:name`), - hide: AboutCodeClueDataTable.TABLE_COLUMNS - .filter((column) => AboutCodeClueDataTable.LICENSE_GROUP.indexOf(column) < 0) + hide: AboutCodeScanDataDataTable.TABLE_COLUMNS + .filter((column) => AboutCodeScanDataDataTable.LICENSE_GROUP.indexOf(column) < 0) .map((column) => `${column.name}:name`) }, { // Show only package columns extend: 'colvisGroup', text: 'Package info', - show: AboutCodeClueDataTable.PACKAGE_GROUP + show: AboutCodeScanDataDataTable.PACKAGE_GROUP .map((column) => `${column.name}:name`), - hide: AboutCodeClueDataTable.TABLE_COLUMNS - .filter((column) => AboutCodeClueDataTable.PACKAGE_GROUP.indexOf(column) < 0) + hide: AboutCodeScanDataDataTable.TABLE_COLUMNS + .filter((column) => AboutCodeScanDataDataTable.PACKAGE_GROUP.indexOf(column) < 0) .map((column) => `${column.name}:name`) } ], @@ -318,7 +318,7 @@ class AboutCodeClueDataTable extends Controller { footer.append(clearFiltersButton); this.dataTable().columns().every(function (columnIndex) { - const columnInfo = AboutCodeClueDataTable.TABLE_COLUMNS[columnIndex]; + const columnInfo = AboutCodeScanDataDataTable.TABLE_COLUMNS[columnIndex]; if ('skipFilter' in columnInfo && columnInfo.skipFilter) { return; @@ -328,7 +328,7 @@ class AboutCodeClueDataTable extends Controller { const footer = $(column.footer()); const columnName = columnInfo.name; - const select = $(``) + const select = $(``) .on('change', function () { const val = $(this).val(); column @@ -345,8 +345,8 @@ class AboutCodeClueDataTable extends Controller { } resetColumnFilters() { - $.each(AboutCodeClueDataTable.TABLE_COLUMNS, (i, column) => { - const columnSelect = $(`select#clue-${column.name}`); + $.each(AboutCodeScanDataDataTable.TABLE_COLUMNS, (i, column) => { + const columnSelect = $(`select#scandata-${column.name}`); columnSelect.empty(); columnSelect.val(''); this.dataTable() @@ -362,7 +362,7 @@ class AboutCodeClueDataTable extends Controller { const that = this; this.dataTable().columns().every(function (columnIndex) { - const columnInfo = AboutCodeClueDataTable.TABLE_COLUMNS[columnIndex]; + const columnInfo = AboutCodeScanDataDataTable.TABLE_COLUMNS[columnIndex]; const currentColumn = that.dataTable().columns(columnIndex); if ('skipFilter' in columnInfo && columnInfo.skipFilter) { @@ -380,7 +380,7 @@ class AboutCodeClueDataTable extends Controller { footer.empty(); - const select = $('#clue-' + columnName) + const select = $('#scandata-' + columnName) .empty() .on('change', function () { const val = $(this).val(); @@ -426,43 +426,43 @@ class AboutCodeClueDataTable extends Controller { // Define DataTable columns static get TABLE_COLUMNS() { - return AboutCodeClueDataTable.LOCATION_COLUMN.concat( - AboutCodeClueDataTable.COPYRIGHT_COLUMNS, - AboutCodeClueDataTable.LICENSE_COLUMNS, - AboutCodeClueDataTable.EMAIL_COLUMNS, - AboutCodeClueDataTable.URL_COLUMNS, - AboutCodeClueDataTable.FILE_COLUMNS, - AboutCodeClueDataTable.PACKAGE_COLUMNS); + return AboutCodeScanDataDataTable.LOCATION_COLUMN.concat( + AboutCodeScanDataDataTable.COPYRIGHT_COLUMNS, + AboutCodeScanDataDataTable.LICENSE_COLUMNS, + AboutCodeScanDataDataTable.EMAIL_COLUMNS, + AboutCodeScanDataDataTable.URL_COLUMNS, + AboutCodeScanDataDataTable.FILE_COLUMNS, + AboutCodeScanDataDataTable.PACKAGE_COLUMNS); } static get ORIGIN_COLUMNS() { - return $.grep(AboutCodeClueDataTable.TABLE_COLUMNS, (column) => { - return $.inArray(column.name, AboutCodeClueDataTable.ORIGIN_COLUMN_NAMES) >= 0; + return $.grep(AboutCodeScanDataDataTable.TABLE_COLUMNS, (column) => { + return $.inArray(column.name, AboutCodeScanDataDataTable.ORIGIN_COLUMN_NAMES) >= 0; }); } static get LICENSE_GROUP() { - return AboutCodeClueDataTable.LOCATION_COLUMN - .concat(AboutCodeClueDataTable.LICENSE_COLUMNS); + return AboutCodeScanDataDataTable.LOCATION_COLUMN + .concat(AboutCodeScanDataDataTable.LICENSE_COLUMNS); } static get COPYRIGHT_GROUP() { - return AboutCodeClueDataTable.LOCATION_COLUMN - .concat(AboutCodeClueDataTable.COPYRIGHT_COLUMNS); + return AboutCodeScanDataDataTable.LOCATION_COLUMN + .concat(AboutCodeScanDataDataTable.COPYRIGHT_COLUMNS); } static get ORIGIN_GROUP() { - return AboutCodeClueDataTable.LOCATION_COLUMN - .concat(AboutCodeClueDataTable.ORIGIN_COLUMNS); + return AboutCodeScanDataDataTable.LOCATION_COLUMN + .concat(AboutCodeScanDataDataTable.ORIGIN_COLUMNS); } static get PACKAGE_GROUP() { - return AboutCodeClueDataTable.LOCATION_COLUMN - .concat(AboutCodeClueDataTable.PACKAGE_COLUMNS); + return AboutCodeScanDataDataTable.LOCATION_COLUMN + .concat(AboutCodeScanDataDataTable.PACKAGE_COLUMNS); } } -AboutCodeClueDataTable.LOCATION_COLUMN = +AboutCodeScanDataDataTable.LOCATION_COLUMN = [ { 'data': 'path', @@ -473,7 +473,7 @@ AboutCodeClueDataTable.LOCATION_COLUMN = } ]; -AboutCodeClueDataTable.COPYRIGHT_COLUMNS = +AboutCodeScanDataDataTable.COPYRIGHT_COLUMNS = [ { 'data': function (row) { @@ -522,7 +522,7 @@ AboutCodeClueDataTable.COPYRIGHT_COLUMNS = } ]; -AboutCodeClueDataTable.LICENSE_COLUMNS = +AboutCodeScanDataDataTable.LICENSE_COLUMNS = [ { 'data': 'license_expressions[
]', @@ -608,7 +608,7 @@ AboutCodeClueDataTable.LICENSE_COLUMNS = } ]; -AboutCodeClueDataTable.EMAIL_COLUMNS = +AboutCodeScanDataDataTable.EMAIL_COLUMNS = [ { 'data': 'email[
]', @@ -631,7 +631,7 @@ AboutCodeClueDataTable.EMAIL_COLUMNS = } ]; -AboutCodeClueDataTable.URL_COLUMNS = +AboutCodeScanDataDataTable.URL_COLUMNS = [ { 'data': 'url', @@ -656,7 +656,7 @@ AboutCodeClueDataTable.URL_COLUMNS = } ]; -AboutCodeClueDataTable.FILE_COLUMNS = +AboutCodeScanDataDataTable.FILE_COLUMNS = [ { 'data': 'type', @@ -772,7 +772,7 @@ AboutCodeClueDataTable.FILE_COLUMNS = } ]; -AboutCodeClueDataTable.PACKAGE_COLUMNS = +AboutCodeScanDataDataTable.PACKAGE_COLUMNS = [ { 'data': 'packages_type', @@ -828,7 +828,7 @@ AboutCodeClueDataTable.PACKAGE_COLUMNS = }, ]; -AboutCodeClueDataTable.ORIGIN_COLUMN_NAMES = +AboutCodeScanDataDataTable.ORIGIN_COLUMN_NAMES = [ 'copyright_statements', 'license_short_name', @@ -837,4 +837,4 @@ AboutCodeClueDataTable.ORIGIN_COLUMN_NAMES = 'url' ]; -module.exports = AboutCodeClueDataTable; +module.exports = AboutCodeScanDataDataTable; diff --git a/assets/app/js/renderer.js b/assets/app/js/renderer.js index 2ca3fd82..62d08388 100644 --- a/assets/app/js/renderer.js +++ b/assets/app/js/renderer.js @@ -23,7 +23,7 @@ const ComponentDialog = require('./controllers/componentDialog'); const AboutCodeDashboard = require('./controllers/aboutCodeDashboard'); const AboutCodeBarChart = require('./controllers/aboutCodeBarChart'); const AboutCodeJsTree = require('./controllers/aboutCodeJsTree'); -const AboutCodeClueDataTable = require('./controllers/aboutCodeClueDataTable'); +const AboutCodeScanDataDataTable = require('./controllers/aboutCodeScanDataDataTable'); const AboutCodeComponentDataTable = require('./controllers/aboutCodeComponentDataTable'); const fs = require('fs'); @@ -48,21 +48,21 @@ $(document).ready(() => { const barChart = new AboutCodeBarChart('#tab-barchart', aboutCodeDB) .on('bar-clicked', (attribute, value) => { // Show files that contain attribute value selected by user in bar chart - cluesTable.clearColumnFilters(); + scanDataTable.clearColumnFilters(); if (value !== 'No Value Detected') { - cluesTable.setColumnFilter(attribute, value); + scanDataTable.setColumnFilter(attribute, value); } else { - cluesTable.setColumnFilter(attribute, 'about_code_data_table_no_value_detected'); + scanDataTable.setColumnFilter(attribute, 'about_code_data_table_no_value_detected'); } - updateViewsByPath(cluesTable._selectedPath); + updateViewsByPath(scanDataTable._selectedPath); // This needs to be done only when the column is visible. // So we do it last to try our best - showClueButton.trigger('click'); + showScanDataButton.trigger('click'); }); - const cluesTable = new AboutCodeClueDataTable('#tab-clues', aboutCodeDB); + const scanDataTable = new AboutCodeScanDataDataTable('#tab-scandata', aboutCodeDB); const componentsTable = new AboutCodeComponentDataTable('#tab-component', aboutCodeDB) .on('upload-clicked', (components) => { @@ -97,13 +97,13 @@ $(document).ready(() => { }); $(document).on('click', '#activate-filters-button', () => { - cluesTable.genFilters(); - updateViewsByPath(cluesTable._selectedPath); + scanDataTable.genFilters(); + updateViewsByPath(scanDataTable._selectedPath); }); $(document).on('click', '#clear-filters-button', () => { - cluesTable.resetColumnFilters(); - updateViewsByPath(cluesTable._selectedPath); + scanDataTable.resetColumnFilters(); + updateViewsByPath(scanDataTable._selectedPath); }); const splitter = new Splitter('#leftCol', '#rightCol') @@ -115,7 +115,7 @@ $(document).ready(() => { // Defines DOM element constants for sidebar buttons. const saveSQLiteFileButton = $('#save-file'); const openSQLiteFileButton = $('#open-file'); - const showClueButton = $('#show-tab-clues'); + const showScanDataButton = $('#show-tab-scandata'); const showComponentButton = $('#show-tab-component'); const showBarChartButton = $('#show-tab-barchart'); const showDashboardButton = $('#show-tab-dashboard'); @@ -126,10 +126,10 @@ $(document).ready(() => { // Save a SQLite Database file saveSQLiteFileButton.click(saveSQLite); - // Show clue DataTable. Hide node view and component summary table - showClueButton.click(() => { + // Show ScanData DataTable. Hide node view and component summary table + showScanDataButton.click(() => { splitter.show(); - cluesTable.redraw(); + scanDataTable.redraw(); }); // Show component summary table. Hide DataTable and node view @@ -154,7 +154,7 @@ $(document).ready(() => { shell.openExternal(evt.target.href); }); - ipcRenderer.on('table-view', () => showClueButton.trigger('click')); + ipcRenderer.on('table-view', () => showScanDataButton.trigger('click')); ipcRenderer.on('component-summary-view', () => showComponentButton.trigger('click')); ipcRenderer.on('open-SQLite', () => openSQLiteFileButton.trigger('click')); ipcRenderer.on('chart-summary-view', () => showBarChartButton.trigger('click')); @@ -169,12 +169,12 @@ $(document).ready(() => { function updateViewsByPath(path) { // Update all the views with the given path string - cluesTable.columns(0).search(path); + scanDataTable.columns(0).search(path); componentDialog.selectedPath(path); dejaCodeExportDialog.selectedPath(path); jstree.selectedPath(path); - cluesTable.selectedPath(path); + scanDataTable.selectedPath(path); componentsTable.selectedPath(path); dashboard.selectedPath(path); barChart.selectedPath(path); @@ -230,13 +230,13 @@ $(document).ready(() => { .then(() => { const currFile = aboutCodeDB.sequelize.options.storage; document.title = 'AboutCode Manager - ' + path.basename(currFile); - cluesTable.clearColumnFilters(); + scanDataTable.clearColumnFilters(); // update all views with the new database. componentDialog.db(aboutCodeDB); dejaCodeExportDialog.db(aboutCodeDB); jstree.db(aboutCodeDB); - cluesTable.db(aboutCodeDB); + scanDataTable.db(aboutCodeDB); componentsTable.db(aboutCodeDB); dashboard.db(aboutCodeDB); barChart.db(aboutCodeDB); @@ -395,7 +395,7 @@ $(document).ready(() => { } }); - const clueFilesPromise = aboutCodeDB.findAll({ + const scanDataFilesPromise = aboutCodeDB.findAll({ attributes: { exclude: ['id', 'createdAt', 'updatedAt'] } @@ -414,15 +414,15 @@ $(document).ready(() => { }); Promise.all([scanCodeInfoPromise, aboutCodeInfoPromise, - filesCountPromise, clueFilesPromise, componentsPromise]) - .then(([scanCodeInfo, aboutCodeInfo, filesCount, clueFiles, components]) => { + filesCountPromise, scanDataFilesPromise, componentsPromise]) + .then(([scanCodeInfo, aboutCodeInfo, filesCount, scanDataFiles, components]) => { const json = { aboutcode_manager_notice: aboutCodeInfo.aboutcode_manager_notice, aboutcode_manager_version: aboutCodeInfo.aboutcode_manager_version, scancode_version: scanCodeInfo.scancode_version, scancode_options: scanCodeInfo.scancode_options, files_count: filesCount, - files: clueFiles, + files: scanDataFiles, components: components }; diff --git a/index.html b/index.html index 04954b8c..d3716d93 100644 --- a/index.html +++ b/index.html @@ -82,7 +82,7 @@
  • -
  • @@ -110,9 +110,9 @@
    - -
    - + +
    +