{"id":38781978,"url":"https://github.com/adpushup/woodlot","last_synced_at":"2026-01-17T12:25:42.974Z","repository":{"id":45583272,"uuid":"86692489","full_name":"adpushup/woodlot","owner":"adpushup","description":"An all-in-one JSON logging utility that supports ExpressJS HTTP logging, custom logging, provides multi-format output and an easy to use events API.","archived":false,"fork":false,"pushed_at":"2021-12-07T05:25:30.000Z","size":1477,"stargazers_count":266,"open_issues_count":2,"forks_count":9,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-10-07T13:01:52.474Z","etag":null,"topics":["apache-logging","express-middleware","http-logger","json-logging","logger","logger-events","logger-middleware","logging-library"],"latest_commit_sha":null,"homepage":"http://adpushup.github.io/woodlot/","language":"JavaScript","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/adpushup.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}},"created_at":"2017-03-30T10:58:01.000Z","updated_at":"2025-01-21T06:24:58.000Z","dependencies_parsed_at":"2022-07-26T11:47:07.485Z","dependency_job_id":null,"html_url":"https://github.com/adpushup/woodlot","commit_stats":null,"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/adpushup/woodlot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adpushup%2Fwoodlot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adpushup%2Fwoodlot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adpushup%2Fwoodlot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adpushup%2Fwoodlot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/adpushup","download_url":"https://codeload.github.com/adpushup/woodlot/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/adpushup%2Fwoodlot/sbom","scorecard":{"id":167581,"data":{"date":"2025-08-11","repo":{"name":"github.com/adpushup/woodlot","commit":"c4ae71d1849bfd22a228a6fcd0bb1bccb0f19311"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.4,"checks":[{"name":"Code-Review","score":3,"reason":"Found 5/16 approved changesets -- score normalized to 3","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":"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":"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":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"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":-1,"reason":"no workflows found","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":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"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":"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":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"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":"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":"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":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 19 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"}}]},"last_synced_at":"2025-08-16T15:20:34.184Z","repository_id":45583272,"created_at":"2025-08-16T15:20:34.184Z","updated_at":"2025-08-16T15:20:34.184Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28508464,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-17T11:50:55.898Z","status":"ssl_error","status_checked_at":"2026-01-17T11:50:55.569Z","response_time":85,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["apache-logging","express-middleware","http-logger","json-logging","logger","logger-events","logger-middleware","logging-library"],"created_at":"2026-01-17T12:25:42.893Z","updated_at":"2026-01-17T12:25:42.961Z","avatar_url":"https://github.com/adpushup.png","language":"JavaScript","funding_links":["https://www.patreon.com/arunmichaeldsouza"],"categories":[],"sub_categories":[],"readme":"\u003cimg src=\"https://raw.githubusercontent.com/adpushup/woodlot/master/icon.png\" width=\"250\" height=\"auto\" alt=\"woodlot icon\"/\u003e\n\n# woodlot [![npm version](https://badge.fury.io/js/woodlot.svg)](https://badge.fury.io/js/woodlot) [![NPM Downloads](https://img.shields.io/npm/dm/woodlot.svg?style=flat-square)](https://www.npmjs.com/package/woodlot) \u003cspan class=\"badge-patreon\"\u003e\u003ca href=\"https://www.patreon.com/arunmichaeldsouza\" title=\"Donate to this project using Patreon\"\u003e\u003cimg src=\"https://img.shields.io/badge/patreon-donate-blue.svg\" alt=\"Patreon donate button\" /\u003e\u003c/a\u003e\u003c/span\u003e\n\nAn all-in-one JSON logging utility that supports ExpressJS HTTP logging, custom logging, provides multi-format output and an easy to use events API.\n\n\u003e - Works as an HTTP logging middleware with `ExpressJS`\n\u003e - Support for custom logging with different logging levels\n\u003e - Provides log output in `json` format with request body/query params, headers and cookies\n\u003e - Support for Apache `common` and `combined` log formats as output\n\u003e - Multiple file stream support for log aggregation\n\u003e - Simple to use events API\n\u003e - Requires node \u003e= `0.10`\n\n\u003cbr/\u003e\n\n## Installation\n\n#### Using `npm`\n\n```javascript\nnpm install woodlot --save\n```\n\n#### Using `yarn`\n\n```javascript\nyarn add woodlot\n```\n\n\u003cbr/\u003e\n\n## Usage\n\n### As an ExpressJS middleware\n\nThe woodlot `middlewareLogger` can be hooked into the existing `ExpressJS` middleware chain and can be used to log all `HTTP` requests.\n\nExample -\n\n```javascript\nvar express = require('express');\nvar app = express();\nvar woodlot = require('woodlot').middlewareLogger;\n\napp.use(\n\twoodlot({\n\t\tstreams: ['./logs/app.log'],\n\t\tstdout: false,\n\t\troutes: {\n\t\t\twhitelist: ['/api', '/dashboard'],\n\t\t\tstrictChecking: false\n\t\t},\n\t\tuserAnalytics: {\n\t\t\tplatform: true,\n\t\t\tcountry: true\n\t\t},\n\t\tformat: {\n\t\t\ttype: 'json',\n\t\t\toptions: {\n\t\t\t\tcookies: true,\n\t\t\t\theaders: true,\n\t\t\t\tspacing: 4,\n\t\t\t\tseparator: '\\n'\n\t\t\t}\n\t\t}\n\t})\n);\n```\n\n#### Options\n\n#### `streams {array}`\n\nThis is an option that specifies the file stream endpoints where the generated logs will be saved. You can specify multiple streams using this option.\n\n#### `stdout {boolean} | Default: true`\n\nIt specifies whether the generated log entry should be logged to the standard output stream i.e. `process.stdout` or not.\n\n#### `routes {object}`\n\nThis option is used with the woodlot `middlewareLogger`. It specifies all the routes (with checking mode) for which logging is to be enabled. By default, log entry is generated for all the routes.\n\n##### `whitelist {array}`\n\nThis option is used with the `routes` option to specify the route whitelist.\n\n##### `strictChecking {boolean} | Default: false`\n\nThis option is used with the `routes` option to specify the checking mode for the route whitelist.\n\n```javascript\nroutes: {\n    whitelist: ['/api'],\n    strictChecking: false\n}\n```\n\nFor the above example, setting it to `false` will enable logging for all routes that have `api` in them. Example - `/api`, `/api/getUser`, `/api/getUser/all`, `/userapi` etc.\n\nWhereas, setting it to `true` will only enable logging for the `/api` route.\n\n#### `userAnalytics {object}`\n\nUse this option to add user details to your logs.\n\n##### `platform {boolean} | Default: false`\n\nUse this option with `userAnalytics`, to specify whether to include user `platform` info in the logs or not i.e. `browser`, `browserVersion`, `os`, and `osVersion`.\n\n##### `country {boolean} | Default: false`\n\nUse this option with `userAnalytics`, to specify whether to include user `country` info in the logs or not i.e. `name` and `isoCode`.\n\nThe `userAnalytics` option will add the following info to your logs -\n\n```javascript\n\"userAnalytics\": {\n    \"browser\": \"Chrome\",\n    \"browserVersion\": \"60.0.3112.90\",\n    \"os\": \"Mac OS\",\n    \"osVersion\": \"10.11.6\",\n    \"country\": {\n        \"name\": \"India\",\n        \"isoCode\": \"IN\"\n    }\n}\n```\n\n#### `format {object}`\n\nThis option sets the log output format and other settings related to that particular format.\n\n##### `type {string} | Default: 'json'`\n\nThe default output format is `json`. The `middlewareLogger` supports two more formats - [common](http://httpd.apache.org/docs/current/logs.html#common) and [combined](http://httpd.apache.org/docs/current/logs.html#combined), which are Apache's access log formats.\n\nThe generated output log for each format is as follows -\n\n##### json\n\n```javascript\n{\n    \"responseTime\": \"4ms\",\n    \"method\": \"GET\",\n    \"url\": \"/api\",\n    \"ip\": \"127.0.01\",\n    \"body\": {},\n    \"params\": {},\n    \"query\": {},\n    \"httpVersion\": \"1.1\",\n    \"statusCode\": 200,\n    \"timeStamp\": \"23/Apr/2017:20:46:01 +0000\",\n    \"contentType\": \"text/html; charset=utf-8\",\n    \"contentLength\": \"4\",\n    \"userAgent\": \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36\",\n    \"referrer\": null,\n    \"userAnalytics\": {\n        \"browser\": \"Chrome\",\n        \"browserVersion\": \"60.0.3112.90\",\n        \"os\": \"Mac OS\",\n        \"osVersion\": \"10.11.6\",\n        \"country\": {\n            \"name\": \"India\",\n            \"isoCode\": \"IN\"\n        }\n    },\n    \"headers\": {\n        \"host\": \"localhost:8000\",\n        \"connection\": \"keep-alive\",\n        \"accept-encoding\": \"gzip, deflate, sdch, br\",\n        \"accept-language\": \"en-US,en;q=0.8,la;q=0.6\"\n    },\n    \"cookies\": {\n        \"userId\": \"zasd-167279192-asknbke-0684\"\n    }\n}\n```\n\n\u003e `json` format supports logging of `body` params and `cookies`. If you wish to log them, please make sure to enable the `bodyParser` and `cookieParser` middlewares before woodlot.\n\n##### common\n\n```javascript\n127.0.01 - - [23/Apr/2017:20:47:28 +0000] \"GET /api HTTP/1.1\" 200 4\n```\n\n##### combined\n\n```javascript\n127.0.01 - - [23/Apr/2017:20:48:10 +0000] \"GET /api HTTP/1.1\" 200 4 \"-\" \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36\"\n```\n\n\u003e The timestamp generated in all logs is in `ISO` format.\n\n#### `options {object}`\n\n##### `cookies {boolean} | Default: false`\n\nThis option is to be used with the `json` format. It specifies whether you want to log request `cookies` or not.\n\n\u003e Please make sure that the `cookieParser` middleware is enabled before woodlot, if this option is to be used.\n\n##### `headers {boolean} | Default: true`\n\nThis option is to be used with the `json` format. It specifies whether you want to log request `headers` or not.\n\n##### `compact {boolean} | Default: false`\n\nThis option is to be used with the `json` format. It specifies whether you want to log json as one line compact string.\n\n**NOTE** `spacing` option will be ignored if this option is set to true.\n\n##### `spacing {string|number} | Default: \\t`\n\nThis option is to be used with the `json` format. It specifies the indentation for the generated log entry. You can specify a tab `\\t` or numeric values `4`, `8` for spaces.\n\n##### `separator {string} | Default: \\n`\n\nThis option can be used with any of the supported formats. It specfies the separator between two log entires. You can add a newline character `\\n`, a `whitespace` or any other valid character.\n\n\u003cbr/\u003e\n\n### Custom logging\n\nThe woodlot `customLogger` can be used to perform custom logging with different logging levels.\n\nExample -\n\n```javascript\nvar express = require('express');\nvar app = express();\nvar woodlotCustomLogger = require('woodlot').customLogger;\n\nvar woodlot = new woodlotCustomLogger({\n\tstreams: ['./logs/custom.log'],\n\tstdout: false,\n\tformat: {\n\t\ttype: 'json',\n\t\toptions: {\n\t\t\tspacing: 4,\n\t\t\tseparator: '\\n'\n\t\t}\n\t}\n});\n\napp.get('/', function (req, res) {\n\tvar id = 4533;\n\twoodlot.info('User id ' + id + ' accessed');\n\treturn res.status(200).send({ userId: id });\n});\n```\n\n#### Log levels\n\n##### info\n\n```javascript\nwoodlot.info('Data sent successfully');\n```\n\n##### debug\n\n```javascript\nwoodlot.debug('Debugging main function');\n```\n\n##### warn\n\n```javascript\nwoodlot.warn('User Id is required');\n```\n\n##### err\n\n```javascript\nwoodlot.err('Server error occurred');\n```\n\n#### Options\n\n#### `streams {array}`\n\nSee [here](https://github.com/adpushup/woodlot#streams-array).\n\n#### `stdout {boolean} | Default: true`\n\nSee [here](https://github.com/adpushup/woodlot#stdout-boolean--default-true).\n\n#### `format {object}`\n\nSee [here](https://github.com/adpushup/woodlot#format-object).\n\n##### `type {string} | Default: 'json'`\n\nThe default output format is `json`. The `customLogger` supports one more format - `text`.\n\nThe generated output log for each format is as follows -\n\n##### json\n\n```javascript\n{\n    \"timeStamp\": \"23/Apr/2017:17:02:33 +0000\",\n    \"message\": \"Data sent successfully\",\n    \"level\": \"INFO\"\n}\n```\n\n##### text\n\n```javascript\nINFO [23/Apr/2017:17:02:33 +0000]: \"Data sent successfully\"\n```\n\n#### `options {object}`\n\n##### `compact {boolean} | Default: false`\n\nThis option is to be used with the `json` format. It specifies whether you want to log json as one line compact string.\n\n**NOTE** `spacing` option will be ignored if this option is set to true.\n\n##### `spacing {string|number} | Default: \\t`\n\nThis option is to be used with the `json` format. It specifies the indentation for the generated log entry. You can specify a tab `\\t` or numeric values `4`, `8` for spaces.\n\n##### `separator {string} | Default: \\n`\n\nThis option can be used with any of the supported formats. It specfies the separator between two log entires. You can add a newline character `\\n`, a `whitespace` or any other valid character.\n\n\u003cbr/\u003e\n\n## Events\n\nWoodlot emits events at various operations that can be used to track critical data.\n\nExample -\n\n```javascript\nvar woodlotEvents = require('woodlot').events;\n\nwoodlotEvents.on('reqLog', function (log) {\n\tconsole.log('New log generated');\n});\n```\n\nThe returned log entry from each event will be of the same format as the one defined in the woodlot configuration.\n\n### middlewareLogger events\n\n#### `reqLog`\n\nThis event is fired whenever a log entry is generated.\n\n```javascript\nwoodlotEvents.on('reqLog', function (log) {\n\tconsole.log('The following log entry was added - \\n' + log);\n});\n```\n\n#### `:statusCode`\n\nThis event is fired whenever a specific status code is returned from the request.\n\n```javascript\nwoodlotEvents.on('200', function (log) {\n\tconsole.log('Success!');\n});\n```\n\n```javascript\nwoodlotEvents.on('403', function (log) {\n\tconsole.log('Request forbidden!');\n});\n```\n\n### `reqErr`\n\nThis event is fired whenever an error is returned from the request.\n\nAll requests returning a status code of `\u003e=400` are considered to be errored. Please refer to the HTTP status codes [guide](http://www.restapitutorial.com/httpstatuscodes.html) for more info.\n\n```javascript\nwoodlotEvents.on('reqErr', function (log) {\n\tconsole.log('Errored!');\n});\n```\n\n### customLogger events\n\n#### `info`\n\nThis event is fired whenever an `info` level log entry is generated.\n\n```javascript\nwoodlotEvents.on('info', function (log) {\n\tconsole.log('Info log - ' + log);\n});\n```\n\n#### `debug`\n\nThis event is fired whenever a `debug` level log entry is generated.\n\n```javascript\nwoodlotEvents.on('debug', function (log) {\n\tconsole.log('Debug log - ' + log);\n});\n```\n\n#### `warn`\n\nThis event is fired whenever a `warn` level log entry is generated.\n\n```javascript\nwoodlotEvents.on('warn', function (log) {\n\tconsole.log('Warn log - ' + log);\n});\n```\n\n#### `err`\n\nThis event is fired whenever an `err` level log entry is generated.\n\n```javascript\nwoodlotEvents.on('err', function (log) {\n\tconsole.log('Error log - ' + log);\n});\n```\n\n\u003cbr/\u003e\n\n## Contributors\n\n|  [\u003cimg src=\"https://avatars3.githubusercontent.com/u/4924614\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eArun Michael Dsouza\u003c/b\u003e\u003c/sub\u003e](https://github.com/ArunMichaelDsouza) | [\u003cimg src=\"https://avatars2.githubusercontent.com/u/10044846\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eDhiraj Singh\u003c/b\u003e\u003c/sub\u003e](https://github.com/DhirajAdPushup)  |  [\u003cimg src=\"https://avatars1.githubusercontent.com/u/6550699\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eChen Li\u003c/b\u003e\u003c/sub\u003e](https://github.com/sirius226) | [\u003cimg src=\"https://avatars.githubusercontent.com/u/3116103?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMichael Samblanet\u003c/b\u003e\u003c/sub\u003e](https://github.com/msamblanet)  | [\u003cimg src=\"https://avatars.githubusercontent.com/u/17977330?v=4\" width=\"100px;\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eAnil Panghal\u003c/b\u003e\u003c/sub\u003e](https://github.com/AnilAdPushup)  |\n|---|---|---|---|---|\n\n\u003cbr/\u003e\n\n## License\n\nMIT License\n\nCopyright (c) 2017 AdPushup Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadpushup%2Fwoodlot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fadpushup%2Fwoodlot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fadpushup%2Fwoodlot/lists"}