From 06814cd0a5ab08ee48266c03c3081e88dd8773cc Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 11 Mar 2025 23:17:51 +0000
Subject: [PATCH 01/16] Bump @babel/core from 7.26.9 to 7.26.10
Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.26.9 to 7.26.10.
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.26.10/packages/babel-core)
---
updated-dependencies:
- dependency-name: "@babel/core"
dependency-type: direct:development
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
package-lock.json | 62 +++++++++++++++++++++++------------------------
package.json | 2 +-
2 files changed, 32 insertions(+), 32 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 119a7bc29..a0381d782 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -31,7 +31,7 @@
"vinyl-source-stream": "^2.0.0"
},
"devDependencies": {
- "@babel/core": "^7.26.9",
+ "@babel/core": "^7.26.10",
"@babel/preset-env": "^7.26.9",
"@uswds/compile": "^1.2.1",
"backstopjs": "^6.3.25",
@@ -97,22 +97,22 @@
}
},
"node_modules/@babel/core": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz",
- "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz",
+ "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.26.2",
- "@babel/generator": "^7.26.9",
+ "@babel/generator": "^7.26.10",
"@babel/helper-compilation-targets": "^7.26.5",
"@babel/helper-module-transforms": "^7.26.0",
- "@babel/helpers": "^7.26.9",
- "@babel/parser": "^7.26.9",
+ "@babel/helpers": "^7.26.10",
+ "@babel/parser": "^7.26.10",
"@babel/template": "^7.26.9",
- "@babel/traverse": "^7.26.9",
- "@babel/types": "^7.26.9",
+ "@babel/traverse": "^7.26.10",
+ "@babel/types": "^7.26.10",
"convert-source-map": "^2.0.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -128,14 +128,14 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.9.tgz",
- "integrity": "sha512-kEWdzjOAUMW4hAyrzJ0ZaTOu9OmpyDIQicIh0zg0EEcEkYXZb2TjtBhnHi2ViX7PKwZqF4xwqfAm299/QMP3lg==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz",
+ "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/parser": "^7.26.9",
- "@babel/types": "^7.26.9",
+ "@babel/parser": "^7.26.10",
+ "@babel/types": "^7.26.10",
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25",
"jsesc": "^3.0.2"
@@ -382,27 +382,27 @@
}
},
"node_modules/@babel/helpers": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.9.tgz",
- "integrity": "sha512-Mz/4+y8udxBKdmzt/UjPACs4G3j5SshJJEFFKxlCGPydG4JAHXxjWjAwjd09tf6oINvl1VfMJo+nB7H2YKQ0dA==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.10.tgz",
+ "integrity": "sha512-UPYc3SauzZ3JGgj87GgZ89JVdC5dj0AoetR5Bw6wj4niittNyFh6+eOGonYvJ1ao6B8lEa3Q3klS7ADZ53bc5g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.26.9",
- "@babel/types": "^7.26.9"
+ "@babel/types": "^7.26.10"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/parser": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.9.tgz",
- "integrity": "sha512-81NWa1njQblgZbQHxWHpxxCzNsa3ZwvFqpUg7P+NNUU6f3UU2jBEg4OlF/J6rl8+PQGh1q6/zWScd001YwcA5A==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.10.tgz",
+ "integrity": "sha512-6aQR2zGE/QFi8JpDLjUZEPYOs7+mhKXm86VaKFiLP35JQwQb6bwUE+XbvkH0EptsYhbNBSUGaUBLKqxH1xSgsA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@babel/types": "^7.26.9"
+ "@babel/types": "^7.26.10"
},
"bin": {
"parser": "bin/babel-parser.js"
@@ -1692,17 +1692,17 @@
}
},
"node_modules/@babel/traverse": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.9.tgz",
- "integrity": "sha512-ZYW7L+pL8ahU5fXmNbPF+iZFHCv5scFak7MZ9bwaRPLUhHh7QQEMjZUg0HevihoqCM5iSYHN61EyCoZvqC+bxg==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.10.tgz",
+ "integrity": "sha512-k8NuDrxr0WrPH5Aupqb2LCVURP/S0vBEn5mK6iH+GIYob66U5EtoZvcdudR2jQ4cmTwhEwW1DLB+Yyas9zjF6A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.26.2",
- "@babel/generator": "^7.26.9",
- "@babel/parser": "^7.26.9",
+ "@babel/generator": "^7.26.10",
+ "@babel/parser": "^7.26.10",
"@babel/template": "^7.26.9",
- "@babel/types": "^7.26.9",
+ "@babel/types": "^7.26.10",
"debug": "^4.3.1",
"globals": "^11.1.0"
},
@@ -1711,9 +1711,9 @@
}
},
"node_modules/@babel/types": {
- "version": "7.26.9",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.9.tgz",
- "integrity": "sha512-Y3IR1cRnOxOCDvMmNiym7XpXQ93iGDDPHx+Zj+NM+rg0fBaShfQLkg+hKPaZCEvg5N/LeCo4+Rj/i3FuJsIQaw==",
+ "version": "7.26.10",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.10.tgz",
+ "integrity": "sha512-emqcG3vHrpxUKTrxcblR36dcrcoRDvKmnL/dCL6ZsHaShW80qxCAcNhzQZrpeM765VzEos+xOi4s+r4IXzTwdQ==",
"dev": true,
"license": "MIT",
"dependencies": {
diff --git a/package.json b/package.json
index 5bf06d1b6..65140f4c0 100644
--- a/package.json
+++ b/package.json
@@ -47,7 +47,7 @@
"vinyl-source-stream": "^2.0.0"
},
"devDependencies": {
- "@babel/core": "^7.26.9",
+ "@babel/core": "^7.26.10",
"@babel/preset-env": "^7.26.9",
"@uswds/compile": "^1.2.1",
"backstopjs": "^6.3.25",
From a652c5f321d2e2cc03e5852df8f5d7ec046d23c3 Mon Sep 17 00:00:00 2001
From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com>
Date: Tue, 11 Mar 2025 23:18:00 +0000
Subject: [PATCH 02/16] Bump @rollup/plugin-node-resolve from 16.0.0 to 16.0.1
Bumps [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/HEAD/packages/node-resolve) from 16.0.0 to 16.0.1.
- [Changelog](https://github.com/rollup/plugins/blob/master/packages/node-resolve/CHANGELOG.md)
- [Commits](https://github.com/rollup/plugins/commits/node-resolve-v16.0.1/packages/node-resolve)
---
updated-dependencies:
- dependency-name: "@rollup/plugin-node-resolve"
dependency-type: direct:production
update-type: version-update:semver-patch
...
Signed-off-by: dependabot[bot]
---
package-lock.json | 9 +++++----
package.json | 2 +-
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 119a7bc29..f24cca180 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,7 +10,7 @@
"license": "CC0",
"dependencies": {
"@rollup/plugin-commonjs": "^28.0.3",
- "@rollup/plugin-node-resolve": "^16.0.0",
+ "@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/stream": "^3.0.1",
"@uswds/uswds": "^3.12.0",
"cbor-js": "0.1.0",
@@ -2273,9 +2273,10 @@
}
},
"node_modules/@rollup/plugin-node-resolve": {
- "version": "16.0.0",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.0.tgz",
- "integrity": "sha512-0FPvAeVUT/zdWoO0jnb/V5BlBsUSNfkIOtFHzMO4H9MOklrmQFY6FduVHKucNb/aTFxvnGhj4MNj/T1oNdDfNg==",
+ "version": "16.0.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-16.0.1.tgz",
+ "integrity": "sha512-tk5YCxJWIG81umIvNkSod2qK5KyQW19qcBF/B78n1bjtOON6gzKoVeSzAE8yHCZEDmqkHKkxplExA8KzdJLJpA==",
+ "license": "MIT",
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"@types/resolve": "1.20.2",
diff --git a/package.json b/package.json
index 5bf06d1b6..4abbb79e8 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,7 @@
},
"dependencies": {
"@rollup/plugin-commonjs": "^28.0.3",
- "@rollup/plugin-node-resolve": "^16.0.0",
+ "@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/stream": "^3.0.1",
"@uswds/uswds": "^3.12.0",
"cbor-js": "0.1.0",
From 21408543d4da84160532cfd101d456864219a35d Mon Sep 17 00:00:00 2001
From: Jonathan Bobel
Date: Wed, 12 Mar 2025 12:52:32 -0400
Subject: [PATCH 03/16] Update request_helper.py
Adjusting cross-origin checks to allow Youtube
---
notifications_utils/request_helper.py | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/notifications_utils/request_helper.py b/notifications_utils/request_helper.py
index 5c3317744..992deb203 100644
--- a/notifications_utils/request_helper.py
+++ b/notifications_utils/request_helper.py
@@ -75,11 +75,23 @@ class ResponseHeaderMiddleware(object):
if SPAN_ID_HEADER.lower() not in lower_existing_header_names:
headers.append((SPAN_ID_HEADER, str(req.span_id)))
- # Some dynamic scan findings
- headers.append(("Cross-Origin-Opener-Policy", "same-origin"))
- headers.append(("Cross-Origin-Embedder-Policy", "require-corp"))
- headers.append(("Cross-Origin-Resource-Policy", "same-origin"))
- headers.append(("Cross-Origin-Opener-Policy", "same-origin"))
+ def rewrite_response_headers(status, headers, exc_info=None):
+ lower_existing_header_names = {name.lower() for name, value in headers}
+
+ # Set COOP once (needed for security)
+ if "cross-origin-opener-policy" not in lower_existing_header_names:
+ headers.append(("Cross-Origin-Opener-Policy", "same-origin"))
+
+ # Ensure `Cross-Origin-Resource-Policy: cross-origin` is set
+ if "cross-origin-resource-policy" not in lower_existing_header_names:
+ headers.append(("Cross-Origin-Resource-Policy", "cross-origin"))
+
+ # Apply COEP restrictions to everything except YouTube
+ if "youtube.com" not in request.url and "youtube-nocookie.com" not in request.url:
+ if "cross-origin-embedder-policy" not in lower_existing_header_names:
+ headers.append(("Cross-Origin-Embedder-Policy", "require-corp"))
+
+ return start_response(status, headers, exc_info)
# svg content type should not contain charset
found_svg = False
From 9e8aec4c5ddd19c5073c1315689b18bf9584c44e Mon Sep 17 00:00:00 2001
From: Jonathan Bobel
Date: Wed, 12 Mar 2025 15:37:51 -0400
Subject: [PATCH 04/16] 2398 - broken TTS link
Updating TTS link, maybe the link used to go to a page that was removed
---
app/templates/base.html | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/templates/base.html b/app/templates/base.html
index 3135e5cdb..1690e8ee3 100644
--- a/app/templates/base.html
+++ b/app/templates/base.html
@@ -94,10 +94,10 @@
{% block footer %}
{% if current_service and current_service.research_mode %}
- {% set meta_suffix = 'Built by the Technology Transformation Servicesresearch mode' %}
+ {% set meta_suffix = 'Built by the Technology Transformation Servicesresearch mode' %}
{% else %}
{% set commit_hash = ", Latest version: " + config['COMMIT_HASH'] %}
- {% set long_link = 'Technology Transformation Services' %}
+ {% set long_link = 'Technology Transformation Services' %}
{% set meta_suffix = "Built by the " + long_link + commit_hash %}
{% endif %}
From 236fafd5975045897cb83ef9193f05bba0b198ff Mon Sep 17 00:00:00 2001
From: Jonathan Bobel
Date: Thu, 13 Mar 2025 14:26:45 -0400
Subject: [PATCH 05/16] Update request_helper.py
---
notifications_utils/request_helper.py | 5 -----
1 file changed, 5 deletions(-)
diff --git a/notifications_utils/request_helper.py b/notifications_utils/request_helper.py
index 992deb203..dd0fc0804 100644
--- a/notifications_utils/request_helper.py
+++ b/notifications_utils/request_helper.py
@@ -86,11 +86,6 @@ class ResponseHeaderMiddleware(object):
if "cross-origin-resource-policy" not in lower_existing_header_names:
headers.append(("Cross-Origin-Resource-Policy", "cross-origin"))
- # Apply COEP restrictions to everything except YouTube
- if "youtube.com" not in request.url and "youtube-nocookie.com" not in request.url:
- if "cross-origin-embedder-policy" not in lower_existing_header_names:
- headers.append(("Cross-Origin-Embedder-Policy", "require-corp"))
-
return start_response(status, headers, exc_info)
# svg content type should not contain charset
From 558753037f94381445bea54e672b472cd0ae432f Mon Sep 17 00:00:00 2001
From: Beverly Nguyen
Date: Thu, 13 Mar 2025 15:43:21 -0700
Subject: [PATCH 06/16] content updates
---
.../uswds/_uswds-theme-custom-styles.scss | 4 ++
app/main/views/index.py | 14 +++--
app/main/views/sub_navigation_dictionaries.py | 4 --
app/templates/base.html | 24 ++++++++
app/templates/components/header.html | 4 +-
app/templates/views/about/about.html | 1 -
.../views/about/why-text-messaging.html | 3 +-
app/templates/views/contact.html | 17 ++----
.../views/notify-service-ending.html | 28 +++++++++
app/templates/views/signedout.html | 60 +++++++------------
tests/app/test_navigation.py | 1 +
urls.js | 8 +--
12 files changed, 96 insertions(+), 72 deletions(-)
create mode 100644 app/templates/views/notify-service-ending.html
diff --git a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss
index 920c8641d..83ad4ece4 100644
--- a/app/assets/sass/uswds/_uswds-theme-custom-styles.scss
+++ b/app/assets/sass/uswds/_uswds-theme-custom-styles.scss
@@ -1047,3 +1047,7 @@ nav.nav {
.form-control-error {
border: 4px solid #b10e1e
}
+
+.usa-site-alert .usa-alert .usa-alert__body {
+ max-width: 75rem;
+}
diff --git a/app/main/views/index.py b/app/main/views/index.py
index 5c0312afc..475fd4e82 100644
--- a/app/main/views/index.py
+++ b/app/main/views/index.py
@@ -258,11 +258,17 @@ def why_text_messaging():
)
-@main.route("/join-notify")
-def join_notify():
+@main.route("/notify-service-ending")
+@user_is_logged_in
+def notify_service_ending():
+ user_is_authenticated = current_user.is_authenticated
+ user_is_platform_admin = getattr(current_user, "platform_admin", False)
+
+ navigation_links = about_notify_nav() if not (user_is_authenticated or user_is_platform_admin) else None
+
return render_template(
- "views/join-notify.html",
- navigation_links=about_notify_nav(),
+ "views/notify-service-ending.html",
+ navigation_links = navigation_links
)
diff --git a/app/main/views/sub_navigation_dictionaries.py b/app/main/views/sub_navigation_dictionaries.py
index db086e511..dc5ddf469 100644
--- a/app/main/views/sub_navigation_dictionaries.py
+++ b/app/main/views/sub_navigation_dictionaries.py
@@ -56,10 +56,6 @@ def about_notify_nav():
},
],
},
- {
- "name": "Join Notify",
- "link": "main.join_notify",
- },
{
"name": "Contact us",
"link": "main.contact",
diff --git a/app/templates/base.html b/app/templates/base.html
index 3135e5cdb..f039933bb 100644
--- a/app/templates/base.html
+++ b/app/templates/base.html
@@ -29,6 +29,30 @@
{% block header %}
{% include 'components/usa_banner.html' %}
+ {% if current_user.is_authenticated or current_service or current_user.platform_admin %}
+
+
+
+
Notify.gov Service Ending
+
+ GSA will no longer offer the Notify.gov service after June 8th, 2025. Visit
+ Notify.gov Service Ending for more information.
+
+
+
+
+ {% else %}
+
+
+
+
Notify.gov Service Ending
+
+ Notify.gov is no longer accepting new partners.
+
+
+
+
+ {% endif %}
{% include 'components/header.html' %}
{% endblock %}
diff --git a/app/templates/components/header.html b/app/templates/components/header.html
index 8445cb3a1..760cc905d 100644
--- a/app/templates/components/header.html
+++ b/app/templates/components/header.html
@@ -1,7 +1,6 @@
{% set is_about_page = request.path.startswith('/about') %}
-{% set is_join_notify_page = request.path.startswith('/join-notify') %}
{% set is_contact_page = request.path.startswith('/contact') %}
-{% set is_information_section = is_about_page or is_join_notify_page or is_contact_page %}
+{% set is_information_section = is_about_page or is_contact_page %}
{% if current_user.is_authenticated %}
{% set navigation = [
@@ -34,7 +33,6 @@
{% else %}
{% set navigation = [
{"href": url_for('main.about_notify'), "text": "About Notify", "active": is_about_page},
- {"href": url_for('main.join_notify'), "text": "Join Notify", "active": is_join_notify_page},
{"href": url_for('main.contact'), "text": "Contact us", "active": is_contact_page}
] %}
{% endif %}
diff --git a/app/templates/views/about/about.html b/app/templates/views/about/about.html
index bc8fec04d..5b034d34f 100644
--- a/app/templates/views/about/about.html
+++ b/app/templates/views/about/about.html
@@ -66,7 +66,6 @@
{% endfor %}
- See if Notify is right for you
Notify.gov is a product of the Public Benefits Studio, a product accelerator inside
the federal government.
diff --git a/app/templates/views/about/why-text-messaging.html b/app/templates/views/about/why-text-messaging.html
index c0d6a29a1..d9ec2635a 100644
--- a/app/templates/views/about/why-text-messaging.html
+++ b/app/templates/views/about/why-text-messaging.html
@@ -40,8 +40,7 @@
Texting not only helps programs reach people using a nearly-universal communication method, it is a cost effective
- way to do so. With Notify.gov you can get started for free, allowing you to try out
- texting to complement your existing communications and outreach strategies.
+ way to do so.
What texting is best for
diff --git a/app/templates/views/contact.html b/app/templates/views/contact.html
index 7eb8b0414..fa0b3a0f0 100644
--- a/app/templates/views/contact.html
+++ b/app/templates/views/contact.html
@@ -7,19 +7,10 @@
{% block content_column_content %}
{% endblock %}
diff --git a/app/templates/views/notify-service-ending.html b/app/templates/views/notify-service-ending.html
new file mode 100644
index 000000000..8f5b2206d
--- /dev/null
+++ b/app/templates/views/notify-service-ending.html
@@ -0,0 +1,28 @@
+{% extends "base.html" %}
+
+{% set page_title = "Notify.gov Service Ending" %}
+
+{% block per_page_title %}{{page_title}}{% endblock %}
+
+{% block content_column_content %}
+
+
+ {{page_title}}
+ GSA will no longer offer the Notify.gov service after June 8th, 2025. Current partners will continue to have service access until it is fully suspended. After May 30, partners will no longer be able to send messages, and the full service will be suspended by June 8, 2025.
+
+ Notify.gov Status Announcement
+ Notify.gov was in beta and will no longer be offered by GSA. Operations will be suspended on or before June 8. There is a chance that the service may need to stop sooner. GSA will keep partners informed to the extent possible.
+
+ All Notify.gov partners will be moved to trial mode no later than May 30, and will no longer be able to send messages. Partners will be able to access their templates and data through June 8.
+
+ We encourage government programs to explore ways to continue utilizing technology to meet people where they are. There are several commercial tools on the market that may work for Notify.gov use cases.
+
+ GSA is working to avoid potential disruptions to partners’ operations and ensure a smooth transition.
+
+ This decision is part of GSA’s renewed focus on its original mission: to be the backbone of the federal government’s administrative operations — streamlining processes, optimizing resources, and ensuring cost-effectiveness. GSA is driven to reducing federal spend, contributing to a more flexible and streamlined government, and delivering value for the American people.
+
+ We wish you all the best as you continue your work.
+
+
+
+{% endblock %}
diff --git a/app/templates/views/signedout.html b/app/templates/views/signedout.html
index ac9d11798..27311f1f9 100644
--- a/app/templates/views/signedout.html
+++ b/app/templates/views/signedout.html
@@ -171,47 +171,29 @@ import usaButton %} {% block meta %}
-
- Who can use Notify.gov?
-
-
- All federal agencies and programs are
- eligible to use Notify.gov.
-
-
- US
- state, local, territorial, or tribal
- governments that administer or deliver federally-funded programs or
- services may qualify to use Notify.gov to communicate with applicants and
- participants in these programs.
-
-