diff --git a/pom.xml b/pom.xml index 0fd04a27d9c..33bba9ed7d3 100644 --- a/pom.xml +++ b/pom.xml @@ -124,6 +124,10 @@ com.oracle.database.jdbc ojdbc11 21.20.0.0 + + + https://nexus-snapshots.xwiki.org/repository/npmhosted/ + https://registry.npmjs.org https://github.com/${xwiki.github.owner}/${xwiki.github.repository}/tree/master/ diff --git a/xwiki-platform-core/xwiki-platform-node/pom.xml b/xwiki-platform-core/xwiki-platform-node/pom.xml index c8e0688fad0..4c64e34caf3 100644 --- a/xwiki-platform-core/xwiki-platform-node/pom.xml +++ b/xwiki-platform-core/xwiki-platform-node/pom.xml @@ -118,6 +118,17 @@ ${basedir}/target + + deploy + + pnpm + + + run deploy -- ${xwiki.npm.snapshot.registry} ${xwiki.npm.release.registry} ${basedir}/src/main/node + ${basedir}/src/main/node + ${basedir}/target + + diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/api/package.json index 49c16bb2a6a..34d762091dd 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/attachments/attachments-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/attachments/attachments-api/package.json index d642c55b45a..e0d523e7f4e 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/attachments/attachments-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/attachments/attachments-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-attachments-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/attachments/attachments-default/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/attachments/attachments-default/package.json index f4e66e81f5c..8ab76b6b8c7 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/attachments/attachments-default/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/attachments/attachments-default/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-attachments-default", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/authentication/authentication-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/authentication/authentication-api/package.json index 6094eba336b..58b3a41cac4 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/authentication/authentication-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/authentication/authentication-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-authentication-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/backends/backend-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/backends/backend-api/package.json index 25e773a48b2..878681b51e1 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/backends/backend-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/backends/backend-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-backend-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/collaboration/collaboration-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/collaboration/collaboration-api/package.json index 4f2154b1061..98f9c8f9aaa 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/collaboration/collaboration-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/collaboration/collaboration-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-collaboration-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/configuration/configuration-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/configuration/configuration-api/package.json index 77d23dfe921..467b8e5febd 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/configuration/configuration-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/configuration/configuration-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-configuration-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/document/document-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/document/document-api/package.json index 01a2feda473..4a290888bde 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/document/document-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/document/document-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-document-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/fn-utils/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/fn-utils/package.json index a6e33dbafbc..b4b3d2614cb 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/fn-utils/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/fn-utils/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-fn-utils", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/icons/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/icons/package.json index ed05a8757f8..616d6464d5c 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/icons/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/icons/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-icons", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "description": "Provide UI components to display icons.", "license": "LGPL 2.1", "author": "XWiki Org Community ", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/link-suggest/link-suggest-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/link-suggest/link-suggest-api/package.json index e3cd7a408dc..0f65eed0fc9 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/link-suggest/link-suggest-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/link-suggest/link-suggest-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-link-suggest-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/macros/macros-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/macros/macros-api/package.json index 0fc70cb9e91..ee30559deab 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/macros/macros-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/macros/macros-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-macros-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/macros/macros-ast-react-jsx/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/macros/macros-ast-react-jsx/package.json index a472a603606..bb0d5563367 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/macros/macros-ast-react-jsx/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/macros/macros-ast-react-jsx/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-macros-ast-react-jsx", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/model/model-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/model/model-api/package.json index 021acf27561..b239124248e 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/model/model-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/model/model-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-model-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/model/model-reference/model-reference-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/model/model-reference/model-reference-api/package.json index ea7388f897e..f6be1e4b3ea 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/model/model-reference/model-reference-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/model/model-reference/model-reference-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-model-reference-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/model/model-remote-url/model-remote-url-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/model/model-remote-url/model-remote-url-api/package.json index c70709614a1..db755d021fa 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/model/model-remote-url/model-remote-url-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/model/model-remote-url/model-remote-url-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-model-remote-url-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/navigation-tree/navigation-tree-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/navigation-tree/navigation-tree-api/package.json index 1821473f4e8..80b7ead7ae2 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/navigation-tree/navigation-tree-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/navigation-tree/navigation-tree-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-navigation-tree-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/uniast/uniast-api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/uniast/uniast-api/package.json index b01efaf4681..4ef5622b930 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/uniast/uniast-api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/uniast/uniast-api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-uniast-api", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/uniast/uniast-markdown/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/uniast/uniast-markdown/package.json index dc3b463ff9a..e711a3196a6 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/core/uniast/uniast-markdown/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/core/uniast/uniast-markdown/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-uniast-markdown", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/ds/api/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/ds/api/package.json index 229c3e849e7..eefc034485b 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/ds/api/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/ds/api/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-dsapi", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/editors/blocknote-headless/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/editors/blocknote-headless/package.json index 42c418e9bfc..87061a12093 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/editors/blocknote-headless/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/editors/blocknote-headless/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-editors-blocknote-headless", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/editors/blocknote-react/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/editors/blocknote-react/package.json index 13e61196446..7b7d8324666 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/editors/blocknote-react/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/editors/blocknote-react/package.json @@ -1,6 +1,6 @@ { "name": "@xwiki/platform-editors-blocknote-react", - "version": "17.10.0", + "version": "18.0.0-SNAPSHOT", "license": "LGPL 2.1", "author": "XWiki Org Community ", "homepage": "https://xwiki.org/", diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/package.json b/xwiki-platform-core/xwiki-platform-node/src/main/node/package.json index 760076912df..754522e3368 100644 --- a/xwiki-platform-core/xwiki-platform-node/src/main/node/package.json +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/package.json @@ -4,6 +4,7 @@ "type": "module", "scripts": { "build": "nx run-many -t build -p \"xwiki-platform-core/xwiki-platform-node/src/main/node/*/**\"", + "deploy": "node scripts/deploy.js", "lint": "nx run-many -t lint -p \"xwiki-platform-core/xwiki-platform-node/src/main/node/*/**\"", "test:unit": "nx run-many -t test -p \"xwiki-platform-core/xwiki-platform-node/src/main/node/*/**\"" }, diff --git a/xwiki-platform-core/xwiki-platform-node/src/main/node/scripts/deploy.js b/xwiki-platform-core/xwiki-platform-node/src/main/node/scripts/deploy.js new file mode 100644 index 00000000000..32251186f75 --- /dev/null +++ b/xwiki-platform-core/xwiki-platform-node/src/main/node/scripts/deploy.js @@ -0,0 +1,189 @@ +#!/usr/bin/env node + +/* + * See the LICENSE file distributed with this work for additional + * information regarding copyright ownership. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ + +import fs from 'fs'; +import {execSync} from 'child_process'; +import path from 'path'; + +/** + * Script to conditionally publish npm packages based on version type (SNAPSHOT vs release) + * Step 1: Updates all package.json files with the same timestamp + * Step 2: Uses pnpm -r publish to publish all packages + * Usage: node publish-package.js [base-directory] + */ + +// Read command line arguments +const snapshotRegistry = process.argv[2]; +const releaseRegistry = process.argv[3]; +const baseDirectory = process.argv[4] || process.cwd(); + +if (!snapshotRegistry || !releaseRegistry) { + console.error('Error: Missing required arguments'); + console.error('Usage: node publish-package.js [base-directory]'); + process.exit(1); +} + +/** + * Recursively find all package.json files in subdirectories + * @param {string} dir - Directory to search + * @param {string[]} fileList - Accumulated list of package.json paths + * @returns {string[]} - Array of package.json file paths + */ +function findPackageJsonFiles(dir, fileList = []) { + const files = fs.readdirSync(dir); + + files.forEach(file => { + const filePath = path.join(dir, file); + const stat = fs.statSync(filePath); + + if (stat.isDirectory()) { + // Skip node_modules and hidden directories + if (file !== 'node_modules' && !file.startsWith('.')) { + findPackageJsonFiles(filePath, fileList); + } + } else if (file === 'package.json') { + fileList.push(filePath); + } + }); + + return fileList; +} + +/** + * Update version in a package.json file + * @param {string} packageJsonPath - Path to package.json + * @param {Object} packageJson - Parsed package.json content + * @param {string} timestamp - Timestamp to replace SNAPSHOT with + * @returns {Object} - {success, originalVersion, newVersion, packageName, isSnapshot} + */ +function updatePackageVersion(packageJsonPath, packageJson, timestamp) { + const originalVersion = packageJson.version; + const packageName = packageJson.name; + const isSnapshot = originalVersion.includes('SNAPSHOT'); + + if (isSnapshot) { + // Replace SNAPSHOT with timestamp + const newVersion = originalVersion.replace('SNAPSHOT', timestamp); + packageJson.version = newVersion; + + try { + fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n'); + return { success: true, originalVersion, newVersion, packageName, isSnapshot: true }; + } catch (error) { + return { success: false }; + } + } else { + return { success: true, originalVersion, newVersion: originalVersion, packageName, isSnapshot: false }; + } +} + +/** + * Restore original versions in all package.json files + * @param {Array} updates - Array of update results + */ +function restoreVersions(updates) { + updates.forEach(update => { + if (update.success && update.isSnapshot && update.path) { + try { + const packageJson = JSON.parse(fs.readFileSync(update.path, 'utf8')); + packageJson.version = update.originalVersion; + fs.writeFileSync(update.path, JSON.stringify(packageJson, null, 2) + '\n'); + } catch (error) { + console.error(`Error restoring ${update.path}: ${error.message}`); + } + } + }); +} + +// Main execution +const packageJsonFiles = findPackageJsonFiles(baseDirectory); + +if (packageJsonFiles.length === 0) { + process.exit(1); +} + +// Generate a common timestamp for all packages. +const timestamp = Math.floor(Date.now() / 1000).toString(); + +// Determine if we're dealing with SNAPSHOT or release versions +// Check the first package.json to determine the mode +let isSnapshotMode = false; +try { + // Look for the first package.json file with a version. + const firstVersion = packageJsonFiles.map(packageJsonPath => JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'))) + .filter(packageJson => packageJson.version) + .map(packageJson => packageJson.version)[0]; + isSnapshotMode = firstVersion.includes('SNAPSHOT'); +} catch (error) { + console.error('Error determining version mode'); + process.exit(1); +} + +// Step 1: Update all package.json versions +const updates = packageJsonFiles + .map(packageJsonPath => { + let packageJson; + + try { + packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); + } catch (error) { + console.error(`Error reading ${packageJsonPath}: ${error.message}`); + return {success: false}; + } + + return {packageJsonPath, packageJson, success: true} + }) + .filter(({packageJsonPath, packageJson, success}) => success && packageJson.version) + .map(({packageJsonPath, packageJson}) => { + const result = updatePackageVersion(packageJsonPath, packageJson, timestamp); + return {...result, path: packageJsonPath}; +}); + +const failedUpdates = updates.filter(u => !u.success); +if (failedUpdates.length > 0) { + console.error(`Failed to update ${failedUpdates.length} package(s)`); + console.error('summary', updates); + process.exit(1); +} + +try { + if (isSnapshotMode) { + execSync( + `pnpm -r publish --registry ${snapshotRegistry} --tag snapshot --no-git-checks`, + { stdio: 'inherit', cwd: baseDirectory } + ); + } else { + execSync( + `pnpm -r publish --registry ${releaseRegistry} --access public`, + { stdio: 'inherit', cwd: baseDirectory } + ); + } +} catch (error) { + console.error('Error during publication', error.message); + process.exit(1); +} finally { + // Restore versions before exiting + if (isSnapshotMode) { + restoreVersions(updates); + } +} +