{"id":18554258,"url":"https://github.com/oracle/coherence","last_synced_at":"2025-12-24T09:36:05.980Z","repository":{"id":37212469,"uuid":"242776849","full_name":"oracle/coherence","owner":"oracle","description":"Oracle Coherence Community Edition","archived":false,"fork":false,"pushed_at":"2025-05-09T23:25:10.000Z","size":577703,"stargazers_count":447,"open_issues_count":7,"forks_count":73,"subscribers_count":31,"default_branch":"main","last_synced_at":"2025-05-09T23:26:45.550Z","etag":null,"topics":["caching","cloud","clustering","coherence","data-grid","distributed","hpc","imdg","in-memory","java","kv-store","microservices","polyglot","scalability"],"latest_commit_sha":null,"homepage":"https://coherence.community","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"upl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oracle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-02-24T15:51:04.000Z","updated_at":"2025-05-09T22:42:48.000Z","dependencies_parsed_at":"2023-10-11T16:27:53.022Z","dependency_job_id":"74ca8938-38c4-493a-b43c-e45ff0692eb8","html_url":"https://github.com/oracle/coherence","commit_stats":{"total_commits":3001,"total_committers":21,"mean_commits":142.9047619047619,"dds":0.7097634121959346,"last_synced_commit":"b7c1ab82c2a62d4b494335b2c900801be0fea644"},"previous_names":[],"tags_count":99,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oracle%2Fcoherence","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oracle%2Fcoherence/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oracle%2Fcoherence/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oracle%2Fcoherence/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oracle","download_url":"https://codeload.github.com/oracle/coherence/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254254042,"owners_count":22039792,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["caching","cloud","clustering","coherence","data-grid","distributed","hpc","imdg","in-memory","java","kv-store","microservices","polyglot","scalability"],"created_at":"2024-11-06T21:20:41.713Z","updated_at":"2025-12-24T09:36:05.919Z","avatar_url":"https://github.com/oracle.png","language":"Java","readme":"\u003c!--\n  Copyright (c) 2000, 2024, Oracle and/or its affiliates.\n\n  Licensed under the Universal Permissive License v 1.0 as shown at\n  https://oss.oracle.com/licenses/upl.\n--\u003e\n\n-----\n\u003cimg src=https://oracle.github.io/coherence/assets/images/logo-red.png\u003e\u003cimg\u003e\n\n[![CI Build](https://github.com/oracle/coherence/workflows/CI%20Build/badge.svg?branch=main)](https://github.com/oracle/coherence/actions?query=workflow%3A%22CI+Build%22+branch%3Amain)\n[![Maven Central](https://img.shields.io/maven-central/v/com.oracle.coherence.ce/coherence.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22com.oracle.coherence.ce%22)\n[![License](http://img.shields.io/badge/license-UPL%201.0-blue.svg)](https://oss.oracle.com/licenses/upl/)\n\n# Oracle Coherence Community Edition\n\n## Contents\n1. [Introduction](#introduction)\n1. [Downloading Coherence Community Edition](#acquire)\n1. [Coherence Overview](#overview)\n1. [Getting Started](#getting-started)\n   1. [Install the Coherence CLI](#install)\n   1. [Create a Cluster](#create)\n   1. [CohQL Console](#cohql)\n   1. [Coherence Console](#coh-console)\n   1. [Code Example](#hello-coh)\n1. [Building](#build)\n1. [Documentation](#documentation)\n1. [Examples](#examples)\n1. [Contributing](#contributing)\n1. [License](#license)\n\n## Introduction\n\n[Coherence](http://coherence.community/) is a scalable, fault-tolerant, cloud-ready,\ndistributed platform for building grid-based applications and reliably storing data.\nThe product is used at scale, for both compute and raw storage, in a vast array of\nindustries such as critical financial trading systems, high performance telecommunication\nproducts and eCommerce applications.\n\nTypically these deployments do not tolerate any downtime and Coherence is chosen due to its\nnovel features in death detection, application data evolvability, and the robust,\nbattle-hardened core of the product that enables it to be seamlessly deployed and\nadapted within any ecosystem.\n\nAt a high level, Coherence provides an implementation of the familiar `Map\u003cK,V\u003e`\ninterface but rather than storing the associated data in the local process it is partitioned\n(or sharded) across a number of designated remote nodes. This partitioning enables\napplications to not only distribute (and therefore scale) their storage across multiple\nprocesses, machines, racks, and data centers but also to perform grid-based processing\nto truly harness the CPU resources of the machines.\n\nThe Coherence interface `NamedMap\u003cK,V\u003e` (an extension of `Map\u003cK,V\u003e`) provides methods\nto query, aggregate (map/reduce style) and compute (send functions to storage nodes\nfor locally executed mutations) the data set. These capabilities, in addition to\nnumerous other features, enable Coherence to be used as a framework for writing robust,\ndistributed applications.\n\n## \u003ca name=\"acquire\"\u003e\u003c/a\u003eDownloading Coherence Community Edition\n\nAs Coherence is generally embedded into an application by using Coherence APIs,\nthe natural place to consume this dependency is from Maven:\n\n```xml\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.oracle.coherence.ce\u003c/groupId\u003e\n        \u003cartifactId\u003ecoherence\u003c/artifactId\u003e\n        \u003cversion\u003e22.06.10\u003c/version\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\nYou can also get Coherence container images from the official [GitHub Packages site](https://github.com/oracle/coherence/pkgs/container/coherence-ce).\nFor other language clients, follow the links to [C++](https://github.com/oracle/coherence-cpp-extend-client), [.NET](https://github.com/oracle/coherence-dotnet-extend-client), [JavaScript](https://github.com/oracle/coherence-js-client), [Go](https://github.com/oracle/coherence-go-client) and [Python](https://github.com/oracle/coherence-py-client). For commercial offerings, go to [Oracle Technology Network](https://www.oracle.com/middleware/technologies/coherence-downloads.html).\n\n## \u003ca name=\"overview\"\u003e\u003c/a\u003eOverview\n\nFirst and foremost, Coherence provides a fundamental service that is responsible\nfor all facets of clustering and is a common denominator / building block for all\nother Coherence services. This service, referred to as 'service 0' internally,\nensures that the mesh of members is maintained and responsive, taking action to collaboratively\nevict, shun, or in some cases, voluntarily depart the cluster when deemed necessary.\nAs members join and leave the cluster, other Coherence services are notified,\nthus enabling those services to react accordingly.\n\n\u003e Note: This part of the Coherence product has been in production for more that 10 years,\n\u003e       being the subject of some extensive and imaginative testing. While this feature has\n\u003e       been discussed here, it certainly is not something that customers, generally,\n\u003e       interact with directly, but is important to be aware of.\n\nCoherence services build on top of the cluster service. The key implementations\nto be aware of are PartitionedService, InvocationService, and ProxyService.\n\nIn the majority of cases, customers deal with maps. A map is represented\nby an implementation of `NamedMap\u003cK,V\u003e`. A `NamedMap` is hosted by a service,\ngenerally the PartitionedService, and is the entry point to store, retrieve,\naggregate, query, and stream data.\n\nCoherence Maps provide a number of features:\n\n* Fundamental **key-based access**: get/put getAll/putAll.\n* Client-side and storage-side events:\n    * **MapListeners** to asynchronously notify clients of changes to data.\n    * **EventInterceptors** (either sync or async) to be notified storage level events, including\nmutations, partition transfer, failover, and so on.\n* **NearCaches** - Locally cached data based on previous requests with local content\ninvalidated upon changes in the storage tier.\n* **ViewCaches** - Locally stored view of remote data that can be a subset based on a\npredicate and is kept in sync, real time.\n* **Queries** - Distributed, parallel query evaluation to return matching key, values,\nor entries with potential to optimize performance with indices.\n* **Aggregations** - A map/reduce style aggregation where data is aggregated in parallel\non all storage nodes, and results streamed back to the client for aggregation of\nthose results to produce a final result.\n* **Data local processing** - Ability to send a function to the relevant storage node\nto execute processing logic for the appropriate entries with exclusive access.\n* **Partition local transactions** - Ability to perform scalable transactions by\nassociating data (thus being on the same partition) and manipulating other entries\non the same partition, potentially across different maps.\n* **Non-blocking / async NamedMap API**\n* **Polyglot clients** - Access the same NamedMap API from [C++](https://github.com/oracle/coherence-cpp-extend-client), [Go](https://github.com/oracle/coherence-go-client), Java, [JavaScript](https://github.com/oracle/coherence-js-client), [.NET](https://github.com/oracle/coherence-dotnet-extend-client), or [Python](https://github.com/oracle/coherence-py-client)\n* **Portable Object Format** - Optimized serialization format, with the ability to\nnavigate the serialized form for optimized queries, aggregations, or data processing.\n* **Integration with Databases** - Database and third party data integration with\nCacheStores, including both synchronous or asynchronous writes.\n* **CohQL** - Ansi-style query language with a console for adhoc queries.\n* **Topics** - Distributed topics implementation that offers pub/sub messaging with\nthe storage capacity, the cluster, and parallelizable subscribers.\n* **Repository API** - a framework implementing the Repository pattern from Domain-Driven Design,\nabstracting persistent storage implementation from application code, with advanced features like\nsupport for pagination, projections, streaming, and updating in-place\n* **coherence-concurrent** - Coherence-backed implementations of types from the `java.util.concurrent` package enabling distributed process coordination through the grid\n    * **Atomics** - for implementing e.g. atomic counters shared between cluster, with an optional asynchronous API\n    * **Executors** - for submitting tasks to be executed in the cluster\n    * **Locks** - for implementing lock-based concurrency control across multiple cluster members\n    * **Queues** - for implementing blocking queue / dequeue behavior across multiple cluster members\n    * **Semaphores** - for implementing synchronization of execution across multiple cluster members\n* **Microservices integration** - broad and close integration with [Helidon](https://docs.oracle.com/en/middleware/standalone/coherence/14.1.2/integrate/index.html), [Micronaut](https://micronaut-projects.github.io/micronaut-coherence/latest/guide/), and [Spring](https://spring.coherence.community/4.3.0/#/about/01_overview) for developing microservices applications using Coherence as a data source or cache\n\nCoherence also provides a number of non-functional features:\n\n* **Rock solid clustering** - Highly tuned and robust clustering stack that enables\nCoherence to scale to thousands of members in a cluster with thousands of partitions\nand terabytes of data being accessed, mutated, queried, and aggregated concurrently.\n* **Safety first** - Resilient data management that ensures backup copies are\non distinct machines, racks, or sites, and the ability to maintain multiple backups.\n* **24/7 Availability** - Zero downtime with rolling redeployment of cluster members\nto upgrade application or product versions.\n  * Backward and forward compatibility of product upgrades, including major versions.\n* **Persistent Maps** - Ability to use local file system persistence (thus\navoid extra network hops) and leverage Coherence consensus protocols to perform\ndistributed disk recovery when appropriate.\n* **Distributed State Snapshot** - Ability to perform distributed point-in-time\nsnapshot of cluster state, and recover snapshot in this or a different cluster\n(leverages persistence feature).\n* **Lossy redundancy** - Ability to reduce the redundancy guarantee by making backups\nand/or persistence asynchronous from a client perspective.\n* **Single Mangement View** - Provides insight into the cluster  with a single\nJMX server that provides a view of all members of the cluster.\n* **Management over REST** - All JMX data and operations can be performed over REST,\nincluding cluster wide thread dumps and heapdumps.\n* **Non-cluster Access** - Provides access to the cluster from the outside via proxies,\nfor distant (high latency) clients and for non-Java languages such as [C++](https://github.com/oracle/coherence-cpp-extend-client), [Go](https://github.com/oracle/coherence-go-client), [JavaScript](https://github.com/oracle/coherence-js-client), [.NET](https://github.com/oracle/coherence-dotnet-extend-client), and [Python](https://github.com/oracle/coherence-py-client).\n* **Kubernetes friendly** - Enables seamless and safe deployment of applications to k8s with\nour own [operator](https://github.com/oracle/coherence-operator).\n\n## Getting Started\n\n### Prerequisites\n\nYou must have the following installed and available on your PATH.\n\n  1. Java - JDK 17 or higher\n  2. Maven - 3.8.5 or higher\n  3. Cohrence CLI Installed (see below)\n\nThe following example shows you how to quickly get started with Coherence using the\n[Coherence CLI](https://github.com/oracle/coherence-cli) to create a 3 node Coherence cluster scoped to you local machine.\nYou will then access data using the CohQL and Coherence consoles.\n\n#### \u003ca name=\"install\"\u003e\u003c/a\u003e Install the Coherence CLI\n\nFor **macOS or Linux** platforms, use the following to install the latest version of the CLI:\n\n```bash\ncurl -sL https://raw.githubusercontent.com/oracle/coherence-cli/main/scripts/install.sh | bash\n```\n\n\u003e When you install the CLI, administrative privileges are required as the `cohctl` executable is moved to the /usr/local/bin directory.\n\nFor **Windows**, see [here](https://oracle.github.io/coherence-cli/docs/latest/#/docs/installation/01_installation) for installation guide.\n\n\n#### \u003ca name=\"create\"\u003e\u003c/a\u003eCreate and start a Cluster\n\nUse the following command to create a 3 node Coherence cluster called `my-cluster`, scoped to your local machine using the default values.\n\n```shell\n$ cohctl create cluster my-cluster\n\nCluster name:         my-cluster\nCluster version:      22.06.10\nCluster port:         7574\nManagement port:      30000\nReplica count:        3\nInitial memory:       128m\nPersistence mode:     on-demand\nGroup ID:             com.oracle.coherence.ce\nAdditional artifacts:\nStartup Profile:      \nDependency Tool:      mvn\nAre you sure you want to create the cluster with the above details? (y/n) y\n\nChecking 3 Maven dependencies...\n- com.oracle.coherence.ce:coherence:22.06.10\n- com.oracle.coherence.ce:coherence-json:22.06.10\n- org.jline:jline:3.26.3\nStarting 3 cluster members for cluster my-cluster\nStarting cluster member storage-0...\nStarting cluster member storage-1...\nStarting cluster member storage-2...\nCurrent context is now my-cluster\nCluster added and started\n```\n\n\u003e Note: If you do not have the Maven artefacts locally, it may take a short while to download them from Maven central.\n\nOnce the cluster is created, wait it a couple of seconds, and use the following command to see the members.\n\n```shell\n$ cohctl get members\n\nUsing cluster connection 'my-cluster' from current context.\n\nTotal cluster members: 3\nCluster Heap - Total: 384 MB Used: 114 MB Available: 270 MB (70.3%)\nStorage Heap - Total: 128 MB Used: 16 MB Available: 112 MB (87.5%)\n\nNODE ID  ADDRESS     PORT   PROCESS  MEMBER     ROLE             STORAGE  MAX HEAP  USED HEAP  AVAIL HEAP\n      1  /127.0.0.1  55654    58270  storage-1  CoherenceServer  true       128 MB      16 MB      112 MB\n      2  /127.0.0.1  55655    58271  storage-2  CoherenceServer  true       128 MB      74 MB       54 MB\n      3  /127.0.0.1  55656    58269  storage-0  CoherenceServer  true       128 MB      24 MB      104 MB\n```\n\nNote: If you do not see the above, then ensure the `java` executable is on your PATH, you are using JDK17, and then issue `cohctl start cluster my-cluster` to start the cluster.\n\n#### \u003ca name=\"cohql\"\u003e\u003c/a\u003eCohQL Console\n\nStart the CohQL Console using the CLI, and run the statements at the `CohQL\u003e` prompt to insert data into your cache.\n\n```shell\n$ cohctl start cohql\n\nCohQL\u003e select * from welcomes\n\nCohQL\u003e insert into welcomes key 'english' value 'Hello'\n\nCohQL\u003e insert into welcomes key 'spanish' value 'Hola'\n\nCohQL\u003e insert into welcomes key 'french' value 'Bonjour'\n\nCohQL\u003e select key(), value() from welcomes\nResults\n[\"french\", \"Bonjour\"]\n[\"english\", \"Hello\"]\n[\"spanish\", \"Hola\"]\n\nCohQL\u003e bye\n\n# Restart to CohQL to show that the data is still present in the Coherence cluster.\n\n$ cohctl start cohql\n\nCohQL\u003e select key(), value() from welcomes\nResults\n[\"french\", \"Bonjour\"]\n[\"english\", \"Hello\"]\n[\"spanish\", \"Hola\"]\n\nCohQL\u003e bye\n```\n\n#### \u003ca name=\"coh-console\"\u003e\u003c/a\u003eCoherence Console\n\nUse the following command to start the Coherence console, which is a different way to interact with the data in a Cache.\n\n```shell\n$ cohctl start console\n\nMap (?): cache welcomes\n\nMap (welcomes): get english\nHello\n\nMap (welcomes): list\nfrench = Bonjour\nspanish = Hola\nenglish = Hello\n\nMap (welcomes): put australian Gudday\nnull\n\nMap (welcomes): list\nspanish = Hola\nenglish = Hello\naustralian = Gudday\nfrench = Bonjour\n\nMap (welcomes): bye\n```\n\n#### Shutdown your Cluster\n\n**Note**: Ensure you shutdown your Coherence cluster using the following:\n\n```#!/usr/bin/env bash\ncohctl stop cluster my-cluster\n```\n\n### \u003ca name=\"hello-coh\"\u003e\u003c/a\u003eProgrammatic Hello Coherence Example\n\nThe following example illustrates starting a **storage enabled** Coherence server,\nfollowed by running the `HelloCoherence` application. The `HelloCoherence` application\ninserts and retrieves data from the Coherence server.\n\n#### Build `HelloCoherence`\n\n1. Create a maven project either manually or by using an archetype such as maven-archetype-quickstart\n2. Add a dependency to the pom file:\n```xml\n    \u003cdependency\u003e\n        \u003cgroupId\u003ecom.oracle.coherence.ce\u003c/groupId\u003e\n        \u003cartifactId\u003ecoherence\u003c/artifactId\u003e\n        \u003cversion\u003e22.06.10\u003c/version\u003e\n    \u003c/dependency\u003e\n```\n3. Copy and paste the following source to a file named src/main/java/HelloCoherence.java:\n```java\n    import com.tangosol.net.CacheFactory;\n    import com.tangosol.net.NamedMap;\n\n    public class HelloCoherence\n        {\n        // ----- static methods -------------------------------------------------\n\n        public static void main(String[] asArgs)\n            {\n            NamedMap\u003cString, String\u003e map = CacheFactory.getCache(\"welcomes\");\n\n            System.out.printf(\"Accessing map \\\"%s\\\" containing %d entries\\n\",\n                    map.getName(),\n                    map.size());\n\n            map.put(\"english\", \"Hello\");\n            map.put(\"spanish\", \"Hola\");\n            map.put(\"french\" , \"Bonjour\");\n\n            // list\n            map.entrySet().forEach(System.out::println);\n            }\n        }\n```\n4. Compile the maven project:\n```shell\n    mvn package\n```\n5. Start a Storage Server\n```shell\n    mvn exec:java -Dexec.mainClass=\"com.tangosol.net.DefaultCacheServer\" \u0026\n```\n6. Run `HelloCoherence`\n```shell\n    mvn exec:java -Dexec.mainClass=\"HelloCoherence\"\n```\n7. Confirm you see output including the following:\n```shell\n    Accessing map \"welcomes\" containing 3 entries\n    ConverterEntry{Key=\"french\", Value=\"Bonjour\"}\n    ConverterEntry{Key=\"spanish\", Value=\"Hola\"}\n    ConverterEntry{Key=\"english\", Value=\"Hello\"}\n```\n8. Kill the storage server started previously:\n```shell\n    kill %1\n```\n\n## \u003ca name=\"build\"\u003e\u003c/a\u003eBuilding\n\n```shell\n\n$\u003e git clone git@github.com:oracle/coherence.git\n$\u003e cd coherence/prj\n\n# build Coherence module\n$\u003e mvn clean install\n\n# build Coherence module skipping tests\n$\u003e mvn clean install -DskipTests\n\n# build all other modules skipping tests\n$\u003e mvn -Pmodules clean install -DskipTests\n\n# build specific module, including all dependent modules and run tests\n$\u003e mvn -Pmodules -am -pl test/functional/persistence clean verify\n\n# only build coherence.jar without running tests\n$\u003e mvn -am -pl coherence clean install -DskipTests\n\n# only build coherence.jar and skip compilation of CDBs and tests\n$\u003e mvn -am -pl coherence clean install -DskipTests -Dtde.compile.not.required\n```\n\n## \u003ca name=\"documentation\"\u003e\u003c/a\u003eDocumentation\n\n### Oracle Coherence Documentation\n\nOracle Coherence product documentation is available\n[here](https://docs.oracle.com/en/middleware/standalone/coherence/14.1.1.2206/index.html).\n\n### Features Not Included in Coherence Community Edition\n\nThe following Oracle Coherence features are not included in Coherence Community Edition:\n\n* Management of Coherence via the Oracle WebLogic Management Framework\n* Deployment of Grid Archives (GARs)\n* HTTP Session Management for Application Servers (Coherence*Web)\n* GoldenGate HotCache\n* TopLink-based CacheLoaders and CacheStores\n* Elastic Data\n* Federation and WAN (wide area network) Support\n* Transaction Framework\n* CommonJ Work Manager\n\nBelow is an overview of features supported in each Coherence edition for comparison purposes:\n\n\u003cimg src=https://oracle.github.io/coherence/assets/images/coherence-edition-matrix.png\u003e\u003cimg\u003e\n\nPlease refer to \u003ca href=\"https://docs.oracle.com/en/middleware/fusion-middleware/fmwlc/application-server-products-new-structure.html#GUID-00982997-3110-4AC8-8729-80F1D904E62B\"\u003eOracle Fusion Middleware Licensing Documentation\u003c/a\u003e for official documentation of Oracle Coherence commercial editions and licensing details.\n\n## Examples\n\nExamples related to Coherence features are located under [examples](./prj/examples) directory of this repository.\n\n## Contributing\n\nThis project welcomes contributions from the community. Before submitting a pull request, please [review our contribution guide](./CONTRIBUTING.md)\n\n## Security\n\nPlease consult the [security guide](./SECURITY.md) for our responsible security vulnerability disclosure process\n\n## License\n\nCopyright (c) 2000, 2024 Oracle and/or its affiliates.\n\nReleased under the Universal Permissive License v1.0 as shown at\n\u003chttps://oss.oracle.com/licenses/upl/\u003e.\n","funding_links":[],"categories":["数据库"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foracle%2Fcoherence","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foracle%2Fcoherence","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foracle%2Fcoherence/lists"}