diff --git a/api/v1/orcid/index.php b/api/v1/orcid/index.php
new file mode 100644
index 00000000000..9e3bc82e2d3
--- /dev/null
+++ b/api/v1/orcid/index.php
@@ -0,0 +1,20 @@
+data = $this->buildOrcidReview();
+ }
+
+ public function toArray(): array
+ {
+ return $this->data;
+ }
+
+ private function buildOrcidReview(): array
+ {
+ $publicationUrl = Application::get()->getDispatcher()->url(
+ Application::get()->getRequest(),
+ Application::ROUTE_PAGE,
+ $this->context->getPath(),
+ 'article',
+ 'view',
+ $this->submission->getId(),
+ urlLocaleForPage: '',
+ );
+
+ $submissionLocale = $this->submission->getData('locale');
+ $currentPublication = $this->submission->getCurrentPublication();
+
+ if (!empty($this->review->getData('dateCompleted')) && $this->context->getData('onlineIssn')) {
+ $reviewCompletionDate = Carbon::parse($this->review->getData('dateCompleted'));
+
+ $orcidReview = [
+ 'reviewer-role' => 'reviewer',
+ 'review-type' => 'review',
+ 'review-completion-date' => [
+ 'year' => [
+ 'value' => $reviewCompletionDate->format('Y')
+ ],
+ 'month' => [
+ 'value' => $reviewCompletionDate->format('m')
+ ],
+ 'day' => [
+ 'value' => $reviewCompletionDate->format('d')
+ ]
+ ],
+ 'review-group-id' => 'issn:' . $this->context->getData('onlineIssn'),
+
+ 'convening-organization' => [
+ 'name' => $this->context->getData('publisherInstitution'),
+ 'address' => [
+ 'city' => OrcidManager::getCity($this->context),
+ 'country' => OrcidManager::getCountry($this->context),
+
+ ]
+ ],
+ 'review-identifiers' => ['external-id' => [
+ [
+ 'external-id-type' => 'source-work-id',
+ 'external-id-value' => $this->review->getData('reviewRoundId'),
+ 'external-id-relationship' => 'part-of']
+ ]]
+ ];
+ if ($this->review->getReviewMethod() == ReviewAssignment::SUBMISSION_REVIEW_METHOD_OPEN) {
+ $orcidReview['subject-url'] = ['value' => $publicationUrl];
+ $orcidReview['review-url'] = ['value' => $publicationUrl];
+ $orcidReview['subject-type'] = 'journal-article';
+ $orcidReview['subject-name'] = [
+ 'title' => ['value' => $this->submission->getCurrentPublication()->getLocalizedData('title') ?? '']
+ ];
+
+ if (!empty($currentPublication->getDoi())) {
+ /** @var Doi $doiObject */
+ $doiObject = $currentPublication->getData('doiObject');
+ $externalIds = [
+ 'external-id-type' => 'doi',
+ 'external-id-value' => $currentPublication->getDoi(),
+ 'external-id-url' => [
+ 'value' => $doiObject->getResolvingUrl(),
+ ],
+ 'external-id-relationship' => 'self'
+
+ ];
+ $orcidReview['subject-external-identifier'] = $externalIds;
+ }
+ }
+
+ $allTitles = $currentPublication->getData('title');
+ foreach ($allTitles as $locale => $title) {
+ if ($locale !== $submissionLocale) {
+ $orcidReview['subject-name']['translated-title'] = ['value' => $title, 'language-code' => LocaleConversion::getIso1FromLocale($locale)];
+ }
+ }
+
+ return $orcidReview;
+ } else {
+ // TODO: Check how this should be handled.
+ // It seems like this should be blocked earlier rather than letting it get to this point.
+ return [];
+ }
+ }
+}
diff --git a/classes/orcid/OrcidWork.php b/classes/orcid/OrcidWork.php
new file mode 100644
index 00000000000..accc2cdbeca
--- /dev/null
+++ b/classes/orcid/OrcidWork.php
@@ -0,0 +1,307 @@
+ 'doi', 'other::urn' => 'urn'];
+ public const USER_GROUP_TO_ORCID_ROLE = ['Author' => 'AUTHOR', 'Translator' => 'CHAIR_OR_TRANSLATOR', 'Journal manager' => 'AUTHOR'];
+
+ private array $data = [];
+
+ public function __construct(
+ private Publication $publication,
+ private Context $context,
+ private array $authors,
+ private ?Issue $issue = null
+ ) {
+ $this->data = $this->build();
+ }
+
+ public function toArray(): array
+ {
+ return $this->data;
+ }
+
+ private function build(): array
+ {
+ $submission = Repo::submission()->get($this->publication->getData('submissionId'));
+
+ $applicationName = Application::get()->getName();
+ $bibtexCitation = '';
+
+ $publicationLocale = $this->publication->getData('locale');
+
+ $publicationUrl = Application::get()->getDispatcher()->url(
+ Application::get()->getRequest(),
+ Application::ROUTE_PAGE,
+ $this->context->getPath(),
+ 'article',
+ 'view',
+ $submission->getId(),
+ urlLocaleForPage: '',
+ );
+
+ $orcidWork = [
+ 'title' => [
+ 'title' => [
+ 'value' => trim(strip_tags($this->publication->getLocalizedTitle($publicationLocale))) ?? ''
+ ],
+ 'subtitle' => [
+ 'value' => trim(strip_tags($this->publication->getLocalizedData('subtitle', $publicationLocale))) ?? ''
+ ]
+ ],
+ 'journal-title' => [
+ 'value' => $this->context->getName($publicationLocale) ?? $this->context->getName($this->context->getPrimaryLocale()),
+ ],
+ 'short-description' => trim(strip_tags($this->publication->getLocalizedData('abstract', $publicationLocale))) ?? '',
+
+ 'external-ids' => [
+ 'external-id' => $this->buildOrcidExternalIds($submission, $this->publication, $this->context, $this->issue, $publicationUrl)
+ ],
+ 'publication-date' => $this->buildOrcidPublicationDate($this->publication, $this->issue),
+ 'url' => $publicationUrl,
+ 'language-code' => LocaleConversion::getIso1FromLocale($publicationLocale),
+ 'contributors' => [
+ 'contributor' => $this->buildOrcidContributors($this->authors, $this->context, $this->publication)
+ ]
+ ];
+
+ if ($applicationName == 'ojs2') {
+ PluginRegistry::loadCategory('generic');
+ $citationPlugin = PluginRegistry::getPlugin('generic', 'citationstylelanguageplugin');
+ /** @var CitationStyleLanguagePlugin $citationPlugin */
+ $bibtexCitation = trim(strip_tags($citationPlugin->getCitation($this->request, $submission, 'bibtex', $this->issue, $this->publication)));
+ $orcidWork['citation'] = [
+ 'citation-type' => 'bibtex',
+ 'citation-value' => $bibtexCitation,
+ ];
+ $orcidWork['type'] = 'journal-article';
+ } elseif ($applicationName == 'ops') {
+ $orcidWork['type'] = 'preprint';
+ }
+
+ foreach ($this->publication->getData('title') as $locale => $title) {
+ if ($locale !== $publicationLocale) {
+ $orcidWork['title']['translated-title'] = ['value' => $title, 'language-code' => LocaleConversion::getIso1FromLocale($locale)];
+ }
+ }
+
+ return $orcidWork;
+ }
+
+ /**
+ * Build the external identifiers ORCID JSON structure from article, journal and issue meta data.
+ *
+ * @see https://pub.orcid.org/v2.0/identifiers Table of valid ORCID identifier types.
+ *
+ * @param Submission $submission The Article object for which the external identifiers should be build.
+ * @param Publication $publication The Article object for which the external identifiers should be build.
+ * @param Journal $context Context the Submission is part of.
+ * @param Issue $issue The Issue object the Article object belongs to.
+ *
+ * @return array An associative array corresponding to ORCID external-id JSON.
+ */
+ private function buildOrcidExternalIds(Submission $submission, Publication $publication, Context $context, Issue $issue, string $articleUrl): array
+ {
+ $contextId = $context->getId();
+
+ $externalIds = [];
+ $pubIdPlugins = PluginRegistry::loadCategory('pubIds', true, $contextId);
+ // Add doi, urn, etc. for article
+ $articleHasStoredPubId = false;
+
+ // Handle non-DOI pubIds
+ if (!empty($pubIdPlugins)) {
+ foreach ($pubIdPlugins as $plugin) {
+ if (!$plugin->getEnabled()) {
+ continue;
+ }
+
+ $pubIdType = $plugin->getPubIdType();
+
+ # Add article ids
+ $pubId = $publication->getStoredPubId($pubIdType);
+
+ if ($pubId) {
+ $externalIds[] = [
+ 'external-id-type' => self::PUBID_TO_ORCID_EXT_ID[$pubIdType],
+ 'external-id-value' => $pubId,
+ 'external-id-url' => [
+ 'value' => $plugin->getResolvingURL($contextId, $pubId)
+ ],
+ 'external-id-relationship' => 'self'
+ ];
+
+ $articleHasStoredPubId = true;
+ }
+
+ # Add issue ids if they exist
+ $pubId = $issue->getStoredPubId($pubIdType);
+ if ($pubId) {
+ $externalIds[] = [
+ 'external-id-type' => self::PUBID_TO_ORCID_EXT_ID[$pubIdType],
+ 'external-id-value' => $pubId,
+ 'external-id-url' => [
+ 'value' => $plugin->getResolvingURL($contextId, $pubId)
+ ],
+ 'external-id-relationship' => 'part-of'
+ ];
+ }
+ }
+ }
+
+ // Handle DOIs
+ if ($context->areDoisEnabled()) {
+ # Add article ids
+ $publicationDoiObject = $publication->getData('doiObject');
+
+ if ($publicationDoiObject) {
+ $externalIds[] = [
+ 'external-id-type' => self::PUBID_TO_ORCID_EXT_ID['doi'],
+ 'external-id-value' => $publicationDoiObject->getData('doi'),
+ 'external-id-url' => [
+ 'value' => $publicationDoiObject->getResolvingUrl()
+ ],
+ 'external-id-relationship' => 'self'
+ ];
+
+ $articleHasStoredPubId = true;
+ }
+
+ // Add issue ids if they exist
+ $issueDoiObject = $issue->getData('doiObject');
+ if ($issueDoiObject) {
+ $externalIds[] = [
+ 'external-id-type' => self::PUBID_TO_ORCID_EXT_ID['doi'],
+ 'external-id-value' => $issueDoiObject->getData('doi'),
+ 'external-id-url' => [
+ 'value' => $issueDoiObject->getResolvingUrl()
+ ],
+ 'external-id-relationship' => 'part-of'
+ ];
+ }
+ }
+
+ if (!$articleHasStoredPubId) {
+ // No pubidplugins available or article does not have any stored pubid
+ // Use URL as an external-id
+ $externalIds[] = [
+ 'external-id-type' => 'uri',
+ 'external-id-value' => $articleUrl,
+ 'external-id-relationship' => 'self'
+ ];
+ }
+
+ // Add journal online ISSN
+ // TODO What about print ISSN?
+ if ($context->getData('onlineIssn')) {
+ $externalIds[] = [
+ 'external-id-type' => 'issn',
+ 'external-id-value' => $context->getData('onlineIssn'),
+ 'external-id-relationship' => 'part-of'
+ ];
+ }
+
+ return $externalIds;
+ }
+
+ /**
+ * Parse issue year and publication date and use the older one of the two as
+ * the publication date of the ORCID work.
+ *
+ * @param null|mixed $issue
+ *
+ * @return array Associative array with year, month and day or only year
+ */
+ private function buildOrcidPublicationDate(Publication $publication, ?Issue $issue = null): array
+ {
+ $publicationPublishDate = Carbon::parse($publication->getData('datePublished'));
+
+ return [
+ 'year' => ['value' => $publicationPublishDate->format('Y')],
+ 'month' => ['value' => $publicationPublishDate->format('m')],
+ 'day' => ['value' => $publicationPublishDate->format('d')]
+ ];
+ }
+
+ /**
+ * Build associative array fitting for ORCID contributor mentions in an
+ * ORCID work from the supplied Authors array.
+ *
+ * @param Author[] $authors Array of Author objects
+ *
+ * @return array[] Array of associative arrays,
+ * one for each contributor
+ */
+ private function buildOrcidContributors(array $authors, Context $context, Publication $publication): array
+ {
+ $contributors = [];
+ $first = true;
+
+ foreach ($authors as $author) {
+ $contributor = [
+ 'credit-name' => $author->getFullName(),
+ 'contributor-attributes' => [
+ 'contributor-sequence' => $first ? 'first' : 'additional'
+ ]
+ ];
+
+ $userGroup = $author->getUserGroup();
+ $role = self::USER_GROUP_TO_ORCID_ROLE[$userGroup->getName('en')];
+
+ if ($role) {
+ $contributor['contributor-attributes']['contributor-role'] = $role;
+ }
+
+ if ($author->getOrcid()) {
+ $orcid = basename(parse_url($author->getOrcid(), PHP_URL_PATH));
+
+ if ($author->getData('orcidSandbox')) {
+ $uri = ORCID_URL_SANDBOX . $orcid;
+ $host = 'sandbox.orcid.org';
+ } else {
+ $uri = $author->getOrcid();
+ $host = 'orcid.org';
+ }
+
+ $contributor['contributor-orcid'] = [
+ 'uri' => $uri,
+ 'path' => $orcid,
+ 'host' => $host
+ ];
+ }
+
+ $first = false;
+
+ $contributors[] = $contributor;
+ }
+
+ return $contributors;
+ }
+}
diff --git a/classes/orcid/actions/SendSubmissionToOrcid.php b/classes/orcid/actions/SendSubmissionToOrcid.php
new file mode 100644
index 00000000000..38bb22937bb
--- /dev/null
+++ b/classes/orcid/actions/SendSubmissionToOrcid.php
@@ -0,0 +1,79 @@
+context)) {
+ // Sending to ORCID only works with the member API
+ return;
+ }
+
+ $issueId = $this->publication->getData('issueId');
+ if (isset($issueId)) {
+ $issue = Repo::issue()->get($issueId);
+ }
+
+ $authors = Repo::author()
+ ->getCollector()
+ ->filterByPublicationIds([$this->publication->getId()])
+ ->getMany();
+
+ // Collect valid ORCID ids and access tokens from submission contributors
+ $authorsWithOrcid = [];
+ foreach ($authors as $author) {
+ if ($author->getOrcid() && $author->getData('orcidAccessToken')) {
+ $orcidAccessExpiresOn = Carbon::parse($author->getData('orcidAccessExpiresOn'));
+ if ($orcidAccessExpiresOn->isFuture()) {
+ # Extract only the ORCID from the stored ORCID uri
+ $orcid = basename(parse_url($author->getOrcid(), PHP_URL_PATH));
+ $authorsWithOrcid[$orcid] = $author;
+ } else {
+ OrcidManager::logError("Token expired on {$orcidAccessExpiresOn} for author " . $author->getId() . ', deleting orcidAccessToken!');
+ OrcidManager::removeOrcidAccessToken($author);
+ }
+ }
+ }
+
+ if (empty($authorsWithOrcid)) {
+ OrcidManager::logInfo('No contributor with ORICD id or valid access token for submission ' . $this->publication->getData('submissionId'));
+ return;
+ }
+
+ $orcidWork = new OrcidWork($this->publication, $this->context, $authors->toArray(), $issue ?? null);
+ OrcidManager::logInfo('Request body (without put-code): ' . json_encode($orcidWork->toArray()));
+
+ foreach ($authorsWithOrcid as $orcid => $author) {
+ dispatch(new DepositOrcidSubmission($author, $this->context, $orcidWork->toArray(), $orcid));
+ }
+
+ }
+}
diff --git a/dbscripts/xml/upgrade.xml b/dbscripts/xml/upgrade.xml
index 8684989c5f1..35c9e2b03b0 100644
--- a/dbscripts/xml/upgrade.xml
+++ b/dbscripts/xml/upgrade.xml
@@ -131,6 +131,7 @@
+
diff --git a/jobs/orcid/DepositOrcidSubmission.php b/jobs/orcid/DepositOrcidSubmission.php
new file mode 100644
index 00000000000..b731b749652
--- /dev/null
+++ b/jobs/orcid/DepositOrcidSubmission.php
@@ -0,0 +1,142 @@
+fail('Application is set to sandbox mode and will not interact with the ORCID service');
+ return;
+ }
+
+ $uri = OrcidManager::getApiPath($this->context) . ORCID_API_VERSION_URL . $this->authorOrcid . '/' . ORCID_WORK_URL;
+ $method = 'POST';
+
+ if ($putCode = $this->author->getData('orcidWorkPutCode')) {
+ // Submission has already been sent to ORCID. Use PUT to update meta data
+ $uri .= '/' . $putCode;
+ $method = 'PUT';
+ $orcidWork['put-code'] = $putCode;
+ } else {
+ // Remove put-code from body because the work has not yet been sent
+ unset($this->orcidWork['put-code']);
+ }
+
+ $headers = [
+ 'Content-type: application/vnd.orcid+json',
+ 'Accept' => 'application/json',
+ 'Authorization' => 'Bearer ' . $this->author->getData('orcidAccessToken')
+ ];
+
+ OrcidManager::logInfo("{$method} {$uri}");
+ OrcidManager::logInfo('Header: ' . var_export($headers, true));
+
+ $httpClient = Application::get()->getHttpClient();
+ try {
+ $response = $httpClient->request(
+ $method,
+ $uri,
+ [
+ 'headers' => $headers,
+ 'json' => $this->orcidWork,
+ ]
+ );
+ } catch (ClientException $exception) {
+ $reason = $exception->getResponse()->getBody();
+ OrcidManager::logError("Publication fail: {$reason}");
+
+ $this->fail($exception);
+ }
+ $httpStatus = $response->getStatusCode();
+ OrcidManager::logInfo("Response status: {$httpStatus}");
+ $responseHeaders = $response->getHeaders();
+
+ switch ($httpStatus) {
+ case 200:
+ // Work updated
+ OrcidManager::logInfo("Work updated in profile, putCode: {$putCode}");
+ // TODO: See what to do with request success variable. Won't be handled by job in anyway by default
+ $requestSuccess = true;
+ break;
+ case 201:
+ $location = $responseHeaders['Location'][0];
+ // Extract the ORCID work put code for updates/deletion.
+ $putCode = intval(basename(parse_url($location, PHP_URL_PATH)));
+ OrcidManager::logInfo("Work added to profile, putCode: {$putCode}");
+ $this->author->setData('orcidWorkPutCode', $putCode);
+ Repo::author()->dao->update($this->author);
+ $requestSuccess = true;
+ break;
+ case 401:
+ // invalid access token, token was revoked
+ $error = json_decode($response->getBody(), true);
+ if ($error['error'] === 'invalid_token') {
+ OrcidManager::logError($error['error_description'] . ', deleting orcidAccessToken from author');
+ OrcidManager::removeOrcidAccessToken($this->author);
+ }
+ $requestSuccess = false;
+ break;
+ case 403:
+ OrcidManager::logError('Work update forbidden: ' . $response->getBody());
+ $requestSuccess = false;
+ break;
+ case 404:
+ // a work has been deleted from a ORCID record. putCode is no longer valid.
+ if ($method === 'PUT') {
+ OrcidManager::logError('Work deleted from ORCID record, deleting putCode form author');
+ $this->author->setData('orcidWorkPutCode', null);
+ Repo::author()->dao->update($this->author);
+ $requestSuccess = false;
+ } else {
+ OrcidManager::logError("Unexpected status {$httpStatus} response, body: " . $response->getBody());
+ $requestSuccess = false;
+ }
+ break;
+ case 409:
+ OrcidManager::logError('Work already added to profile, response body: ' . $response->getBody());
+ $requestSuccess = false;
+ break;
+ default:
+ OrcidManager::logError("Unexpected status {$httpStatus} response, body: " . $response->getBody());
+ $requestSuccess = false;
+ }
+ }
+}
diff --git a/jobs/orcid/PublishReviewerWorkToOrcid.php b/jobs/orcid/PublishReviewerWorkToOrcid.php
new file mode 100644
index 00000000000..e6d61f1a5b6
--- /dev/null
+++ b/jobs/orcid/PublishReviewerWorkToOrcid.php
@@ -0,0 +1,120 @@
+fail('Application is set to sandbox mode and will not interact with the ORCID service');
+ return;
+ }
+
+ if (!OrcidManager::isMemberApiEnabled($this->context)) {
+ return;
+ }
+
+ if (!OrcidManager::getCity($this->context) || !OrcidManager::getCountry($this->context)) {
+ return;
+ }
+
+ $reviewer = Repo::user()->get($this->reviewAssignment->getData('reviewerId'));
+
+ if ($reviewer->getOrcid() && $reviewer->getData('orcidAccessToken')) {
+ $orcidAccessExpiresOn = Carbon::parse($reviewer->getData('orcidAccessExpiresOn'));
+ if ($orcidAccessExpiresOn->isFuture()) {
+ # Extract only the ORCID from the stored ORCID uri
+ $orcid = basename(parse_url($reviewer->getOrcid(), PHP_URL_PATH));
+
+ $orcidReview = new OrcidReview($this->submission, $this->reviewAssignment, $this->context);
+
+ $uri = OrcidManager::getApiPath($this->context) . ORCID_API_VERSION_URL . $orcid . '/' . ORCID_REVIEW_URL;
+ $method = 'POST';
+ if ($putCode = $reviewer->getData('orcidReviewPutCode')) {
+ $uri .= '/' . $putCode;
+ $method = 'PUT';
+ $orcidReview['put-code'] = $putCode;
+ }
+ $headers = [
+ 'Content-Type' => ' application/vnd.orcid+json; qs=4',
+ 'Accept' => 'application/json',
+ 'Authorization' => 'Bearer ' . $reviewer->getData('orcidAccessToken')
+ ];
+ $httpClient = Application::get()->getHttpClient();
+
+ try {
+ $response = $httpClient->request(
+ $method,
+ $uri,
+ [
+ 'headers' => $headers,
+ 'json' => $orcidReview->toArray(),
+ ]
+ );
+ } catch (ClientException $exception) {
+ $reason = $exception->getResponse()->getBody();
+ OrcidManager::logInfo("Publication fail: {$reason}");
+
+ $this->fail($exception);
+ }
+ $httpStatus = $response->getStatusCode();
+ OrcidManager::logInfo("Response status: {$httpStatus}");
+ $responseHeaders = $response->getHeaders();
+ switch ($httpStatus) {
+ case 200:
+ OrcidManager::logInfo("Review updated in profile, putCode: {$putCode}");
+ break;
+ case 201:
+ $location = $responseHeaders['Location'][0];
+ // Extract the ORCID work put code for updates/deletion.
+ $putCode = basename(parse_url($location, PHP_URL_PATH));
+ $reviewer->setData('orcidReviewPutCode', $putCode);
+ Repo::user()->edit($reviewer, ['orcidReviewPutCode']);
+ OrcidManager::logInfo("Review added to profile, putCode: {$putCode}");
+ break;
+ default:
+ OrcidManager::logError("Unexpected status {$httpStatus} response, body: {$responseHeaders}");
+ }
+ }
+ }
+ }
+}
diff --git a/pages/article/ArticleHandler.php b/pages/article/ArticleHandler.php
index 18de5d32962..57ae0b93020 100644
--- a/pages/article/ArticleHandler.php
+++ b/pages/article/ArticleHandler.php
@@ -34,6 +34,7 @@
use PKP\core\PKPApplication;
use PKP\core\PKPJwt as JWT;
use PKP\db\DAORegistry;
+use PKP\orcid\OrcidManager;
use PKP\plugins\Hook;
use PKP\plugins\PluginRegistry;
use PKP\security\authorization\ContextRequiredPolicy;
@@ -307,6 +308,7 @@ public function view($args, $request)
'copyrightYear' => $publication->getData('copyrightYear'),
'pubIdPlugins' => PluginRegistry::loadCategory('pubIds', true),
'keywords' => $publication->getData('keywords'),
+ 'orcidIcon' => OrcidManager::getIcon(),
]);
// Fetch and assign the galley to the template
diff --git a/plugins/themes/default/styles/index.less b/plugins/themes/default/styles/index.less
index 52eea2223f7..5b82741f955 100644
--- a/plugins/themes/default/styles/index.less
+++ b/plugins/themes/default/styles/index.less
@@ -20,6 +20,8 @@
@import "../../../../lib/pkp/styles/variables.less";
@import "../../../../lib/pkp/styles/utils.less";
@import "../../../../lib/pkp/styles/helpers.less";
+// General ORCID styles
+@import '../../../../lib/pkp/styles/orcid.less';
// Styles unique to this theme
@import "variables.less";
diff --git a/registry/emailTemplates.xml b/registry/emailTemplates.xml
index 33a38623f5c..5fac37ce923 100644
--- a/registry/emailTemplates.xml
+++ b/registry/emailTemplates.xml
@@ -76,4 +76,6 @@
+
+