{"id":18719702,"url":"https://github.com/vheemstra/fill-pot-po","last_synced_at":"2025-04-12T14:08:44.283Z","repository":{"id":37044747,"uuid":"498818548","full_name":"vHeemstra/fill-pot-po","owner":"vHeemstra","description":"Generate pre-filled PO files from POT file, using source PO files in NodeJS.","archived":false,"fork":false,"pushed_at":"2024-10-01T21:19:38.000Z","size":2011,"stargazers_count":2,"open_issues_count":6,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-09T04:23:46.477Z","etag":null,"topics":["create","fill-pot-po","gettext","javascript","merge","nodejs","po","pot","prefill","translation"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/fill-pot-po","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/vHeemstra.png","metadata":{"files":{"readme":"readme.md","changelog":null,"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}},"created_at":"2022-06-01T16:41:18.000Z","updated_at":"2024-07-10T17:59:57.000Z","dependencies_parsed_at":"2023-02-15T02:46:18.165Z","dependency_job_id":"82e39639-f33e-4987-9b03-188bb3b6cf24","html_url":"https://github.com/vHeemstra/fill-pot-po","commit_stats":{"total_commits":279,"total_committers":4,"mean_commits":69.75,"dds":0.3046594982078853,"last_synced_commit":"650c189bdff393ba048dbaf6525ec6ad8d200ded"},"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vHeemstra%2Ffill-pot-po","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vHeemstra%2Ffill-pot-po/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vHeemstra%2Ffill-pot-po/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vHeemstra%2Ffill-pot-po/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vHeemstra","download_url":"https://codeload.github.com/vHeemstra/fill-pot-po/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248578869,"owners_count":21127713,"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":["create","fill-pot-po","gettext","javascript","merge","nodejs","po","pot","prefill","translation"],"created_at":"2024-11-07T13:27:35.840Z","updated_at":"2025-04-12T14:08:44.264Z","avatar_url":"https://github.com/vHeemstra.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# fill-pot-po \u0026nbsp;\u0026nbsp;[![GitHub release (latest SemVer)][release-image]][release-url] [![NPM version][npm-image]][npm-url]\n\n[![Build Status][ci-image]][ci-url]\n[![Coverall Coverage Status][coverage-image]][coverage-url]\n[![Dependencies Status][deps-image]][deps-url]\n[![Downloads][downloads-image]][npm-url]\n\n\u003e Generate pre-filled PO files from POT file, using source PO files.\n\u003e\n\u003e _Based on the POT filename or set options, it looks for source PO files. For each PO file, it will create a new one, based on the contents of the POT file. The source PO file is used to fill in the matching translated strings._\n\u003e\n\u003e ✨ **_This package now only supports ESM. For CommonJS use version 3._** 🎉\n\n## Use case\n\nIf you have a development set-up where gettext translation strings are automatically extracted and compiled into a POT file, it can be bothersome to have to re-create PO files from that new POT file and include already translated strings from previous PO files. Especially, if you have multiple languages, like for a WordPress theme or plugin.\n\nIn this case, you can use this module to auto-create new PO files based on the new POT file, and have it fill in existing translated strings from previous PO files. The created PO files can now be opened and edited with the benefit of having to do fewer copy-pastes.\n\nFor Gulp, there is a wrapper plugin [**gulp-fill-pot-po**](https://github.com/vHeemstra/gulp-fill-pot-po/).\n\n## Install\n\n```bash\nnpm install --save-dev fill-pot-po\n```\n\n## Usage\n\nThe `fill-pot-po` module exports an asynchronous and a synchronous method.\n\nDepending on the chosen method, the result and the handling of the result is slightly different (see examples below).\n\n### 1. Asynchronous (recommended)\n\n### `fillPotPo( cb, options )`\n\nProcesses the POT files and found PO files in parallel.\n\n\u003ctable\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003cstrong\u003ecb\u003c/strong\u003e\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003erequired\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003efunction\u003c/code\u003e Callback function, with one argument containing the results (see \u003ca href=\"#results---async-mode\"\u003eResults\u003c/a\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd rowspan=\"2\"\u003e\u003cstrong\u003eoptions\u003c/strong\u003e\u003c/td\u003e\n        \u003ctd rowspan=\"2\"\u003e\u003ccode\u003eoptional\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003eobject\u003c/code\u003e Options object (see \u003ca href=\"#options\"\u003eOptions\u003c/a\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003estring|array\u003c/code\u003e Alternatively, a glob string or array can be provided that will be used as \u003ca href=\"#posources\"\u003e\u003ccode\u003eoptions.poSources\u003c/code\u003e\u003c/a\u003e. All other options will have their default values.\u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Example (ESM)\n\n```js\nimport fillPotPo from \"fill-pot-po\";\n\nconst cb = (results) =\u003e {\n  // ...\n};\n\nfillPotPo(cb, options);\n```\n\n#### Example (CommonJS - only with versions \u003c= 3)\n\n```js\nconst fillPotPo = require(\"fill-pot-po\");\n\nconst cb = (results) =\u003e {\n  // ...\n};\n\nfillPotPo(cb, options);\n```\n\n### 2. Synchronous\n\n### `fillPotPoSync( options )`\n\nProcesses the POT files and found PO files in series (slower).\n\n\u003ctable\u003e\n    \u003ctr\u003e\n        \u003ctd rowspan=\"2\"\u003e\u003cstrong\u003eoptions\u003c/strong\u003e\u003c/td\u003e\n        \u003ctd rowspan=\"2\"\u003e\u003ccode\u003eoptional\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003eobject\u003c/code\u003e Options object (see \u003ca href=\"#options\"\u003eOptions\u003c/a\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003estring|array\u003c/code\u003e Alternatively, a glob string or array can be provided that will be used as \u003ca href=\"#posources\"\u003e\u003ccode\u003eoptions.poSources\u003c/code\u003e\u003c/a\u003e. All other options will have their default values.\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd colspan=\"2\"\u003e\u003cstrong\u003e\u003cem\u003ereturns\u003c/em\u003e\u003c/strong\u003e\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003earray\u003c/code\u003e Results array on success (see \u003ca href=\"#results---sync-mode\"\u003eResults\u003c/a\u003e).\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd colspan=\"2\"\u003e\u003cstrong\u003e\u003cem\u003ethrows\u003c/em\u003e\u003c/strong\u003e\u003c/td\u003e\n        \u003ctd\u003e\u003ccode\u003ePluginError\u003c/code\u003e On error ;)\u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\n#### Example (ESM)\n\n```js\nimport { sync as fillPotPoSync } from \"fill-pot-po\";\n\ntry {\n  const results = fillPotPoSync(options);\n\n  //...\n} catch (error) {\n  console.log(error);\n}\n```\n\n#### Example (CommonJS - only with versions \u003c= 3)\n\n```js\nconst fillPotPoSync = require(\"fill-pot-po\").sync;\n\ntry {\n  const results = fillPotPoSync(options);\n\n  //...\n} catch (error) {\n  console.log(error);\n}\n```\n\n## Locating PO files for each POT file\n\nFor each POT file that is processed, the module will try to locate the proper PO files.\n\nThis is the algorithm in pseudo-code:\n\n```js\nif (options.poSources) {\n  po_search_glob = options.poSources;\n} else {\n  source_dir = options.srcDir || pot_file_directory;\n\n  if (options.domainInPOPath) {\n    if (options.domainFromPOTPath) {\n      // NOTE: If the POT file is an unnamed Vinyl object, an error will be thrown now.\n\n      po_search_glob = `${source_dir}/${pot_file_basename_without_ext}-${any_locale}.po`;\n    } else {\n      // NOTE: If options.domain is empty, an error will be thrown now.\n\n      po_search_glob = `${source_dir}/${options.domain}-${any_locale}.po`;\n    }\n  } else {\n    po_search_glob = `${source_dir}/${any_locale}.po`;\n  }\n}\n\n// NOTE: For all glob searches, options.srcGlobOptions will be used.\n```\n\nFor actual source code, see [**`getPOFilepaths()`**](https://github.com/vHeemstra/fill-pot-po/blob/main/src/shared.ts#L134) in **src/shared.js**.\n\nSee also options [`poSources`](#posources), [`srcDir`](#srcdir), [`domainInPOPath`](#domaininpopath), [`domainFromPOTPath`](#domainfrompotpath) and [`domain`](#domain).\n\n## Options\n\n### _Overview of all defaults_\n\n```js\n{\n    // Input-related\n    potSources: ['**/*.pot', '!node_modules/**'],\n    poSources: null,\n    srcDir: '',\n    domainInPOPath: true,\n    domainFromPOTPath: true,\n    domain: '',\n    srcGlobOptions: {},\n\n    // Content-related\n    wrapLength: 77,\n    defaultContextAsFallback: false,\n    appendNonIncludedFromPO: false,\n    includePORevisionDate: false,\n    includeGenerator: true,\n\n    // Output-related\n    returnPOT: false,\n    writeFiles: true,\n    destDir: '',\n    logResults: false,\n}\n```\n\n### potSources\n\n`string|Vinyl|array`\n\n\u003e The POT files to process. Can be a path or glob string, a Vinyl object, an array of strings or an array of Vinyl objects.\n\nDefault: `['**/*.pot', '!node_modules/**']`\n\n### Options related to locating PO files\n\n#### poSources\n\n`string|array`\n\n\u003e The PO source files to use. Can be a path or glob string, or an array of paths/globs.\n\u003e\n\u003e By default, or if falsy, the module will look for PO files with filenames like `{text-domain}-{locale}.po` or `{locale}.po` if [`domainInPOPath`](#domaininpopath) is set to false.\n\u003e\n\u003e `{text-domain}` is either the POT filename or the value set in the [`domain`](#domain) option.\n\u003e\n\u003e See [**Locating PO files for each POT file**](#locating-po-files-for-each-pot-file) for more info.\n\nDefault: `null`\n\n#### srcDir\n\n`string`\n\n\u003e Relative path from current working directory or absolute path to folder where source PO files can be found.\n\u003e\n\u003e By default, the same folder as the POT file will be used.\n\u003e\n\u003e See [**Locating PO files for each POT file**](#locating-po-files-for-each-pot-file) for more info.\n\nDefault: `''`\n\n#### domainInPOPath\n\n`boolean`\n\n\u003e Match source PO files with the text domain name in the filename.\n\u003e\n\u003e For example: `text-domain-en_EN.po` and `text-domain-nl_NL.po`.\n\u003e\n\u003e See [**Locating PO files for each POT file**](#locating-po-files-for-each-pot-file) for more info.\n\nDefault: `true`\n\n#### domainFromPOTPath\n\n`boolean`\n\n\u003e Whether or not to get the text domain from the POT filename (excluding extension).\n\u003e\n\u003e If set to `false` and [`domainInPOPath`](#domaininpopath) is `true`, a text domain must be set using the [`domain`](#domain) option.\n\u003e\n\u003e See [**Locating PO files for each POT file**](#locating-po-files-for-each-pot-file) for more info.\n\nDefault: `true`\n\n#### domain\n\n`string`\n\n\u003e The text domain slug, like `text-domain`.\n\u003e\n\u003e By default this is the POT filename excluding extension and is used to find the right PO source files.\n\u003e\n\u003e See [**Locating PO files for each POT file**](#locating-po-files-for-each-pot-file) for more info.\n\nDefault: `''`\n\n#### srcGlobOptions\n\n`object`\n\n\u003e Glob options used when matching PO source files.\n\u003e\n\u003e See [**Locating PO files for each POT file**](#locating-po-files-for-each-pot-file) for more info.\n\nDefault: `{}`\n\n### Options related to output\n\n#### returnPOT\n\n`boolean`\n\n\u003e Whether the plugin should return the source POT file(s) (`true`) or the generated PO file(s) (`false`).\n\u003e\n\u003e By default, it will return the generated PO files.\n\u003e\n\u003e _**NOTE**_: If set to `true`, you need to set [`writeFiles`](#writefiles) to `true` as well or else no PO files will be generated and the plugin throws an error.\n\nDefault: `false`\n\n#### writeFiles\n\n`boolean`\n\n\u003e Whether or not to write the newly generated PO files to disk.\n\u003e\n\u003e If you wish to process the results array and content buffers yourself, you could set this to `false`.\n\u003e\n\u003e _**NOTE**_: When using [**gulp-fill-pot-po**](https://github.com/vHeemstra/gulp-fill-pot-po), the default is `false`, since the resulting buffers will probably be `.pipe( dest() )`'d, which writes them to disk instead.\n\nDefault: `true` (for gulp-fill-pot-po: `false`)\n\n#### destDir\n\n`string`\n\n\u003e _Only if [`writeFiles`](#writefiles) is `true`._\n\u003e\n\u003e Relative path from current working directory or absolute path to the folder where the PO files should be written.\n\nDefault: `''`\n\n#### logResults\n\n`boolean`\n\n\u003e Log results to console.\n\nDefault: `false`\n\n### Options related to generating PO content\n\n#### wrapLength\n\n`integer`\n\n\u003e Line wrapping length excluding quotation marks.\n\u003e\n\u003e This is forwarded as `foldLength` to [`gettext-parser`](https://github.com/smhg/gettext-parser#compile-po-from-a-translation-object).\n\nDefault: `77`\n\n#### defaultContextAsFallback\n\n`boolean`\n\n\u003e If a string is not found in the PO source file with a certain context, try searching for the same string without a context and use that.\n\u003e\n\u003e A flag comment `#, fuzzy` will be added to signal translators to check the translation.\n\nDefault: `false`\n\n#### appendNonIncludedFromPO\n\n`boolean`\n\n\u003e Append all translated strings from the source PO file that were not in the POT file.\n\u003e\n\u003e A translator comment `# DEPRECATED` will be added to them.\n\nDefault: `false`\n\n#### includePORevisionDate\n\n`boolean`\n\n\u003e Include a `PO-Revision-Date` header to the PO files with the current timestamp.\n\nDefault: `false`\n\n#### includeGenerator\n\n`boolean`\n\n\u003e Include a `X-Generator` header to the PO files.\n\nDefault: `true`\n\n## Results\n\n### Results - Async mode\n\nThe first argument of the callback function will be the results array:\n\n#### results[0]\n\n`boolean` True on success, false on error.\n\n#### results[1] (on success)\n\n`array` Array of [Vinyl](https://github.com/gulpjs/vinyl) file objects, depending on the value of [`options.returnPOT`](#returnpot):\n\n\u003cul\u003e\u003ctable\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eThe generated PO files. \u003cem\u003e(default)\u003c/em\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eThe input POT files.\u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\u003c/ul\u003e\n\n#### results[1] (on error)\n\n`string` Error message.\n\n### Results - Sync mode\n\n#### On success\n\n`array` Returns an array of [Vinyl](https://github.com/gulpjs/vinyl) file objects, depending on the value of [`options.returnPOT`](#returnpot):\n\n\u003cul\u003e\u003ctable\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003efalse\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eThe generated PO files. \u003cem\u003e(default)\u003c/em\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n        \u003ctd\u003e\u003ccode\u003etrue\u003c/code\u003e\u003c/td\u003e\n        \u003ctd\u003eThe input POT files.\u003c/td\u003e\n    \u003c/tr\u003e\n\u003c/table\u003e\n\u003c/ul\u003e\n\n#### On error\n\nOn error, `fillPotPoSync()` will throw an error.\n\n## Related\n\n- [gulp-fill-pot-po](https://github.com/vheemstra/gulp-fill-pot-po) - Run fill-pot-po in gulp\n- [gettext-parser](https://github.com/smhg/gettext-parser) - Parse and compile gettext PO and MO files with NodeJS\n- [gulp-wp-pot](https://github.com/wp-pot/gulp-wp-pot) - Generate POT files in WordPress project in gulp\n\n## Extra\n\n- [Guide for migrating your Gulp set-up from CommonJS to ESM](https://gist.github.com/noraj/007a943dc781dc8dd3198a29205bae04)\n\n## License\n\nMIT © [Philip van Heemstra](https://github.com/vheemstra)\n\n[release-url]: https://github.com/vHeemstra/fill-pot-po/releases\n[release-image]: https://img.shields.io/github/v/release/vHeemstra/fill-pot-po?sort=semver\u0026logo=github\u0026logoColor=959DA5\u0026labelColor=444D56\n[ci-url]: https://github.com/vHeemstra/fill-pot-po/actions/workflows/ci_push_on_main.yml\n[ci-image]: https://img.shields.io/github/actions/workflow/status/vHeemstra/fill-pot-po/ci_push_on_main.yml?branch=main\u0026label=lint%20%26%20test\u0026logo=github\u0026logoColor=959DA5\u0026labelColor=444D56\n[ci-image2]: https://github.com/vHeemstra/fill-pot-po/actions/workflows/ci_push_on_main.yml/badge.svg\n[ci-image3]: https://img.shields.io/static/v1?logo=github\u0026logoColor=959DA5\u0026label=lint%20%26%20tests\u0026labelColor=444D56\u0026message=passing\u0026color=34D058\n[ci-image4]: https://img.shields.io/github/workflow/status/vHeemstra/fill-pot-po/Lint%20%7C%20Test%20%7C%20Release?label=lint%20%26%20test\u0026logo=github\u0026logoColor=959DA5\u0026labelColor=444D56\n[coverage-url]: https://coveralls.io/github/vHeemstra/fill-pot-po?branch=main\n[coverage-image]: https://img.shields.io/coveralls/github/vHeemstra/fill-pot-po?logo=coveralls\u0026logoColor=959DA5\u0026labelColor=444D56\n[coverage-image_]: https://coveralls.io/repos/github/vHeemstra/fill-pot-po/badge.svg?branch=main\n[coverage-url2]: https://codecov.io/gh/vHeemstra/fill-pot-po\n[coverage-image2]: https://codecov.io/gh/vHeemstra/fill-pot-po/branch/main/graph/badge.svg?token=sZaKGStMXg\n[deps-url]: https://libraries.io/npm/fill-pot-po\n[deps-image]: https://img.shields.io/librariesio/release/npm/fill-pot-po?logo=libraries.io\u0026logoColor=959DA5\u0026labelColor=444D56\n[deps-image2]: https://img.shields.io/librariesio/github/vHeemstra/fill-pot-po?logo=libraries.io\u0026logoColor=959DA5\u0026labelColor=444D56\n[npm-url]: https://www.npmjs.com/package/fill-pot-po\n[npm-image]: https://img.shields.io/npm/v/fill-pot-po.svg?color=cb0000\u0026labelColor=444D56\u0026logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjOTU5REE1IiBkPSJNMS43NjMgMEMuNzg2IDAgMCAuNzg2IDAgMS43NjN2MjAuNDc0QzAgMjMuMjE0Ljc4NiAyNCAxLjc2MyAyNGgyMC40NzRjLjk3NyAwIDEuNzYzLS43ODYgMS43NjMtMS43NjNWMS43NjNDMjQgLjc4NiAyMy4yMTQgMCAyMi4yMzcgMHpNNS4xMyA1LjMyM2wxMy44MzcuMDE5LS4wMDkgMTMuODM2aC0zLjQ2NGwuMDEtMTAuMzgyaC0zLjQ1NkwxMi4wNCAxOS4xN0g1LjExM3oiPjwvcGF0aD48L3N2Zz4=\n[downloads-image]: https://img.shields.io/npm/dm/fill-pot-po.svg?labelColor=444D56\u0026logo=data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHZpZXdCb3g9IjAgMCAyNCAyNCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjOTU5REE1IiBkPSJNMS43NjMgMEMuNzg2IDAgMCAuNzg2IDAgMS43NjN2MjAuNDc0QzAgMjMuMjE0Ljc4NiAyNCAxLjc2MyAyNGgyMC40NzRjLjk3NyAwIDEuNzYzLS43ODYgMS43NjMtMS43NjNWMS43NjNDMjQgLjc4NiAyMy4yMTQgMCAyMi4yMzcgMHpNNS4xMyA1LjMyM2wxMy44MzcuMDE5LS4wMDkgMTMuODM2aC0zLjQ2NGwuMDEtMTAuMzgyaC0zLjQ1NkwxMi4wNCAxOS4xN0g1LjExM3oiPjwvcGF0aD48L3N2Zz4=\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvheemstra%2Ffill-pot-po","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvheemstra%2Ffill-pot-po","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvheemstra%2Ffill-pot-po/lists"}