{"_id":"@dein-ticket-shop/lexoffice-client-js","_rev":"2-bc6ed64d7a2cc9abe9a275ffceb6d2ef","name":"@dein-ticket-shop/lexoffice-client-js","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@dein-ticket-shop/lexoffice-client-js","version":"1.0.0","keywords":["lexoffice","api","client","javascript","typescript","node","browser"],"author":{"name":"elbstack","email":"hello@elbstack.com"},"license":"MIT","_id":"@dein-ticket-shop/lexoffice-client-js@1.0.0","maintainers":[{"name":"hrueger","email":"hannesrueger@gmx.de"}],"contributors":[{"name":"Annaelle Rössert","email":"annaelle@elbstack.com"}],"homepage":"https://github.com/elbstack/lexoffice-client-js#readme","bugs":{"url":"https://github.com/elbstack/lexoffice-client-js/issues"},"dist":{"shasum":"862b8d612f168e1eaa9d0a1ab3bcbb1c00313f68","tarball":"https://registry.npmjs.org/@dein-ticket-shop/lexoffice-client-js/-/lexoffice-client-js-1.0.0.tgz","fileCount":122,"integrity":"sha512-cE/Q+7Wmg1x0SaNDhmgCSG5FiBQBAj5fSnIguKxGNwKAPikruX0C4mKuIJoIAJX/qHPF0fVm5Fvpig2MraZRzw==","signatures":[{"sig":"MEUCIQDDQd7HWIxPVt5iht5VLHzMmvmKhjf7eFF3Sa5stBu8SAIgGUg3kzJgKPkoCcImUwK9GLAV4jICBIYkBPOXGcfqhZU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":403660},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.m.js","source":"src/index.ts","gitHead":"725253b4c8c32e42c244448a23e7d66221026b5f","scripts":{"dev":"microbundle watch","lint":"eslint 'src/**/*.ts' --fix","test":"echo \"No test specified\"","build":"rm -rf dist && microbundle","release":"npm run build && np","start:example":"ts-node example/index.ts"},"_npmUser":{"name":"hrueger","email":"hannesrueger@gmx.de"},"umd:main":"dist/index.umd.js","repository":{"url":"git+https://github.com/elbstack/lexoffice-client-js.git","type":"git"},"_npmVersion":"10.9.2","description":"An universal client for the Lexoffice API written in Typescript","directories":{},"_nodeVersion":"22.13.0","dependencies":{"axios":"^1.7.9","tslib":"^2.8.1","uri-tag":"^2.0.0","form-data":"^4.0.1","ts-results-es":"^4.2.0","utility-types":"^3.11.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"np":"^10.2.0","jest":"^29.7.0","nock":"^14.0.0","eslint":"^9.19.0","ts-node":"^10.9.2","prettier":"^3.4.2","typescript":"^5.7.3","@types/jest":"^29.5.14","microbundle":"^0.15.1","eslint-plugin-import":"^2.31.0","eslint-config-prettier":"^10.0.1","local-package-publisher":"^1.0.5","@typescript-eslint/parser":"^8.22.0","@typescript-eslint/eslint-plugin":"^8.22.0"},"_npmOperationalInternal":{"tmp":"tmp/lexoffice-client-js_1.0.0_1738336084415_0.963545466595662","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@dein-ticket-shop/lexoffice-client-js","version":"1.1.0","description":"An universal client for the Lexoffice API written in Typescript","main":"dist/index.js","module":"dist/index.m.js","umd:main":"dist/index.umd.js","types":"dist/index.d.ts","source":"src/index.ts","scripts":{"build":"rm -rf dist && microbundle","dev":"microbundle watch","release":"npm run build && np","lint":"eslint 'src/**/*.ts' --fix","test":"echo \"No test specified\"","start:example":"ts-node example/index.ts"},"repository":{"type":"git","url":"git+https://github.com/elbstack/lexoffice-client-js.git"},"keywords":["lexoffice","api","client","javascript","typescript","node","browser"],"author":{"name":"elbstack","email":"hello@elbstack.com"},"contributors":[{"name":"Annaelle Rössert","email":"annaelle@elbstack.com"}],"license":"MIT","bugs":{"url":"https://github.com/elbstack/lexoffice-client-js/issues"},"homepage":"https://github.com/elbstack/lexoffice-client-js#readme","publishConfig":{"access":"public"},"devDependencies":{"@types/jest":"^29.5.14","@typescript-eslint/eslint-plugin":"^8.22.0","@typescript-eslint/parser":"^8.22.0","eslint":"^9.19.0","eslint-config-prettier":"^10.0.1","eslint-plugin-import":"^2.31.0","jest":"^29.7.0","local-package-publisher":"^1.0.5","microbundle":"^0.15.1","nock":"^14.0.0","np":"^10.2.0","prettier":"^3.4.2","ts-node":"^10.9.2","typescript":"^5.7.3"},"dependencies":{"axios":"^1.7.9","form-data":"^4.0.1","ts-results-es":"^4.2.0","tslib":"^2.8.1","uri-tag":"^2.0.0","utility-types":"^3.11.0"},"_id":"@dein-ticket-shop/lexoffice-client-js@1.1.0","gitHead":"05b2228acb1cdc01866ed43d1792fa0085657e64","_nodeVersion":"22.13.0","_npmVersion":"11.2.0","dist":{"integrity":"sha512-Z6O+K5h0kytGOe9kOjOFfOugEVpojjWSTkjoT8jydA5NLICrug/+3BjEp0KP5A9qrki56+YwuJI8QQaD0clYQQ==","shasum":"07ac3f2cba79a8efe4d1675e896aa2aa97480a49","tarball":"https://registry.npmjs.org/@dein-ticket-shop/lexoffice-client-js/-/lexoffice-client-js-1.1.0.tgz","fileCount":122,"unpackedSize":403644,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEOwJJFK5e6rtjqL85POZdjCluwjA+Q7ABaBBYgADAjJAiEA9Qcz8SjAEnR3dgl2mlPo8hWSz/RNMNfS3CmmgxzMATk="}]},"_npmUser":{"name":"hrueger","email":"hannesrueger@gmx.de"},"directories":{},"maintainers":[{"name":"hrueger","email":"hannesrueger@gmx.de"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/lexoffice-client-js_1.1.0_1748367825824_0.5991349407953397"},"_hasShrinkwrap":false}},"time":{"created":"2025-01-31T15:08:04.332Z","modified":"2025-05-27T17:43:46.229Z","1.0.0":"2025-01-31T15:08:04.649Z","1.1.0":"2025-05-27T17:43:46.025Z"},"bugs":{"url":"https://github.com/elbstack/lexoffice-client-js/issues"},"author":{"name":"elbstack","email":"hello@elbstack.com"},"license":"MIT","homepage":"https://github.com/elbstack/lexoffice-client-js#readme","keywords":["lexoffice","api","client","javascript","typescript","node","browser"],"repository":{"type":"git","url":"git+https://github.com/elbstack/lexoffice-client-js.git"},"description":"An universal client for the Lexoffice API written in Typescript","contributors":[{"name":"Annaelle Rössert","email":"annaelle@elbstack.com"}],"maintainers":[{"name":"hrueger","email":"hannesrueger@gmx.de"}],"readme":"<h1 align = \"center\">lexoffice-client-js</h1>\n\n<p align=\"center\">\n  <strong>Javascript client library for the <a href=\"https://www.lexoffice.de/partner/public-api/\">lexoffice Public API<a>.</strong>\n</p>\n\n<p align=\"center\"><strong><img src=\"https://emojis.slackmojis.com/emojis/images/1479745458/1383/typescript.png?1479745458\" width=\"20\" height=\"20\"/> fully typed</strong></p>\n<p align=\"center\"><strong><img src=\"/images/promise-logo.png\" width=\"20\" height=\"20\"/> promise based</strong></p>\n<p align=\"center\"><strong>❌ non throwing</strong></p>\n<br>\n<p align=\"center\">\n  <a href=\"https://github.com/elbstack/lexoffice-client-js\">\n    <img src=\"https://badgen.net/badge/-/github?icon=github&label alt=\"GitHub\" />\n  </a>\n  <a href=\"https://github.com/elbstack/lexoffice-client-js/stargazers\">\n    <img src=\"https://badgen.net/github/stars/elbstack/lexoffice-client-js\" alt=\"GitHub Stars\"/>\n  </a>\n    <a>\n    <img alt=\"npm (latest)\" src=\"https://img.shields.io/npm/v/@elbstack/lexoffice-client-js/latest?color=%23f73149\"/>\n  </a>\n  <a>\n    <img alt=\"npm (next)\" src=\"https://img.shields.io/npm/v/@elbstack/lexoffice-client-js/next?color=%23e044aa\"/>\n  </a>\n    <br>\n  <a href=\"https://github.com/elbstack/lexoffice-client-js/pulse\" >\n    <img src=\"https://img.shields.io/github/commit-activity/m/elbstack/lexoffice-client-js?color=%23329121\" alt=\"Activity\" />        \n  </a>\n  <a href=\"https://github.com/elbstack/lexoffice-client-js/graphs/contributors\">\n    <img src=\"https://img.shields.io/github/contributors/elbstack/lexoffice-client-js?color=%2345e6db\" alt=\"Contributors\" />\n  </a>\n  <a href=\"https://github.com/elbstack/lexoffice-client-js/blob/main/LICENSE\">\n    <img\n      src=\"https://badgen.net/badge/license/MIT/blue\"\n      alt=\"MIT license\"\n    />\n  </a>\n</p>\n\n## 📦 Contents\n\n- [⚙️ Installation](#installation)\n- [📚 Documentation](#documentation)\n- [🔑 Usage](#usage)\n- [💡 Examples](#examples)\n  - [Retrieve an invoice](#retrieve-an-invoice)\n  - [Create an invoice](#create-an-invoice)\n  - [Upload file](#upload-file)\n- [❌ Error handling](#error-handling)\n- [🛠 Provided methods grouped by endpoint](#provided-methods)\n  - [Contact](#contact)\n  - [Country](#country)\n  - [Credit note](#credit-note)\n  - [Down payment invoice](#down-payment-invoice)\n  - [Event subscription](#event-subscription)\n  - [File](#file)\n  - [Invoice](#invoice)\n  - [Order confirmation](#order-confirmation)\n  - [Payment](#payment)\n  - [Payment condition](#payment-condition)\n  - [Posting category](#posting-category)\n  - [Profile](#profile)\n  - [Quotation](#quotation)\n  - [Recurring Template](#recurring-template)\n  - [Voucher](#voucher)\n  - [Voucherlist](#voucherlist)\n- [🔖 Side notes](#side-notes)\n<ul><li><a href=\"#about\"><img src=\"/images/favicon-32x32.png\"width=\"20\" height=\"20\"/> About us</a></li></ul>\n\n---\n\n<h2 name=\"installation\" >⚙️ Installation</h2>\n\n```bash\nnpm install @elbstack/lexoffice-client-js\n```\n\nor\n\n```bash\nyarn add @elbstack/lexoffice-client-js\n```\n\n<h2 name=\"documentation\">📚 Documentation</h2>\n\nYou can find the official lexoffice API documentation [here](https://developers.lexware.io/docs/#lexoffice-api-documentation).\n\n<h2 name=\"usage\" >🔑 Usage</h2>\n\nTo get your API Key, you must already be a Lexware Office user. Get it [here](https://app.lexware.de/settings/#/public-api).\n\n```ts\nimport { Client } from '@elbstack/lexoffice-client-js';\n\nconst client = new Client(YOUR_LEXOFFICE_API_KEY);\n```\n\n<h2 name=\"examples\">💡 Examples</h2>\n\nAll functions are promise based. These promises are formatted by the [ts-results package](https://github.com/vultix/ts-results), for extended error handling see [Error handling](#error-handling).\n\n### Retrieve an invoice\n\n```ts\nconst invoiceResult = await client.retrieveInvoice('caf4e0c3-c3e8-4a06-bcfe-346bc7190b2');\n\nif (invoiceResult.ok) {\n  const invoice = invoiceResult.val;\n} else {\n  console.error('An error occured');\n}\n```\n\n### Create an invoice\n\n```ts\nconst invoice = {\n  voucherDate: '2017-02-22T00:00:00.000+01:00',\n  address: {\n    name: 'Bike & Ride GmbH & Co. KG',\n    supplement: 'Gebäude 10',\n    street: 'Musterstraße 42',\n    city: 'Freiburg',\n    zip: '79112',\n    countryCode: 'DE',\n  },\n  lineItems: [\n    {\n      type: 'custom',\n      name: 'Energieriegel Testpaket',\n      quantity: 1,\n      unitName: 'Stück',\n      unitPrice: {\n        currency: 'EUR',\n        netAmount: 5,\n        taxRatePercentage: 0,\n      },\n      discountPercentage: 0,\n    },\n    {\n      type: 'text',\n      name: 'Strukturieren Sie Ihre Belege durch Text-Elemente.',\n      description: 'Das hilft beim Verständnis',\n    },\n  ],\n  totalPrice: {\n    currency: 'EUR',\n  },\n  taxConditions: {\n    taxType: 'net',\n  },\n  shippingConditions: {\n    shippingDate: '2017-04-22T00:00:00.000+02:00',\n    shippingType: 'delivery',\n  },\n  title: 'Rechnung',\n  introduction: 'Ihre bestellten Positionen stellen wir Ihnen hiermit in Rechnung',\n  remark: 'Vielen Dank für Ihren Einkauf',\n};\n\nconst createdInvoiceResult = await client.createInvoice(invoice, { finalize: true });\n\nif (createdInvoiceResult.ok) {\n  const invoice = createdInvoiceResult.val;\n} else {\n  console.error('An error occured');\n}\n```\n\n### Upload File\n\n```ts\nlet fs = require('fs');\nlet FormData = require('form-data');\n\nlet data = new FormData();\n\ndata.append('file', fs.createReadStream(__dirname + '/yourFolder/yourFile'));\ndata.append('type', 'voucher');\n\nconst uploadedFileResult = await client.uploadFile(data);\n\nif (uploadedFileResult.ok) {\n  const invoice = uploadedFileResult.val;\n} else {\n  console.error('An error occured');\n}\n```\n\n<h2 name=\"error-handling\">❌ Error handling</h2>\n\nAs mentioned above, the returned promises are formatted by ts-results which is a typescript implementation of Rust's [Result](https://doc.rust-lang.org/std/result/) and [Option](https://doc.rust-lang.org/std/option/) objects. It brings compile-time error checking and optional values to typescript.\nAll errors are instances of type RequestError.\nIf you want to use the advantages of ts-results, all client responses should be processed similar to the following:\n\n```ts\nif (YOUR_RESULT.ok) {\n  const YOUR_VARIABLE = YOUR_RESULT.val;\n  // Work with your result\n} else {\n  // Your request returned an error\n  const error = YOUR_RESULT.val;\n  console.log('error:', error);\n  // Further error checking is possible by\n  if (error instanceof RequestError) {\n    console.log('Hello instance of RequestError!');\n\n    if (error instanceof RequestNotFoundError) {\n      console.log('Wow, it looks like you have many instances!');\n    }\n    if (error instanceof RequestMethodNotAcceptableLegacyError) {\n      console.log('Seems, that you take care of your legacy!');\n    }\n  }\n}\n```\n\n### Error codes and types\n\n<table>\n<th colspan=\"4\">Regular errors</th>\n<tr>\n<th width=\"15%\">❌ Error code</th>\n<th width=\"35%\"><img src=\"https://emojis.slackmojis.com/emojis/images/1479745458/1383/typescript.png?1479745458\" width=\"20\" height=\"20\"/> Error type</th>\n<th width=\"15%\">❌ Server error code</th>\n<th width=\"35%\"><img src=\"https://emojis.slackmojis.com/emojis/images/1479745458/1383/typescript.png?1479745458\" width=\"20\" height=\"20\"/> Error type</th>\n</tr>\n<tr>\n<td>400</td>\n<td>RequestBadRequestError</td>\n<td>500</td>\n<td>RequestInternalServerError</td>\n</tr>\n<tr>\n<td>401</td>\n<td>RequestUnauthorizedError</td>\n<td>503</td>\n<td>RequestServiceUnavailableError</td>\n</tr>\n<tr>\n<td>402</td>\n<td>RequestPaymentRequiredError</td>\n<td>504</td>\n<td>RequestGatewayTimeoutError</td>\n</tr>\n<tr>\n<td>403</td>\n<td>RequestForbiddenError</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td>404</td>\n<td>RequestNotFoundError</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td>405</td>\n<td>RequestMethodNotAllowedError</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td>406</td>\n<td>RequestMethodNotAcceptableError</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td>409</td>\n<td>RequestConflictError</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td>415</td>\n<td>RequestUnsupportedMediaTypeError</td>\n<td></td>\n<td></td>\n</tr>\n<tr>\n<td>429</td>\n<td>RequestTooManyRequestsError</td>\n<td></td>\n<td></td>\n</tr>\n<th colspan=\"4\">Legacy errors (used by the endpoints files, profiles and contacts)</th>\n<tr>\n<td>400</td>\n<td>RequestBadRequestLegacyError</td>\n<td>500</td>\n<td>RequestInternalServerLegacyError</td>\n</tr>\n<tr>\n<td>406</td>\n<td>\nRequestMethodNotAcceptableLegacyError</td>\n<td></td>\n<td></td>\n</tr>\n</table>\n\n<h2 name=\"provided-methods\">🛠 Provided methods grouped by endpoint</h2>\n\n### Contact\n\n```ts\n\ncreateContact(contact: ContactCreatePerson | ContactCreateCompany): Promise<Result<ContactCreateResponse, RequestError>>\n\nretrieveContact(id: string): Promise<Result<ContactRetrieveResponse, RequestError>>\n\nupdateContact(id: string, contact: ContactUpdatePerson | ContactUpdateCompany): Promise<Result<ContactUpdateResponse, RequestError>>\n\nfilterContact(filter?: OptionalFilters & Partial<PagingParameters>): Promise<Result<ContactFilterRetrieveResponse, RequestError>>\n```\n\n### Country\n\n```ts\nretrieveListOfCountries(): Promise<Result<Country[], RequestError>>\n```\n\n### Credit note\n\n```ts\ncreateCreditNote(creditNote: CreditNoteCreate, optionalFinalized?: OptionalFinalized): Promise<Result<CreditNoteCreateResponse, RequestError>>\n\nretrieveCreditNote(id: string): Promise<Result<CreditNoteRetrieveResponse, RequestError>>\n\nrenderCreditNoteDocumentFileId(id: string): Promise<Result<DocumentFileId, RequestError>>\n```\n\n### Down payment invoice\n\n```ts\nretrieveDownPaymentInvoice(id: string): Promise<Result<DownPaymentInvoice, RequestError>>\n```\n\n### Event subscription\n\n```ts\ncreateEventSubscription(eventSubscription: EventSubscriptionCreate): Promise<Result<EventSubscription, RequestError>>\n\nretrieveEventSubscription(id: string): Promise<Result<EventSubscription, RequestError>>\n\nretrieveAllEventSubscriptions(): Promise<Result<EventSubscriptions, RequestError>>\n\ndeleteEventSubscription(id: string): Promise<Result<unknown, RequestError>>\n```\n\n### File\n\n```ts\nuploadFile(data: FormData): Promise<Result<FileResponse, RequestError>>\n\ndownloadFile(documentFileId: string, optionalParameter?: RenderType): Promise<Result<unknown, RequestError>>\n```\n\n### Invoice\n\n```ts\ncreateInvoice(invoice: InvoiceCreate | XRechnung, optionalFinalized?: OptionalFinalized): Promise<Result<InvoiceCreateResponse, RequestError>>\n\nretrieveInvoice(id: string): Promise<Result<InvoiceRetrieveResponse, RequestError>>\n\nrenderInvoiceDocumentFileId(id: string): Promise<Result<DocumentFileId, RequestError>>\n```\n\n### Order confirmation\n\n```ts\ncreateOrderConfirmation(orderConfirmation: OrderConfirmation): Promise<Result<OrderConfirmationResponse, RequestError>>\n\nretrieveOrderConfirmation(id: string): Promise<Result<OrderConfirmationRetrieveResponse, RequestError>>\n\nrenderOrderConfirmationDocumentFileId(id: string): Promise<Result<DocumentFileId, RequestError>>\n```\n\n### Payment\n\n```ts\nretrievePayment(id: string): Promise<Result<Payment, RequestError>>\n```\n\n### Payment condition\n\n```ts\nretrievePaymentConditionList(): Promise<Result<PaymentCondition, RequestError>>\n```\n\n### Posting category\n\n```ts\nretrieveListPostingCategories(): Promise<Result<PostingCategory[], RequestError>>\n```\n\n### Profile\n\n```ts\nretrieveProfile(): Promise<Result<Profile, RequestError>>\n```\n\n### Quotation\n\n```ts\ncreateQuotation(quotation: QuotationCreate, optionalFilter?: OptionalFinalized): Promise<Result<QuotationCreate, RequestError>>\n\nretrieveQuotation(id: string): Promise<Result<Partial<Quotation>, RequestError>>\n\nrenderQuotationDocumentFileId(id: string): Promise<Result<DocumentFileId, RequestError>>\n```\n\n### Recurring template\n\n```ts\nretrieveRecurringTemplate(id: string): Promise<Result<Partial<RecurringTemplate>, RequestError>>\n\nretrieveAllRecurringTemplates(optionalFilter?: PagingParameters): Promise<Result<RecurringTemplates, RequestError>>\n```\n\n### Voucher\n\n```ts\ncreateVoucher(voucher: CreateVoucher): Promise<Result<VoucherCreateResponse, RequestError>>\n\nretrieveVoucher(id: string): Promise<Result<Partial<Voucher>, RequestError>>\n\nupdateVoucher(id: string, voucher: CreateVoucher): Promise<Result<VoucherCreateResponse, RequestError>>\n\nfilterVoucher(voucherNumber: VoucherNumber): Promise<Result<Partial<Vouchers>, RequestError>>\n\nuploadFileToVoucher(data: FormData, id: string): Promise<Result<FileResponse, RequestError>>\n```\n\n### Voucherlist\n\n```ts\nretrieveVoucherlist(filterParameter: FilterParameter): Promise<Result<Voucherlist, RequestError>>\n```\n\n<h2 name=\"side-notes\">🔖 Side notes</h2>\n\n### Updating\n\nFor updating any type of vouchers where the \"version\" property is required, you first need to retrieve it and use the current \"version\" value to properly update.\n\n### Rendering Document File Id\n\nOnly possible for any type of vouchers that are not in \"draft\" mode.\n\n### Download File\n\nThe required id is not the id itself, it is the documentFileId, which can be required with the matching method and the vouchers id:\n\n```ts\nrenderCreditNoteDocumentFileId(id);\nrenderInvoiceDocumentFileId(id);\nrenderOrderConfirmationDocumentFileId(id);\nrenderQuotationDocumentFileId(id);\n```\n\n<h2 name=\"about\"><img src=\"images/favicon-32x32.png\" width=\"30\" height=\"30\"/> This package has been brought to you by elbstack!</h2>\n\nelbstack is a software engineering & design company. We question, we advise, and we're excited to help your next project to succeed.<br>\nWe offer software development and design as service. That's how we support you with the realisation of your projects - with individual employees or with a whole team. We love to work remotely, but we will work at your place, too.\n\n### 👩🏻‍💻👨🏽‍💻 We are hiring!\n\n<p>We are more than a classic software agency, rather like a highly self organized company with our own start-up incubator. You can choose how much, for whom and what you want to work for. Acquire your own customers and projects, simply make your sideproject become reality or even a proper start-up.</p>\n<p>Sounds like a scam?</p>\n\n<a href=\"https://www.kununu.com/de/elbstack2\">➡️ Go and check kununu.com</a><br>\n<a href=\"https://elbstack.com\">➡️ elbstack.com</a>\n","readmeFilename":"README.md"}