{"id":13573244,"url":"https://github.com/opentripplanner/otp-ui","last_synced_at":"2026-05-01T20:01:49.551Z","repository":{"id":37445038,"uuid":"222808065","full_name":"opentripplanner/otp-ui","owner":"opentripplanner","description":"React component library, which can be used to build trip planner webapps.","archived":false,"fork":false,"pushed_at":"2026-04-21T20:08:37.000Z","size":81231,"stargazers_count":71,"open_issues_count":84,"forks_count":39,"subscribers_count":10,"default_branch":"master","last_synced_at":"2026-04-21T22:06:27.700Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://www.opentripplanner.org/otp-ui/?path=/story/transitvehicleoverlay--real-time-rectangles","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/opentripplanner.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-11-19T23:13:51.000Z","updated_at":"2026-04-21T20:08:38.000Z","dependencies_parsed_at":"2023-09-21T18:44:41.300Z","dependency_job_id":"a25052ce-35a0-4996-9ea3-efb39ffa89b1","html_url":"https://github.com/opentripplanner/otp-ui","commit_stats":{"total_commits":4595,"total_committers":28,"mean_commits":"164.10714285714286","dds":0.7562568008705114,"last_synced_commit":"e5929ff203e4826834910a345b03e880ee470aa7"},"previous_names":[],"tags_count":2211,"template":false,"template_full_name":null,"purl":"pkg:github/opentripplanner/otp-ui","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentripplanner%2Fotp-ui","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentripplanner%2Fotp-ui/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentripplanner%2Fotp-ui/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentripplanner%2Fotp-ui/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/opentripplanner","download_url":"https://codeload.github.com/opentripplanner/otp-ui/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opentripplanner%2Fotp-ui/sbom","scorecard":{"id":710660,"data":{"date":"2025-08-11","repo":{"name":"github.com/opentripplanner/otp-ui","commit":"fa96aafe295f0eebd4466a963bbe423cc1e714e1"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":2,"reason":"Found 5/21 approved changesets -- score normalized to 2","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/codespell.yml:1","Warn: no topLevel permission defined: .github/workflows/node-ci.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codespell.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/opentripplanner/otp-ui/codespell.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/codespell.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/opentripplanner/otp-ui/codespell.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node-ci.yml:5: update your workflow using https://app.stepsecurity.io/secureworkflow/opentripplanner/otp-ui/node-ci.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/node-ci.yml:8: update your workflow using https://app.stepsecurity.io/secureworkflow/opentripplanner/otp-ui/node-ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/node-ci.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/opentripplanner/otp-ui/node-ci.yml/master?enable=pin","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 14 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"27 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-h5c3-5r3r-rr8q","Warn: Project is vulnerable to: GHSA-rmvr-2pp2-xj38","Warn: Project is vulnerable to: GHSA-xx4v-prfh-6cgc","Warn: Project is vulnerable to: GHSA-jr5f-v2jv-69x6","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-67mh-4wv8-2f99","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-mwcw-c2x4-8c55","Warn: Project is vulnerable to: GHSA-r683-j2x4-v87g","Warn: Project is vulnerable to: GHSA-j9fq-vwqv-2fm2","Warn: Project is vulnerable to: GHSA-pqw5-jmp5-px4v","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-6fw4-hr69-g3rv","Warn: Project is vulnerable to: GHSA-3f95-r44v-8mrg","Warn: Project is vulnerable to: GHSA-28xr-mwxg-3qc8","Warn: Project is vulnerable to: GHSA-9p95-fxvg-qgq2","Warn: Project is vulnerable to: GHSA-9w5j-4mwv-2wj8","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-w5p7-h5w8-2hfq","Warn: Project is vulnerable to: GHSA-7p7h-4mm5-852v","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-22T08:08:02.798Z","repository_id":37445038,"created_at":"2025-08-22T08:08:02.798Z","updated_at":"2025-08-22T08:08:02.798Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32510815,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-30T13:12:12.517Z","status":"online","status_checked_at":"2026-05-01T02:00:05.856Z","response_time":64,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-08-01T15:00:32.296Z","updated_at":"2026-05-01T20:01:49.492Z","avatar_url":"https://github.com/opentripplanner.png","language":"TypeScript","funding_links":[],"categories":["Uncategorized","Using Data"],"sub_categories":["Uncategorized","Consumer Apps"],"readme":"# OTP-UI React Component Library\n\n[![Join the chat at https://gitter.im/opentripplanner/otp-react-redux](https://badges.gitter.im/repo.png)](https://gitter.im/opentripplanner/otp-react-redux)\n[![Build process badge](https://img.shields.io/github/actions/workflow/status/opentripplanner/otp-ui/node-ci.yml)](https://github.com/opentripplanner/otp-ui/actions/workflows/node-ci.yml)\n\n## Description\n\nReact component library, which can be used to build trip planner webapps.\n\nSee:\n\n- [Examples and docs (via Storybook)](http://www.opentripplanner.org/otp-ui/?path=/story/itinerarybody--itinerarybody-with-walk-transit-walk-itinerary-with-custom-view-trip-button-activated-and-custom-route-abbreviation)\n- [Current npm releases](https://www.npmjs.com/org/opentripplanner)\n- [A reference implementation of otp-ui](https://github.com/opentripplanner/otp-react-redux) -- IMPORTANT NOTE: otp-ui use in otp-rr is a WIP / TBD\n\n## Getting Started\n\n```bash\n git checkout https://github.com/opentripplanner/otp-ui.git\n pnpm install\n pnpm dev\n```\n\n## Development\n\nYou can chat with the main OTP-RR developers in our [Gitter chat](https://gitter.im/opentripplanner/otp-react-redux). Support is not guaranteed, but we may be able to answer questions and assist people wishing to make contributions.\n\nSome packages in otp-ui depend on sibling packages (e.g., `@opentripplanner/core-utils` is used by many of its siblings). Internal dependencies are handled with the `workspace:*` version, which is a notation provided by pnpm. This allows us to always reference the current internal dependency version. Therefore, before the storybook can be run, it's necessary to run `pnpm prepublish` so that all internal packages are built.\n\nIf the Storybook addon bar (a bar of controls at the bottom of the story) does not appear, you may need to clear localStorage by opening the browser console and typing `localStorage.clear()`.\n\n### Storyshot testing\n\nThis repo utilizes the [Storyshot](https://storybook.js.org/docs/react/workflows/snapshot-testing) Storybook addon to perform snapshot tests of every story in this monorepo. Whenever the script `pnpm unit` is ran, the Storyshot addon will be included along with all the other tests. It will compare the initial output of every story to the saved snapshot of that story. This provides a quick way to make sure nothing drastic has changed and that every single story is able to initially render without an error. Storyshot doesn't snapshot all possible changes that can be done while interacting with story components. Often times these snapshots will need to be updated and that can be accomplished by running `pnpm update-snapshots`.\n\n## Stack\n\n\u003e A Monorepo with multiple packages and a shared build, test, and release process.\n\n- 🐉 [Lerna](https://lernajs.io/)  - The Monorepo manager\n- 📦 [PNPM Workspaces](https://pnpm.io/workspaces)  -  Sane multi-package management\n- 🚀 [React](https://reactjs.org/)  -  JavaScript library for user interfaces\n- 💅 [styled-components](https://www.styled-components.com/)  -  CSS in JS elegance\n- 🛠 [Babel](https://babeljs.io/)  -  Compiles next-gen JavaScript\n- 📖 [Storybook](https://storybook.js.org/) - UI Component Environment\n- 🃏 [Jest](https://jestjs.io/)  -  Unit/Snapshot Testing\n\n## Usage\n\n- `pnpm dev` - This starts Storybook for viewing all the components locally.\n- `pnpm install` - This installs all of the packages and links dependent packages together.\n- `pnpm preppublish` - This babelfies all of the packages and creates `/lib` and `/esm` folders for each one.\n- `pnpm unit` - Run jest unit tests.\n- `pnpm coverage` - Shows jest unit coverage.\n- `pnpm clean` - Deletes all files in the gitignore (note: this can delete local editor settings)\n- `pnpm pack-all` - Creates tarball packages for all non-private packages and displays their locations.\n- `npx lerna changed` - Show which packages have changed.\n- `npx lerna diff` - Show specifically what files have cause the packages to change.\n- `npx lerna create \u003cpackageName\u003e` - Creates new package and walks through setting up package.json\n\n## Releasing\n\nThis project uses semantic-release to create releases to NPM. It is expect that contributors create [Conventional Commit](https://www.conventionalcommits.org/en/v1.0.0/) messages. These are then parsed by semantic-release which will automatically create an appropriate release for each package whenever a branch is merged to master.\n\n## Local Testing\n\nInternal package dependencies are referenced using the `workspace` [protocol provided by pnpm](https://pnpm.io/workspaces). This allows us to depend on our internal packages without keeping versions up to date, but these versions must be replaced with the actual version numbers prior to release. pnpm handles this when publishing automatically. However, if you wish to rely on an otp-ui package in a local filesystem project using the `file` protocol, you need to use `pnpm pack` to create a tarball of the package, then reference that tarball in the other project's package.json.\n\nFor example, to depend on core-utils locally, you can run `pnpm pack` from within the `packages/core-utils`. Next, in the other project, use a line like this to reference the resulting tarball. `\"@opentripplanner/core-utils\": \"file:../otp-ui/packages/core-utils/opentripplanner-core-utils-12.0.2.tgz\",`\n\n### Package Tarball Creation\n\nThe `pnpm pack-all` command creates tarball packages for all non-private packages in the monorepo and displays their locations. This is useful for testing packages locally in another project.\n\nWhen executed, this command runs `pnpm pack` for each non-private package and outputs the path to the generated tarball file. You can then reference these tarballs directly in other projects using the file protocol in your other project's package.json.\n\n## Raster Tile Versions\n\nAs of Fall 2022, the otp-ui map layers have migrated from [Leaflet](https://leafletjs.com) to [MapLibreGL](https://maplibre.org/projects/maplibre-gl-js/). This migration was a breaking change, so existing uses of otp-ui should be unaffected. If you wish to migrate to the latest version, please see the [Migration Guide](https://github.com/opentripplanner/otp-ui/blob/master/VECTOR-TILES-MIGRATION-GUIDE.md).\n\nWe understand not all will want to upgrade to vector tiles right away, and so will be maintaining the _raster tile_ versions of all relevant packages for the foreseeable future.\n\nThe following table lists the last major version of each package which uses raster tiles. These major versions will receive fresh minor versions as updates are needed.\n\n| Package                   | Latest Major Version with Raster Tiles |\n| ------------------------- | -------------------------------------- |\n| `base-map`                | 2                                      |\n| `core-utils`              | 7                                      |\n| `endpoints-overlay`       | 1                                      |\n| `itinerary-body`          | 4                                      |\n| `park-and-ride-overlay`   | 1                                      |\n| `route-viewer-overlay`    | 1                                      |\n| `stop-viewer-overlay`     | 1                                      |\n| `stops-overlay`           | 4                                      |\n| `transit-vehicle-overlay` | 2                                      |\n| `transitive-overlay`      | 2                                      |\n| `trip-viewer-overlay`     | 1                                      |\n| `types`                   | 3                                      |\n| `vehicle-rental-overlay`  | 1                                      |\n| `zoom-based-markers`      | 1                                      |\n\n## Internationalization\n\nOTP-UI uses `react-intl` from the [`formatjs`](https://github.com/formatjs/formatjs) library for internationalization.\nBoth `react-intl` and `formatjs` take advantage of native internationalization features provided by web browsers.\n\nLanguage-specific content is located in YML files under the `i18n` folder of packages that have internationalizable content\n(e.g. `en-US.yml` for American English, `fr.yml` for generic French, etc.).\n\nNote: Do not add comments to these YML files! Comments are removed by `yaml-sort` during pre-commit.\nInstead, comments for other developers should be placed in the corresponding js/jsx/ts/tsx file.\nComments for translators should be entered into Weblate (see [Contributing Translations](#contributing-translations))\n\nTo use the YML files in your react-intl application:\n\n- Merge the content of this file into the messages object that has your other localized strings,\n- Flatten the ids, i.e. convert a structure such as\n  ```\n    otpUi \u003e ItineraryBody \u003e travelByMode \u003e bike\n  ```\n  into\n  ```\n    otpUi.ItineraryBody.travelByMode.bike\n  ```\n- Pass the resulting object to the messages prop of `IntlProvider`.\n  See `packages/from-to-location-picker/src/index.story.tsx` for an example of how to initialize localized messages with `IntlProvider`.\n\n### Using internationalized content in the code\n\nAccess the internationalized content in code, typically using either\n\n```jsx\nimport { FormattedMessage } from \"react-intl\";\n...\n\u003cFormattedMessage id=\"...\" /\u003e\n```\n\nor, if you need a `string`,\n\n```js\n// Obtain `intl` using `injectIntl` or `useIntl`.\nintl.formatMessage({ id: ... })\n```\n\nwhere the id passed to `FormattedMessage` and `intl.formatMessage` can be literal or a computed value.\nSee [Internationalization checks and reporting](#internationalization-checks-and-reporting) for caveats.\n\n### Internationalization checks and reporting\n\nCode and translation integrity is checked by scripts that you can run locally.\n`check:i18n-all` checks for all languages. `check:i18n-en-fr` checks for English (US) and French and is run on GitHub after each push.\n\nThese scripts check the following:\n\n- All entries in the applicable translation files are used in the code.\n- All message ids used in the code have translations.\n\nFor the scripts to work best, you should use **literal** ids as much as possible with `\u003cFormattedMessage\u003e` or `intl.formatMessage`.\nThis is because the scripts use the `formatJS` CLI, and the `formatJS` CLI simply ignores message ids that are not literals.\n\n### Exceptions to checks\n\nExceptions to the checks above can be defined when:\n\n- Reusing a message defined in another package,\n- A message id needs to be computed, with some portion of it coming from a parameter,\n  and implementing a `switch` case does not provide substantial benefits.\n\nExceptions are defined in optional files named `i18n-exceptions.json`. See the [scripts package README](./packages/scripts/README.md#exceptions) for setting these files up.\n\n### Contributing translations\n\nOTP-UI now uses [Hosted Weblate](https://www.weblate.org) to manage translations!\n\n\u003cfigure\u003e\n  \u003ca href=\"https://hosted.weblate.org/engage/otp-react-redux/\"\u003e\n    \u003cimg src=\"https://hosted.weblate.org/widgets/otp-react-redux/-/horizontal-auto.svg\" alt=\"Translation status\" /\u003e\n  \u003c/a\u003e\n  \u003cfigcaption\u003eTranslation status for\n    \u003ca href=\"https://hosted.weblate.org/engage/otp-react-redux/\"\u003eOTP-react-redux and OTP-UI on Hosted Weblate\u003c/a\u003e\n  \u003c/figcaption\u003e\n\u003c/figure\u003e\n\nTranslations from the community are welcome and very much appreciated,\nplease see instructions at https://hosted.weblate.org/projects/otp-react-redux/.\nCommunity input from Weblate will appear as pull requests with changes to files in the applicable `i18n` folders for our review.\n(Contributions may be edited or rejected to remain in line with long-term project goals.)\n\nIf changes to a specific language file is needed but not enabled in Weblate, please open an issue or a pull request with the changes needed.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopentripplanner%2Fotp-ui","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopentripplanner%2Fotp-ui","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopentripplanner%2Fotp-ui/lists"}