From 283d516331ea8b37311d08f3b0af0dce657c75b6 Mon Sep 17 00:00:00 2001
From: babayaga
Date: Sun, 23 Feb 2025 19:13:41 +0100
Subject: [PATCH] esm init registry | vfs | discourse
---
packages/.gitignore | 5 +
packages/discourse/.gitignore | 5 +
packages/discourse/.npmignore | 4 +
packages/discourse/.vscode/launch.json | 178 +
packages/discourse/.vscode/settings.json | 9 +
packages/discourse/LICENSE | 9 +
packages/discourse/README.md | 161 +
packages/discourse/_cli.d.ts | 3 +
packages/discourse/_cli.js | 71 +
packages/discourse/_cli.js.map | 1 +
packages/discourse/_package.json | 85 +
packages/discourse/commands/category.d.ts | 12 +
packages/discourse/commands/category.js | 103 +
packages/discourse/commands/category.js.map | 1 +
.../discourse/commands/import-oa-howtos.d.ts | 2 +
.../discourse/commands/import-oa-howtos.js | 53 +
.../discourse/commands/import-oa-users.d.ts | 2 +
.../discourse/commands/import-oa-users.js | 88 +
packages/discourse/commands/import-oa.d.ts | 10 +
packages/discourse/commands/import-oa.js | 89 +
packages/discourse/commands/info.d.ts | 2 +
packages/discourse/commands/info.js | 27 +
packages/discourse/commands/info.js.map | 1 +
packages/discourse/commands/product.d.ts | 14 +
packages/discourse/commands/product.js | 110 +
packages/discourse/commands/product.js.map | 1 +
packages/discourse/commands/query.d.ts | 2 +
packages/discourse/commands/query.js | 56 +
packages/discourse/commands/query.js.map | 1 +
.../discourse/commands/sync-component.d.ts | 4 +
packages/discourse/commands/sync-component.js | 124 +
packages/discourse/commands/sync-file.d.ts | 2 +
packages/discourse/commands/sync-file.js | 55 +
packages/discourse/config/machines.js | 0
packages/discourse/constants.d.ts | 1 +
packages/discourse/constants.js | 5 +
packages/discourse/constants.js.map | 1 +
packages/discourse/discourse-sync.json | 34 +
packages/discourse/docs/data.md | 22 +
packages/discourse/index.d.ts | 9 +
packages/discourse/index.js | 89 +
packages/discourse/index.js.map | 1 +
packages/discourse/index.md | 146 +
packages/discourse/lib/discourse/cache.d.ts | 10 +
packages/discourse/lib/discourse/cache.js | 122 +
.../discourse/lib/discourse/constants.d.ts | 70 +
packages/discourse/lib/discourse/constants.js | 100 +
packages/discourse/lib/discourse/index.d.ts | 181 +
packages/discourse/lib/discourse/index.js | 936 +
packages/discourse/lib/discourse/index.js.map | 1 +
packages/discourse/lib/discourse/types.d.ts | 697 +
packages/discourse/lib/discourse/types.js | 5 +
packages/discourse/lib/discourse/types.js.map | 1 +
.../discourse/lib/discourse/types/bevry.d.ts | 130 +
.../discourse/lib/discourse/types/bevry.js | 3 +
.../lib/discourse/types/bevry.js.map | 1 +
.../lib/discourse/types/discourse.d.ts | 364 +
.../lib/discourse/types/discourse.js | 5 +
.../lib/discourse/types/discourse.js.map | 1 +
packages/discourse/lib/discourse/util.d.ts | 26 +
packages/discourse/lib/discourse/util.js | 184 +
packages/discourse/lib/discourse/util.js.map | 1 +
packages/discourse/lib/discourse/youtube.d.ts | 260 +
packages/discourse/lib/discourse/youtube.js | 30 +
.../discourse/lib/discourse/youtube.js.map | 1 +
packages/discourse/lib/git/index.d.ts | 5 +
packages/discourse/lib/git/index.js | 39 +
packages/discourse/lib/index.d.ts | 2 +
packages/discourse/lib/index.js | 19 +
packages/discourse/lib/index.js.map | 1 +
packages/discourse/lib/markdown/Pattern.d.ts | 7 +
packages/discourse/lib/markdown/Pattern.js | 14 +
packages/discourse/lib/markdown/Rule.d.ts | 7 +
packages/discourse/lib/markdown/Rule.js | 14 +
packages/discourse/lib/markdown/index.d.ts | 14 +
packages/discourse/lib/markdown/index.js | 104 +
packages/discourse/lib/markdown/types.d.ts | 5 +
packages/discourse/lib/markdown/types.js | 3 +
packages/discourse/lib/oa/commons.d.ts | 27 +
packages/discourse/lib/oa/commons.js | 106 +
packages/discourse/lib/oa/howtos.d.ts | 10 +
packages/discourse/lib/oa/howtos.js | 475 +
packages/discourse/lib/oa/index.d.ts | 3 +
packages/discourse/lib/oa/index.js | 20 +
packages/discourse/lib/oa/lib.d.ts | 3 +
packages/discourse/lib/oa/lib.js | 197 +
packages/discourse/lib/oa/types.d.ts | 91 +
packages/discourse/lib/oa/types.js | 3 +
packages/discourse/lib/oa/users.d.ts | 30 +
packages/discourse/lib/oa/users.js | 936 +
packages/discourse/lib/oa/utils.d.ts | 26 +
packages/discourse/lib/oa/utils.js | 172 +
packages/discourse/lib/osr/index.d.ts | 1 +
packages/discourse/lib/osr/index.js | 18 +
packages/discourse/lib/osr/urls.d.ts | 1 +
packages/discourse/lib/osr/urls.js | 6 +
packages/discourse/lib/sync/commons.d.ts | 12 +
packages/discourse/lib/sync/commons.js | 174 +
packages/discourse/lib/sync/component.d.ts | 6 +
packages/discourse/lib/sync/component.js | 373 +
packages/discourse/lib/sync/download.d.ts | 5 +
packages/discourse/lib/sync/download.js | 48 +
packages/discourse/lib/sync/file.d.ts | 6 +
packages/discourse/lib/sync/file.js | 253 +
packages/discourse/lib/sync/fs.d.ts | 6 +
packages/discourse/lib/sync/fs.js | 275 +
packages/discourse/lib/sync/index.d.ts | 6 +
packages/discourse/lib/sync/index.js | 36 +
packages/discourse/lib/sync/osrl.d.ts | 4 +
packages/discourse/lib/sync/osrl.js | 75 +
packages/discourse/lib/types.d.ts | 0
packages/discourse/lib/types.js | 2 +
packages/discourse/lib/types.js.map | 1 +
packages/discourse/main.d.ts | 2 +
packages/discourse/main.js | 28 +
packages/discourse/main.js.map | 1 +
packages/discourse/options.d.ts | 3 +
packages/discourse/options.js | 39 +
packages/discourse/options.js.map | 1 +
packages/discourse/package-lock.json | 5849 ++
packages/discourse/scripts/link-dev.sh | 1 +
packages/discourse/scripts/sync-components.sh | 1 +
packages/discourse/scripts/test.sh | 14 +
packages/discourse/src/_cli.ts | 81 +
.../src/commands/import-oa-howtos.ts | 95 +
.../discourse/src/commands/import-oa-users.ts | 118 +
packages/discourse/src/commands/info.ts | 24 +
packages/discourse/src/commands/query.ts | 59 +
.../discourse/src/commands/sync-component.ts | 137 +
.../discourse/src/commands/sync-directory.ts | 142 +
packages/discourse/src/commands/sync-file.ts | 64 +
packages/discourse/src/constants.ts | 1 +
packages/discourse/src/index.ts | 82 +
packages/discourse/src/lib/discourse/cache.ts | 192 +
.../discourse/src/lib/discourse/constants.ts | 119 +
packages/discourse/src/lib/discourse/index.ts | 1295 +
packages/discourse/src/lib/discourse/types.ts | 761 +
packages/discourse/src/lib/git/index.ts | 42 +
packages/discourse/src/lib/index.ts | 3 +
.../discourse/src/lib/markdown/Pattern.ts | 13 +
packages/discourse/src/lib/markdown/Rule.ts | 17 +
.../discourse/src/lib/markdown/index.test.ts | 144 +
packages/discourse/src/lib/markdown/index.ts | 125 +
packages/discourse/src/lib/markdown/page.ts | 28 +
packages/discourse/src/lib/markdown/types.ts | 6 +
packages/discourse/src/lib/oa/commons.ts | 141 +
packages/discourse/src/lib/oa/howtos.ts | 607 +
packages/discourse/src/lib/oa/index.ts | 4 +
packages/discourse/src/lib/oa/lib.ts | 194 +
packages/discourse/src/lib/oa/types.ts | 120 +
packages/discourse/src/lib/oa/users.ts | 1090 +
packages/discourse/src/lib/oa/utils.ts | 180 +
packages/discourse/src/lib/osr/index.ts | 1 +
packages/discourse/src/lib/osr/urls.ts | 2 +
packages/discourse/src/lib/sync/commons.ts | 204 +
packages/discourse/src/lib/sync/component.ts | 454 +
packages/discourse/src/lib/sync/directory.ts | 400 +
packages/discourse/src/lib/sync/download.ts | 46 +
packages/discourse/src/lib/sync/file.ts | 314 +
packages/discourse/src/lib/sync/index.ts | 55 +
packages/discourse/src/lib/sync/osrl.ts | 80 +
packages/discourse/src/main.ts | 22 +
packages/discourse/src/options.ts | 33 +
packages/discourse/src/types.ts | 214 +
packages/discourse/temp/h.json | 1 +
packages/discourse/temp/l.md | 1 +
packages/discourse/temp/post.html | 969 +
packages/discourse/temp/t.json | 7 +
packages/discourse/temp/user.json | 447 +
.../templates/discourse/machines/debug.osr | 6 +
.../templates/discourse/machines/global.json | 33 +
.../discourse/machines/header_jekyll.osr | 95 +
.../discourse/machines/plugins/html.js | 50 +
.../templates/discourse/machines/root.html | 54 +
.../discourse/machines/variables.osr | 56 +
.../discourse/machines/widgets/authors.osr | 10 +
.../machines/widgets/authors_html.osr | 8 +
.../machines/widgets/extra_resources.md | 0
.../discourse/machines/widgets/forum.osr | 25 +
.../discourse/machines/widgets/gallery.osr | 10 +
.../discourse/machines/widgets/howtos.osr | 12 +
.../machines/widgets/other_products.osr | 25 +
.../machines/widgets/overview_drawings.osr | 27 +
.../discourse/machines/widgets/parts.osr | 7 +
.../discourse/machines/widgets/resources.osr | 45 +
.../discourse/machines/widgets/showreel.osr | 7 +
.../machines/widgets/social_links.osr | 38 +
.../discourse/machines/widgets/specs.osr | 18 +
.../discourse/machines/widgets/table.osr | 16 +
packages/discourse/tests/image.jpg | Bin 0 -> 130249 bytes
packages/discourse/tests/sync/md.md | 52 +
packages/discourse/tmp-a.json | 268 +
packages/discourse/tmp.json | 268 +
packages/discourse/tsconfig.json | 26 +
packages/discourse/types.d.ts | 158 +
packages/discourse/types.js | 41 +
packages/discourse/types.js.map | 1 +
packages/registry/.gitignore | 4 +
packages/registry/.npmignore | 4 +
packages/registry/LICENSE | 9 +
packages/registry/README.md | 21 +
packages/registry/_cli.d.ts | 3 +
packages/registry/_cli.js | 21 +
packages/registry/_cli.js.map | 1 +
packages/registry/commands/info.d.ts | 2 +
packages/registry/commands/info.js | 51 +
packages/registry/commands/info.js.map | 1 +
packages/registry/constants.d.ts | 1 +
packages/registry/constants.js | 5 +
packages/registry/constants.js.map | 1 +
packages/registry/index.d.ts | 4 +
packages/registry/index.js | 26 +
packages/registry/index.js.map | 1 +
packages/registry/lib/index.d.ts | 2 +
packages/registry/lib/index.js | 19 +
packages/registry/lib/index.js.map | 1 +
packages/registry/lib/keyv.d.ts | 5 +
packages/registry/lib/keyv.js | 28 +
packages/registry/lib/keyv.js.map | 1 +
packages/registry/lib/types.d.ts | 2 +
packages/registry/lib/types.js | 3 +
packages/registry/lib/types.js.map | 1 +
packages/registry/main.d.ts | 2 +
packages/registry/main.js | 17 +
packages/registry/main.js.map | 1 +
packages/registry/package-lock.json | 4848 ++
packages/registry/package.json | 48 +
packages/registry/ref/CKBaseManager.h | 743 +
packages/registry/ref/CKBaseManager.ts | 273 +
packages/registry/ref/CKEnums.h | 518 +
packages/registry/ref/CKEnums.ts | 273 +
packages/registry/ref/CKParameter.h | 160 +
packages/registry/ref/CKParameter.ts | 202 +
packages/registry/ref/CKParameterIn.h | 270 +
packages/registry/ref/CKParameterIn.ts | 110 +
packages/registry/ref/CKParameterLocal.h | 91 +
packages/registry/ref/CKParameterLocal.ts | 43 +
packages/registry/ref/CKParameterManager.h | 335 +
packages/registry/ref/CKParameterManager.ts | 335 +
packages/registry/ref/CKParameterOperation.h | 171 +
packages/registry/ref/CKParameterOperation.ts | 118 +
packages/registry/ref/CKParameterOut.h | 128 +
packages/registry/ref/CKParameterOut.ts | 69 +
packages/registry/ref/CKPluginManager.h | 318 +
packages/registry/ref/CKPluginManager.ts | 104 +
packages/registry/ref/to-typescript.md | 5 +
packages/registry/ref/toTS.sh | 1 +
packages/registry/src/.gitignore | 0
packages/registry/src/_cli.ts | 23 +
packages/registry/src/commands/info.ts | 53 +
packages/registry/src/commands/test.ts | 66 +
packages/registry/src/constants.ts | 1 +
packages/registry/src/index.ts | 9 +
packages/registry/src/lib/index.ts | 7 +
packages/registry/src/lib/keyv.ts | 22 +
packages/registry/src/lib/types.ts | 2 +
packages/registry/src/main.ts | 14 +
packages/registry/src/options.ts | 18 +
packages/registry/src/types.ts | 2 +
packages/registry/tsconfig.json | 30 +
packages/registry/types.d.ts | 1 +
packages/registry/types.js | 3 +
packages/registry/types.js.map | 1 +
packages/vfs/.gitignore | 4 +
packages/vfs/.npmignore | 4 +
packages/vfs/LICENSE | 9 +
packages/vfs/README.md | 7 +
packages/vfs/_cli.js | 16 +
packages/vfs/_cli.js.map | 1 +
packages/vfs/_package.json | 78 +
packages/vfs/argv.js | 230 +
packages/vfs/argv.js.map | 1 +
packages/vfs/commands/info.js | 52 +
packages/vfs/constants.js | 6 +
packages/vfs/constants.js.map | 1 +
packages/vfs/index.js | 20 +
packages/vfs/index.js.map | 1 +
packages/vfs/main.js | 18 +
packages/vfs/main.js.map | 1 +
packages/vfs/package-lock.json | 8098 +++
packages/vfs/rclone.js/.gitignore | 5 +
packages/vfs/rclone.js/CNAME | 1 +
packages/vfs/rclone.js/README.md | 159 +
packages/vfs/rclone.js/_config.yml | 1 +
packages/vfs/rclone.js/bin/rclone.exe | Bin 0 -> 62620160 bytes
packages/vfs/rclone.js/bin/rclone.js | 49 +
packages/vfs/rclone.js/package-lock.json | 69 +
packages/vfs/rclone.js/package.json | 57 +
packages/vfs/rclone.js/rclone.js | 205 +
packages/vfs/rclone.js/rclone/selfupdate.js | 107 +
packages/vfs/rclone.js/test/index.js | 49 +
packages/vfs/rclone.js/test/rclone-test.js | 135 +
packages/vfs/ref-rclone/api_examples.sh | 34 +
packages/vfs/ref-rclone/gdrive_sync.sh | 22 +
packages/vfs/ref-rclone/local_sync.sh | 19 +
.../vfs/ref-rclone/rclone-examples/README.md | 20 +
.../vfs/ref-rclone/rclone-examples/api.conf | 10 +
.../vfs/ref-rclone/rclone-examples/local.conf | 8 +
.../vfs/ref-rclone/rclone-examples/s3.conf | 11 +
.../vfs/ref-rclone/rclone-examples/sftp.conf | 12 +
packages/vfs/ref-rclone/rclone.conf | 0
packages/vfs/ref-server/app.module.ts | 18 +
packages/vfs/ref-server/config.ts | 6 +
.../ref-server/controllers/ContextManager.ts | 27 +
.../controllers/account.controller.ts | 79 +
.../ref-server/controllers/base.controller.ts | 61 +
.../controllers/content-types.controller.ts | 163 +
.../controllers/devices.controller.ts | 423 +
.../ref-server/controllers/events.gateway.ts | 76 +
.../controllers/groups.controller.ts | 165 +
packages/vfs/ref-server/controllers/index.ts | 18 +
.../controllers/permissions.controller.ts | 182 +
.../controllers/projects.controller.ts | 164 +
.../controllers/users.controller.ts | 188 +
packages/vfs/ref-server/controllers/utils.ts | 10 +
.../ref-server/controllers/vfs.controller.ts | 197 +
packages/vfs/ref-server/core.module.ts | 21 +
.../decorators/permissions.decorator.ts | 3 +
.../ref-server/decorators/roles.decorator.ts | 3 +
packages/vfs/ref-server/dto/account.dto.ts | 12 +
.../vfs/ref-server/dto/content-type.dto.ts | 14 +
packages/vfs/ref-server/dto/device.dto.ts | 55 +
packages/vfs/ref-server/dto/file.dto.ts | 5 +
.../dto/group-with-permissions.dto.ts | 20 +
packages/vfs/ref-server/dto/group.dto.ts | 15 +
.../ref-server/dto/in-account-login.dto.ts | 16 +
.../ref-server/dto/in-account-register.dto.ts | 17 +
packages/vfs/ref-server/dto/in-account.dto.ts | 26 +
.../vfs/ref-server/dto/in-content-type.dto.ts | 14 +
packages/vfs/ref-server/dto/in-device.dto.ts | 10 +
packages/vfs/ref-server/dto/in-file.dto.ts | 3 +
packages/vfs/ref-server/dto/in-group.dto.ts | 14 +
.../vfs/ref-server/dto/in-permission.dto.ts | 20 +
packages/vfs/ref-server/dto/in-project.dto.ts | 4 +
packages/vfs/ref-server/dto/in-token.dto.ts | 9 +
packages/vfs/ref-server/dto/in-user.dto.ts | 44 +
packages/vfs/ref-server/dto/meta.dto.ts | 12 +
.../ref-server/dto/out-account-token.dto.ts | 14 +
.../ref-server/dto/out-content-type.dto.ts | 10 +
.../ref-server/dto/out-content-types.dto.ts | 14 +
packages/vfs/ref-server/dto/out-device.dto.ts | 9 +
.../vfs/ref-server/dto/out-devices.dto.ts | 14 +
packages/vfs/ref-server/dto/out-file.dto.ts | 9 +
packages/vfs/ref-server/dto/out-group.dto.ts | 10 +
packages/vfs/ref-server/dto/out-groups.dto.ts | 14 +
.../vfs/ref-server/dto/out-permission.dto.ts | 11 +
.../vfs/ref-server/dto/out-permissions.dto.ts | 14 +
.../vfs/ref-server/dto/out-project.dto.ts | 9 +
packages/vfs/ref-server/dto/out-user.dto.ts | 10 +
packages/vfs/ref-server/dto/out-users.dto.ts | 14 +
packages/vfs/ref-server/dto/permission.dto.ts | 20 +
packages/vfs/ref-server/dto/project.dto.ts | 21 +
packages/vfs/ref-server/dto/user.dto.ts | 41 +
.../entities/content-type.entity.ts | 40 +
.../vfs/ref-server/entities/device.entity.ts | 151 +
.../vfs/ref-server/entities/file.entity.ts | 50 +
.../vfs/ref-server/entities/group.entity.ts | 70 +
packages/vfs/ref-server/entities/index.ts | 9 +
.../ref-server/entities/permission.entity.ts | 67 +
.../vfs/ref-server/entities/project.entity.ts | 64 +
.../vfs/ref-server/entities/user.entity.ts | 130 +
packages/vfs/ref-server/errors.ts | 332 +
.../exceptions/custom-exception.filter.ts | 38 +
.../exceptions/custom-validation.error.ts | 9 +
packages/vfs/ref-server/extensions/Evented.ts | 24 +
packages/vfs/ref-server/extensions/Logged.ts | 15 +
.../vfs/ref-server/guards/access.guard.ts | 57 +
packages/vfs/ref-server/interfaces.ts | 51 +
packages/vfs/ref-server/lib.ts | 0
packages/vfs/ref-server/log.ts | 19 +
.../ref-server/manager/ConnectionManager.ts | 218 +
packages/vfs/ref-server/manager/Context.ts | 67 +
.../migrations/FillData1514404694792.ts | 240 +
.../vfs/ref-server/migrations/marantz.json | 817 +
packages/vfs/ref-server/model/Connection.ts | 34 +
.../pipes/parse-int-with-default.pipe.ts | 21 +
.../vfs/ref-server/pipes/validation.pipe.ts | 26 +
packages/vfs/ref-server/protocols/Protocol.ts | 79 +
packages/vfs/ref-server/protocols/Tcp.ts | 450 +
packages/vfs/ref-server/server.ts | 66 +
.../vfs/ref-server/services/DeviceService.ts | 4 +
.../ref-server/services/account.service.ts | 93 +
.../vfs/ref-server/services/groups.service.ts | 42 +
packages/vfs/ref-server/services/index.ts | 8 +
.../vfs/ref-server/services/token.service.ts | 50 +
packages/vfs/ref-server/types.ts | 53 +
packages/vfs/ref/LICENSE | 29 +
packages/vfs/ref/Makefile | 28 +
packages/vfs/ref/acl/ACLC.ts | 745 +
packages/vfs/ref/acl/backend.ts | 87 +
packages/vfs/ref/acl/data/File.ts | 51 +
packages/vfs/ref/acl/data/Memory.ts | 178 +
packages/vfs/ref/acl/interfaces.ts | 90 +
.../ControlFreak/services/Directory.ts | 48 +
packages/vfs/ref/components/Component.ts | 30 +
packages/vfs/ref/components/xfile/xfile.ts | 188 +
.../ref/components/xideve/ExportOptions.ts | 76 +
.../vfs/ref/components/xideve/Exporter.ts | 637 +
.../ref/components/xideve/export/export.js | 641 +
.../ref/components/xideve/routes/Preview.ts | 92 +
.../components/xideve/services/Workbench.ts | 73 +
.../vfs/ref/components/xideve/views/debug.ejs | 417 +
.../ref/components/xideve/views/release.ejs | 304 +
packages/vfs/ref/components/xideve/xideve.ts | 22 +
packages/vfs/ref/console.ts | 24 +
packages/vfs/ref/debug.ts | 64 +
packages/vfs/ref/di/README.md | 20 +
packages/vfs/ref/di/agent.spec.ts | 63 +
packages/vfs/ref/di/agent.ts | 98 +
packages/vfs/ref/di/core/attribute.ts | 40 +
packages/vfs/ref/di/core/chain.ts | 28 +
packages/vfs/ref/di/core/decorator.ts | 110 +
packages/vfs/ref/di/core/index.ts | 6 +
packages/vfs/ref/di/core/interceptor.ts | 53 +
.../vfs/ref/di/core/interceptors/construct.ts | 55 +
.../vfs/ref/di/core/interceptors/prototype.ts | 45 +
.../vfs/ref/di/core/interceptors/proxy.ts | 90 +
packages/vfs/ref/di/core/invocation.ts | 35 +
packages/vfs/ref/di/core/metadata.ts | 63 +
packages/vfs/ref/di/core/reflection.spec.ts | 55 +
packages/vfs/ref/di/core/reflection.ts | 113 +
packages/vfs/ref/di/core/utils.ts | 60 +
packages/vfs/ref/di/domain.spec.ts | 95 +
packages/vfs/ref/di/domain.ts | 100 +
packages/vfs/ref/di/extra/cache.spec.ts | 56 +
packages/vfs/ref/di/extra/cache.ts | 61 +
packages/vfs/ref/di/extra/conditional.spec.ts | 45 +
packages/vfs/ref/di/extra/conditional.ts | 46 +
packages/vfs/ref/di/extra/failure.spec.ts | 45 +
packages/vfs/ref/di/extra/failure.ts | 34 +
packages/vfs/ref/di/extra/index.ts | 9 +
packages/vfs/ref/di/extra/inject.spec.ts | 81 +
packages/vfs/ref/di/extra/inject.ts | 17 +
packages/vfs/ref/di/extra/normalize.spec.ts | 73 +
packages/vfs/ref/di/extra/normalize.ts | 33 +
.../vfs/ref/di/extra/prerequisite.spec.ts | 52 +
packages/vfs/ref/di/extra/prerequisite.ts | 47 +
packages/vfs/ref/di/extra/ready.spec.ts | 55 +
packages/vfs/ref/di/extra/ready.ts | 13 +
packages/vfs/ref/di/extra/stream.spec.ts | 28 +
packages/vfs/ref/di/extra/stream.ts | 30 +
packages/vfs/ref/di/extra/success.spec.ts | 47 +
packages/vfs/ref/di/extra/success.ts | 36 +
packages/vfs/ref/di/extra/timestamp.spec.ts | 81 +
packages/vfs/ref/di/extra/timestamp.ts | 25 +
packages/vfs/ref/di/index.ts | 16 +
packages/vfs/ref/fs/append.ts | 53 +
packages/vfs/ref/fs/copy.ts | 619 +
packages/vfs/ref/fs/dir.ts | 176 +
packages/vfs/ref/fs/errors.ts | 46 +
packages/vfs/ref/fs/exists.ts | 52 +
packages/vfs/ref/fs/file.ts | 167 +
packages/vfs/ref/fs/find.ts | 121 +
packages/vfs/ref/fs/imports.ts | 8 +
packages/vfs/ref/fs/inspect.ts | 246 +
packages/vfs/ref/fs/inspect_tree.ts | 141 +
packages/vfs/ref/fs/interfaces.ts | 474 +
packages/vfs/ref/fs/iterator.ts | 40 +
packages/vfs/ref/fs/jetpack.ts | 328 +
packages/vfs/ref/fs/list.ts | 66 +
packages/vfs/ref/fs/move.ts | 108 +
packages/vfs/ref/fs/playground.ts | 208 +
packages/vfs/ref/fs/promisify.ts | 44 +
packages/vfs/ref/fs/read.ts | 92 +
packages/vfs/ref/fs/remove.ts | 352 +
packages/vfs/ref/fs/rename.ts | 23 +
packages/vfs/ref/fs/streams.ts | 2 +
packages/vfs/ref/fs/symlink.ts | 50 +
packages/vfs/ref/fs/uri.ts | 433 +
packages/vfs/ref/fs/utils/dot.ts | 12 +
packages/vfs/ref/fs/utils/matcher.ts | 79 +
packages/vfs/ref/fs/utils/mime_match.ts | 19 +
packages/vfs/ref/fs/utils/mode.ts | 12 +
packages/vfs/ref/fs/utils/paths.ts | 41 +
packages/vfs/ref/fs/utils/platform.ts | 40 +
packages/vfs/ref/fs/utils/strings.ts | 15 +
packages/vfs/ref/fs/utils/tree_walker.ts | 119 +
packages/vfs/ref/fs/utils/validate.ts | 119 +
packages/vfs/ref/fs/utils/wildcard.ts | 65 +
packages/vfs/ref/fs/write.ts | 92 +
packages/vfs/ref/global.ts | 18 +
packages/vfs/ref/index.d.ts | 11 +
packages/vfs/ref/index.ts | 136 +
packages/vfs/ref/interfaces/Application.ts | 9 +
packages/vfs/ref/interfaces/CI.ts | 19 +
packages/vfs/ref/interfaces/Capabilities.ts | 8 +
packages/vfs/ref/interfaces/Resource.ts | 40 +
packages/vfs/ref/interfaces/Service.ts | 14 +
packages/vfs/ref/interfaces/Store.ts | 9 +
packages/vfs/ref/interfaces/VFS.ts | 111 +
packages/vfs/ref/interfaces/index.ts | 51 +
packages/vfs/ref/interfaces/io.ts | 4 +
packages/vfs/ref/io/base64.ts | 23 +
packages/vfs/ref/io/json.ts | 217 +
packages/vfs/ref/lang/Aspect.ts | 538 +
packages/vfs/ref/lang/AspectDecorator.ts | 72 +
packages/vfs/ref/lang/promisify.ts | 44 +
packages/vfs/ref/model/Path.ts | 329 +
packages/vfs/ref/resource/Query.ts | 29 +
packages/vfs/ref/resource/Renderer.ts | 51 +
packages/vfs/ref/resource/Resolver.ts | 11 +
packages/vfs/ref/route/uploads.ts | 40 +
packages/vfs/ref/rpc/JSON-RPC-2-Errors.ts | 92 +
packages/vfs/ref/rpc/JSON-RPC-2-Response.ts | 75 +
packages/vfs/ref/rpc/JSON-RPC-2.ts | 70 +
packages/vfs/ref/services/Base.ts | 223 +
packages/vfs/ref/services/Bean.ts | 57 +
packages/vfs/ref/services/Devices.ts | 218 +
packages/vfs/ref/services/Directory.ts | 477 +
packages/vfs/ref/services/Drivers.ts | 209 +
packages/vfs/ref/services/External.ts | 204 +
packages/vfs/ref/services/JSONFile.ts | 118 +
packages/vfs/ref/services/Logs.ts | 90 +
packages/vfs/ref/services/Mounts.ts | 16 +
packages/vfs/ref/services/Services.ts | 29 +
packages/vfs/ref/services/Tracking.ts | 33 +
packages/vfs/ref/services/_osfs.js | 547 +
packages/vfs/ref/services/external/Mongod.ts | 489 +
packages/vfs/ref/services/register.ts | 21 +
packages/vfs/ref/std/collections.ts | 660 +
packages/vfs/ref/std/primitives.ts | 247 +
packages/vfs/ref/types/Device.ts | 78 +
packages/vfs/ref/types/Driver.ts | 28 +
packages/vfs/ref/utils/CIUtils.ts | 258 +
packages/vfs/ref/utils/FileUtils.ts | 169 +
packages/vfs/ref/utils/HexUtils.ts | 1500 +
packages/vfs/ref/utils/PlatformUtils.ts | 9 +
packages/vfs/ref/utils/StringUtils.ts | 461 +
packages/vfs/ref/utils/open.ts | 59 +
packages/vfs/ref/vfs/Local.ts | 1220 +
packages/vfs/ref/vfs/github/Github.ts | 517 +
packages/vfs/ref/vfs/ssh/sftp.ts | 305 +
packages/vfs/ref/vfs/utils.ts | 33 +
packages/vfs/src/.gitignore | 0
packages/vfs/src/_cli.ts | 13 +
packages/vfs/src/acl/ACLC.ts | 745 +
packages/vfs/src/acl/backend.ts | 87 +
packages/vfs/src/acl/data/File.ts | 51 +
packages/vfs/src/acl/data/Memory.ts | 178 +
packages/vfs/src/acl/interfaces.ts | 90 +
packages/vfs/src/argv.ts | 237 +
packages/vfs/src/commands/info.ts | 12 +
packages/vfs/src/constants.ts | 2 +
packages/vfs/src/index.ts | 8 +
packages/vfs/src/interfaces/Application.ts | 9 +
packages/vfs/src/interfaces/CI.ts | 19 +
packages/vfs/src/interfaces/Capabilities.ts | 8 +
packages/vfs/src/interfaces/Resource.ts | 40 +
packages/vfs/src/interfaces/Service.ts | 14 +
packages/vfs/src/interfaces/Store.ts | 9 +
packages/vfs/src/interfaces/VFS.ts | 111 +
packages/vfs/src/interfaces/index.ts | 51 +
packages/vfs/src/interfaces/io.ts | 4 +
packages/vfs/src/lang/Aspect.ts | 538 +
packages/vfs/src/lang/AspectDecorator.ts | 72 +
packages/vfs/src/lang/promisify.ts | 44 +
packages/vfs/src/main.ts | 16 +
packages/vfs/src/provider/Local.ts | 1220 +
packages/vfs/src/provider/gitea/api.ts | 29706 +++++++++
packages/vfs/src/provider/gitea/client.ts | 49730 ++++++++++++++++
packages/vfs/src/provider/gitea/gen.js | 18 +
packages/vfs/src/provider/gitea/package.json | 15 +
packages/vfs/src/provider/gitea/schema.json | 17108 ++++++
.../vfs/src/provider/gitea/swagger-gen.json | 0
packages/vfs/src/provider/gitea/yarn.lock | 1604 +
packages/vfs/src/provider/github/Github.ts | 517 +
packages/vfs/src/provider/ssh/sftp.ts | 305 +
packages/vfs/src/provider/utils.ts | 33 +
packages/vfs/src/readme.md | 30 +
packages/vfs/src/types.ts | 22 +
packages/vfs/src/types/Device.ts | 78 +
packages/vfs/src/types/Driver.ts | 28 +
packages/vfs/src/utils/CIUtils.ts | 258 +
packages/vfs/src/utils/FileUtils.ts | 169 +
packages/vfs/src/utils/HexUtils.ts | 1500 +
packages/vfs/src/utils/PlatformUtils.ts | 9 +
packages/vfs/src/utils/StringUtils.ts | 461 +
packages/vfs/src/utils/open.ts | 59 +
packages/vfs/tsconfig.json | 27 +
packages/vfs/types.js | 3 +
packages/vfs/types.js.map | 1 +
581 files changed, 175611 insertions(+)
create mode 100644 packages/.gitignore
create mode 100644 packages/discourse/.gitignore
create mode 100644 packages/discourse/.npmignore
create mode 100644 packages/discourse/.vscode/launch.json
create mode 100644 packages/discourse/.vscode/settings.json
create mode 100644 packages/discourse/LICENSE
create mode 100644 packages/discourse/README.md
create mode 100644 packages/discourse/_cli.d.ts
create mode 100644 packages/discourse/_cli.js
create mode 100644 packages/discourse/_cli.js.map
create mode 100644 packages/discourse/_package.json
create mode 100644 packages/discourse/commands/category.d.ts
create mode 100644 packages/discourse/commands/category.js
create mode 100644 packages/discourse/commands/category.js.map
create mode 100644 packages/discourse/commands/import-oa-howtos.d.ts
create mode 100644 packages/discourse/commands/import-oa-howtos.js
create mode 100644 packages/discourse/commands/import-oa-users.d.ts
create mode 100644 packages/discourse/commands/import-oa-users.js
create mode 100644 packages/discourse/commands/import-oa.d.ts
create mode 100644 packages/discourse/commands/import-oa.js
create mode 100644 packages/discourse/commands/info.d.ts
create mode 100644 packages/discourse/commands/info.js
create mode 100644 packages/discourse/commands/info.js.map
create mode 100644 packages/discourse/commands/product.d.ts
create mode 100644 packages/discourse/commands/product.js
create mode 100644 packages/discourse/commands/product.js.map
create mode 100644 packages/discourse/commands/query.d.ts
create mode 100644 packages/discourse/commands/query.js
create mode 100644 packages/discourse/commands/query.js.map
create mode 100644 packages/discourse/commands/sync-component.d.ts
create mode 100644 packages/discourse/commands/sync-component.js
create mode 100644 packages/discourse/commands/sync-file.d.ts
create mode 100644 packages/discourse/commands/sync-file.js
create mode 100644 packages/discourse/config/machines.js
create mode 100644 packages/discourse/constants.d.ts
create mode 100644 packages/discourse/constants.js
create mode 100644 packages/discourse/constants.js.map
create mode 100644 packages/discourse/discourse-sync.json
create mode 100644 packages/discourse/docs/data.md
create mode 100644 packages/discourse/index.d.ts
create mode 100644 packages/discourse/index.js
create mode 100644 packages/discourse/index.js.map
create mode 100644 packages/discourse/index.md
create mode 100644 packages/discourse/lib/discourse/cache.d.ts
create mode 100644 packages/discourse/lib/discourse/cache.js
create mode 100644 packages/discourse/lib/discourse/constants.d.ts
create mode 100644 packages/discourse/lib/discourse/constants.js
create mode 100644 packages/discourse/lib/discourse/index.d.ts
create mode 100644 packages/discourse/lib/discourse/index.js
create mode 100644 packages/discourse/lib/discourse/index.js.map
create mode 100644 packages/discourse/lib/discourse/types.d.ts
create mode 100644 packages/discourse/lib/discourse/types.js
create mode 100644 packages/discourse/lib/discourse/types.js.map
create mode 100644 packages/discourse/lib/discourse/types/bevry.d.ts
create mode 100644 packages/discourse/lib/discourse/types/bevry.js
create mode 100644 packages/discourse/lib/discourse/types/bevry.js.map
create mode 100644 packages/discourse/lib/discourse/types/discourse.d.ts
create mode 100644 packages/discourse/lib/discourse/types/discourse.js
create mode 100644 packages/discourse/lib/discourse/types/discourse.js.map
create mode 100644 packages/discourse/lib/discourse/util.d.ts
create mode 100644 packages/discourse/lib/discourse/util.js
create mode 100644 packages/discourse/lib/discourse/util.js.map
create mode 100644 packages/discourse/lib/discourse/youtube.d.ts
create mode 100644 packages/discourse/lib/discourse/youtube.js
create mode 100644 packages/discourse/lib/discourse/youtube.js.map
create mode 100644 packages/discourse/lib/git/index.d.ts
create mode 100644 packages/discourse/lib/git/index.js
create mode 100644 packages/discourse/lib/index.d.ts
create mode 100644 packages/discourse/lib/index.js
create mode 100644 packages/discourse/lib/index.js.map
create mode 100644 packages/discourse/lib/markdown/Pattern.d.ts
create mode 100644 packages/discourse/lib/markdown/Pattern.js
create mode 100644 packages/discourse/lib/markdown/Rule.d.ts
create mode 100644 packages/discourse/lib/markdown/Rule.js
create mode 100644 packages/discourse/lib/markdown/index.d.ts
create mode 100644 packages/discourse/lib/markdown/index.js
create mode 100644 packages/discourse/lib/markdown/types.d.ts
create mode 100644 packages/discourse/lib/markdown/types.js
create mode 100644 packages/discourse/lib/oa/commons.d.ts
create mode 100644 packages/discourse/lib/oa/commons.js
create mode 100644 packages/discourse/lib/oa/howtos.d.ts
create mode 100644 packages/discourse/lib/oa/howtos.js
create mode 100644 packages/discourse/lib/oa/index.d.ts
create mode 100644 packages/discourse/lib/oa/index.js
create mode 100644 packages/discourse/lib/oa/lib.d.ts
create mode 100644 packages/discourse/lib/oa/lib.js
create mode 100644 packages/discourse/lib/oa/types.d.ts
create mode 100644 packages/discourse/lib/oa/types.js
create mode 100644 packages/discourse/lib/oa/users.d.ts
create mode 100644 packages/discourse/lib/oa/users.js
create mode 100644 packages/discourse/lib/oa/utils.d.ts
create mode 100644 packages/discourse/lib/oa/utils.js
create mode 100644 packages/discourse/lib/osr/index.d.ts
create mode 100644 packages/discourse/lib/osr/index.js
create mode 100644 packages/discourse/lib/osr/urls.d.ts
create mode 100644 packages/discourse/lib/osr/urls.js
create mode 100644 packages/discourse/lib/sync/commons.d.ts
create mode 100644 packages/discourse/lib/sync/commons.js
create mode 100644 packages/discourse/lib/sync/component.d.ts
create mode 100644 packages/discourse/lib/sync/component.js
create mode 100644 packages/discourse/lib/sync/download.d.ts
create mode 100644 packages/discourse/lib/sync/download.js
create mode 100644 packages/discourse/lib/sync/file.d.ts
create mode 100644 packages/discourse/lib/sync/file.js
create mode 100644 packages/discourse/lib/sync/fs.d.ts
create mode 100644 packages/discourse/lib/sync/fs.js
create mode 100644 packages/discourse/lib/sync/index.d.ts
create mode 100644 packages/discourse/lib/sync/index.js
create mode 100644 packages/discourse/lib/sync/osrl.d.ts
create mode 100644 packages/discourse/lib/sync/osrl.js
create mode 100644 packages/discourse/lib/types.d.ts
create mode 100644 packages/discourse/lib/types.js
create mode 100644 packages/discourse/lib/types.js.map
create mode 100644 packages/discourse/main.d.ts
create mode 100644 packages/discourse/main.js
create mode 100644 packages/discourse/main.js.map
create mode 100644 packages/discourse/options.d.ts
create mode 100644 packages/discourse/options.js
create mode 100644 packages/discourse/options.js.map
create mode 100644 packages/discourse/package-lock.json
create mode 100644 packages/discourse/scripts/link-dev.sh
create mode 100644 packages/discourse/scripts/sync-components.sh
create mode 100644 packages/discourse/scripts/test.sh
create mode 100644 packages/discourse/src/_cli.ts
create mode 100644 packages/discourse/src/commands/import-oa-howtos.ts
create mode 100644 packages/discourse/src/commands/import-oa-users.ts
create mode 100644 packages/discourse/src/commands/info.ts
create mode 100644 packages/discourse/src/commands/query.ts
create mode 100644 packages/discourse/src/commands/sync-component.ts
create mode 100644 packages/discourse/src/commands/sync-directory.ts
create mode 100644 packages/discourse/src/commands/sync-file.ts
create mode 100644 packages/discourse/src/constants.ts
create mode 100644 packages/discourse/src/index.ts
create mode 100644 packages/discourse/src/lib/discourse/cache.ts
create mode 100644 packages/discourse/src/lib/discourse/constants.ts
create mode 100644 packages/discourse/src/lib/discourse/index.ts
create mode 100644 packages/discourse/src/lib/discourse/types.ts
create mode 100644 packages/discourse/src/lib/git/index.ts
create mode 100644 packages/discourse/src/lib/index.ts
create mode 100644 packages/discourse/src/lib/markdown/Pattern.ts
create mode 100644 packages/discourse/src/lib/markdown/Rule.ts
create mode 100644 packages/discourse/src/lib/markdown/index.test.ts
create mode 100644 packages/discourse/src/lib/markdown/index.ts
create mode 100644 packages/discourse/src/lib/markdown/page.ts
create mode 100644 packages/discourse/src/lib/markdown/types.ts
create mode 100644 packages/discourse/src/lib/oa/commons.ts
create mode 100644 packages/discourse/src/lib/oa/howtos.ts
create mode 100644 packages/discourse/src/lib/oa/index.ts
create mode 100644 packages/discourse/src/lib/oa/lib.ts
create mode 100644 packages/discourse/src/lib/oa/types.ts
create mode 100644 packages/discourse/src/lib/oa/users.ts
create mode 100644 packages/discourse/src/lib/oa/utils.ts
create mode 100644 packages/discourse/src/lib/osr/index.ts
create mode 100644 packages/discourse/src/lib/osr/urls.ts
create mode 100644 packages/discourse/src/lib/sync/commons.ts
create mode 100644 packages/discourse/src/lib/sync/component.ts
create mode 100644 packages/discourse/src/lib/sync/directory.ts
create mode 100644 packages/discourse/src/lib/sync/download.ts
create mode 100644 packages/discourse/src/lib/sync/file.ts
create mode 100644 packages/discourse/src/lib/sync/index.ts
create mode 100644 packages/discourse/src/lib/sync/osrl.ts
create mode 100644 packages/discourse/src/main.ts
create mode 100644 packages/discourse/src/options.ts
create mode 100644 packages/discourse/src/types.ts
create mode 100644 packages/discourse/temp/h.json
create mode 100644 packages/discourse/temp/l.md
create mode 100644 packages/discourse/temp/post.html
create mode 100644 packages/discourse/temp/t.json
create mode 100644 packages/discourse/temp/user.json
create mode 100644 packages/discourse/templates/discourse/machines/debug.osr
create mode 100644 packages/discourse/templates/discourse/machines/global.json
create mode 100644 packages/discourse/templates/discourse/machines/header_jekyll.osr
create mode 100644 packages/discourse/templates/discourse/machines/plugins/html.js
create mode 100644 packages/discourse/templates/discourse/machines/root.html
create mode 100644 packages/discourse/templates/discourse/machines/variables.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/authors.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/authors_html.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/extra_resources.md
create mode 100644 packages/discourse/templates/discourse/machines/widgets/forum.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/gallery.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/howtos.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/other_products.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/overview_drawings.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/parts.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/resources.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/showreel.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/social_links.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/specs.osr
create mode 100644 packages/discourse/templates/discourse/machines/widgets/table.osr
create mode 100644 packages/discourse/tests/image.jpg
create mode 100644 packages/discourse/tests/sync/md.md
create mode 100644 packages/discourse/tmp-a.json
create mode 100644 packages/discourse/tmp.json
create mode 100644 packages/discourse/tsconfig.json
create mode 100644 packages/discourse/types.d.ts
create mode 100644 packages/discourse/types.js
create mode 100644 packages/discourse/types.js.map
create mode 100644 packages/registry/.gitignore
create mode 100644 packages/registry/.npmignore
create mode 100644 packages/registry/LICENSE
create mode 100644 packages/registry/README.md
create mode 100644 packages/registry/_cli.d.ts
create mode 100644 packages/registry/_cli.js
create mode 100644 packages/registry/_cli.js.map
create mode 100644 packages/registry/commands/info.d.ts
create mode 100644 packages/registry/commands/info.js
create mode 100644 packages/registry/commands/info.js.map
create mode 100644 packages/registry/constants.d.ts
create mode 100644 packages/registry/constants.js
create mode 100644 packages/registry/constants.js.map
create mode 100644 packages/registry/index.d.ts
create mode 100644 packages/registry/index.js
create mode 100644 packages/registry/index.js.map
create mode 100644 packages/registry/lib/index.d.ts
create mode 100644 packages/registry/lib/index.js
create mode 100644 packages/registry/lib/index.js.map
create mode 100644 packages/registry/lib/keyv.d.ts
create mode 100644 packages/registry/lib/keyv.js
create mode 100644 packages/registry/lib/keyv.js.map
create mode 100644 packages/registry/lib/types.d.ts
create mode 100644 packages/registry/lib/types.js
create mode 100644 packages/registry/lib/types.js.map
create mode 100644 packages/registry/main.d.ts
create mode 100644 packages/registry/main.js
create mode 100644 packages/registry/main.js.map
create mode 100644 packages/registry/package-lock.json
create mode 100644 packages/registry/package.json
create mode 100644 packages/registry/ref/CKBaseManager.h
create mode 100644 packages/registry/ref/CKBaseManager.ts
create mode 100644 packages/registry/ref/CKEnums.h
create mode 100644 packages/registry/ref/CKEnums.ts
create mode 100644 packages/registry/ref/CKParameter.h
create mode 100644 packages/registry/ref/CKParameter.ts
create mode 100644 packages/registry/ref/CKParameterIn.h
create mode 100644 packages/registry/ref/CKParameterIn.ts
create mode 100644 packages/registry/ref/CKParameterLocal.h
create mode 100644 packages/registry/ref/CKParameterLocal.ts
create mode 100644 packages/registry/ref/CKParameterManager.h
create mode 100644 packages/registry/ref/CKParameterManager.ts
create mode 100644 packages/registry/ref/CKParameterOperation.h
create mode 100644 packages/registry/ref/CKParameterOperation.ts
create mode 100644 packages/registry/ref/CKParameterOut.h
create mode 100644 packages/registry/ref/CKParameterOut.ts
create mode 100644 packages/registry/ref/CKPluginManager.h
create mode 100644 packages/registry/ref/CKPluginManager.ts
create mode 100644 packages/registry/ref/to-typescript.md
create mode 100644 packages/registry/ref/toTS.sh
create mode 100644 packages/registry/src/.gitignore
create mode 100644 packages/registry/src/_cli.ts
create mode 100644 packages/registry/src/commands/info.ts
create mode 100644 packages/registry/src/commands/test.ts
create mode 100644 packages/registry/src/constants.ts
create mode 100644 packages/registry/src/index.ts
create mode 100644 packages/registry/src/lib/index.ts
create mode 100644 packages/registry/src/lib/keyv.ts
create mode 100644 packages/registry/src/lib/types.ts
create mode 100644 packages/registry/src/main.ts
create mode 100644 packages/registry/src/options.ts
create mode 100644 packages/registry/src/types.ts
create mode 100644 packages/registry/tsconfig.json
create mode 100644 packages/registry/types.d.ts
create mode 100644 packages/registry/types.js
create mode 100644 packages/registry/types.js.map
create mode 100644 packages/vfs/.gitignore
create mode 100644 packages/vfs/.npmignore
create mode 100644 packages/vfs/LICENSE
create mode 100644 packages/vfs/README.md
create mode 100644 packages/vfs/_cli.js
create mode 100644 packages/vfs/_cli.js.map
create mode 100644 packages/vfs/_package.json
create mode 100644 packages/vfs/argv.js
create mode 100644 packages/vfs/argv.js.map
create mode 100644 packages/vfs/commands/info.js
create mode 100644 packages/vfs/constants.js
create mode 100644 packages/vfs/constants.js.map
create mode 100644 packages/vfs/index.js
create mode 100644 packages/vfs/index.js.map
create mode 100644 packages/vfs/main.js
create mode 100644 packages/vfs/main.js.map
create mode 100644 packages/vfs/package-lock.json
create mode 100644 packages/vfs/rclone.js/.gitignore
create mode 100644 packages/vfs/rclone.js/CNAME
create mode 100644 packages/vfs/rclone.js/README.md
create mode 100644 packages/vfs/rclone.js/_config.yml
create mode 100644 packages/vfs/rclone.js/bin/rclone.exe
create mode 100644 packages/vfs/rclone.js/bin/rclone.js
create mode 100644 packages/vfs/rclone.js/package-lock.json
create mode 100644 packages/vfs/rclone.js/package.json
create mode 100644 packages/vfs/rclone.js/rclone.js
create mode 100644 packages/vfs/rclone.js/rclone/selfupdate.js
create mode 100644 packages/vfs/rclone.js/test/index.js
create mode 100644 packages/vfs/rclone.js/test/rclone-test.js
create mode 100644 packages/vfs/ref-rclone/api_examples.sh
create mode 100644 packages/vfs/ref-rclone/gdrive_sync.sh
create mode 100644 packages/vfs/ref-rclone/local_sync.sh
create mode 100644 packages/vfs/ref-rclone/rclone-examples/README.md
create mode 100644 packages/vfs/ref-rclone/rclone-examples/api.conf
create mode 100644 packages/vfs/ref-rclone/rclone-examples/local.conf
create mode 100644 packages/vfs/ref-rclone/rclone-examples/s3.conf
create mode 100644 packages/vfs/ref-rclone/rclone-examples/sftp.conf
create mode 100644 packages/vfs/ref-rclone/rclone.conf
create mode 100644 packages/vfs/ref-server/app.module.ts
create mode 100644 packages/vfs/ref-server/config.ts
create mode 100644 packages/vfs/ref-server/controllers/ContextManager.ts
create mode 100644 packages/vfs/ref-server/controllers/account.controller.ts
create mode 100644 packages/vfs/ref-server/controllers/base.controller.ts
create mode 100644 packages/vfs/ref-server/controllers/content-types.controller.ts
create mode 100644 packages/vfs/ref-server/controllers/devices.controller.ts
create mode 100644 packages/vfs/ref-server/controllers/events.gateway.ts
create mode 100644 packages/vfs/ref-server/controllers/groups.controller.ts
create mode 100644 packages/vfs/ref-server/controllers/index.ts
create mode 100644 packages/vfs/ref-server/controllers/permissions.controller.ts
create mode 100644 packages/vfs/ref-server/controllers/projects.controller.ts
create mode 100644 packages/vfs/ref-server/controllers/users.controller.ts
create mode 100644 packages/vfs/ref-server/controllers/utils.ts
create mode 100644 packages/vfs/ref-server/controllers/vfs.controller.ts
create mode 100644 packages/vfs/ref-server/core.module.ts
create mode 100644 packages/vfs/ref-server/decorators/permissions.decorator.ts
create mode 100644 packages/vfs/ref-server/decorators/roles.decorator.ts
create mode 100644 packages/vfs/ref-server/dto/account.dto.ts
create mode 100644 packages/vfs/ref-server/dto/content-type.dto.ts
create mode 100644 packages/vfs/ref-server/dto/device.dto.ts
create mode 100644 packages/vfs/ref-server/dto/file.dto.ts
create mode 100644 packages/vfs/ref-server/dto/group-with-permissions.dto.ts
create mode 100644 packages/vfs/ref-server/dto/group.dto.ts
create mode 100644 packages/vfs/ref-server/dto/in-account-login.dto.ts
create mode 100644 packages/vfs/ref-server/dto/in-account-register.dto.ts
create mode 100644 packages/vfs/ref-server/dto/in-account.dto.ts
create mode 100644 packages/vfs/ref-server/dto/in-content-type.dto.ts
create mode 100644 packages/vfs/ref-server/dto/in-device.dto.ts
create mode 100644 packages/vfs/ref-server/dto/in-file.dto.ts
create mode 100644 packages/vfs/ref-server/dto/in-group.dto.ts
create mode 100644 packages/vfs/ref-server/dto/in-permission.dto.ts
create mode 100644 packages/vfs/ref-server/dto/in-project.dto.ts
create mode 100644 packages/vfs/ref-server/dto/in-token.dto.ts
create mode 100644 packages/vfs/ref-server/dto/in-user.dto.ts
create mode 100644 packages/vfs/ref-server/dto/meta.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-account-token.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-content-type.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-content-types.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-device.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-devices.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-file.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-group.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-groups.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-permission.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-permissions.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-project.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-user.dto.ts
create mode 100644 packages/vfs/ref-server/dto/out-users.dto.ts
create mode 100644 packages/vfs/ref-server/dto/permission.dto.ts
create mode 100644 packages/vfs/ref-server/dto/project.dto.ts
create mode 100644 packages/vfs/ref-server/dto/user.dto.ts
create mode 100644 packages/vfs/ref-server/entities/content-type.entity.ts
create mode 100644 packages/vfs/ref-server/entities/device.entity.ts
create mode 100644 packages/vfs/ref-server/entities/file.entity.ts
create mode 100644 packages/vfs/ref-server/entities/group.entity.ts
create mode 100644 packages/vfs/ref-server/entities/index.ts
create mode 100644 packages/vfs/ref-server/entities/permission.entity.ts
create mode 100644 packages/vfs/ref-server/entities/project.entity.ts
create mode 100644 packages/vfs/ref-server/entities/user.entity.ts
create mode 100644 packages/vfs/ref-server/errors.ts
create mode 100644 packages/vfs/ref-server/exceptions/custom-exception.filter.ts
create mode 100644 packages/vfs/ref-server/exceptions/custom-validation.error.ts
create mode 100644 packages/vfs/ref-server/extensions/Evented.ts
create mode 100644 packages/vfs/ref-server/extensions/Logged.ts
create mode 100644 packages/vfs/ref-server/guards/access.guard.ts
create mode 100644 packages/vfs/ref-server/interfaces.ts
create mode 100644 packages/vfs/ref-server/lib.ts
create mode 100644 packages/vfs/ref-server/log.ts
create mode 100644 packages/vfs/ref-server/manager/ConnectionManager.ts
create mode 100644 packages/vfs/ref-server/manager/Context.ts
create mode 100644 packages/vfs/ref-server/migrations/FillData1514404694792.ts
create mode 100644 packages/vfs/ref-server/migrations/marantz.json
create mode 100644 packages/vfs/ref-server/model/Connection.ts
create mode 100644 packages/vfs/ref-server/pipes/parse-int-with-default.pipe.ts
create mode 100644 packages/vfs/ref-server/pipes/validation.pipe.ts
create mode 100644 packages/vfs/ref-server/protocols/Protocol.ts
create mode 100644 packages/vfs/ref-server/protocols/Tcp.ts
create mode 100644 packages/vfs/ref-server/server.ts
create mode 100644 packages/vfs/ref-server/services/DeviceService.ts
create mode 100644 packages/vfs/ref-server/services/account.service.ts
create mode 100644 packages/vfs/ref-server/services/groups.service.ts
create mode 100644 packages/vfs/ref-server/services/index.ts
create mode 100644 packages/vfs/ref-server/services/token.service.ts
create mode 100644 packages/vfs/ref-server/types.ts
create mode 100644 packages/vfs/ref/LICENSE
create mode 100644 packages/vfs/ref/Makefile
create mode 100644 packages/vfs/ref/acl/ACLC.ts
create mode 100644 packages/vfs/ref/acl/backend.ts
create mode 100644 packages/vfs/ref/acl/data/File.ts
create mode 100644 packages/vfs/ref/acl/data/Memory.ts
create mode 100644 packages/vfs/ref/acl/interfaces.ts
create mode 100644 packages/vfs/ref/applications/ControlFreak/services/Directory.ts
create mode 100644 packages/vfs/ref/components/Component.ts
create mode 100644 packages/vfs/ref/components/xfile/xfile.ts
create mode 100644 packages/vfs/ref/components/xideve/ExportOptions.ts
create mode 100644 packages/vfs/ref/components/xideve/Exporter.ts
create mode 100644 packages/vfs/ref/components/xideve/export/export.js
create mode 100644 packages/vfs/ref/components/xideve/routes/Preview.ts
create mode 100644 packages/vfs/ref/components/xideve/services/Workbench.ts
create mode 100644 packages/vfs/ref/components/xideve/views/debug.ejs
create mode 100644 packages/vfs/ref/components/xideve/views/release.ejs
create mode 100644 packages/vfs/ref/components/xideve/xideve.ts
create mode 100644 packages/vfs/ref/console.ts
create mode 100644 packages/vfs/ref/debug.ts
create mode 100644 packages/vfs/ref/di/README.md
create mode 100644 packages/vfs/ref/di/agent.spec.ts
create mode 100644 packages/vfs/ref/di/agent.ts
create mode 100644 packages/vfs/ref/di/core/attribute.ts
create mode 100644 packages/vfs/ref/di/core/chain.ts
create mode 100644 packages/vfs/ref/di/core/decorator.ts
create mode 100644 packages/vfs/ref/di/core/index.ts
create mode 100644 packages/vfs/ref/di/core/interceptor.ts
create mode 100644 packages/vfs/ref/di/core/interceptors/construct.ts
create mode 100644 packages/vfs/ref/di/core/interceptors/prototype.ts
create mode 100644 packages/vfs/ref/di/core/interceptors/proxy.ts
create mode 100644 packages/vfs/ref/di/core/invocation.ts
create mode 100644 packages/vfs/ref/di/core/metadata.ts
create mode 100644 packages/vfs/ref/di/core/reflection.spec.ts
create mode 100644 packages/vfs/ref/di/core/reflection.ts
create mode 100644 packages/vfs/ref/di/core/utils.ts
create mode 100644 packages/vfs/ref/di/domain.spec.ts
create mode 100644 packages/vfs/ref/di/domain.ts
create mode 100644 packages/vfs/ref/di/extra/cache.spec.ts
create mode 100644 packages/vfs/ref/di/extra/cache.ts
create mode 100644 packages/vfs/ref/di/extra/conditional.spec.ts
create mode 100644 packages/vfs/ref/di/extra/conditional.ts
create mode 100644 packages/vfs/ref/di/extra/failure.spec.ts
create mode 100644 packages/vfs/ref/di/extra/failure.ts
create mode 100644 packages/vfs/ref/di/extra/index.ts
create mode 100644 packages/vfs/ref/di/extra/inject.spec.ts
create mode 100644 packages/vfs/ref/di/extra/inject.ts
create mode 100644 packages/vfs/ref/di/extra/normalize.spec.ts
create mode 100644 packages/vfs/ref/di/extra/normalize.ts
create mode 100644 packages/vfs/ref/di/extra/prerequisite.spec.ts
create mode 100644 packages/vfs/ref/di/extra/prerequisite.ts
create mode 100644 packages/vfs/ref/di/extra/ready.spec.ts
create mode 100644 packages/vfs/ref/di/extra/ready.ts
create mode 100644 packages/vfs/ref/di/extra/stream.spec.ts
create mode 100644 packages/vfs/ref/di/extra/stream.ts
create mode 100644 packages/vfs/ref/di/extra/success.spec.ts
create mode 100644 packages/vfs/ref/di/extra/success.ts
create mode 100644 packages/vfs/ref/di/extra/timestamp.spec.ts
create mode 100644 packages/vfs/ref/di/extra/timestamp.ts
create mode 100644 packages/vfs/ref/di/index.ts
create mode 100644 packages/vfs/ref/fs/append.ts
create mode 100644 packages/vfs/ref/fs/copy.ts
create mode 100644 packages/vfs/ref/fs/dir.ts
create mode 100644 packages/vfs/ref/fs/errors.ts
create mode 100644 packages/vfs/ref/fs/exists.ts
create mode 100644 packages/vfs/ref/fs/file.ts
create mode 100644 packages/vfs/ref/fs/find.ts
create mode 100644 packages/vfs/ref/fs/imports.ts
create mode 100644 packages/vfs/ref/fs/inspect.ts
create mode 100644 packages/vfs/ref/fs/inspect_tree.ts
create mode 100644 packages/vfs/ref/fs/interfaces.ts
create mode 100644 packages/vfs/ref/fs/iterator.ts
create mode 100644 packages/vfs/ref/fs/jetpack.ts
create mode 100644 packages/vfs/ref/fs/list.ts
create mode 100644 packages/vfs/ref/fs/move.ts
create mode 100644 packages/vfs/ref/fs/playground.ts
create mode 100644 packages/vfs/ref/fs/promisify.ts
create mode 100644 packages/vfs/ref/fs/read.ts
create mode 100644 packages/vfs/ref/fs/remove.ts
create mode 100644 packages/vfs/ref/fs/rename.ts
create mode 100644 packages/vfs/ref/fs/streams.ts
create mode 100644 packages/vfs/ref/fs/symlink.ts
create mode 100644 packages/vfs/ref/fs/uri.ts
create mode 100644 packages/vfs/ref/fs/utils/dot.ts
create mode 100644 packages/vfs/ref/fs/utils/matcher.ts
create mode 100644 packages/vfs/ref/fs/utils/mime_match.ts
create mode 100644 packages/vfs/ref/fs/utils/mode.ts
create mode 100644 packages/vfs/ref/fs/utils/paths.ts
create mode 100644 packages/vfs/ref/fs/utils/platform.ts
create mode 100644 packages/vfs/ref/fs/utils/strings.ts
create mode 100644 packages/vfs/ref/fs/utils/tree_walker.ts
create mode 100644 packages/vfs/ref/fs/utils/validate.ts
create mode 100644 packages/vfs/ref/fs/utils/wildcard.ts
create mode 100644 packages/vfs/ref/fs/write.ts
create mode 100644 packages/vfs/ref/global.ts
create mode 100644 packages/vfs/ref/index.d.ts
create mode 100644 packages/vfs/ref/index.ts
create mode 100644 packages/vfs/ref/interfaces/Application.ts
create mode 100644 packages/vfs/ref/interfaces/CI.ts
create mode 100644 packages/vfs/ref/interfaces/Capabilities.ts
create mode 100644 packages/vfs/ref/interfaces/Resource.ts
create mode 100644 packages/vfs/ref/interfaces/Service.ts
create mode 100644 packages/vfs/ref/interfaces/Store.ts
create mode 100644 packages/vfs/ref/interfaces/VFS.ts
create mode 100644 packages/vfs/ref/interfaces/index.ts
create mode 100644 packages/vfs/ref/interfaces/io.ts
create mode 100644 packages/vfs/ref/io/base64.ts
create mode 100644 packages/vfs/ref/io/json.ts
create mode 100644 packages/vfs/ref/lang/Aspect.ts
create mode 100644 packages/vfs/ref/lang/AspectDecorator.ts
create mode 100644 packages/vfs/ref/lang/promisify.ts
create mode 100644 packages/vfs/ref/model/Path.ts
create mode 100644 packages/vfs/ref/resource/Query.ts
create mode 100644 packages/vfs/ref/resource/Renderer.ts
create mode 100644 packages/vfs/ref/resource/Resolver.ts
create mode 100644 packages/vfs/ref/route/uploads.ts
create mode 100644 packages/vfs/ref/rpc/JSON-RPC-2-Errors.ts
create mode 100644 packages/vfs/ref/rpc/JSON-RPC-2-Response.ts
create mode 100644 packages/vfs/ref/rpc/JSON-RPC-2.ts
create mode 100644 packages/vfs/ref/services/Base.ts
create mode 100644 packages/vfs/ref/services/Bean.ts
create mode 100644 packages/vfs/ref/services/Devices.ts
create mode 100644 packages/vfs/ref/services/Directory.ts
create mode 100644 packages/vfs/ref/services/Drivers.ts
create mode 100644 packages/vfs/ref/services/External.ts
create mode 100644 packages/vfs/ref/services/JSONFile.ts
create mode 100644 packages/vfs/ref/services/Logs.ts
create mode 100644 packages/vfs/ref/services/Mounts.ts
create mode 100644 packages/vfs/ref/services/Services.ts
create mode 100644 packages/vfs/ref/services/Tracking.ts
create mode 100644 packages/vfs/ref/services/_osfs.js
create mode 100644 packages/vfs/ref/services/external/Mongod.ts
create mode 100644 packages/vfs/ref/services/register.ts
create mode 100644 packages/vfs/ref/std/collections.ts
create mode 100644 packages/vfs/ref/std/primitives.ts
create mode 100644 packages/vfs/ref/types/Device.ts
create mode 100644 packages/vfs/ref/types/Driver.ts
create mode 100644 packages/vfs/ref/utils/CIUtils.ts
create mode 100644 packages/vfs/ref/utils/FileUtils.ts
create mode 100644 packages/vfs/ref/utils/HexUtils.ts
create mode 100644 packages/vfs/ref/utils/PlatformUtils.ts
create mode 100644 packages/vfs/ref/utils/StringUtils.ts
create mode 100644 packages/vfs/ref/utils/open.ts
create mode 100644 packages/vfs/ref/vfs/Local.ts
create mode 100644 packages/vfs/ref/vfs/github/Github.ts
create mode 100644 packages/vfs/ref/vfs/ssh/sftp.ts
create mode 100644 packages/vfs/ref/vfs/utils.ts
create mode 100644 packages/vfs/src/.gitignore
create mode 100644 packages/vfs/src/_cli.ts
create mode 100644 packages/vfs/src/acl/ACLC.ts
create mode 100644 packages/vfs/src/acl/backend.ts
create mode 100644 packages/vfs/src/acl/data/File.ts
create mode 100644 packages/vfs/src/acl/data/Memory.ts
create mode 100644 packages/vfs/src/acl/interfaces.ts
create mode 100644 packages/vfs/src/argv.ts
create mode 100644 packages/vfs/src/commands/info.ts
create mode 100644 packages/vfs/src/constants.ts
create mode 100644 packages/vfs/src/index.ts
create mode 100644 packages/vfs/src/interfaces/Application.ts
create mode 100644 packages/vfs/src/interfaces/CI.ts
create mode 100644 packages/vfs/src/interfaces/Capabilities.ts
create mode 100644 packages/vfs/src/interfaces/Resource.ts
create mode 100644 packages/vfs/src/interfaces/Service.ts
create mode 100644 packages/vfs/src/interfaces/Store.ts
create mode 100644 packages/vfs/src/interfaces/VFS.ts
create mode 100644 packages/vfs/src/interfaces/index.ts
create mode 100644 packages/vfs/src/interfaces/io.ts
create mode 100644 packages/vfs/src/lang/Aspect.ts
create mode 100644 packages/vfs/src/lang/AspectDecorator.ts
create mode 100644 packages/vfs/src/lang/promisify.ts
create mode 100644 packages/vfs/src/main.ts
create mode 100644 packages/vfs/src/provider/Local.ts
create mode 100644 packages/vfs/src/provider/gitea/api.ts
create mode 100644 packages/vfs/src/provider/gitea/client.ts
create mode 100644 packages/vfs/src/provider/gitea/gen.js
create mode 100644 packages/vfs/src/provider/gitea/package.json
create mode 100644 packages/vfs/src/provider/gitea/schema.json
create mode 100644 packages/vfs/src/provider/gitea/swagger-gen.json
create mode 100644 packages/vfs/src/provider/gitea/yarn.lock
create mode 100644 packages/vfs/src/provider/github/Github.ts
create mode 100644 packages/vfs/src/provider/ssh/sftp.ts
create mode 100644 packages/vfs/src/provider/utils.ts
create mode 100644 packages/vfs/src/readme.md
create mode 100644 packages/vfs/src/types.ts
create mode 100644 packages/vfs/src/types/Device.ts
create mode 100644 packages/vfs/src/types/Driver.ts
create mode 100644 packages/vfs/src/utils/CIUtils.ts
create mode 100644 packages/vfs/src/utils/FileUtils.ts
create mode 100644 packages/vfs/src/utils/HexUtils.ts
create mode 100644 packages/vfs/src/utils/PlatformUtils.ts
create mode 100644 packages/vfs/src/utils/StringUtils.ts
create mode 100644 packages/vfs/src/utils/open.ts
create mode 100644 packages/vfs/tsconfig.json
create mode 100644 packages/vfs/types.js
create mode 100644 packages/vfs/types.js.map
diff --git a/packages/.gitignore b/packages/.gitignore
new file mode 100644
index 00000000..46e7e7a5
--- /dev/null
+++ b/packages/.gitignore
@@ -0,0 +1,5 @@
+/node_modules
+/coverage
+*.log
+.DS_Store
+part-registry
diff --git a/packages/discourse/.gitignore b/packages/discourse/.gitignore
new file mode 100644
index 00000000..74490cf0
--- /dev/null
+++ b/packages/discourse/.gitignore
@@ -0,0 +1,5 @@
+/node_modules
+/coverage
+*.log
+.DS_Store
+tmp
diff --git a/packages/discourse/.npmignore b/packages/discourse/.npmignore
new file mode 100644
index 00000000..4c9addac
--- /dev/null
+++ b/packages/discourse/.npmignore
@@ -0,0 +1,4 @@
+./docs
+./scripts
+./tests
+./incoming
\ No newline at end of file
diff --git a/packages/discourse/.vscode/launch.json b/packages/discourse/.vscode/launch.json
new file mode 100644
index 00000000..a33c61b5
--- /dev/null
+++ b/packages/discourse/.vscode/launch.json
@@ -0,0 +1,178 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Import - OA-Users ",
+ "skipFiles": [
+ "/**"
+ ],
+ "program": "${workspaceFolder}\\main.js",
+ "preLaunchTask": "tsc: build - tsconfig.json",
+ "args": [
+ "import-users",
+ "import",
+ "--src='${OA_ROOT}/data/latest.json'",
+ "--debug=true"
+ ],
+ "outFiles": [
+ "${workspaceFolder}/**/*.js"
+ ],
+ "console": "internalConsole",
+ "outputCapture": "std",
+ "trace": true
+ },
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Update - OA-Users ",
+ "skipFiles": [
+ "/**"
+ ],
+ "program": "${workspaceFolder}\\main.js",
+ "preLaunchTask": "tsc: build - tsconfig.json",
+ "args": [
+ "import-users",
+ "update",
+ "--src='${OA_ROOT}/data/latest.json'",
+ "--debug=true"
+ ],
+ "outFiles": [
+ "${workspaceFolder}/**/*.js"
+ ],
+ "console": "internalConsole",
+ "outputCapture": "std"
+ },
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Index - OA-Users ",
+ "skipFiles": [
+ "/**"
+ ],
+ "program": "${workspaceFolder}\\main.js",
+ "preLaunchTask": "tsc: build - tsconfig.json",
+ "args": [
+ "import-users",
+ "index",
+ "--src='${OA_ROOT}/data/latest.json'",
+ "--debug=true"
+ ],
+ "outFiles": [
+ "${workspaceFolder}/**/*.js"
+ ],
+ "console": "internalConsole",
+ "outputCapture": "std"
+ },
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Import - OA-Howtos",
+ "skipFiles": [
+ "/**"
+ ],
+ "program": "${workspaceFolder}\\main.js",
+ "preLaunchTask": "tsc: build - tsconfig.json",
+ "args": [
+ "import-howtos",
+ // "--src='${OA_ROOT}/data/latest.json'",
+ "--track='${OA_ROOT}/oa-data/howtos/latest_track.json'",
+ "--debug=true"
+ ],
+ "outFiles": [
+ "${workspaceFolder}/**/*.js"
+ ],
+ "outputCapture": "std"
+ },
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "test sync:fs",
+ "skipFiles": [
+ "/**"
+ ],
+ "program": "${workspaceFolder}\\main.js",
+ "preLaunchTask": "tsc: build - tsconfig.json",
+ "args": [
+ "sync",
+ "file",
+ "--yaml=true",
+ "--src='./tests/**/*.md'"
+ ],
+ "outFiles": [
+ "${workspaceFolder}/**/*.js"
+ ]
+ },
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "test sync:component",
+ "skipFiles": [
+ "/**"
+ ],
+ "program": "${workspaceFolder}\\main.js",
+ "preLaunchTask": "tsc: build - tsconfig.json",
+ "args": [
+ "sync-component",
+ "--src='${PRODUCT_ROOT}/products/'"
+ ],
+ "outFiles": [
+ "${workspaceFolder}/**/*.js"
+ ]
+ },
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "test sync:forum-pages",
+ "skipFiles": [
+ "/**"
+ ],
+ "program": "${workspaceFolder}\\main.js",
+ "preLaunchTask": "tsc: build - tsconfig.json",
+ "args": [
+ "sync-component",
+ "--src='${OSR_ROOT}/osr-forum-pages/pages/kb/**/*.md'",
+ "--watch",
+ "--yaml",
+ "--sync=mine"
+ ],
+ "outFiles": [
+ "${workspaceFolder}/**/*.js"
+ ]
+ },
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "test sync:library",
+ "skipFiles": [
+ "/**"
+ ],
+ "program": "${workspaceFolder}\\main.js",
+ "preLaunchTask": "tsc: build - tsconfig.json",
+ "args": [
+ "sync-component",
+ "--cache=true",
+ "--skip=true",
+ "--src2='${OSR_LIBRARY_MACHINES}/injection/**/config.+(json)'",
+ "--src2='${OSR_LIBRARY_MACHINES}/extrusion/**/config.+(json)'",
+ "--src='${OSR_LIBRARY_MACHINES}/sheetpress/**/config.+(json)'",
+ "--src2='${OSR_LIBRARY_MACHINES}/shredder/**/config.+(json)'",
+ "--src2='${OSR_LIBRARY_MACHINES}/zoe/config.+(json)'",
+ // "--src='${OSR_LIBRARY_MACHINES}/combo/IntegrationUnitMonash/config.+(json)'",
+ "--src1='${OSR_LIBRARY_MACHINES}/injection/**/config.+(json)'",
+ //"--src='${OSR_LIBRARY_MACHINES}/sheetpress/cassandra-light/config.+(json)'",
+ "--root='${OSR_LIBRARY_MACHINES}'",
+ "--sync=mine",
+ "--logLevel=debug"
+ ],
+ "outFiles": [
+ "${workspaceFolder}/**/*.js"
+ ],
+ "outputCapture": "std"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/packages/discourse/.vscode/settings.json b/packages/discourse/.vscode/settings.json
new file mode 100644
index 00000000..0fe4b255
--- /dev/null
+++ b/packages/discourse/.vscode/settings.json
@@ -0,0 +1,9 @@
+{
+ "cSpell.words": [
+ "Discorse",
+ "OSRL",
+ "plastichub",
+ "Salamand"
+ ],
+ "cmake.configureOnOpen": false
+}
\ No newline at end of file
diff --git a/packages/discourse/LICENSE b/packages/discourse/LICENSE
new file mode 100644
index 00000000..b0e20f53
--- /dev/null
+++ b/packages/discourse/LICENSE
@@ -0,0 +1,9 @@
+Copyright (c) All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packages/discourse/README.md b/packages/discourse/README.md
new file mode 100644
index 00000000..204fe53e
--- /dev/null
+++ b/packages/discourse/README.md
@@ -0,0 +1,161 @@
+# Discourse library and CLI for OSR content
+
+## Commands
+
+### `info`
+
+#### Print configuration and commands
+
+```
+osr-discourse info
+```
+
+### `deploy`
+
+Create/Update post from directory, using OSR-Specs
+
+**usage**
+
+```sh
+
+osr-discourse deploy --src="./*"
+
+```
+
+### `sync `
+
+Sync file
+
+**usage**
+
+```sh
+
+osr-discourse sync
+
+ --src=""
+ --cat=
+ --owner="user_name|user_id"
+ --config=
+ --timestamp=
+ --download-assets=true|false
+ --tags=
+
+```
+
+### `sync-kb`
+
+Create/Update/Sync kb from directory
+
+**usage**
+
+```sh
+
+osr-discourse sync --src="./*"
+
+```
+
+### `list`
+
+List posts per category or search query
+
+**usage**
+
+```sh
+
+osr-discourse list --query="discourse-query" --dst="output.[json|xls|csv]" --fields="[post-fields]"
+
+```
+
+### `oa-user-import`
+
+Imports oa-users from dump file
+
+**usage**
+
+```sh
+
+osr-discourse oa-user --src="raw.json"
+
+```
+
+### `ig-user-sync`
+
+Imports IG users from dump file
+
+**usage**
+
+```sh
+
+osr-discourse ig-user sync --src="raw.json"
+
+```
+
+### `osr-commons-sync`
+
+Sync all osr-commons ( taxonomy )
+
+**usage**
+
+```sh
+
+osr-discourse osr-sync --src="path to commons (JSON)"
+
+```
+
+### `pm`
+
+Notify all users, using Discourse private message
+
+**usage**
+
+```sh
+
+osr-discourse pm --src="path to message (MD|HTML)" --groups="osr groups"
+
+```
+
+### `invite`
+
+Send invite to a list of users, common MC/OSR CSV format
+
+**usage**
+
+```sh
+
+osr-discourse invite --src="path to message (MD|HTML)" --src="path to CSV"
+
+```
+
+## Library / API
+
+## References
+
+- [ts-json-schema-generator - issue - functions](https://github.com/loopingz/webda.io/blob/main/packages/shell/src/code/compiler.ts#L154-243)
+
+### Todos
+
+////////////////////////
+ //
+ // 1. Fetch Tags
+ // 2. Populate Tags
+ // 3. Download (oa-bot)
+ // 4. Sync - Assets (osr-machines)
+ // 5. Ensure/Find user
+ //
+ // Content
+ //
+ // Body (descr full)
+ // each step
+ // footer (refs)
+ // set tags
+ // set ts
+ //
+ // Post
+ // -> sync lib
+ // -> translate -> lib
+ // -> digest
+ // -> notifications
+ // -> index
+ // -> update ext refs
+ // -> market place
+ // -> sync externals (git, ...)
diff --git a/packages/discourse/_cli.d.ts b/packages/discourse/_cli.d.ts
new file mode 100644
index 00000000..f700ffb5
--- /dev/null
+++ b/packages/discourse/_cli.d.ts
@@ -0,0 +1,3 @@
+import { IOptions, IOptionsSync } from './types';
+export declare const defaults: () => void;
+export declare const sanitize: (argv: any) => IOptionsSync | IOptions | boolean;
diff --git a/packages/discourse/_cli.js b/packages/discourse/_cli.js
new file mode 100644
index 00000000..290946ca
--- /dev/null
+++ b/packages/discourse/_cli.js
@@ -0,0 +1,71 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.sanitize = exports.defaults = void 0;
+const exists_1 = require("@plastichub/fs/exists");
+const _1 = require("./");
+const path = require("path");
+const globBase = require('glob-base');
+const defaults = () => {
+ // default command
+ const DefaultCommand = 'info';
+ if (process.argv.length === 2) {
+ process.argv.push(DefaultCommand);
+ }
+ process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
+ // currently no default handler, display only :
+ process.on('unhandledRejection', (reason) => {
+ console.error('Unhandled rejection, reason: ', reason);
+ });
+};
+exports.defaults = defaults;
+const sanitize = (argv) => {
+ let ret = {
+ ...argv
+ };
+ ret.src = argv.src;
+ let srcInfo;
+ let variables = {};
+ /*
+ if (ret.src) {
+ ret.src = forward_slash(substitute(ret.alt,ret.src,variables))
+ // in case a file with a glob pattern is provided, strip the glob
+ // this is a special case, enabling shared scripts in Alt-Tap Salamand
+ const glob_base = globBase(ret.src)
+ const file = ret.src.replace(glob_base.glob, '').replace(/\/$/, '')
+
+ if(exists(file) && isFile(file)){
+ ret.src = file
+ }
+
+ srcInfo = pathInfo(resolve(ret.src, ret.alt, variables))
+
+ if (srcInfo && srcInfo.FILES && srcInfo.FILES.length) {
+ ret.srcInfo = srcInfo
+ for (const key in srcInfo) {
+ if (Object.prototype.hasOwnProperty.call(srcInfo, key)) {
+ variables['SRC_' + key] = srcInfo[key];
+ }
+ }
+ } else {
+ ret.src = resolve(ret.src, ret.alt, variables)
+ }
+ }
+ */
+ if (argv.cwd) {
+ ret.cwd = path.resolve(argv.cwd);
+ if (!(0, exists_1.sync)((ret.cwd))) {
+ _1.logger.error(`Invalid working directory ${argv.cwd}`);
+ }
+ }
+ else {
+ ret.cwd = process.cwd();
+ }
+ ret = {
+ ...ret,
+ variables,
+ srcInfo
+ };
+ return ret;
+};
+exports.sanitize = sanitize;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiX2NsaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNyYy9fY2xpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLGtEQUFzRDtBQUV0RCx5QkFBMkI7QUFDM0IsNkJBQTRCO0FBTzVCLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQTtBQUU5QixNQUFNLFFBQVEsR0FBRyxHQUFHLEVBQUU7SUFDekIsa0JBQWtCO0lBQ2xCLE1BQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQztJQUM5QixJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtRQUMzQixPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztLQUNyQztJQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMsOEJBQThCLENBQUMsR0FBRyxHQUFHLENBQUM7SUFFbEQsK0NBQStDO0lBQy9DLE9BQU8sQ0FBQyxFQUFFLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxNQUFjLEVBQUUsRUFBRTtRQUNoRCxPQUFPLENBQUMsS0FBSyxDQUFDLCtCQUErQixFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzNELENBQUMsQ0FBQyxDQUFDO0FBQ1AsQ0FBQyxDQUFBO0FBYlksUUFBQSxRQUFRLFlBYXBCO0FBRU0sTUFBTSxRQUFRLEdBQUcsQ0FBQyxJQUFTLEVBQXFDLEVBQUU7SUFFckUsSUFBSSxHQUFHLEdBQVE7UUFDWCxHQUFHLElBQUk7S0FDVixDQUFBO0lBRUQsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFBO0lBQ2xCLElBQUksT0FBTyxDQUFBO0lBQ1gsSUFBSSxTQUFTLEdBQUcsRUFBRSxDQUFBO0lBRWxCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O01BeUJFO0lBRUYsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFO1FBQ1YsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsSUFBQSxhQUFNLEVBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRTtZQUNwQixTQUFNLENBQUMsS0FBSyxDQUFDLDZCQUE2QixJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQTtTQUN4RDtLQUNKO1NBQU07UUFDSCxHQUFHLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQTtLQUMxQjtJQUVELEdBQUcsR0FBRztRQUNGLEdBQUcsR0FBRztRQUNOLFNBQVM7UUFDVCxPQUFPO0tBQ1YsQ0FBQTtJQUVELE9BQU8sR0FBRyxDQUFBO0FBQ2QsQ0FBQyxDQUFBO0FBckRZLFFBQUEsUUFBUSxZQXFEcEIifQ==
\ No newline at end of file
diff --git a/packages/discourse/_cli.js.map b/packages/discourse/_cli.js.map
new file mode 100644
index 00000000..1eea15e8
--- /dev/null
+++ b/packages/discourse/_cli.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"_cli.js","sourceRoot":"","sources":["src/_cli.ts"],"names":[],"mappings":";;;AAAA,kDAAsD;AAEtD,yBAA2B;AAC3B,6BAA4B;AAE5B,sBAAsB;AACf,MAAM,QAAQ,GAAG,GAAG,EAAE;IACzB,kBAAkB;IAClB,MAAM,cAAc,GAAG,MAAM,CAAC;IAC9B,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE;QAC3B,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;KACrC;IAED,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,GAAG,GAAG,CAAC;IAElD,+CAA+C;IAC/C,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAc,EAAE,EAAE;QAChD,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,MAAM,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAbW,QAAA,QAAQ,YAanB;AAEK,MAAM,QAAQ,GAAG,CAAC,IAAS,EAAsB,EAAE;IAEtD,IAAI,GAAG,GAAQ;QACX,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,KAAK,EAAE,IAAI,CAAC,KAAK;KACpB,CAAA;IAED,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,KAAK,MAAM,IAAI,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;IAClE,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;IAEnB,IAAI,IAAI,CAAC,GAAG,EAAE;QACV,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,IAAA,aAAM,EAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE;YACpB,SAAM,CAAC,KAAK,CAAC,6BAA6B,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;SACzD;KACJ;SAAM;QACH,GAAG,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;KAC3B;IAED,GAAG,mCACI,GAAG,GACH,EAAE,SAAS,EAAE,EAAE,EAAE,CACvB,CAAA;IAED,OAAO,GAAG,CAAC;AACf,CAAC,CAAC;AA/BW,QAAA,QAAQ,YA+BnB"}
\ No newline at end of file
diff --git a/packages/discourse/_package.json b/packages/discourse/_package.json
new file mode 100644
index 00000000..567a1e77
--- /dev/null
+++ b/packages/discourse/_package.json
@@ -0,0 +1,85 @@
+{
+ "name": "@plastichub/osr-discourse",
+ "description": "",
+ "version": "0.1.9",
+ "typings": "index.d.ts",
+ "publishConfig": {
+ "access": "public"
+ },
+ "module": "main.js",
+ "main": "main.js",
+ "bin": {
+ "osr-discourse": "main.js"
+ },
+ "dependencies": {
+ "@iarna/toml": "^2.2.5",
+ "@plastichub/core": "^0.2.5",
+ "@plastichub/fs": "^0.13.39",
+ "@plastichub/osr-cache": "^0.4.7",
+ "@plastichub/osr-cli-commons": "^0.5.1",
+ "@plastichub/osr-commons": "^0.3.3",
+ "@plastichub/osr-fs-utils": "^0.1.4",
+ "@plastichub/osrl": "file:../osrl",
+ "@types/markdown-it": "^12.2.3",
+ "@types/node": "^14.17.5",
+ "@types/yargs": "^17.0.11",
+ "axios": "^0.27.2",
+ "bluebird": "^3.7.2",
+ "chalk": "^2.4.1",
+ "cheerio": "^1.0.0-rc.12",
+ "chokidar": "^3.5.3",
+ "download": "^8.0.0",
+ "env-var": "^7.1.1",
+ "escape-html": "^1.0.3",
+ "fast-glob": "^3.3.0",
+ "filenamify": "^4.3.0",
+ "find-up": "^5.0.0",
+ "front-matter": "^4.0.2",
+ "generate-password": "^1.7.0",
+ "glob-base": "^0.3.0",
+ "isomorphic-unfetch": "^4.0.2",
+ "js-base64": "^3.7.2",
+ "js-beautify": "^1.14.9",
+ "json-to-pretty-yaml": "^1.2.2",
+ "markdown-it": "^13.0.1",
+ "md5": "^2.3.0",
+ "moment": "^2.29.4",
+ "native-promise-pool": "^3.19.0",
+ "pretty": "^2.0.0",
+ "querystring": "^0.2.1",
+ "request": "^2.88.2",
+ "sanitize-filename": "^1.6.3",
+ "showdown": "^2.1.0",
+ "simple-git": "^3.19.1",
+ "slugify": "^1.6.6",
+ "tslog": "^3.3.4",
+ "turndown": "^7.1.2",
+ "typescript": "^4.3.5",
+ "uri-js": "^4.4.1",
+ "yargs": "^17.5.1"
+ },
+ "scripts": {
+ "test": "tsc; mocha --full-trace mocha \"spec/**/*.spec.js\"",
+ "test-with-coverage": "istanbul cover node_modules/.bin/_mocha -- 'spec/**/*.spec.js'",
+ "lint": "tslint --project=./tsconfig.json",
+ "build": "tsc -p . --declaration",
+ "dev": "tsc -p . --declaration -w",
+ "typings": "tsc --declaration",
+ "docs": "npx typedoc src/index.ts",
+ "dev-test-watch": "mocha-typescript-watch",
+ "typesafe-i18n": "typesafe-i18n",
+ "link-dev": "sh scripts/link-dev.sh"
+ },
+ "homepage": "https://git.osr-plastic.org/plastichub/lib-content",
+ "repository": {
+ "type": "git",
+ "url": "https://git.osr-plastic.org/plastichub/lib-content.git"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ },
+ "license": "BSD-3-Clause",
+ "keywords": [
+ "typescript"
+ ]
+}
diff --git a/packages/discourse/commands/category.d.ts b/packages/discourse/commands/category.d.ts
new file mode 100644
index 00000000..5ea23d05
--- /dev/null
+++ b/packages/discourse/commands/category.d.ts
@@ -0,0 +1,12 @@
+import * as CLI from 'yargs';
+export declare const register: (cli: CLI.Argv) => CLI.Argv<{
+ debug: boolean;
+} & {
+ short: string | boolean;
+} & {
+ disabled: string | boolean;
+} & {
+ dry: string;
+} & {
+ env_key: string;
+}>;
diff --git a/packages/discourse/commands/category.js b/packages/discourse/commands/category.js
new file mode 100644
index 00000000..64bf7168
--- /dev/null
+++ b/packages/discourse/commands/category.js
@@ -0,0 +1,103 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.register = void 0;
+const path = require("path");
+const write_1 = require("@plastichub/fs/write");
+const osr_cli_commons_1 = require("@plastichub/osr-cli-commons");
+const _cli_1 = require("../_cli");
+const options_1 = require("../options");
+const __1 = require("..");
+const lib_1 = require("../lib");
+const category_1 = require("../lib/cscart/category");
+const defaultOptions = (yargs) => {
+ return yargs.option('debug', {
+ default: false,
+ describe: 'debug messages',
+ type: 'boolean'
+ }).option('short', {
+ default: 'true',
+ describe: 'Emit short info only',
+ type: 'boolean'
+ }).option('disabled', {
+ default: 'false',
+ describe: 'Enumerate disabled products',
+ type: 'boolean'
+ }).option('dry', {
+ default: 'false',
+ describe: 'Process files for debug purposes only.'
+ }).option('env_key', {
+ default: 'OSR-CONFIG',
+ describe: 'Environment key to the config path.'
+ });
+};
+let options = (yargs) => defaultOptions(yargs);
+const register = (cli) => {
+ return cli.command('category ', 'Category namespace', options, (argv) => __awaiter(void 0, void 0, void 0, function* () {
+ (0, _cli_1.defaults)();
+ if (argv.help) {
+ return;
+ }
+ const args = argv;
+ const config = (0, osr_cli_commons_1.CONFIG_DEFAULT)(args.env_key);
+ let options = (0, _cli_1.sanitize)(argv);
+ if (!options) {
+ return;
+ }
+ options.debug && __1.logger.debug(`CLI Args In`, argv);
+ let opts = (0, options_1.parse)(options, args);
+ if (!opts.verb) {
+ __1.logger.error('No verb specified');
+ return;
+ }
+ if (opts.verb == 'list') {
+ let _categories = yield (0, lib_1.categories)(config.cscart);
+ if (opts.dst) {
+ (0, category_1.writeCategories)(_categories, opts);
+ }
+ else {
+ __1.logger.debug('Categories', _categories);
+ }
+ }
+ if (opts.verb == 'get') {
+ let cat = yield (0, category_1.get_category)(opts.id, config.cscart);
+ opts.debug && __1.logger.debug(`Get category ${opts.id} `, cat);
+ if (cat && opts.dst) {
+ let _path = path.resolve(opts.dst);
+ (0, write_1.sync)(_path, cat);
+ opts.debug && __1.logger.debug(`Writing category to ${_path}`);
+ }
+ }
+ if (opts.verb == 'delete') {
+ return yield (0, category_1.delete_category)(opts.id, config.cscart);
+ }
+ if (opts.verb == 'create') {
+ const args = {
+ category: 'cat',
+ company_id: 1,
+ status: 'H',
+ parent_id: 6
+ };
+ let _item = yield (0, category_1.create_category)(args, config.cscart);
+ __1.logger.debug(`Created category ! ID:`, _item);
+ }
+ if (opts.verb == 'update') {
+ const args = {
+ category: 'renamed'
+ };
+ let _item = yield (0, category_1.update_category)(opts.id, args, config.cscart);
+ __1.logger.debug(`Updated category ! ID:${opts.id}`, _item);
+ }
+ return;
+ }));
+};
+exports.register = register;
+//# sourceMappingURL=category.js.map
\ No newline at end of file
diff --git a/packages/discourse/commands/category.js.map b/packages/discourse/commands/category.js.map
new file mode 100644
index 00000000..ae4671ed
--- /dev/null
+++ b/packages/discourse/commands/category.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"category.js","sourceRoot":"","sources":["../src/commands/category.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/discourse/commands/import-oa-howtos.d.ts b/packages/discourse/commands/import-oa-howtos.d.ts
new file mode 100644
index 00000000..443f33e5
--- /dev/null
+++ b/packages/discourse/commands/import-oa-howtos.d.ts
@@ -0,0 +1,2 @@
+import * as CLI from 'yargs';
+export declare const register: (cli: CLI.Argv) => CLI.Argv<{}>;
diff --git a/packages/discourse/commands/import-oa-howtos.js b/packages/discourse/commands/import-oa-howtos.js
new file mode 100644
index 00000000..817dec19
--- /dev/null
+++ b/packages/discourse/commands/import-oa-howtos.js
@@ -0,0 +1,53 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.register = void 0;
+const _cli_1 = require("../_cli");
+const index_1 = require("../index");
+const discourse_1 = require("../lib/discourse");
+const commons_1 = require("../lib/oa/commons");
+const howtos_1 = require("../lib/oa/howtos");
+const path = require("path");
+const fs_1 = require("@plastichub/osr-commons");
+const KB_ROOT = '${KB_ROOT}';
+const osr_commons_1 = require("@plastichub/osr-commons");
+const defaultOptions = (yargs) => {
+ return yargs.option('debug', {
+ default: true,
+ describe: 'debug messages',
+ type: 'boolean'
+ }).option('src', {
+ default: osr_commons_1.OA_LATEST,
+ type: 'string',
+ }).option('track', {
+ default: '${OA_ROOT}/oa-data/howtos/latest_track.json',
+ type: 'string',
+ }).option('env_key', {
+ default: 'OSR-CONFIG',
+ describe: 'Environment key to the config path.'
+ });
+};
+let options = (yargs) => defaultOptions(yargs);
+const register = (cli) => {
+ return cli.command('import-howtos', 'Import oa-howtos', options, async (argv) => {
+ (0, _cli_1.defaults)();
+ if (argv.help) {
+ return;
+ }
+ let options = argv;
+ if (!options) {
+ return;
+ }
+ options.debug && index_1.logger.debug(`CLI Args In`, argv);
+ const discourse = (0, discourse_1.Instance)();
+ const _opts = {
+ src: path.resolve((0, fs_1.resolve)(options.src)),
+ track: path.resolve((0, fs_1.resolve)(options.track))
+ };
+ let howtos = (0, commons_1.read_howtos)(_opts.src);
+ howtos = (0, commons_1.filter_valid)(howtos);
+ await (0, howtos_1.importHowtos)(discourse, _opts, howtos);
+ await (0, howtos_1.updateHowtos)(discourse, _opts, howtos);
+ });
+};
+exports.register = register;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wb3J0LW9hLWhvd3Rvcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tYW5kcy9pbXBvcnQtb2EtaG93dG9zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUVBLGtDQUE0QztBQUU1QyxvQ0FBOEM7QUFFOUMsZ0RBQTJDO0FBZTNDLCtDQUswQjtBQUUxQiw2Q0FFeUI7QUFRekIsNkJBQTRCO0FBQzVCLHVEQUF3RDtBQUd4RCxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUE7QUFRNUIseURBQW1EO0FBRW5ELE1BQU0sY0FBYyxHQUFHLENBQUMsS0FBZSxFQUFFLEVBQUU7SUFDdkMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRTtRQUN6QixPQUFPLEVBQUUsSUFBSTtRQUNiLFFBQVEsRUFBRSxnQkFBZ0I7UUFDMUIsSUFBSSxFQUFFLFNBQVM7S0FDbEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7UUFDYixPQUFPLEVBQUUsdUJBQVM7UUFDbEIsSUFBSSxFQUFFLFFBQVE7S0FDakIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7UUFDZixPQUFPLEVBQUUsNkNBQTZDO1FBQ3RELElBQUksRUFBRSxRQUFRO0tBQ2pCLENBQUMsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFO1FBQ2pCLE9BQU8sRUFBRSxZQUFZO1FBQ3JCLFFBQVEsRUFBRSxxQ0FBcUM7S0FDbEQsQ0FBQyxDQUFBO0FBQ04sQ0FBQyxDQUFBO0FBRUQsSUFBSSxPQUFPLEdBQUcsQ0FBQyxLQUFlLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQTtBQUVqRCxNQUFNLFFBQVEsR0FBRyxDQUFDLEdBQWEsRUFBRSxFQUFFO0lBQ3RDLE9BQU8sR0FBRyxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsa0JBQWtCLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFtQixFQUFFLEVBQUU7UUFDM0YsSUFBQSxlQUFRLEdBQUUsQ0FBQTtRQUNWLElBQUksSUFBSSxDQUFDLElBQUksRUFBRTtZQUFFLE9BQU07U0FBRTtRQUN6QixJQUFJLE9BQU8sR0FBSSxJQUF3QixDQUFBO1FBRXZDLElBQUksQ0FBQyxPQUFPLEVBQUU7WUFDVixPQUFNO1NBQ1Q7UUFDRCxPQUFPLENBQUMsS0FBSyxJQUFJLGNBQU0sQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxDQUFBO1FBRWxELE1BQU0sU0FBUyxHQUFHLElBQUEsb0JBQVEsR0FBRSxDQUFBO1FBRTVCLE1BQU0sS0FBSyxHQUFHO1lBQ1YsR0FBRyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBQSxZQUFPLEVBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3ZDLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUEsWUFBTyxFQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNsQyxDQUFBO1FBRWIsSUFBSSxNQUFNLEdBQUcsSUFBQSxxQkFBVyxFQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNuQyxNQUFNLEdBQUcsSUFBQSxzQkFBWSxFQUFDLE1BQU0sQ0FBQyxDQUFBO1FBQzdCLE1BQU0sSUFBQSxxQkFBWSxFQUFDLFNBQVMsRUFBQyxLQUFLLEVBQUMsTUFBTSxDQUFDLENBQUE7UUFDMUMsTUFBTSxJQUFBLHFCQUFZLEVBQUMsU0FBUyxFQUFDLEtBQUssRUFBQyxNQUFNLENBQUMsQ0FBQTtJQUM5QyxDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUMsQ0FBQTtBQXZCWSxRQUFBLFFBQVEsWUF1QnBCIn0=
\ No newline at end of file
diff --git a/packages/discourse/commands/import-oa-users.d.ts b/packages/discourse/commands/import-oa-users.d.ts
new file mode 100644
index 00000000..443f33e5
--- /dev/null
+++ b/packages/discourse/commands/import-oa-users.d.ts
@@ -0,0 +1,2 @@
+import * as CLI from 'yargs';
+export declare const register: (cli: CLI.Argv) => CLI.Argv<{}>;
diff --git a/packages/discourse/commands/import-oa-users.js b/packages/discourse/commands/import-oa-users.js
new file mode 100644
index 00000000..84b3f40f
--- /dev/null
+++ b/packages/discourse/commands/import-oa-users.js
@@ -0,0 +1,88 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.register = void 0;
+const _cli_1 = require("../_cli");
+const options_1 = require("../options");
+const index_1 = require("../index");
+const discourse_1 = require("../lib/discourse");
+const write_1 = require("@plastichub/fs/write");
+const users_1 = require("../lib/oa/users");
+const path = require("path");
+const fs_1 = require("@plastichub/osr-commons");
+const defaultOptions = (yargs) => {
+ return yargs.option('debug', {
+ default: false,
+ describe: 'debug messages',
+ type: 'boolean'
+ }).option('src', {
+ default: '${OA_ROOT}/data/latest.json',
+ type: 'string',
+ }).option('track', {
+ default: '${OSR_ROOT}/osr-directory/pp/merged.json',
+ type: 'string',
+ }).option('env_key', {
+ default: 'OSR-CONFIG',
+ describe: 'Environment key to the config path.'
+ });
+};
+let options = (yargs) => defaultOptions(yargs);
+const register = (cli) => {
+ return cli.command('import-users ', 'Import oa-users', options, async (argv) => {
+ (0, _cli_1.defaults)();
+ if (argv.help) {
+ return;
+ }
+ const args = argv;
+ let options = (0, _cli_1.sanitize)(argv);
+ if (!options) {
+ return;
+ }
+ options.debug && index_1.logger.debug(`CLI Args In`, argv);
+ let opts = (0, options_1.parse)(options, args);
+ const discourse = (0, discourse_1.Instance)();
+ const _opts = {
+ verb: argv.verb,
+ src: path.resolve((0, fs_1.resolve)(options.src)),
+ track: path.resolve((0, fs_1.resolve)(options.track))
+ };
+ let users = (0, users_1.read_users)(_opts.src);
+ users = (0, users_1.filter_valid)(users);
+ //////////////////////////
+ //
+ // store invalid
+ let usersInvalid = (0, users_1.read_users)(_opts.src);
+ usersInvalid = (0, users_1.filter_email_only)(usersInvalid);
+ usersInvalid = (0, users_1.filter_invalid)(usersInvalid);
+ index_1.logger.debug('write invalidUsers.json : ', (0, users_1.getDataPath)('/invalidUsers.json'));
+ (0, write_1.sync)((0, users_1.getDataPath)('/invalidUsers.json'), usersInvalid.map((u) => {
+ return {
+ ...u.detail,
+ id: u._id,
+ email: (0, users_1.oa_user_email)(u)
+ };
+ }));
+ let usersInvalidEmail = (0, users_1.read_users)(_opts.src);
+ usersInvalidEmail = (0, users_1.filter_email_missing)(usersInvalidEmail);
+ index_1.logger.debug('write invalidUsersEMail.json : ', (0, users_1.getDataPath)('/invalidUsersEMail.json'));
+ (0, write_1.sync)((0, users_1.getDataPath)('./invalidUsersEMail.json'), usersInvalidEmail.map((u) => {
+ return {
+ ...u.detail,
+ id: u._id
+ };
+ }));
+ index_1.logger.debug('invalid users email : ', usersInvalidEmail.length);
+ index_1.logger.debug('invalid users : ', usersInvalid.length);
+ if (opts.verb == 'index') {
+ await (0, users_1.indexUsers)(discourse, options, users);
+ }
+ if (opts.verb == 'import') {
+ await (0, users_1.importUsers)(discourse, options, users);
+ }
+ if (opts.verb == 'update') {
+ await (0, users_1.updateUsers)(discourse, options, users);
+ }
+ return;
+ });
+};
+exports.register = register;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wb3J0LW9hLXVzZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbW1hbmRzL2ltcG9ydC1vYS11c2Vycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxrQ0FBNEM7QUFDNUMsd0NBQWtDO0FBRWxDLG9DQUE4QztBQUU5QyxnREFBMkM7QUFFM0MsZ0RBQW9EO0FBSXBELDJDQVV3QjtBQUV4Qiw2QkFBNEI7QUFDNUIsdURBQXdEO0FBRXhELE1BQU0sY0FBYyxHQUFHLENBQUMsS0FBZSxFQUFFLEVBQUU7SUFDdkMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRTtRQUN6QixPQUFPLEVBQUUsS0FBSztRQUNkLFFBQVEsRUFBRSxnQkFBZ0I7UUFDMUIsSUFBSSxFQUFFLFNBQVM7S0FDbEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUU7UUFDYixPQUFPLEVBQUUsNkJBQTZCO1FBQ3RDLElBQUksRUFBRSxRQUFRO0tBQ2pCLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFO1FBQ2YsT0FBTyxFQUFFLDBDQUEwQztRQUNuRCxJQUFJLEVBQUUsUUFBUTtLQUNqQixDQUFDLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRTtRQUNqQixPQUFPLEVBQUUsWUFBWTtRQUNyQixRQUFRLEVBQUUscUNBQXFDO0tBQ2xELENBQUMsQ0FBQTtBQUNOLENBQUMsQ0FBQTtBQUVELElBQUksT0FBTyxHQUFHLENBQUMsS0FBZSxFQUFFLEVBQUUsQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUE7QUFFakQsTUFBTSxRQUFRLEdBQUcsQ0FBQyxHQUFhLEVBQUUsRUFBRTtJQUN0QyxPQUFPLEdBQUcsQ0FBQyxPQUFPLENBQUMscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFtQixFQUFFLEVBQUU7UUFFaEcsSUFBQSxlQUFRLEdBQUUsQ0FBQTtRQUVWLElBQUksSUFBSSxDQUFDLElB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
\ No newline at end of file
diff --git a/packages/discourse/commands/import-oa.d.ts b/packages/discourse/commands/import-oa.d.ts
new file mode 100644
index 00000000..eb7ef92a
--- /dev/null
+++ b/packages/discourse/commands/import-oa.d.ts
@@ -0,0 +1,10 @@
+import * as CLI from 'yargs';
+export declare const register: (cli: CLI.Argv) => CLI.Argv<{
+ debug: boolean;
+} & {
+ src: string;
+} & {
+ track: string;
+} & {
+ env_key: string;
+}>;
diff --git a/packages/discourse/commands/import-oa.js b/packages/discourse/commands/import-oa.js
new file mode 100644
index 00000000..905ccbcc
--- /dev/null
+++ b/packages/discourse/commands/import-oa.js
@@ -0,0 +1,89 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.register = void 0;
+const _cli_1 = require("../_cli");
+const options_1 = require("../options");
+const index_1 = require("../index");
+const discourse_1 = require("../lib/discourse");
+const write_1 = require("@plastichub/fs/write");
+const users_1 = require("../lib/oa/users");
+const path = require("path");
+const fs_1 = require("@plastichub/osr-commons");
+const KB_ROOT = '${KB_ROOT}';
+const defaultOptions = (yargs) => {
+ return yargs.option('debug', {
+ default: false,
+ describe: 'debug messages',
+ type: 'boolean'
+ }).option('src', {
+ default: '${OA_ROOT}/data/latest.json',
+ type: 'string',
+ }).option('track', {
+ default: './latest_track.json',
+ type: 'string',
+ }).option('env_key', {
+ default: 'OSR-CONFIG',
+ describe: 'Environment key to the config path.'
+ });
+};
+let options = (yargs) => defaultOptions(yargs);
+const register = (cli) => {
+ return cli.command('import ', 'Import oa-users', options, async (argv) => {
+ (0, _cli_1.defaults)();
+ if (argv.help) {
+ return;
+ }
+ const args = argv;
+ let options = (0, _cli_1.sanitize)(argv);
+ if (!options) {
+ return;
+ }
+ options.debug && index_1.logger.debug(`CLI Args In`, argv);
+ let opts = (0, options_1.parse)(options, args);
+ if (!opts.verb) {
+ index_1.logger.error('No verb specified');
+ return;
+ }
+ const discourse = (0, discourse_1.Instance)();
+ const _opts = {
+ verb: argv.verb,
+ src: path.resolve((0, fs_1.resolve)(options.src)),
+ track: path.resolve((0, fs_1.resolve)(options.track))
+ };
+ if (opts.verb == 'users') {
+ let users = (0, users_1.read_users)(_opts.src);
+ // users = filter_email_only(users)
+ //users = filter_accepted(users as IImportUser[])
+ users = (0, users_1.filter_valid)(users);
+ //////////////////////////
+ //
+ // store invalid
+ let usersInvalid = (0, users_1.read_users)(_opts.src);
+ usersInvalid = (0, users_1.filter_email_only)(usersInvalid);
+ usersInvalid = (0, users_1.filter_invalid)(usersInvalid);
+ (0, write_1.sync)((0, users_1.getDataPath)('/invalidUsers.json'), usersInvalid.map((u) => {
+ return {
+ ...u.detail,
+ id: u._id,
+ email: (0, users_1.oa_user_email)(u)
+ };
+ }));
+ let usersInvalidEmail = (0, users_1.read_users)(_opts.src);
+ usersInvalidEmail = (0, users_1.filter_email_missing)(usersInvalidEmail);
+ (0, write_1.sync)((0, users_1.getDataPath)('./invalidUsersEMail.json'), usersInvalidEmail.map((u) => {
+ return {
+ ...u.detail,
+ id: u._id
+ };
+ }));
+ console.log('invalid users : ', usersInvalidEmail.length);
+ await (0, users_1.importUsers)(discourse, options, users);
+ // await updateUsers(discourse, options, users)
+ // const items = await discourse.search('Sheetpress - Cell','tags:sheetpress')
+ // logger.info('items',items)
+ }
+ return;
+ });
+};
+exports.register = register;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1wb3J0LW9hLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbW1hbmRzL2ltcG9ydC1vYS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxrQ0FBNEM7QUFDNUMsd0NBQWtDO0FBRWxDLG9DQUE4QztBQUU5QyxnREFBMkM7QUFFM0MsZ0RBQW9EO0FBRXBELDJDQVV3QjtBQUd4Qiw2QkFBNEI7QUFDNUIsdURBQXdEO0FBSXhELE1BQU0sT0FBTyxHQUFHLFlBQVksQ0FBQTtBQUU1QixNQUFNLGNBQWMsR0FBRyxDQUFDLEtBQWUsRUFBRSxFQUFFO0lBQ3ZDLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7UUFDekIsT0FBTyxFQUFFLEtBQUs7UUFDZCxRQUFRLEVBQUUsZ0JBQWdCO1FBQzFCLElBQUksRUFBRSxTQUFTO0tBQ2xCLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFO1FBQ2IsT0FBTyxFQUFFLDZCQUE2QjtRQUN0QyxJQUFJLEVBQUUsUUFBUTtLQUNqQixDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRTtRQUNmLE9BQU8sRUFBRSxxQkFBcUI7UUFDOUIsSUFBSSxFQUFFLFFBQVE7S0FDakIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUU7UUFDakIsT0FBTyxFQUFFLFlBQVk7UUFDckIsUUFBUSxFQUFFLHFDQUFxQztLQUNsRCxDQUFDLENBQUE7QUFDTixDQUFDLENBQUE7QUFFRCxJQUFJLE9BQU8sR0FBRyxDQUFDLEtBQWUsRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFBO0FBRWpELE1BQU0sUUFBUSxHQUFHLENBQUMsR0FBYSxFQUFFLEVBQUU7SUFDdEMsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxpQkFBaUIsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQW1CLEVBQUUsRUFBRTtRQUUxRixJQUFBLGVBQVEsR0FBRSxDQUFBO1FBRVYs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
\ No newline at end of file
diff --git a/packages/discourse/commands/info.d.ts b/packages/discourse/commands/info.d.ts
new file mode 100644
index 00000000..443f33e5
--- /dev/null
+++ b/packages/discourse/commands/info.d.ts
@@ -0,0 +1,2 @@
+import * as CLI from 'yargs';
+export declare const register: (cli: CLI.Argv) => CLI.Argv<{}>;
diff --git a/packages/discourse/commands/info.js b/packages/discourse/commands/info.js
new file mode 100644
index 00000000..8efb656e
--- /dev/null
+++ b/packages/discourse/commands/info.js
@@ -0,0 +1,27 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.register = void 0;
+const osr_cli_commons_1 = require("@plastichub/osr-cli-commons");
+const index_1 = require("../index");
+const defaultOptions = (yargs) => {
+ return yargs.option('debug', {
+ default: 'false',
+ describe: 'debug messages'
+ }).option('env_key', {
+ default: 'OSR-CONFIG',
+ describe: 'Environment key to the config path'
+ });
+};
+let options = (yargs) => defaultOptions(yargs);
+const register = (cli) => {
+ return cli.command('info', 'info', options, async (argv) => {
+ if (argv.help) {
+ return;
+ }
+ const args = argv;
+ const src = (0, osr_cli_commons_1.CONFIG_DEFAULT)(args.env_key);
+ index_1.logger.debug(`Reading OSR Config with key "${argv.env_key}"`, src);
+ });
+};
+exports.register = register;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5mby5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9jb21tYW5kcy9pbmZvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLGlFQUE0RDtBQUM1RCxvQ0FBaUM7QUFFakMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxLQUFlLEVBQUUsRUFBRTtJQUN2QyxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFO1FBQ3pCLE9BQU8sRUFBRSxPQUFPO1FBQ2hCLFFBQVEsRUFBRSxnQkFBZ0I7S0FDN0IsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUU7UUFDakIsT0FBTyxFQUFFLFlBQVk7UUFDckIsUUFBUSxFQUFFLG9DQUFvQztLQUNqRCxDQUFDLENBQUE7QUFDTixDQUFDLENBQUE7QUFFRCxJQUFJLE9BQU8sR0FBRyxDQUFDLEtBQWUsRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBRWxELE1BQU0sUUFBUSxHQUFHLENBQUMsR0FBYSxFQUFFLEVBQUU7SUFDdEMsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxJQUFtQixFQUFFLEVBQUU7UUFDdEUsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQUUsT0FBTTtTQUFFO1FBQ3pCLE1BQU0sSUFBSSxHQUFRLElBQUksQ0FBQTtRQUN0QixNQUFNLEdBQUcsR0FBRyxJQUFBLGdDQUFjLEVBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQ3hDLGNBQU0sQ0FBQyxLQUFLLENBQUMsZ0NBQWdDLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUN0RSxDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUMsQ0FBQTtBQVBZLFFBQUEsUUFBUSxZQU9wQiJ9
\ No newline at end of file
diff --git a/packages/discourse/commands/info.js.map b/packages/discourse/commands/info.js.map
new file mode 100644
index 00000000..34acfddc
--- /dev/null
+++ b/packages/discourse/commands/info.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"info.js","sourceRoot":"","sources":["../src/commands/info.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,iEAA6D;AAC7D,2BAA4B;AAE5B,MAAM,cAAc,GAAG,CAAC,KAAe,EAAE,EAAE;IACvC,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE;QACzB,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,gBAAgB;KAC7B,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE;QACjB,OAAO,EAAE,YAAY;QACrB,QAAQ,EAAE,oCAAoC;KACjD,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,IAAI,OAAO,GAAG,CAAC,KAAe,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;AAElD,MAAM,QAAQ,GAAG,CAAC,GAAa,EAAE,EAAE;IACtC,OAAO,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAO,IAAmB,EAAE,EAAE;QACtE,IAAI,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO;SAAE;QAC1B,MAAM,IAAI,GAAQ,IAAI,CAAC;QACvB,MAAM,GAAG,GAAG,IAAA,gCAAc,EAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACzC,UAAM,CAAC,KAAK,CAAC,gCAAgC,IAAI,CAAC,OAAO,GAAG,EAAE,GAAG,CAAC,CAAC;IACvE,CAAC,CAAA,CAAC,CAAC;AACP,CAAC,CAAC;AAPW,QAAA,QAAQ,YAOnB"}
\ No newline at end of file
diff --git a/packages/discourse/commands/product.d.ts b/packages/discourse/commands/product.d.ts
new file mode 100644
index 00000000..675c3fc3
--- /dev/null
+++ b/packages/discourse/commands/product.d.ts
@@ -0,0 +1,14 @@
+import * as CLI from 'yargs';
+export declare const register: (cli: CLI.Argv) => CLI.Argv<{
+ debug: boolean;
+} & {
+ id: number;
+} & {
+ short: string | boolean;
+} & {
+ disabled: string | boolean;
+} & {
+ dry: string;
+} & {
+ env_key: string;
+}>;
diff --git a/packages/discourse/commands/product.js b/packages/discourse/commands/product.js
new file mode 100644
index 00000000..708c4468
--- /dev/null
+++ b/packages/discourse/commands/product.js
@@ -0,0 +1,110 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.register = void 0;
+const path = require("path");
+const osr_cli_commons_1 = require("@plastichub/osr-cli-commons");
+const write_1 = require("@plastichub/fs/write");
+const _cli_1 = require("../_cli");
+const options_1 = require("../options");
+const __1 = require("..");
+const product_1 = require("../lib/cscart/product");
+const defaultOptions = (yargs) => {
+ return yargs.option('debug', {
+ default: false,
+ describe: 'debug messages',
+ type: 'boolean'
+ }).option('id', {
+ describe: 'Entity ID',
+ type: 'number'
+ }).option('short', {
+ default: 'true',
+ describe: 'Emit short info only',
+ type: 'boolean'
+ }).option('disabled', {
+ default: 'false',
+ describe: 'Enumerate disabled products',
+ type: 'boolean'
+ }).option('dry', {
+ default: 'false',
+ describe: 'Process files for debug purposes only.'
+ }).option('env_key', {
+ default: 'OSR-CONFIG',
+ describe: 'Environment key to the config path.'
+ });
+};
+let options = (yargs) => defaultOptions(yargs);
+const register = (cli) => {
+ return cli.command('product ', 'Product namespace', options, (argv) => __awaiter(void 0, void 0, void 0, function* () {
+ (0, _cli_1.defaults)();
+ if (argv.help) {
+ return;
+ }
+ const args = argv;
+ const config = (0, osr_cli_commons_1.CONFIG_DEFAULT)(args.env_key);
+ let options = (0, _cli_1.sanitize)(argv);
+ if (!options) {
+ return;
+ }
+ options.debug && __1.logger.debug(`CLI Args In`, argv);
+ let opts = (0, options_1.parse)(options, args);
+ if (!opts.verb) {
+ __1.logger.error('No verb specified');
+ return;
+ }
+ if (opts.verb == 'list') {
+ let _products = yield (0, product_1.products)(config.cscart);
+ if (opts.dst) {
+ (0, product_1.writeProducts)(_products, opts);
+ }
+ }
+ if (opts.verb == 'delete') {
+ return yield (0, product_1.delete_product)(opts.id, config.cscart);
+ }
+ if (opts.verb == 'get') {
+ let _product = yield (0, product_1.get_product)(opts.id, config.cscart);
+ opts.debug && __1.logger.debug(`Get product ${opts.id} `, _product);
+ if (_product && opts.dst) {
+ let _path = path.resolve(opts.dst);
+ (0, write_1.sync)(_path, _product);
+ opts.debug && __1.logger.debug(`Writing product to ${_path}`);
+ }
+ }
+ if (opts.verb == 'create') {
+ const args = {
+ product: 'xxxx2',
+ price: 1234,
+ main_category: 22,
+ category_ids: [22],
+ status: 'A',
+ company_id: 1
+ };
+ let _product = yield (0, product_1.create_product)(args, config.cscart);
+ __1.logger.debug(`Created product ! ID:`, _product);
+ }
+ if (opts.verb == 'update') {
+ const args = {
+ price: 12342,
+ product: "cscart-api-test",
+ status: 'H',
+ full_description: "test - es>",
+ meta_keywords: "pp,hdpe",
+ category_ids: [22, 15],
+ lang_code: 'es'
+ };
+ let _product = yield (0, product_1.update_product)(opts.id, args, config.cscart);
+ __1.logger.debug(`Updated product ! ID:${opts.id}`, _product);
+ }
+ return;
+ }));
+};
+exports.register = register;
+//# sourceMappingURL=product.js.map
\ No newline at end of file
diff --git a/packages/discourse/commands/product.js.map b/packages/discourse/commands/product.js.map
new file mode 100644
index 00000000..b255d414
--- /dev/null
+++ b/packages/discourse/commands/product.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"product.js","sourceRoot":"","sources":["../src/commands/product.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/discourse/commands/query.d.ts b/packages/discourse/commands/query.d.ts
new file mode 100644
index 00000000..443f33e5
--- /dev/null
+++ b/packages/discourse/commands/query.d.ts
@@ -0,0 +1,2 @@
+import * as CLI from 'yargs';
+export declare const register: (cli: CLI.Argv) => CLI.Argv<{}>;
diff --git a/packages/discourse/commands/query.js b/packages/discourse/commands/query.js
new file mode 100644
index 00000000..44350480
--- /dev/null
+++ b/packages/discourse/commands/query.js
@@ -0,0 +1,56 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.register = void 0;
+const _cli_1 = require("../_cli");
+const options_1 = require("../options");
+const index_1 = require("../index");
+const discourse_1 = require("../lib/discourse");
+const defaultOptions = (yargs) => {
+ return yargs.option('debug', {
+ default: false,
+ describe: 'debug messages',
+ type: 'boolean'
+ }).option('short', {
+ default: 'true',
+ describe: 'Emit short info only',
+ type: 'boolean'
+ }).option('disabled', {
+ default: 'false',
+ describe: 'Enumerate disabled products',
+ type: 'boolean'
+ }).option('dry', {
+ default: 'false',
+ describe: 'Process files for debug purposes only.'
+ }).option('env_key', {
+ default: 'OSR-CONFIG',
+ describe: 'Environment key to the config path.'
+ });
+};
+let options = (yargs) => defaultOptions(yargs);
+const register = (cli) => {
+ return cli.command('query ', 'Search namespace', options, async (argv) => {
+ (0, _cli_1.defaults)();
+ if (argv.help) {
+ return;
+ }
+ const args = argv;
+ let options = (0, _cli_1.sanitize)(argv);
+ if (!options) {
+ return;
+ }
+ options.debug && index_1.logger.debug(`CLI Args In`, argv);
+ let opts = (0, options_1.parse)(options, args);
+ if (!opts.verb) {
+ index_1.logger.error('No verb specified');
+ return;
+ }
+ const discourse = (0, discourse_1.Instance)();
+ if (opts.verb == 'tags') {
+ const items = await discourse.search('Sheetpress - Cell', 'tags:sheetpress');
+ index_1.logger.info('items', items);
+ }
+ return;
+ });
+};
+exports.register = register;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVlcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29tbWFuZHMvcXVlcnkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsa0NBQTRDO0FBQzVDLHdDQUFrQztBQUVsQyxvQ0FBaUM7QUFFakMsZ0RBQTJDO0FBRTNDLE1BQU0sY0FBYyxHQUFHLENBQUMsS0FBZSxFQUFFLEVBQUU7SUFDdkMsT0FBTyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRTtRQUN6QixPQUFPLEVBQUUsS0FBSztRQUNkLFFBQVEsRUFBRSxnQkFBZ0I7UUFDMUIsSUFBSSxFQUFFLFNBQVM7S0FDbEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUU7UUFDZixPQUFPLEVBQUUsTUFBTTtRQUNmLFFBQVEsRUFBRSxzQkFBc0I7UUFDaEMsSUFBSSxFQUFFLFNBQVM7S0FDbEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxVQUFVLEVBQUU7UUFDbEIsT0FBTyxFQUFFLE9BQU87UUFDaEIsUUFBUSxFQUFFLDZCQUE2QjtRQUN2QyxJQUFJLEVBQUUsU0FBUztLQUNsQixDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRTtRQUNiLE9BQU8sRUFBRSxPQUFPO1FBQ2hCLFFBQVEsRUFBRSx3Q0FBd0M7S0FDckQsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUU7UUFDakIsT0FBTyxFQUFFLFlBQVk7UUFDckIsUUFBUSxFQUFFLHFDQUFxQztLQUNsRCxDQUFDLENBQUE7QUFDTixDQUFDLENBQUE7QUFFRCxJQUFJLE9BQU8sR0FBRyxDQUFDLEtBQWUsRUFBRSxFQUFFLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFBO0FBRWpELE1BQU0sUUFBUSxHQUFHLENBQUMsR0FBYSxFQUFFLEVBQUU7SUFDdEMsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQW1CLEVBQUUsRUFBRTtRQUMxRixJQUFBLGVBQVEsR0FBRSxDQUFDO1FBQ1gsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQUUsT0FBTTtTQUFFO1FBQ3pCLE1BQU0sSUFBSSxHQUFRLElBQUksQ0FBQTtRQUV0QixJQUFJLE9BQU8sR0FBRyxJQUFBLGVBQVEsRUFBQyxJQUFXLENBQWEsQ0FBQTtRQUUvQyxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ1YsT0FBTTtTQUNUO1FBQ0QsT0FBTyxDQUFDLEtBQUssSUFBSSxjQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQTtRQUNsRCxJQUFJLElBQUksR0FBRyxJQUFBLGVBQUssRUFBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUE7UUFFL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDWixjQUFNLENBQUMsS0FBSyxDQUFDLG1CQUFtQixDQUFDLENBQUE7WUFDakMsT0FBTztTQUNWO1FBQ0QsTUFBTSxTQUFTLEdBQUcsSUFBQSxvQkFBUSxHQUFFLENBQUE7UUFDNUIsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLE1BQU0sRUFBRTtZQUNyQixNQUFNLEtBQUssR0FBRyxNQUFNLFNBQVMsQ0FBQyxNQUFNLENBQUMsbUJBQW1CLEVBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUM1RSxjQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBQyxLQUFLLENBQUMsQ0FBQTtTQUM3QjtRQUNELE9BQU07SUFDVixDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUMsQ0FBQTtBQXpCWSxRQUFBLFFBQVEsWUF5QnBCIn0=
\ No newline at end of file
diff --git a/packages/discourse/commands/query.js.map b/packages/discourse/commands/query.js.map
new file mode 100644
index 00000000..2f4871b8
--- /dev/null
+++ b/packages/discourse/commands/query.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"query.js","sourceRoot":"","sources":["../src/commands/query.ts"],"names":[],"mappings":";;;;;;;;;;;;AAEA,kCAA4C;AAC5C,wCAAkC;AAElC,0BAA2B;AAE3B,gDAA2C;AAE3C,MAAM,cAAc,GAAG,CAAC,KAAe,EAAE,EAAE;IACvC,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE;QACzB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,gBAAgB;QAC1B,IAAI,EAAE,SAAS;KAClB,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE;QACf,OAAO,EAAE,MAAM;QACf,QAAQ,EAAE,sBAAsB;QAChC,IAAI,EAAE,SAAS;KAClB,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE;QAClB,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,6BAA6B;QACvC,IAAI,EAAE,SAAS;KAClB,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE;QACb,OAAO,EAAE,OAAO;QAChB,QAAQ,EAAE,wCAAwC;KACrD,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE;QACjB,OAAO,EAAE,YAAY;QACrB,QAAQ,EAAE,qCAAqC;KAClD,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,IAAI,OAAO,GAAG,CAAC,KAAe,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;AAElD,MAAM,QAAQ,GAAG,CAAC,GAAa,EAAE,EAAE;IACtC,OAAO,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAO,IAAmB,EAAE,EAAE;QAC1F,IAAA,eAAQ,GAAE,CAAC;QACX,IAAI,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO;SAAE;QAC1B,MAAM,IAAI,GAAQ,IAAI,CAAC;QACvB,IAAI,OAAO,GAAG,IAAA,eAAQ,EAAC,IAAW,CAAa,CAAC;QAEhD,IAAI,CAAC,OAAO,EAAE;YACV,OAAO;SACV;QACD,OAAO,CAAC,KAAK,IAAI,UAAM,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QACnD,IAAI,IAAI,GAAG,IAAA,eAAK,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAEhC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YACZ,UAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAClC,OAAO;SACV;QAED,MAAM,SAAS,GAAG,IAAA,oBAAQ,GAAE,CAAA;QAE5B,IAAI,IAAI,CAAC,IAAI,IAAI,MAAM,EAAE;YACrB,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,mBAAmB,EAAC,iBAAiB,CAAC,CAAC;YAC5E,UAAM,CAAC,IAAI,CAAC,OAAO,EAAC,KAAK,CAAC,CAAA;SAC7B;QAED,OAAO;IAEX,CAAC,CAAA,CAAC,CAAC;AACP,CAAC,CAAC;AA5BW,QAAA,QAAQ,YA4BnB"}
\ No newline at end of file
diff --git a/packages/discourse/commands/sync-component.d.ts b/packages/discourse/commands/sync-component.d.ts
new file mode 100644
index 00000000..1d55e593
--- /dev/null
+++ b/packages/discourse/commands/sync-component.d.ts
@@ -0,0 +1,4 @@
+import * as CLI from 'yargs';
+import { IOptionsSyncComponent } from '../types';
+export declare const parse: (argv: any) => IOptionsSyncComponent | boolean;
+export declare const register: (cli: CLI.Argv) => CLI.Argv<{}>;
diff --git a/packages/discourse/commands/sync-component.js b/packages/discourse/commands/sync-component.js
new file mode 100644
index 00000000..55e73f4c
--- /dev/null
+++ b/packages/discourse/commands/sync-component.js
@@ -0,0 +1,124 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.register = exports.parse = void 0;
+const path = require("path");
+const osr_cli_commons_1 = require("@plastichub/osr-cli-commons");
+const fs_1 = require("@plastichub/osr-commons");
+const exists_1 = require("@plastichub/fs/exists");
+const constants_1 = require("../lib/discourse/constants");
+const _cli_1 = require("../_cli");
+const index_1 = require("../index");
+const component_1 = require("../lib/sync/component");
+const osr_fs_utils_1 = require("@plastichub/osr-fs-utils");
+const globBase = require('glob-base');
+const parse = (argv) => {
+ let ret = {
+ ...argv
+ };
+ let srcInfo;
+ let variables = {};
+ ret.src = argv.src;
+ ret.source = (0, fs_1.resolve)((0, osr_cli_commons_1.forward_slash)(ret.source), ret.alt, variables);
+ ret.root = (0, fs_1.resolve)((0, osr_cli_commons_1.forward_slash)(ret.root), ret.alt, variables);
+ ret.product_root = (0, fs_1.resolve)((0, osr_cli_commons_1.forward_slash)(ret.product_root), ret.alt, variables);
+ if (ret.src) {
+ ret.src = (0, fs_1.resolve)(ret.src, ret.alt, variables);
+ // in case a file with a glob pattern is provided, strip the glob
+ // this is a special case, enabling shared scripts in Alt-Tap Salamand
+ const glob_base = globBase(ret.src);
+ const file = ret.src.replace(glob_base.glob, '').replace(/\/$/, '');
+ // case : single file
+ if ((0, exists_1.sync)(file) && (0, fs_1.isFile)(file)) {
+ ret.src = file;
+ }
+ const src = (0, fs_1.resolve)((0, osr_cli_commons_1.forward_slash)(ret.src), ret.alt, variables);
+ srcInfo = (0, osr_cli_commons_1.pathInfo)(src);
+ // case : glob pattern
+ if (srcInfo && srcInfo.FILES && srcInfo.FILES.length) {
+ ret.srcInfo = srcInfo;
+ for (const key in srcInfo) {
+ if (Object.prototype.hasOwnProperty.call(srcInfo, key)) {
+ variables['SRC_' + key] = srcInfo[key];
+ }
+ }
+ }
+ else {
+ ret.src = (0, fs_1.resolve)(ret.src, ret.alt, variables);
+ }
+ }
+ if (argv.cwd) {
+ ret.cwd = path.resolve(argv.cwd);
+ if (!(0, exists_1.sync)((ret.cwd))) {
+ index_1.logger.error(`Invalid working directory ${argv.cwd}`);
+ }
+ }
+ else {
+ ret.cwd = process.cwd();
+ }
+ ret = {
+ ...ret,
+ variables,
+ srcInfo
+ };
+ return ret;
+};
+exports.parse = parse;
+const defaultOptions = (yargs) => {
+ return yargs
+ //standard options
+ .option('alt', { type: 'boolean', default: false, describe: 'alt token (%)' })
+ //discourse
+ .option('yaml', { type: 'boolean', default: false, describe: 'Parse options from YAML header' })
+ .option('skip', { type: 'boolean', default: true, describe: 'Skip existing' })
+ .option('uploadLocal', { type: 'boolean', default: true, describe: 'Upload local images to Discourse' })
+ .option('uploadRemote', { type: 'boolean', default: true, describe: 'Upload remote images to Discourse' })
+ .option('title', { type: 'string', default: 'Title of the Discourse post' })
+ .option('cat', { default: constants_1.CAT_TEST, type: 'number' })
+ .option('timestamp', { type: 'number', default: Date.now() })
+ .option('owner', { type: 'number', default: constants_1.DEFAULT_IMPORT_OWNER })
+ .option('config', { type: 'string', default: 'discourse_admin' })
+ //osrl
+ .option('src', {
+ default: '${OSR_ROOT}/osr-machines/injection/**/config.json',
+ type: 'string',
+ describe: 'Source : Path|Glob. Supported: HTML|MD|OSR(Options via YAML header)'
+ })
+ .option('src2', {
+ default: '${OSR_ROOT}/osr-machines/sheetpress/cassandra-light/config.json',
+ type: 'string',
+ describe: 'Source : Path|Glob. Supported: HTML|MD|OSR(Options via YAML header)'
+ })
+ .option('env', { type: 'string', default: 'forum' })
+ .option('profile', { type: 'string', default: "${OSR_ROOT}/osr-templates/discourse/base.json" })
+ .option('format', { type: 'string', default: 'md' })
+ .option('source', { type: 'string', default: "${OSR_ROOT}/osr-templates/discourse/root.html" })
+ .option('language', { type: 'string', default: 'osr' })
+ .option('plugins', { type: 'string', default: '${root}/osr/plugins' })
+ .option('root', { type: 'string', default: process.cwd() })
+ .option('product_root', { type: 'string', default: '${PRODUCT_ROOT}/products' })
+ .option('cwd', { type: 'string', default: process.cwd() })
+ .option('module', { type: 'string', default: 'osr-lib-components' })
+ .option('filter', { type: 'string', default: osr_fs_utils_1.PFilterValid.library_component })
+ .option('cache', { type: 'boolean', default: true })
+ .option('env_key', { type: 'string', default: 'OSR-CONFIG', describe: 'Environment key to the config path.' });
+};
+let options = (yargs) => defaultOptions(yargs);
+const register = (cli) => {
+ return cli.command('sync-component', 'Sync OSR Component', options, async (argv) => {
+ (0, _cli_1.defaults)();
+ if (argv.help) {
+ return;
+ }
+ let options = (0, exports.parse)(argv);
+ if (!options) {
+ return;
+ }
+ index_1.logger.setSettings({ minLevel: argv.logLevel });
+ // options.debug && logger.debug(`CLI Args In`, argv)
+ index_1.logger.debug('Options', options);
+ let ret = (0, component_1.syncComponent)(options);
+ return ret;
+ });
+};
+exports.register = register;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY29tbWFuZHMvc3luYy1jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkJBQTRCO0FBRzVCLGlFQUFxRTtBQUNyRSx1REFBZ0U7QUFFaEUsa0RBQXNEO0FBRXRELDBEQUEyRTtBQUUzRSxrQ0FBa0M7QUFFbEMsb0NBQWlDO0FBQ2pDLHFEQUFxRDtBQUNyRCwyREFBdUQ7QUFDdkQsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFBO0FBRTlCLE1BQU0sS0FBSyxHQUFHLENBQUMsSUFBUyxFQUFtQyxFQUFFO0lBRWhFLElBQUksR0FBRyxHQUFRO1FBQ1gsR0FBRyxJQUFJO0tBQ1YsQ0FBQTtJQUVELElBQUksT0FBTyxDQUFBO0lBQ1gsSUFBSSxTQUFTLEdBQUcsRUFBRSxDQUFBO0lBRWxCLEdBQUcsQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQTtJQUVsQixHQUFHLENBQUMsTUFBTSxHQUFHLElBQUEsWUFBTyxFQUFDLElBQUEsK0JBQWEsRUFBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQTtJQUNuRSxHQUFHLENBQUMsSUFBSSxHQUFHLElBQUEsWUFBTyxFQUFDLElBQUEsK0JBQWEsRUFBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQTtJQUMvRCxHQUFHLENBQUMsWUFBWSxHQUFHLElBQUEsWUFBTyxFQUFDLElBQUEsK0JBQWEsRUFBQyxHQUFHLENBQUMsWUFBWSxDQUFDLEVBQUUsR0FBRyxDQUFDLEdBQUcsRUFBRSxTQUFTLENBQUMsQ0FBQTtJQUUvRSxJQUFJLEdBQUcsQ0FBQyxHQUFHLEVBQUU7UUFFVCxHQUFHLENBQUMsR0FBRyxHQUFHLElBQUEsWUFBTyxFQUFDLEdB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
\ No newline at end of file
diff --git a/packages/discourse/commands/sync-file.d.ts b/packages/discourse/commands/sync-file.d.ts
new file mode 100644
index 00000000..443f33e5
--- /dev/null
+++ b/packages/discourse/commands/sync-file.d.ts
@@ -0,0 +1,2 @@
+import * as CLI from 'yargs';
+export declare const register: (cli: CLI.Argv) => CLI.Argv<{}>;
diff --git a/packages/discourse/commands/sync-file.js b/packages/discourse/commands/sync-file.js
new file mode 100644
index 00000000..e0a797ab
--- /dev/null
+++ b/packages/discourse/commands/sync-file.js
@@ -0,0 +1,55 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.register = void 0;
+const _cli_1 = require("../_cli");
+const index_1 = require("../index");
+const file_1 = require("../lib/sync/file");
+const constants_1 = require("../lib/discourse/constants");
+const defaultOptions = (yargs) => {
+ return yargs
+ .option('debug', { type: 'boolean', default: true, describe: 'debug messages' })
+ .option('verbose', { type: 'boolean', default: true, describe: 'even more debug messages' })
+ .option('yaml', { type: 'boolean', default: true, describe: 'Parse options from YAML header' })
+ .option('alt', { type: 'boolean', default: false, describe: 'alt token (%)' })
+ .option('uploadLocal', { type: 'boolean', default: true, describe: 'Upload local images to Discourse' })
+ .option('uploadRemote', { type: 'boolean', default: true, describe: 'Upload remote images to Discourse' })
+ .option('src', {
+ default: './tests/**/*.md',
+ type: 'string',
+ describe: 'Source : Path|Glob. Supported: HTML|MD|OSR(Options via YAML header)'
+ })
+ .option('title', { type: 'string', default: 'Title of the Discourse post' })
+ .option('config', { type: 'string', default: 'osr_admin' })
+ .option('cat', { default: constants_1.CAT_TEST, type: 'number' })
+ .option('timestamp', { type: 'number', default: Date.now() })
+ .option('owner', { type: 'number', default: constants_1.DEFAULT_IMPORT_OWNER })
+ .option('config', { type: 'string', default: 'discourse_admin' })
+ .option('env', { type: 'string', default: 'test-import' })
+ .option('profile', { type: 'string', default: "${OSR_ROOT}/osr-profiles/osr/base.json" })
+ .option('format', { type: 'string', default: 'html' })
+ .option('root', { type: 'string', default: process.cwd() })
+ .option('cwd', { type: 'string', default: process.cwd() })
+ .option('cache', { type: 'boolean', default: true })
+ .option('env_key', { type: 'string', default: 'OSR-CONFIG', describe: 'Environment key to the config path.' });
+};
+let options = (yargs) => defaultOptions(yargs);
+const register = (cli) => {
+ return cli.command('sync ', 'Sync file', options, async (argv) => {
+ (0, _cli_1.defaults)();
+ if (argv.help) {
+ return;
+ }
+ let options = (0, _cli_1.sanitize)(argv);
+ if (!options) {
+ return;
+ }
+ options.debug && index_1.logger.debug(`CLI Args In`, argv);
+ if (!options.verb) {
+ index_1.logger.error('No verb specified');
+ return;
+ }
+ return (0, file_1.syncYAML)(options);
+ });
+};
+exports.register = register;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1maWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2NvbW1hbmRzL3N5bmMtZmlsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxrQ0FBNEM7QUFFNUMsb0NBQWlDO0FBU2pDLDJDQUEyQztBQUMzQywwREFBMkU7QUFFM0UsTUFBTSxjQUFjLEdBQUcsQ0FBQyxLQUFlLEVBQUUsRUFBRTtJQUN2QyxPQUFPLEtBQUs7U0FDUCxNQUFNLENBQUMsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDO1NBQy9FLE1BQU0sQ0FBQyxTQUFTLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLDBCQUEwQixFQUFFLENBQUM7U0FDM0YsTUFBTSxDQUFDLE1BQU0sRUFBRSxFQUFJLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsZ0NBQWdDLEVBQUMsQ0FBQztTQUMvRixNQUFNLENBQUMsS0FBSyxFQUFFLEVBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxlQUFlLEVBQUMsQ0FBQztTQUMzRSxNQUFNLENBQUMsYUFBYSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxrQ0FBa0MsRUFBQyxDQUFDO1NBQ3RHLE1BQU0sQ0FBQyxjQUFjLEVBQUUsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLG1DQUFtQyxFQUFDLENBQUM7U0FDeEcsTUFBTSxDQUFDLEtBQUssRUFBRTtRQUNYLE9BQU8sRUFBRSxpQkFBaUI7UUFDMUIsSUFBSSxFQUFFLFFBQVE7UUFDZCxRQUFRLEVBQUUscUVB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
\ No newline at end of file
diff --git a/packages/discourse/config/machines.js b/packages/discourse/config/machines.js
new file mode 100644
index 00000000..e69de29b
diff --git a/packages/discourse/constants.d.ts b/packages/discourse/constants.d.ts
new file mode 100644
index 00000000..ca2c1318
--- /dev/null
+++ b/packages/discourse/constants.d.ts
@@ -0,0 +1 @@
+export declare const MODULE_NAME = "OSR-DISCOURSE";
diff --git a/packages/discourse/constants.js b/packages/discourse/constants.js
new file mode 100644
index 00000000..652da578
--- /dev/null
+++ b/packages/discourse/constants.js
@@ -0,0 +1,5 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MODULE_NAME = void 0;
+exports.MODULE_NAME = `OSR-DISCOURSE`;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3JjL2NvbnN0YW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBYSxRQUFBLFdBQVcsR0FBRyxlQUFlLENBQUEifQ==
\ No newline at end of file
diff --git a/packages/discourse/constants.js.map b/packages/discourse/constants.js.map
new file mode 100644
index 00000000..8bb5513a
--- /dev/null
+++ b/packages/discourse/constants.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"constants.js","sourceRoot":"","sources":["src/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,WAAW,GAAG,eAAe,CAAA"}
\ No newline at end of file
diff --git a/packages/discourse/discourse-sync.json b/packages/discourse/discourse-sync.json
new file mode 100644
index 00000000..7cf74cab
--- /dev/null
+++ b/packages/discourse/discourse-sync.json
@@ -0,0 +1,34 @@
+{
+ "./tests/image.jpg": {
+ "id": 9561,
+ "url": "https://forum.osr-plastic.org/uploads/default/original/2X/e/e501e5aa77623b161069805f5e84a4dcd5e9632a.jpeg",
+ "original_filename": "image.jpg",
+ "filesize": 130249,
+ "width": 828,
+ "height": 1472,
+ "thumbnail_width": 281,
+ "thumbnail_height": 500,
+ "extension": "jpeg",
+ "short_url": "upload://wFTp838ZYs2IcwTpTMT9g566ijU.jpeg",
+ "short_path": "/uploads/short-url/wFTp838ZYs2IcwTpTMT9g566ijU.jpeg",
+ "retain_hours": null,
+ "human_filesize": "127 KB",
+ "dominant_color": "4C4D4E"
+ },
+ "https://osr-plastic.org/machines/injection/components/304_Valve-40mm/renderings/webp/perspective.webp": {
+ "id": 9562,
+ "url": "https://forum.osr-plastic.org/uploads/default/original/2X/0/020b78cdced1bf3095da4ababa8347e2334f26dd.webp",
+ "original_filename": "perspective.webp",
+ "filesize": 14366,
+ "width": 1080,
+ "height": 864,
+ "thumbnail_width": 625,
+ "thumbnail_height": 500,
+ "extension": "webp",
+ "short_url": "upload://i5x4cSq74UrBXgc4Kw66mIf7rL.webp",
+ "short_path": "/uploads/short-url/i5x4cSq74UrBXgc4Kw66mIf7rL.webp",
+ "retain_hours": null,
+ "human_filesize": "14 KB",
+ "dominant_color": "E7E4E2"
+ }
+}
\ No newline at end of file
diff --git a/packages/discourse/docs/data.md b/packages/discourse/docs/data.md
new file mode 100644
index 00000000..4343dffd
--- /dev/null
+++ b/packages/discourse/docs/data.md
@@ -0,0 +1,22 @@
+### OA - Users
+
+cli::import-oa-users import|update
+
+src -> export const osr-commons/OA_LATEST = '${OSR_ROOT}/osr-directory/pp/${YYYY}_${MM}.json'
+
+ -> write (${OSR_ROOT}/${OSR_ROOT}/osr-directory/pp/invalidUsers.json)
+ -> write (${OSR_ROOT}/${OSR_ROOT}/osr-directory/pp/invalidUsersEMail.json)
+ -> merge to '${OSR_ROOT}/${OSR_ROOT}/osr-directory/pp/merged.json'
+
+### Discourse Directory Layout
+
+- Intro Page
+ - Continent (cat, +tags)
+ - country page (+tags, +lang)
+ - item (+tags, +lang)
+
+- External feeds
+ - social
+ - products
+ - osr content
+ - news
diff --git a/packages/discourse/index.d.ts b/packages/discourse/index.d.ts
new file mode 100644
index 00000000..4cc5bf88
--- /dev/null
+++ b/packages/discourse/index.d.ts
@@ -0,0 +1,9 @@
+export * from './constants';
+export * from './types';
+export * from './lib';
+export * from './lib/oa/types';
+import { Logger } from "tslog";
+export { Logger } from 'tslog';
+export declare const logger: Logger;
+import { IObjectLiteral } from "@plastichub/core";
+export declare const substitute: (alt: boolean, template: string, vars?: IObjectLiteral) => any;
diff --git a/packages/discourse/index.js b/packages/discourse/index.js
new file mode 100644
index 00000000..29638d69
--- /dev/null
+++ b/packages/discourse/index.js
@@ -0,0 +1,89 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.substitute = exports.logger = exports.Logger = void 0;
+__exportStar(require("./constants"), exports);
+__exportStar(require("./types"), exports);
+__exportStar(require("./lib"), exports);
+__exportStar(require("./lib/oa/types"), exports);
+const debug_1 = require("@plastichub/core/debug");
+const constants_1 = require("./constants");
+var tslog_1 = require("tslog");
+Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return tslog_1.Logger; } });
+let loggers = {};
+/*
+const _logger = new Logger({
+ prettyLogTemplate: "{{yyyy}}.{{mm}}.{{dd}} {{hh}}:{{MM}}:{{ss}}:{{ms}}\t{{logLevelName}}\t[{{filePathWithLine}}{{name}}]\t",
+ prettyErrorTemplate: "\n{{errorName}} {{errorMessage}}\nerror stack:\n{{errorStack}}",
+ prettyErrorStackTemplate: " • {{fileName}}\t{{method}}\n\t{{filePathWithLine}}",
+ prettyErrorParentNamesSeparator: ":",
+ prettyErrorLoggerNameDelimiter: "\t",
+ stylePrettyLogs: true,
+ prettyLogTimeZone: "UTC",
+ prettyLogStyles: {
+ logLevelName: {
+ "*": ["bold", "black", "bgWhiteBright", "dim"],
+ SILLY: ["bold", "white"],
+ TRACE: ["bold", "whiteBright"],
+ DEBUG: ["bold", "green"],
+ INFO: ["bold", "blue"],
+ WARN: ["bold", "yellow"],
+ ERROR: ["bold", "red"],
+ FATAL: ["bold", "redBright"],
+ },
+ dateIsoStr: "white",
+ filePathWithLine: "white",
+ name: ["white", "bold"],
+ nameWithDelimiterPrefix: ["white", "bold"],
+ nameWithDelimiterSuffix: ["white", "bold"],
+ errorName: ["bold", "bgRedBright", "whiteBright"],
+ fileName: ["yellow"],
+ fileNameWithLine: "white",
+ },
+ });
+ */
+/*
+export const __logger = (name: string = MODULE_NAME, options: ISettingsParam = {}): Logger => {
+ if (!loggers[name]) {
+ const logger: Logger = new Logger({
+ name: name,
+ type: 'pretty',
+ ...options
+ });
+ // const trans = (transportLogger: LogObj & ILogObjMet)
+ (logger as any).attachTransport((logObj) => {
+ debugger
+ //transports.push(logObj);
+ });
+
+ logger.debug('test')
+
+ loggers[name] = logger;
+ }
+ return loggers[name]
+}*/
+exports.logger = (0, debug_1.logger)(constants_1.MODULE_NAME);
+/*
+export const log = (msg: string, ...args: any) => logger().info(msg, ...args);
+export const info = (msg: string, ...args: any) => logger().info(msg, ...args);
+export const error = (msg: string, ...args: any) => logger().error(msg, ...args);
+export const warn = (msg: string, ...args: any) => logger().warn(msg, ...args);
+export const debug = (msg: string, ...args: any) => logger().debug(msg, ...args);
+*/
+const strings_1 = require("@plastichub/core/strings");
+const substitute = (alt, template, vars = {}) => alt ? (0, strings_1.substituteAlt)(template, vars) : (0, strings_1.substitute)(template, vars);
+exports.substitute = substitute;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw4Q0FBMkI7QUFDM0IsMENBQXVCO0FBQ3ZCLHdDQUFxQjtBQUNyQixpREFBOEI7QUFFOUIsa0RBQTBEO0FBRTFELDJDQUF5QztBQUV6QywrQkFBOEI7QUFBckIsK0ZBQUEsTUFBTSxPQUFBO0FBRWYsSUFBSSxPQUFPLEdBQUcsRUFBRSxDQUFDO0FBRWpCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7SUE4Qkk7QUFDSjs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUdVLFFBQUEsTUFBTSxHQUFHLElBQUEsY0FBTyxFQUFDLHVCQUFXLENBQUMsQ0FBQTtBQUUxQzs7Ozs7O0VBTUU7QUFHRixzREFBcUc7QUFJOUYsTUFBTSxVQUFVLEdBQUcsQ0FBQyxHQUFZLEVBQUUsUUFBZ0IsRUFBRSxPQUF1QixFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBQSx1QkFBYyxFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBQSxvQkFBVyxFQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQTtBQUE5SSxRQUFBLFVBQVUsY0FBb0kifQ==
\ No newline at end of file
diff --git a/packages/discourse/index.js.map b/packages/discourse/index.js.map
new file mode 100644
index 00000000..25190a41
--- /dev/null
+++ b/packages/discourse/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,8CAA2B;AAC3B,0CAAuB;AAEvB,kDAA0D;AAE1D,2CAAyC;AAI5B,QAAA,MAAM,GAAG,IAAA,cAAO,EAAC,uBAAW,CAAC,CAAA;AAE1C,2CAAgH;AAEzG,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,QAAe,EAAE,IAAmB,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAA,oBAAc,EAAC,QAAQ,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,iBAAW,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;AAArI,QAAA,UAAU,cAA2H"}
\ No newline at end of file
diff --git a/packages/discourse/index.md b/packages/discourse/index.md
new file mode 100644
index 00000000..751fdea7
--- /dev/null
+++ b/packages/discourse/index.md
@@ -0,0 +1,146 @@
+## Directory Index
+
+**Hidden / Censored Users** :
+
+**Total** :
+
+## Africa
+ - [Algeria (6)](/directory/users_algeria-af)
+- [Botswana (1)](/directory/users_botswana-af)
+- [Burkina Faso (2)](/directory/users_burkina-faso-af)
+- [Cabo Verde (1)](/directory/users_cabo-verde-af)
+- [Cameroon (2)](/directory/users_cameroon-af)
+- [Congo (3)](/directory/users_congo-(the-democratic-republic-of-the)-af)
+- [Egypt (7)](/directory/users_egypt-af)
+- [Eswatini (1)](/directory/users_eswatini-af)
+- [Ethiopia (2)](/directory/users_ethiopia-af)
+- [Ghana (5)](/directory/users_ghana-af)
+- [Kenya (14)](/directory/users_kenya-af)
+- [Libya (1)](/directory/users_libya-af)
+- [Madagascar (2)](/directory/users_madagascar-af)
+- [Mali (2)](/directory/users_mali-af)
+- [Mauritius (2)](/directory/users_mauritius-af)
+- [Morocco (2)](/directory/users_morocco-af)
+- [Namibia (3)](/directory/users_namibia-af)
+- [Nigeria (7)](/directory/users_nigeria-af)
+- [Reunion (1)](/directory/users_reunion-af)
+- [Senegal (1)](/directory/users_senegal-af)
+- [Somalia (1)](/directory/users_somalia-af)
+- [South Africa (16)](/directory/users_south-africa-af)
+- [Spain (58)](/directory/users_spain-af)
+- [Tanzania, the United Republic of (6)](/directory/users_tanzania-the-united-republic-of-af)
+- [Tunisia (3)](/directory/users_tunisia-af)
+- [Uganda (1)](/directory/users_uganda-af)
+- [Zambia (2)](/directory/users_zambia-af)
+## Asia
+ - [Armenia (1)](/directory/users_armenia-as)
+- [Azerbaijan (2)](/directory/users_azerbaijan-as)
+- [Bangladesh (6)](/directory/users_bangladesh-as)
+- [Cambodia (2)](/directory/users_cambodia-as)
+- [China (3)](/directory/users_china-as)
+- [Christmas Island (1)](/directory/users_christmas-island-as)
+- [Cyprus (3)](/directory/users_cyprus-as)
+- [Georgia (3)](/directory/users_georgia-as)
+- [Hong Kong (7)](/directory/users_hong-kong-as)
+- [India (42)](/directory/users_india-as)
+- [Indonesia (57)](/directory/users_indonesia-as)
+- [Iran (1)](/directory/users_iran-(islamic-republic-of)-as)
+- [Iraq (2)](/directory/users_iraq-as)
+- [Israel (1)](/directory/users_israel-as)
+- [Japan (16)](/directory/users_japan-as)
+- [Jordan (4)](/directory/users_jordan-as)
+- [Kazakhstan (1)](/directory/users_kazakhstan-as)
+- [Korea (16)](/directory/users_korea-(the-republic-of)-as)
+- [Kyrgyzstan (1)](/directory/users_kyrgyzstan-as)
+- [Lao People's Democratic Republic (1)](/directory/users_lao-people's-democratic-republic-(the)-as)
+- [Lebanon (2)](/directory/users_lebanon-as)
+- [Malaysia (13)](/directory/users_malaysia-as)
+- [Mongolia (2)](/directory/users_mongolia-as)
+- [Myanmar (1)](/directory/users_myanmar-as)
+- [Pakistan (1)](/directory/users_pakistan-as)
+- [Philippines (5)](/directory/users_philippines-(the)-as)
+- [Russian Federation (31)](/directory/users_russian-federation-(the)-as)
+- [Saudi Arabia (3)](/directory/users_saudi-arabia-as)
+- [Singapore (4)](/directory/users_singapore-as)
+- [Sri Lanka (1)](/directory/users_sri-lanka-as)
+- [Taiwan (2)](/directory/users_taiwan-(province-of-china)-as)
+- [Thailand (12)](/directory/users_thailand-as)
+- [Timor-Leste (2)](/directory/users_timor-leste-as)
+- [Turkiye (16)](/directory/users_turkiye-as)
+- [United Arab Emirates (3)](/directory/users_united-arab-emirates-(the)-as)
+- [Uzbekistan (2)](/directory/users_uzbekistan-as)
+- [Viet Nam (12)](/directory/users_viet-nam-as)
+## Australian continent
+ - [Australia (53)](/directory/users_australia-au)
+## Europe
+ - [Albania (2)](/directory/users_albania-eu)
+- [Austria (6)](/directory/users_austria-eu)
+- [Belarus (1)](/directory/users_belarus-eu)
+- [Belgium (18)](/directory/users_belgium-eu)
+- [Bosnia and Herzegovina (3)](/directory/users_bosnia-and-herzegovina-eu)
+- [Bulgaria (5)](/directory/users_bulgaria-eu)
+- [Croatia (4)](/directory/users_croatia-eu)
+- [Czechia (7)](/directory/users_czechia-eu)
+- [Denmark (4)](/directory/users_denmark-eu)
+- [Estonia (1)](/directory/users_estonia-eu)
+- [Finland (2)](/directory/users_finland-eu)
+- [France (95)](/directory/users_france-eu)
+- [Germany (66)](/directory/users_germany-eu)
+- [Greece (14)](/directory/users_greece-eu)
+- [Hungary (5)](/directory/users_hungary-eu)
+- [Iceland (1)](/directory/users_iceland-eu)
+- [Ireland (5)](/directory/users_ireland-eu)
+- [Italy (31)](/directory/users_italy-eu)
+- [Latvia (2)](/directory/users_latvia-eu)
+- [Liechtenstein (1)](/directory/users_liechtenstein-eu)
+- [Lithuania (2)](/directory/users_lithuania-eu)
+- [Malta (1)](/directory/users_malta-eu)
+- [Montenegro (1)](/directory/users_montenegro-eu)
+- [Netherlands (37)](/directory/users_netherlands-(the)-eu)
+- [Norway (7)](/directory/users_norway-eu)
+- [Poland (4)](/directory/users_poland-eu)
+- [Portugal (17)](/directory/users_portugal-eu)
+- [Romania (5)](/directory/users_romania-eu)
+- [Russian Federation (31)](/directory/users_russian-federation-(the)-eu)
+- [Serbia (6)](/directory/users_serbia-eu)
+- [Slovakia (6)](/directory/users_slovakia-eu)
+- [Slovenia (1)](/directory/users_slovenia-eu)
+- [Spain (58)](/directory/users_spain-eu)
+- [Sweden (4)](/directory/users_sweden-eu)
+- [Switzerland (15)](/directory/users_switzerland-eu)
+- [Ukraine (16)](/directory/users_ukraine-eu)
+- [United Kingdom of Great Britain and Northern Ireland (65)](/directory/users_united-kingdom-of-great-britain-and-northern-ireland-(the)-eu)
+## North America
+ - [Canada (42)](/directory/users_canada-na)
+- [Costa Rica (6)](/directory/users_costa-rica-na)
+- [Cuba (1)](/directory/users_cuba-na)
+- [Curacao (1)](/directory/users_curacao-na)
+- [Dominican Republic (9)](/directory/users_dominican-republic-(the)-na)
+- [Guatemala (2)](/directory/users_guatemala-na)
+- [Haiti (2)](/directory/users_haiti-na)
+- [Mexico (57)](/directory/users_mexico-na)
+- [Netherlands (37)](/directory/users_netherlands-(the)-na)
+- [Panama (3)](/directory/users_panama-na)
+- [Puerto Rico (3)](/directory/users_puerto-rico-na)
+- [United States of America (167)](/directory/users_united-states-of-america-(the)-na)
+## Oceania
+ - [Fiji (2)](/directory/users_fiji-oc)
+- [Guam (1)](/directory/users_guam-oc)
+- [Micronesia (1)](/directory/users_micronesia-(federated-states-of)-oc)
+- [New Caledonia (1)](/directory/users_new-caledonia-oc)
+- [New Zealand (10)](/directory/users_new-zealand-oc)
+- [United States of America (167)](/directory/users_united-states-of-america-(the)-oc)
+## South America
+ - [Argentina (34)](/directory/users_argentina-sa)
+- [Bolivia (2)](/directory/users_bolivia-(plurinational-state-of)-sa)
+- [Brazil (57)](/directory/users_brazil-sa)
+- [Chile (26)](/directory/users_chile-sa)
+- [Colombia (39)](/directory/users_colombia-sa)
+- [Ecuador (11)](/directory/users_ecuador-sa)
+- [Guyana (1)](/directory/users_guyana-sa)
+- [Paraguay (2)](/directory/users_paraguay-sa)
+- [Peru (9)](/directory/users_peru-sa)
+- [Uruguay (4)](/directory/users_uruguay-sa)
+- [Venezuela (5)](/directory/users_venezuela-(bolivarian-republic-of)-sa)
+
+
diff --git a/packages/discourse/lib/discourse/cache.d.ts b/packages/discourse/lib/discourse/cache.d.ts
new file mode 100644
index 00000000..fe047e18
--- /dev/null
+++ b/packages/discourse/lib/discourse/cache.d.ts
@@ -0,0 +1,10 @@
+///
+import { IDiscourseUser } from '../../';
+import { Discourser } from '../index';
+export declare const fileAsBuffer: (path: string) => Buffer;
+export declare const cacheCategories: (options: any, discourse: Discourser) => Promise;
+export declare const cacheTopics: (options: any, discourse: Discourser) => Promise;
+export declare const _getForumUsers: (d: Discourser, page: any, detail: any) => any;
+export declare const getForumUsers: (d: any, detail: any) => Promise;
+export declare const cacheUsers: (options: any, discourse: Discourser) => Promise;
+export declare const cacheTags: (options: any, discourse: Discourser) => Promise;
diff --git a/packages/discourse/lib/discourse/cache.js b/packages/discourse/lib/discourse/cache.js
new file mode 100644
index 00000000..6238f7d3
--- /dev/null
+++ b/packages/discourse/lib/discourse/cache.js
@@ -0,0 +1,122 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.cacheTags = exports.cacheUsers = exports.getForumUsers = exports._getForumUsers = exports.cacheTopics = exports.cacheCategories = exports.fileAsBuffer = void 0;
+const bluebird_1 = require("bluebird");
+const read_1 = require("@plastichub/fs/read");
+const exists_1 = require("@plastichub/fs/exists");
+const write_1 = require("@plastichub/fs/write");
+const fs_1 = require("@plastichub/osr-commons");
+const constants_1 = require("../discourse/constants");
+const path = require("path");
+const escapeHtml = require('escape-html');
+const pretty = require('pretty');
+const fileAsBuffer = (path) => (0, read_1.sync)(path, 'buffer') || Buffer.from("-");
+exports.fileAsBuffer = fileAsBuffer;
+const lib_1 = require("@plastichub/osr-cache/lib");
+const osr_cli_commons_1 = require("@plastichub/osr-cli-commons");
+const constants_2 = require("../../constants");
+const cacheCategories = async (options, discourse) => {
+ const osr_cache = (0, osr_cli_commons_1.OSR_CACHE)();
+ const cPath = path.resolve((0, fs_1.resolve)(constants_1.DISCOURSE_CATEGORY_CACHE));
+ const cached = (0, exists_1.sync)(cPath) ? await (0, lib_1.get_cached)(cPath, {}, constants_2.MODULE_NAME) : null;
+ if (osr_cache && cached && options.cache !== false) {
+ return JSON.parse(cached);
+ }
+ let cats = await discourse.getCategories({
+ include_subcategories: true
+ });
+ (0, write_1.sync)(cPath, cats);
+ if (osr_cache && options.cache !== false) {
+ await (0, lib_1.set_cached)(cPath, {}, constants_2.MODULE_NAME, cats);
+ }
+ return cats;
+};
+exports.cacheCategories = cacheCategories;
+const cacheTopics = async (options, discourse) => {
+};
+exports.cacheTopics = cacheTopics;
+let uPage = 1;
+let usersAll = [];
+const _getForumUsers = async (d, page, detail) => {
+ const uPath = path.resolve((0, fs_1.resolve)(constants_1.DISCOURSE_USER_CACHE));
+ if (uPage == 1) {
+ usersAll = [];
+ }
+ let users = await d.getUsers(page);
+ if (users.length) {
+ usersAll = usersAll.concat(users);
+ uPage++;
+ return (0, exports._getForumUsers)(d, uPage, detail);
+ }
+ else {
+ uPage = 1;
+ (0, write_1.sync)(uPath, usersAll);
+ let fUsers = (0, read_1.sync)(uPath, 'json') || [];
+ const add = async (u) => {
+ return new Promise((resolve, reject) => {
+ let fUser = fUsers.find((fu) => u.id == fu.id);
+ if (!fUser) {
+ fUsers.push(u);
+ fUser = u;
+ }
+ if (fUser.detail) {
+ console.log('Retrieve User Detail ' + u.name);
+ setTimeout(() => {
+ d.getUser(fUser.id).then((detail) => {
+ if (detail) {
+ fUser.detail = detail;
+ }
+ (0, write_1.sync)(uPath, fUsers);
+ resolve(fUser);
+ });
+ }, 200);
+ }
+ else {
+ resolve(fUser);
+ }
+ });
+ };
+ return await bluebird_1.Promise.resolve(usersAll).map((u) => {
+ return add(u);
+ }, { concurrency: 1 });
+ }
+};
+exports._getForumUsers = _getForumUsers;
+const getForumUsers = async (d, detail) => {
+ return (0, exports._getForumUsers)(d, uPage, detail);
+};
+exports.getForumUsers = getForumUsers;
+const cacheUsers = async (options, discourse) => {
+ const osr_cache = (0, osr_cli_commons_1.OSR_CACHE)();
+ const uPath = path.resolve((0, fs_1.resolve)(constants_1.DISCOURSE_USER_CACHE));
+ const cached = (0, exists_1.sync)(uPath) ? await (0, lib_1.get_cached)(uPath, {}, constants_2.MODULE_NAME) : null;
+ if (osr_cache && options.cache !== false && (0, exists_1.sync)(uPath)) {
+ return (0, read_1.sync)(uPath, 'json');
+ }
+ if (osr_cache && cached && options.cache !== false) {
+ return JSON.parse(cached);
+ }
+ let users = await (0, exports.getForumUsers)(discourse, false);
+ (0, write_1.sync)(uPath, users);
+ if (osr_cache && options.cache !== false) {
+ await (0, lib_1.set_cached)(uPath, {}, constants_2.MODULE_NAME, users);
+ }
+ return users;
+};
+exports.cacheUsers = cacheUsers;
+const cacheTags = async (options, discourse) => {
+ const osr_cache = (0, osr_cli_commons_1.OSR_CACHE)();
+ const tPath = path.resolve((0, fs_1.resolve)(constants_1.DISCOURSE_TAGS_CACHE));
+ const cached = (0, exists_1.sync)(tPath) ? await (0, lib_1.get_cached)(tPath, {}, constants_2.MODULE_NAME) : null;
+ if (osr_cache && cached && options.cache !== false) {
+ return JSON.parse(cached);
+ }
+ let tags = await discourse.getTags();
+ (0, write_1.sync)(tPath, tags);
+ if (osr_cache && options.cache !== false) {
+ await (0, lib_1.set_cached)(tPath, {}, constants_2.MODULE_NAME, tags);
+ }
+ return tags;
+};
+exports.cacheTags = cacheTags;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FjaGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL2Rpc2NvdXJzZS9jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSx1Q0FBOEM7QUFDOUMsOENBQWtEO0FBQ2xELGtEQUFzRDtBQUN0RCxnREFBb0Q7QUFDcEQsdURBQXdEO0FBcUJ4RCxzREFRK0I7QUFLL0IsNkJBQTRCO0FBTzVCLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQTtBQUN6QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUE7QUFFekIsTUFBTSxZQUFZLEdBQUcsQ0FBQyxJQUFZLEVBQUUsRUFBRSxDQUFDLElBQUEsV0FBSSxFQUFDLElBQUksRUFBRSxRQUFRLENBQVcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQW5GLFFBQUEsWUFBWSxnQkFBdUU7QUFFaEcsbURBQWtFO0FBQ2xFLGlFQUF1RDtBQUl2RCwrQ0FFd0I7QUFHakIsTUFBTSxlQUFlLEdBQUcsS0FBSyxFQUFFLE9BQVksRUFBRSxTQUFxQixFQUFFLEVBQUU7SUFFekUsTUFBTSxTQUFTLEdBQUcsSUFBQSwyQkFBUyxHQUFFLENBQUE7SUFFN0IsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFBLFlBQU8sRUFBQyxvQ0FBd0IsQ0FBQyxDQUFDLENBQUE7SUFFN0QsTUFBTSxNQUFNLEdBQUcsSUFBQSxhQUFNLEVBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBQSxnQkFBVSxFQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsdUJBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7SUFFOUUsSUFBSSxTQUFTLElBQUksTUFBTSxJQUFJLE9BQU8sQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFO1FBQ2hELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENB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
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/constants.d.ts b/packages/discourse/lib/discourse/constants.d.ts
new file mode 100644
index 00000000..49a2ce1c
--- /dev/null
+++ b/packages/discourse/lib/discourse/constants.d.ts
@@ -0,0 +1,70 @@
+export type EDiscourseConfigKey = 'discourse' | 'discourse_admin';
+export declare const SYNC_TRACK_FILENAME = "discourse-sync.json";
+export declare const OSR_CACHE_ROOT = "${OSR_CACHE}";
+export declare const OSR_DISCOURSE_CACHE = "${OSR_CACHE}/discourse";
+export declare const DISCOURSE_CATEGORY_CACHE = "${OSR_CACHE}/discourse/cats.json";
+export declare const DISCOURSE_TOPICS_CACHE = "${OSR_CACHE}/discourse/topics.json";
+export declare const DISCOURSE_TAGS_CACHE = "${OSR_CACHE}/discourse/tags.json";
+export declare const DISCOURSE_USER_CACHE = "${OSR_CACHE}/discourse/users.json";
+export declare const OA_DIRECTORY_OVERVIEW_TOPIC = 28873;
+export declare const OA_USER_IMPORT_GROUP = 43;
+export declare const KB_USERS = "${KB_ROOT}/static/users";
+export declare const DATA_PATH = "${OSR_ROOT}/osr-directory/pp";
+export declare const LATEST_TRACK = "${OSR_ROOT}/osr-directory/pp/merged.json";
+export declare const LATEST_TEST = "./latest_test.json";
+export declare const FETCH_DUSERS = false;
+export declare const F_USERS_NOW = "./fusers.json";
+export declare const F_USERS_ALL = "./fusers-all.json";
+export declare const DEFAULT_PASSWORD: () => string;
+export declare const HOWTOS_ASSETS_URL: () => string;
+export declare const MACHINES_ASSETS_URL: () => string;
+export declare const CAT_TEST = 65;
+export declare const TAGS_TEST = "plastic, meta";
+export declare const DEFAULT_IMPORT_OWNER = 1;
+export declare const D_ROOT_CAT = 97;
+export declare const D_ROOT_AFRICA = 79;
+export declare const D_ROOT_ASIA = 60;
+export declare const D_ROOT_EUROPE = 59;
+export declare const D_ROOT_AUSTRALIA = 76;
+export declare const D_ROOT_NAMERICA = 101;
+export declare const D_ROOT_SAMERICA = 102;
+export declare const D_ROOT_OCEANIA = 103;
+export declare const HT_CAT_ROOT = 54;
+export declare const HT_CAT_GUIDES = 86;
+export declare const HT_CAT_MACHINES = 87;
+export declare const HT_CAT_PRODUCTS = 88;
+export declare const HT_CAT_MOULDS = 89;
+export declare const HT_CAT_IDS: {
+ HT_CAT_ROOT: number;
+ HT_CAT_GUIDES: number;
+ HT_CAT_MACHINES: number;
+ HT_CAT_PRODUCTS: number;
+ HT_CAT_MOULDS: number;
+};
+export declare const HT_CATS: {
+ Guides: number;
+ Machines: number;
+ Products: number;
+ Moulds: number;
+};
+export declare const MACHINE_CAT_INJECTION = 50;
+export declare const MACHINE_CAT_EXTRUSION = 51;
+export declare const MACHINE_CAT_SHREDDER = 52;
+export declare const MACHINE_CAT_SHEETPRESS = 63;
+export declare const MACHINE_CAT_3DPRINT = 70;
+export declare const MACHINE_CAT_MOULDS = 71;
+export declare const MACHINE_CAT_IDS: {
+ MACHINE_CAT_INJECTION: number;
+ MACHINE_CAT_EXTRUSION: number;
+ MACHINE_CAT_SHREDDER: number;
+ MACHINE_CAT_SHEETPRESS: number;
+ MACHINE_CAT_3DPRINT: number;
+ MACHINE_CAT_MOULDS: number;
+};
+export declare const MACHINE_CATS: {
+ Injection: number;
+ Extrusion: number;
+ Sheetpress: number;
+ '3DPrint': number;
+ Moulds: number;
+};
diff --git a/packages/discourse/lib/discourse/constants.js b/packages/discourse/lib/discourse/constants.js
new file mode 100644
index 00000000..b6d5f2f0
--- /dev/null
+++ b/packages/discourse/lib/discourse/constants.js
@@ -0,0 +1,100 @@
+"use strict";
+//////////////////////////////////////////////////////////////
+//
+// Keys
+//
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.MACHINE_CATS = exports.MACHINE_CAT_IDS = exports.MACHINE_CAT_MOULDS = exports.MACHINE_CAT_3DPRINT = exports.MACHINE_CAT_SHEETPRESS = exports.MACHINE_CAT_SHREDDER = exports.MACHINE_CAT_EXTRUSION = exports.MACHINE_CAT_INJECTION = exports.HT_CATS = exports.HT_CAT_IDS = exports.HT_CAT_MOULDS = exports.HT_CAT_PRODUCTS = exports.HT_CAT_MACHINES = exports.HT_CAT_GUIDES = exports.HT_CAT_ROOT = exports.D_ROOT_OCEANIA = exports.D_ROOT_SAMERICA = exports.D_ROOT_NAMERICA = exports.D_ROOT_AUSTRALIA = exports.D_ROOT_EUROPE = exports.D_ROOT_ASIA = exports.D_ROOT_AFRICA = exports.D_ROOT_CAT = exports.DEFAULT_IMPORT_OWNER = exports.TAGS_TEST = exports.CAT_TEST = exports.MACHINES_ASSETS_URL = exports.HOWTOS_ASSETS_URL = exports.DEFAULT_PASSWORD = exports.F_USERS_ALL = exports.F_USERS_NOW = exports.FETCH_DUSERS = exports.LATEST_TEST = exports.LATEST_TRACK = exports.DATA_PATH = exports.KB_USERS = exports.OA_USER_IMPORT_GROUP = exports.OA_DIRECTORY_OVERVIEW_TOPIC = exports.DISCOURSE_USER_CACHE = exports.DISCOURSE_TAGS_CACHE = exports.DISCOURSE_TOPICS_CACHE = exports.DISCOURSE_CATEGORY_CACHE = exports.OSR_DISCOURSE_CACHE = exports.OSR_CACHE_ROOT = exports.SYNC_TRACK_FILENAME = void 0;
+//////////////////////////////////////////////////////////////
+//
+// Paths
+//
+exports.SYNC_TRACK_FILENAME = 'discourse-sync.json';
+exports.OSR_CACHE_ROOT = '${OSR_CACHE}';
+exports.OSR_DISCOURSE_CACHE = '${OSR_CACHE}/discourse';
+exports.DISCOURSE_CATEGORY_CACHE = '${OSR_CACHE}/discourse/cats.json';
+exports.DISCOURSE_TOPICS_CACHE = '${OSR_CACHE}/discourse/topics.json';
+exports.DISCOURSE_TAGS_CACHE = '${OSR_CACHE}/discourse/tags.json';
+exports.DISCOURSE_USER_CACHE = '${OSR_CACHE}/discourse/users.json';
+//////////////////////////////////////////////////////////////
+//
+// OA - User Import
+//
+exports.OA_DIRECTORY_OVERVIEW_TOPIC = 28873;
+exports.OA_USER_IMPORT_GROUP = 43;
+exports.KB_USERS = '${KB_ROOT}/static/users';
+exports.DATA_PATH = '${OSR_ROOT}/osr-directory/pp';
+exports.LATEST_TRACK = '${OSR_ROOT}/osr-directory/pp/merged.json';
+exports.LATEST_TEST = './latest_test.json';
+exports.FETCH_DUSERS = false;
+exports.F_USERS_NOW = './fusers.json';
+exports.F_USERS_ALL = './fusers-all.json';
+const DEFAULT_PASSWORD = () => '4g0&KPN$e*Un';
+exports.DEFAULT_PASSWORD = DEFAULT_PASSWORD;
+const HOWTOS_ASSETS_URL = () => `https://kb.osr-plastic.org/howtos/`;
+exports.HOWTOS_ASSETS_URL = HOWTOS_ASSETS_URL;
+const MACHINES_ASSETS_URL = () => `https://assets.osr-plastic.org/machines/`;
+exports.MACHINES_ASSETS_URL = MACHINES_ASSETS_URL;
+exports.CAT_TEST = 65;
+exports.TAGS_TEST = 'plastic, meta';
+exports.DEFAULT_IMPORT_OWNER = 1;
+//////////////////////////////////////////////////////////////
+//
+// OA - Directory Import
+//
+exports.D_ROOT_CAT = 97;
+exports.D_ROOT_AFRICA = 79;
+exports.D_ROOT_ASIA = 60;
+exports.D_ROOT_EUROPE = 59;
+exports.D_ROOT_AUSTRALIA = 76;
+exports.D_ROOT_NAMERICA = 101;
+exports.D_ROOT_SAMERICA = 102;
+exports.D_ROOT_OCEANIA = 103;
+//////////////////////////////////////////////////////////////
+//
+// OA - Howto Import
+//
+exports.HT_CAT_ROOT = 54;
+exports.HT_CAT_GUIDES = 86;
+exports.HT_CAT_MACHINES = 87;
+exports.HT_CAT_PRODUCTS = 88;
+exports.HT_CAT_MOULDS = 89;
+exports.HT_CAT_IDS = {
+ HT_CAT_ROOT: exports.HT_CAT_ROOT,
+ HT_CAT_GUIDES: exports.HT_CAT_GUIDES,
+ HT_CAT_MACHINES: exports.HT_CAT_MACHINES,
+ HT_CAT_PRODUCTS: exports.HT_CAT_PRODUCTS,
+ HT_CAT_MOULDS: exports.HT_CAT_MOULDS
+};
+exports.HT_CATS = {
+ 'Guides': exports.HT_CAT_GUIDES,
+ 'Machines': exports.HT_CAT_MACHINES,
+ 'Products': exports.HT_CAT_PRODUCTS,
+ 'Moulds': exports.HT_CAT_MOULDS
+};
+//////////////////////////////////////////////////////////////
+//
+// OA - Library Import
+//
+exports.MACHINE_CAT_INJECTION = 50;
+exports.MACHINE_CAT_EXTRUSION = 51;
+exports.MACHINE_CAT_SHREDDER = 52;
+exports.MACHINE_CAT_SHEETPRESS = 63;
+exports.MACHINE_CAT_3DPRINT = 70;
+exports.MACHINE_CAT_MOULDS = 71;
+exports.MACHINE_CAT_IDS = {
+ MACHINE_CAT_INJECTION: exports.MACHINE_CAT_INJECTION,
+ MACHINE_CAT_EXTRUSION: exports.MACHINE_CAT_EXTRUSION,
+ MACHINE_CAT_SHREDDER: exports.MACHINE_CAT_SHREDDER,
+ MACHINE_CAT_SHEETPRESS: exports.MACHINE_CAT_SHEETPRESS,
+ MACHINE_CAT_3DPRINT: exports.MACHINE_CAT_3DPRINT,
+ MACHINE_CAT_MOULDS: exports.MACHINE_CAT_MOULDS
+};
+exports.MACHINE_CATS = {
+ 'Injection': exports.MACHINE_CAT_INJECTION,
+ 'Extrusion': exports.MACHINE_CAT_EXTRUSION,
+ 'Sheetpress': exports.MACHINE_CAT_SHEETPRESS,
+ '3DPrint': exports.MACHINE_CAT_3DPRINT,
+ 'Moulds': exports.HT_CAT_MOULDS
+};
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9kaXNjb3Vyc2UvY29uc3RhbnRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFDQSw4REFBOEQ7QUFDOUQsRUFBRTtBQUNGLFFBQVE7QUFDUixFQUFFOzs7QUFJRiw4REFBOEQ7QUFDOUQsRUFBRTtBQUNGLFNBQVM7QUFDVCxFQUFFO0FBRVcsUUFBQSxtQkFBbUIsR0FBRyxxQkFBcUIsQ0FBQTtBQUUzQyxRQUFBLGNBQWMsR0FBRyxjQUFjLENBQUE7QUFDL0IsUUFBQSxtQkFBbUIsR0FBRyx3QkFBd0IsQ0FBQTtBQUU5QyxRQUFBLHdCQUF3QixHQUFHLGtDQUFrQyxDQUFBO0FBQzdELFFBQUEsc0JBQXNCLEdBQUcsb0NBQW9DLENBQUE7QUFDN0QsUUFBQSxvQkFBb0IsR0FBRyxrQ0FBa0MsQ0FBQTtBQUN6RCxRQUFBLG9CQUFvQixHQUFHLG1DQUFtQyxDQUFBO0FBRXZFLDhEQUE4RDtBQUM5RCxFQUFFO0FBQ0Ysb0JBQW9CO0FBQ3BCLEVBQUU7QUFFVyxRQUFBLDJCQUEyQixHQUFHLEtBQUssQ0FBQTtBQUNuQyxRQUFBLG9CQUFvQixHQUFHLEVBQUUsQ0FBQTtBQUN6QixRQUFBLFFBQVEsR0FBRyx5QkFBeUIsQ0FBQTtBQUNwQyxRQUFBLFNBQVMsR0FBRyw4QkFBOEIsQ0FBQTtBQUUxQyxRQUFBLFlBQVksR0FBRywwQ0FBMEMsQ0FBQTtBQUN6RCxRQUFBLFdBQVcsR0FBRyxvQkFBb0IsQ0FBQTtBQUNsQyxRQUFBLFlBQVksR0FBRyxLQUFLLENBQUE7QUFDcEIsUUFBQSxXQUFXLEdBQUcsZUFBZSxDQUFBO0FBQzdCLFFBQUEsV0FBVyxHQUFHLG1CQUFtQixDQUFBO0FBRXZDLE1BQU0sZ0JBQWdCLEdBQUcsR0FBRyxFQUFFLENBQUMsY0FBYyxDQUFBO0FBQXZDLFFBQUEsZ0JBQWdCLG9CQUF1QjtBQUU3QyxNQUFNLGlCQUFpQixHQUFHLEdBQUcsRUFBRSxD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
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/index.d.ts b/packages/discourse/lib/discourse/index.d.ts
new file mode 100644
index 00000000..a67155dd
--- /dev/null
+++ b/packages/discourse/lib/discourse/index.d.ts
@@ -0,0 +1,181 @@
+export declare const logger: any;
+import PromisePool from 'native-promise-pool';
+export declare const escape: (path: string) => string;
+import { TPostStatus, TPostStatusUpdate, UserPreferencesUpdate } from './types';
+import { Category, CategoriesResponse, PostsResponse, PostResponse, TopicResponse, TopicItem, CategoryResponse, PostItem, PostUpdateItem, IDiscourserConfig, Thread, PostModifier, FetchConfig, FetchOptions, ISearchResult, ICreateUserResponse, IUserDetail, TagsResponse, Tag, TopicUpdateBasicTopic } from './types';
+import { IDiscourseUser } from '@plastichub/osr-commons';
+import { EDiscourseConfigKey } from './constants';
+import { IDImage } from '../oa/index';
+/**
+ * Discourser is an API Client for the [Discourse API](https://docs.discourse.org)
+ * It special features are:
+ * - TypeScript Types
+ * - Respecting Rate Limits
+ * - Optional Heavy Caching
+ * - Post Modifiers (can be used for global find and replace across all posts on the forum)
+ */
+export declare class Discourser {
+ readonly host: string;
+ readonly key: string;
+ readonly username: string;
+ readonly cache?: string;
+ readonly useCache?: boolean;
+ readonly dry: boolean;
+ readonly pool: PromisePool;
+ /**
+ * Construct our Discourser instance
+ * See {@link IDiscourserConfig} for available configuration.
+ */
+ constructor(config: IDiscourserConfig);
+ /** Get the URL of a topic */
+ getTopicURL(topic: TopicItem | TopicResponse | number): string;
+ /** Fetch a discourse API URL, with rate limit concurrency and optional caching */
+ fetch({ url, useCache, request }: FetchConfig): Promise;
+ /** Fetch a discourse API URL, with rate limit retries */
+ private _post;
+ /** Fetch a discourse API URL, with rate limit retries */
+ private _fetch;
+ /**
+ * API Helper for {@link .search}
+ * https://docs.discourse.org/#tag/Search/operation/search
+ */
+ search(query: string, params?: string, opts?: FetchOptions): Promise;
+ /**
+ * API Helper for {@link .getTags}
+ */
+ protected getTagsResponse(opts?: FetchOptions): Promise;
+ /**
+ * Fetch the whole information, for all categories of the forum
+ */
+ getTags(opts?: FetchOptions): Promise;
+ createTag(name: any): Promise;
+ /**
+ * API Helper for {@link .getCategories}
+ */
+ protected getCategoriesResponse(opts?: FetchOptions): Promise;
+ /**
+ * Fetch the whole information, for all categories of the forum
+ */
+ getCategories(opts?: FetchOptions): Promise;
+ /**
+ * API Helper for {@link .getTopicItemsOfCategory}
+ * Discourse does not provide an API for fetching category information for a specific category.
+ * Instead, all that it provides is a way of getting the topics for a specific category.
+ */
+ protected getCategoryResponse(categoryID: number, opts?: FetchOptions): Promise;
+ /**
+ * Fetch the partial information, for all topics of a specific category
+ */
+ getTopicItemsOfCategory(categoryID: number, opts?: FetchOptions): Promise;
+ /**
+ * Fetch the partial information, for all topics of specific categoires
+ */
+ getTopicItemsOfCategories(categoryIDs: number[], opts?: FetchOptions): Promise;
+ /**
+ * Fetch the partial information, for all topics of the forum
+ */
+ getTopicItems(opts?: FetchOptions): Promise;
+ /**
+ * Fetch the whole information, for a specific topic of the forum
+ */
+ getTopic(id: number, opts?: FetchOptions): Promise;
+ /**
+ * Fetch the whole information, for all topics, or specific topics, of the forum
+ */
+ getTopics(topicIDs?: number[] | null, opts?: FetchOptions): Promise;
+ updateTopicVisibility(topicID: number, listed?: boolean, visible?: TPostStatus): Promise;
+ updateTopicTimestamp(topicID: number, timestamp: Date | string | number, token: string): Promise;
+ /**
+ * API Helper for {@link .getPostItemsOfTopic}
+ */
+ protected getPostItemsOfTopicResponse(topicID: number, opts?: FetchOptions): Promise;
+ _createUser(name: any, email: any, pUserGroup: any): Promise;
+ getUsers(page: any): Promise;
+ getUser(id: any): Promise;
+ /**
+ * Fetch the partial information, for all posts of a specific topic
+ */
+ getPostItemsOfTopic(topicID: number, opts?: FetchOptions): Promise;
+ /**
+ * Fetch the partial information, for all posts of specific topics
+ */
+ getPostItemsOfTopics(topicIDs: number[], opts?: FetchOptions): Promise;
+ /**
+ * Fetch the partial information, for all posts of a specific category
+ */
+ getPostItemsOfCategory(categoryID: number, opts?: FetchOptions): Promise;
+ /**
+ * Fetch the partial information, for all posts of specific categories
+ */
+ getPostItemsOfCategories(categoryIDs: number[], opts?: FetchOptions): Promise;
+ /**
+ * Fetch the partial information, for all posts of the forum
+ */
+ getPostItems(opts?: FetchOptions): Promise;
+ /**
+ * Fetch the whole information, for a specific post of the forum
+ */
+ getPost(id: number, opts?: FetchOptions): Promise;
+ createReply(postId: any, raw: any, category: any): Promise;
+ changeOwner(postId: string | number, topicId: string | number, owner: string): Promise;
+ createUser(data: any): Promise;
+ getUserByUsername(username: any): Promise;
+ setUserAvatar(user_name: any, upload_id: any): Promise;
+ updateUser(user_name: any, args: any): Promise;
+ updateGroup(user_name: any, group: any): Promise>;
+ upload(userId: any, file: any): Promise;
+ uploadFile(userId: any, file: any): Promise;
+ /**
+ * Fetch the whole information, for all posts, or specific posts, of the forum
+ */
+ getPosts(postIDs?: number[] | null, opts?: FetchOptions): Promise;
+ createPost(title: string, raw: string, category: number): Promise;
+ /**
+ * Update a post with the content
+ * @param postID the identifier of the post to update
+ * @param content the new raw content for the post
+ * @param reason the reason, if provided, for modifying the post
+ * @param old if the old raw content is provided, then the update verified that you are working with the latest post content before applying the update
+ */
+ updatePost(postID: number, content: string, reason?: string, old?: string): Promise;
+ /**
+ * Update post meta
+ */
+ updateTopic(postId: number, category_id: number, title: string, tags?: string[]): Promise;
+ rebakePost(postID: number): Promise;
+ /**
+ * Modify a post using a modifier
+ */
+ modifyPost(post: PostResponse, modifier: PostModifier): Promise;
+ /**
+ * Modify a post (via its post identifier) using a modifier
+ */
+ modifyPostID(post: number, modifier: PostModifier): Promise;
+ /**
+ * Modify a post (via fetching the whole post from the partial post identifier) using a modifier
+ */
+ modifyPostItem(post: PostItem, modifier: PostModifier): Promise;
+ /**
+ * Run the post modifier on all specified posts
+ */
+ modifyPosts(posts: PostResponse[], modifier: PostModifier): Promise;
+ /**
+ * Fetch the partial information, for all posts of a specific topic
+ * Alias of {@link .getPostItemsOfTopic}.
+ */
+ getThread(topicID: number, opts?: FetchOptions): Promise;
+ /**
+ * Fetch the partial information, for all posts of specific topics, grouped by topic
+ */
+ getThreads(topicIDs: number[], opts?: FetchOptions): Promise;
+ /**
+ * Fetch the partial information, for all posts of specific categories, grouped by topic
+ */
+ getThreadsOfCategory(categoryID: number, opts?: FetchOptions): Promise;
+ /**
+ * Fetch the partial information, for all posts of specific categories, grouped by category, then topic
+ */
+ getThreadsOfCategories(categoryIDs: number[], opts?: FetchOptions): Promise;
+ updateUserProfile(userId: any, prefs: UserPreferencesUpdate): Promise;
+}
+export declare const Instance: (config?: IDiscourseConfig, key?: EDiscourseConfigKey) => Discourser;
diff --git a/packages/discourse/lib/discourse/index.js b/packages/discourse/lib/discourse/index.js
new file mode 100644
index 00000000..335b6d90
--- /dev/null
+++ b/packages/discourse/lib/discourse/index.js
@@ -0,0 +1,936 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Instance = exports.Discourser = exports.escape = exports.logger = void 0;
+const constants_1 = require("../../constants");
+const osr_cli_commons_1 = require("@plastichub/osr-cli-commons");
+const debug_1 = require("@plastichub/core/debug");
+exports.logger = (0, debug_1.logger)(constants_1.MODULE_NAME);
+const write_1 = require("@plastichub/fs/write");
+const write_2 = require("@plastichub/fs/write");
+const exists_1 = require("@plastichub/fs/exists");
+const native_promise_pool_1 = require("native-promise-pool");
+const path_1 = require("path");
+const axios_1 = require("axios");
+const fs = require("fs");
+const path = require("path");
+const FormData = require("form-data");
+const https = require('https');
+const request = require("request");
+const fetch = require('isomorphic-unfetch');
+const escape = (path) => path.replace(/[^\w]/g, '-').replace(/-+/, '-');
+exports.escape = escape;
+const generate_password_1 = require("generate-password");
+/**
+ * Discourser is an API Client for the [Discourse API](https://docs.discourse.org)
+ * It special features are:
+ * - TypeScript Types
+ * - Respecting Rate Limits
+ * - Optional Heavy Caching
+ * - Post Modifiers (can be used for global find and replace across all posts on the forum)
+ */
+class Discourser {
+ /**
+ * Construct our Discourser instance
+ * See {@link IDiscourserConfig} for available configuration.
+ */
+ constructor(config) {
+ this.host = config.host;
+ this.key = config.key;
+ this.username = config.username;
+ this.cache = config.cache;
+ this.useCache = config.useCache;
+ this.dry = config.dry || false;
+ this.pool = new native_promise_pool_1.default(config.rateLimitConcurrency || 60);
+ }
+ /** Get the URL of a topic */
+ getTopicURL(topic) {
+ if (typeof topic === 'number') {
+ return `${this.host}/t/${topic}`;
+ }
+ return `${this.host}/t/${topic.slug}/${topic.id}`;
+ }
+ /** Fetch a discourse API URL, with rate limit concurrency and optional caching */
+ async fetch({ url, useCache, request }) {
+ // check if cache is enabled
+ useCache = false;
+ const cache = this.cache &&
+ ((request === null || request === void 0 ? void 0 : request.method) || 'get') === 'get' &&
+ (0, path_1.join)(this.cache, (0, exports.escape)(url));
+ // check if we should and can read from cache
+ if (cache &&
+ this.useCache !== false &&
+ useCache !== false &&
+ ((0, exists_1.sync)(cache))) {
+ const result = (0, write_2.sync)(cache, 'json');
+ return result;
+ }
+ // fetch
+ const result = await this.pool.open(() => this._fetch({ url, request }));
+ // write to cache if cache is enabled
+ if (cache) {
+ (0, write_1.sync)(cache, result);
+ }
+ // return the result
+ return result;
+ }
+ /** Fetch a discourse API URL, with rate limit retries */
+ async _post(url, data) {
+ var _a;
+ const opts = {
+ headers: {
+ 'Api-Key': this.key,
+ 'Api-Username': this.username,
+ },
+ };
+ let d = data;
+ const res = await axios_1.default.post(url, d, {
+ headers: opts.headers
+ });
+ // fetch text then parse as json, so that when errors occur we can output what it was
+ // rather than being stuck with errors like these:
+ // FetchError: invalid json response body at https://discuss.bevry.me/posts/507.json reason: Unexpected token < in JSON at position 0
+ const text = await res.data;
+ // check if there are errors
+ if (typeof data.errors !== 'undefined') {
+ // check if the error is a rate limit
+ const wait = (_a = data.extras) === null || _a === void 0 ? void 0 : _a.wait_seconds;
+ if (wait != null) {
+ // if it was, try later
+ // return await retry(wait + 1)
+ }
+ // otherwise fail
+ // logger.debug({ data, url, opts })
+ return Promise.reject(new Error(`fetch of [${url}] received failed response:\n${data}`));
+ }
+ return text;
+ }
+ /** Fetch a discourse API URL, with rate limit retries */
+ async _fetch({ url, request }) {
+ var _a;
+ const httpsAgent = new https.Agent({
+ rejectUnauthorized: false,
+ });
+ const opts = {
+ ...request,
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username,
+ ...request === null || request === void 0 ? void 0 : request.headers
+ },
+ rejectUnauthorized: false,
+ agent: httpsAgent
+ };
+ const retry = (seconds) => {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => this._fetch({ url, request })
+ .then(resolve)
+ .catch(reject), (seconds || 60) * 1000);
+ });
+ };
+ try {
+ const res = await fetch(url, opts);
+ // fetch text then parse as json, so that when errors occur we can output what it was
+ // rather than being stuck with errors like these:
+ // FetchError: invalid json response body at https://discuss.bevry.me/posts/507.json reason: Unexpected token < in JSON at position 0
+ const text = await res.text();
+ let data;
+ try {
+ data = JSON.parse(text);
+ }
+ catch (err) {
+ // check if it was cloudflare reporting that the server has been hit too hard
+ if (text.includes('Please try again in a few minutes')) {
+ exports.logger.debug('server has stalled, trying again in a minute');
+ return await retry(60);
+ }
+ // otherwise log the error page and die
+ // logger.debug({ text, url , opts })
+ return Promise.reject(exports.logger.error(text, url, opts, err) &&
+ new Error(`fetch of [${url}] received invalid response:\n${text}`));
+ }
+ // check if there are errors
+ if (typeof data.errors !== 'undefined') {
+ // check if the error is a rate limit
+ const wait = (_a = data.extras) === null || _a === void 0 ? void 0 : _a.wait_seconds;
+ if (wait != null) {
+ // if it was, try later
+ return await retry(wait + 1);
+ }
+ // otherwise fail
+ // logger.debug({ data, url, opts })
+ return Promise.reject(new Error(`fetch of [${url}] received failed response:\n${data}`));
+ }
+ return data;
+ }
+ catch (err) {
+ // logger.debug({ err, url, opts })
+ return Promise.reject(exports.logger.error(`fetch of [${url}] failed with error`, err));
+ }
+ }
+ // =================================
+ // Search
+ /**
+ * API Helper for {@link .search}
+ * https://docs.discourse.org/#tag/Search/operation/search
+ */
+ async search(query, params = '', opts = {}) {
+ let url = `${this.host}/search.json?q=${encodeURIComponent(query)} ${encodeURIComponent(params)}`;
+ return await this.fetch({ url, ...opts });
+ }
+ // =================================
+ // Tags
+ /**
+ * API Helper for {@link .getTags}
+ */
+ async getTagsResponse(opts = {}) {
+ const url = `${this.host}/tags.json`;
+ return await this.fetch({ url, ...opts });
+ }
+ /**
+ * Fetch the whole information, for all categories of the forum
+ */
+ async getTags(opts = {}) {
+ const response = await this.getTagsResponse(opts);
+ const tags = response.tags;
+ return tags;
+ }
+ async createTag(name) {
+ const url = `${this.host}/tag_groups.json`;
+ try {
+ return await this._post(url, {
+ name
+ });
+ }
+ catch (error) {
+ debugger;
+ }
+ }
+ // =================================
+ // CATEGORIES
+ /**
+ * API Helper for {@link .getCategories}
+ */
+ async getCategoriesResponse(opts = {}) {
+ const url = `${this.host}/categories.json` +
+ (opts.include_subcategories ? '?include_subcategories=true' : '');
+ return await this.fetch({ url, ...opts });
+ }
+ /**
+ * Fetch the whole information, for all categories of the forum
+ */
+ async getCategories(opts = {}) {
+ const response = await this.getCategoriesResponse(opts);
+ const categories = response.category_list.categories;
+ return categories;
+ }
+ /**
+ * API Helper for {@link .getTopicItemsOfCategory}
+ * Discourse does not provide an API for fetching category information for a specific category.
+ * Instead, all that it provides is a way of getting the topics for a specific category.
+ */
+ async getCategoryResponse(categoryID, opts = {}) {
+ const url = `${this.host}/c/${categoryID}.json` +
+ (opts.page !== 0 ? `?page=${opts.page}` : '');
+ return await this.fetch({ url, ...opts });
+ }
+ // =================================
+ // TOPICS
+ /**
+ * Fetch the partial information, for all topics of a specific category
+ */
+ async getTopicItemsOfCategory(categoryID, opts = {}) {
+ // prepare and fetch
+ let page = opts.page || 0;
+ const response = await this.getCategoryResponse(categoryID, {
+ ...opts,
+ page,
+ });
+ let topics = response.topic_list.topics;
+ // fetch the next page
+ if (topics.length === response.topic_list.per_page) {
+ page += 1;
+ const more = await this.getTopicItemsOfCategory(categoryID, {
+ ...opts,
+ page,
+ });
+ topics.push(...more);
+ }
+ // if we are the first page, then output count as we now have all of them
+ if (page === 0) {
+ const ids = topics.map((i) => i.id);
+ }
+ topics = topics.filter((t) => t.visible === true);
+ return topics;
+ }
+ /**
+ * Fetch the partial information, for all topics of specific categoires
+ */
+ async getTopicItemsOfCategories(categoryIDs, opts = {}) {
+ // fetch topic items for specific categories
+ try {
+ const topicsOfCategories = await Promise.all(categoryIDs.map((id) => this.getTopicItemsOfCategory(id, opts)));
+ // @ts-ignore
+ return topicsOfCategories.flat();
+ }
+ catch (error) {
+ exports.logger.error(error);
+ }
+ }
+ /**
+ * Fetch the partial information, for all topics of the forum
+ */
+ async getTopicItems(opts = {}) {
+ const categories = await this.getCategories();
+ const categoryIDs = categories.map((i) => i.id);
+ return this.getTopicItemsOfCategories(categoryIDs, opts);
+ }
+ /**
+ * Fetch the whole information, for a specific topic of the forum
+ */
+ getTopic(id, opts = {}) {
+ const url = `${this.host}/t/${id}.json`;
+ return this.fetch({ url, ...opts });
+ }
+ /**
+ * Fetch the whole information, for all topics, or specific topics, of the forum
+ */
+ async getTopics(topicIDs, opts = {}) {
+ // if no topics, use all topics
+ if (!topicIDs) {
+ const topics = await this.getTopicItems(opts);
+ topicIDs = topics.map((i) => i.id);
+ }
+ // fetch whole topics
+ return Promise.all(topicIDs.map((id) => this.getTopic(id, opts)));
+ }
+ async updateTopicVisibility(topicID, listed = true, visible = 'visible') {
+ const url = `${this.host}/t/${topicID}/status`;
+ let ret = await fetch(url, {
+ "headers": {
+ "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ },
+ "body": `status=${visible}&enabled=${listed}`,
+ "method": "PUT"
+ });
+ return ret;
+ }
+ async updateTopicTimestamp(topicID, timestamp, token) {
+ let time;
+ if (typeof timestamp === 'number') {
+ time = timestamp;
+ }
+ else if (typeof timestamp === 'number') {
+ time = Number(timestamp);
+ }
+ else if (timestamp instanceof Date) {
+ // ms to seconds
+ time = timestamp.getTime() / 1000;
+ }
+ else {
+ return Promise.reject(new Error('invalid timestamp format'));
+ }
+ const url = `${this.host}/t/${topicID}/change-timestamp`;
+ let ret = await fetch(url, {
+ "headers": {
+ "accept-language": "en-GB,en-US;q=0.9,en;q=0.8,de;q=0.7,es;q=0.6,fr;q=0.5",
+ "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
+ "x-csrf-token": token,
+ "x-requested-with": "XMLHttpRequest",
+ "cookie": "_bypass_cache=true; _ga_MBZGKNMDWC=GS1.1.1685892974.20.1.1685893082.0.0.0; _ga_P4SR15V1XR=GS1.1.1687459978.51.1.1687460537.0.0.0; _ga_H8W78Y3P2B=GS1.1.1687604701.23.0.1687604701.0.0.0; _ga=GA1.1.401826746.1678337758; _t=xQ05qW5JFxLM9Pq0lIwG6ez74Z1q2OLpak0DzRx8VdFYE5eI3oJXhLURPrdm2zIcHmYcBj9q%2BKdHhGz5N6j9mXitYzcMwkXHL3K9GYKdO4gJ8tBQimpmd1HFaRhB9Ml9aJ8WviqQWDZDOYwEUKFcWw3wbAalfQtbdIbUSX8gH9sG6DLFU3HiEg7tWModRy%2BoFrTm6QOalDuajRW3nBazau%2FiY8ZCVm2g30Y10CBDfqJHL1ztV8XM4kEIeulLNTzGVtSb7uuO1OcjZRSb--aDgCPEalq7SIpnH5--HWCNf5readaeij3oDl9b9w%3D%3D; __profilin=p%3Dt%2Ca%3Deef38e031f99cc8240f3518e1b8811cf; _forum_session=RkEWuzKI1QXBYCnP6KRamD8mweZ3h9%2B6G%2Fi23gAWUgy8gp8FuiyQD5lKU0Fbx3FzzaM4SiQcvnIiEAnb5P4OYjlvstqwWlfRp%2B9is7iX8StwYGiYsncHQ5LrzSbV3y9mR7sj%2F8JZ8evQOe2ZZjZB3iEkppsGrmyFrw5PsUgSphRTZm70SKIw96JrW17yK4hhLqtk%2BaQPgNu4oJl42YfXAr%2FCBldcBUKXFeHppYmv61WECV0531hCo7GcA4t06B9QpSr%2BeoiM1Ok9tpQrAlZf36Ka4lVCTyXXu3SNvbtvfd9tZMJCWDYv69jdMsezuOaEP870pk9qYPaL4x6nAY5EXO3u9usCggqQ1B1EydCK9uMy7ZUCIo9wONw7QOIgEQ%3D%3D--GMqYSb2H7xXVDky6--R9gVciBqwC0IL9LefywrFw%3D%3D; _ga_GVR8PEPG6C=GS1.1.1687710574.106.1.1687710599.0.0.0",
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ },
+ "body": `timestamp=${time}`,
+ "method": "PUT"
+ });
+ if (ret && ret.status === 200) {
+ return true;
+ }
+ return;
+ /*
+ let data = new FormData();
+ data.append('timestamp', time);
+
+ try {
+ let ret = await axios.put(url, data, {
+ headers: {
+ //'Accept-Language': 'en-US,en;q=0.8',
+ //'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
+ //'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ debugger
+ } catch (error) {
+ debugger
+ }
+
+
+ return
+ */
+ /*
+ var options = {
+ method: 'PUT',
+ url: url,
+ headers:
+ {
+ 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ },
+ body: `timestamp=${time}`
+ };
+
+ new Promise((resolve, reject) => {
+ request(options, function (error, response, body) {
+ if (error) {
+ throw new Error(error);
+ } else {
+ resolve(body);
+ }
+ });
+ });
+ */
+ /*
+ var options = {
+ method: 'POST',
+ url: url,
+ headers:
+ {
+ 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ },
+ body
+ }
+
+
+ return new Promise((resolve, reject) => {
+ request(options, function (error, response, body) {
+ if (error) {
+ throw new Error(error);
+ } else {
+ resolve(body);
+ }
+ });
+ });
+*/
+ // prepare the request
+ const request = {
+ timestamp: time,
+ };
+ // send the update
+ exports.logger.debug('updating', topicID, 'topic timestamp with', request);
+ //const url = `${this.host}/t/${topicID}/change-timestamp`
+ const response = await this.fetch({
+ url,
+ request: {
+ method: 'put',
+ body: `timestamp=${time}`,
+ headers: {
+ 'Api-Key': this.key,
+ 'Api-Username': this.username,
+ "content-type": "application/x-www-form-urlencoded; charset=UTF-8"
+ }
+ }
+ });
+ // check it
+ if (response.success !== 'OK') {
+ return Promise.reject(new Error(`timestamp update of topic ${topicID} failed:\n${{
+ url,
+ request,
+ response,
+ }}`));
+ }
+ return response;
+ }
+ // =================================
+ // POSTS
+ /**
+ * API Helper for {@link .getPostItemsOfTopic}
+ */
+ async getPostItemsOfTopicResponse(topicID, opts = {}) {
+ const url = `${this.host}/t/${topicID}/posts.json`;
+ const response = await this.fetch({ url, ...opts });
+ return response;
+ }
+ async _createUser(name, email, pUserGroup) {
+ const pwd = (0, generate_password_1.generate)({
+ length: 10,
+ numbers: true
+ });
+ let user = await this.createUser({
+ "name": name,
+ "email": email,
+ "password": pwd,
+ "username": name,
+ "active": true,
+ "approved": true,
+ "user_fields[1]": true
+ });
+ if (user && user.user_id) {
+ await this.updateGroup(name, pUserGroup);
+ return { ...user, password: pwd };
+ }
+ else {
+ if (user && user.message && user.message == 'Username must be unique\nPrimary email has already been taken') {
+ return null;
+ }
+ else if (user && user.message && user.message == 'Your account is activated and ready to use.') {
+ if (user.user_id) {
+ return { ...user, password: pwd };
+ }
+ return null;
+ }
+ else {
+ console.log('cant create user ' + name, user);
+ }
+ return null;
+ }
+ }
+ async getUsers(page) {
+ const url = `${this.host}/admin/users/list/active.json?page=` + page;
+ const response = await this.fetch({ url });
+ return response;
+ }
+ async getUser(id) {
+ const url = `${this.host}/admin/users/${id}.json`;
+ const response = await this.fetch({ url });
+ return response;
+ }
+ /**
+ * Fetch the partial information, for all posts of a specific topic
+ */
+ async getPostItemsOfTopic(topicID, opts = {}) {
+ const response = await this.getPostItemsOfTopicResponse(topicID, opts);
+ const posts = response.post_stream.posts;
+ const ids = posts.map((i) => i.id);
+ return posts;
+ }
+ /**
+ * Fetch the partial information, for all posts of specific topics
+ */
+ async getPostItemsOfTopics(topicIDs, opts = {}) {
+ // fetch post items for specific topics
+ const postItemsOfTopics = await Promise.all(topicIDs.map((id) => this.getPostItemsOfTopic(id, opts)));
+ // @ts-ignore
+ return postItemsOfTopics.flat();
+ }
+ /**
+ * Fetch the partial information, for all posts of a specific category
+ */
+ async getPostItemsOfCategory(categoryID, opts = {}) {
+ // fetch topics for the category
+ const topics = await this.getTopicItemsOfCategory(categoryID, opts);
+ const topicIDs = topics.map((i) => i.id);
+ // fetch
+ const posts = await this.getPostItemsOfTopics(topicIDs);
+ const ids = posts.map((i) => i.id);
+ return posts;
+ }
+ /**
+ * Fetch the partial information, for all posts of specific categories
+ */
+ async getPostItemsOfCategories(categoryIDs, opts = {}) {
+ // fetch post items for specific categories
+ const postItemsOfCategories = await Promise.all(categoryIDs.map((id) => this.getPostItemsOfCategory(id, opts)));
+ // @ts-ignore
+ return postItemsOfCategories.flat();
+ }
+ /**
+ * Fetch the partial information, for all posts of the forum
+ */
+ async getPostItems(opts = {}) {
+ const categories = await this.getCategories();
+ const categoryIDs = categories.map((i) => i.id);
+ return this.getPostItemsOfCategories(categoryIDs, opts);
+ }
+ /**
+ * Fetch the whole information, for a specific post of the forum
+ */
+ getPost(id, opts = {}) {
+ const url = `${this.host}/posts/${id}.json`;
+ return this.fetch({ url, ...opts });
+ }
+ async createReply(postId, raw, category) {
+ const url = `${this.host}/posts.json`;
+ let data = new FormData();
+ data.append('topic_id', '' + postId);
+ data.append('raw', raw);
+ data.append('nested_post', 'true');
+ data.append('category', category);
+ var options = {
+ method: 'POST',
+ url: url,
+ headers: {
+ 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ },
+ "body": `raw=${raw}&unlist_topic=false&category=${category}&topic_id=${postId}&is_warning=false&archetype=regular&featured_link=&shared_draft=false&nested_post=true`,
+ };
+ return new Promise((resolve, reject) => {
+ request(options, function (error, response, body) {
+ if (error) {
+ throw new Error(error);
+ }
+ else {
+ resolve(body);
+ }
+ });
+ });
+ }
+ async changeOwner(postId, topicId, owner) {
+ const url = `${this.host}/t/${topicId}/change-owner.json`;
+ var options = {
+ method: 'POST',
+ url: url,
+ headers: {
+ 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ },
+ body: `post_ids%5B%5D=${postId}&username=${owner}`
+ };
+ return new Promise((resolve, reject) => {
+ request(options, function (error, response, body) {
+ if (error) {
+ throw new Error(error);
+ }
+ else {
+ resolve(body);
+ }
+ });
+ });
+ }
+ async createUser(data) {
+ const url = `${this.host}/users`;
+ return await this._post(url, data);
+ }
+ async getUserByUsername(username) {
+ const url = `${this.host}/u/${username}.json`;
+ const response = await this.fetch({ url });
+ return response.user;
+ }
+ async setUserAvatar(user_name, upload_id) {
+ // fetch whole posts
+ const url = `${this.host}/u/${user_name}/preferences/avatar/pick.json`;
+ return await axios_1.default.put(url, {
+ upload_id,
+ username: user_name,
+ type: 'uploaded'
+ }, {
+ headers: {
+ 'accept': 'application/json',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ }
+ async updateUser(user_name, args) {
+ const url = `${this.host}/u/${user_name}.json`;
+ return await axios_1.default.put(url, {
+ ...args
+ }, {
+ headers: {
+ 'accept': 'application/json',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ }
+ async updateGroup(user_name, group) {
+ // fetch whole posts
+ const url = `${this.host}/groups/${group}/members.json`;
+ const t = axios_1.default.put(url, {
+ usernames: user_name,
+ notify_users: false
+ }, {
+ headers: {
+ 'accept': 'application/json',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ t.then((d) => {
+ }).catch((e) => {
+ //debugger;
+ });
+ return t;
+ }
+ async upload(userId, file) {
+ // fetch whole posts
+ const url = `${this.host}/uploads.json`;
+ let data = new FormData();
+ const fsData = path.parse(file);
+ data.append('file', file, fsData.base);
+ data.append('user_id', userId);
+ data.append('upload_type', 'avatar');
+ data.append('file', fs.createReadStream(file));
+ return await axios_1.default.post(url, data, {
+ headers: {
+ 'accept': 'application/json',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ 'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ }
+ async uploadFile(userId, file) {
+ // fetch whole posts
+ const url = `${this.host}/uploads.json`;
+ let data = new FormData();
+ const fsData = path.parse(file);
+ data.append('file', file, fsData.base);
+ data.append('user_id', userId);
+ data.append('upload_type', 'composer');
+ data.append('file', fs.createReadStream(file));
+ return await axios_1.default.post(url, data, {
+ headers: {
+ 'accept': 'application/json',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ 'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ }
+ // =================================
+ // POSTS: UPDATING
+ /**
+ * Fetch the whole information, for all posts, or specific posts, of the forum
+ */
+ async getPosts(postIDs, opts = {}) {
+ // if no posts, use all
+ if (!postIDs) {
+ const posts = await this.getPostItems(opts);
+ postIDs = posts.map((i) => i.id);
+ }
+ // fetch whole posts
+ return await Promise.all(postIDs.map((id) => this.getPost(id, opts)));
+ }
+ async createPost(title, raw, category) {
+ // fetch whole posts
+ const url = `${this.host}/posts`;
+ return new Promise((resolve) => {
+ return this._post(url, { raw, title, category }).then((d) => {
+ resolve(d);
+ }).catch((e) => {
+ resolve(e.response.data);
+ });
+ });
+ }
+ /**
+ * Update a post with the content
+ * @param postID the identifier of the post to update
+ * @param content the new raw content for the post
+ * @param reason the reason, if provided, for modifying the post
+ * @param old if the old raw content is provided, then the update verified that you are working with the latest post content before applying the update
+ */
+ async updatePost(postID, content, reason = 'api update', old) {
+ // prepare the request
+ const data = {
+ post: {
+ raw: content,
+ edit_reason: reason,
+ },
+ };
+ if (old) {
+ data.post.raw_old = old;
+ }
+ // send the update
+ const url = `${this.host}/posts/${postID}.json`;
+ const response = await this.fetch({
+ url,
+ request: {
+ method: 'put',
+ body: JSON.stringify(data),
+ },
+ });
+ // return the response
+ return response.post;
+ }
+ /**
+ * Update post meta
+ */
+ async updateTopic(postId, category_id, title, tags) {
+ const data = {
+ title,
+ tags: tags || [],
+ featuredLink: null,
+ category_id
+ };
+ const url = `${this.host}/t/${postId}.json`;
+ const response = await this.fetch({
+ url,
+ request: {
+ method: 'put',
+ body: JSON.stringify(data),
+ },
+ });
+ return response.basic_topic;
+ }
+ async rebakePost(postID) {
+ const url = `${this.host}/posts/${postID}/rebake`;
+ exports.logger.debug('rebaking', postID);
+ const response = await this.fetch({
+ url,
+ request: {
+ method: 'put'
+ }
+ });
+ exports.logger.debug('rebaked', postID);
+ return response;
+ }
+ /**
+ * Modify a post using a modifier
+ */
+ async modifyPost(post, modifier) {
+ // check if we received a post item, instead of a post response
+ if (post.raw == null) {
+ post = await this.getPost(post.id);
+ }
+ // check
+ if (!post.raw) {
+ return Promise.resolve(null);
+ }
+ // replace
+ const { result, reason } = modifier(post);
+ if (result === post.raw) {
+ // if (post.cooked) {
+ // const { result, reason } = modifier(post.cooked)
+ // if (result !== post.cooked) {
+ // logger.debug(
+ // 'replace did have an effect on cooked post',
+ // postID,
+ // 'so rebaking it'
+ // )
+ // return await this.rebakePost(postID)
+ // }
+ // }
+ return Promise.resolve(null);
+ }
+ // dry
+ if (this.dry) {
+ return Promise.resolve({
+ ...post,
+ result,
+ reason,
+ });
+ }
+ // update
+ try {
+ return await this.updatePost(post.id, result, reason, post.raw);
+ }
+ catch (err) {
+ if (err.message.includes('That post was edited by another user and your changes can no longer be saved.')) {
+ return this.modifyPost(await this.getPost(post.id, { useCache: false }), modifier);
+ }
+ exports.logger.error(err);
+ return Promise.reject(`modifying post ${post.id} failed`);
+ }
+ }
+ /**
+ * Modify a post (via its post identifier) using a modifier
+ */
+ async modifyPostID(post, modifier) {
+ return this.modifyPost(await this.getPost(post), modifier);
+ }
+ /**
+ * Modify a post (via fetching the whole post from the partial post identifier) using a modifier
+ */
+ async modifyPostItem(post, modifier) {
+ return this.modifyPost(await this.getPost(post.id), modifier);
+ }
+ /**
+ * Run the post modifier on all specified posts
+ */
+ async modifyPosts(posts, modifier) {
+ const updates = await Promise.all(posts.map((post) => this.modifyPost(post, modifier)));
+ const updated = updates.filter((i) => i);
+ return updated;
+ }
+ // =================================
+ // THREADS
+ /**
+ * Fetch the partial information, for all posts of a specific topic
+ * Alias of {@link .getPostItemsOfTopic}.
+ */
+ async getThread(topicID, opts = {}) {
+ const topic = await this.getTopic(topicID, opts);
+ const [post, ...replies] = await this.getPostItemsOfTopic(topicID, opts);
+ return {
+ topic,
+ post,
+ replies,
+ };
+ }
+ /**
+ * Fetch the partial information, for all posts of specific topics, grouped by topic
+ */
+ async getThreads(topicIDs, opts = {}) {
+ return await Promise.all(topicIDs.map((id) => this.getThread(id, opts)));
+ }
+ /**
+ * Fetch the partial information, for all posts of specific categories, grouped by topic
+ */
+ async getThreadsOfCategory(categoryID, opts = {}) {
+ // fetch topics for the category
+ const topics = await this.getTopicItemsOfCategory(categoryID, opts);
+ const topicIDs = topics.map((i) => i.id);
+ // return threads
+ return await this.getThreads(topicIDs);
+ }
+ /**
+ * Fetch the partial information, for all posts of specific categories, grouped by category, then topic
+ */
+ async getThreadsOfCategories(categoryIDs, opts = {}) {
+ return await Promise.all(categoryIDs.map((id) => this.getThreadsOfCategory(id, opts)));
+ }
+ async updateUserProfile(userId, prefs) {
+ const url = `${this.host}/u/${userId}.json`;
+ let data = new FormData();
+ data.append('bio_raw', prefs.bio_raw);
+ prefs.location && data.append('location', prefs.location);
+ prefs.website && data.append('website', prefs.website);
+ return await axios_1.default.put(url, data, {
+ headers: {
+ 'accept': 'application/json',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ }
+}
+exports.Discourser = Discourser;
+const Instance = (config, key = 'discourse_admin') => {
+ return new Discourser(config || (0, osr_cli_commons_1.CONFIG_DEFAULT)()[key]);
+ /*
+
+ d.getTopicItemsOfCategories([cat]).then(posts => {
+ //console.log('posts', posts)
+ let content = ""
+ posts = posts.map((p) => {
+ const url = `${config.discourse.host}/t/${p.id}`;
+ const title = `${p.fancy_title}`;
+ return `${title} `;
+ }).join('\n');
+ content += posts + " ";
+ resolve(content);
+
+ });
+ */
+};
+exports.Instance = Instance;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL2Rpc2NvdXJzZS9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQ0FBNkM7QUFFN0MsaUVBQTREO0FBSTVELGtEQUEwRDtBQUU3QyxRQUFBLE1BQU0sR0FBUSxJQUFBLGNBQU8sRUFBQyx1QkFBVyxDQUFDLENBQUE7QUFFL0MsZ0RBQW9EO0FBQ3BELGdEQUFtRDtBQUNuRCxrREFBc0Q7QUFFdEQsNkRBQTZDO0FBRzdDLCtCQUEyQjtBQUMzQixpQ0FBeUI7QUFDekIseUJBQXdCO0FBQ3hCLDZCQUE0QjtBQUM1QixzQ0FBcUM7QUFFckMsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO0FBQzlCLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUNsQyxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQTtBQUVwQyxNQUFNLE1BQU0sR0FBRyxDQUFDLElBQVksRUFBRSxFQUFFLENBQ3RDLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUE7QUFEbEMsUUFBQSxNQUFNLFVBQzRCO0FBRS9DLHlEQUE0QztBQXNDNUM7Ozs7Ozs7R0FPRztBQUNILE1BQWEsVUFBVTtJQVN0Qjs7O09BR0c7SUFDSCxZQUFZLE1BQXlCO1FBQ3BDLElBQUksQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQTtRQUN2QixJQUFJLENBQUMsR0FBRyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUE7UUFDckIsSUFBSSxDQUFDLFFBQVEsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFBO1FBQy9CLElBQUksQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQTtRQUN6QixJQUFJLENBQUMsUUFBUSxHQUFH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
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/index.js.map b/packages/discourse/lib/discourse/index.js.map
new file mode 100644
index 00000000..2cd25095
--- /dev/null
+++ b/packages/discourse/lib/discourse/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/discourse/index.ts"],"names":[],"mappings":"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"}
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/types.d.ts b/packages/discourse/lib/discourse/types.d.ts
new file mode 100644
index 00000000..717972e6
--- /dev/null
+++ b/packages/discourse/lib/discourse/types.d.ts
@@ -0,0 +1,697 @@
+export interface Failure {
+ success: 'OK';
+}
+export interface Success {
+ failed: 'FAILED';
+}
+export type Response = Failure & Success;
+export interface Action {
+ can_act: boolean;
+ id: number;
+ count?: number;
+ hidden?: boolean;
+}
+export interface Poster {
+ description: string;
+ extras: string;
+ user_id: number;
+}
+export interface Person {
+ avatar_template: string;
+ id: number;
+ username: string;
+}
+export interface Participant extends Person {
+ post_count: number;
+}
+export interface Link {
+ url: string;
+ internal: boolean;
+ reflection: boolean;
+ title: string;
+ clicks: number;
+}
+/**
+ * Update a Topic Timestamp
+ * https://docs.discourse.org/#tag/Topics/paths/~1t~1{id}~1change-timestamp/put
+ */
+export interface TopicUpdateTimestampRequest {
+ timestamp: number;
+}
+export type TopicUpdateTimestampResponse = Response;
+/**
+ * Update a Post
+ * https://docs.discourse.org/#tag/Posts/paths/~1posts~1{id}.json/put
+ */
+export interface PostUpdateResponse {
+ post: PostUpdateItem;
+}
+export interface TopicUpdateBasicTopic {
+ fancy_title: string;
+ id: number;
+ posts_count: number;
+ slug: string;
+ title: string;
+}
+export interface TopicUpdateResponse {
+ basic_topic: TopicUpdateBasicTopic;
+}
+export interface PostUpdateItem {
+ actions_summary: Array;
+ admin: boolean;
+ avatar_template: string;
+ avg_time: object;
+ can_delete: boolean;
+ can_edit: boolean;
+ can_recover: boolean;
+ can_view_edit_history: boolean;
+ can_wiki: boolean;
+ cooked: string;
+ created_at: string;
+ deleted_at: object;
+ display_username: string;
+ draft_sequence: number;
+ edit_reason: object;
+ hidden_reason_id: object;
+ hidden: boolean;
+ id: number;
+ incoming_link_count: number;
+ moderator: boolean;
+ name: string;
+ post_number: number;
+ post_type: number;
+ primary_group_flair_bg_color: object;
+ primary_group_flair_color: object;
+ primary_group_flair_url: object;
+ primary_group_name: object;
+ quote_count: number;
+ reads: number;
+ reply_count: number;
+ reply_to_post_number: object;
+ score: number;
+ staff: boolean;
+ topic_id: number;
+ topic_slug: string;
+ trust_level: number;
+ updated_at: string;
+ user_deleted: boolean;
+ user_id: number;
+ user_title: object;
+ username: string;
+ version: number;
+ wiki: boolean;
+ yours: boolean;
+}
+export interface PostUpdateRequest {
+ post: {
+ raw: string;
+ raw_old?: string;
+ edit_reason?: string;
+ cooked?: string;
+ };
+}
+export interface TagsResponse {
+ tags: Tag[];
+ extras: TagsExtras;
+}
+export interface TagsExtras {
+ categories: any[];
+}
+export interface Tag {
+ count: number;
+ description: null;
+ id: string;
+ name: string;
+ pm_only: boolean;
+ target_tag: null;
+ text: string;
+}
+/** https://docs.discourse.org/#tag/Categories/paths/~1categories.json/get */
+export interface CategoriesResponse {
+ category_list: {
+ can_create_category: boolean;
+ can_create_topic: boolean;
+ categories: Category[];
+ draft_key: string;
+ draft_sequence: number;
+ draft: boolean;
+ };
+}
+export interface Category {
+ background_url: string;
+ can_edit: boolean;
+ color: string;
+ description_excerpt: string;
+ description_text: string;
+ description: string;
+ has_children: boolean;
+ id: number;
+ logo_url: string;
+ name: string;
+ notification_level: string;
+ permission: number;
+ position: number;
+ post_count: number;
+ read_restricted: boolean;
+ slug: string;
+ text_color: string;
+ topic_count: number;
+ topic_template: string;
+ topic_url: string;
+ topics_all_time: number;
+ topics_day: number;
+ topics_month: number;
+ topics_week: number;
+ topics_year: number;
+}
+/**
+ * Get Single Topic
+ * https://docs.discourse.org/#tag/Topics/paths/~1t~1{id}.json/get
+ */
+export interface TopicResponse {
+ actions_summary: Array;
+ archetype: string;
+ archived: boolean;
+ bookmarked: object;
+ category_id: number;
+ chunk_size: number;
+ closed: boolean;
+ created_at: string;
+ deleted_at: object;
+ deleted_by: object;
+ details: TopicDetails;
+ draft_key: string;
+ draft_sequence: object;
+ draft: object;
+ fancy_title: string;
+ has_summary: boolean;
+ highest_post_number: number;
+ id: number;
+ last_posted_at: object;
+ like_count: number;
+ participant_count: number;
+ pinned_at: string;
+ pinned_globally: boolean;
+ pinned_until: object;
+ pinned: boolean;
+ posts_count: number;
+ reply_count: number;
+ slug: string;
+ tags: string[];
+ title: string;
+ unpinned: object;
+ user_id: number;
+ views: number;
+ visible: boolean;
+ word_count: object;
+ post_stream: {
+ posts: Array;
+ stream: Array;
+ };
+ timeline_lookup: [
+ {
+ '0': Array;
+ }
+ ];
+}
+export interface TopicDetails {
+ auto_close_at: object;
+ auto_close_based_on_last_post: boolean;
+ auto_close_hours: object;
+ can_flag_topic: boolean;
+ created_by: Person;
+ last_poster: Person;
+ notification_level: number;
+ participants: Array;
+ suggested_topics: Array;
+}
+export interface TopicItem {
+ archetype: string;
+ archived: boolean;
+ bookmarked: object;
+ bumped_at: string;
+ bumped: boolean;
+ category_id: number;
+ closed: boolean;
+ created_at: string;
+ excerpt: string;
+ fancy_title: string;
+ has_summary: boolean;
+ highest_post_number: number;
+ id: number;
+ image_url: string;
+ last_posted_at: string;
+ last_poster_username: string;
+ like_count: number;
+ liked: object;
+ pinned_globally: boolean;
+ pinned: boolean;
+ posters: Array;
+ posts_count: number;
+ reply_count: number;
+ slug: string;
+ title: string;
+ unpinned: boolean;
+ unseen: boolean;
+ views: number;
+ visible: boolean;
+}
+/**
+ * Get Topics for Category
+ * https://docs.discourse.org/#tag/Categories/paths/~1c~1{id}.json/get
+ */
+export interface CategoryResponse {
+ users: Person[];
+ topic_list: {
+ can_create_topic: boolean;
+ draft: boolean;
+ draft_key: string;
+ draft_sequence: number;
+ per_page: number;
+ topics: Array;
+ };
+}
+/**
+ * Whole Post Information
+ * As returned by getting a single Post
+ * https://docs.discourse.org/#tag/Posts/paths/~1posts~1{id}.json/get
+ */
+export interface PostResponse {
+ actions_summary: Array;
+ admin: boolean;
+ avatar_template: string;
+ avg_time: object;
+ can_delete: boolean;
+ can_edit: boolean;
+ can_recover: boolean;
+ can_view_edit_history: boolean;
+ can_wiki: boolean;
+ cooked: string;
+ created_at: string;
+ deleted_at: object;
+ display_username: string;
+ edit_reason: object;
+ hidden_reason_id: object;
+ hidden: boolean;
+ id: number;
+ incoming_link_count: number;
+ moderator: boolean;
+ name: string;
+ post_number: number;
+ post_type: number;
+ primary_group_flair_bg_color: object;
+ primary_group_flair_color: object;
+ primary_group_flair_url: object;
+ primary_group_name: object;
+ quote_count: number;
+ raw: string;
+ reads: number;
+ reply_count: number;
+ reply_to_post_number: object;
+ score: number;
+ staff: boolean;
+ topic_id: number;
+ topic_slug: string;
+ trust_level: number;
+ updated_at: string;
+ user_deleted: boolean;
+ user_id: number;
+ user_title: object;
+ username: string;
+ version: number;
+ wiki: boolean;
+ yours: boolean;
+}
+export interface ICreateUserResponse {
+ success: boolean;
+ active: boolean;
+ message: string;
+ user_id: number;
+ password: string;
+}
+/**
+ * Get the Posts of a Topic
+ * https://docs.discourse.org/#tag/Topics/paths/~1t~1{id}~1posts.json/get
+ */
+export interface PostsResponse {
+ post_stream: {
+ posts: Array;
+ };
+ id: number;
+}
+/**
+ * Partial Post Information
+ * As returned by a listing
+ */
+export interface PostItem {
+ accepted_answer: boolean;
+ actions_summary: Array;
+ admin: boolean;
+ avatar_template: string;
+ can_accept_answer: boolean;
+ can_delete: boolean;
+ can_edit: boolean;
+ can_recover: boolean;
+ can_unaccept_answer: boolean;
+ can_view_edit_history: boolean;
+ can_wiki: boolean;
+ cooked: string;
+ created_at: string;
+ deleted_at: null;
+ display_username: string;
+ edit_reason: null;
+ hidden: boolean;
+ id: number;
+ incoming_link_count: number;
+ link_counts: Array ;
+ moderator: boolean;
+ name: string;
+ post_number: number;
+ post_type: number;
+ primary_group_flair_bg_color: null | object;
+ primary_group_flair_color: null | object;
+ primary_group_flair_url: null | object;
+ primary_group_name: null | object;
+ quote_count: number;
+ read: boolean;
+ readers_count: number;
+ reads: number;
+ reply_count: number;
+ reply_to_post_number: null | number;
+ reviewable_id: number;
+ reviewable_score_count: number;
+ reviewable_score_pending_count: number;
+ score: number;
+ staff: boolean;
+ topic_id: number;
+ topic_slug: string;
+ trust_level: number;
+ updated_at: string;
+ user_deleted: boolean;
+ user_id: number;
+ user_title: null | object;
+ username: string;
+ version: number;
+ wiki: boolean;
+ yours: boolean;
+}
+export type Thread = {
+ topic: TopicResponse;
+ post: PostItem;
+ replies: PostItem[];
+};
+/** When finding and replacing, determine replacements using a method that matches this */
+export type PostModifier = (post: PostResponse) => {
+ result: string;
+ reason?: string;
+};
+/** Configuration for Discourser */
+export interface IDiscourserConfig {
+ /** the discourse hostname to connect to, including protocol */
+ host: string;
+ /** the API key to connect with */
+ key: string;
+ /** the username to behave as */
+ username: string;
+ /** the cache directory to use, if we are caching */
+ cache?: string;
+ /** Whether or not we should read from the cache */
+ useCache?: boolean;
+ /** whether or not updates should be dry (non-applying) */
+ dry?: boolean;
+ /** how many concurrency requests to send to the server at once */
+ rateLimitConcurrency?: number;
+}
+export interface FetchOptions {
+ /** Whether or not we should read from the cache */
+ useCache?: boolean;
+ /** Only applicable to fetching topics of category */
+ page?: number;
+ /** Any thing to init the fetch call with? */
+ request?: RequestInit;
+ include_subcategories?: boolean;
+}
+export interface FetchConfig extends FetchOptions {
+ url: string;
+}
+export interface PostConfig extends FetchOptions {
+ url: string;
+ data: any;
+}
+export interface ISearchPost {
+ id: number;
+ name: string;
+ username: string;
+ avatar_template: string;
+ created_at: Date;
+ like_count: number;
+ blurb: string;
+ post_number: number;
+ topic_id: number;
+}
+export interface ISearchTagsDescriptions {
+}
+export interface ISearchTopic {
+ id: number;
+ title: string;
+ fancy_title: string;
+ slug: string;
+ posts_count: number;
+ reply_count: number;
+ highest_post_number: number;
+ created_at: Date;
+ last_posted_at: Date;
+ bumped: boolean;
+ bumped_at: Date;
+ archetype: string;
+ unseen: boolean;
+ pinned: boolean;
+ unpinned?: any;
+ excerpt: string;
+ visible: boolean;
+ closed: boolean;
+ archived: boolean;
+ bookmarked?: any;
+ liked?: any;
+ tags: any[];
+ tags_descriptions: ISearchTagsDescriptions;
+ category_id: number;
+ has_accepted_answer: boolean;
+}
+export interface IGroupedSearchResult {
+ more_posts?: any;
+ more_users?: any;
+ more_categories?: any;
+ term: string;
+ search_log_id: number;
+ more_full_page_results?: any;
+ can_create_topic: boolean;
+ error?: any;
+ post_ids: number[];
+ user_ids: any[];
+ category_ids: any[];
+ tag_ids: any[];
+ group_ids: any[];
+}
+export interface ISearchResult {
+ posts: ISearchPost[];
+ topics: ISearchTopic[];
+ users: any[];
+ categories: any[];
+ tags: any[];
+ groups: any[];
+ grouped_search_result: IGroupedSearchResult;
+}
+export interface IUserDetail {
+ id: number;
+ username: string;
+ name: string;
+ avatar_template: string;
+ email: string;
+ secondary_emails: any[];
+ active: boolean;
+ admin: boolean;
+ moderator: boolean;
+ last_seen_at: string;
+ last_emailed_at: string;
+ created_at: string;
+ last_seen_age: number;
+ last_emailed_age: number;
+ created_at_age: number;
+ trust_level: number;
+ manual_locked_trust_level: any;
+ flag_level: number;
+ title: string;
+ time_read: number;
+ staged: boolean;
+ days_visited: number;
+ posts_read_count: number;
+ topics_entered: number;
+ post_count: number;
+ associated_accounts: AssociatedAccount[];
+ can_send_activation_email: boolean;
+ can_activate: boolean;
+ can_deactivate: boolean;
+ ip_address: string;
+ registration_ip_address: string;
+ can_grant_admin: boolean;
+ can_revoke_admin: boolean;
+ can_grant_moderation: boolean;
+ can_revoke_moderation: boolean;
+ can_impersonate: boolean;
+ like_count: number;
+ like_given_count: number;
+ topic_count: number;
+ post_edits_count: number;
+ flags_given_count: number;
+ flags_received_count: number;
+ private_topics_count: number;
+ can_delete_all_posts: boolean;
+ can_be_deleted: boolean;
+ can_be_anonymized: boolean;
+ can_be_merged: boolean;
+ full_suspend_reason: any;
+ silence_reason: any;
+ penalty_counts: PenaltyCounts;
+ next_penalty: string;
+ primary_group_id: any;
+ badge_count: number;
+ warnings_received_count: number;
+ user_fields: UserFields;
+ bounce_score: number;
+ reset_bounce_score_after: any;
+ can_view_action_logs: boolean;
+ can_disable_second_factor: boolean;
+ can_delete_sso_record: boolean;
+ api_key_count: number;
+ external_ids: ExternalIds;
+ single_sign_on_record: any;
+ approved_by: ApprovedBy;
+ suspended_by: any;
+ silenced_by: any;
+ tl3_requirements: Tl3Requirements;
+ groups: Group[];
+}
+export interface AssociatedAccount {
+ name: string;
+ description: string;
+}
+export interface PenaltyCounts {
+ silenced: number;
+ suspended: number;
+}
+export interface UserFields {
+ "1": string;
+ "2": string;
+ "3": string;
+ "4": string;
+ "5": string;
+}
+export interface ExternalIds {
+ google_oauth2: string;
+}
+export interface ApprovedBy {
+ id: number;
+ username: string;
+ name: string;
+ avatar_template: string;
+}
+export interface Tl3Requirements {
+ time_period: number;
+ requirements_met: boolean;
+ requirements_lost: boolean;
+ trust_level_locked: boolean;
+ on_grace_period: boolean;
+ days_visited: number;
+ min_days_visited: number;
+ num_topics_replied_to: number;
+ min_topics_replied_to: number;
+ topics_viewed: number;
+ min_topics_viewed: number;
+ posts_read: number;
+ min_posts_read: number;
+ topics_viewed_all_time: number;
+ min_topics_viewed_all_time: number;
+ posts_read_all_time: number;
+ min_posts_read_all_time: number;
+ num_flagged_posts: number;
+ max_flagged_posts: number;
+ num_flagged_by_users: number;
+ max_flagged_by_users: number;
+ num_likes_given: number;
+ min_likes_given: number;
+ num_likes_received: number;
+ min_likes_received: number;
+ num_likes_received_days: number;
+ min_likes_received_days: number;
+ num_likes_received_users: number;
+ min_likes_received_users: number;
+ penalty_counts: PenaltyCounts2;
+}
+export interface PenaltyCounts2 {
+ silenced: number;
+ suspended: number;
+ total: number;
+}
+export interface Group {
+ id: number;
+ automatic: boolean;
+ name: string;
+ display_name?: string;
+ user_count: number;
+ mentionable_level: number;
+ messageable_level: number;
+ visibility_level: number;
+ primary_group: boolean;
+ title: any;
+ grant_trust_level?: number;
+ incoming_email: any;
+ has_messages: boolean;
+ flair_url: any;
+ flair_bg_color?: string;
+ flair_color?: string;
+ bio_raw?: string;
+ bio_cooked?: string;
+ bio_excerpt?: string;
+ public_admission: boolean;
+ public_exit: boolean;
+ allow_membership_requests: boolean;
+ full_name?: string;
+ default_notification_level: number;
+ membership_request_template: any;
+ members_visibility_level: number;
+ can_see_members: boolean;
+ can_admin_group: boolean;
+ publish_read_state: boolean;
+ can_edit_group?: boolean;
+}
+export type TPostStatus = 'visible' | 'archived' | 'pinned' | 'closed';
+export interface TPostStatusUpdate {
+ success: string;
+ topic_status_update: any;
+}
+export interface UserPreferencesUpdate {
+ bio_raw?: string;
+ website?: string;
+ location?: string;
+ custom_fields?: CustomFields;
+ timezone?: string;
+ default_calendar?: string;
+ profile_background_upload_url?: string;
+ card_background_upload_url?: string;
+}
+export interface CustomFields {
+ geo_location: GeoLocation;
+}
+export interface GeoLocation {
+ lat: string;
+ lon: string;
+ address: string;
+ countrycode: string;
+ city: string;
+ state: string;
+ country: string;
+ postalcode: string;
+ boundingbox: string[];
+ type: string;
+}
diff --git a/packages/discourse/lib/discourse/types.js b/packages/discourse/lib/discourse/types.js
new file mode 100644
index 00000000..a2a22c10
--- /dev/null
+++ b/packages/discourse/lib/discourse/types.js
@@ -0,0 +1,5 @@
+"use strict";
+// Attempt at TypeScript Types for the Discourse API
+// https://docs.discourse.org
+Object.defineProperty(exports, "__esModule", { value: true });
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL2Rpc2NvdXJzZS90eXBlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsb0RBQW9EO0FBQ3BELDZCQUE2QiJ9
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/types.js.map b/packages/discourse/lib/discourse/types.js.map
new file mode 100644
index 00000000..b4e4ac86
--- /dev/null
+++ b/packages/discourse/lib/discourse/types.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/discourse/types.ts"],"names":[],"mappings":";AAAA,oDAAoD;AACpD,6BAA6B"}
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/types/bevry.d.ts b/packages/discourse/lib/discourse/types/bevry.d.ts
new file mode 100644
index 00000000..2b0953b9
--- /dev/null
+++ b/packages/discourse/lib/discourse/types/bevry.d.ts
@@ -0,0 +1,130 @@
+import { YoutubeVideoData } from '../youtube';
+import { PostItem, TopicResponse } from './discourse';
+export interface DatabaseJSON {
+ users: {
+ [id: string]: User;
+ };
+ videos: {
+ [id: string]: VideoJSON;
+ };
+ series: {
+ [id: string]: SeriesJSON;
+ };
+ youtube: {
+ [id: string]: YoutubeVideoData;
+ };
+ transcripts: {
+ [videoID: string]: string;
+ };
+}
+export interface Database {
+ users: {
+ [id: string]: User;
+ };
+ videos: {
+ [id: string]: Video;
+ };
+ series: {
+ [id: string]: Series;
+ };
+ youtube: {
+ [id: string]: YoutubeVideoData;
+ };
+ transcripts: {
+ [videoID: string]: string;
+ };
+}
+export interface YoutubeBase {
+ youtubeID: string;
+ youtubeURL: string;
+ /** for videos, this is the video topic, for series, this is the tag, for meetings, this is null for now */
+ forumURL?: string | null;
+ studyURL?: string | null;
+ /** utc iso string */
+ datetime: string;
+ name: string;
+}
+export interface YoutubeJSON extends YoutubeBase {
+ author: string;
+}
+export interface Youtube extends YoutubeBase {
+ author: User;
+ toJSON: () => YoutubeJSON;
+}
+export interface NoteBase {
+ forumURL: string;
+ content: string;
+}
+export interface NoteJSON extends NoteBase {
+ video: string;
+ author: string;
+}
+export interface Note extends NoteBase {
+ video: Video;
+ author: User;
+ toJSON: () => NoteJSON;
+}
+export interface CommentJSON extends NoteJSON {
+ seconds: number;
+}
+export interface Comment extends Note {
+ seconds: number;
+ toJSON: () => CommentJSON;
+}
+export interface DiscussionBase {
+ forumURL: string;
+ name: string;
+ datetime: string;
+}
+export interface DiscussionJSON extends DiscussionBase {
+ video?: string | null;
+}
+export interface Discussion extends DiscussionBase {
+ video?: Video | null;
+ toJSON: () => DiscussionJSON;
+}
+export interface VideoBase {
+ notes: Note[];
+ discussions: Discussion[];
+ comments: Comment[];
+ thread: Thread;
+}
+export interface VideoJSON extends VideoBase, YoutubeJSON {
+ series?: string | null;
+ youtube: string;
+}
+export interface Video extends VideoBase, Youtube {
+ series?: Series | null;
+ youtube: YoutubeVideoData;
+ toJSON: () => VideoJSON;
+}
+export interface SeriesRaw {
+ youtubeID: string;
+ youtubeURL: string;
+ studyURL?: string | null;
+ name: string;
+ forumURL: string;
+}
+export interface SeriesJSON extends YoutubeJSON {
+ videos: SeriesRaw[];
+}
+export interface Series extends Youtube {
+ videos: Video[];
+ toJSON: () => SeriesJSON;
+}
+export interface User {
+ id: string;
+ name: string;
+ profiles: Profile[];
+}
+export interface Profile {
+ service: 'bevry' | 'youtube' | 'goodreads' | 'twitter' | 'email';
+ value: string;
+ url?: string;
+ data?: object;
+}
+export type Thread = {
+ topic: TopicResponse;
+ post: PostItem;
+ replies: PostItem[];
+};
diff --git a/packages/discourse/lib/discourse/types/bevry.js b/packages/discourse/lib/discourse/types/bevry.js
new file mode 100644
index 00000000..826ad1b4
--- /dev/null
+++ b/packages/discourse/lib/discourse/types/bevry.js
@@ -0,0 +1,3 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+//# sourceMappingURL=bevry.js.map
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/types/bevry.js.map b/packages/discourse/lib/discourse/types/bevry.js.map
new file mode 100644
index 00000000..501ab6f3
--- /dev/null
+++ b/packages/discourse/lib/discourse/types/bevry.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"bevry.js","sourceRoot":"","sources":["../../../src/lib/discourse/types/bevry.ts"],"names":[],"mappings":""}
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/types/discourse.d.ts b/packages/discourse/lib/discourse/types/discourse.d.ts
new file mode 100644
index 00000000..6762c9d6
--- /dev/null
+++ b/packages/discourse/lib/discourse/types/discourse.d.ts
@@ -0,0 +1,364 @@
+export interface Failure {
+ success: 'OK';
+}
+export interface Success {
+ failed: 'FAILED';
+}
+export type Response = Failure & Success;
+export interface Action {
+ can_act: boolean;
+ id: number;
+ count?: number;
+ hidden?: boolean;
+}
+export interface Poster {
+ description: string;
+ extras: string;
+ user_id: number;
+}
+export interface Person {
+ avatar_template: string;
+ id: number;
+ username: string;
+}
+export interface Participant extends Person {
+ post_count: number;
+}
+export interface Link {
+ url: string;
+ internal: boolean;
+ reflection: boolean;
+ title: string;
+ clicks: number;
+}
+/**
+ * Update a Topic Timestamp
+ * https://docs.discourse.org/#tag/Topics/paths/~1t~1{id}~1change-timestamp/put
+ */
+export interface TopicUpdateTimestampRequest {
+ timestamp: number;
+}
+export type TopicUpdateTimestampResponse = Response;
+/**
+ * Update a Post
+ * https://docs.discourse.org/#tag/Posts/paths/~1posts~1{id}.json/put
+ */
+export interface PostUpdateResponse {
+ post: PostUpdateItem;
+}
+export interface PostUpdateItem {
+ actions_summary: Array;
+ admin: boolean;
+ avatar_template: string;
+ avg_time: object;
+ can_delete: boolean;
+ can_edit: boolean;
+ can_recover: boolean;
+ can_view_edit_history: boolean;
+ can_wiki: boolean;
+ cooked: string;
+ created_at: string;
+ deleted_at: object;
+ display_username: string;
+ draft_sequence: number;
+ edit_reason: object;
+ hidden_reason_id: object;
+ hidden: boolean;
+ id: number;
+ incoming_link_count: number;
+ moderator: boolean;
+ name: string;
+ post_number: number;
+ post_type: number;
+ primary_group_flair_bg_color: object;
+ primary_group_flair_color: object;
+ primary_group_flair_url: object;
+ primary_group_name: object;
+ quote_count: number;
+ reads: number;
+ reply_count: number;
+ reply_to_post_number: object;
+ score: number;
+ staff: boolean;
+ topic_id: number;
+ topic_slug: string;
+ trust_level: number;
+ updated_at: string;
+ user_deleted: boolean;
+ user_id: number;
+ user_title: object;
+ username: string;
+ version: number;
+ wiki: boolean;
+ yours: boolean;
+}
+export interface PostUpdateRequest {
+ post: {
+ raw: string;
+ raw_old?: string;
+ edit_reason?: string;
+ cooked?: string;
+ };
+}
+/** https://docs.discourse.org/#tag/Categories/paths/~1categories.json/get */
+export interface CategoriesResponse {
+ category_list: {
+ can_create_category: boolean;
+ can_create_topic: boolean;
+ categories: Category[];
+ draft_key: string;
+ draft_sequence: number;
+ draft: boolean;
+ };
+}
+export interface Category {
+ background_url: string;
+ can_edit: boolean;
+ color: string;
+ description_excerpt: string;
+ description_text: string;
+ description: string;
+ has_children: boolean;
+ id: number;
+ logo_url: string;
+ name: string;
+ notification_level: string;
+ permission: number;
+ position: number;
+ post_count: number;
+ read_restricted: boolean;
+ slug: string;
+ text_color: string;
+ topic_count: number;
+ topic_template: string;
+ topic_url: string;
+ topics_all_time: number;
+ topics_day: number;
+ topics_month: number;
+ topics_week: number;
+ topics_year: number;
+}
+/**
+ * Get Single Topic
+ * https://docs.discourse.org/#tag/Topics/paths/~1t~1{id}.json/get
+ */
+export interface TopicResponse {
+ actions_summary: Array;
+ archetype: string;
+ archived: boolean;
+ bookmarked: object;
+ category_id: number;
+ chunk_size: number;
+ closed: boolean;
+ created_at: string;
+ deleted_at: object;
+ deleted_by: object;
+ details: TopicDetails;
+ draft_key: string;
+ draft_sequence: object;
+ draft: object;
+ fancy_title: string;
+ has_summary: boolean;
+ highest_post_number: number;
+ id: number;
+ last_posted_at: object;
+ like_count: number;
+ participant_count: number;
+ pinned_at: string;
+ pinned_globally: boolean;
+ pinned_until: object;
+ pinned: boolean;
+ posts_count: number;
+ reply_count: number;
+ slug: string;
+ tags: string[];
+ title: string;
+ unpinned: object;
+ user_id: number;
+ views: number;
+ visible: boolean;
+ word_count: object;
+ post_stream: {
+ posts: Array;
+ stream: Array;
+ };
+ timeline_lookup: [
+ {
+ '0': Array;
+ }
+ ];
+}
+export interface TopicDetails {
+ auto_close_at: object;
+ auto_close_based_on_last_post: boolean;
+ auto_close_hours: object;
+ can_flag_topic: boolean;
+ created_by: Person;
+ last_poster: Person;
+ notification_level: number;
+ participants: Array;
+ suggested_topics: Array;
+}
+export interface TopicItem {
+ archetype: string;
+ archived: boolean;
+ bookmarked: object;
+ bumped_at: string;
+ bumped: boolean;
+ category_id: number;
+ closed: boolean;
+ created_at: string;
+ excerpt: string;
+ fancy_title: string;
+ has_summary: boolean;
+ highest_post_number: number;
+ id: number;
+ image_url: string;
+ last_posted_at: string;
+ last_poster_username: string;
+ like_count: number;
+ liked: object;
+ pinned_globally: boolean;
+ pinned: boolean;
+ posters: Array;
+ posts_count: number;
+ reply_count: number;
+ slug: string;
+ title: string;
+ unpinned: boolean;
+ unseen: boolean;
+ views: number;
+ visible: boolean;
+}
+/**
+ * Get Topics for Category
+ * https://docs.discourse.org/#tag/Categories/paths/~1c~1{id}.json/get
+ */
+export interface CategoryResponse {
+ users: Person[];
+ topic_list: {
+ can_create_topic: boolean;
+ draft: boolean;
+ draft_key: string;
+ draft_sequence: number;
+ per_page: number;
+ topics: Array;
+ };
+}
+/**
+ * Whole Post Information
+ * As returned by getting a single Post
+ * https://docs.discourse.org/#tag/Posts/paths/~1posts~1{id}.json/get
+ */
+export interface PostResponse {
+ actions_summary: Array;
+ admin: boolean;
+ avatar_template: string;
+ avg_time: object;
+ can_delete: boolean;
+ can_edit: boolean;
+ can_recover: boolean;
+ can_view_edit_history: boolean;
+ can_wiki: boolean;
+ cooked: string;
+ created_at: string;
+ deleted_at: object;
+ display_username: string;
+ edit_reason: object;
+ hidden_reason_id: object;
+ hidden: boolean;
+ id: number;
+ incoming_link_count: number;
+ moderator: boolean;
+ name: string;
+ post_number: number;
+ post_type: number;
+ primary_group_flair_bg_color: object;
+ primary_group_flair_color: object;
+ primary_group_flair_url: object;
+ primary_group_name: object;
+ quote_count: number;
+ raw: string;
+ reads: number;
+ reply_count: number;
+ reply_to_post_number: object;
+ score: number;
+ staff: boolean;
+ topic_id: number;
+ topic_slug: string;
+ trust_level: number;
+ updated_at: string;
+ user_deleted: boolean;
+ user_id: number;
+ user_title: object;
+ username: string;
+ version: number;
+ wiki: boolean;
+ yours: boolean;
+}
+/**
+ * Get the Posts of a Topic
+ * https://docs.discourse.org/#tag/Topics/paths/~1t~1{id}~1posts.json/get
+ */
+export interface PostsResponse {
+ post_stream: {
+ posts: Array;
+ };
+ id: number;
+}
+/**
+ * Partial Post Information
+ * As returned by a listing
+ */
+export interface PostItem {
+ accepted_answer: boolean;
+ actions_summary: Array;
+ admin: boolean;
+ avatar_template: string;
+ can_accept_answer: boolean;
+ can_delete: boolean;
+ can_edit: boolean;
+ can_recover: boolean;
+ can_unaccept_answer: boolean;
+ can_view_edit_history: boolean;
+ can_wiki: boolean;
+ cooked: string;
+ created_at: string;
+ deleted_at: null;
+ display_username: string;
+ edit_reason: null;
+ hidden: boolean;
+ id: number;
+ incoming_link_count: number;
+ link_counts: Array ;
+ moderator: boolean;
+ name: string;
+ post_number: number;
+ post_type: number;
+ primary_group_flair_bg_color: null | object;
+ primary_group_flair_color: null | object;
+ primary_group_flair_url: null | object;
+ primary_group_name: null | object;
+ quote_count: number;
+ read: boolean;
+ readers_count: number;
+ reads: number;
+ reply_count: number;
+ reply_to_post_number: null | number;
+ reviewable_id: number;
+ reviewable_score_count: number;
+ reviewable_score_pending_count: number;
+ score: number;
+ staff: boolean;
+ topic_id: number;
+ topic_slug: string;
+ trust_level: number;
+ updated_at: string;
+ user_deleted: boolean;
+ user_id: number;
+ user_title: null | object;
+ username: string;
+ version: number;
+ wiki: boolean;
+ yours: boolean;
+}
diff --git a/packages/discourse/lib/discourse/types/discourse.js b/packages/discourse/lib/discourse/types/discourse.js
new file mode 100644
index 00000000..5e8d99f7
--- /dev/null
+++ b/packages/discourse/lib/discourse/types/discourse.js
@@ -0,0 +1,5 @@
+"use strict";
+// Attempt at TypeScript Types for the Discourse API
+// https://docs.discourse.org
+Object.defineProperty(exports, "__esModule", { value: true });
+//# sourceMappingURL=discourse.js.map
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/types/discourse.js.map b/packages/discourse/lib/discourse/types/discourse.js.map
new file mode 100644
index 00000000..422d97b1
--- /dev/null
+++ b/packages/discourse/lib/discourse/types/discourse.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"discourse.js","sourceRoot":"","sources":["../../../src/lib/discourse/types/discourse.ts"],"names":[],"mappings":";AAAA,oDAAoD;AACpD,6BAA6B"}
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/util.d.ts b/packages/discourse/lib/discourse/util.d.ts
new file mode 100644
index 00000000..8c80c60c
--- /dev/null
+++ b/packages/discourse/lib/discourse/util.d.ts
@@ -0,0 +1,26 @@
+import { Discourser } from './index';
+export declare const uploadFile: (discourse: any, forum: any, name: any, filePath: any) => Promise;
+export declare const findReplyPage: (b: any, pages: any) => any;
+export declare const findReplyUpload: (u: any, page: any) => any;
+export declare const getPages: (topics: any, topic: any) => any;
+export declare const getReplies: (topics: any, topic: any) => any[];
+export declare const findFile: (folder: any, filename: any) => any;
+export declare const topicFolder: (forum: any, folder: any, title: any) => string;
+export declare const dOptions: {
+ host: string;
+ key: string;
+ username: string;
+ rateLimitConcurrency: number;
+};
+export declare const getFUser: (users: any, user_name: any) => any;
+export declare const getOAvatar: (index: any, user: any) => any;
+export declare const getTopics: (index: any) => any[];
+export declare const convert: (input: string) => any;
+export declare const getDiscourse: () => Discourser;
+export declare function inspect(arg: any): string;
+export declare function log(...args: any[]): void;
+export declare function mkdirp(path: string): Promise;
+export declare function readJSON(path: string): Promise;
+export declare function writeJSON(path: string, data: object): Promise;
+export declare function exists(path: string): Promise;
+export declare function escape(path: string): string;
diff --git a/packages/discourse/lib/discourse/util.js b/packages/discourse/lib/discourse/util.js
new file mode 100644
index 00000000..f55ce447
--- /dev/null
+++ b/packages/discourse/lib/discourse/util.js
@@ -0,0 +1,184 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.escape = exports.exists = exports.writeJSON = exports.readJSON = exports.mkdirp = exports.log = exports.inspect = exports.getDiscourse = exports.convert = exports.getTopics = exports.getOAvatar = exports.getFUser = exports.dOptions = exports.topicFolder = exports.findFile = exports.getReplies = exports.getPages = exports.findReplyUpload = exports.findReplyPage = exports.uploadFile = void 0;
+const fs_1 = require("fs");
+const util_1 = require("util");
+const cwd = process.cwd();
+var TurndownService = require('turndown');
+const index_1 = require("./index");
+const path = require("path");
+const fg = require('fast-glob');
+const slugify_1 = require("slugify");
+var sanitize = require("sanitize-filename");
+var mom = require('moment');
+const uploadFile = (discourse, forum, name, filePath) => __awaiter(void 0, void 0, void 0, function* () {
+ return yield discourse.upload(1, filePath);
+});
+exports.uploadFile = uploadFile;
+const findReplyPage = (b, pages) => {
+ return pages.find((p) => {
+ return p.replies.find((r) => {
+ return r.replyBody == b;
+ });
+ });
+};
+exports.findReplyPage = findReplyPage;
+const findReplyUpload = (u, page) => {
+ const f_pics = page.f_pics || [];
+ return f_pics.find((p) => {
+ return p.url === u;
+ });
+};
+exports.findReplyUpload = findReplyUpload;
+const getPages = (topics, topic) => {
+ return topics.filter((t) => {
+ return t.title == topic.title;
+ });
+};
+exports.getPages = getPages;
+const getReplies = (topics, topic) => {
+ if (topic.nextPages) {
+ const all = topics.filter((t) => {
+ return t.title == topic.title;
+ });
+ let replies = all.map((t) => t.replies);
+ replies = [].concat.apply([], replies);
+ replies = replies.sort((a, b) => {
+ const d1 = mom(a.replyDate, 'DD/MM/YYYY AT HH:mm').toDate();
+ const d2 = mom(b.replyDate, 'DD/MM/YYYY AT HH:mm').toDate();
+ return new Date(d1).getTime() > new Date(d2).getTime() ? 1 : -1;
+ });
+ return replies;
+ /*
+ const findReply = (b, pages) => {
+ return pages.find((p) => {
+ return p.replies.find((r) => {
+ return r.replyBody == b;
+ })
+ })
+ }
+ const p = findReply('\n\n\nsounds great, let me get Old Tony´s Schaeubling 13 and a surface grinder first, after that I can do the parts for the espresso machine in the best maker porn fashion possible, no seriously, every time I thought I know something, there’s just another video around the next corner making me cry like a baby, incl. the coffee machine
\n', all);
+ debugger;
+ */
+ }
+ return [];
+};
+exports.getReplies = getReplies;
+const findFile = (folder, filename) => {
+ const files = fg.sync('**/**/*' + filename + '*', { dot: true, cwd: folder, absolute: true });
+ if (files.length == 0) {
+ return false;
+ }
+ return files[0];
+};
+exports.findFile = findFile;
+const topicFolder = (forum, folder, title) => {
+ const _title = sanitize((0, slugify_1.default)(title));
+ const tf = path.resolve(forum + '/' + folder + '/' + _title);
+ return tf;
+};
+exports.topicFolder = topicFolder;
+exports.dOptions = {
+ host: 'https://forum.osr-plastic.org',
+ key: 'f624b8385fb2219cb49de63d1e22883afdf7b7367a0bebf822523f49f2678031',
+ username: 'admin',
+ rateLimitConcurrency: 1
+};
+const getFUser = (users, user_name) => {
+ return users.find((u) => {
+ return u.name == user_name;
+ });
+};
+exports.getFUser = getFUser;
+const getOAvatar = (index, user) => {
+ const topics = (0, exports.getTopics)(index);
+ let topic = topics.find((t) => {
+ return t.authorName == user;
+ });
+ if (topic) {
+ return topic.authorImage;
+ }
+ for (let i = 0; i < topics.length; i++) {
+ const t = topics[i];
+ if (t.replies) {
+ const r = t.replies.find((r) => {
+ return r.user == user;
+ });
+ if (r) {
+ return r.avatar;
+ }
+ }
+ }
+ return null;
+};
+exports.getOAvatar = getOAvatar;
+const getTopics = (index) => {
+ let topics = [];
+ for (let t in index) {
+ topics.push(index[t]);
+ }
+ return topics;
+};
+exports.getTopics = getTopics;
+const convert = (input) => {
+ var turndownService = new TurndownService();
+ return turndownService.turndown(input);
+};
+exports.convert = convert;
+const getDiscourse = () => {
+ return new index_1.Discourser(exports.dOptions);
+};
+exports.getDiscourse = getDiscourse;
+function inspect(arg) {
+ return (0, util_1.inspect)(arg, {
+ depth: 5,
+ colors: true,
+ });
+}
+exports.inspect = inspect;
+function log(...args) {
+ console.log(...args.map((arg) => inspect(arg)));
+}
+exports.log = log;
+function mkdirp(path) {
+ return __awaiter(this, void 0, void 0, function* () {
+ try {
+ yield fs_1.default.promises.mkdir(path);
+ }
+ catch (err) {
+ // don't care if it already exists
+ }
+ });
+}
+exports.mkdirp = mkdirp;
+function readJSON(path) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const text = yield fs_1.default.promises.readFile(path, 'utf8');
+ return JSON.parse(text);
+ });
+}
+exports.readJSON = readJSON;
+function writeJSON(path, data) {
+ return fs_1.default.promises.writeFile(path, JSON.stringify(data));
+}
+exports.writeJSON = writeJSON;
+function exists(path) {
+ return new Promise(function (resolve) {
+ fs_1.default.exists(path, resolve);
+ });
+}
+exports.exists = exists;
+function escape(path) {
+ return path.replace(/[^\w]/g, '-').replace(/-+/, '-');
+}
+exports.escape = escape;
+//# sourceMappingURL=util.js.map
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/util.js.map b/packages/discourse/lib/discourse/util.js.map
new file mode 100644
index 00000000..72ea9c72
--- /dev/null
+++ b/packages/discourse/lib/discourse/util.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/lib/discourse/util.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2BAAmB;AACnB,+BAA6C;AAE7C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;AACzB,IAAI,eAAe,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAC1C,mCAAqC;AAGrC,6BAA6B;AAC7B,MAAM,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAChC,qCAA8B;AAC9B,IAAI,QAAQ,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;AAI5C,IAAI,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AACrB,MAAM,UAAU,GAAG,CAAO,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;IACpE,OAAO,MAAM,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC5C,CAAC,CAAA,CAAA;AAFY,QAAA,UAAU,cAEtB;AAEM,MAAM,aAAa,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;IACzC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QACvB,OAAO,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;YAC3B,OAAO,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC;QACzB,CAAC,CAAC,CAAA;IACH,CAAC,CAAC,CAAA;AACH,CAAC,CAAA;AANY,QAAA,aAAa,iBAMzB;AAEM,MAAM,eAAe,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;IACjC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QACxB,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;IACpB,CAAC,CAAC,CAAA;AACH,CAAC,CAAA;AALY,QAAA,eAAe,mBAK3B;AAEM,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;IACzC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC1B,OAAO,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC;IAC/B,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC;AAJW,QAAA,QAAQ,YAInB;AAEK,MAAM,UAAU,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;IAC3C,IAAI,KAAK,CAAC,SAAS,EAAE;QACpB,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YAC/B,OAAO,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC;QAC/B,CAAC,CAAC,CAAC;QACH,IAAI,OAAO,GAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC5C,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;QACvC,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAM,EAAE,CAAM,EAAE,EAAE;YACzC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,EAAC,qBAAqB,CAAC,CAAC,MAAM,EAAE,CAAA;YAC1D,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,EAAC,qBAAqB,CAAC,CAAC,MAAM,EAAE,CAAA;YAC1D,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,OAAO,OAAO,CAAC;QACf;;;;;;;;;;UAUE;KACF;IACD,OAAO,EAAE,CAAC;AACX,CAAC,CAAA;AA3BY,QAAA,UAAU,cA2BtB;AAEM,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;IAC5C,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,GAAG,QAAQ,GAAG,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9F,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,EAAE;QACtB,OAAO,KAAK,CAAC;KAEb;IACD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAA;AAPY,QAAA,QAAQ,YAOpB;AAEM,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;IACnD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAA,iBAAO,EAAC,KAAK,CAAC,CAAC,CAAC;IACxC,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,GAAG,GAAG,GAAG,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,CAAC;IAC7D,OAAO,EAAE,CAAC;AACX,CAAC,CAAA;AAJY,QAAA,WAAW,eAIvB;AAEY,QAAA,QAAQ,GAAG;IACvB,IAAI,EAAE,+BAA+B;IACrC,GAAG,EAAE,kEAAkE;IACvE,QAAQ,EAAE,OAAO;IACjB,oBAAoB,EAAE,CAAC;CACvB,CAAA;AACM,MAAM,QAAQ,GAAG,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;IAC5C,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QACvB,OAAO,CAAC,CAAC,IAAI,IAAI,SAAS,CAAA;IAC3B,CAAC,CAAC,CAAA;AACH,CAAC,CAAA;AAJY,QAAA,QAAQ,YAIpB;AAEM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACzC,MAAM,MAAM,GAAG,IAAA,iBAAS,EAAC,KAAK,CAAC,CAAC;IAChC,IAAI,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;QAC7B,OAAO,CAAC,CAAC,UAAU,IAAI,IAAI,CAAC;IAC7B,CAAC,CAAC,CAAC;IACH,IAAI,KAAK,EAAE;QACV,OAAO,KAAK,CAAC,WAAW,CAAC;KACzB;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACvC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,CAAC,CAAC,OAAO,EAAE;YACd,MAAM,CAAC,GAAI,CAAC,CAAC,OAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE;gBACzC,OAAO,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC;YACvB,CAAC,CAAC,CAAA;YACF,IAAI,CAAC,EAAE;gBACN,OAAO,CAAC,CAAC,MAAM,CAAC;aAChB;SACD;KACD;IACD,OAAO,IAAI,CAAC;AACb,CAAC,CAAA;AApBY,QAAA,UAAU,cAoBtB;AAEM,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,EAAE;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,IAAI,KAAK,EAAE;QACpB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;KACtB;IACD,OAAO,MAAM,CAAC;AACf,CAAC,CAAA;AANY,QAAA,SAAS,aAMrB;AAEM,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,EAAE;IACxC,IAAI,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;IAC3C,OAAO,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACxC,CAAC,CAAA;AAHY,QAAA,OAAO,WAGnB;AAEM,MAAM,YAAY,GAAG,GAAG,EAAE;IAChC,OAAO,IAAI,kBAAU,CAAC,gBAAQ,CAAC,CAAC;AACjC,CAAC,CAAA;AAFY,QAAA,YAAY,gBAExB;AAED,SAAgB,OAAO,CAAC,GAAQ;IAC/B,OAAO,IAAA,cAAW,EAAC,GAAG,EAAE;QACvB,KAAK,EAAE,CAAC;QACR,MAAM,EAAE,IAAI;KACZ,CAAC,CAAA;AACH,CAAC;AALD,0BAKC;AAED,SAAgB,GAAG,CAAC,GAAG,IAAW;IACjC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;AAChD,CAAC;AAFD,kBAEC;AAED,SAAsB,MAAM,CAAC,IAAY;;QACxC,IAAI;YACH,MAAM,YAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;SAC7B;QAAC,OAAO,GAAG,EAAE;YACb,kCAAkC;SAClC;IACF,CAAC;CAAA;AAND,wBAMC;AAED,SAAsB,QAAQ,CAAmB,IAAY;;QAC5D,MAAM,IAAI,GAAG,MAAM,YAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QACrD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACxB,CAAC;CAAA;AAHD,4BAGC;AAED,SAAgB,SAAS,CAAC,IAAY,EAAE,IAAY;IACnD,OAAO,YAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAA;AACzD,CAAC;AAFD,8BAEC;AAED,SAAgB,MAAM,CAAC,IAAY;IAClC,OAAO,IAAI,OAAO,CAAC,UAAU,OAAO;QACnC,YAAE,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;AACH,CAAC;AAJD,wBAIC;AAED,SAAgB,MAAM,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;AACtD,CAAC;AAFD,wBAEC"}
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/youtube.d.ts b/packages/discourse/lib/discourse/youtube.d.ts
new file mode 100644
index 00000000..305ab150
--- /dev/null
+++ b/packages/discourse/lib/discourse/youtube.d.ts
@@ -0,0 +1,260 @@
+export declare function getYoutubeVideo(videoID: string): Promise;
+export interface YoutubeVideoData {
+ playabilityStatus: PlayabilityStatus;
+ streamingData: StreamingData;
+ playbackTracking: PlaybackTracking;
+ captions: Captions;
+ videoDetails: VideoDetails;
+ playerConfig: PlayerConfig;
+ storyboards: Storyboards;
+ microformat: Microformat;
+ trackingParams: string;
+ attestation: Attestation;
+ videoQualityPromoSupportedRenderers: VideoQualityPromoSupportedRenderers;
+}
+export interface Attestation {
+ playerAttestationRenderer: PlayerAttestationRenderer;
+}
+export interface PlayerAttestationRenderer {
+ challenge: string;
+ botguardData: BotguardData;
+}
+export interface BotguardData {
+ program: string;
+ interpreterUrl: string;
+}
+export interface Captions {
+ playerCaptionsRenderer: PlayerCaptionsRenderer;
+ playerCaptionsTracklistRenderer: PlayerCaptionsTracklistRenderer;
+}
+export interface PlayerCaptionsRenderer {
+ baseUrl: string;
+ visibility: string;
+ contribute: Contribute;
+}
+export interface Contribute {
+ captionsMetadataRenderer: CaptionsMetadataRenderer;
+}
+export interface CaptionsMetadataRenderer {
+ addSubtitlesText: AddSubtitlesText;
+ noSubtitlesText: Description;
+ promoSubtitlesText: Description;
+}
+export interface AddSubtitlesText {
+ runs: AddSubtitlesTextRun[];
+}
+export interface AddSubtitlesTextRun {
+ text: string;
+ navigationEndpoint: NavigationEndpoint;
+}
+export interface NavigationEndpoint {
+ clickTrackingParams: string;
+ urlEndpoint: NavigationEndpointURLEndpoint;
+}
+export interface NavigationEndpointURLEndpoint {
+ url: string;
+}
+export interface Description {
+ simpleText: string;
+}
+export interface PlayerCaptionsTracklistRenderer {
+ captionTracks: CaptionTrack[];
+ audioTracks: AudioTrack[];
+ translationLanguages: TranslationLanguage[];
+ defaultAudioTrackIndex: number;
+ contribute: Contribute;
+}
+export interface AudioTrack {
+ captionTrackIndices: number[];
+}
+export interface CaptionTrack {
+ baseUrl: string;
+ name: Description;
+ vssId: string;
+ languageCode: string;
+ kind: string;
+ isTranslatable: boolean;
+}
+export interface TranslationLanguage {
+ languageCode: string;
+ languageName: Description;
+}
+export interface Microformat {
+ playerMicroformatRenderer: PlayerMicroformatRenderer;
+}
+export interface PlayerMicroformatRenderer {
+ thumbnail: PlayerMicroformatRendererThumbnail;
+ embed: Embed;
+ title: Description;
+ description: Description;
+ lengthSeconds: string;
+ ownerProfileUrl: string;
+ externalChannelId: string;
+ availableCountries: string[];
+ isUnlisted: boolean;
+ hasYpcMetadata: boolean;
+ viewCount: string;
+ category: string;
+ publishDate: Date;
+ ownerChannelName: string;
+ uploadDate: Date;
+}
+export interface Embed {
+ iframeUrl: string;
+ flashUrl: string;
+ width: number;
+ height: number;
+ flashSecureUrl: string;
+}
+export interface PlayerMicroformatRendererThumbnail {
+ thumbnails: ThumbnailElement[];
+}
+export interface ThumbnailElement {
+ url: string;
+ width: number;
+ height: number;
+}
+export interface PlayabilityStatus {
+ status: string;
+ playableInEmbed: boolean;
+ contextParams: string;
+}
+export interface PlaybackTracking {
+ videostatsPlaybackUrl: PtrackingURLClass;
+ videostatsDelayplayUrl: PtrackingURLClass;
+ videostatsWatchtimeUrl: PtrackingURLClass;
+ ptrackingUrl: PtrackingURLClass;
+ qoeUrl: PtrackingURLClass;
+ setAwesomeUrl: AtrURLClass;
+ atrUrl: AtrURLClass;
+}
+export interface AtrURLClass {
+ baseUrl: string;
+ elapsedMediaTimeSeconds: number;
+}
+export interface PtrackingURLClass {
+ baseUrl: string;
+}
+export interface PlayerConfig {
+ audioConfig: AudioConfig;
+ streamSelectionConfig: StreamSelectionConfig;
+ mediaCommonConfig: MediaCommonConfig;
+}
+export interface AudioConfig {
+ loudnessDb: number;
+ perceptualLoudnessDb: number;
+ enablePerFormatLoudness: boolean;
+}
+export interface MediaCommonConfig {
+ dynamicReadaheadConfig: DynamicReadaheadConfig;
+}
+export interface DynamicReadaheadConfig {
+ maxReadAheadMediaTimeMs: number;
+ minReadAheadMediaTimeMs: number;
+ readAheadGrowthRateMs: number;
+}
+export interface StreamSelectionConfig {
+ maxBitrate: string;
+}
+export interface Storyboards {
+ playerStoryboardSpecRenderer: PlayerStoryboardSpecRenderer;
+}
+export interface PlayerStoryboardSpecRenderer {
+ spec: string;
+}
+export interface StreamingData {
+ expiresInSeconds: string;
+ formats: Format[];
+ adaptiveFormats: Format[];
+}
+export interface Format {
+ itag: number;
+ url: string;
+ mimeType: string;
+ bitrate: number;
+ width?: number;
+ height?: number;
+ initRange?: Range;
+ indexRange?: Range;
+ lastModified: string;
+ contentLength?: string;
+ quality: string;
+ fps?: number;
+ qualityLabel?: string;
+ projectionType: ProjectionType;
+ averageBitrate?: number;
+ approxDurationMs: string;
+ colorInfo?: ColorInfo;
+ highReplication?: boolean;
+ audioQuality?: string;
+ audioSampleRate?: string;
+ audioChannels?: number;
+}
+export interface ColorInfo {
+ primaries: string;
+ transferCharacteristics: string;
+ matrixCoefficients: string;
+}
+export interface Range {
+ start: string;
+ end: string;
+}
+export declare enum ProjectionType {
+ Rectangular = "RECTANGULAR"
+}
+export interface VideoDetails {
+ videoId: string;
+ title: string;
+ lengthSeconds: string;
+ keywords: string[];
+ channelId: string;
+ isOwnerViewing: boolean;
+ shortDescription: string;
+ isCrawlable: boolean;
+ thumbnail: PlayerMicroformatRendererThumbnail;
+ averageRating: number;
+ allowRatings: boolean;
+ viewCount: string;
+ author: string;
+ isPrivate: boolean;
+ isUnpluggedCorpus: boolean;
+ isLiveContent: boolean;
+}
+export interface VideoQualityPromoSupportedRenderers {
+ videoQualityPromoRenderer: VideoQualityPromoRenderer;
+}
+export interface VideoQualityPromoRenderer {
+ triggerCriteria: TriggerCriteria;
+ text: Text;
+ endpoint: Endpoint;
+ trackingParams: string;
+ closeButton: CloseButton;
+}
+export interface CloseButton {
+ videoQualityPromoCloseRenderer: VideoQualityPromoCloseRenderer;
+}
+export interface VideoQualityPromoCloseRenderer {
+ trackingParams: string;
+}
+export interface Endpoint {
+ clickTrackingParams: string;
+ urlEndpoint: EndpointURLEndpoint;
+}
+export interface EndpointURLEndpoint {
+ url: string;
+ target: string;
+}
+export interface Text {
+ runs: TextRun[];
+}
+export interface TextRun {
+ text: string;
+ bold?: boolean;
+}
+export interface TriggerCriteria {
+ connectionWhitelists: string[];
+ joinLatencySeconds: number;
+ rebufferTimeSeconds: number;
+ watchTimeWindowSeconds: number;
+ refractorySeconds: number;
+}
diff --git a/packages/discourse/lib/discourse/youtube.js b/packages/discourse/lib/discourse/youtube.js
new file mode 100644
index 00000000..86abe41e
--- /dev/null
+++ b/packages/discourse/lib/discourse/youtube.js
@@ -0,0 +1,30 @@
+"use strict";
+var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
+ return new (P || (P = Promise))(function (resolve, reject) {
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
+ });
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.ProjectionType = exports.getYoutubeVideo = void 0;
+const isomorphic_unfetch_1 = require("isomorphic-unfetch");
+function getYoutubeVideo(videoID) {
+ return __awaiter(this, void 0, void 0, function* () {
+ const eurl = `https://youtube.googleapis.com/v/${videoID}`;
+ const response = yield (0, isomorphic_unfetch_1.default)(`https://www.youtube.com/get_video_info?video_id=${videoID}&el=embedded&eurl=${eurl}&sts=18333`);
+ const text = yield response.text();
+ const params = new URLSearchParams(text);
+ //const data = JSON.parse(Object.fromEntries(params).player_response)
+ // return data as YoutubeVideoData
+ return {};
+ });
+}
+exports.getYoutubeVideo = getYoutubeVideo;
+var ProjectionType;
+(function (ProjectionType) {
+ ProjectionType["Rectangular"] = "RECTANGULAR";
+})(ProjectionType = exports.ProjectionType || (exports.ProjectionType = {}));
+//# sourceMappingURL=youtube.js.map
\ No newline at end of file
diff --git a/packages/discourse/lib/discourse/youtube.js.map b/packages/discourse/lib/discourse/youtube.js.map
new file mode 100644
index 00000000..3edc47f0
--- /dev/null
+++ b/packages/discourse/lib/discourse/youtube.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"youtube.js","sourceRoot":"","sources":["../../src/lib/discourse/youtube.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2DAAsC;AAEtC,SAAsB,eAAe,CACpC,OAAe;;QAEf,MAAM,IAAI,GAAG,oCAAoC,OAAO,EAAE,CAAA;QAC1D,MAAM,QAAQ,GAAG,MAAM,IAAA,4BAAK,EAC3B,mDAAmD,OAAO,qBAAqB,IAAI,YAAY,CAC/F,CAAA;QACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAClC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAA;QACxC,qEAAqE;QACrE,kCAAkC;QAClC,OAAO,EAAsB,CAAC;IAC/B,CAAC;CAAA;AAZD,0CAYC;AAiPD,IAAY,cAEX;AAFD,WAAY,cAAc;IACzB,6CAA2B,CAAA;AAC5B,CAAC,EAFW,cAAc,GAAd,sBAAc,KAAd,sBAAc,QAEzB"}
\ No newline at end of file
diff --git a/packages/discourse/lib/git/index.d.ts b/packages/discourse/lib/git/index.d.ts
new file mode 100644
index 00000000..3dd29ec2
--- /dev/null
+++ b/packages/discourse/lib/git/index.d.ts
@@ -0,0 +1,5 @@
+export declare function git_status(cwd: any, dir: any): Promise;
+export declare function git_log(cwd: any, dir: any): Promise<{
+ files: any;
+ last: any;
+}>;
diff --git a/packages/discourse/lib/git/index.js b/packages/discourse/lib/git/index.js
new file mode 100644
index 00000000..0e1c2164
--- /dev/null
+++ b/packages/discourse/lib/git/index.js
@@ -0,0 +1,39 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.git_log = exports.git_status = void 0;
+const index_1 = require("../../index");
+const GIT_CHANGELOG_MESSAGE_PREFIX = '';
+const simpleGit = require("simple-git/promise");
+const moment = require("moment");
+async function git_status(cwd, dir) {
+ const git = simpleGit(cwd);
+ let statusSummary = null;
+ try {
+ statusSummary = await git.log(['--stat', dir]);
+ }
+ catch (e) {
+ index_1.logger.error('Error Git', e);
+ }
+ return statusSummary;
+}
+exports.git_status = git_status;
+async function git_log(cwd, dir) {
+ const stats = await git_status(cwd, dir);
+ index_1.logger.info(`Reading Git log at ${cwd}/${dir}`);
+ let changelogs = stats.all.filter((e) => e.message.trim().toLowerCase().startsWith(GIT_CHANGELOG_MESSAGE_PREFIX.toLowerCase()));
+ if (!changelogs.length) {
+ return { files: [], last: stats.latest };
+ }
+ let pretty = changelogs.map((e) => {
+ return {
+ files: e.diff.files.map((f) => { return { path: f.file }; }),
+ msg: e.message.toLowerCase().replace(GIT_CHANGELOG_MESSAGE_PREFIX.toLowerCase(), '').trim(),
+ hash: e.hash,
+ date: moment(e.date).format('LLLL')
+ };
+ });
+ return { files: pretty, last: stats.latest };
+}
+exports.git_log = git_log;
+;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL2dpdC9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSx1Q0FBa0M7QUFFbEMsTUFBTSw0QkFBNEIsR0FBRyxFQUFFLENBQUE7QUFJdkMsZ0RBQWdEO0FBRWhELGlDQUFpQztBQUUxQixLQUFLLFVBQVUsVUFBVSxDQUFDLEdBQUcsRUFBRSxHQUFHO0lBRXJDLE1BQU0sR0FBRyxHQUFjLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN0QyxJQUFJLGFBQWEsR0FBTyxJQUFJLENBQUM7SUFDN0IsSUFBSTtRQUNBLGFBQWEsR0FBRyxNQUFNLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztLQUNsRDtJQUNELE9BQU8sQ0FBQyxFQUFFO1FBQ04sY0FBTSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDLENBQUM7S0FDaEM7SUFDRCxPQUFPLGFBQWEsQ0FBQztBQUN6QixDQUFDO0FBWEQsZ0NBV0M7QUFFTSxLQUFLLFVBQVUsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHO0lBQ2xDLE1BQU0sS0FBSyxHQUFHLE1BQU0sVUFBVSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUN6QyxjQUFNLENBQUMsSUFBSSxDQUFDLHNCQUFzQixHQUFHLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNoRCxJQUFJLFVBQVUsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxVQUFVLENBQUMsNEJBQTRCLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2hJLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFO1FBQ3BCLE9BQU8sRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUE7S0FDMUM7SUFDRCxJQUFJLE1BQU0sR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7UUFDOUIsT0FBTztZQUNILEtBQUssRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFBLENBQUMsQ0FBQyxDQUFDO1lBQzNELEdBQUcsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyw0QkFBNEIsQ0FBQyxXQUFXLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLEVBQUU7WUFDM0YsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJO1lBQ1osSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztTQUN0QyxDQUFBO0lBQ0wsQ0FBQyxDQUFDLENBQUM7SUFFSCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO0FBQ2pELENBQUM7QUFqQkQsMEJBaUJDO0FBQUEsQ0FBQyJ9
\ No newline at end of file
diff --git a/packages/discourse/lib/index.d.ts b/packages/discourse/lib/index.d.ts
new file mode 100644
index 00000000..f34b2558
--- /dev/null
+++ b/packages/discourse/lib/index.d.ts
@@ -0,0 +1,2 @@
+export * from './discourse';
+export * from './discourse/types';
diff --git a/packages/discourse/lib/index.js b/packages/discourse/lib/index.js
new file mode 100644
index 00000000..c0b519a1
--- /dev/null
+++ b/packages/discourse/lib/index.js
@@ -0,0 +1,19 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./discourse"), exports);
+__exportStar(require("./discourse/types"), exports);
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvbGliL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSw4Q0FBMkI7QUFDM0Isb0RBQWlDIn0=
\ No newline at end of file
diff --git a/packages/discourse/lib/index.js.map b/packages/discourse/lib/index.js.map
new file mode 100644
index 00000000..a7fb63af
--- /dev/null
+++ b/packages/discourse/lib/index.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/lib/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA2B;AAC3B,oDAAiC"}
\ No newline at end of file
diff --git a/packages/discourse/lib/markdown/Pattern.d.ts b/packages/discourse/lib/markdown/Pattern.d.ts
new file mode 100644
index 00000000..dd02b1a1
--- /dev/null
+++ b/packages/discourse/lib/markdown/Pattern.d.ts
@@ -0,0 +1,7 @@
+import { RegExCallback } from './types';
+export declare class Pattern {
+ regex: RegExp;
+ replacement: RegExCallback;
+ constructor(regex: RegExp, replacement: any);
+ apply(raw: string): string;
+}
diff --git a/packages/discourse/lib/markdown/Pattern.js b/packages/discourse/lib/markdown/Pattern.js
new file mode 100644
index 00000000..09ca45bf
--- /dev/null
+++ b/packages/discourse/lib/markdown/Pattern.js
@@ -0,0 +1,14 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Pattern = void 0;
+class Pattern {
+ constructor(regex, replacement) {
+ this.regex = regex;
+ this.replacement = replacement;
+ }
+ apply(raw) {
+ return raw.replace(this.regex, this.replacement);
+ }
+}
+exports.Pattern = Pattern;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGF0dGVybi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvbWFya2Rvd24vUGF0dGVybi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxNQUFhLE9BQU87SUFHbEIsWUFBWSxLQUFhLEVBQUUsV0FBZ0I7UUFDekMsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUE7UUFDbEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxXQUFXLENBQUE7SUFDaEMsQ0FBQztJQUVELEtBQUssQ0FBQyxHQUFXO1FBQ2YsT0FBTyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFBO0lBQ2xELENBQUM7Q0FDRjtBQVhELDBCQVdDIn0=
\ No newline at end of file
diff --git a/packages/discourse/lib/markdown/Rule.d.ts b/packages/discourse/lib/markdown/Rule.d.ts
new file mode 100644
index 00000000..f19edcd8
--- /dev/null
+++ b/packages/discourse/lib/markdown/Rule.d.ts
@@ -0,0 +1,7 @@
+import { Pattern } from './Pattern';
+export declare class Rule {
+ name: string;
+ patterns: Pattern[];
+ constructor(name: string, patterns: Pattern[]);
+ apply(raw: string): string;
+}
diff --git a/packages/discourse/lib/markdown/Rule.js b/packages/discourse/lib/markdown/Rule.js
new file mode 100644
index 00000000..9d6b927a
--- /dev/null
+++ b/packages/discourse/lib/markdown/Rule.js
@@ -0,0 +1,14 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.Rule = void 0;
+class Rule {
+ constructor(name, patterns) {
+ this.name = name;
+ this.patterns = patterns;
+ }
+ apply(raw) {
+ return this.patterns.reduce((result, pattern) => pattern.apply(result), raw);
+ }
+}
+exports.Rule = Rule;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUnVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvbWFya2Rvd24vUnVsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxNQUFhLElBQUk7SUFHZixZQUFZLElBQVksRUFBRSxRQUFtQjtRQUMzQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUNqQixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztJQUMzQixDQUFDO0lBRUQsS0FBSyxDQUFDLEdBQVc7UUFDZixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUN6QixDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLEVBQzFDLEdBQUcsQ0FDSixDQUFDO0lBQ0osQ0FBQztDQUNGO0FBZEQsb0JBY0MifQ==
\ No newline at end of file
diff --git a/packages/discourse/lib/markdown/index.d.ts b/packages/discourse/lib/markdown/index.d.ts
new file mode 100644
index 00000000..32743bb1
--- /dev/null
+++ b/packages/discourse/lib/markdown/index.d.ts
@@ -0,0 +1,14 @@
+import { Rule } from './Rule';
+import { RMarkOptions } from './types';
+export declare const RE_IMAGES: RegExp;
+export declare const RE_LINKS: RegExp;
+export declare class RMark {
+ constructor(options: RMarkOptions);
+ private rules;
+ addRuleBefore(rule: Rule, before: string): RMark;
+ addRule(rule: Rule): RMark;
+ render(raw: string): string;
+}
+export { Rule } from './Rule';
+export { Pattern } from './Pattern';
+export declare const toHTML: (content: any) => string;
diff --git a/packages/discourse/lib/markdown/index.js b/packages/discourse/lib/markdown/index.js
new file mode 100644
index 00000000..ac075114
--- /dev/null
+++ b/packages/discourse/lib/markdown/index.js
@@ -0,0 +1,104 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.toHTML = exports.Pattern = exports.Rule = exports.RMark = exports.RE_LINKS = exports.RE_IMAGES = void 0;
+const Rule_1 = require("./Rule");
+const Pattern_1 = require("./Pattern");
+exports.RE_IMAGES = /\!\[([^\]]+)\]\((\S+)\)/g;
+exports.RE_LINKS = /\[([^\n]+)\]\(([^\n]+)\)/g;
+const markdown = require("markdown-it");
+const defaultRules = [
+ new Rule_1.Rule('header', [
+ new Pattern_1.Pattern(/^#{6}\s?([^\n]+)/gm, '$1 '),
+ new Pattern_1.Pattern(/^#{5}\s?([^\n]+)/gm, '$1 '),
+ new Pattern_1.Pattern(/^#{4}\s?([^\n]+)/gm, '$1 '),
+ new Pattern_1.Pattern(/^#{3}\s?([^\n]+)/gm, '$1 '),
+ new Pattern_1.Pattern(/^#{2}\s?([^\n]+)/gm, '$1 '),
+ new Pattern_1.Pattern(/^#{1}\s?([^\n]+)/gm, '$1 '),
+ ]),
+ new Rule_1.Rule('bold', [
+ new Pattern_1.Pattern(/\*\*\s?([^\n]+)\*\*/g, '$1 '),
+ new Pattern_1.Pattern(/\_\_\s?([^\n]+)\_\_/g, '$1 '),
+ ]),
+ new Rule_1.Rule('italic', [
+ new Pattern_1.Pattern(/\*\s?([^\n]+)\*/g, '$1 '),
+ new Pattern_1.Pattern(/\_\s?([^\n]+)\_/g, '$1 '),
+ ]),
+ new Rule_1.Rule('image', [
+ new Pattern_1.Pattern(/\!\[([^\]]+)\]\((\S+)\)/g, ' '),
+ ]),
+ new Rule_1.Rule('link', [
+ new Pattern_1.Pattern(/\[([^\n]+)\]\(([^\n]+)\)/g, '$1 '),
+ ]),
+ new Rule_1.Rule('paragraph', [
+ // this regex can't skip processed HTML
+ new Pattern_1.Pattern(/([^\n]+\n?)/g, '\n$1
\n'),
+ // another possible regex that can't skip processed HTML
+ // new Pattern(/(?:^|\n)([^\n\<]+(?:\n[^\n\>]+)*)(?:\n|$)/gm, '\n$1
\n'),
+ ])
+];
+const defaultRulesDiscourse = (images, links) => {
+ return [
+ new Rule_1.Rule('image', [
+ new Pattern_1.Pattern(exports.RE_LINKS, images)
+ ]) /*,
+ new Rule('link', [
+ new Pattern(
+ RE_LINKS,
+ links
+ )
+ ])*/
+ ];
+};
+class RMark {
+ constructor(options) {
+ this.rules = defaultRulesDiscourse(options.images, options.links);
+ }
+ addRuleBefore(rule, before) {
+ const index = this.rules.findIndex((r) => r.name === before);
+ if (index !== -1) {
+ this.rules.splice(index, 0, rule);
+ }
+ return this;
+ }
+ addRule(rule) {
+ this.addRuleBefore(rule, 'paragraph');
+ return this;
+ }
+ render(raw) {
+ let result = raw;
+ this.rules.forEach((rule) => {
+ result = rule.apply(result);
+ });
+ return result;
+ }
+}
+exports.RMark = RMark;
+var Rule_2 = require("./Rule");
+Object.defineProperty(exports, "Rule", { enumerable: true, get: function () { return Rule_2.Rule; } });
+var Pattern_2 = require("./Pattern");
+Object.defineProperty(exports, "Pattern", { enumerable: true, get: function () { return Pattern_2.Pattern; } });
+// export const find = (content:string, reg:RegExp) => content.match(reg)
+const toHTML = (content) => {
+ const md = new markdown({
+ html: true,
+ breaks: true
+ });
+ return md.render(content);
+};
+exports.toHTML = toHTML;
+function image_urls(input) {
+ const regex = /https?:\/\/(?:[a-z0-9\-]+\.)+[a-z]{2,}(?:\/[^\/#\s]*)*\.(?:jpe?g|gif|png|webp)/g;
+ const matches = input.match(regex);
+ return matches || [];
+}
+function image_urls_local(input) {
+ const regex = /\/(?:[^\/#\s]+\/)*[^\/#\s]+\.(?:jpe?g|gif|png|webp)/g;
+ const matches = input.match(regex);
+ return matches || [];
+}
+function findUploadImageUrls(input) {
+ const regex = /upload:\/\/[^\s]+?\.(?:jpe?g|gif|png)/gi;
+ const matches = input.match(regex);
+ return matches || [];
+}
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL21hcmtkb3duL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLGlDQUE2QjtBQUM3Qix1Q0FBbUM7QUFJdEIsUUFBQSxTQUFTLEdBQVcsMEJBQTBCLENBQUE7QUFDOUMsUUFBQSxRQUFRLEdBQVcsMkJBQTJCLENBQUE7QUFFM0Qsd0NBQXVDO0FBSXZDLE1BQU0sWUFBWSxHQUFXO0lBQzNCLElBQUksV0FBSSxDQUFDLFFBQVEsRUFBRTtRQUNqQixJQUFJLGlCQUFPLENBQUMsb0JBQW9CLEVBQUUsYUFBYSxDQUFDO1FBQ2hELElBQUksaUJBQU8sQ0FBQyxvQkFBb0IsRUFBRSxhQUFhLENBQUM7UUFDaEQsSUFBSSxpQkFBTyxDQUFDLG9CQUFvQixFQUFFLGFBQWEsQ0FBQztRQUNoRCxJQUFJLGlCQUFPLENBQUMsb0JBQW9CLEVBQUUsYUFBYSxDQUFDO1FBQ2hELElBQUksaUJBQU8sQ0FBQyxvQkFBb0IsRUFBRSxhQUFhLENBQUM7UUFDaEQsSUFBSSxpQkFBTyxDQUFDLG9CQUFvQixFQUFFLGFBQWEsQ0FBQztLQUNqRCxDQUFDO0lBQ0YsSUFBSSxXQUFJLENBQUMsTUFBTSxFQUFFO1FBQ2YsSUFBSSxpQkFBTyxDQUFDLHNCQUFzQixFQUFFLFdBQVcsQ0FBQztRQUNoRCxJQUFJLGlCQUFPLENBQUMsc0JBQXNCLEVBQUUsV0FBVyxDQUFDO0tBQ2pELENBQUM7SUFDRixJQUFJLFdBQUksQ0FBQyxRQUFRLEVBQUU7UUFDakIsSUFBSSxpQkFBTyxDQUFDLGtCQUFrQixFQUFFLFdBQVcsQ0FBQztRQUM1QyxJQUFJLGlCQUFPLENBQUMsa0JBQWtCLEVBQUUsV0FBVyxDQUFDO0tBQzdDLENBQUM7SUFDRixJQUFJLFdBQUksQ0FBQyxPQUFPLEVBQUU7UUFDaEIsSUFBSSxpQkFBTyxDQUFDLDBCQUEwQixFQUFFLDJCQUEyQixDQUFDO0tBQ3JFLENBQUM7SUFDRixJ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
\ No newline at end of file
diff --git a/packages/discourse/lib/markdown/types.d.ts b/packages/discourse/lib/markdown/types.d.ts
new file mode 100644
index 00000000..912a5295
--- /dev/null
+++ b/packages/discourse/lib/markdown/types.d.ts
@@ -0,0 +1,5 @@
+export type RegExCallback = (match: any, capture: any, arg1: any, arg2: any) => string;
+export interface RMarkOptions {
+ images: RegExCallback;
+ links?: RegExCallback;
+}
diff --git a/packages/discourse/lib/markdown/types.js b/packages/discourse/lib/markdown/types.js
new file mode 100644
index 00000000..806a986f
--- /dev/null
+++ b/packages/discourse/lib/markdown/types.js
@@ -0,0 +1,3 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL21hcmtkb3duL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
\ No newline at end of file
diff --git a/packages/discourse/lib/oa/commons.d.ts b/packages/discourse/lib/oa/commons.d.ts
new file mode 100644
index 00000000..45211337
--- /dev/null
+++ b/packages/discourse/lib/oa/commons.d.ts
@@ -0,0 +1,27 @@
+import { IUploadedFileMeta } from '@plastichub/osr-commons';
+import { IImportUser, IOAHowto, IOACategory, IOATags, IOAHowtoImport } from '../../';
+export declare const DEFAULT_HT_CATEGORY: {
+ _modified: string;
+ label: string;
+ _id: string;
+ _created: string;
+ _deleted: boolean;
+};
+export declare const LATEST_TRACK = "${OSR_ROOT}/oa-data/howtos/latest_track.json";
+export declare const LATEST_TEST = "./latest_test.json";
+export declare const DEFAULT_USER = "katharinaelleke";
+export declare const getDataPath: (_path?: string) => string;
+export declare const getHowtosPath: () => string;
+export declare const getHowtos: () => IOAHowtoImport[];
+export declare const read_howtos: (src: string) => IOAHowtoImport[];
+export declare const read_categories: (src: string) => IOACategory[];
+export declare const read_tags: (src: string) => IOATags[];
+export declare const filter_valid: (users: IOAHowtoImport[]) => IOAHowtoImport[];
+export declare const kb_howto_folder: (howto: any) => string;
+export declare const kb_howto_file: (howto: any, filename: any) => string;
+export declare const getHowtoUser: (howto: IOAHowto) => IImportUser;
+export declare const toMDImage: (image: IUploadedFileMeta) => string;
+export declare const md_edit_wrap: (content: any, f: any, prefix?: string, context?: string) => any;
+export declare const removeEmojis: (string: any) => any;
+export declare const toHTML: (path: any, markdown: any) => any;
+export declare const createTextLinks_: (text: any) => any;
diff --git a/packages/discourse/lib/oa/commons.js b/packages/discourse/lib/oa/commons.js
new file mode 100644
index 00000000..d01ef525
--- /dev/null
+++ b/packages/discourse/lib/oa/commons.js
@@ -0,0 +1,106 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.createTextLinks_ = exports.toHTML = exports.removeEmojis = exports.md_edit_wrap = exports.toMDImage = exports.getHowtoUser = exports.kb_howto_file = exports.kb_howto_folder = exports.filter_valid = exports.read_tags = exports.read_categories = exports.read_howtos = exports.getHowtos = exports.getHowtosPath = exports.getDataPath = exports.DEFAULT_USER = exports.LATEST_TEST = exports.LATEST_TRACK = exports.DEFAULT_HT_CATEGORY = void 0;
+const lib_1 = require("./lib");
+const path = require("path");
+const read_1 = require("@plastichub/fs/read");
+const fs_1 = require("@plastichub/osr-commons");
+const users_1 = require("./users");
+const js_beautify_1 = require("js-beautify");
+const showdown_1 = require("showdown");
+var escapeHtml = require('escape-html');
+const pretty = require('pretty');
+const TEST = false;
+exports.DEFAULT_HT_CATEGORY = {
+ "_modified": "2022-09-18T08:51:47.196Z",
+ "label": "Guides",
+ "_id": "CrZjHORWfxEl6iDrrPIO",
+ "_created": "2022-09-18T08:51:47.196Z",
+ "_deleted": false
+};
+exports.LATEST_TRACK = '${OSR_ROOT}/oa-data/howtos/latest_track.json';
+exports.LATEST_TEST = './latest_test.json';
+exports.DEFAULT_USER = 'katharinaelleke';
+const getDataPath = (_path = '') => path.resolve(path.join((0, fs_1.resolve)('${OSR_ROOT}/oa-data/howtos/'), _path));
+exports.getDataPath = getDataPath;
+const getHowtosPath = () => path.resolve((0, fs_1.resolve)(TEST ? exports.LATEST_TEST : exports.LATEST_TRACK));
+exports.getHowtosPath = getHowtosPath;
+const getHowtos = () => (0, read_1.sync)(path.resolve((0, exports.getHowtosPath)()), 'json') || [];
+exports.getHowtos = getHowtos;
+const read_howtos = (src) => {
+ const raw = (0, read_1.sync)(src, 'json');
+ return raw.v3_howtos;
+};
+exports.read_howtos = read_howtos;
+const read_categories = (src) => {
+ const raw = (0, read_1.sync)(src, 'json');
+ return raw.v3_categories;
+};
+exports.read_categories = read_categories;
+const read_tags = (src) => {
+ const raw = (0, read_1.sync)(src, 'json');
+ return raw.v3_tags;
+};
+exports.read_tags = read_tags;
+const filter_valid = (users) => {
+ return users.filter((user) => {
+ if (user.title === 'Build a Fishing Canoe') {
+ //debugger
+ }
+ if (user.moderation.toLowerCase() !== 'accepted') {
+ return false;
+ }
+ return true;
+ });
+};
+exports.filter_valid = filter_valid;
+const kb_howto_folder = (howto) => path.resolve(path.join((0, fs_1.resolve)("${KB_ROOT}/src/howtos/"), howto.slug));
+exports.kb_howto_folder = kb_howto_folder;
+const kb_howto_file = (howto, filename) => path.resolve(path.join((0, fs_1.resolve)("${KB_ROOT}/src/howtos/"), howto.slug, (0, lib_1.sanitize)(filename)));
+exports.kb_howto_file = kb_howto_file;
+const getHowtoUser = (howto) => {
+ const users = (0, users_1.getUsers)();
+ let user = users.find((u) => u._id == howto._createdBy);
+ if (user && user.f_id) {
+ return user;
+ }
+ else {
+ user = users.find((u) => u._id == exports.DEFAULT_USER);
+ if (user && user.f_id) {
+ console.error('using default user : ' + exports.DEFAULT_USER + ' : for' + howto.slug);
+ return user;
+ }
+ }
+};
+exports.getHowtoUser = getHowtoUser;
+const toMDImage = (image) => ``;
+exports.toMDImage = toMDImage;
+const md_edit_wrap = (content, f, prefix = '', context = '') => (0, js_beautify_1.html_beautify)(`${content}
`);
+exports.md_edit_wrap = md_edit_wrap;
+const removeEmojis = (string) => {
+ return string.replace(/([#0-9]\u20E3)|[\xA9\xAE\u203C\u2047-\u2049\u2122\u2139\u3030\u303D\u3297\u3299][\uFE00-\uFEFF]?|[\u2190-\u21FF][\uFE00-\uFEFF]?|[\u2300-\u23FF][\uFE00-\uFEFF]?|[\u2460-\u24FF][\uFE00-\uFEFF]?|[\u25A0-\u25FF][\uFE00-\uFEFF]?|[\u2600-\u27BF][\uFE00-\uFEFF]?|[\u2900-\u297F][\uFE00-\uFEFF]?|[\u2B00-\u2BF0][\uFE00-\uFEFF]?|(?:\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDEFF])[\uFE00-\uFEFF]?/g, '');
+};
+exports.removeEmojis = removeEmojis;
+const toHTML = (path, markdown) => {
+ const content = (0, read_1.sync)(path, 'string');
+ if (!markdown) {
+ let converter = new showdown_1.Converter({ tables: true });
+ converter.setOption('literalMidWordUnderscores', 'true');
+ return converter.makeHtml(content);
+ }
+ else {
+ return content;
+ }
+};
+exports.toHTML = toHTML;
+const createTextLinks_ = (text) => {
+ return (text || "").replace(/([^\S]|^)(((https?\:\/\/)|(www\.))(\S+))/gi, function (match, space, url) {
+ var hyperlink = url;
+ if (!hyperlink.match('^https?:\/\/')) {
+ hyperlink = 'http://' + hyperlink;
+ }
+ return space + '' + url + ' ';
+ });
+};
+exports.createTextLinks_ = createTextLinks_;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvb2EvY29tbW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUF3QkEsK0JBQXlDO0FBRXpDLDZCQUE0QjtBQUM1Qiw4Q0FBa0Q7QUFLbEQsdURBQXdEO0FBR3hELG1DQUFpRDtBQUVqRCw2Q0FBMkM7QUFDM0MsdUNBQW9DO0FBQ3BDLElBQUksVUFBVSxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztBQUd4QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUE7QUFHaEMsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFBO0FBRUwsUUFBQSxtQkFBbUIsR0FBRztJQUMvQixXQUFXLEVBQUUsMEJBQTBCO0lBQ3ZDLE9BQU8sRUFBRSxRQUFRO0lBQ2pCLEtBQUssRUFBRSxzQkFBc0I7SUFDN0IsVUFBVSxFQUFFLDBCQUEwQjtJQUN0QyxVQUFVLEVBQUUsS0FBSztDQUNwQixDQUFBO0FBR1ksUUFBQSxZQUFZLEdBQUcsOENBQThDLENBQUE7QUFDN0QsUUFBQSxXQUFXLEdBQUcsb0JBQW9CLENBQUE7QUFFbEMsUUFBQSxZQUFZLEdBQUcsaUJBQWlCLENBQUE7QUFFdEMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxLQUFLLEdBQUcsRUFBRSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBQSxZQUFPLEVBQUMsNkJBQTZCLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFBO0FBQXBHLFFBQUEsV0FBVyxlQUF5RjtBQUMxRyxNQUFNLGFBQWEsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUEsWUFBTyxFQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsbUJBQVcsQ0FBQyxDQUFDLENBQUMsb0JBQVksQ0FBQyxDQUFDLENBQUE7QUFBOUUsUUFBQSxhQUFhLGlCQUFpRTtB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
\ No newline at end of file
diff --git a/packages/discourse/lib/oa/howtos.d.ts b/packages/discourse/lib/oa/howtos.d.ts
new file mode 100644
index 00000000..fa372fd5
--- /dev/null
+++ b/packages/discourse/lib/oa/howtos.d.ts
@@ -0,0 +1,10 @@
+import { IOptions, IOAHowtoImport } from '../../';
+import { Discourser } from '../index';
+export declare const mergeLatest: (discorse: any, options: IOptions, oa_howtos: IOAHowtoImport[]) => IOAHowtoImport[];
+export declare const read_fragments: (src: any, config: any, prefix?: string, context?: string) => any;
+export declare function howto_content(howto: IOAHowtoImport, folder: string, fragments: any, templates: any): Promise;
+export declare const createHowtoTopic: (discourse: any, howto: IOAHowtoImport, create?: boolean) => Promise;
+export declare const importHowto: (discorse: any, howto: IOAHowtoImport) => Promise;
+export declare const importHowtos: (discorse: any, options: IOptions, howtos: IOAHowtoImport[]) => Promise;
+export declare const updateHowto: (discourse: Discourser, howto: IOAHowtoImport, options: IOptions) => Promise;
+export declare const updateHowtos: (discorse: any, options: IOptions, howtos: IOAHowtoImport[]) => Promise;
diff --git a/packages/discourse/lib/oa/howtos.js b/packages/discourse/lib/oa/howtos.js
new file mode 100644
index 00000000..eb0ab03b
--- /dev/null
+++ b/packages/discourse/lib/oa/howtos.js
@@ -0,0 +1,475 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.updateHowtos = exports.updateHowto = exports.importHowtos = exports.importHowto = exports.createHowtoTopic = exports.howto_content = exports.read_fragments = exports.mergeLatest = void 0;
+const bluebird_1 = require("bluebird");
+const osr_cli_commons_1 = require("@plastichub/osr-cli-commons");
+const core_1 = require("@plastichub/core");
+const strings_1 = require("@plastichub/core/strings");
+const index_1 = require("../../index");
+const constants_1 = require("../discourse/constants");
+const lib_1 = require("./lib");
+const path = require("path");
+const read_1 = require("@plastichub/fs/read");
+const exists_1 = require("@plastichub/fs/exists");
+const write_1 = require("@plastichub/fs/write");
+const fs_1 = require("@plastichub/osr-commons");
+const cheerio = require("cheerio");
+const users_1 = require("./users");
+var escapeHtml = require('escape-html');
+const dir_1 = require("@plastichub/fs/dir");
+const osr_cli_commons_2 = require("@plastichub/osr-cli-commons");
+const FUCKING_TOKEN = 'j7oYrkQe5nbnikCNHcfoP2DGtXKV4iHHzDFip8gGatS145g3B65UU6mI09KeFday9mY5HNQnU2jXUTe7LLkP-w';
+const commons_1 = require("./commons");
+const mergeLatest = (discorse, options, oa_howtos) => {
+ const howtos = (0, commons_1.getHowtos)();
+ oa_howtos.forEach((h) => {
+ const howto = howtos.find((tu) => {
+ return tu._id === h._id;
+ });
+ if (!howto) {
+ howtos.push(h);
+ }
+ });
+ (0, write_1.sync)((0, commons_1.getHowtosPath)(), howtos);
+ return howtos;
+};
+exports.mergeLatest = mergeLatest;
+const updateHowtoFile = (howto) => {
+ const howtos = (0, commons_1.getHowtos)();
+ const index = howtos.findIndex((u) => u._id == howto._id);
+ howtos[index] = howto;
+ (0, write_1.sync)((0, commons_1.getHowtosPath)(), howtos);
+};
+const uploadImage = async (discourse, user, image, localPath) => {
+ if (image.data) {
+ return image;
+ }
+ index_1.logger.debug('uploading image:', image.name);
+ const upped = await discourse.uploadFile(user.f_id, localPath);
+ const data = upped.data;
+ if (data && data.id) {
+ image.data = data;
+ }
+ else {
+ index_1.logger.error('error uploading image');
+ }
+ return image;
+};
+const read_fragments = (src, config, prefix = '', context = '') => {
+ if (!(0, exists_1.sync)(src)) {
+ (0, dir_1.sync)(src);
+ }
+ let fragments = (0, osr_cli_commons_2.files)(src, '*.html');
+ fragments.map((f) => {
+ config[path.parse(f).name] = (0, commons_1.md_edit_wrap)((0, commons_1.toHTML)(f, true), f, prefix, context);
+ });
+ fragments = (0, osr_cli_commons_2.files)(src, '*.md');
+ fragments.map((f) => {
+ config[path.parse(f).name] = (0, commons_1.md_edit_wrap)((0, commons_1.toHTML)(f, false), f, prefix, context);
+ });
+ return config;
+};
+exports.read_fragments = read_fragments;
+async function howto_content(howto, folder, fragments, templates) {
+ //const tags = data.v3_tags;
+ const howtoTags = [];
+ /*
+ for (const ht in howto.tags) {
+ const gt = tags.find((t) => t._id === ht);
+ if (gt) {
+ howtoTags.push(gt.label);
+ // logger.debug('resolved ' + ht + ' to ' + gt.label);
+ } else {
+ // logger.error('Cant resolve tag : ' + ht);
+ }
+ }
+*/
+ howto.slug = howto.slug.trim();
+ let s = '';
+ let step_template = "" + templates.step;
+ let invalid_step_images = false;
+ const step_image = (i) => {
+ if (!i.data || !i.data.short_url) {
+ index_1.logger.error('invalid image : ' + i.downloadUrl + ' : ' + howto.slug);
+ invalid_step_images = true;
+ return '\n';
+ }
+ return `\n${(0, commons_1.toMDImage)(i)}`;
+ };
+ const step_file = (i) => {
+ const image = `/howtos/${howto.slug}/${encodeURIComponent((0, lib_1.sanitize)(i.name))}`;
+ return ``;
+ };
+ const step_files = (s) => {
+ const files = s.files.map(step_file).join('\n');
+ return `
+ ${files}
+
+ `;
+ };
+ const step_images = (s) => {
+ const images = s.images.map(step_image).join('\n');
+ return `${images}`;
+ };
+ const step_images_gallery = (s) => {
+ const images = s.images.map(step_image).join('');
+ return `\n${images}
`;
+ };
+ const step = (s, i) => {
+ const t = (0, strings_1.substitute)(step_template, {
+ title: s.title,
+ text: (0, commons_1.createTextLinks_)(escapeHtml(s.text.trim()).replace(/(?:\r\n|\r|\n)/g, '\n\n')),
+ step_number: i + 1,
+ images: s.images.length > 1 ? step_images_gallery(s) : step_images(s)
+ });
+ return t;
+ };
+ const steps = howto.steps.map((s, i) => step(s, i)).join('\n\n');
+ const attachments = howto.files.map((f) => {
+ return `[${(0, lib_1.sanitize)(f.name)}](${f.downloadUrl})`;
+ });
+ howto.description = (0, commons_1.removeEmojis)(howto.description);
+ howto.description = (0, commons_1.createTextLinks_)(howto.description);
+ let authorName = (howto.user && howto.user.data && howto.user.data && howto.user.data.title) ? howto.user.data.title : (howto.user ? howto.user._id : 'OSR-Plastic');
+ if (authorName === 'Precious Plastic Headquarters') {
+ authorName = 'Precious Plastic Nantes';
+ }
+ let _3dFiles = [...(0, osr_cli_commons_2.files)(path.resolve(`${folder}`), '**/**/*.step'), ...(0, osr_cli_commons_2.files)(path.resolve(`${folder}`), '**/**/*.STEP'), ...(0, osr_cli_commons_2.files)(path.resolve(`${folder}`), '**/**/*.stp')];
+ _3dFiles = _3dFiles.map((f) => {
+ return (0, osr_cli_commons_1.forward_slash)(`${howto.slug}/${path.relative(path.resolve(folder), f)}`);
+ });
+ let previews = '';
+ if (_3dFiles.length) {
+ previews += '';
+ previews += '
';
+ _3dFiles = _3dFiles.map((f) => {
+ return `
+
+ 3D Step File: ${f.replace(howto.slug, '')} -
+
+ Preview
+
+ `;
+ });
+ previews += _3dFiles.join('');
+ previews += ' ';
+ }
+ if (invalid_step_images) {
+ return false;
+ }
+ let index = (0, strings_1.substitute)(templates.howto, {
+ ...fragments,
+ image: `/howtos/${howto.slug}/${encodeURIComponent((0, lib_1.sanitize)(howto.cover_image.name))}`,
+ title: howto.title.trim(),
+ description: escapeHtml(howto.description.trim()) || "",
+ enabled: howto.moderation == "accepted" ? true : false,
+ steps: steps,
+ keywords: ['Precious plastic', 'Preciousplastic', 'plastichub', 'osr', ...howtoTags].join(','),
+ user: howto._createdBy,
+ files: `${attachments.join('\n')}`,
+ authorName: authorName,
+ authorUrl: `https://osr-plastic.org/users/${howto.user ? howto.user._id : 'https://osr-plastic.org/users/plastichub'}.html`,
+ // short: escapeHtml(howto.description.trim()).substring(0, 100) + '....',
+ slug: howto.slug,
+ previews3D: previews
+ });
+ const $ = cheerio.load(index, {
+ xmlMode: true
+ });
+ /*
+ $('a').each(function () {
+ const url = $(this).attr("href");
+ logger.debug('url : ' + url);
+ if(url.indexOf('dropbox')){
+
+ }
+ });*/
+ //write(index_md, pretty(index, { ocd: true }));
+ return (0, commons_1.removeEmojis)(index);
+}
+exports.howto_content = howto_content;
+const createHowtoTopic = async (discourse, howto, create = true) => {
+ if (!howto.category || !howto.category.label) {
+ howto.category = commons_1.DEFAULT_HT_CATEGORY;
+ index_1.logger.error(`create howto : invalid category: ${howto.category} : ${howto.slug}`);
+ }
+ const user = (0, commons_1.getHowtoUser)(howto);
+ if (!user) {
+ index_1.logger.error(`create howto : invalid user : ${howto._createdBy} :: ${howto.title}`);
+ }
+ const howto_folder = (0, commons_1.kb_howto_folder)(howto);
+ const howto_cover_image = (0, commons_1.kb_howto_file)(howto, howto.cover_image.name);
+ if (!(0, exists_1.sync)(howto_folder)) {
+ index_1.logger.error('howto folder doesnt exists', howto.title);
+ }
+ if (!(0, exists_1.sync)(howto_cover_image)) {
+ index_1.logger.error('howto cover image doesnt exists', howto.title);
+ }
+ if (!user || !user.f_id) {
+ index_1.logger.error(`create howto : invalid user : ${howto._createdBy} :: ${howto.title}`);
+ return false;
+ }
+ howto.cover_image = await uploadImage(discourse, user, howto.cover_image, howto_cover_image);
+ updateHowtoFile(howto);
+ let invalid_images = false;
+ for (const step of howto.steps) {
+ let i = 0;
+ for await (const image of step.images) {
+ const image_name = (0, lib_1.sanitize)(image.name);
+ const imagePath = path.resolve(path.join(howto_folder, (0, lib_1.sanitize)(image_name)));
+ if (!(0, exists_1.sync)(imagePath)) {
+ index_1.logger.error('step image doesnt exists : ' + image.name + ' in ' + howto.slug);
+ invalid_images = true;
+ continue;
+ }
+ step.images[i] = await uploadImage(discourse, user, step.images[i], imagePath);
+ updateHowtoFile(howto);
+ i++;
+ }
+ }
+ if (invalid_images) {
+ index_1.logger.error('invalid images : ' + howto.slug);
+ return false;
+ }
+ const cat = constants_1.HT_CATS[howto.category.label];
+ if (!cat) {
+ index_1.logger.error('invalid kat');
+ return false;
+ }
+ const templatesRoot = path.resolve((0, fs_1.resolve)("${OSR_ROOT}/osr-templates/discourse"));
+ const cPath = path.resolve(`${templatesRoot}/base.json`);
+ index_1.logger.debug(`read config at ${cPath}`);
+ const config = (0, read_1.sync)(cPath, 'json');
+ const templates = path.resolve(`${templatesRoot}/howto`);
+ if (!(0, exists_1.sync)(templates)) {
+ index_1.logger.error(`\t Cant find templates at ${templates}, path doesn't exists`);
+ return;
+ }
+ let fragments = { ...config.variables };
+ (0, exports.read_fragments)(templates, fragments, "product_rel_path_name", "machine");
+ let template = (0, read_1.sync)(path.resolve(`${templates}/howto.md`), 'string');
+ let step = (0, read_1.sync)(path.resolve(`${templates}/step.md`), 'string');
+ (0, core_1.resolveConfig)(fragments);
+ const content = await howto_content(howto, howto_folder, fragments, {
+ howto: template,
+ step: '' + step
+ });
+ if (!content) {
+ index_1.logger.error('invalid content : ' + howto.slug);
+ return;
+ }
+ let data;
+ if (create) {
+ data = await discourse.createPost((0, lib_1.sanitize)(howto.title), content, cat);
+ if (data) {
+ index_1.logger.debug('created topic : ' + howto.title + ' : ' + data.id);
+ if (data && data.id) {
+ howto.post_id = data.id;
+ howto.topic_id = data.topic_id;
+ updateHowtoFile(howto);
+ try {
+ index_1.logger.debug('change user to ', user._id);
+ await discourse.changeOwner(howto.post_id, howto.topic_id, (0, users_1.get_user_name)(user));
+ }
+ catch (e) {
+ index_1.logger.debug('changing owner ' + howto.title + ' failed!');
+ howto.oF = true;
+ updateHowtoFile(howto);
+ }
+ }
+ else {
+ index_1.logger.debug('creating ' + howto.title + ' failed!', data.errors);
+ howto.post_id = 'failed';
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ index_1.logger.error('title already used : ' + howto.slug);
+ howto.post_id = 'already';
+ }
+ }
+ updateHowtoFile(howto);
+ }
+ }
+ }
+ else {
+ data = await discourse.updatePost(howto.post_id, content);
+ howto._updatedContent1 = true;
+ updateHowtoFile(howto);
+ }
+};
+exports.createHowtoTopic = createHowtoTopic;
+const importHowto = async (discorse, howto) => {
+ //const howtos = getHowtos()
+ //const index = howtos.findIndex((u) => u._id == howto._id)
+ const ret = await (0, exports.createHowtoTopic)(discorse, howto);
+ return ret;
+};
+exports.importHowto = importHowto;
+const importHowtos = async (discorse, options, howtos) => {
+ index_1.logger.debug('read howtos from ', path.resolve((0, commons_1.getHowtosPath)()));
+ howtos = (0, exports.mergeLatest)(discorse, options, howtos);
+ howtos = howtos.filter((h) => {
+ if (h.title === 'Build a Fishing Canoe') {
+ //debugger
+ }
+ if (h.post_id || h.post_id < 0) {
+ return false;
+ }
+ if (h.post_id === 'failed') {
+ index_1.logger.debug('skip failed : ' + h.slug);
+ return false;
+ }
+ //if (u.alreadyExists || u.invalidData) {
+ // return false;
+ //}
+ return true;
+ });
+ return await bluebird_1.Promise.resolve(howtos).map((h) => {
+ try {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ const d = (0, exports.importHowto)(discorse, h);
+ if (d) {
+ d.then(resolve);
+ }
+ else {
+ reject();
+ }
+ }, 500);
+ });
+ }
+ catch (e) {
+ debugger;
+ index_1.logger.error('error creating howto ' + h._id, e);
+ }
+ }, { concurrency: 1 });
+};
+exports.importHowtos = importHowtos;
+/////////////////////////////////////////////////////////////////////////
+//
+// Update Howtos
+//
+let _discorseTags;
+const getDiscourseTags = async (discourse) => {
+ if (!_discorseTags) {
+ _discorseTags = await discourse.getTags();
+ }
+ return _discorseTags;
+};
+const updateHowto = async (discourse, howto, options) => {
+ const tags = (0, commons_1.read_tags)(options.src);
+ let howtoTags = [];
+ for (const ht in howto.tags) {
+ const t = ht;
+ const gt = tags.find((t) => {
+ return t._id === ht;
+ });
+ if (gt) {
+ howtoTags.push(gt.label);
+ }
+ else {
+ // logger.error('Cant resolve tag : ' + ht);
+ }
+ }
+ howtoTags.push('oa-import');
+ let discorseTags = await getDiscourseTags(discourse);
+ const cat = constants_1.HT_CATS[howto.category.label];
+ if (howtoTags && howtoTags.length) {
+ try {
+ const ret = await discourse.updateTopic(howto.topic_id, cat, (0, lib_1.sanitize)(howto.title), howtoTags);
+ index_1.logger.debug('Updating howto tags : ' + howto.title);
+ }
+ catch (error) {
+ index_1.logger.error('Error updating post' + howto.title, howto.topic_id, cat, howtoTags, error);
+ howto['updateFailed1'] = 1;
+ updateHowtoFile(howto);
+ //debugger
+ }
+ }
+ howto.updatedTags = true;
+ updateHowtoFile(howto);
+ const _date = howto._modified || howto._created;
+ if (_date) {
+ let date = new Date(_date);
+ index_1.logger.debug('update ts ' + howto.slug + ' : ' + new Date(date).toLocaleDateString());
+ let offset = 0;
+ const valueOf = date.valueOf() - (offset) * 60000;
+ let ts = Math.floor(valueOf / 1000);
+ const tUpdate = await discourse.updateTopicTimestamp(howto.topic_id, ts, FUCKING_TOKEN);
+ if (tUpdate) {
+ howto.updatedTime8 = true;
+ updateHowtoFile(howto);
+ return true;
+ }
+ }
+ else {
+ index_1.logger.error('Have no ts : ' + howto.slug);
+ }
+};
+exports.updateHowto = updateHowto;
+const updateHowtos = async (discorse, options, howtos) => {
+ index_1.logger.debug('update howtos from ', path.resolve((0, commons_1.getHowtosPath)()));
+ howtos = (0, exports.mergeLatest)(discorse, options, howtos);
+ const forceUpdateContent = true;
+ const forceUpdateMeta = true;
+ const updateContent = true;
+ const updateMeta = true;
+ howtos = howtos.filter((h) => {
+ if (!h.post_id || !h.topic_id) {
+ return false;
+ }
+ if (h.post_id === 'failed') {
+ index_1.logger.debug('skip failed : ' + h.slug);
+ return false;
+ }
+ if (forceUpdateContent || forceUpdateMeta) {
+ return true;
+ }
+ if (!h._updatedContent1) {
+ return true;
+ }
+ if (h.updatedTags && h.updatedTime8) {
+ return false;
+ }
+ if (!h.updatedTags || !h.updatedTime8) {
+ return true;
+ }
+ return true;
+ });
+ return await bluebird_1.Promise.resolve(howtos).map((h) => {
+ try {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ if (updateContent) {
+ index_1.logger.debug('\t recook howto content', h.title);
+ let d = (0, exports.createHowtoTopic)(discorse, h, false);
+ d.then(() => {
+ if (updateMeta) {
+ d = (0, exports.updateHowto)(discorse, h, options);
+ if (d) {
+ d.then(resolve);
+ }
+ else {
+ reject();
+ }
+ }
+ else {
+ resolve(1);
+ }
+ });
+ }
+ }, 500);
+ });
+ }
+ catch (e) {
+ debugger;
+ index_1.logger.error('error creating howto ' + h._id, e);
+ }
+ }, { concurrency: 1 });
+};
+exports.updateHowtos = updateHowtos;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaG93dG9zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9vYS9ob3d0b3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsdUNBQThDO0FBRTlDLGlFQUEyRDtBQUMzRCwyQ0FBZ0Q7QUFDaEQsc0RBQXFEO0FBV3JELHVDQUVvQjtBQUVwQixzREFFK0I7QUFJL0IsK0JBQXlDO0FBRXpDLDZCQUE0QjtBQUM1Qiw4Q0FBa0Q7QUFDbEQsa0RBQXNEO0FBRXRELGdEQUFvRDtBQUVwRCx1REFBd0Q7QUFFeEQsbUNBQWtDO0FBQ2xDLG1DQUFpRDtBQUVqRCxJQUFJLFVBQVUsR0FBRyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7QUFDeEMsNENBQWtEO0FBQ2xELGlFQUFtRDtBQUluRCxNQUFNLGFBQWEsR0FBRyx3RkFBd0YsQ0FBQTtBQUU5Ryx1Q0Fja0I7QUFFWCxNQUFNLFdBQVcsR0FBRyxDQUFDLFFBQVEsRUFBRSxPQUFpQixFQUFFLFNBQTJCLEVBQW9CLEVBQUU7SUFFdEcsTUFBTSxNQUFNLEdBQVUsSUFBQSxtQkFBUyxHQUFFLENBQUE7SUFDakMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1FBQ3BCLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTtZQUM3QixPQUFPLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQTtRQUMzQixDQUFDLENBQUMsQ0FBQTtRQUNGLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDUixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBO1NBQ2pCO0lBRUwsQ0FBQyxDQUFDLENBQUE7SUFDRixJQUFBLFlBQUssRUFBQyxJQUFBLHVCQUFhLEdBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUM5QixPQUFPLE1BQU0sQ0FBQTtBQUNqQixDQUFDLENBQUE7QUFkWSxRQUFBLFdBQVcsZUFj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
\ No newline at end of file
diff --git a/packages/discourse/lib/oa/index.d.ts b/packages/discourse/lib/oa/index.d.ts
new file mode 100644
index 00000000..7966de83
--- /dev/null
+++ b/packages/discourse/lib/oa/index.d.ts
@@ -0,0 +1,3 @@
+export * from './lib';
+export * from './users';
+export * from './types';
diff --git a/packages/discourse/lib/oa/index.js b/packages/discourse/lib/oa/index.js
new file mode 100644
index 00000000..c854f1a4
--- /dev/null
+++ b/packages/discourse/lib/oa/index.js
@@ -0,0 +1,20 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./lib"), exports);
+__exportStar(require("./users"), exports);
+__exportStar(require("./types"), exports);
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL29hL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSx3Q0FBcUI7QUFDckIsMENBQXVCO0FBQ3ZCLDBDQUF1QiJ9
\ No newline at end of file
diff --git a/packages/discourse/lib/oa/lib.d.ts b/packages/discourse/lib/oa/lib.d.ts
new file mode 100644
index 00000000..49c99ad8
--- /dev/null
+++ b/packages/discourse/lib/oa/lib.d.ts
@@ -0,0 +1,3 @@
+export declare const sanitize: (f: any) => string;
+export declare const getImageName: (url: any) => string;
+export declare const convert: (input: string) => any;
diff --git a/packages/discourse/lib/oa/lib.js b/packages/discourse/lib/oa/lib.js
new file mode 100644
index 00000000..696cd8ee
--- /dev/null
+++ b/packages/discourse/lib/oa/lib.js
@@ -0,0 +1,197 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.convert = exports.getImageName = exports.sanitize = void 0;
+const _sanitize = require("sanitize-filename");
+const URI = require("uri-js");
+const path = require("path");
+const filenamify = require('filenamify');
+var TurndownService = require('turndown');
+const sanitize = (f) => {
+ let str = filenamify(_sanitize(f)).replace(/[^\x00-\x7F]/g, "");
+ if (str.startsWith('_')) {
+ str = str.substring(1);
+ }
+ return str;
+};
+exports.sanitize = sanitize;
+const getImageName = (url) => {
+ const parsed = URI.parse(decodeURIComponent(url));
+ const pParsed = path.parse(parsed.path);
+ const fileName = (0, exports.sanitize)(decodeURIComponent(pParsed.base));
+ return fileName;
+};
+exports.getImageName = getImageName;
+const convert = (input) => {
+ var turndownService = new TurndownService();
+ return turndownService.turndown(input);
+};
+exports.convert = convert;
+/*
+
+
+const getFUser = (users, user_name) => {
+ return users.find((u) => {
+ return u.name == user_name
+ })
+}
+
+
+const indexUsers = async (d, forum: string, detail) => {
+
+ const forumUsers = await getForumUsers(d, detail)
+ const raw = (read(path.resolve(forum + '/index.json'), 'json') as any)
+ const users_raw = raw.users
+ let users = []
+ for (let u in users_raw) {
+ const user = users_raw[u];
+ const avatar = getOAvatar(raw, u);
+ let aFileName = '';
+ let fUser = getFUser(forumUsers, u);
+ if (avatar) {
+ const parsed = URI.parse(avatar);
+ const pParsed = path.parse(parsed.path);
+ aFileName = pParsed.base;
+ }
+ users.push({
+ name: u,
+ avatar: avatar,
+ avatarFileName: aFileName,
+ user_id: fUser ? fUser.id : -1
+ });
+ }
+ write(path.resolve(forum + '/user.json'), users);
+}
+
+const _createUser = async (discorse, forum, name, email) => {
+
+ const users = getUsers()
+ const index = users.findIndex((u) => u.detail.name == name)
+ let user = await createUser(discorse, null)
+
+
+ if (user && users[index].upload_id) {
+ await discorse.setUserAvatar(name, users[index].upload_id);
+ //return users;
+ }
+
+ if (user > 0 && index) {
+ users[index].f_id = user;
+ console.log('created ' + name + ' ' + user);
+ write(getUsersPath(), users);
+ } else {
+ console.error('cant create user - error', name, user)
+ }
+}
+
+
+const _updateGroup = async (discorse, forum, name, id, forumUsers) => {
+ const users = (read(path.resolve(forum + '/user.json'), 'json') as any);
+ const index = users.findIndex((u) => u.name == name);
+ try {
+ const d = await discorse.updateGroup(name, pUserGroup);
+ console.log('updated user group for ' + name);
+ users[index].g_id = pUserGroup;
+ write(path.resolve(forum + '/user.json'), users);
+ if (users[index].upload_id) {
+ //await discorse.setUserAvatar(name, users[index].upload_id);
+ }
+ } catch (e) {
+ if (e.data && e.data.status == 422) {
+ users[index].g_id = pUserGroup;
+ write(path.resolve(forum + '/user.json'), users);
+ console.log('updated user group for ' + name);
+ }
+ }
+}
+
+const _updateAvatar = async (discorse, forum, name) => {
+ const users = (read(path.resolve(forum + '/user.json'), 'json') as any);
+ const index = users.findIndex((u) => u.name == name);
+ return new Promise((resolve, reject) => {
+ try {
+ setTimeout(() => {
+ discorse.setUserAvatar(name, users[index].upload_id).then(() => {
+ console.log('updated avatar for ' + name);
+ users[index].avatarSet = true;
+ write(path.resolve(forum + '/user.json'), users);
+ resolve(1);
+ });
+ }, 200);
+ } catch (e) {
+ console.error('-error setting avatar', e);
+ debugger;
+ }
+ });
+}
+
+
+const createUsers = async (d, forum) => {
+
+ const forumUsers = await getForumUsers(d, true)
+ const users = (read(path.resolve(forum + '/user.json'), 'json') as any);
+ const toBeCreated = users.filter((u) => {
+ if (u.f_id || u.f_id < 0) {
+ return false;
+ }
+ if (u.name === 'plastichub' || u.name === 'lu' || u.name === 'timberstar' || u.name === 'nickname') {
+ return false
+ }
+ return true;
+ });
+
+ console.log('Create Users ' + users.length + ' Total | Left: ' + toBeCreated.length);
+
+ return await BPromise.resolve(toBeCreated).map((u: any) => {
+ const t = _createUser(d, forum, u.name, u.email);
+ return t;
+ }, { concurrency: 1 })
+
+}
+
+const updateUserGroups = async (forum) => {
+ const forumUsers = (read(path.resolve(forum + '/fusers.json'), 'json') as any);
+ const users = (read(path.resolve(forum + '/user.json'), 'json') as any);
+ const toBeUpdated = users.filter((u) => {
+ if (u.g_id) {
+ return false;
+ }
+ if (u.name === 'plastichub' || u.name === 'lu' || u.name === 'timberstar' || u.name === 'nickname') {
+ return false
+ }
+ return true;
+ });
+ const d = getDiscourse();
+ console.log('Update Users ' + users.length + ' Total | Left: ' + toBeUpdated.length);
+ return await BPromise.resolve(toBeUpdated).map((u: any) => {
+ const t = _updateGroup(d, forum, u.name, u.f_id, forumUsers);
+ return t;
+ }, { concurrency: 1 })
+
+}
+
+const updateUserAvatars = async (forum) => {
+ const users = (read(path.resolve(forum + '/user.json'), 'json') as any);
+ const toBeUpdated = users.filter((u) => {
+ if (!u.upload_id) {
+ return false;
+ }
+
+ if (u.avatarSet) {
+ return false;
+ }
+
+ if (u.name === 'plastichub' || u.name === 'lu' || u.name === 'timberstar' || u.name === 'nickname') {
+ return false
+ }
+ return true;
+ });
+ const d = getDiscourse();
+ console.log('Update User Avatar ' + users.length + ' Total | Left: ' + toBeUpdated.length);
+ return await BPromise.resolve(toBeUpdated).map((u: any) => {
+ const t = _updateAvatar(d, forum, u.name);
+ return t;
+ }, { concurrency: 1 })
+
+}
+*/
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGliLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9vYS9saWIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUE7QUFDOUMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFBO0FBQzdCLDZCQUE0QjtBQUM1QixNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUE7QUFDeEMsSUFBSSxlQUFlLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ25DLE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUU7SUFDMUIsSUFBSSxHQUFHLEdBQVcsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDeEUsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFO1FBQ3JCLEdBQUcsR0FBRyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFBO0tBQ3pCO0lBQ0QsT0FBTyxHQUFHLENBQUE7QUFDZCxDQUFDLENBQUE7QUFOWSxRQUFBLFFBQVEsWUFNcEI7QUFHTSxNQUFNLFlBQVksR0FBSSxDQUFDLEdBQUcsRUFBRSxFQUFFO0lBQ2pDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNsRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN4QyxNQUFNLFFBQVEsR0FBRyxJQUFBLGdCQUFRLEVBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7SUFDM0QsT0FBTyxRQUFRLENBQUE7QUFDbkIsQ0FBQyxDQUFBO0FBTFksUUFBQSxZQUFZLGdCQUt4QjtBQUVNLE1BQU0sT0FBTyxHQUFHLENBQUMsS0FBYSxFQUFFLEVBQUU7SUFDeEMsSUFBSSxlQUFlLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQTtJQUMzQyxPQUFPLGVBQWUsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDeEMsQ0FBQyxDQUFBO0FBSFksUUFBQSxPQUFPLFdBR25CO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBdUtFIn0=
\ No newline at end of file
diff --git a/packages/discourse/lib/oa/types.d.ts b/packages/discourse/lib/oa/types.d.ts
new file mode 100644
index 00000000..836543ee
--- /dev/null
+++ b/packages/discourse/lib/oa/types.d.ts
@@ -0,0 +1,91 @@
+import { IUploadedFileMeta, I_OSR_USER } from '@plastichub/osr-commons';
+export interface IOACategory {
+ _created: string;
+ _id: string;
+ _deleted: boolean;
+ label: string;
+ _modified: string;
+}
+export interface IOATag {
+ categories: string[];
+ image: string;
+ _created: string;
+ _deleted: boolean;
+ label: string;
+ _createdBy: string;
+ _modified: string;
+ _id: string;
+}
+export type IOADifficultyLevel = 'Easy' | 'Medium' | 'Hard' | 'Very Hard';
+export interface IDImage {
+ id: number;
+ url: string;
+ original_filename: string;
+ filesize: number;
+ width: number;
+ height: number;
+ thumbnail_width: number;
+ thumbnail_height: number;
+ extension: string;
+ short_url: string;
+ short_path: string;
+ retain_hours: any;
+ human_filesize: string;
+}
+export interface IOAHowto {
+ moderation: string;
+ category: IOACategory;
+ previousSlugs: string[];
+ total_downloads: number;
+ _createdBy: string;
+ slug: string;
+ cover_image: IUploadedFileMeta;
+ _modified: string;
+ files: any[];
+ description: string;
+ mentions: any[];
+ time: string;
+ _created: string;
+ fileLink: string;
+ steps: IOAStep[];
+ creatorCountry: string;
+ title: string;
+ tags: IOATags;
+ _id: string;
+ _deleted: boolean;
+ total_views: number;
+ difficulty_level: IOADifficultyLevel;
+ comments: any[];
+ user: IImportUser;
+ pics?: string[];
+}
+export interface IOAStep {
+ _animationKey: string;
+ images: IUploadedFileMeta[];
+ text: string;
+ title: string;
+}
+export interface IOATags {
+ [key: string]: boolean;
+}
+export type IOAHowtoImport = IOAHowto & {
+ post_id?: number | string;
+ topic_id?: number;
+ oF?: boolean;
+ updatedTags?: boolean;
+ updatedTime8?: boolean;
+ _updatedContent1?: boolean;
+};
+export interface IImportUser extends I_OSR_USER {
+ f_id: number;
+ upload_id: number;
+ avatar: string;
+ _didSetAvatar: boolean;
+ _didSetGroup: boolean;
+ alreadyExists: boolean;
+ invalidData: boolean;
+ didUpdateName: boolean;
+ profileHeader?: IDImage;
+ cardBackground?: IDImage;
+ avatarImage?: IDImage;
+}
diff --git a/packages/discourse/lib/oa/types.js b/packages/discourse/lib/oa/types.js
new file mode 100644
index 00000000..b1a4cd6c
--- /dev/null
+++ b/packages/discourse/lib/oa/types.js
@@ -0,0 +1,3 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL29hL3R5cGVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIifQ==
\ No newline at end of file
diff --git a/packages/discourse/lib/oa/users.d.ts b/packages/discourse/lib/oa/users.d.ts
new file mode 100644
index 00000000..b6b09b40
--- /dev/null
+++ b/packages/discourse/lib/oa/users.d.ts
@@ -0,0 +1,30 @@
+import { I_OSR_USER } from '@plastichub/osr-commons';
+import { IOptions, IImportUser, IDiscourseUser } from '../../';
+import { Discourser } from '../index';
+export declare const read_users: (src: string) => I_OSR_USER[];
+export declare const filter_valid: (users: IImportUser[]) => IImportUser[];
+export declare const filter_email_only: (users: any[]) => any[];
+export declare const filter_invalid: (users: any[]) => any[];
+export declare const filter_email_missing: (users: any[]) => any[];
+export declare const filter_accepted: (users: IImportUser[]) => IImportUser[];
+export declare const oa_user_email: (user: I_OSR_USER) => string | false;
+export declare const get_user_name: (user: IImportUser) => string;
+export declare const get_user_display_name: (user: IImportUser) => string;
+export declare const getDataPath: (_path?: string) => string;
+export declare const getUsersPath: () => string;
+export declare const getUsers: () => IImportUser[];
+export declare const _getForumUsers: (d: Discourser, page: any, detail: any) => any;
+export declare const getForumUsers: (d: any, detail: any) => Promise;
+export declare const createUser: (discourse: Discourser, oa_user: IImportUser) => Promise;
+export declare const uploadAvatar: (discourse: any, name: any, filePath: any) => Promise;
+export declare const updateUser: (discorse: Discourser, oa_user: IImportUser) => Promise;
+export declare const importUser: (discorse: Discourser, oa_user: IImportUser) => Promise;
+export declare const mergeLatestUsers: (discorse: any, options: IOptions, oa_users: I_OSR_USER[]) => IImportUser[];
+export declare const mergeLatestUsersTest: (discorse: any, options: IOptions, oa_users: I_OSR_USER[]) => IImportUser[];
+export declare const importUsers: (discorse: any, options: IOptions, oa_users: I_OSR_USER[]) => Promise;
+export declare const updateUsers: (discorse: any, options: IOptions, oa_users: I_OSR_USER[]) => Promise;
+export declare const md_edit_wrap: (content: any, f: any, prefix?: string, context?: string) => any;
+export declare const toHTML: (path: any, markdown: any) => any;
+export declare const imageName: (url: any) => string;
+export declare const read_fragments: (src: any, config: any, prefix?: string, context?: string) => any;
+export declare const indexUsers: (discorse: any, options: IOptions, oa_users: I_OSR_USER[]) => Promise;
diff --git a/packages/discourse/lib/oa/users.js b/packages/discourse/lib/oa/users.js
new file mode 100644
index 00000000..399e4d4a
--- /dev/null
+++ b/packages/discourse/lib/oa/users.js
@@ -0,0 +1,936 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.indexUsers = exports.read_fragments = exports.imageName = exports.toHTML = exports.md_edit_wrap = exports.updateUsers = exports.importUsers = exports.mergeLatestUsersTest = exports.mergeLatestUsers = exports.importUser = exports.updateUser = exports.uploadAvatar = exports.createUser = exports.getForumUsers = exports._getForumUsers = exports.getUsers = exports.getUsersPath = exports.getDataPath = exports.get_user_display_name = exports.get_user_name = exports.oa_user_email = exports.filter_accepted = exports.filter_email_missing = exports.filter_invalid = exports.filter_email_only = exports.filter_valid = exports.read_users = void 0;
+const bluebird_1 = require("bluebird");
+const lib_1 = require("./lib");
+const utils_1 = require("@plastichub/core/utils");
+const path = require("path");
+const read_1 = require("@plastichub/fs/read");
+const exists_1 = require("@plastichub/fs/exists");
+const write_1 = require("@plastichub/fs/write");
+const fs_1 = require("@plastichub/osr-commons");
+const index_1 = require("../../index");
+const slugify = require('slugify');
+const core_1 = require("@plastichub/core");
+const js_beautify_1 = require("js-beautify");
+const dir_1 = require("@plastichub/fs/dir");
+const osr_cli_commons_1 = require("@plastichub/osr-cli-commons");
+const showdown_1 = require("showdown");
+const URI = require("uri-js");
+const constants_1 = require("../discourse/constants");
+const filenamify = require('filenamify');
+const fg = require('fast-glob');
+const TEST = false;
+const read_users = (src) => {
+ const raw = (0, read_1.sync)(src, 'json');
+ return raw.v3_mappins.filter((f) => f.data != null);
+};
+exports.read_users = read_users;
+const filter_valid = (users) => {
+ return users.filter((user) => {
+ if (!user.data) {
+ return false;
+ }
+ if (!user.geo) {
+ return false;
+ }
+ if (!user.data.urls) {
+ return false;
+ }
+ if (!user.data.title) {
+ return false;
+ }
+ if (!user.detail) {
+ return false;
+ }
+ if (!user.detail.heroImageUrl) {
+ return false;
+ }
+ if (user.data && user.data.jsError) {
+ return false;
+ }
+ if (user.moderation !== 'accepted') {
+ //return false
+ }
+ return true;
+ });
+};
+exports.filter_valid = filter_valid;
+const filter_email_only = (users) => {
+ return users.filter((user) => {
+ if (!user.data) {
+ return false;
+ }
+ if (!user.geo) {
+ return false;
+ }
+ if (!user.data.urls) {
+ return false;
+ }
+ if (user.data && user.data.jsError) {
+ return false;
+ }
+ if (!user.detail) {
+ return false;
+ }
+ if (!user.detail.name) {
+ return false;
+ }
+ if (user.data.urls.find((l) => l.name == 'Email') == undefined) {
+ return false;
+ }
+ return true;
+ });
+};
+exports.filter_email_only = filter_email_only;
+const filter_invalid = (users) => {
+ return users.filter((user) => {
+ if (!user.data) {
+ return false;
+ }
+ if (!user.geo) {
+ return false;
+ }
+ if (!user.data.urls) {
+ return false;
+ }
+ if (user.data && user.data.jsError) {
+ return false;
+ }
+ if (!user.detail.name) {
+ return true;
+ }
+ if (user.data.urls.find((l) => l.name == 'Email') == undefined) {
+ return true;
+ }
+ if (user.moderation !== 'accepted') {
+ return true;
+ }
+ return false;
+ });
+};
+exports.filter_invalid = filter_invalid;
+const filter_email_missing = (users) => {
+ return users.filter((user) => {
+ if (!user.data) {
+ return false;
+ }
+ if (!user.geo) {
+ return false;
+ }
+ if (!user.data.urls) {
+ return false;
+ }
+ if (user.data && user.data.jsError) {
+ return false;
+ }
+ if (!user.detail) {
+ return false;
+ }
+ if (!user.detail.name) {
+ return false;
+ }
+ if (user.moderation !== 'accepted') {
+ return false;
+ }
+ if (!user.data.urls.find((l) => l.name == 'Email')) {
+ return true;
+ }
+ return false;
+ });
+};
+exports.filter_email_missing = filter_email_missing;
+const filter_accepted = (users) => {
+ return users.filter((user) => {
+ if (!user.data) {
+ return false;
+ }
+ if (!user.geo) {
+ return false;
+ }
+ if (!user.data.urls) {
+ return false;
+ }
+ if (!user.detail.heroImageUrl) {
+ return false;
+ }
+ if (user.data && user.data.jsError) {
+ return false;
+ }
+ if (user.moderation !== 'accepted') {
+ return false;
+ }
+ return true;
+ });
+};
+exports.filter_accepted = filter_accepted;
+const oa_user_email = (user) => {
+ if (!user.data) {
+ return false;
+ }
+ if (!user.geo) {
+ return false;
+ }
+ if (!user.data.urls) {
+ return false;
+ }
+ if (user.data && user.data.jsError) {
+ return false;
+ }
+ let u = user.data.urls.find((l) => l.name == 'Email');
+ if (u) {
+ return u.url.replace('mailto:', '');
+ }
+};
+exports.oa_user_email = oa_user_email;
+const get_user_name = (user) => {
+ let ret = (0, utils_1.replaceAll)('--', '-', (0, lib_1.sanitize)(filenamify(user._id)).replace(/^\-+/g, '').replace(/\-$/, ''));
+ ret = ret.replace(/\-$/, '');
+ ret = ret.replace(/\_$/, '');
+ if (!(0, exports.oa_user_email)(user)) {
+ ret += '-uc';
+ }
+ return ret;
+};
+exports.get_user_name = get_user_name;
+const get_user_display_name = (user) => (0, utils_1.replaceAll)('--', '-', (0, lib_1.sanitize)(filenamify(user.data.title)).replace(/^\-+/g, '').replace(/\-$/, ''));
+exports.get_user_display_name = get_user_display_name;
+const getDataPath = (_path = '') => path.resolve(path.join((0, fs_1.resolve)(constants_1.DATA_PATH), _path));
+exports.getDataPath = getDataPath;
+const getUsersPath = () => path.resolve((0, fs_1.resolve)(TEST ? constants_1.LATEST_TEST : constants_1.LATEST_TRACK));
+exports.getUsersPath = getUsersPath;
+const getUsers = () => (0, read_1.sync)(path.resolve((0, exports.getUsersPath)()), 'json') || [];
+exports.getUsers = getUsers;
+let uPage = 1;
+let usersAll = [];
+const _getForumUsers = async (d, page, detail) => {
+ if (uPage == 1) {
+ usersAll = [];
+ }
+ let users = await d.getUsers(page);
+ if (users.length) {
+ usersAll = usersAll.concat(users);
+ uPage++;
+ return (0, exports._getForumUsers)(d, uPage, detail);
+ }
+ else {
+ uPage = 1;
+ (0, write_1.sync)(path.resolve(constants_1.F_USERS_NOW), usersAll);
+ let fUsers = (0, read_1.sync)(path.resolve(constants_1.F_USERS_ALL), 'json') || [];
+ const add = async (u) => {
+ return new Promise((resolve, reject) => {
+ let fUser = fUsers.find((fu) => u.id == fu.id);
+ if (!fUser) {
+ fUsers.push(u);
+ fUser = u;
+ }
+ if (!fUser.detail) {
+ index_1.logger.debug('Retrieve User Detail ' + u.name);
+ setTimeout(() => {
+ d.getUser(fUser.id).then((detail) => {
+ if (detail) {
+ fUser.detail = detail;
+ }
+ (0, write_1.sync)(path.resolve('./fusers-all.json'), fUsers);
+ resolve(fUser);
+ });
+ }, 200);
+ }
+ else {
+ resolve(fUser);
+ }
+ });
+ };
+ return await bluebird_1.Promise.resolve(usersAll).map((u) => {
+ return add(u);
+ }, { concurrency: 1 });
+ }
+};
+exports._getForumUsers = _getForumUsers;
+const getForumUsers = async (d, detail) => {
+ if (!constants_1.FETCH_DUSERS) {
+ return (0, read_1.sync)((0, exports.getDataPath)(constants_1.F_USERS_ALL), 'json') || [];
+ }
+ return (0, exports._getForumUsers)(d, uPage, detail);
+};
+exports.getForumUsers = getForumUsers;
+const createUser = async (discourse, oa_user) => {
+ /*
+ Bazar
+ https://shop.osr-plastic.org
+ Website
+ website2
+ Instagram
+ https://www.instagram.com/osr_plastic/
+ Directory / Map Url
+ https://www.google.com/maps/contrib/117674167598277014013
+ OSR - Marketplace Url
+ https://shop.osr-plastic.org/plastichub/
+ */
+ if (!oa_user.data.title) {
+ return -120;
+ }
+ let name = (0, utils_1.replaceAll)('--', '-', (0, exports.get_user_display_name)(oa_user).replace(/^\-+/g, '').replace(/\-$/, ''));
+ let user_name = (0, exports.get_user_name)(oa_user);
+ name = user_name.replace(/\-$/, '');
+ name = user_name.replace(/\_$/, '');
+ let opts = {
+ "name": name,
+ "email": (0, exports.oa_user_email)(oa_user) || `${user_name}_uc@osr-plastic.org`,
+ "password": (0, constants_1.DEFAULT_PASSWORD)(),
+ "username": user_name,
+ "active": true,
+ "approved": true,
+ "user_fields[1]": true
+ };
+ let user = await discourse.createUser(opts);
+ if (name.length < 4) {
+ return -120;
+ }
+ if (user_name.length > 50) {
+ return -120;
+ }
+ if (user && user.errors) {
+ if (user.message === "Username must be no more than 50 characters" ||
+ user.message === 'Username must not contain a sequence of 2 or more special chars (.-_)') {
+ return -120;
+ }
+ if (user.message === "Username must be unique" || user.message === "Primary email has already been taken") {
+ return -100;
+ }
+ if (user.errors.email && user.errors.username) {
+ user = await discourse.getUserByUsername(user_name);
+ if (user && user.id && !oa_user._didSetGroup) {
+ try {
+ let gret = await discourse.updateGroup(user_name, constants_1.OA_USER_IMPORT_GROUP);
+ }
+ catch (e) {
+ index_1.logger.error('error adding to group', user_name);
+ }
+ return user.id;
+ }
+ ;
+ }
+ index_1.logger.error('Error creating user ' + user_name, user.errors);
+ }
+ if (user && user.user_id) {
+ try {
+ await discourse.updateGroup(user_name, constants_1.OA_USER_IMPORT_GROUP);
+ return user.user_id;
+ }
+ catch (e) {
+ index_1.logger.error('error adding to group', user_name);
+ return user.user_id;
+ }
+ }
+ else {
+ if (user && user.message && user.message == 'Username must be unique\nPrimary email has already been taken') {
+ index_1.logger.error('already created', oa_user.detail.name);
+ return -10;
+ }
+ else if (user && user.message && user.message == 'Your account is activated and ready to use.') {
+ if (user.user_id) {
+ return user.user_id;
+ }
+ return -10;
+ }
+ else {
+ index_1.logger.debug('cant create user ' + oa_user.detail.name, user);
+ }
+ return null;
+ }
+ return null;
+};
+exports.createUser = createUser;
+const uploadAvatar = async (discourse, name, filePath) => {
+ const users = (0, exports.getUsers)();
+ const index = users.findIndex((u) => u.detail.name == name);
+ try {
+ const upped = await discourse.upload(1, filePath);
+ const data = upped.data;
+ if (data && data.id) {
+ users[index].upload_id = data.id;
+ index_1.logger.debug('uploaded avatar ' + name + ' ' + data.id);
+ (0, write_1.sync)((0, exports.getUsersPath)(), users);
+ }
+ else {
+ index_1.logger.error('upload - error', name);
+ }
+ return users;
+ }
+ catch (error) {
+ users[index].upload_id = -1;
+ index_1.logger.error('error uploading avatar', name);
+ (0, write_1.sync)((0, exports.getUsersPath)(), users);
+ }
+};
+exports.uploadAvatar = uploadAvatar;
+const uploadAvatars = async (discourse, users) => {
+ const toBeUploaded = users.filter((u) => {
+ if (u.upload_id) {
+ return false;
+ }
+ const hero = (0, lib_1.getImageName)(u.detail.heroImageUrl);
+ const avatar = findAvatar(u, hero);
+ if (!avatar) {
+ index_1.logger.error('cant find avatar : ', u._id, hero);
+ return false;
+ }
+ u.avatar = avatar;
+ return true;
+ });
+ return await bluebird_1.Promise.resolve(toBeUploaded).map((u) => {
+ if (!u.detail.name) {
+ return;
+ }
+ index_1.logger.debug('upload avatar : ' + u._id);
+ const t = (0, exports.uploadAvatar)(discourse, u.detail.name, u.avatar);
+ return t;
+ }, { concurrency: 1 });
+};
+const findAvatar = (user, filename) => {
+ const root = path.resolve((0, fs_1.resolve)(constants_1.DATA_PATH));
+ const _path = path.resolve(`${root}/${user._id}/${filename}`);
+ if ((0, exists_1.sync)(_path)) {
+ return _path;
+ }
+ const files = fg.sync('**/**/*' + filename + '*', { dot: true, cwd: root, absolute: true });
+ if (files.length == 0) {
+ return false;
+ }
+ return files[0];
+};
+/////////////////////////////////////////////////////
+//
+// users
+//
+const updateUser = async (discorse, oa_user) => {
+ const users = (0, exports.getUsers)();
+ const index = users.findIndex((u) => u.detail.name == oa_user.detail.name);
+ const user_name = (0, utils_1.replaceAll)('--', '-', (0, exports.get_user_name)(oa_user).replace(/^\-+/g, '').replace(/\-$/, ''));
+ let ret = null;
+ try {
+ ret = await discorse.updateUser(user_name, {
+ name: oa_user.data.title
+ });
+ try {
+ let location;
+ if (oa_user.geo) {
+ location = `${oa_user.geo.continent} / ${oa_user.geo.countryName} / ${oa_user.geo.city} `;
+ }
+ let website;
+ if (oa_user.data) {
+ website = oa_user.data.urls.find((l) => l.name == 'Website');
+ if (website) {
+ website = website.url;
+ }
+ }
+ let description;
+ if (oa_user.data) {
+ if (oa_user.data.description) {
+ description += oa_user.data.description;
+ }
+ description += '\n';
+ if (oa_user.data.services) {
+ let services = `### Services \n`;
+ let hasServices = false;
+ for (let s in oa_user.data.services[0]) {
+ if (oa_user.data.services[0][s]) {
+ services += `- [x] ${(0, utils_1.capitalize)(s)}\n`;
+ hasServices = true;
+ }
+ }
+ if (hasServices) {
+ description += services;
+ }
+ }
+ }
+ let links = '';
+ if (oa_user.data.urls) {
+ links = oa_user.data.urls.filter((r) => r.name !== 'Bazar' && r.name !== 'sponsor the work').map((l) => {
+ let label = '' + l.name;
+ if (label === 'Social media') {
+ if (l.url.indexOf('facebook') !== -1) {
+ label = 'Facebook';
+ }
+ if (l.url.indexOf('instagram') !== -1) {
+ label = 'Instagram';
+ }
+ }
+ label += " - " + l.url;
+ label = label.replace("https://", "");
+ label = label.replace("http://", "");
+ label = label.replace("mailto:", "");
+ return `${label} `;
+ }).join(" \n");
+ description += '\n### Links\n';
+ description += links;
+ }
+ if (oa_user.location) {
+ description += `\n\n Get Directions \n`;
+ }
+ let updatePrefs = await discorse.updateUserProfile(user_name, {
+ bio_raw: (0, utils_1.replaceAll)('undefined', '', description),
+ location,
+ website
+ });
+ }
+ catch (error) {
+ index_1.logger.error(`Error updating user prefs : ${user_name}`);
+ }
+ }
+ catch (error) {
+ index_1.logger.error('error updating user', oa_user._id, error.message);
+ return;
+ }
+ if (ret.status === 200) {
+ users[index].didUpdateName = true;
+ index_1.logger.debug('did update user', oa_user._id, ' # ', oa_user.data.title);
+ (0, write_1.sync)((0, exports.getUsersPath)(), users);
+ }
+ else {
+ index_1.logger.error('did update user failed ', oa_user._id);
+ }
+};
+exports.updateUser = updateUser;
+const importUser = async (discorse, oa_user) => {
+ const users = (0, exports.getUsers)();
+ const index = users.findIndex((u) => u._id == oa_user._id);
+ let user = null;
+ try {
+ user = await (0, exports.createUser)(discorse, oa_user);
+ }
+ catch (error) {
+ debugger;
+ index_1.logger.error('error creating user', error);
+ return false;
+ }
+ if (user === -100) {
+ users[index].alreadyExists = true;
+ (0, write_1.sync)((0, exports.getUsersPath)(), users);
+ return;
+ }
+ if (user === -120) {
+ users[index].invalidData = true;
+ (0, write_1.sync)((0, exports.getUsersPath)(), users);
+ return;
+ }
+ if (user && users[index].upload_id && !users[index]._didSetAvatar) {
+ try {
+ await discorse.setUserAvatar((0, exports.get_user_name)(oa_user), users[index].upload_id);
+ }
+ catch (e) {
+ index_1.logger.error('error setting avatar', (0, exports.get_user_name)(oa_user));
+ }
+ }
+ const _t = users[index];
+ if (user > 0) {
+ users[index].f_id = user;
+ users[index]._didSetAvatar = true;
+ users[index]._didSetGroup = true;
+ index_1.logger.debug('\t created ' + oa_user.data.title);
+ (0, write_1.sync)((0, exports.getUsersPath)(), users);
+ }
+ else {
+ index_1.logger.error('cant create user - error', oa_user.detail.name, user);
+ }
+ return users[index];
+};
+exports.importUser = importUser;
+const mergeLatestUsers = (discorse, options, oa_users) => {
+ const users = (0, exports.getUsers)();
+ oa_users.forEach((u) => {
+ const tUser = users.find((tu) => {
+ return tu._id === u._id;
+ });
+ if (!tUser) {
+ users.push(u);
+ }
+ });
+ index_1.logger.debug(`Merged users to ${(0, exports.getUsersPath)()}`);
+ (0, write_1.sync)((0, exports.getUsersPath)(), users);
+ return users;
+};
+exports.mergeLatestUsers = mergeLatestUsers;
+const mergeLatestUsersTest = (discorse, options, oa_users) => {
+ const users = ((0, read_1.sync)(constants_1.LATEST_TEST, 'json') || []);
+ oa_users.forEach((u) => {
+ const tUser = users.find((u) => {
+ return u._id === u._id;
+ });
+ if (!tUser) {
+ users.push(u);
+ }
+ });
+ (0, write_1.sync)(options.track, users);
+ return users;
+};
+exports.mergeLatestUsersTest = mergeLatestUsersTest;
+const importUsers = async (discorse, options, oa_users) => {
+ index_1.logger.debug('read users from ', path.resolve((0, exports.getUsersPath)()));
+ let users = (0, exports.mergeLatestUsers)(discorse, options, oa_users);
+ //const users = mergeLatestUsersTest(discorse, options, oa_users)
+ users = users.filter((u) => {
+ if (u.f_id || u.f_id < 0) {
+ return false;
+ }
+ if (u.detail.name === 'plastichub' || u.detail.name === 'lu' || u.detail.name === 'timberstar' || u.detail.name === 'nickname') {
+ return false;
+ }
+ if (u.alreadyExists || u.invalidData) {
+ return false;
+ }
+ return true;
+ });
+ index_1.logger.debug('Create Users ' + users.length + ' Total | Left: ' + users.length);
+ await uploadAvatars(discorse, users);
+ return await bluebird_1.Promise.resolve(users).map((u) => {
+ index_1.logger.debug('import user ' + (0, exports.get_user_name)(u));
+ try {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ const d = (0, exports.importUser)(discorse, u);
+ if (d) {
+ d.then(resolve);
+ }
+ else {
+ reject();
+ }
+ }, 500);
+ });
+ }
+ catch (e) {
+ debugger;
+ index_1.logger.error('error creating user ' + u._id, e);
+ }
+ }, { concurrency: 1 });
+};
+exports.importUsers = importUsers;
+const updateUsers = async (discorse, options, oa_users) => {
+ // https://forum.osr-plastic.org/u/easymoulds/preferences/profile
+ const users = (0, exports.mergeLatestUsers)(discorse, options, oa_users);
+ //const users = mergeLatestUsersTest(discorse, options, oa_users)
+ let toBeCreated = users.filter((u) => {
+ if (u.f_id || u.f_id < 0) {
+ return true;
+ }
+ if (u.didUpdateName) {
+ return false;
+ }
+ return true;
+ });
+ const testUser = 'easymoulds';
+ const test = toBeCreated.find((u) => {
+ return u._id === testUser;
+ });
+ // toBeCreated = [test]
+ return await bluebird_1.Promise.resolve(toBeCreated).map((u) => {
+ /*
+ if (u.didUpdateName) {
+ return false
+ }
+ */
+ try {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ const d = (0, exports.updateUser)(discorse, u);
+ if (d) {
+ d.then(resolve);
+ }
+ else {
+ reject();
+ }
+ }, 200);
+ });
+ }
+ catch (e) {
+ debugger;
+ index_1.logger.error('error creating user ' + u._id, e);
+ }
+ }, { concurrency: 1 });
+};
+exports.updateUsers = updateUsers;
+const md_edit_wrap = (content, f, prefix = '', context = '') => {
+ return (0, js_beautify_1.html_beautify)(`${content}
`);
+};
+exports.md_edit_wrap = md_edit_wrap;
+const toHTML = (path, markdown) => {
+ const content = (0, read_1.sync)(path, 'string');
+ if (!markdown) {
+ let converter = new showdown_1.Converter({ tables: true });
+ converter.setOption('literalMidWordUnderscores', 'true');
+ return converter.makeHtml(content);
+ }
+ else {
+ return content;
+ }
+};
+exports.toHTML = toHTML;
+const imageName = (url) => {
+ if (!url) {
+ return "";
+ }
+ try {
+ const parsed = URI.parse(decodeURIComponent(url));
+ const pParsed = path.parse(parsed.path);
+ return (0, lib_1.sanitize)(decodeURIComponent(pParsed.base));
+ }
+ catch (error) {
+ index_1.logger.error('error image name : ', url);
+ return "";
+ }
+};
+exports.imageName = imageName;
+const read_fragments = (src, config, prefix = '', context = '') => {
+ if (!(0, exists_1.sync)(src)) {
+ //debug.warn(`Create template folder ${src}`);
+ (0, dir_1.sync)(src);
+ }
+ let fragments = (0, osr_cli_commons_1.files)(src, '*.html');
+ fragments.map((f) => {
+ config[path.parse(f).name] = (0, exports.md_edit_wrap)((0, exports.toHTML)(f, true), f, prefix, context);
+ });
+ fragments = (0, osr_cli_commons_1.files)(src, '*.md');
+ fragments.map((f) => {
+ config[path.parse(f).name] = (0, exports.md_edit_wrap)((0, exports.toHTML)(f, false), f, prefix, context);
+ });
+ return config;
+};
+exports.read_fragments = read_fragments;
+const indexUsers = async (discorse, options, oa_users) => {
+ let users = (0, exports.mergeLatestUsers)(discorse, options, oa_users);
+ users = users.filter((u) => {
+ if (u.f_id && u.data && u.geo) {
+ return true;
+ }
+ return false;
+ });
+ const continents = [];
+ const countries = [];
+ const navIndex = [];
+ users.forEach((u) => {
+ if (!u.geo || !u.data || u.data.jsError || !u.detail || !u.detail.heroImageUrl) {
+ return;
+ }
+ if (!u.detail.heroImageUrl) {
+ return;
+ }
+ let code = null;
+ if (u.geo.continent && continents.indexOf(u.geo.continent) == -1) {
+ continents.push(u.geo.continent);
+ navIndex.push({
+ title: u.geo.continent,
+ url: `/users/${slugify(u.geo.continent)}.html`,
+ children: [],
+ code: u.geo.continentCode
+ // code:u.geo.continentCode
+ });
+ }
+ if (countries.indexOf(u.geo.countryName) == -1) {
+ countries.push(u.geo.countryName);
+ }
+ const c = navIndex.find((c) => c.title === u.geo.continent);
+ if (c) {
+ const cc = c.children.find((i) => i.title == u.geo.countryName);
+ if (!cc) {
+ c.children.push({
+ title: u.geo.countryName,
+ url: `/users/${slugify(c.title)}.html#${slugify(u.geo.countryName.toLocaleLowerCase())}`,
+ postTitle: `Directory - ${u.geo.countryName}`
+ });
+ }
+ }
+ });
+ navIndex.sort((a, b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+ if (a.title > b.title) {
+ return 1;
+ }
+ return 0;
+ });
+ navIndex.forEach((c) => {
+ c.children.sort((a, b) => {
+ if (a.title < b.title) {
+ return -1;
+ }
+ if (a.title > b.title) {
+ return 1;
+ }
+ return 0;
+ });
+ });
+ const directoryRoot = path.resolve((0, fs_1.resolve)('${OSR_ROOT}/osr-directory/pp'));
+ const createContinentPage = (continent) => {
+ const templates_path = path.resolve(`${directoryRoot}/templates`);
+ if (!(0, exists_1.sync)(templates_path)) {
+ index_1.logger.error(`\t Cant find templates at ${templates_path}, path doesn't exists`);
+ return;
+ }
+ const cPath = path.resolve(`${directoryRoot}/templates/config.json`);
+ const config = (0, read_1.sync)(cPath, 'json');
+ let fragments = { ...config };
+ (0, exports.read_fragments)(templates_path, fragments, "product_rel_path_name", "machine");
+ let templateCountry = (0, read_1.sync)(path.resolve(`${templates_path}/country_users.md`), 'string');
+ const ccountries = {};
+ let code = null;
+ users.forEach((u) => {
+ if (!u.geo || !u.data || u.data.jsError || !u.detail || !u.detail.heroImageUrl) {
+ return;
+ }
+ if (!u.detail.heroImageUrl) {
+ return;
+ }
+ if (u.geo.continent && u.geo.continent === continent) {
+ if (!code) {
+ code = u.geo.continentCode;
+ }
+ if (!ccountries[u.geo.countryName]) {
+ ccountries[u.geo.countryName] = [];
+ }
+ ccountries[u.geo.countryName].push(u);
+ }
+ });
+ if (continent === 'Africa') {
+ //debugger;
+ }
+ let weight = 100;
+ for (var country in ccountries) {
+ let cPage = "";
+ if (country === 'Kenya') {
+ //debugger;
+ }
+ cPage += `\n#### ${slugify(country)}\n\n`;
+ if (country === 'undefined' || country === 'unknown' || !country) {
+ return;
+ }
+ cPage += '';
+ cPage += '
';
+ let cusers = ccountries[country];
+ cusers = cusers.sort((a, b) => a.type === b.type ? 1 : -1);
+ const cUsersC = cusers.map((u) => {
+ const prefix = u.moderation === 'rejected' ? "
Censored " : "";
+ const image = `/users/${u._id}/${encodeURIComponent((0, lib_1.sanitize)((0, exports.imageName)(u.detail.heroImageUrl)))}`;
+ const title = u.data && u.data.title ? u.data.title : u._id;
+ const uUrl = `/directory/users/${u._id}`;
+ let censored = u.moderation === 'rejected' ? '
Yes ' : 'No';
+ return `
+
+
+
+
${title}
+
Type: ${u.type}
+
Censored: ${censored}
+
+
${u.geo.principalSubdivision} / ${u.geo.locality} - ${u.geo.principalSubdivisionCode} - ${u.geo.postcode}
+
+
`;
+ });
+ cPage += cUsersC.join('');
+ cPage += '
';
+ country = country.replace(' (the)', '');
+ /*
+ const cPagePath = path.resolve(`${kb}/src/directory/users_${sanitize(slugify(country))}-${code}.md`)
+
+ const title = 'Users - ' + country;
+
+ cPage = substitute(templateCountry, {
+ ...fragments,
+ title: title,
+ keywords: 'Precious Plastic, Precious Plastic Users - ' + country,
+ content: html_beautify(cPage),
+ continent: slugify(continent),
+ country: slugify(country),
+ identifier: country + "-" + continent,
+ weight: weight
+ });
+
+ weight++;
+ write(cPagePath, cPage);
+ console.log('write ' + cPagePath);
+ */
+ }
+ /*
+ content = substitute(template, {
+ ...fragments,
+ title: 'Precious Plastic - Users ' + continent,
+ keywords: 'Precious Plastic, Precious Plastic Users - ' + continent,
+ content: content,
+ continent: slugify(continent)
+ });
+ */
+ //const index_md = path.resolve(`${root}/_pages/users_${code}.md`);
+ //write(index_md, content);
+ };
+ const templates_path = path.resolve(`${directoryRoot}/templates`);
+ const createCountryPages = async (index, indexPath) => {
+ let i = 0;
+ for await (const continent of index) {
+ const countries = continent.children;
+ for await (const country of countries) {
+ const d = 0;
+ }
+ }
+ };
+ await createCountryPages(navIndex, './');
+ const createIntroPage = async (users, index, dst) => {
+ let template = (0, read_1.sync)(path.resolve(`${templates_path}/intro_users.md`));
+ let content = "";
+ const usersPerCountry = (country) => {
+ return users.filter((u) => u.geo.countryName === country);
+ };
+ index.forEach((i) => {
+ const heading = `## ${i.title}`;
+ let countries = '';
+ i.children.forEach((c) => {
+ let title = c.title.replace(/ *\([^)]*\) */g, "");
+ const nb = usersPerCountry(c.title).length;
+ title = `${title} \(${nb}\)`;
+ const cPagePath = `/directory/users_${(0, lib_1.sanitize)(slugify(c.title))}-${i.code}`;
+ countries += `- [${(title)}](${cPagePath.toLowerCase()})\n`;
+ });
+ content += `${heading}\n ${countries}`;
+ });
+ (0, write_1.sync)(dst, (0, core_1.substitute)(template, {
+ content: content,
+ /*hidden: data.v3_mappins.filter((u) => u.moderation !== "accepted").length,
+ total: data.v3_mappins.length*/
+ }));
+ let data;
+ try {
+ data = await discorse.updatePost(constants_1.OA_DIRECTORY_OVERVIEW_TOPIC, content);
+ debugger;
+ //logger.debug('update post : ' + options.title + ' : ' + data.id + ' | topic id ' + data.topic_id)
+ }
+ catch (e) {
+ return false;
+ }
+ };
+ // await createIntroPage(users, navIndex, './index.md')
+ /*
+
+ return await BPromise.resolve(users).map((u: IImportUser) => {
+ try {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ const d = updateUser(discorse, u)
+ if (d) {
+ d.then(resolve)
+ } else {
+ reject()
+ }
+ }, 200)
+
+ })
+
+ } catch (e) {
+ debugger;
+ logger.error('error creating user ' + u._id, e)
+ }
+ }, { concurrency: 1 })
+
+ */
+};
+exports.indexUsers = indexUsers;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL29hL3VzZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHVDQUE4QztBQUs5QywrQkFBOEM7QUFFOUMsa0RBQXdFO0FBQ3hFLDZCQUE0QjtBQUM1Qiw4Q0FBa0Q7QUFDbEQsa0RBQXNEO0FBQ3RELGdEQUFvRDtBQUVwRCx1REFBd0Q7QUFFeEQsdUNBQW9DO0FBRXBDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUVsQywyQ0FBNEQ7QUFFNUQsNkNBQTJDO0FBQzNDLDRDQUFrRDtBQUNsRCxpRUFBa0U7QUFDbEUsdUNBQW9DO0FBQ3BDLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQTtBQUU3QixzREFXK0I7QUFLL0IsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFBO0FBQ3hDLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQTtBQUcvQixNQUFNLElBQUksR0FBRyxLQUFLLENBQUE7QUFJWCxNQUFNLFVBQVUsR0FBRyxDQUFDLEdBQVcsRUFBZ0IsRUFBRTtJQUNwRCxNQUFNLEdBQUcsR0FBRyxJQUFBLFdBQUksRUFBQyxHQUFHLEVBQUUsTUFBTSxDQUFRLENBQUE7SUFDcEMsT0FBTyxHQUFHLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQTtBQUN2RCxDQUFDLENBQUE7QUFIWSxRQUFBLFVBQVUsY0FHdEI7QUFFTSxNQUFNLFlBQVksR0FBRyxDQUFDLEtBQW9CLEVBQUUsRUFBRTtJQUNqRCxPQUFPLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRTtRQUN6QixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtZQUNaLE9BQU8s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
\ No newline at end of file
diff --git a/packages/discourse/lib/oa/utils.d.ts b/packages/discourse/lib/oa/utils.d.ts
new file mode 100644
index 00000000..90a40b1e
--- /dev/null
+++ b/packages/discourse/lib/oa/utils.d.ts
@@ -0,0 +1,26 @@
+import { Discourser } from '../index';
+export declare const uploadFile: (discourse: any, forum: any, name: any, filePath: any) => Promise;
+export declare const findReplyPage: (b: any, pages: any) => any;
+export declare const findReplyUpload: (u: any, page: any) => any;
+export declare const getPages: (topics: any, topic: any) => any;
+export declare const getReplies: (topics: any, topic: any) => any[];
+export declare const findFile: (folder: any, filename: any) => any;
+export declare const topicFolder: (forum: any, folder: any, title: any) => string;
+export declare const getFUser: (users: any, user_name: any) => any;
+export declare const dOptions: {
+ host: string;
+ key: string;
+ username: string;
+ rateLimitConcurrency: number;
+};
+export declare const getOAvatar: (index: any, user: any) => any;
+export declare const getTopics: (index: any) => any[];
+export declare const convert: (input: string) => any;
+export declare const getDiscourse: () => Discourser;
+export declare function inspect(arg: any): string;
+export declare function log(...args: any[]): void;
+export declare function mkdirp(path: string): Promise;
+export declare function readJSON(path: string): Promise;
+export declare function writeJSON(path: string, data: object): Promise;
+export declare function exists(path: string): Promise;
+export declare function escape(path: string): string;
diff --git a/packages/discourse/lib/oa/utils.js b/packages/discourse/lib/oa/utils.js
new file mode 100644
index 00000000..f553ad16
--- /dev/null
+++ b/packages/discourse/lib/oa/utils.js
@@ -0,0 +1,172 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.escape = exports.exists = exports.writeJSON = exports.readJSON = exports.mkdirp = exports.log = exports.inspect = exports.getDiscourse = exports.convert = exports.getTopics = exports.getOAvatar = exports.dOptions = exports.getFUser = exports.topicFolder = exports.findFile = exports.getReplies = exports.getPages = exports.findReplyUpload = exports.findReplyPage = exports.uploadFile = void 0;
+const fs_1 = require("fs");
+const util_1 = require("util");
+const cwd = process.cwd();
+var TurndownService = require('turndown');
+const index_1 = require("../index");
+const path = require("path");
+const fg = require('fast-glob');
+const slugify_1 = require("slugify");
+var sanitize = require("sanitize-filename");
+//import { replaceAll } from '../../lib';
+var mom = require('moment');
+const uploadFile = async (discourse, forum, name, filePath) => {
+ return await discourse.upload(1, filePath);
+};
+exports.uploadFile = uploadFile;
+const findReplyPage = (b, pages) => {
+ return pages.find((p) => {
+ return p.replies.find((r) => {
+ return r.replyBody == b;
+ });
+ });
+};
+exports.findReplyPage = findReplyPage;
+const findReplyUpload = (u, page) => {
+ const f_pics = page.f_pics || [];
+ return f_pics.find((p) => {
+ return p.url === u;
+ });
+};
+exports.findReplyUpload = findReplyUpload;
+const getPages = (topics, topic) => {
+ return topics.filter((t) => {
+ return t.title == topic.title;
+ });
+};
+exports.getPages = getPages;
+const getReplies = (topics, topic) => {
+ if (topic.nextPages) {
+ const all = topics.filter((t) => {
+ return t.title == topic.title;
+ });
+ let replies = all.map((t) => t.replies);
+ replies = [].concat.apply([], replies);
+ replies = replies.sort((a, b) => {
+ const d1 = mom(a.replyDate, 'DD/MM/YYYY AT HH:mm').toDate();
+ const d2 = mom(b.replyDate, 'DD/MM/YYYY AT HH:mm').toDate();
+ return new Date(d1).getTime() > new Date(d2).getTime() ? 1 : -1;
+ });
+ return replies;
+ /*
+ const findReply = (b, pages) => {
+ return pages.find((p) => {
+ return p.replies.find((r) => {
+ return r.replyBody == b;
+ })
+ })
+ }
+ const p = findReply('\n\n\nsounds great, let me get Old Tony´s Schaeubling 13 and a surface grinder first, after that I can do the parts for the espresso machine in the best maker porn fashion possible, no seriously, every time I thought I know something, there’s just another video around the next corner making me cry like a baby, incl. the coffee machine
\n', all);
+ debugger;
+ */
+ }
+ return [];
+};
+exports.getReplies = getReplies;
+const findFile = (folder, filename) => {
+ const files = fg.sync('**/**/*' + filename + '*', { dot: true, cwd: folder, absolute: true });
+ if (files.length == 0) {
+ return false;
+ }
+ return files[0];
+};
+exports.findFile = findFile;
+const topicFolder = (forum, folder, title) => {
+ const _title = sanitize((0, slugify_1.default)(title));
+ const tf = path.resolve(forum + '/' + folder + '/' + _title);
+ return tf;
+};
+exports.topicFolder = topicFolder;
+const getFUser = (users, user_name) => {
+ return users.find((u) => {
+ return u.name == user_name;
+ });
+};
+exports.getFUser = getFUser;
+exports.dOptions = {
+ host: 'https://forum.osr-plastic.org',
+ key: 'f624b8385fb2219cb49de63d1e22883afdf7b7367a0bebf822523f49f2678031',
+ username: 'admin',
+ rateLimitConcurrency: 1
+};
+const getOAvatar = (index, user) => {
+ const topics = (0, exports.getTopics)(index);
+ let topic = topics.find((t) => {
+ return t.authorName == user;
+ });
+ if (topic) {
+ return topic.authorImage;
+ }
+ for (let i = 0; i < topics.length; i++) {
+ const t = topics[i];
+ if (t.replies) {
+ const r = t.replies.find((r) => {
+ return r.user == user;
+ });
+ if (r) {
+ return r.avatar;
+ }
+ }
+ }
+ return null;
+};
+exports.getOAvatar = getOAvatar;
+const getTopics = (index) => {
+ let topics = [];
+ for (let t in index) {
+ topics.push(index[t]);
+ }
+ return topics;
+};
+exports.getTopics = getTopics;
+const convert = (input) => {
+ var turndownService = new TurndownService();
+ return turndownService.turndown(input);
+};
+exports.convert = convert;
+const getDiscourse = () => {
+ return new index_1.Discourser(exports.dOptions);
+};
+exports.getDiscourse = getDiscourse;
+function inspect(arg) {
+ return (0, util_1.inspect)(arg, {
+ depth: 5,
+ colors: true,
+ });
+}
+exports.inspect = inspect;
+function log(...args) {
+ console.log(...args.map((arg) => inspect(arg)));
+}
+exports.log = log;
+async function mkdirp(path) {
+ try {
+ await fs_1.default.promises.mkdir(path);
+ }
+ catch (err) {
+ // don't care if it already exists
+ }
+}
+exports.mkdirp = mkdirp;
+async function readJSON(path) {
+ const text = await fs_1.default.promises.readFile(path, 'utf8');
+ return JSON.parse(text);
+}
+exports.readJSON = readJSON;
+function writeJSON(path, data) {
+ return fs_1.default.promises.writeFile(path, JSON.stringify(data));
+}
+exports.writeJSON = writeJSON;
+function exists(path) {
+ return new Promise(function (resolve) {
+ fs_1.default.exists(path, resolve);
+ });
+}
+exports.exists = exists;
+function escape(path) {
+ return path.replace(/[^\w]/g, '-').replace(/-+/, '-');
+}
+exports.escape = escape;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL29hL3V0aWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJCQUFtQjtBQUNuQiwrQkFBNkM7QUFFN0MsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFBO0FBQ3pCLElBQUksZUFBZSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQTtBQUN6QyxvQ0FBcUM7QUFHckMsNkJBQTRCO0FBQzVCLE1BQU0sRUFBRSxHQUFHLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQTtBQUMvQixxQ0FBNkI7QUFFN0IsSUFBSSxRQUFRLEdBQUcsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUE7QUFLM0MseUNBQXlDO0FBR3pDLElBQUksR0FBRyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQTtBQUVwQixNQUFNLFVBQVUsR0FBRyxLQUFLLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEVBQUU7SUFDcEUsT0FBTyxNQUFNLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQzVDLENBQUMsQ0FBQTtBQUZZLFFBQUEsVUFBVSxjQUV0QjtBQUVNLE1BQU0sYUFBYSxHQUFHLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxFQUFFO0lBQ3pDLE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1FBQ3ZCLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUMzQixPQUFPLENBQUMsQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFBO0lBQ0gsQ0FBQyxDQUFDLENBQUE7QUFDSCxDQUFDLENBQUE7QUFOWSxRQUFBLGFBQWEsaUJBTXpCO0FBRU0sTUFBTSxlQUFlLEdBQUcsQ0FB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
\ No newline at end of file
diff --git a/packages/discourse/lib/osr/index.d.ts b/packages/discourse/lib/osr/index.d.ts
new file mode 100644
index 00000000..ffd16f3f
--- /dev/null
+++ b/packages/discourse/lib/osr/index.d.ts
@@ -0,0 +1 @@
+export * from './urls';
diff --git a/packages/discourse/lib/osr/index.js b/packages/discourse/lib/osr/index.js
new file mode 100644
index 00000000..8811f26b
--- /dev/null
+++ b/packages/discourse/lib/osr/index.js
@@ -0,0 +1,18 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+__exportStar(require("./urls"), exports);
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL29zci9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7O0FBQUEseUNBQXNCIn0=
\ No newline at end of file
diff --git a/packages/discourse/lib/osr/urls.d.ts b/packages/discourse/lib/osr/urls.d.ts
new file mode 100644
index 00000000..84d162bd
--- /dev/null
+++ b/packages/discourse/lib/osr/urls.d.ts
@@ -0,0 +1 @@
+export declare const marketplaceUrl: (store: any, product_id: any) => string;
diff --git a/packages/discourse/lib/osr/urls.js b/packages/discourse/lib/osr/urls.js
new file mode 100644
index 00000000..e70e6a6b
--- /dev/null
+++ b/packages/discourse/lib/osr/urls.js
@@ -0,0 +1,6 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.marketplaceUrl = void 0;
+const marketplaceUrl = (store, product_id) => `${store}/dispatch=products.view&product_id=${product_id}`;
+exports.marketplaceUrl = marketplaceUrl;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXJscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvb3NyL3VybHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQU8sTUFBTSxjQUFjLEdBQUcsQ0FBQyxLQUFLLEVBQUUsVUFBVSxFQUFFLEVBQUUsQ0FDaEQsR0FBRyxLQUFLLHNDQUFzQyxVQUFVLEVBQUUsQ0FBQTtBQURqRCxRQUFBLGNBQWMsa0JBQ21DIn0=
\ No newline at end of file
diff --git a/packages/discourse/lib/sync/commons.d.ts b/packages/discourse/lib/sync/commons.d.ts
new file mode 100644
index 00000000..252f5882
--- /dev/null
+++ b/packages/discourse/lib/sync/commons.d.ts
@@ -0,0 +1,12 @@
+///
+import { IOptionsSync, IOptionsSyncComponent } from '../../';
+export declare const fileAsBuffer: (path: string) => Buffer;
+export declare const images_urls: (content: string) => any[];
+export declare const adjustUrls: (content: string, options: IOptionsSync) => string;
+export declare const fromJSON: (content: string, file: string, options: IOptionsSyncComponent) => void;
+export declare const fromYAML: (content: string, options: IOptionsSync) => {
+ attributes: any;
+ body: any;
+};
+export declare const option: (option: string, taskOptions: any, col: any, _default?: any) => any;
+export declare const createContent: (file: any, _options: any) => Promise;
diff --git a/packages/discourse/lib/sync/commons.js b/packages/discourse/lib/sync/commons.js
new file mode 100644
index 00000000..42a4c364
--- /dev/null
+++ b/packages/discourse/lib/sync/commons.js
@@ -0,0 +1,174 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.createContent = exports.option = exports.fromYAML = exports.fromJSON = exports.adjustUrls = exports.images_urls = exports.fileAsBuffer = void 0;
+const path = require("path");
+const Engine_1 = require("@plastichub/osrl/Engine");
+const options_1 = require("@plastichub/osrl/options");
+const glob_1 = require("@plastichub/osr-cli-commons/glob");
+const fs_1 = require("@plastichub/osr-commons");
+const __1 = require("../../");
+const exists_1 = require("@plastichub/fs/exists");
+const read_1 = require("@plastichub/fs/read");
+const write_1 = require("@plastichub/fs/write");
+const bluebird_1 = require("bluebird");
+const constants_1 = require("../../constants");
+const chokidar = require("chokidar");
+const cheerio = require('cheerio');
+const frontMatter = require('front-matter');
+const fileAsBuffer = (path) => (0, read_1.sync)(path, 'buffer') || Buffer.from("-");
+exports.fileAsBuffer = fileAsBuffer;
+const lib_1 = require("@plastichub/osr-cache/lib");
+const osr_cli_commons_1 = require("@plastichub/osr-cli-commons");
+const md5 = require("md5");
+const markdown_1 = require("../markdown");
+const images_urls = (content) => {
+ const html = (0, markdown_1.toHTML)(content);
+ const $ = cheerio.load(html, {
+ xmlMode: true
+ });
+ const images = [];
+ const links = [];
+ $('img').each(function () {
+ images.push($(this).attr('src'));
+ });
+ return images;
+};
+exports.images_urls = images_urls;
+const adjustUrls = (content, options) => {
+ let ret = new markdown_1.RMark({
+ images: (match, capture, arg1, arg2) => ``,
+ //links: (match, capture, arg1, arg2) => `[${capture}](${arg1})`
+ }).render(content);
+ return ret;
+};
+exports.adjustUrls = adjustUrls;
+const fromJSON = (content, file, options) => {
+};
+exports.fromJSON = fromJSON;
+const fromYAML = (content, options) => {
+ if (frontMatter.test(content)) {
+ const fm = frontMatter(content);
+ return {
+ attributes: fm.attributes,
+ body: fm.body
+ };
+ }
+ else {
+ return {
+ attributes: {},
+ body: content
+ };
+ }
+};
+exports.fromYAML = fromYAML;
+// to be changed to osr-defaults
+const option = (option, taskOptions, col, _default) => {
+ // support grunt or yargs
+ const val = col.option ? col.option : (option) => col[option];
+ let ret = taskOptions[option] !== undefined ? taskOptions[option] : _default;
+ if (val(option) !== undefined) {
+ ret = val(option);
+ }
+ return ret;
+};
+exports.option = option;
+const createContent = async (file, _options) => {
+ const parts = path.parse(file);
+ const rel = path.relative(_options.root, file);
+ let output = _options.output;
+ let outputInfo = (0, glob_1.pathInfo)(_options.output);
+ const variables = {
+ root: '.',
+ cwd: _options.cwd || path.resolve('.'),
+ ..._options.variables
+ };
+ if (!outputInfo.FILE_EXT) {
+ output = path.resolve(`${_options.output}/${path.parse(rel).dir}/${parts.name}.md`);
+ }
+ else {
+ output = path.resolve((0, fs_1.resolve)(output, false, variables));
+ }
+ const defaults = {
+ language: _options.lang,
+ debug: _options.debug,
+ profile: _options.profile,
+ output: output,
+ plugins: _options.plugins,
+ env: _options.env || 'library',
+ cwd: _options.cwd || path.resolve('.'),
+ source: file,
+ variables
+ };
+ const options = (0, options_1.parse)(defaults, defaults);
+ const eOptions = {
+ ...options,
+ root: [
+ ...options.profile.includes,
+ path.parse(file).dir
+ ],
+ toHTML: false,
+ cache: false,
+ keepOutputType: true,
+ trimTagRight: false,
+ trimTagLeft: false,
+ trimOutputRight: false,
+ trimOutputLeft: false,
+ greedy: false
+ };
+ const Engine = new Engine_1.Engine(eOptions);
+ options.source = path.resolve(options.source);
+ const osr_cache = (0, osr_cli_commons_1.OSR_CACHE)();
+ const cached = await (0, lib_1.get_cached)(options.source, eOptions, _options.module || constants_1.MODULE_NAME);
+ if (osr_cache && cached && _options.cache !== false) {
+ options.debug && __1.logger.info('Compile file serving from cache: ' + options.source);
+ let md5Src = md5(Buffer.from(cached));
+ let md5Dst = md5((0, exports.fileAsBuffer)(options.output));
+ if (!(0, exists_1.sync)(options.output) || md5Src !== md5Dst) {
+ (0, write_1.sync)(options.output, cached);
+ }
+ return cached;
+ }
+ options.debug && __1.logger.info('Compile file ' + file, eOptions);
+ let content = await Engine.render(options.source, options.variables);
+ if (_options.onCompiled) {
+ content = await _options.onCompiled(options.source, output, content);
+ }
+ if (osr_cache && _options.cache !== false) {
+ options.debug && __1.logger.info('Write output to cache', output);
+ await (0, lib_1.set_cached)(options.source, eOptions, _options.module || constants_1.MODULE_NAME, content);
+ }
+ let dst = path.resolve((0, fs_1.resolve)(output, false, options.variables));
+ _options.debug && __1.logger.info('Write output to: ', dst);
+ (0, write_1.sync)(dst, content);
+ if (_options.onCompileDone) {
+ await _options.onCompileDone(options.source, dst, options, content);
+ }
+ return content;
+};
+exports.createContent = createContent;
+const watch = async (src, options) => {
+ src = path.resolve(src);
+ const watcher = chokidar.watch(`${src}`, {
+ ignored: /(^|[\/\\])\../,
+ persistent: true
+ });
+ watcher.on('change', async (path) => {
+ await (0, exports.createContent)(path, options);
+ });
+ return watcher;
+};
+const compileAll = async (files, options) => {
+ return await bluebird_1.Promise.resolve(files).map((f) => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ (0, exports.createContent)(f, options).then(() => resolve(true));
+ }, 50);
+ });
+ }, { concurrency: 1 });
+};
+const compileAllEx = async (files, options) => {
+ return await bluebird_1.Promise.resolve(files).map((f) => {
+ return (0, exports.createContent)(f, options);
+ }, { concurrency: 1 });
+};
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvc3luYy9jb21tb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZCQUE0QjtBQUU1QixvREFBMEQ7QUFDMUQsc0RBQWdEO0FBRWhELDJEQUEyRDtBQUMzRCx1REFBd0Q7QUFDeEQsOEJBQW9FO0FBQ3BFLGtEQUFzRDtBQUN0RCw4Q0FBa0Q7QUFDbEQsZ0RBQW9EO0FBRXBELHVDQUE4QztBQUU5QywrQ0FFd0I7QUFFeEIsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFBO0FBQ3BDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUNsQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUE7QUFHcEMsTUFBTSxZQUFZLEdBQUcsQ0FBQyxJQUFZLEVBQUUsRUFBRSxDQUFDLElBQUEsV0FBSSxFQUFDLElBQUksRUFBRSxRQUFRLENBQVcsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0FBQW5GLFFBQUEsWUFBWSxnQkFBdUU7QUFFaEcsbURBQWtFO0FBQ2xFLGlFQUF1RDtBQUV2RCwyQkFBMEI7QUFFMUIsMENBQTJDO0FBQ3BDLE1BQU0sV0FBVyxHQUFHLENBQUMsT0FBZSxFQUFFLEVBQUU7SUFFM0MsTUFBTSxJQUFJLEdBQUcsSUFBQSxpQkFBTSxFQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQzVCLE1BQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFO1FBQ3pCLE9BQU8sRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztJQUVILE1BQU0sTUFBTSxHQUFHLEVBQUUsQ0FBQTtJQUNqQixNQUFNLEtBQUssR0FBRyxFQUFFLENBQUE7SUFDaEIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNWLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBO0lBQ3BDLENBQUMsQ0FBQyxDQUFBO0lBRUYsT0FBTyxNQUFNLENBQUE7QUFDakIsQ0FBQyxDQUFBO0FBZFksUUFBQSxXQUFXLGVBY3ZCO0FBRU0sTUFBTSxVQUFVLEdBQUcsQ0FBQyxPQUFlLEVBQUUsT0FBcUIsRUFBRSxFQUFFO0lBQ2pFLElBQUksR0FBRyxHQUFHLElBQUksZ0JBQUssQ0FDZjtRQUNJLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsS0FBSyxPQUFPLEtBQUssSUFBSSxHQUFHO1FBQ2hFLGdFQUFnRTtLQUNuRSxDQUNKLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ2pCLE9BQU8sR0FBRyxDQUFBO0FBQ2QsQ0FBQyxDQUFBO0FBUlksUUFBQSxVQUFVLGNBUXRCO0FBQ00sTUFBTSxRQUFRLEdBQUcsQ0FBQyxPQUFlLEVBQUUsSUFBVyxFQUFFLE9BQThCLEVBQUUsRUFBRTtBQUV6RixDQUFDLENBQUE7QUFGWSxRQUFBLFFBQVEsWUFFcEI7QUFDTSxNQUFNLFFBQVEsR0FBRyxDQUFDLE9BQWUsRUFBRSxPQUFxQixFQUFFLEVBQUU7SUFDL0QsSUFBSSxXQUFXLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQzNCLE1BQU0sRUFBRSxHQUFHLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUMvQixPQUFPO1lBQ0gsVUFBVSxFQUFFLEVBQUUsQ0FBQyxVQUFVO1lBQ3pCLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSTtTQUNoQixDQUFBO0tBQ0o7U0FBTTtRQUNILE9BQU87WUFDSCxVQUFVLEVBQUUsRUFBRTtZQUNkLElBQUksRUFBRSxPQUFPO1NBQ2hCLENBQUE7S0FDSjtBQUNMLENBQUMsQ0FBQTtBQWJZLFFBQUEsUUFBUSxZQWFwQjtBQUVELGdDQUFnQztBQUN6QixNQUFNLE1BQU0sR0FBRyxDQUFDLE1BQWMsRUFBRSxXQUFnQixFQUFFLEdBQUcsRUFBRSxRQUFjLEVBQUUsRUFBRTtJQUU1RSx5QkFBeUI7SUFDekIsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUU3RCxJQUFJLEdBQUcsR0FBRyxXQUFXLENBQUMsTUFBTSxDQUFDLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztJQUM3RSxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxTQUFTLEVBQUU7UUFDM0IsR0FBRyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQTtLQUNwQjtJQUNELE9BQU8sR0FBRyxDQUFBO0FBQ2QsQ0FBQyxDQUFBO0FBVlksUUFBQSxNQUFNLFVBVWxCO0FBRU0sTUFBTSxhQUFhLEdBQUcsS0FBSyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsRUFBRTtJQUNsRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9CLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztJQUUvQyxJQUFJLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDO0lBQzdCLElBQUksVUFBVSxHQUFHLElBQUEsZUFBUSxFQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUMxQyxNQUFNLFNBQVMsR0FBRztRQUNkLElBQUksRUFBRSxHQUFHO1FBQ1QsR0FBRyxFQUFFLFFBQVEsQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUM7UUFDdEMsR0FBRyxRQUFRLENBQUMsU0FBUztLQUN4QixDQUFBO0lBRUQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxRQUFRLEVBQUU7UUFDdEIsTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxRQUFRLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFBO0tBQ3RGO1NBQU07UUFDSCxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFBLFlBQU8sRUFBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7S0FDNUQ7SUFFRCxNQUFNLFFBQVEsR0FBUTtRQUNsQixRQUFRLEVBQUUsUUFBUSxDQUFDLElBQUk7UUFDdkIsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLO1FBQ3JCLE9BQU8sRUFBRSxRQUFRLENBQUMsT0FBTztRQUN6QixNQUFNLEVBQUUsTUFBTTtRQUNkLE9BQU8sRUFBRSxRQUFRLENBQUMsT0FBTztRQUN6QixHQUFHLEVBQUUsUUFBUSxDQUFDLEdBQUcsSUFBSSxTQUFTO1FBQzlCLEdBQUcsRUFBRSxRQUFRLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDO1FBQ3RDLE1BQU0sRUFBRSxJQUFJO1FBQ1osU0FBUztLQUNaLENBQUE7SUFHRCxNQUFNLE9BQU8sR0FBRyxJQUFBLGVBQUssRUFBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDMUMsTUFBTSxRQUFRLEdBQUc7UUFDYixHQUFHLE9BQU87UUFDVixJQUFJLEVBQUU7WUFDRixHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsUUFBUTtZQUMzQixJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUc7U0FDdkI7UUFDRCxNQUFNLEVBQUUsS0FBSztRQUNiLEtBQUssRUFBRSxLQUFLO1FBQ1osY0FBYyxFQUFFLElBQUk7UUFDcEIsWUFBWSxFQUFFLEtBQUs7UUFDbkIsV0FBVyxFQUFFLEtBQUs7UUFDbEIsZUFBZSxFQUFFLEtBQUs7UUFDdEIsY0FBYyxFQUFFLEtBQUs7UUFDckIsTUFBTSxFQUFFLEtBQUs7S0FDSixDQUFBO0lBRWIsTUFBTSxNQUFNLEdBQUcsSUFBSSxlQUFNLENBQUMsUUFBUSxDQUFDLENBQUE7SUFFbkMsT0FBTyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUU3QyxNQUFNLFNBQVMsR0FBRyxJQUFBLDJCQUFTLEdBQUUsQ0FBQTtJQUM3QixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUEsZ0JBQVUsRUFBQyxPQUFPLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsTUFBTSxJQUFJLHVCQUFXLENBQUMsQ0FBQTtJQUV6RixJQUFJLFNBQVMsSUFBSSxNQUFNLElBQUksUUFBUSxDQUFDLEtBQUssS0FBSyxLQUFLLEVBQUU7UUFDakQsT0FBTyxDQUFDLEtBQUssSUFBSSxVQUFNLENBQUMsSUFBSSxDQUFDLG1DQUFtQyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUVsRixJQUFJLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLElBQUksTUFBTSxHQUFHLEdBQUcsQ0FBQyxJQUFBLG9CQUFZLEVBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLElBQUEsYUFBTSxFQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxNQUFNLEtBQUssTUFBTSxFQUFFO1lBQzlDLElBQUEsWUFBSyxFQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7U0FDakM7UUFDRCxPQUFPLE1BQU0sQ0FBQTtLQUNoQjtJQUVELE9BQU8sQ0FBQyxLQUFLLElBQUksVUFBTSxDQUFDLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFBO0lBRTlELElBQUksT0FBTyxHQUFHLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUVwRSxJQUFJLFFBQVEsQ0FBQyxVQUFVLEVBQUU7UUFDckIsT0FBTyxHQUFHLE1BQU0sUUFBUSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQTtLQUN2RTtJQUVELElBQUksU0FBUyxJQUFJLFFBQVEsQ0FBQyxLQUFLLEtBQUssS0FBSyxFQUFFO1FBQ3ZDLE9BQU8sQ0FBQyxLQUFLLElBQUksVUFBTSxDQUFDLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUM3RCxNQUFNLElBQUEsZ0JBQVUsRUFBQyxPQUFPLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsTUFBTSxJQUFJLHVCQUFXLEVBQUUsT0FBTyxDQUFDLENBQUE7S0FDdEY7SUFFRCxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUEsWUFBTyxFQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUE7SUFDakUsUUFBUSxDQUFDLEtBQUssSUFBSSxVQUFNLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBQ3ZELElBQUEsWUFBSyxFQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUVuQixJQUFJLFFBQVEsQ0FBQyxhQUFhLEVBQUU7UUFDeEIsTUFBTSxRQUFRLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQTtLQUN0RTtJQUVELE9BQU8sT0FBTyxDQUFBO0FBQ2xCLENBQUMsQ0FBQTtBQXhGWSxRQUFBLGFBQWEsaUJBd0Z6QjtBQUVELE1BQU0sS0FBSyxHQUFHLEtBQUssRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLEVBQUU7SUFDakMsR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDeEIsTUFBTSxPQUFPLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsRUFBRSxFQUFFO1FBQ3JDLE9BQU8sRUFBRSxlQUFlO1FBQ3hCLFVBQVUsRUFBRSxJQUFJO0tBQ25CLENBQUMsQ0FBQztJQUNILE9BQU8sQ0FBQyxFQUFFLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBQyxJQUFJLEVBQUMsRUFBRTtRQUM5QixNQUFNLElBQUEscUJBQWEsRUFBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDdEMsQ0FBQyxDQUFDLENBQUM7SUFDSCxPQUFPLE9BQU8sQ0FBQTtBQUNsQixDQUFDLENBQUE7QUFFRCxNQUFNLFVBQVUsR0FBRyxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFO0lBQ3hDLE9BQU8sTUFBTSxrQkFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtRQUMzQyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDM0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDWixJQUFBLHFCQUFhLEVBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtZQUN2RCxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFDVixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQzNCLENBQUMsQ0FBQTtBQUVELE1BQU0sWUFBWSxHQUFHLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7SUFDMUMsT0FBTyxNQUFNLGtCQUFRLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFO1FBQzNDLE9BQU8sSUFBQSxxQkFBYSxFQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQTtJQUNwQyxDQUFDLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUMzQixDQUFDLENBQUEifQ==
\ No newline at end of file
diff --git a/packages/discourse/lib/sync/component.d.ts b/packages/discourse/lib/sync/component.d.ts
new file mode 100644
index 00000000..1d3c8b71
--- /dev/null
+++ b/packages/discourse/lib/sync/component.d.ts
@@ -0,0 +1,6 @@
+import { IOptionsSync } from '../../types';
+import { Discourser } from '../discourse';
+export declare const createPost: (discourse: Discourser, options: IOptionsSync, content: any) => Promise;
+export declare const updatePost: (discourse: Discourser, options: IOptionsSync, topic_id: any, content: any) => Promise;
+export declare const syncComponent: (options: IOptionsSync) => Promise;
+export declare const sync: (options: IOptionsSync) => Promise;
diff --git a/packages/discourse/lib/sync/component.js b/packages/discourse/lib/sync/component.js
new file mode 100644
index 00000000..21b2eadf
--- /dev/null
+++ b/packages/discourse/lib/sync/component.js
@@ -0,0 +1,373 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.sync = exports.syncComponent = exports.updatePost = exports.createPost = void 0;
+const path = require("path");
+const exists_1 = require("@plastichub/fs/exists");
+const dir_1 = require("@plastichub/fs/dir");
+const write_1 = require("@plastichub/fs/write");
+const fs_1 = require("@plastichub/osr-commons");
+const bluebird_1 = require("bluebird");
+const osrl_1 = require("./osrl");
+const YAML = require('json-to-pretty-yaml');
+const cheerio = require('cheerio');
+const findUp = require('find-up');
+const frontMatter = require('front-matter');
+const md5 = require('md5');
+const download_1 = require("./download");
+const markdown_1 = require("../markdown");
+const primitives_1 = require("@plastichub/core/primitives");
+const _1 = require("./");
+const cache_1 = require("../discourse/cache");
+const discourse_1 = require("../discourse");
+const commons_1 = require("./commons");
+const osr_fs_utils_1 = require("@plastichub/osr-fs-utils");
+const index_1 = require("../../index");
+const osr_cli_commons_1 = require("@plastichub/osr-cli-commons");
+const CONTENT_TEST = false;
+const SKIP_EXISTING = false;
+const createPost = async (discourse, options, content) => {
+ if (!(0, primitives_1.isNumber)(options.cat)) {
+ index_1.logger.error(`category not a number! ${options.title} `);
+ }
+ let data;
+ try {
+ data = await discourse.createPost(options.title, content, options.cat);
+ }
+ catch (e) {
+ debugger;
+ }
+ if (data) {
+ if (data && data.id) {
+ try {
+ options.post_id = data.id;
+ options.topic_id = data.topic_id;
+ await discourse.changeOwner(options.post_id, options.topic_id, options.user_name);
+ index_1.logger.debug('created topic : ' + options.title + ' : ' + data.id + ' | topic id :' + data.topic_id);
+ return true;
+ }
+ catch (e) {
+ index_1.logger.error('changing owner ' + options.title + ' failed!', e);
+ }
+ }
+ else {
+ index_1.logger.debug('creating ' + options.title + ' failed!', data.errors, data);
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ index_1.logger.error('title already used : ' + options.title);
+ }
+ }
+ }
+ }
+ else {
+ return false;
+ }
+};
+exports.createPost = createPost;
+const updatePost = async (discourse, options, topic_id, content) => {
+ let data;
+ try {
+ data = await discourse.updatePost(topic_id, content);
+ index_1.logger.debug('update post : ' + options.title + ' : ' + data.id + ' | topic id ' + data.topic_id);
+ }
+ catch (e) {
+ return false;
+ }
+ if (data) {
+ if (data && data.id) {
+ try {
+ // logger.debug('change user to ', options.owner);
+ options.post_id = data.id;
+ options.topic_id = data.topic_id;
+ await new Promise(f => setTimeout(f, 1000));
+ await discourse.changeOwner(topic_id, topic_id, options.user_name);
+ return true;
+ }
+ catch (e) {
+ index_1.logger.debug('changing owner ' + options.title + ' failed!');
+ return false;
+ }
+ }
+ else {
+ index_1.logger.debug('creating ' + options.title + ' failed!', data.errors);
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ index_1.logger.error('title already used : ' + options.title);
+ }
+ return false;
+ }
+ }
+ }
+};
+exports.updatePost = updatePost;
+const uploadImages = async (content, discourse, options) => {
+ const root = path.resolve((0, fs_1.resolve)(options.root));
+ if (!(0, exists_1.sync)(root)) {
+ return false;
+ }
+ const track_path = (0, _1.trackingPath)(root);
+ const track = (0, _1.tracking)(root);
+ const html = (0, markdown_1.toHTML)(content);
+ const $ = cheerio.load(html, {
+ xmlMode: true
+ });
+ const images = (0, commons_1.images_urls)(content);
+ $('img').each(function () {
+ if ($(this).attr('src') && $(this).attr('src').length > 5) {
+ images.push($(this).attr('src'));
+ }
+ });
+ for await (const image of Object.entries(images)) {
+ const url = image[1];
+ if (url.length < 10) {
+ continue;
+ }
+ if (url.startsWith('upload:')) {
+ continue;
+ }
+ if (options.uploadRemote && url.startsWith('http')) {
+ const contentHash = md5(content).substring(0, 5);
+ const cache_path = path.resolve((0, fs_1.resolve)('${OSR_CACHE}/discourse-downloads/' + contentHash));
+ if (!(0, exists_1.sync)(cache_path)) {
+ (0, dir_1.sync)(cache_path);
+ }
+ const image_name = (0, download_1.imageName)(url);
+ const image_local = path.join(cache_path, image_name);
+ if (!(0, exists_1.sync)(image_local)) {
+ try {
+ await (0, download_1.downloadFile)(url, cache_path);
+ }
+ catch (e) {
+ continue;
+ }
+ }
+ if (!(0, exists_1.sync)(image_local)) {
+ continue;
+ }
+ if (!track[url]) {
+ const upped = await discourse.uploadFile(options.owner, image_local);
+ const data = upped.data;
+ if (data && data.id) {
+ track[url] = data;
+ (0, write_1.sync)(track_path, track);
+ }
+ else {
+ console.error('error uploading image');
+ }
+ }
+ continue;
+ }
+ if (options.uploadLocal) {
+ const image_path = path.join(root, url);
+ if ((0, exists_1.sync)(image_path) && (!track[url] || options.cache === false)) {
+ const upped = await discourse.uploadFile(options.owner, image_path);
+ const data = upped.data;
+ if (data && data.id) {
+ track[url] = data;
+ (0, write_1.sync)(track_path, track);
+ }
+ else {
+ console.error('error uploading image');
+ }
+ }
+ }
+ }
+ return track;
+};
+const syncFile = async (file, options) => {
+ const discourse = (0, discourse_1.Instance)(null, options.config);
+ let config = (0, _1.fromJSON)(file, options) || {};
+ const componentDir = path.parse(file).dir;
+ // ph3 back sync
+ const rel = (0, osr_cli_commons_1.forward_slash)(path.relative(options.root, componentDir));
+ const productConfigPath = path.join(options.product_root, rel, 'config.json');
+ let body = await (0, osrl_1.createContent)(componentDir, options);
+ let images_track;
+ if (options.uploadLocal || options.uploadRemote) {
+ images_track = await uploadImages(body, discourse, options);
+ const image_urls = (0, commons_1.images_urls)(body);
+ image_urls.forEach((i) => {
+ if (images_track[i]) {
+ body = body.replace(i, images_track[i].short_url);
+ }
+ else {
+ index_1.logger.warn(`Cant resolve image url : ${i} - ${componentDir} ! Image Upload track invalid`);
+ }
+ });
+ }
+ index_1.logger.debug(`Processing ${componentDir}`);
+ const output = path.join(componentDir, '.osr/discourse_raw.md');
+ let dst = path.resolve((0, fs_1.resolve)(output));
+ options.debug && index_1.logger.info('Write output to: ', dst);
+ (0, write_1.sync)(dst, body);
+ let post_id, topic_id;
+ let dOpts = {
+ ...options,
+ cat: config.forumCategory,
+ id: options.id,
+ owner: config.forumUserId || 1,
+ tags: config.forumTags,
+ title: config.name,
+ topic_id: config.forumTopicId,
+ post_id: config.forumPostId
+ };
+ options = {
+ ...options,
+ ...dOpts
+ };
+ const hash = md5(JSON.stringify({
+ cat: dOpts.cat,
+ tags: dOpts.tags,
+ owner: dOpts.owner,
+ body,
+ title: dOpts.title
+ }, null));
+ // const cats = await cacheCategories(options, discourse)
+ // const tags = await cacheTags(options, discourse)
+ const users = await (0, cache_1.cacheUsers)(options, discourse);
+ await new Promise(f => setTimeout(f, 1000));
+ let search = await discourse.search(dOpts.title);
+ await new Promise(f => setTimeout(f, 2000));
+ let dTopic;
+ let dPost;
+ if (search && search.posts && search.topics) {
+ search.topics.forEach((t, i) => {
+ if (t.title === dOpts.title) {
+ dTopic = t;
+ dPost = search.posts[i];
+ topic_id = dTopic.id;
+ post_id = dPost.id;
+ }
+ });
+ }
+ if (!dTopic || !dPost) {
+ console.error('!dTopic || !dPost : cant find ' + dOpts.title);
+ // return
+ }
+ const user = users.find((u) => {
+ return u.id === dOpts.owner;
+ });
+ if (!user) {
+ index_1.logger.error('Invalid user : ', dOpts.owner);
+ return false;
+ }
+ options.user_name = user.username;
+ if (SKIP_EXISTING && hash === config.forumPostHash &&
+ config.forumTopicId && config.forumPostId) {
+ return;
+ }
+ if (CONTENT_TEST) {
+ return;
+ }
+ if (post_id) {
+ if (await (0, exports.updatePost)(discourse, options, post_id, body)) {
+ if (topic_id) {
+ await new Promise(f => setTimeout(f, 2000));
+ await discourse.updateTopic(topic_id, dOpts.cat, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : []);
+ }
+ }
+ else {
+ index_1.logger.error(`Error updating post ${dOpts.title}`);
+ }
+ }
+ else {
+ if (await (0, exports.createPost)(discourse, options, body)) {
+ await new Promise(f => setTimeout(f, 1000));
+ await discourse.updateTopic(options.topic_id, dOpts.cat, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : []);
+ }
+ else {
+ index_1.logger.error('Creating post failed !', dOpts.title);
+ }
+ }
+ // const visStatus = await discourse.updateTopicVisibility(topic_id, true)
+ // re-read without defaults
+ config = (0, osr_fs_utils_1.readOSRConfig)(file);
+ config.forumPostHash = hash;
+ if (dTopic) {
+ config.forumTopicId = dTopic.id;
+ }
+ else if (topic_id) {
+ config.forumTopicId = topic_id;
+ }
+ if (dPost) {
+ config.forumPostId = dPost.id;
+ }
+ else if (post_id) {
+ config.forumPostId = post_id;
+ }
+ (0, write_1.sync)(file, config);
+ //ph3 products
+ if ((0, exists_1.sync)(productConfigPath)) {
+ let pConfig = (0, osr_fs_utils_1.readOSRConfig)(productConfigPath);
+ index_1.logger.debug(`Updating product config ${productConfigPath}`);
+ pConfig = {
+ ...config
+ //...pConfig,
+ //...
+ /*
+ forumTopicId:config.forumTopicId,
+ forumPostId:config.forumPostId,
+ forumPostHash: config.forumPostHash
+ */
+ };
+ (0, write_1.sync)(productConfigPath, pConfig);
+ }
+ return body;
+};
+const syncComponent = async (options) => {
+ let components = options.srcInfo.FILES.filter(osr_fs_utils_1.isValidLibraryComponent);
+ //let components = options.srcInfo.FILES.filter((c) => {
+ //components = components.filter((c) => {
+ /*
+try {
+ const config = readOSRConfig(c) as IComponentConfig
+ if (config) {
+ if (config.forum === false) {
+ return false
+ }
+ // return !config.code && !config.cscartId && !config.steps
+ return !!config.name
+ }
+ return false
+} catch (error) {
+ logger.error(`Invalid config : ${c}`)
+}
+})*/
+ const skipExisting = options.skip;
+ /*
+ [
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/asterix-pp/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/asterix-sm-morren/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/bicycle-shredder/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/idefix/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/obelix/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/pp-v3.3/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/components/shredder_v21-light-ex/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/components/shredder_v31-light/config.json",
+ ]
+ */
+ if (skipExisting) {
+ components = components.filter((f) => {
+ const config = (0, osr_fs_utils_1.readOSRConfig)(f);
+ if (config.forumPostId && config.forumTopicId) {
+ return false;
+ }
+ return true;
+ });
+ }
+ //components = [components[0]]
+ index_1.logger.info(`Syncing ${components.length} components`, components);
+ await bluebird_1.Promise.resolve(components).map((f) => {
+ try {
+ return syncFile(f, options);
+ }
+ catch (error) {
+ debugger;
+ }
+ }, { concurrency: 1 });
+};
+exports.syncComponent = syncComponent;
+const sync = async (options) => {
+ return (0, exports.syncComponent)(options);
+};
+exports.sync = sync;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2xpYi9zeW5jL2NvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2QkFBNEI7QUFDNUIsa0RBQXNEO0FBRXRELDRDQUFnRDtBQUNoRCxnREFBb0Q7QUFHcEQsdURBQXdEO0FBRXhELHVDQUE4QztBQUc5QyxpQ0FBc0M7QUFFdEMsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLHFCQUFxQixDQUFDLENBQUE7QUFDM0MsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFBO0FBQ2xDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUNqQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUE7QUFDM0MsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO0FBRTFCLHlDQUFvRDtBQUVwRCwwQ0FBb0M7QUFDcEMsNERBQXNEO0FBRXRELHlCQUFvRTtBQU9wRSw4Q0FLMkI7QUFHM0IsNENBR3FCO0FBRXJCLHVDQUVrQjtBQVVsQiwyREFBaUY7QUFFakYsdUNBQW9DO0FBQ3BDLGlFQUEyRDtBQUUzRCxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUE7QUFDMUIsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFBO0FBRXBCLE1BQU0sVUFBVSxHQUFHLEtBQUssRUFBRSxTQUFxQixFQUFFLE9BQXFCLEVBQUUsT0FBTyxFQUFFLEVBQUU7SUFFdEYsSUFBSSxDQUFDLElBQUEscUJBQVEsRUFBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUU7UUFDeEIsY0FBTSxDQUFDLEtBQUssQ0FBQywwQkFBMEIsT0FBTyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUE7S0FDM0Q7SUFFRCxJQUFJLElBQVMsQ0FBQTtJQUNiLElBQUk7UUFDQSxJQUFJLEdBQUcsTUFBTSxTQUFTLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLE9BQU8sQ0FBQyxHQUFhLENBQUMsQ0FBQTtLQUNuRjtJQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQ1IsUUFBUSxDQUFBO0tBQ1g7SUFFRCxJQUFJLElBQUksRUFBRTtRQUNOLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxFQUFFLEVBQUU7WUFDakIsSUFBSTtnQkFDQSxPQUFPLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQzFCLE9BQU8sQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQTtnQkFDaEMsTUFBTSxTQUFTLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUE7Z0JBQ2pGLGNBQU0sQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEdBQUcsT0FBTyxDQUFDLEtBQUssR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDLEVBQUUsR0FBRyxlQUFlLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO2dCQUNyRyxPQUFPLElBQUksQ0FBQTthQUNkO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1IsY0FBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsR0FBRyxPQUFPLENBQUMsS0FBSyxHQUFHLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQTthQUNsRTtTQUNKO2FBQU07WUFDSCxjQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsS0FBSyxHQUFHLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzFFLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtnQkFDYixJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyw2QkFBNkIsRUFBRTtvQkFDcEUsY0FBTSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7aUJBQ3hEO2FBQ0o7U0FDSjtLQUNKO1NBQU07UUFDSCxPQUFPLEtBQUssQ0FBQTtLQUNmO0FBQ0wsQ0FBQyxDQUFBO0FBbkNZLFFBQUEsVUFBVSxjQW1DdEI7QUFFTSxNQUFNLFVBQVUsR0FBRyxLQUFLLEVBQUUsU0FBcUIsRUFBRSxPQUFxQixFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsRUFBRTtJQUVoRyxJQUFJLElBQVMsQ0FBQTtJQUNiLElBQUk7UUFDQSxJQUFJLEdBQUcsTUFBTSxTQUFTLENBQUMsVUFBVSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUNwRCxjQUFNLENBQUMsS0FBSyxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxLQUFLLEdBQUcsTUFBTSxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsY0FBYyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQTtLQUNyRztJQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQ1IsT0FBTyxLQUFLLENBQUE7S0FDZjtJQUVELElBQUksSUFBSSxFQUFFO1FBQ04sSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUUsRUFBRTtZQUNqQixJQUFJO2dCQUNBLGtEQUFrRDtnQkFDbEQsT0FBTyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUMxQixPQUFPLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUE7Z0JBQ2hDLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLE1BQU0sU0FBUyxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtnQkFDbEUsT0FBTyxJQUFJLENBQUE7YUFDZDtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNSLGNBQU0sQ0FBQyxLQUFLLENBQUMsaUJBQWlCLEdBQUcsT0FBTyxDQUFDLEtBQUssR0FBRyxVQUFVLENBQUMsQ0FBQTtnQkFDNUQsT0FBTyxLQUFLLENBQUE7YUFDZjtTQUNKO2FBQU07WUFDSCxjQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsR0FBRyxPQUFPLENBQUMsS0FBSyxHQUFHLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUE7WUFDbkUsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUNiLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLDZCQUE2QixFQUFFO29CQUNwRSxjQUFNLENBQUMsS0FBSyxDQUFDLHVCQUF1QixHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQTtpQkFDeEQ7Z0JBQ0QsT0FBTyxLQUFLLENBQUE7YUFDZjtTQUNKO0tBQ0o7QUFDTCxDQUFDLENBQUE7QUFqQ1ksUUFBQSxVQUFVLGNBaUN0QjtBQUlELE1BQU0sWUFBWSxHQUFHLEtBQUssRUFBRSxPQUFlLEVBQUUsU0FBcUIsRUFBRSxPQUFxQixFQUFFLEVBQUU7SUFFekYsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFBLFlBQU8sRUFBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtJQUNoRCxJQUFJLENBQUMsSUFBQSxhQUFNLEVBQUMsSUFBSSxDQUFDLEVBQUU7UUFDZixPQUFPLEtBQUssQ0FBQTtLQUNmO0lBRUQsTUFBTSxVQUFVLEdBQUcsSUFBQSxlQUFZLEVBQUMsSUFBSSxDQUFDLENBQUE7SUFDckMsTUFBTSxLQUFLLEdBQUcsSUFBQSxXQUFRLEVBQUMsSUFBSSxDQUFDLENBQUE7SUFFNUIsTUFBTSxJQUFJLEdBQUcsSUFBQSxpQkFBTSxFQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQzVCLE1BQU0sQ0FBQyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFO1FBQ3pCLE9BQU8sRUFBRSxJQUFJO0tBQ2hCLENBQUMsQ0FBQztJQUVILE1BQU0sTUFBTSxHQUFHLElBQUEscUJBQVcsRUFBQyxPQUFPLENBQUMsQ0FBQTtJQUVuQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ1YsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUN2RCxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQTtTQUNuQztJQUNMLENBQUMsQ0FBQyxDQUFBO0lBRUYsSUFBSSxLQUFLLEVBQUUsTUFBTSxLQUFLLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsRUFBRTtRQUM5QyxNQUFNLEdBQUcsR0FBVyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFFNUIsSUFBSSxHQUFHLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRTtZQUNqQixTQUFRO1NBQ1g7UUFFRCxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEVBQUU7WUFDM0IsU0FBUTtTQUNYO1FBQ0QsSUFBSSxPQUFPLENBQUMsWUFBWSxJQUFJLEdBQUcsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFFaEQsTUFBTSxXQUFXLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUE7WUFDaEQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFBLFlBQU8sRUFBQyxtQ0FBbUMsR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFBO1lBQzNGLElBQUksQ0FBQyxJQUFBLGFBQU0sRUFBQyxVQUFVLENBQUMsRUFBRTtnQkFDckIsSUFBQSxVQUFHLEVBQUMsVUFBVSxDQUFDLENBQUE7YUFDbEI7WUFDRCxNQUFNLFVBQVUsR0FBRyxJQUFBLG9CQUFTLEVBQUMsR0FBRyxDQUFDLENBQUE7WUFDakMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsVUFBVSxDQUFDLENBQUE7WUFDckQsSUFBSSxDQUFDLElBQUEsYUFBTSxFQUFDLFdBQVcsQ0FBQyxFQUFFO2dCQUN0QixJQUFJO29CQUNBLE1BQU0sSUFBQSx1QkFBWSxFQUFDLEdBQUcsRUFBRSxVQUFVLENBQUMsQ0FBQTtpQkFDdEM7Z0JBQUMsT0FBTyxDQUFDLEVBQUU7b0JBQ1IsU0FBUTtpQkFDWDthQUNKO1lBQ0QsSUFBSSxDQUFDLElBQUEsYUFBTSxFQUFDLFdBQVcsQ0FBQyxFQUFFO2dCQUN0QixTQUFRO2FBQ1g7WUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUNiLE1BQU0sS0FBSyxHQUFRLE1BQU0sU0FBUyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxDQUFBO2dCQUN6RSxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO2dCQUN4QixJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsRUFBRSxFQUFFO29CQUNqQixLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFBO29CQUNqQixJQUFBLFlBQUssRUFBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUE7aUJBQzNCO3FCQUFNO29CQUNILE9BQU8sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLENBQUMsQ0FBQTtpQkFDekM7YUFDSjtZQUVELFNBQVE7U0FDWDtRQUVELElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRTtZQUNyQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQTtZQUN2QyxJQUFJLElBQUEsYUFBTSxFQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksT0FBTyxDQUFDLEtBQUssS0FBSyxLQUFLLENBQUMsRUFBRTtnQkFDaEUsTUFBTSxLQUFLLEdBQVEsTUFBTSxTQUFTLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsVUFBVSxDQUFDLENBQUE7Z0JBQ3hFLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUM7Z0JBQ3hCLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxFQUFFLEVBQUU7b0JBQ2pCLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUE7b0JBQ2pCLElBQUEsWUFBSyxFQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQTtpQkFDM0I7cUJBQU07b0JBQ0gsT0FBTyxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFBO2lCQUN6QzthQUNKO1NBQ0o7S0FDSjtJQUVELE9BQU8sS0FBSyxDQUFBO0FBQ2hCLENBQUMsQ0FBQTtBQUVELE1BQU0sUUFBUSxHQUFHLEtBQUssRUFBRSxJQUFZLEVBQUUsT0FBcUIsRUFBRSxFQUFFO0lBRTNELE1BQU0sU0FBUyxHQUFHLElBQUEsb0JBQVEsRUFBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLE1BQTZCLENBQUMsQ0FBQTtJQUV2RSxJQUFJLE1BQU0sR0FBRyxJQUFBLFdBQVEsRUFBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksRUFBc0IsQ0FBQTtJQUU5RCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQTtJQUV6QyxnQkFBZ0I7SUFDaEIsTUFBTSxHQUFHLEdBQUcsSUFBQSwrQkFBYSxFQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFBO0lBQ3BFLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRSxhQUFhLENBQUMsQ0FBQTtJQUU3RSxJQUFJLElBQUksR0FBRyxNQUFNLElBQUEsb0JBQWEsRUFBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFFckQsSUFBSSxZQUFZLENBQUE7SUFFaEIsSUFBSSxPQUFPLENBQUMsV0FBVyxJQUFJLE9BQU8sQ0FBQyxZQUFZLEVBQUU7UUFDN0MsWUFBWSxHQUFHLE1BQU0sWUFBWSxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUE7UUFDM0QsTUFBTSxVQUFVLEdBQUcsSUFBQSxxQkFBVyxFQUFDLElBQUksQ0FBQyxDQUFBO1FBQ3BDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtZQUNyQixJQUFJLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFBRTtnQkFDakIsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQTthQUNwRDtpQkFBTTtnQkFDSCxjQUFNLENBQUMsSUFBSSxDQUFDLDRCQUE0QixDQUFDLE1BQU0sWUFBWSwrQkFBK0IsQ0FBQyxDQUFBO2FBQzlGO1FBQ0wsQ0FBQyxDQUFDLENBQUE7S0FDTDtJQUlELGNBQU0sQ0FBQyxLQUFLLENBQUMsY0FBYyxZQUFZLEVBQUUsQ0FBQyxDQUFDO0lBRTNDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLHVCQUF1QixDQUFDLENBQUE7SUFDL0QsSUFBSSxHQUFHLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFBLFlBQU8sRUFBQyxNQUFNLENBQUMsQ0FBQyxDQUFBO0lBQ3ZDLE9BQU8sQ0FBQyxLQUFLLElBQUksY0FBTSxDQUFDLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxHQUFHLENBQUMsQ0FBQTtJQUN0RCxJQUFBLFlBQUssRUFBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUE7SUFFaEIsSUFBSSxPQUFPLEVBQUUsUUFBUSxDQUFBO0lBRXJCLElBQUksS0FBSyxHQUE4QjtRQUNuQyxHQUFHLE9BQU87UUFDVixHQUFHLEVBQUUsTUFBTSxDQUFDLGFBQWE7UUFDekIsRUFBRSxFQUFFLE9BQU8sQ0FBQyxFQUFFO1FBQ2QsS0FBSyxFQUFFLE1BQU0sQ0FBQyxXQUFXLElBQUksQ0FBQztRQUM5QixJQUFJLEVBQUUsTUFBTSxDQUFDLFNBQW1CO1FBQ2hDLEtBQUssRUFBRSxNQUFNLENBQUMsSUFBSTtRQUNsQixRQUFRLEVBQUUsTUFBTSxDQUFDLFlBQVk7UUFDN0IsT0FBTyxFQUFFLE1BQU0sQ0FBQyxXQUFXO0tBQzlCLENBQUE7SUFFRCxPQUFPLEdBQUc7UUFDTixHQUFHLE9BQU87UUFDVixHQUFHLEtBQUs7S0FDWCxDQUFBO0lBRUQsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDNUIsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHO1FBQ2QsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO1FBQ2hCLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSztRQUNsQixJQUFJO1FBQ0osS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO0tBQ3JCLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQTtJQUtULHlEQUF5RDtJQUN6RCxtREFBbUQ7SUFFbkQsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFBLGtCQUFVLEVBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxDQUFBO0lBQ2xELE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDNUMsSUFBSSxNQUFNLEdBQUcsTUFBTSxTQUFTLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUNoRCxNQUFNLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBRTVDLElBQUksTUFBb0IsQ0FBQTtJQUN4QixJQUFJLEtBQWtCLENBQUE7SUFFdEIsSUFBSSxNQUFNLElBQUksTUFBTSxDQUFDLEtBQUssSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFO1FBQ3pDLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzNCLElBQUksQ0FBQyxDQUFDLEtBQUssS0FBSyxLQUFLLENBQUMsS0FBSyxFQUFFO2dCQUN6QixNQUFNLEdBQUcsQ0FBQyxDQUFBO2dCQUNWLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFBO2dCQUN2QixRQUFRLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQTtnQkFDcEIsT0FBTyxHQUFHLEtBQUssQ0FBQyxFQUFFLENBQUE7YUFDckI7UUFDTCxDQUFDLENBQUMsQ0FBQTtLQUNMO0lBRUQsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLEtBQUssRUFBRTtRQUNuQixPQUFPLENBQUMsS0FBSyxDQUFDLGdDQUFnQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUM3RCxTQUFTO0tBQ1o7SUFFRCxNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7UUFDMUIsT0FBTyxDQUFDLENBQUMsRUFBRSxLQUFLLEtBQUssQ0FBQyxLQUFLLENBQUE7SUFDL0IsQ0FBQyxDQUFDLENBQUE7SUFFRixJQUFJLENBQUMsSUFBSSxFQUFFO1FBQ1AsY0FBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDNUMsT0FBTyxLQUFLLENBQUE7S0FDZjtJQUVELE9BQU8sQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQTtJQUVqQyxJQUFJLGFBQWEsSUFBSSxJQUFJLEtBQUssTUFBTSxDQUFDLGFBQWE7UUFDOUMsTUFBTSxDQUFDLFlBQVksSUFBSSxNQUFNLENBQUMsV0FBVyxFQUFFO1FBQzNDLE9BQU07S0FDVDtJQUVELElBQUksWUFBWSxFQUFFO1FBQ2QsT0FBTTtLQUNUO0lBRUQsSUFBSSxPQUFPLEVBQUU7UUFDVCxJQUFJLE1BQU0sSUFBQSxrQkFBVSxFQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxFQUFFO1lBQ3JELElBQUksUUFBUSxFQUFFO2dCQUNWLE1BQU0sSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLE1BQU0sU0FBUyxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLEdBQWEsRUFBRSxLQUFLLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQTthQUNuSDtTQUNKO2FBQU07WUFDSCxjQUFNLENBQUMsS0FBSyxDQUFDLHVCQUF1QixLQUFLLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQTtTQUNyRDtLQUNKO1NBQU07UUFDSCxJQUFJLE1BQU0sSUFBQSxrQkFBVSxFQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLEVBQUU7WUFDNUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUM1QyxNQUFNLFNBQVMsQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxLQUFLLENBQUMsR0FBYSxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFBO1NBQzNIO2FBQU07WUFDSCxjQUFNLENBQUMsS0FBSyxDQUFDLHdCQUF3QixFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQTtTQUN0RDtLQUNKO0lBRUQsMEVBQTBFO0lBRTFFLDJCQUEyQjtJQUMzQixNQUFNLEdBQUcsSUFBQSw0QkFBYSxFQUFDLElBQUksQ0FBQyxDQUFBO0lBRTVCLE1BQU0sQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFBO0lBRTNCLElBQUksTUFBTSxFQUFFO1FBQ1IsTUFBTSxDQUFDLFlBQVksR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFBO0tBQ2xDO1NBQUssSUFBRyxRQUFRLEVBQUM7UUFDZCxNQUFNLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQTtLQUNqQztJQUVELElBQUksS0FBSyxFQUFFO1FBQ1AsTUFBTSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFBO0tBQ2hDO1NBQUssSUFBRyxPQUFPLEVBQUM7UUFDYixNQUFNLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQTtLQUMvQjtJQUVELElBQUEsWUFBSyxFQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUVuQixjQUFjO0lBQ2QsSUFBSSxJQUFBLGFBQU0sRUFBQyxpQkFBaUIsQ0FBQyxFQUFFO1FBQzNCLElBQUksT0FBTyxHQUFHLElBQUEsNEJBQWEsRUFBQyxpQkFBaUIsQ0FBQyxDQUFBO1FBQzlDLGNBQU0sQ0FBQyxLQUFLLENBQUMsMkJBQTJCLGlCQUFpQixFQUFFLENBQUMsQ0FBQTtRQUM1RCxPQUFPLEdBQUc7WUFDTixHQUFHLE1BQU07WUFDVCxhQUFhO1lBQ2IsS0FBSztZQUNMOzs7O2NBSUU7U0FDTCxDQUFBO1FBQ0QsSUFBQSxZQUFLLEVBQUMsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLENBQUE7S0FDcEM7SUFDRCxPQUFPLElBQUksQ0FBQTtBQUNmLENBQUMsQ0FBQTtBQUVNLE1BQU0sYUFBYSxHQUFHLEtBQUssRUFBRSxPQUFxQixFQUFFLEVBQUU7SUFFekQsSUFBSSxVQUFVLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLHNDQUF1QixDQUFDLENBQUE7SUFDdEUsd0RBQXdEO0lBQ3hELDBDQUEwQztJQUMxQzs7Ozs7Ozs7Ozs7Ozs7SUFjQTtJQUVBLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUE7SUFDakM7Ozs7Ozs7Ozs7O1FBV0k7SUFDSixJQUFJLFlBQVksRUFBRTtRQUNkLFVBQVUsR0FBRyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7WUFDakMsTUFBTSxNQUFNLEdBQUcsSUFBQSw0QkFBYSxFQUFDLENBQUMsQ0FBcUIsQ0FBQTtZQUNuRCxJQUFJLE1BQU0sQ0FBQyxXQUFXLElBQUksTUFBTSxDQUFDLFlBQVksRUFBRTtnQkFDM0MsT0FBTyxLQUFLLENBQUE7YUFDZjtZQUNELE9BQU8sSUFBSSxDQUFBO1FBQ2YsQ0FBQyxDQUFDLENBQUE7S0FDTDtJQUVELDhCQUE4QjtJQUM5QixjQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsVUFBVSxDQUFDLE1BQU0sYUFBYSxFQUFFLFVBQVUsQ0FBQyxDQUFBO0lBQ2xFLE1BQU0sa0JBQVEsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7UUFDekMsSUFBSTtZQUNBLE9BQU8sUUFBUSxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQTtTQUM5QjtRQUFDLE9BQU8sS0FBSyxFQUFFO1lBQ1osUUFBUSxDQUFBO1NBQ1g7SUFDTCxDQUFDLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQTtBQUUxQixDQUFDLENBQUE7QUF0RFksUUFBQSxhQUFhLGlCQXNEekI7QUFFTSxNQUFNLElBQUksR0FBRyxLQUFLLEVBQUUsT0FBcUIsRUFBRSxFQUFFO0lBQ2hELE9BQU8sSUFBQSxxQkFBYSxFQUFDLE9BQU8sQ0FBQyxDQUFBO0FBQ2pDLENBQUMsQ0FBQTtBQUZZLFFBQUEsSUFBSSxRQUVoQiJ9
\ No newline at end of file
diff --git a/packages/discourse/lib/sync/download.d.ts b/packages/discourse/lib/sync/download.d.ts
new file mode 100644
index 00000000..668cfd3d
--- /dev/null
+++ b/packages/discourse/lib/sync/download.d.ts
@@ -0,0 +1,5 @@
+export declare const sanitize: (f: any) => string;
+export declare const sanitize_ex: (f: any) => string;
+export declare const filename: (_url: any) => string;
+export declare const imageName: (url: any) => string;
+export declare const downloadFile: (_url: string, dir: string) => Promise;
diff --git a/packages/discourse/lib/sync/download.js b/packages/discourse/lib/sync/download.js
new file mode 100644
index 00000000..61e62fd7
--- /dev/null
+++ b/packages/discourse/lib/sync/download.js
@@ -0,0 +1,48 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.downloadFile = exports.imageName = exports.filename = exports.sanitize_ex = exports.sanitize = void 0;
+const path = require("path");
+const _sanitize = require("sanitize-filename");
+const filenamify = require('filenamify');
+const download = require("download");
+const URI = require("uri-js");
+const url = require("url");
+const sanitize = (f) => {
+ let str = filenamify(_sanitize(f)).replace(/[^\x00-\x7F]/g, "");
+ if (str.startsWith('_')) {
+ str = str.substring(1);
+ }
+ return str;
+};
+exports.sanitize = sanitize;
+const sanitize_ex = (f) => {
+ let str = filenamify(_sanitize(f)).replace(/[^\x00-\x7F]/g, "").replace('_', '');
+ return str;
+};
+exports.sanitize_ex = sanitize_ex;
+const filename = (_url) => {
+ return path.basename(url.parse(_url).path);
+};
+exports.filename = filename;
+const imageName = (url) => {
+ if (!url) {
+ return "";
+ }
+ try {
+ const parsed = URI.parse(decodeURIComponent(url));
+ const pParsed = path.parse(parsed.path);
+ return (0, exports.sanitize)(decodeURIComponent(pParsed.base));
+ }
+ catch (error) {
+ console.error('error image name : ', url);
+ return "";
+ }
+};
+exports.imageName = imageName;
+const downloadFile = async (_url, dir) => {
+ return download(_url, dir, {
+ filename: (0, exports.imageName)(_url)
+ });
+};
+exports.downloadFile = downloadFile;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG93bmxvYWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3N5bmMvZG93bmxvYWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkJBQTRCO0FBRTVCLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO0FBRTlDLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQTtBQUN4QyxxQ0FBb0M7QUFDcEMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFBO0FBRTdCLDJCQUEwQjtBQUVuQixNQUFNLFFBQVEsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFO0lBQzFCLElBQUksR0FBRyxHQUFXLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3hFLElBQUksR0FBRyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUNyQixHQUFHLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUMxQjtJQUNELE9BQU8sR0FBRyxDQUFDO0FBQ2YsQ0FBQyxDQUFBO0FBTlksUUFBQSxRQUFRLFlBTXBCO0FBRU0sTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRTtJQUM3QixJQUFJLEdBQUcsR0FBVyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ3pGLE9BQU8sR0FBRyxDQUFDO0FBQ2YsQ0FBQyxDQUFBO0FBSFksUUFBQSxXQUFXLGVBR3ZCO0FBRU0sTUFBTSxRQUFRLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRTtJQUM3QixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUMvQyxDQUFDLENBQUE7QUFGWSxRQUFBLFFBQVEsWUFFcEI7QUFHTSxNQUFNLFNBQVMsR0FBRyxDQUFDLEdBQUcsRUFBRSxFQUFFO0lBQzdCLElBQUcsQ0FBQyxHQUFHLEVBQUM7UUFDSixPQUFPLEVBQUUsQ0FBQTtLQUNaO0lBQ0QsSUFBSTtRQUNBLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNsRCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QyxPQUFPLElBQUEsZ0JBQVEsRUFBQyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztLQUNyRDtJQUFDLE9BQU8sS0FBSyxFQUFFO1FBQ1osT0FBTyxDQUFDLEtBQUssQ0FBQyxxQkFBcUIsRUFBQyxHQUFHLENBQUMsQ0FBQTtRQUN4QyxPQUFPLEVBQUUsQ0FBQTtLQUNaO0FBQ0wsQ0FBQyxDQUFBO0FBWlksUUFBQSxTQUFTLGFBWXJCO0FBQ00sTUFBTSxZQUFZLEdBQUcsS0FBSyxFQUFFLElBQVcsRUFBRSxHQUFVLEVBQUUsRUFBRTtJQUMxRCxPQUFPLFFBQVEsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFO1FBQ3ZCLFFBQVEsRUFBRSxJQUFBLGlCQUFTLEVBQUMsSUFBSSxDQUFDO0tBQzVCLENBQUMsQ0FBQTtBQUNOLENBQUMsQ0FBQTtBQUpZLFFBQUEsWUFBWSxnQkFJeEIifQ==
\ No newline at end of file
diff --git a/packages/discourse/lib/sync/file.d.ts b/packages/discourse/lib/sync/file.d.ts
new file mode 100644
index 00000000..b06a049b
--- /dev/null
+++ b/packages/discourse/lib/sync/file.d.ts
@@ -0,0 +1,6 @@
+import { IOptionsSync } from '../../types';
+import { Discourser } from '../discourse';
+export declare const createTopic: (discourse: Discourser, options: IOptionsSync, content: any) => Promise;
+export declare const updateTopic: (discourse: Discourser, options: IOptionsSync, topic_id: any, content: any) => Promise;
+export declare const syncYAML: (options: IOptionsSync) => Promise;
+export declare const sync: (options: IOptionsSync) => Promise;
diff --git a/packages/discourse/lib/sync/file.js b/packages/discourse/lib/sync/file.js
new file mode 100644
index 00000000..1cfbdc3a
--- /dev/null
+++ b/packages/discourse/lib/sync/file.js
@@ -0,0 +1,253 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.sync = exports.syncYAML = exports.updateTopic = exports.createTopic = void 0;
+const path = require("path");
+const exists_1 = require("@plastichub/fs/exists");
+const dir_1 = require("@plastichub/fs/dir");
+const write_1 = require("@plastichub/fs/write");
+const read_1 = require("@plastichub/fs/read");
+const fs_1 = require("@plastichub/osr-commons");
+const bluebird_1 = require("bluebird");
+const download_1 = require("./download");
+const YAML = require('json-to-pretty-yaml');
+const cheerio = require('cheerio');
+const markdown_1 = require("../markdown");
+const constants_1 = require("../discourse/constants");
+const cache_1 = require("../discourse/cache");
+const discourse_1 = require("../discourse");
+const commons_1 = require("./commons");
+const index_1 = require("../../index");
+const md5 = require("md5");
+const createTopic = async (discourse, options, content) => {
+ let data;
+ try {
+ data = await discourse.createPost(options.title, content, options.cat);
+ }
+ catch (e) {
+ debugger;
+ }
+ if (data) {
+ index_1.logger.debug('created topic : ' + options.title + ' : ' + data.id);
+ if (data && data.id) {
+ try {
+ options.post_id = data.id;
+ options.topic_id = data.topic_id;
+ await discourse.changeOwner(options.post_id, options.topic_id, options.user_name);
+ }
+ catch (e) {
+ index_1.logger.error('changing owner ' + options.title + ' failed!', e);
+ }
+ }
+ else {
+ index_1.logger.debug('creating ' + options.title + ' failed!', data.errors);
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ index_1.logger.error('title already used : ' + options.title);
+ }
+ }
+ }
+ }
+};
+exports.createTopic = createTopic;
+const updateTopic = async (discourse, options, topic_id, content) => {
+ let data;
+ try {
+ data = await discourse.updatePost(topic_id, content);
+ }
+ catch (e) {
+ }
+ if (data) {
+ index_1.logger.debug('created topic : ' + options.title + ' : ' + data.id);
+ if (data && data.id) {
+ try {
+ index_1.logger.debug('change user to ', options.owner);
+ options.post_id = data.id;
+ options.topic_id = data.topic_id;
+ await discourse.changeOwner(topic_id, topic_id, options.user_name);
+ }
+ catch (e) {
+ index_1.logger.debug('changing owner ' + options.title + ' failed!');
+ }
+ }
+ else {
+ index_1.logger.debug('creating ' + options.title + ' failed!', data.errors);
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ index_1.logger.error('title already used : ' + options.title);
+ }
+ }
+ }
+ }
+};
+exports.updateTopic = updateTopic;
+const images_urls = (content) => {
+ const html = (0, markdown_1.toHTML)(content);
+ const $ = cheerio.load(html, {
+ xmlMode: true
+ });
+ const images = [];
+ const links = [];
+ $('img').each(function () {
+ images.push($(this).attr('src'));
+ });
+ return images;
+};
+const uploadImages = async (content, discourse, options) => {
+ const root = path.resolve((0, fs_1.resolve)(options.root));
+ if (!(0, exists_1.sync)(root)) {
+ return false;
+ }
+ const track_path = path.join(root, constants_1.SYNC_TRACK_FILENAME);
+ const track = (0, read_1.sync)(track_path, 'json') || {};
+ const html = (0, markdown_1.toHTML)(content);
+ const $ = cheerio.load(html, {
+ xmlMode: true
+ });
+ const images = images_urls(content);
+ $('img').each(function () {
+ images.push($(this).attr('src'));
+ });
+ for await (const image of Object.entries(images)) {
+ const url = image[1];
+ if (url.startsWith('upload:')) {
+ continue;
+ }
+ if (options.uploadRemote && url.startsWith('http')) {
+ const contentHash = md5(content).substring(0, 5);
+ const cache_path = path.resolve((0, fs_1.resolve)('${OSR_CACHE}/discourse-downloads/' + contentHash));
+ if (!(0, exists_1.sync)(cache_path)) {
+ (0, dir_1.sync)(cache_path);
+ }
+ const image_name = (0, download_1.imageName)(url);
+ const image_local = path.join(cache_path, image_name);
+ if (!(0, exists_1.sync)(image_local)) {
+ await (0, download_1.downloadFile)(url, cache_path);
+ }
+ if ((0, exists_1.sync)(image_local)) {
+ const upped = await discourse.uploadFile(options.owner, image_local);
+ const data = upped.data;
+ if (data && data.id) {
+ track[url] = data;
+ (0, write_1.sync)(track_path, track);
+ }
+ else {
+ console.error('error uploading image');
+ }
+ }
+ continue;
+ }
+ if (options.uploadLocal) {
+ const image_path = path.join(root, url);
+ if ((0, exists_1.sync)(image_path) && !track[url]) {
+ const upped = await discourse.uploadFile(options.owner, image_path);
+ const data = upped.data;
+ if (data && data.id) {
+ track[url] = data;
+ (0, write_1.sync)(track_path, track);
+ }
+ else {
+ console.error('error uploading image');
+ }
+ }
+ }
+ }
+ return track;
+};
+const syncFile = async (file, options) => {
+ const discourse = (0, discourse_1.Instance)(null, options.config);
+ let content = (0, read_1.sync)(file);
+ const fm = (0, commons_1.fromYAML)(content, options) || {};
+ let body = "" + fm.body;
+ let images_track;
+ if (options.uploadLocal || options.uploadRemote) {
+ images_track = await uploadImages(body, discourse, options);
+ const image_urls = images_urls(body);
+ image_urls.forEach((i) => {
+ if (images_track[i])
+ body = body.replace(i, images_track[i].short_url);
+ });
+ }
+ (0, write_1.sync)('./out/md.md', body);
+ let dOpts = options.yaml ? fm.attributes : {
+ cat: options.cat,
+ id: options.id,
+ owner: options.owner,
+ tags: options.tags,
+ title: options.title
+ };
+ options = {
+ ...options,
+ ...dOpts
+ };
+ const cats = await (0, cache_1.cacheCategories)(options, discourse);
+ const tags = await (0, cache_1.cacheTags)(options, discourse);
+ const users = await (0, cache_1.cacheUsers)(options, discourse);
+ const search = await discourse.search(dOpts.title);
+ let post_id, topic_id;
+ if (options.yaml) {
+ post_id = dOpts.post_id;
+ topic_id = dOpts.topic_id;
+ }
+ let dTopic;
+ let dPost;
+ if (search.posts && search.topics
+ && search.posts[0] && search.topics[0]
+ && search.topics[0].title === dOpts.title) {
+ dPost = search.posts[0];
+ dTopic = search.topics[0];
+ topic_id = dTopic.id;
+ post_id = dPost.id;
+ }
+ else if (post_id && topic_id) {
+ }
+ const user = users.find((u) => {
+ return u.id === dOpts.owner;
+ });
+ if (!user) {
+ index_1.logger.error('Invalid user : ', dOpts.owner);
+ return false;
+ }
+ options.user_name = user.username;
+ let topic = null;
+ if (post_id) {
+ topic = await (0, exports.updateTopic)(discourse, options, post_id, body);
+ if (topic_id) {
+ topic = await discourse.updateTopic(topic_id, dOpts.cat, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : []);
+ }
+ }
+ else {
+ await (0, exports.createTopic)(discourse, options, body);
+ topic_id = options.topic_id;
+ post_id = options.post_id;
+ await discourse.updateTopic(topic_id, dOpts.cat, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : []);
+ }
+ if (dTopic) {
+ options.topic_id = dTopic.id;
+ }
+ if (dPost) {
+ options.post_id = dPost.id;
+ }
+ if (options.yaml) {
+ let contentOut = `---\n`;
+ contentOut += YAML.stringify({
+ ...fm.attributes,
+ topic_id: topic_id,
+ post_id: post_id
+ });
+ contentOut += `---\n`;
+ contentOut += fm.body;
+ (0, write_1.sync)(file, contentOut);
+ }
+ return content;
+};
+const syncYAML = async (options) => {
+ await bluebird_1.Promise.resolve(options.srcInfo.FILES).map((f) => {
+ return syncFile(f, options);
+ }, { concurrency: 1 });
+};
+exports.syncYAML = syncYAML;
+const sync = async (options) => {
+ return (0, exports.syncYAML)(options);
+};
+exports.sync = sync;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvc3luYy9maWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZCQUE0QjtBQUM1QixrREFBc0Q7QUFFdEQsNENBQWdEO0FBQ2hELGdEQUFvRDtBQUNwRCw4Q0FBa0Q7QUFFbEQsdURBQXdEO0FBRXhELHVDQUE4QztBQUU5Qyx5Q0FBb0Q7QUFHcEQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLHFCQUFxQixDQUFDLENBQUE7QUFDM0MsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBRW5DLDBDQUFvQztBQUVwQyxzREFFK0I7QUFFL0IsOENBSzJCO0FBRTNCLDRDQUdxQjtBQUVyQix1Q0FFa0I7QUFHbEIsdUNBQStEO0FBRS9ELDJCQUEwQjtBQUVuQixNQUFNLFdBQVcsR0FBRyxLQUFLLEVBQUUsU0FBcUIsRUFBRSxPQUFxQixFQUFFLE9BQU8sRUFBRSxFQUFFO0lBRXZGLElBQUksSUFBUyxDQUFBO0lBQ2IsSUFBSTtRQUNBLElBQUksR0FBRyxNQUFNLFNBQVMsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLEdBQWEsQ0FBQyxDQUFBO0tBQ25GO0lBQUMsT0FBTyxDQUFDLEVBQUU7UUFDUixRQUFRLENBQUE7S0FDWDtJQUVELElBQUksSUFBSSxFQUFFO1FBQ04sY0FBTSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsR0FBRyxPQUFPLENBQUMsS0FBSyxHQUFHLE1BQU0sR0FBRyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7UUFDbkUsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLEVBQUUsRUFBRTtZQUVqQixJQUFJO2dCQUNBLE9BQU8sQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDMUIsT0FBTyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFBO2dC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
\ No newline at end of file
diff --git a/packages/discourse/lib/sync/fs.d.ts b/packages/discourse/lib/sync/fs.d.ts
new file mode 100644
index 00000000..b06a049b
--- /dev/null
+++ b/packages/discourse/lib/sync/fs.d.ts
@@ -0,0 +1,6 @@
+import { IOptionsSync } from '../../types';
+import { Discourser } from '../discourse';
+export declare const createTopic: (discourse: Discourser, options: IOptionsSync, content: any) => Promise;
+export declare const updateTopic: (discourse: Discourser, options: IOptionsSync, topic_id: any, content: any) => Promise;
+export declare const syncYAML: (options: IOptionsSync) => Promise;
+export declare const sync: (options: IOptionsSync) => Promise;
diff --git a/packages/discourse/lib/sync/fs.js b/packages/discourse/lib/sync/fs.js
new file mode 100644
index 00000000..2a3279fa
--- /dev/null
+++ b/packages/discourse/lib/sync/fs.js
@@ -0,0 +1,275 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.sync = exports.syncYAML = exports.updateTopic = exports.createTopic = void 0;
+const path = require("path");
+const exists_1 = require("@plastichub/fs/exists");
+const dir_1 = require("@plastichub/fs/dir");
+const write_1 = require("@plastichub/fs/write");
+const read_1 = require("@plastichub/fs/read");
+const fs_1 = require("@plastichub/osr-commons");
+const bluebird_1 = require("bluebird");
+const YAML = require('json-to-pretty-yaml');
+const cheerio = require('cheerio');
+const download_1 = require("./download");
+const markdown_1 = require("../markdown");
+const constants_1 = require("../discourse/constants");
+const cache_1 = require("../discourse/cache");
+const discourse_1 = require("../discourse");
+const index_1 = require("../../index");
+const md5 = require("md5");
+const frontMatter = require('front-matter');
+const fromYAML = (content, options) => {
+ if (frontMatter.test(content)) {
+ const fm = frontMatter(content);
+ return {
+ attributes: fm.attributes,
+ body: fm.body
+ };
+ }
+ else {
+ return {
+ attributes: {},
+ body: content
+ };
+ }
+};
+const adjustUrls = (content, options) => {
+ let ret = new markdown_1.RMark({
+ images: (match, capture, arg1, arg2) => ``,
+ //links: (match, capture, arg1, arg2) => `[${capture}](${arg1})`
+ }).render(content);
+ return ret;
+};
+const createTopic = async (discourse, options, content) => {
+ let data;
+ try {
+ data = await discourse.createPost(options.title, content, options.cat);
+ }
+ catch (e) {
+ debugger;
+ }
+ if (data) {
+ index_1.logger.debug('created topic : ' + options.title + ' : ' + data.id);
+ if (data && data.id) {
+ try {
+ options.post_id = data.id;
+ options.topic_id = data.topic_id;
+ await discourse.changeOwner(options.post_id, options.topic_id, options.user_name);
+ }
+ catch (e) {
+ index_1.logger.error('changing owner ' + options.title + ' failed!', e);
+ }
+ }
+ else {
+ index_1.logger.debug('creating ' + options.title + ' failed!', data.errors);
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ index_1.logger.error('title already used : ' + options.title);
+ }
+ }
+ }
+ }
+};
+exports.createTopic = createTopic;
+const updateTopic = async (discourse, options, topic_id, content) => {
+ let data;
+ try {
+ data = await discourse.updatePost(topic_id, content);
+ }
+ catch (e) {
+ }
+ if (data) {
+ index_1.logger.debug('created topic : ' + options.title + ' : ' + data.id);
+ if (data && data.id) {
+ try {
+ index_1.logger.debug('change user to ', options.owner);
+ options.post_id = data.id;
+ options.topic_id = data.topic_id;
+ await discourse.changeOwner(topic_id, topic_id, options.user_name);
+ }
+ catch (e) {
+ index_1.logger.debug('changing owner ' + options.title + ' failed!');
+ }
+ }
+ else {
+ index_1.logger.debug('creating ' + options.title + ' failed!', data.errors);
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ index_1.logger.error('title already used : ' + options.title);
+ }
+ }
+ }
+ }
+};
+exports.updateTopic = updateTopic;
+const images_urls = (content) => {
+ const html = (0, markdown_1.toHTML)(content);
+ const $ = cheerio.load(html, {
+ xmlMode: true
+ });
+ const images = [];
+ const links = [];
+ $('img').each(function () {
+ images.push($(this).attr('src'));
+ });
+ return images;
+};
+const uploadImages = async (content, discourse, options) => {
+ const root = path.resolve((0, fs_1.resolve)(options.root));
+ if (!(0, exists_1.sync)(root)) {
+ return false;
+ }
+ const track_path = path.join(root, constants_1.SYNC_TRACK_FILENAME);
+ const track = (0, read_1.sync)(track_path, 'json') || {};
+ const html = (0, markdown_1.toHTML)(content);
+ const $ = cheerio.load(html, {
+ xmlMode: true
+ });
+ const images = images_urls(content);
+ $('img').each(function () {
+ images.push($(this).attr('src'));
+ });
+ for await (const image of Object.entries(images)) {
+ const url = image[1];
+ if (url.startsWith('upload:')) {
+ continue;
+ }
+ if (options.uploadRemote && url.startsWith('http')) {
+ const contentHash = md5(content).substring(0, 5);
+ const cache_path = path.resolve((0, fs_1.resolve)('${OSR_CACHE}/discourse-downloads/' + contentHash));
+ if (!(0, exists_1.sync)(cache_path)) {
+ (0, dir_1.sync)(cache_path);
+ }
+ const image_name = (0, download_1.imageName)(url);
+ const image_local = path.join(cache_path, image_name);
+ if (!(0, exists_1.sync)(image_local)) {
+ await (0, download_1.downloadFile)(url, cache_path);
+ }
+ if ((0, exists_1.sync)(image_local)) {
+ const upped = await discourse.uploadFile(options.owner, image_local);
+ const data = upped.data;
+ if (data && data.id) {
+ track[url] = data;
+ (0, write_1.sync)(track_path, track);
+ }
+ else {
+ console.error('error uploading image');
+ }
+ }
+ continue;
+ }
+ if (options.uploadLocal) {
+ const image_path = path.join(root, url);
+ if ((0, exists_1.sync)(image_path) && !track[url]) {
+ const upped = await discourse.uploadFile(options.owner, image_path);
+ const data = upped.data;
+ if (data && data.id) {
+ track[url] = data;
+ (0, write_1.sync)(track_path, track);
+ }
+ else {
+ console.error('error uploading image');
+ }
+ }
+ }
+ }
+ return track;
+};
+const syncFile = async (file, options) => {
+ const discourse = (0, discourse_1.Instance)(null, options.config);
+ let content = (0, read_1.sync)(file);
+ const fm = fromYAML(content, options) || {};
+ let body = "" + fm.body;
+ let images_track;
+ if (options.uploadLocal || options.uploadRemote) {
+ images_track = await uploadImages(body, discourse, options);
+ const image_urls = images_urls(body);
+ image_urls.forEach((i) => {
+ if (images_track[i])
+ body = body.replace(i, images_track[i].short_url);
+ });
+ }
+ (0, write_1.sync)('./out/md.md', body);
+ let dOpts = options.yaml ? fm.attributes : {
+ cat: options.cat,
+ id: options.id,
+ owner: options.owner,
+ tags: options.tags,
+ title: options.title
+ };
+ options = {
+ ...options,
+ ...dOpts
+ };
+ const cats = await (0, cache_1.cacheCategories)(options, discourse);
+ const tags = await (0, cache_1.cacheTags)(options, discourse);
+ const users = await (0, cache_1.cacheUsers)(options, discourse);
+ const search = await discourse.search(dOpts.title);
+ let post_id, topic_id;
+ if (options.yaml) {
+ post_id = dOpts.post_id;
+ topic_id = dOpts.topic_id;
+ }
+ let dTopic;
+ let dPost;
+ if (search.posts && search.topics
+ && search.posts[0] && search.topics[0]
+ && search.topics[0].title === dOpts.title) {
+ dPost = search.posts[0];
+ dTopic = search.topics[0];
+ topic_id = dTopic.id;
+ post_id = dPost.id;
+ }
+ else if (post_id && topic_id) {
+ }
+ const user = users.find((u) => {
+ return u.id === dOpts.owner;
+ });
+ if (!user) {
+ index_1.logger.error('Invalid user : ', dOpts.owner);
+ return false;
+ }
+ options.user_name = user.username;
+ let topic = null;
+ if (post_id) {
+ topic = await (0, exports.updateTopic)(discourse, options, post_id, body);
+ if (topic_id) {
+ topic = await discourse.updateTopic(topic_id, dOpts.cat, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : []);
+ }
+ }
+ else {
+ await (0, exports.createTopic)(discourse, options, body);
+ topic_id = options.topic_id;
+ post_id = options.post_id;
+ await discourse.updateTopic(topic_id, dOpts.cat, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : []);
+ }
+ if (dTopic) {
+ options.topic_id = dTopic.id;
+ }
+ if (dPost) {
+ options.post_id = dPost.id;
+ }
+ if (options.yaml) {
+ let contentOut = `---\n`;
+ contentOut += YAML.stringify({
+ ...fm.attributes,
+ topic_id: topic_id,
+ post_id: post_id
+ });
+ contentOut += `---\n`;
+ contentOut += fm.body;
+ (0, write_1.sync)(file, contentOut);
+ }
+ return content;
+};
+const syncYAML = async (options) => {
+ await bluebird_1.Promise.resolve(options.srcInfo.FILES).map((f) => {
+ return syncFile(f, options);
+ }, { concurrency: 1 });
+};
+exports.syncYAML = syncYAML;
+const sync = async (options) => {
+ return (0, exports.syncYAML)(options);
+};
+exports.sync = sync;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3N5bmMvZnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkJBQTRCO0FBQzVCLGtEQUFzRDtBQUV0RCw0Q0FBZ0Q7QUFDaEQsZ0RBQW9EO0FBQ3BELDhDQUFrRDtBQUVsRCx1REFBd0Q7QUFFeEQsdUNBQThDO0FBSzlDLE1BQU0sSUFBSSxHQUFHLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFBO0FBQzNDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUduQyx5Q0FBb0Q7QUFFcEQsMENBQTJDO0FBRTNDLHNEQUUrQjtBQUUvQiw4Q0FLMkI7QUFHM0IsNENBR3FCO0FBSXJCLHVDQUErRDtBQUUvRCwyQkFBMEI7QUFFMUIsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFBO0FBRTNDLE1BQU0sUUFBUSxHQUFHLENBQUMsT0FBZSxFQUFFLE9BQXFCLEVBQUUsRUFBRTtJQUN4RCxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDM0IsTUFBTSxFQUFFLEdBQUcsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQy9CLE9BQU87WUFDSCxVQUFVLEVBQUUsRUFBRSxDQUFDLFVBQVU7WUFDekIsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJO1NBQ2hCLENBQUE7S0FDSjtTQUFNO1FBQ0gsT0FBTztZQUNILFVBQVUsRUFBRSxFQUFFO1lBQ2QsSUFBSSxFQUFFLE9BQU87U0FDaEIsQ0FBQTtLQUNKO0FBQ0wsQ0FBQyxDQUFBO0FBRUQsTUFBTSxVQUFVLEdBQUcsQ0FBQyxPQUFlLEVBQUUsT0FBcUIsRUFBRSxFQUFFO0lBQzFELElBQUksR0FBRyxHQUFHLElBQUksZ0JBQUssQ0FDZjtRQUNJLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFF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
\ No newline at end of file
diff --git a/packages/discourse/lib/sync/index.d.ts b/packages/discourse/lib/sync/index.d.ts
new file mode 100644
index 00000000..05bc6d93
--- /dev/null
+++ b/packages/discourse/lib/sync/index.d.ts
@@ -0,0 +1,6 @@
+import { IOptionsSync } from '../../types';
+import { IComponentConfig } from '@plastichub/osr-commons';
+export declare const trackingPath: (root: any) => string;
+export declare const tracking: (root: any) => import("@plastichub/fs/interfaces").ReadWriteDataType;
+export declare const defaultConfig: (configFile: string, options: IOptionsSync) => IComponentConfig;
+export declare const fromJSON: (configFile: string, options: IOptionsSync) => IComponentConfig;
diff --git a/packages/discourse/lib/sync/index.js b/packages/discourse/lib/sync/index.js
new file mode 100644
index 00000000..9fd4ea29
--- /dev/null
+++ b/packages/discourse/lib/sync/index.js
@@ -0,0 +1,36 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.fromJSON = exports.defaultConfig = exports.tracking = exports.trackingPath = void 0;
+const path = require("path");
+const read_1 = require("@plastichub/fs/read");
+const constants_1 = require("../discourse/constants");
+const YAML = require('json-to-pretty-yaml');
+const cheerio = require('cheerio');
+const findUp = require('find-up');
+const frontMatter = require('front-matter');
+const osr_fs_utils_1 = require("@plastichub/osr-fs-utils");
+const trackingPath = (root) => path.join(root, constants_1.SYNC_TRACK_FILENAME);
+exports.trackingPath = trackingPath;
+const tracking = (root) => (0, read_1.sync)((0, exports.trackingPath)(root), 'json') || {};
+exports.tracking = tracking;
+const defaultConfig = (configFile, options) => {
+ let defaultsJSON = findUp.sync('defaults.json', {
+ cwd: path.parse(configFile).dir,
+ stopAt: options.root
+ });
+ if (defaultsJSON) {
+ return (0, osr_fs_utils_1.readOSRConfig)(defaultsJSON);
+ }
+ return {};
+};
+exports.defaultConfig = defaultConfig;
+const fromJSON = (configFile, options) => {
+ const defaults = (0, exports.defaultConfig)(configFile, options);
+ const config = (0, osr_fs_utils_1.readOSRConfig)(configFile);
+ return {
+ ...defaults,
+ ...config
+ };
+};
+exports.fromJSON = fromJSON;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbGliL3N5bmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkJBQTRCO0FBQzVCLDhDQUFrRDtBQUNsRCxzREFFK0I7QUFjL0IsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLHFCQUFxQixDQUFDLENBQUE7QUFDM0MsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFBO0FBQ2xDLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtBQUNqQyxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUE7QUFJM0MsMkRBQWlGO0FBRTFFLE1BQU0sWUFBWSxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FDakMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsK0JBQW1CLENBQUMsQ0FBQTtBQUQzQixRQUFBLFlBQVksZ0JBQ2U7QUFHakMsTUFBTSxRQUFRLEdBQUcsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUM3QixJQUFBLFdBQUksRUFBQyxJQUFBLG9CQUFZLEVBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFBO0FBRDdCLFFBQUEsUUFBUSxZQUNxQjtBQUVuQyxNQUFNLGFBQWEsR0FBRyxDQUFDLFVBQWtCLEVBQUUsT0FBcUIsRUFBb0IsRUFBRTtJQUN6RixJQUFJLFlBQVksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRTtRQUM1QyxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQyxHQUFHO1FBQy9CLE1BQU0sRUFBRSxPQUFPLENBQUMsSUFBSTtLQUN2QixDQUFDLENBQUE7SUFDRixJQUFJLFlBQVksRUFBRTtRQUNkLE9BQU8sSUFBQSw0QkFBYSxFQUFDLFlBQVksQ0FBQyxDQUFBO0tBQ3JDO0lBQ0QsT0FBTyxFQUVjLENBQUE7QUFDekIsQ0FBQyxDQUFBO0FBWFksUUFBQSxhQUFhLGlCQVd6QjtBQUVNLE1BQU0sUUFBUSxHQUFHLENBQUMsVUFBa0IsRUFBRSxPQUFxQixFQUFvQixFQUFFO0lBQ3BGLE1BQU0sUUFBUSxHQUFHLElBQUEscUJBQWEsRUFBQyxVQUFVLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDbkQsTUFBTSxNQUFNLEdBQUcsSUFBQSw0QkFBYSxFQUFDLFVBQVUsQ0FBQyxDQUFBO0lBQ3hDLE9BQU87UUFDSCxHQUFHLFFBQVE7UUFDWCxHQUFHLE1BQU07S0FDWixDQUFBO0FBQ0wsQ0FBQyxDQUFBO0FBUFksUUFBQSxRQUFRLFlBT3BCIn0=
\ No newline at end of file
diff --git a/packages/discourse/lib/sync/osrl.d.ts b/packages/discourse/lib/sync/osrl.d.ts
new file mode 100644
index 00000000..14a939a0
--- /dev/null
+++ b/packages/discourse/lib/sync/osrl.d.ts
@@ -0,0 +1,4 @@
+///
+import { IOptionsSyncComponent } from '../../';
+export declare const fileAsBuffer: (path: string) => Buffer;
+export declare const createContent: (component: any, _options: IOptionsSyncComponent) => Promise;
diff --git a/packages/discourse/lib/sync/osrl.js b/packages/discourse/lib/sync/osrl.js
new file mode 100644
index 00000000..9b848a5e
--- /dev/null
+++ b/packages/discourse/lib/sync/osrl.js
@@ -0,0 +1,75 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.createContent = exports.fileAsBuffer = void 0;
+const path = require("path");
+const Engine_1 = require("@plastichub/osrl/Engine");
+const options_1 = require("@plastichub/osrl/options");
+const glob_1 = require("@plastichub/osr-cli-commons/glob");
+const fs_1 = require("@plastichub/osr-commons");
+const index_1 = require("../../index");
+const git_1 = require("../git");
+const moment = require("moment");
+const read_1 = require("@plastichub/fs/read");
+const fileAsBuffer = (path) => (0, read_1.sync)(path, 'buffer') || Buffer.from("-");
+exports.fileAsBuffer = fileAsBuffer;
+const variable_extras = async (component, rel, options) => {
+ const root = path.resolve((0, fs_1.resolve)('${OSR_LIBRARY_MACHINES}'));
+ const gitStats = await (0, git_1.git_status)(root, rel);
+ const latest = gitStats.latest;
+ return {
+ "GIT_LAST": moment(latest.date).format('LLLL'),
+ "GIT_AUTHOR": latest.author_name,
+ "GIT_MESSAGE": latest.message,
+ "GIT_COMMIT": latest.hash
+ };
+};
+const createContent = async (component, _options) => {
+ const parts = path.parse(component);
+ const rel = (0, glob_1.forward_slash)(path.relative(_options.root, component));
+ const extras = await variable_extras(component, rel, _options);
+ const variables = {
+ root: _options.root,
+ cwd: _options.cwd,
+ ..._options.variables,
+ product: rel,
+ product_rel: rel,
+ product_rel_min: rel,
+ ...extras
+ };
+ const defaults = {
+ language: _options.language,
+ debug: false,
+ profile: _options.profile,
+ // output: output,
+ plugins: [],
+ env: _options.env || 'forum',
+ cwd: _options.cwd,
+ source: _options.src,
+ variables
+ };
+ const options = (0, options_1.parse)(defaults, defaults);
+ const eOptions = {
+ ...options,
+ root: [
+ ...options.profile.includes,
+ component
+ ],
+ toHTML: false,
+ cache: false,
+ keepOutputType: true,
+ trimTagRight: false,
+ trimTagLeft: false,
+ trimOutputRight: false,
+ trimOutputLeft: false,
+ greedy: false
+ };
+ const Engine = new Engine_1.Engine(eOptions);
+ options.debug && index_1.logger.info('Compile file ' + component, eOptions);
+ let content = await Engine.render(options.source, {
+ ...options.variables,
+ ...extras
+ });
+ return content;
+};
+exports.createContent = createContent;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3NybC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9saWIvc3luYy9vc3JsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDZCQUE0QjtBQUU1QixvREFBMEQ7QUFDMUQsc0RBQWdEO0FBRWhELDJEQUFnRTtBQUVoRSx1REFBd0Q7QUFHeEQsdUNBQW9DO0FBQ3BDLGdDQUFtQztBQUNuQyxpQ0FBZ0M7QUFDaEMsOENBQWtEO0FBRTNDLE1BQU0sWUFBWSxHQUFHLENBQUMsSUFBWSxFQUFFLEVBQUUsQ0FBQyxJQUFBLFdBQUksRUFBQyxJQUFJLEVBQUUsUUFBUSxDQUFXLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtBQUFuRixRQUFBLFlBQVksZ0JBQXVFO0FBQ2hHLE1BQU0sZUFBZSxHQUFHLEtBQUssRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE9BQThCLEVBQUUsRUFBRTtJQUM3RSxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUEsWUFBTyxFQUFDLHlCQUF5QixDQUFDLENBQUMsQ0FBQTtJQUM3RCxNQUFNLFFBQVEsR0FBRyxNQUFNLElBQUEsZ0JBQVUsRUFBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUE7SUFDNUMsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQTtJQUM5QixPQUFPO1FBQ0gsVUFBVSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUMvQyxZQUFZLEVBQUcsTUFBTSxDQUFDLFdBQVc7UUFDakMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxPQUFPO1FBQzdCLFlBQVksRUFBRyxNQUFNLENBQUMsSUFBSTtLQUM3QixDQUFBO0FBQ0wsQ0FBQyxDQUFBO0FBRU0sTUFBTSxhQUFhLEdBQUcsS0FBSyxFQUFFLFNBQVMsRUFBRSxRQUErQixFQUFFLEVBQUU7SUFFOUUsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUNuQyxNQUFNLEdBQUcsR0FBRyxJQUFBLG9CQUFhLEVBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUE7SUFDbEUsTUFBTSxNQUFNLEdBQUcsTUFBTSxlQUFlLENBQUMsU0FBUyxFQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQTtJQUM3RCxNQUFNLFNBQVMsR0FBRztRQUNkLElBQUksRUFBRSxRQUFRLENBQUMsSUFBSTtRQUNuQixHQUFHLEVBQUUsUUFBUSxDQUFDLEdBQUc7UUFDakIsR0FBRyxRQUFRLENBQUMsU0FBUztRQUNyQixPQUFPLEVBQUUsR0FBRztRQUNaLFdBQVcsRUFBRSxHQUFHO1FBQ2hCLGVBQWUsRUFBRSxHQUFHO1FBQ3BCLEdBQUcsTUFBTTtLQUNaLENBQUE7SUFDRCxNQUFNLFFBQVEsR0FBUTtRQUNsQixRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVE7UUFDM0IsS0FBSyxFQUFFLEtBQUs7UUFDWixPQUFPLEVBQUUsUUFBUSxDQUFDLE9BQU87UUFDN0IscUJBQXFCO1FBQ2pCLE9BQU8sRUFBRSxFQUFFO1FBQ1gsR0FBRyxFQUFFLFFBQVEsQ0FBQyxHQUFHLElBQUksT0FBTztRQUM1QixHQUFHLEVBQUUsUUFBUSxDQUFDLEdBQUc7UUFDakIsTUFBTSxFQUFFLFFBQVEsQ0FBQyxHQUFHO1FBQ3BCLFNBQVM7S0FDWixDQUFBO0lBQ0QsTUFBTSxPQUFPLEdBQUcsSUFBQSxlQUFLLEVBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzFDLE1BQU0sUUFBUSxHQUFHO1FBQ2IsR0FBRyxPQUFPO1FBQ1YsSUFBSSxFQUFFO1lBQ0YsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVE7WUFDM0IsU0FBUztTQUNaO1FBQ0QsTUFBTSxFQUFFLEtBQUs7UUFDYixLQUFLLEVBQUUsS0FBSztRQUNaLGNBQWMsRUFBRSxJQUFJO1FBQ3BCLFlBQVksRUFBRSxLQUFLO1FBQ25CLFdBQVcsRUFBRSxLQUFLO1FBQ2xCLGVBQWUsRUFBRSxLQUFLO1FBQ3RCLGNBQWMsRUFBRSxLQUFLO1FBQ3JCLE1BQU0sRUFBRSxLQUFLO0tBQ0osQ0FBQTtJQUViLE1BQU0sTUFBTSxHQUFHLElBQUksZUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBRXBDLE9BQU8sQ0FBQyxLQUFLLElBQUksY0FBTSxDQUFDLElBQUksQ0FBQyxlQUFlLEdBQUcsU0FBUyxFQUFFLFFBQVEsQ0FBQyxDQUFBO0lBRW5FLElBQUksT0FBTyxHQUFHLE1BQU0sTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFO1FBQzlDLEdBQUcsT0FBTyxDQUFDLFNBQVM7UUFDcEIsR0FBRyxNQUFNO0tBQ1osQ0FBQyxDQUFBO0lBQ0YsT0FBTyxPQUFPLENBQUE7QUFDbEIsQ0FBQyxDQUFBO0FBbkRZLFFBQUEsYUFBYSxpQkFtRHpCIn0=
\ No newline at end of file
diff --git a/packages/discourse/lib/types.d.ts b/packages/discourse/lib/types.d.ts
new file mode 100644
index 00000000..e69de29b
diff --git a/packages/discourse/lib/types.js b/packages/discourse/lib/types.js
new file mode 100644
index 00000000..61fa7256
--- /dev/null
+++ b/packages/discourse/lib/types.js
@@ -0,0 +1,2 @@
+"use strict";
+//# sourceMappingURL=types.js.map
\ No newline at end of file
diff --git a/packages/discourse/lib/types.js.map b/packages/discourse/lib/types.js.map
new file mode 100644
index 00000000..247b4c7e
--- /dev/null
+++ b/packages/discourse/lib/types.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/lib/types.ts"],"names":[],"mappings":""}
\ No newline at end of file
diff --git a/packages/discourse/main.d.ts b/packages/discourse/main.d.ts
new file mode 100644
index 00000000..d1ebc9c7
--- /dev/null
+++ b/packages/discourse/main.d.ts
@@ -0,0 +1,2 @@
+#!/usr/bin/env node
+export {};
diff --git a/packages/discourse/main.js b/packages/discourse/main.js
new file mode 100644
index 00000000..0d4817fd
--- /dev/null
+++ b/packages/discourse/main.js
@@ -0,0 +1,28 @@
+#!/usr/bin/env node
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
+const _cli_1 = require("./_cli");
+(0, _cli_1.defaults)();
+const cli = require("yargs");
+const info_1 = require("./commands/info");
+(0, info_1.register)(cli);
+const query_1 = require("./commands/query");
+(0, query_1.register)(cli);
+const import_oa_users_1 = require("./commands/import-oa-users");
+(0, import_oa_users_1.register)(cli);
+const import_oa_howtos_1 = require("./commands/import-oa-howtos");
+(0, import_oa_howtos_1.register)(cli);
+const sync_file_1 = require("./commands/sync-file");
+(0, sync_file_1.register)(cli);
+const sync_component_1 = require("./commands/sync-component");
+(0, sync_component_1.register)(cli);
+const argv = cli.argv;
+if (argv.help) {
+ cli.showHelp();
+ process.exit();
+}
+else if (argv.v || argv.version) {
+ process.exit();
+}
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFpbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNyYy9tYWluLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLE9BQU8sQ0FBQyxHQUFHLENBQUMsOEJBQThCLENBQUMsR0FBRyxHQUFHLENBQUM7QUFFbEQsaUNBQWtDO0FBQUMsSUFBQSxlQUFRLEdBQUUsQ0FBQztBQUM5Qyw2QkFBNkI7QUFDN0IsMENBQTJEO0FBQUMsSUFBQSxlQUFZLEVBQUMsR0FBRyxDQUFDLENBQUE7QUFDN0UsNENBQTZEO0FBQUMsSUFBQSxnQkFBYSxFQUFDLEdBQUcsQ0FBQyxDQUFBO0FBRWhGLGdFQUEwRTtBQUFDLElBQUEsMEJBQWdCLEVBQUMsR0FBRyxDQUFDLENBQUE7QUFDaEcsa0VBQWlGO0FBQUMsSUFBQSwyQkFBc0IsRUFBQyxHQUFHLENBQUMsQ0FBQTtBQUU3RyxvREFBZ0U7QUFBQyxJQUFBLG9CQUFZLEVBQUMsR0FBRyxDQUFDLENBQUE7QUFDbEYsOERBQThFO0FBQUMsSUFBQSx5QkFBcUIsRUFBQyxHQUFHLENBQUMsQ0FBQTtBQUV6RyxNQUFNLElBQUksR0FBUSxHQUFHLENBQUMsSUFBSSxDQUFDO0FBRTNCLElBQUksSUFBSSxDQUFDLElBQUksRUFBRTtJQUNYLEdBQUcsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNmLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztDQUNsQjtLQUFNLElBQUksSUFBSSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO0lBQy9CLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztDQUNsQiJ9
\ No newline at end of file
diff --git a/packages/discourse/main.js.map b/packages/discourse/main.js.map
new file mode 100644
index 00000000..c060d445
--- /dev/null
+++ b/packages/discourse/main.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"main.js","sourceRoot":"","sources":["src/main.ts"],"names":[],"mappings":";;;AACA,iCAAkC;AAAC,IAAA,eAAQ,GAAE,CAAC;AAC9C,6BAA6B;AAC7B,0CAA2D;AAAC,IAAA,eAAY,EAAC,GAAG,CAAC,CAAC;AAC9E,4CAA6D;AAAC,IAAA,gBAAa,EAAC,GAAG,CAAC,CAAC;AACjF;;;;EAIE;AACF,MAAM,IAAI,GAAQ,GAAG,CAAC,IAAI,CAAC;AAE3B,IAAI,IAAI,CAAC,IAAI,EAAE;IACX,GAAG,CAAC,QAAQ,EAAE,CAAC;IACf,OAAO,CAAC,IAAI,EAAE,CAAC;CAClB;KAAM,IAAI,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE;IAC/B,OAAO,CAAC,IAAI,EAAE,CAAC;CAClB"}
\ No newline at end of file
diff --git a/packages/discourse/options.d.ts b/packages/discourse/options.d.ts
new file mode 100644
index 00000000..c6ac043b
--- /dev/null
+++ b/packages/discourse/options.d.ts
@@ -0,0 +1,3 @@
+export * from './lib';
+import { IOptions } from './types';
+export declare const parse: (options: IOptions, argv: any) => IOptions;
diff --git a/packages/discourse/options.js b/packages/discourse/options.js
new file mode 100644
index 00000000..54c45415
--- /dev/null
+++ b/packages/discourse/options.js
@@ -0,0 +1,39 @@
+"use strict";
+var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ var desc = Object.getOwnPropertyDescriptor(m, k);
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
+ desc = { enumerable: true, get: function() { return m[k]; } };
+ }
+ Object.defineProperty(o, k2, desc);
+}) : (function(o, m, k, k2) {
+ if (k2 === undefined) k2 = k;
+ o[k2] = m[k];
+}));
+var __exportStar = (this && this.__exportStar) || function(m, exports) {
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.parse = void 0;
+const core_1 = require("@plastichub/core");
+__exportStar(require("./lib"), exports);
+const parse = (options, argv) => {
+ for (const k in argv) {
+ if (!(k in options.variables) && k !== '_'
+ && k !== '$0'
+ && k !== 'variables'
+ && k !== 'src'
+ && k !== 'format'
+ && k !== 'profile'
+ && k !== 'output') {
+ options.variables[k] = argv[k];
+ }
+ }
+ options.variables['cwd'] = options.variables['cwd'] ? options.variables['cwd'] : options.cwd;
+ (0, core_1.resolveConfig)(options.variables);
+ let variables = {};
+ options.pathVariables = variables;
+ return options;
+};
+exports.parse = parse;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3B0aW9ucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInNyYy9vcHRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBRUEsMkNBQWdEO0FBTWhELHdDQUFxQjtBQUtkLE1BQU0sS0FBSyxHQUFHLENBQUMsT0FBaUIsRUFBRSxJQUFTLEVBQVksRUFBRTtJQUU1RCxLQUFLLE1BQU0sQ0FBQyxJQUFJLElBQUksRUFBRTtRQUNsQixJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxHQUFHO2VBQ25DLENBQUMsS0FBSyxJQUFJO2VBQ1YsQ0FBQyxLQUFLLFdBQVc7ZUFDakIsQ0FBQyxLQUFLLEtBQUs7ZUFDWCxDQUFDLEtBQUssUUFBUTtlQUNkLENBQUMsS0FBSyxTQUFTO2VBQ2YsQ0FBQyxLQUFLLFFBQVEsRUFBRTtZQUNuQixPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUNsQztLQUNKO0lBRUQsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFBO0lBQzVGLElBQUEsb0JBQWEsRUFBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUE7SUFDaEMsSUFBSSxTQUFTLEdBQUcsRUFBRSxDQUFBO0lBQ2xCLE9BQU8sQ0FBQyxhQUFhLEdBQUcsU0FBUyxDQUFBO0lBQ2pDLE9BQU8sT0FBTyxDQUFBO0FBQ2xCLENBQUMsQ0FBQTtBQW5CWSxRQUFBLEtBQUssU0FtQmpCIn0=
\ No newline at end of file
diff --git a/packages/discourse/options.js.map b/packages/discourse/options.js.map
new file mode 100644
index 00000000..c33ab0a6
--- /dev/null
+++ b/packages/discourse/options.js.map
@@ -0,0 +1 @@
+{"version":3,"file":"options.js","sourceRoot":"","sources":["src/options.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAEA,2CAA4D;AAC5D,wCAAqB;AAId,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,EAAE;IAEzB,IAAI,IAAI,IAAI,GAAG,IAAI,QAAQ,IAAI,OAAO,GAAG;QAAE,OAAO,GAAG,CAAC;IACtD,IAAI,IAAI,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAC7B,KAAK,IAAI,IAAI,IAAI,GAAG,EAAE;QAClB,IAAI,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;KACxD;IACD,OAAO,IAAI,CAAC;AAChB,CAAC,CAAA;AARY,QAAA,KAAK,SAQjB;AAEM,MAAM,OAAO,GAAG,CAAC,CAAS,EAAE,OAAiB,EAAE,EAAE;AAExD,CAAC,CAAA;AAFY,QAAA,OAAO,WAEnB;AAGM,MAAM,KAAK,GAAG,CAAC,OAAiB,EAAE,IAAS,EAAY,EAAE;IAE5D,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE;QAClB,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,GAAG;eACnC,CAAC,KAAK,IAAI;eACV,CAAC,KAAK,WAAW;eACjB,CAAC,KAAK,QAAQ;eACd,CAAC,KAAK,UAAU;eAChB,CAAC,KAAK,cAAc;eACpB,CAAC,KAAK,eAAe;eACrB,CAAC,KAAK,QAAQ;eACd,CAAC,KAAK,SAAS;eACf,CAAC,KAAK,QAAQ;eACd,CAAC,KAAK,SAAS;eACf,CAAC,KAAK,KAAK;eACX,CAAC,KAAK,QAAQ;eACd,CAAC,KAAK,WAAW,EAAE;YACtB,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;SAClC;KACJ;IAED,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC;IAE7F,IAAA,oBAAa,EAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAEjC,IAAI,SAAS,GAAG,EAAE,CAAC;IAEnB,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAClC,OAAO,OAAO,CAAC;AACnB,CAAC,CAAA;AA7BY,QAAA,KAAK,SA6BjB"}
\ No newline at end of file
diff --git a/packages/discourse/package-lock.json b/packages/discourse/package-lock.json
new file mode 100644
index 00000000..99be53f0
--- /dev/null
+++ b/packages/discourse/package-lock.json
@@ -0,0 +1,5849 @@
+{
+ "name": "@plastichub/osr-discourse",
+ "version": "0.1.9",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "@plastichub/osr-discourse",
+ "version": "0.1.9",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@iarna/toml": "^2.2.5",
+ "@plastichub/core": "^0.2.5",
+ "@plastichub/fs": "^0.13.39",
+ "@plastichub/osr-cache": "^0.4.7",
+ "@plastichub/osr-cli-commons": "^0.5.1",
+ "@plastichub/osr-commons": "^0.3.3",
+ "@plastichub/osr-fs-utils": "^0.1.4",
+ "@plastichub/osrl": "file:../osrl",
+ "@types/markdown-it": "^12.2.3",
+ "@types/node": "^14.17.5",
+ "@types/yargs": "^17.0.11",
+ "axios": "^0.27.2",
+ "bluebird": "^3.7.2",
+ "chalk": "^2.4.1",
+ "cheerio": "^1.0.0-rc.12",
+ "chokidar": "^3.5.3",
+ "download": "^8.0.0",
+ "env-var": "^7.1.1",
+ "escape-html": "^1.0.3",
+ "fast-glob": "^3.3.0",
+ "filenamify": "^4.3.0",
+ "find-up": "^5.0.0",
+ "front-matter": "^4.0.2",
+ "generate-password": "^1.7.0",
+ "glob-base": "^0.3.0",
+ "isomorphic-unfetch": "^4.0.2",
+ "js-base64": "^3.7.2",
+ "js-beautify": "^1.14.9",
+ "json-to-pretty-yaml": "^1.2.2",
+ "markdown-it": "^13.0.1",
+ "md5": "^2.3.0",
+ "moment": "^2.29.4",
+ "native-promise-pool": "^3.19.0",
+ "pretty": "^2.0.0",
+ "querystring": "^0.2.1",
+ "request": "^2.88.2",
+ "sanitize-filename": "^1.6.3",
+ "showdown": "^2.1.0",
+ "simple-git": "^3.19.1",
+ "slugify": "^1.6.6",
+ "tslog": "^3.3.4",
+ "turndown": "^7.1.2",
+ "typescript": "^4.3.5",
+ "uri-js": "^4.4.1",
+ "yargs": "^17.5.1"
+ },
+ "bin": {
+ "osr-discourse": "main.js"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "../osr-cli-commons": {
+ "name": "@plastichub/osr-cli-commons",
+ "version": "0.4.1",
+ "extraneous": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@plastichub/core": "^0.2.6",
+ "@plastichub/fs": "^0.13.32",
+ "@plastichub/osr-commons": "^0.2.0",
+ "@types/cacache": "^15.0.1",
+ "@types/node": "^14.17.5",
+ "@types/yargs": "^17.0.2",
+ "cacache": "^16.1.2",
+ "chalk": "^2.4.1",
+ "convert-units": "^2.3.4",
+ "cryptr": "^6.0.3",
+ "env-var": "^7.1.1",
+ "fast-glob": "^3.2.11",
+ "glob-base": "^0.3.0",
+ "is-glob": "^4.0.3",
+ "parse-glob": "^3.0.4",
+ "rage-edit": "^1.2.0",
+ "typescript": "^4.3.5",
+ "yargs": "^17.5.1"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "../osrl": {
+ "name": "@plastichub/osrl",
+ "version": "0.5.4",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@elastic/elasticsearch": "^7.13.0",
+ "@google-cloud/local-auth": "^2.1.0",
+ "@iarna/toml": "^2.2.5",
+ "@plastichub/core": "^0.2.6",
+ "@plastichub/fs": "^0.13.39",
+ "@plastichub/osr-ai": "file:../osr-ai",
+ "@plastichub/osr-cache": "^0.3.9",
+ "@plastichub/osr-cli-commons": "file:../osr-cli-commons",
+ "@plastichub/osr-i18n": "file:../osr-i18n",
+ "@plastichub/osr-tasks": "file:../osr-tasks",
+ "@plastichub/osr-vcs": "^0.0.3",
+ "@types/cacache": "^15.0.1",
+ "@types/download": "^8.0.1",
+ "@types/get-stdin": "^7.0.0",
+ "@types/inquirer": "^7.3.3",
+ "@types/is-glob": "^4.0.2",
+ "@types/js-beautify": "^1.13.2",
+ "@types/jsonpath": "^0.2.0",
+ "@types/moment": "^2.13.0",
+ "@types/node": "^20.14.2",
+ "@types/yargs": "^17.0.2",
+ "axios": "^0.21.1",
+ "bluebird": "^3.7.2",
+ "cacache": "^15.2.0",
+ "chalk": "^2.4.1",
+ "cheerio": "^1.0.0-rc.10",
+ "convert-units": "^2.3.4",
+ "download": "^8.0.0",
+ "env-var": "^7.3.0",
+ "errlop": "^4.5.0",
+ "exception-formatter": "^2.1.2",
+ "fast-glob": "^3.2.7",
+ "find-up": "4.0",
+ "front-matter": "^4.0.2",
+ "get-stdin": "^9.0.0",
+ "gitea-js": "^1.20.1",
+ "glob-base": "^0.3.0",
+ "googleapis": "^105.0.0",
+ "gray-matter": "^4.0.3",
+ "grunt": "^1.6.1",
+ "grunt-cli": "^1.4.3",
+ "grunt-contrib-clean": "^2.0.0",
+ "grunt-extend-config": "^0.9.7",
+ "grunt-parallel": "^0.5.1",
+ "grunt-shell": "^3.0.1",
+ "highlight.js": "^11.1.0",
+ "inquirer": "^8.1.2",
+ "is-glob": "^4.0.1",
+ "is-url": "^1.2.4",
+ "isomorphic-unfetch": "^3.1.0",
+ "js-base64": "^3.7.2",
+ "js-beautify": "^1.14.0",
+ "jsdom": "^16.7.0",
+ "jsome": "^2.3.24",
+ "json-format-highlight": "^1.0.4",
+ "json-pretty-html": "^1.1.6",
+ "json-to-pretty-yaml": "^1.2.2",
+ "jsonpath": "^1.1.1",
+ "keyv": "^4.5.4",
+ "keyv-file": "^0.3.1",
+ "lodash": "^4.17.21",
+ "markdown-table": "^3.0.3",
+ "moment": "^2.29.1",
+ "native-promise-pool": "^3.19.0",
+ "node-xlsx": "^0.24.0",
+ "npm-run-all": "^4.1.5",
+ "open-graph-scraper": "^5.0.5",
+ "ora": "^1.3.0",
+ "parse-glob": "^3.0.4",
+ "pretty": "^2.0.0",
+ "query-string": "^7.1.3",
+ "readline": "^1.3.0",
+ "require-like": "^0.1.2",
+ "rotating-file-stream": "^3.2.3",
+ "sharp": "^0.33.4",
+ "showdown": "^2.1.0",
+ "turndown": "^7.2.0",
+ "typescript": "^4.9.4",
+ "uri-js": "^4.4.1",
+ "yaml": "^2.4.2",
+ "yargs": "^14.2.3",
+ "yargs-parser": "^15.0.3"
+ },
+ "bin": {
+ "osrl": "main.js"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ },
+ "optionalDependencies": {
+ "@img/sharp-win32-x64": "^0.33.4"
+ }
+ },
+ "node_modules/@gar/promisify": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
+ "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw=="
+ },
+ "node_modules/@iarna/toml": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz",
+ "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg=="
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+ "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
+ },
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@kwsites/file-exists": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz",
+ "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==",
+ "dependencies": {
+ "debug": "^4.1.1"
+ }
+ },
+ "node_modules/@kwsites/promise-deferred": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz",
+ "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw=="
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@npmcli/fs": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz",
+ "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==",
+ "dependencies": {
+ "@gar/promisify": "^1.1.3",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@npmcli/fs/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@npmcli/fs/node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@npmcli/move-file": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz",
+ "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==",
+ "deprecated": "This functionality has been moved to @npmcli/fs",
+ "dependencies": {
+ "mkdirp": "^1.0.4",
+ "rimraf": "^3.0.2"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@npmcli/move-file/node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@npmcli/move-file/node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@one-ini/wasm": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
+ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw=="
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@plastichub/core": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/@plastichub/core/-/core-0.2.6.tgz",
+ "integrity": "sha512-DF2IUZu6cw8+iVnFv2BFvd+s/7DYfrfXh7o3Uhg0IjbZ/QOIXY21URarnMQoTl9NEwUKN8ZZIHJmOIulT8helg==",
+ "dependencies": {
+ "deepmerge": "^4.3.1",
+ "tslog": "^3.3.3"
+ }
+ },
+ "node_modules/@plastichub/fs": {
+ "version": "0.13.39",
+ "resolved": "https://registry.npmjs.org/@plastichub/fs/-/fs-0.13.39.tgz",
+ "integrity": "sha512-Q96zN5LAlTmtj6gIbHbVM0erp2NgP+P4izRzdhqnMz/WopAvD7ZJxjQ/J44e67R6WKQuvcxt/eXPNaFBB5ehlg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@plastichub/core": "^0.2.1",
+ "@types/denodeify": "^1.2.31",
+ "@types/glob": "^8.1.0",
+ "@types/minimatch": "^3.0.3",
+ "@types/node": "^14.18.63",
+ "denodeify": "^1.2.1",
+ "errno": "^0.1.4",
+ "glob": "^10.4.1",
+ "mime": "^2.0.3",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "progress-stream": "^1.2.0",
+ "q": "^1.4.1",
+ "rimraf": "^2.7.1",
+ "throttle": "^1.0.3",
+ "trash": "^4.3.0",
+ "typescript": "^4.0.3",
+ "write-file-atomic": "^1.3.1",
+ "yargs": "^17.7.2"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ }
+ },
+ "node_modules/@plastichub/fs/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@plastichub/fs/node_modules/glob": {
+ "version": "10.4.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz",
+ "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@plastichub/fs/node_modules/glob/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@plastichub/fs/node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/@plastichub/osr-cache": {
+ "version": "0.4.7",
+ "resolved": "https://registry.npmjs.org/@plastichub/osr-cache/-/osr-cache-0.4.7.tgz",
+ "integrity": "sha512-uSuU+4xefo0+mX+Nft0QP4UZsp1y3afwGPOvcuRDusiMB+ShnVybUJs3T15M3JEuWSG32fViQfZnexVNiSCLLg==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@plastichub/core": "^0.2.6",
+ "@plastichub/fs": "^0.13.32",
+ "@plastichub/osr-cli-commons": "^0.5.1",
+ "@types/node": "^20.14.9",
+ "@types/yargs": "^17.0.32",
+ "cacache": "^18.0.3",
+ "md5": "^2.3.0",
+ "yargs": "^17.7.2"
+ },
+ "bin": {
+ "osr-cache": "main.js"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/@npmcli/fs": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz",
+ "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==",
+ "license": "ISC",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/@types/node": {
+ "version": "20.16.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz",
+ "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.19.2"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/cacache": {
+ "version": "18.0.4",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz",
+ "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==",
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/fs": "^3.1.0",
+ "fs-minipass": "^3.0.0",
+ "glob": "^10.2.2",
+ "lru-cache": "^10.0.1",
+ "minipass": "^7.0.3",
+ "minipass-collect": "^2.0.1",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "p-map": "^4.0.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11",
+ "unique-filename": "^3.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/fs-minipass": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz",
+ "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "license": "ISC"
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/minipass-collect": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz",
+ "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "license": "MIT",
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/semver": {
+ "version": "7.6.3",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
+ "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/ssri": {
+ "version": "10.0.6",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz",
+ "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==",
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/unique-filename": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz",
+ "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==",
+ "license": "ISC",
+ "dependencies": {
+ "unique-slug": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-cache/node_modules/unique-slug": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz",
+ "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==",
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-cli-commons": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/@plastichub/osr-cli-commons/-/osr-cli-commons-0.5.1.tgz",
+ "integrity": "sha512-qEhCgnLsQ5xHivRL1/lfWGb7sBZSKYnjhvN9bdh8bA/qvIHbUa4azoFbC+wKMX6DxMZNlnzRUqH3fQvTQ8kkoQ==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@plastichub/core": "^0.2.6",
+ "@plastichub/fs": "^0.13.32",
+ "@plastichub/osr-commons": "^0.3.3",
+ "@types/cacache": "^15.0.1",
+ "@types/node": "^20.14.9",
+ "@types/which": "^3.0.4",
+ "@types/yargs": "^17.0.2",
+ "bluebird": "^3.7.2",
+ "cacache": "^16.1.2",
+ "chalk": "^2.4.1",
+ "convert-units": "^2.3.4",
+ "cryptr": "^6.0.3",
+ "env-var": "^7.1.1",
+ "fast-glob": "^3.2.11",
+ "glob": "^10.4.1",
+ "glob-base": "github:justin-caribou/glob-base",
+ "is-glob": "^4.0.3",
+ "parse-glob": "^3.0.4",
+ "rage-edit": "^1.2.0",
+ "typescript": "^4.3.5",
+ "which": "^4.0.0",
+ "yargs": "^17.5.1"
+ },
+ "bin": {
+ "osr-cli": "main.js"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-cli-commons/node_modules/@types/node": {
+ "version": "20.16.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.5.tgz",
+ "integrity": "sha512-VwYCweNo3ERajwy0IUlqqcyZ8/A7Zwa9ZP3MnENWcB11AejO+tLy3pu850goUW2FC/IJMdZUfKpX/yxL1gymCA==",
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.19.2"
+ }
+ },
+ "node_modules/@plastichub/osr-cli-commons/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-cli-commons/node_modules/glob": {
+ "version": "10.4.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz",
+ "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@plastichub/osr-cli-commons/node_modules/isexe": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz",
+ "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@plastichub/osr-cli-commons/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@plastichub/osr-cli-commons/node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/@plastichub/osr-cli-commons/node_modules/which": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
+ "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-commons": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/@plastichub/osr-commons/-/osr-commons-0.3.3.tgz",
+ "integrity": "sha512-NW2XBeeD7AdFh5HkKOGDEMxJf6E8rS8cr8LdaY8JfM1DDae+VeX+H2wOMsSY8dgJy0VYU9ci21yuGWbEWHjGVA==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@plastichub/core": "^0.2.1",
+ "@plastichub/fs": "^0.13.32",
+ "convert-units": "^2.3.4",
+ "cryptr": "^6.0.3",
+ "env-var": "^7.1.1",
+ "filenamify": "^4.3.0",
+ "querystring": "^0.2.1",
+ "sanitize-filename": "^1.6.3",
+ "shell-escape": "^0.2.0",
+ "tslog": "^3.3.3",
+ "typescript": "^4.3.5",
+ "yargs": "^17.5.1"
+ },
+ "bin": {
+ "osr-commons": "main.js"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-fs-utils": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/@plastichub/osr-fs-utils/-/osr-fs-utils-0.1.4.tgz",
+ "integrity": "sha512-MRIhPDv9m6eEcignsWN2738CZp1HOkxCKDAv39O8HivUbop5jK17LKSj8egHScHFWsajojlaYFRb0KjPyB1Fqg==",
+ "dependencies": {
+ "@plastichub/core": "^0.2.6",
+ "@plastichub/fs": "^0.13.39",
+ "@plastichub/osr-cli-commons": "^0.4.9",
+ "@plastichub/osr-commons": "^0.3.3",
+ "@schemastore/package": "^0.0.8",
+ "@types/tar": "^6.1.5",
+ "bluebird": "^3.7.2",
+ "csv-generate": "^4.2.6",
+ "live-plugin-manager": "^0.17.1",
+ "node-xlsx": "^0.24.0",
+ "simple-git": "^3.18.0"
+ },
+ "bin": {
+ "osr-fs": "main.js"
+ },
+ "engines": {
+ "node": ">= 18.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-fs-utils/node_modules/@plastichub/osr-cli-commons": {
+ "version": "0.4.9",
+ "resolved": "https://registry.npmjs.org/@plastichub/osr-cli-commons/-/osr-cli-commons-0.4.9.tgz",
+ "integrity": "sha512-/cVXEqMp1T4n8njCnzzSqchTdSyPmzcqiucjCiR8Jc27uvzNAtTE+8pOxnmyibUqjkKijFV2CoJ2jVGguthAyA==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@plastichub/core": "^0.2.6",
+ "@plastichub/fs": "^0.13.32",
+ "@plastichub/osr-commons": "^0.3.3",
+ "@types/cacache": "^15.0.1",
+ "@types/node": "^14.17.5",
+ "@types/which": "^3.0.3",
+ "@types/yargs": "^17.0.2",
+ "bluebird": "^3.7.2",
+ "cacache": "^16.1.2",
+ "chalk": "^2.4.1",
+ "convert-units": "^2.3.4",
+ "cryptr": "^6.0.3",
+ "env-var": "^7.1.1",
+ "fast-glob": "^3.2.11",
+ "glob": "^10.4.1",
+ "glob-base": "github:justin-caribou/glob-base",
+ "is-glob": "^4.0.3",
+ "parse-glob": "^3.0.4",
+ "rage-edit": "^1.2.0",
+ "typescript": "^4.3.5",
+ "which": "^4.0.0",
+ "yargs": "^17.5.1"
+ },
+ "bin": {
+ "osr-cli": "main.js"
+ },
+ "engines": {
+ "node": ">= 14.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-fs-utils/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/@plastichub/osr-fs-utils/node_modules/glob": {
+ "version": "10.4.5",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@plastichub/osr-fs-utils/node_modules/isexe": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz",
+ "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/@plastichub/osr-fs-utils/node_modules/minimatch": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@plastichub/osr-fs-utils/node_modules/minipass": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/@plastichub/osr-fs-utils/node_modules/which": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz",
+ "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==",
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/@plastichub/osrl": {
+ "resolved": "../osrl",
+ "link": true
+ },
+ "node_modules/@schemastore/package": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/@schemastore/package/-/package-0.0.8.tgz",
+ "integrity": "sha512-1jMrmFLUZBeQ7zdxe3ez1LSLYrUH4eY3gAPisW1rbNZ62zoYy8sudo9fXSS182s8f7p6TRy7wD6ybZvz9SUT1Q=="
+ },
+ "node_modules/@sindresorhus/df": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-2.1.0.tgz",
+ "integrity": "sha512-yozEsK3X8sEjh9fiolh3JntMUuGKe2n2t8gtE3yZ1PqAFFeaSxTrSiEVORy/YkPzUsxQ85RzLcGqmqSOgiFhtg==",
+ "dependencies": {
+ "execa": "^0.2.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@sindresorhus/df/node_modules/execa": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.2.2.tgz",
+ "integrity": "sha512-zmBGzLd3nhA/NB9P7VLoceAO6vyYPftvl809Vjwe5U2fYI9tYWbeKqP3wZlAw9WS+znnkogf/bhSU+Gcn2NbkQ==",
+ "dependencies": {
+ "cross-spawn-async": "^2.1.1",
+ "npm-run-path": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "path-key": "^1.0.0",
+ "strip-eof": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.12"
+ }
+ },
+ "node_modules/@sindresorhus/df/node_modules/npm-run-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-1.0.0.tgz",
+ "integrity": "sha512-PrGAi1SLlqNvKN5uGBjIgnrTb8fl0Jz0a3JJmeMcGnIBh7UE9Gc4zsAMlwDajOMg2b1OgP6UPvoLUboTmMZPFA==",
+ "dependencies": {
+ "path-key": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@sindresorhus/df/node_modules/path-key": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-1.0.0.tgz",
+ "integrity": "sha512-T3hWy7tyXlk3QvPFnT+o2tmXRzU4GkitkUWLp/WZ0S/FXd7XMx176tRurgTvHTNMJOQzTcesHNpBqetH86mQ9g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@sindresorhus/is": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.7.0.tgz",
+ "integrity": "sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@types/cacache": {
+ "version": "15.0.1",
+ "resolved": "https://registry.npmjs.org/@types/cacache/-/cacache-15.0.1.tgz",
+ "integrity": "sha512-JhL2GFJuHMx4RMg4z0XfXB4ZkKdyiOaOLpjoYMXcyKfrkF3IBXNZBj6/Peo9zX/7PPHyfI63NWVD589cI2YTzg==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/debug": {
+ "version": "4.1.12",
+ "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
+ "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==",
+ "dependencies": {
+ "@types/ms": "*"
+ }
+ },
+ "node_modules/@types/denodeify": {
+ "version": "1.2.35",
+ "resolved": "https://registry.npmjs.org/@types/denodeify/-/denodeify-1.2.35.tgz",
+ "integrity": "sha512-5ixm6RMZKJUMlFKPZj378M/NOCGdodVVzvkYKlYbGp6mQ/r1C7C5KVroSTsZTI75qqmczZeOhhGywcWVURPMMw=="
+ },
+ "node_modules/@types/fs-extra": {
+ "version": "9.0.13",
+ "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz",
+ "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==",
+ "dependencies": {
+ "@types/minimatch": "^5.1.2",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/glob/node_modules/@types/minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA=="
+ },
+ "node_modules/@types/linkify-it": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz",
+ "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA=="
+ },
+ "node_modules/@types/lockfile": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@types/lockfile/-/lockfile-1.0.4.tgz",
+ "integrity": "sha512-Q8oFIHJHr+htLrTXN2FuZfg+WXVHQRwU/hC2GpUu+Q8e3FUM9EDkS2pE3R2AO1ZGu56f479ybdMCNF1DAu8cAQ=="
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "12.2.3",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz",
+ "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==",
+ "dependencies": {
+ "@types/linkify-it": "*",
+ "@types/mdurl": "*"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz",
+ "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA=="
+ },
+ "node_modules/@types/minimatch": {
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz",
+ "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ=="
+ },
+ "node_modules/@types/minipass": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/@types/minipass/-/minipass-3.3.5.tgz",
+ "integrity": "sha512-M2BLHQdEmDmH671h0GIlOQQJrgezd1vNqq7PVj1VOsHZ2uQQb4iPiQIl0SlMdhxZPUsLIfEklmeEHXg8DJRewA==",
+ "deprecated": "This is a stub types definition. minipass provides its own type definitions, so you do not need this installed.",
+ "dependencies": {
+ "minipass": "*"
+ }
+ },
+ "node_modules/@types/ms": {
+ "version": "0.7.34",
+ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz",
+ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g=="
+ },
+ "node_modules/@types/node": {
+ "version": "14.18.63",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz",
+ "integrity": "sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ=="
+ },
+ "node_modules/@types/node-fetch": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.9.tgz",
+ "integrity": "sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA==",
+ "dependencies": {
+ "@types/node": "*",
+ "form-data": "^4.0.0"
+ }
+ },
+ "node_modules/@types/semver": {
+ "version": "7.5.6",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.6.tgz",
+ "integrity": "sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A=="
+ },
+ "node_modules/@types/tar": {
+ "version": "6.1.10",
+ "resolved": "https://registry.npmjs.org/@types/tar/-/tar-6.1.10.tgz",
+ "integrity": "sha512-60ZO+W0tRKJ3ggdzJKp75xKVlNogKYMqGvr2bMH/+k3T0BagfYTnbmVDFMJB1BFttz6yRgP5MDGP27eh7brrqw==",
+ "dependencies": {
+ "@types/node": "*",
+ "minipass": "^4.0.0"
+ }
+ },
+ "node_modules/@types/tar/node_modules/minipass": {
+ "version": "4.2.8",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz",
+ "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@types/url-join": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@types/url-join/-/url-join-4.0.1.tgz",
+ "integrity": "sha512-wDXw9LEEUHyV+7UWy7U315nrJGJ7p1BzaCxDpEoLr789Dk1WDVMMlf3iBfbG2F8NdWnYyFbtTxUn2ZNbm1Q4LQ=="
+ },
+ "node_modules/@types/which": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/@types/which/-/which-3.0.4.tgz",
+ "integrity": "sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w=="
+ },
+ "node_modules/@types/yargs": {
+ "version": "17.0.33",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
+ "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
+ "license": "MIT",
+ "dependencies": {
+ "@types/yargs-parser": "*"
+ }
+ },
+ "node_modules/@types/yargs-parser": {
+ "version": "21.0.0",
+ "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz",
+ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA=="
+ },
+ "node_modules/abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+ },
+ "node_modules/aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dependencies": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "6.12.6",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
+ "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/anymatch": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
+ "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
+ "dependencies": {
+ "normalize-path": "^3.0.0",
+ "picomatch": "^2.0.4"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/archive-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/archive-type/-/archive-type-4.0.0.tgz",
+ "integrity": "sha512-zV4Ky0v1F8dBrdYElwTvQhweQ0P7Kwc1aluqJsYtOBP01jXcWCyW2IEfI1YiqsG+Iy7ZR+o5LF1N+PGECBxHWA==",
+ "dependencies": {
+ "file-type": "^4.2.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/archive-type/node_modules/file-type": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz",
+ "integrity": "sha512-f2UbFQEk7LXgWpi5ntcO86OeA/cC80fuDDDaX/fZ2ZGel+AF7leRQqBBW1eJNiiQkrZlAoM6P+VYP5P6bOlDEQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==",
+ "dependencies": {
+ "array-uniq": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/asn1": {
+ "version": "0.2.6",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
+ "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
+ "dependencies": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "node_modules/assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
+ },
+ "node_modules/aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/aws4": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz",
+ "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg=="
+ },
+ "node_modules/axios": {
+ "version": "0.27.2",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.27.2.tgz",
+ "integrity": "sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==",
+ "dependencies": {
+ "follow-redirects": "^1.14.9",
+ "form-data": "^4.0.0"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "node_modules/base64-js": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
+ "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
+ "dependencies": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
+ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/bl": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.3.tgz",
+ "integrity": "sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==",
+ "dependencies": {
+ "readable-stream": "^2.3.5",
+ "safe-buffer": "^5.1.1"
+ }
+ },
+ "node_modules/bl/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+ },
+ "node_modules/bl/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/bl/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/bl/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg=="
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww=="
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/braces": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
+ "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
+ "dependencies": {
+ "fill-range": "^7.1.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/buffer": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+ "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "base64-js": "^1.3.1",
+ "ieee754": "^1.1.13"
+ }
+ },
+ "node_modules/buffer-alloc": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
+ "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
+ "dependencies": {
+ "buffer-alloc-unsafe": "^1.1.0",
+ "buffer-fill": "^1.0.0"
+ }
+ },
+ "node_modules/buffer-alloc-unsafe": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
+ "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg=="
+ },
+ "node_modules/buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/buffer-fill": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+ "integrity": "sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ=="
+ },
+ "node_modules/buffer-from": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
+ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
+ },
+ "node_modules/cacache": {
+ "version": "16.1.3",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz",
+ "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==",
+ "dependencies": {
+ "@npmcli/fs": "^2.1.0",
+ "@npmcli/move-file": "^2.0.0",
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.1.0",
+ "glob": "^8.0.1",
+ "infer-owner": "^1.0.4",
+ "lru-cache": "^7.7.1",
+ "minipass": "^3.1.6",
+ "minipass-collect": "^1.0.2",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "mkdirp": "^1.0.4",
+ "p-map": "^4.0.0",
+ "promise-inflight": "^1.0.1",
+ "rimraf": "^3.0.2",
+ "ssri": "^9.0.0",
+ "tar": "^6.1.11",
+ "unique-filename": "^2.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/cacache/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/cacache/node_modules/glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/cacache/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cacache/node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cacache/node_modules/p-map": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
+ "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cacache/node_modules/rimraf": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+ "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/cacache/node_modules/rimraf/node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/cacache/node_modules/rimraf/node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/cacache/node_modules/rimraf/node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/cacheable-request": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-2.1.4.tgz",
+ "integrity": "sha512-vag0O2LKZ/najSoUwDbVlnlCFvhBE/7mGTY2B5FgCBDcRD+oVV1HYTOwM6JZfMg/hIcM6IwnTZ1uQQL5/X3xIQ==",
+ "dependencies": {
+ "clone-response": "1.0.2",
+ "get-stream": "3.0.0",
+ "http-cache-semantics": "3.8.1",
+ "keyv": "3.0.0",
+ "lowercase-keys": "1.0.0",
+ "normalize-url": "2.0.1",
+ "responselike": "1.0.2"
+ }
+ },
+ "node_modules/cacheable-request/node_modules/lowercase-keys": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
+ "integrity": "sha512-RPlX0+PHuvxVDZ7xX+EBVAp4RsVxP/TdDSN2mJYdiq1Lc4Hz7EUSjUI7RZrKKlmrIzVhf6Jo2stj7++gVarS0A==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw=="
+ },
+ "node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/charenc": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz",
+ "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/cheerio": {
+ "version": "1.0.0-rc.12",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
+ "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
+ "dependencies": {
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1",
+ "htmlparser2": "^8.0.1",
+ "parse5": "^7.0.0",
+ "parse5-htmlparser2-tree-adapter": "^7.0.0"
+ },
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-select": "^5.1.0",
+ "css-what": "^6.1.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "3.5.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+ "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ ],
+ "dependencies": {
+ "anymatch": "~3.1.2",
+ "braces": "~3.0.2",
+ "glob-parent": "~5.1.2",
+ "is-binary-path": "~2.1.0",
+ "is-glob": "~4.0.1",
+ "normalize-path": "~3.0.0",
+ "readdirp": "~3.6.0"
+ },
+ "engines": {
+ "node": ">= 8.10.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/chownr": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz",
+ "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/clone-response": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+ "integrity": "sha512-yjLXh88P599UOyPTFX0POsd7WxnbsVsGohcwzHOLspIhhpalPw1BcqED8NblyZLKcGrL8dTgMlcaZxV2jAD41Q==",
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ },
+ "node_modules/condense-newlines": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/condense-newlines/-/condense-newlines-0.2.1.tgz",
+ "integrity": "sha512-P7X+QL9Hb9B/c8HI5BFFKmjgBu2XpQuF98WZ9XkO+dBGgk5XgwiQz7o1SmpglNWId3581UcS0SFAWfoIhMHPfg==",
+ "dependencies": {
+ "extend-shallow": "^2.0.1",
+ "is-whitespace": "^0.3.0",
+ "kind-of": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "node_modules/content-disposition": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
+ "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==",
+ "dependencies": {
+ "safe-buffer": "5.2.1"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/convert-units": {
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/convert-units/-/convert-units-2.3.4.tgz",
+ "integrity": "sha512-ERHfdA0UhHJp1IpwE6PnFJx8LqG7B1ZjJ20UvVCmopEnVCfER68Tbe3kvN63dLbYXDA2xFWRE6zd4Wsf0w7POg==",
+ "dependencies": {
+ "lodash.foreach": "2.3.x",
+ "lodash.keys": "2.3.x"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
+ },
+ "node_modules/cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dependencies": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "engines": {
+ "node": ">=4.8"
+ }
+ },
+ "node_modules/cross-spawn-async": {
+ "version": "2.2.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn-async/-/cross-spawn-async-2.2.5.tgz",
+ "integrity": "sha512-snteb3aVrxYYOX9e8BabYFK9WhCDhTlw1YQktfTthBogxri4/2r9U2nQc0ffY73ZAxezDc+U8gvHAeU1wy1ubQ==",
+ "deprecated": "cross-spawn no longer requires a build toolchain, use it instead",
+ "dependencies": {
+ "lru-cache": "^4.0.0",
+ "which": "^1.2.8"
+ }
+ },
+ "node_modules/cross-spawn-async/node_modules/lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dependencies": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "node_modules/cross-spawn-async/node_modules/yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
+ },
+ "node_modules/crypt": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz",
+ "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/cryptr": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/cryptr/-/cryptr-6.2.0.tgz",
+ "integrity": "sha512-jYi8SxvOFebTT7EYOABiPpHKY6lwWaP9IVcvT/aIVJUVoFdzTgi0ySPCL78q1ig8w2kwfXFCZACXoCXaye57aw=="
+ },
+ "node_modules/css-select": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
+ "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
+ "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/csv-generate": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/csv-generate/-/csv-generate-4.3.0.tgz",
+ "integrity": "sha512-7KdVId/2RgwPIKfWHaHtjBq7I9mgdi8ICzsUyIhP8is6UwpwVGGSC/aPnrZ8/SkgBcCP20lXrdPuP64Irs1VBg=="
+ },
+ "node_modules/dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/data-uri-to-buffer": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz",
+ "integrity": "sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA==",
+ "engines": {
+ "node": ">= 12"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/decode-uri-component": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz",
+ "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==",
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/decompress": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.1.tgz",
+ "integrity": "sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ==",
+ "dependencies": {
+ "decompress-tar": "^4.0.0",
+ "decompress-tarbz2": "^4.0.0",
+ "decompress-targz": "^4.0.0",
+ "decompress-unzip": "^4.0.1",
+ "graceful-fs": "^4.1.10",
+ "make-dir": "^1.0.0",
+ "pify": "^2.3.0",
+ "strip-dirs": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==",
+ "dependencies": {
+ "mimic-response": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-tar": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
+ "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==",
+ "dependencies": {
+ "file-type": "^5.2.0",
+ "is-stream": "^1.1.0",
+ "tar-stream": "^1.5.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-tar/node_modules/file-type": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
+ "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-tarbz2": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz",
+ "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==",
+ "dependencies": {
+ "decompress-tar": "^4.1.0",
+ "file-type": "^6.1.0",
+ "is-stream": "^1.1.0",
+ "seek-bzip": "^1.0.5",
+ "unbzip2-stream": "^1.0.9"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-tarbz2/node_modules/file-type": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz",
+ "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-targz": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz",
+ "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==",
+ "dependencies": {
+ "decompress-tar": "^4.1.1",
+ "file-type": "^5.2.0",
+ "is-stream": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-targz/node_modules/file-type": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz",
+ "integrity": "sha512-Iq1nJ6D2+yIO4c8HHg4fyVb8mAJieo1Oloy1mLLaB2PvezNedhBVm+QU7g0qM42aiMbRXTxKKwGD17rjKNJYVQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-unzip": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz",
+ "integrity": "sha512-1fqeluvxgnn86MOh66u8FjbtJpAFv5wgCT9Iw8rcBqQcCo5tO8eiJw7NNTrvt9n4CRBVq7CstiS922oPgyGLrw==",
+ "dependencies": {
+ "file-type": "^3.8.0",
+ "get-stream": "^2.2.0",
+ "pify": "^2.3.0",
+ "yauzl": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress-unzip/node_modules/file-type": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+ "integrity": "sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/decompress-unzip/node_modules/get-stream": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz",
+ "integrity": "sha512-AUGhbbemXxrZJRD5cDvKtQxLuYaIbNtDTK8YqupCI393Q2KSTreEsLUN3ZxAWFGiKTzL6nKuzfcIvieflUX9qA==",
+ "dependencies": {
+ "object-assign": "^4.0.1",
+ "pinkie-promise": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/decompress/node_modules/make-dir": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+ "dependencies": {
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/decompress/node_modules/make-dir/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/deepmerge": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
+ "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/denodeify": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz",
+ "integrity": "sha512-KNTihKNmQENUZeKu5fzfpzRqR5S2VMp4gl9RFHiWzj9DfvYQPMJ6XHKNaQxaGCXwPk6y9yme3aUoaiAe+KX+vg=="
+ },
+ "node_modules/dir-glob": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
+ "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
+ "dependencies": {
+ "path-type": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ]
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domino": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/domino/-/domino-2.1.6.tgz",
+ "integrity": "sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ=="
+ },
+ "node_modules/domutils": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz",
+ "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/download": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/download/-/download-8.0.0.tgz",
+ "integrity": "sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA==",
+ "dependencies": {
+ "archive-type": "^4.0.0",
+ "content-disposition": "^0.5.2",
+ "decompress": "^4.2.1",
+ "ext-name": "^5.0.0",
+ "file-type": "^11.1.0",
+ "filenamify": "^3.0.0",
+ "get-stream": "^4.1.0",
+ "got": "^8.3.1",
+ "make-dir": "^2.1.0",
+ "p-event": "^2.1.0",
+ "pify": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/download/node_modules/filenamify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-3.0.0.tgz",
+ "integrity": "sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g==",
+ "dependencies": {
+ "filename-reserved-regex": "^2.0.0",
+ "strip-outer": "^1.0.0",
+ "trim-repeated": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/download/node_modules/get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/download/node_modules/pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/duplexer3": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz",
+ "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA=="
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
+ },
+ "node_modules/ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
+ "dependencies": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "node_modules/editorconfig": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz",
+ "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==",
+ "dependencies": {
+ "@one-ini/wasm": "0.1.1",
+ "commander": "^10.0.0",
+ "minimatch": "9.0.1",
+ "semver": "^7.5.3"
+ },
+ "bin": {
+ "editorconfig": "bin/editorconfig"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/editorconfig/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/editorconfig/node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/editorconfig/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/editorconfig/node_modules/minimatch": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
+ "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/editorconfig/node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+ },
+ "node_modules/end-of-stream": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
+ "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
+ "dependencies": {
+ "once": "^1.4.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/env-var": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/env-var/-/env-var-7.3.0.tgz",
+ "integrity": "sha512-qwtwYJ9d3XFxXRDudPEAMszaggpDgcfb1ZGYb9/cNyMugN2/a8EtviopnRL6c+petj2vp6/gxwYd9ExL1/iPcw==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/errno": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz",
+ "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==",
+ "dependencies": {
+ "prr": "~1.0.1"
+ },
+ "bin": {
+ "errno": "cli.js"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow=="
+ },
+ "node_modules/escape-string-applescript": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-applescript/-/escape-string-applescript-2.0.0.tgz",
+ "integrity": "sha512-Z7OsRJUi5+OHT89RRJlkS8cKxIh9AyPmgtEevsSQFCx5WLIiS3hy/HRiiQZzYQMsn6MWyCDZ5elBFa/9dxT0BA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/execa": {
+ "version": "0.10.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz",
+ "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==",
+ "dependencies": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^3.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ext-list": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz",
+ "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==",
+ "dependencies": {
+ "mime-db": "^1.28.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ext-name": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz",
+ "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==",
+ "dependencies": {
+ "ext-list": "^2.0.0",
+ "sort-keys-length": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "node_modules/extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==",
+ "dependencies": {
+ "is-extendable": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==",
+ "engines": [
+ "node >=0.6.0"
+ ]
+ },
+ "node_modules/fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz",
+ "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==",
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fast-json-stable-stringify": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
+ },
+ "node_modules/fastq": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
+ "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/fd-slicer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
+ "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
+ "dependencies": {
+ "pend": "~1.2.0"
+ }
+ },
+ "node_modules/fetch-blob": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
+ "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "dependencies": {
+ "node-domexception": "^1.0.0",
+ "web-streams-polyfill": "^3.0.3"
+ },
+ "engines": {
+ "node": "^12.20 || >= 14.13"
+ }
+ },
+ "node_modules/file-type": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-11.1.0.tgz",
+ "integrity": "sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/filename-reserved-regex": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
+ "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/filenamify": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz",
+ "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==",
+ "dependencies": {
+ "filename-reserved-regex": "^2.0.0",
+ "strip-outer": "^1.0.1",
+ "trim-repeated": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
+ "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/find-up/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/follow-redirects": {
+ "version": "1.15.6",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
+ "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/RubenVerborgh"
+ }
+ ],
+ "engines": {
+ "node": ">=4.0"
+ },
+ "peerDependenciesMeta": {
+ "debug": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/foreground-child": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
+ "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/foreground-child/node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/foreground-child/node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/foreground-child/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/foreground-child/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/foreground-child/node_modules/signal-exit": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.0.2.tgz",
+ "integrity": "sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/foreground-child/node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/formdata-polyfill": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
+ "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
+ "dependencies": {
+ "fetch-blob": "^3.1.2"
+ },
+ "engines": {
+ "node": ">=12.20.0"
+ }
+ },
+ "node_modules/from2": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+ "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==",
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0"
+ }
+ },
+ "node_modules/from2/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+ },
+ "node_modules/from2/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/from2/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/from2/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/front-matter": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz",
+ "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==",
+ "dependencies": {
+ "js-yaml": "^3.13.1"
+ }
+ },
+ "node_modules/fs-constants": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
+ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
+ },
+ "node_modules/fs-extra": {
+ "version": "0.30.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz",
+ "integrity": "sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==",
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0",
+ "path-is-absolute": "^1.0.0",
+ "rimraf": "^2.2.8"
+ }
+ },
+ "node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
+ "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
+ "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "hasInstallScript": true,
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/generate-password": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/generate-password/-/generate-password-1.7.0.tgz",
+ "integrity": "sha512-WPCtlfy0jexf7W5IbwxGUgpIDvsZIohbI2DAq2Q6TSlKKis+G4GT9sxvPxrZUGL8kP6WUXMWNqYnxY6DDKAdFA=="
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
+ "dependencies": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "node_modules/glob": {
+ "version": "7.2.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+ "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.1.1",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-base": {
+ "version": "0.3.0",
+ "resolved": "git+ssh://git@github.com/justin-caribou/glob-base.git#d4fe4313e55988a902a3940127cb946a7defbb50",
+ "dependencies": {
+ "glob-parent": "^6.0.2",
+ "is-glob": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/glob-base/node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob-base/node_modules/glob-parent/node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/glob-base/node_modules/is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==",
+ "dependencies": {
+ "is-extglob": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/glob-base/node_modules/is-glob/node_modules/is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/got": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/got/-/got-8.3.2.tgz",
+ "integrity": "sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw==",
+ "dependencies": {
+ "@sindresorhus/is": "^0.7.0",
+ "cacheable-request": "^2.1.1",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^3.0.0",
+ "into-stream": "^3.1.0",
+ "is-retry-allowed": "^1.1.0",
+ "isurl": "^1.0.0-alpha5",
+ "lowercase-keys": "^1.0.0",
+ "mimic-response": "^1.0.0",
+ "p-cancelable": "^0.4.0",
+ "p-timeout": "^2.0.1",
+ "pify": "^3.0.0",
+ "safe-buffer": "^5.1.1",
+ "timed-out": "^4.0.1",
+ "url-parse-lax": "^3.0.0",
+ "url-to-options": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/got/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
+ },
+ "node_modules/har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/har-validator": {
+ "version": "5.1.5",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz",
+ "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==",
+ "deprecated": "this library is no longer supported",
+ "dependencies": {
+ "ajv": "^6.12.3",
+ "har-schema": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/has-symbol-support-x": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz",
+ "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/has-to-string-tag-x": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+ "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+ "dependencies": {
+ "has-symbol-support-x": "^1.4.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz",
+ "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==",
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1",
+ "entities": "^4.4.0"
+ }
+ },
+ "node_modules/http-cache-semantics": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz",
+ "integrity": "sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w=="
+ },
+ "node_modules/http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==",
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ },
+ "engines": {
+ "node": ">=0.8",
+ "npm": ">=1.3.7"
+ }
+ },
+ "node_modules/ieee754": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/ignore": {
+ "version": "3.3.10",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz",
+ "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug=="
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/infer-owner": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz",
+ "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ },
+ "node_modules/into-stream": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-3.1.0.tgz",
+ "integrity": "sha512-TcdjPibTksa1NQximqep2r17ISRiNE9fwlfbg3F8ANdvP5/yrFTew86VcO//jk4QTaMlbjypPBq76HN2zaKfZQ==",
+ "dependencies": {
+ "from2": "^2.1.1",
+ "p-is-promise": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-binary-path": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
+ "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
+ "dependencies": {
+ "binary-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+ },
+ "node_modules/is-dotfile": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
+ "integrity": "sha512-9YclgOGtN/f8zx0Pr4FQYMdibBiTaH3sn52vjYip4ZSf6C4/6RfTEZ+MR4GvKhCxdPh21Bg42/WL55f6KSnKpg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-natural-number": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz",
+ "integrity": "sha512-Y4LTamMe0DDQIIAlaer9eKebAlDSV6huy+TWhJVPlzZh2o4tRP5SQWFlLn5N0To4mDD22/qdOq+veo1cSISLgQ=="
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-object": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.2.tgz",
+ "integrity": "sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-retry-allowed": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz",
+ "integrity": "sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA=="
+ },
+ "node_modules/is-whitespace": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/is-whitespace/-/is-whitespace-0.3.0.tgz",
+ "integrity": "sha512-RydPhl4S6JwAyj0JJjshWJEFG6hNye3pZFBRZaTUfZFwGHxzppNaNOVgQuS/E/SlhrApuMXrpnK1EEIXfdo3Dg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ=="
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
+ },
+ "node_modules/isomorphic-unfetch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/isomorphic-unfetch/-/isomorphic-unfetch-4.0.2.tgz",
+ "integrity": "sha512-1Yd+CF/7al18/N2BDbsLBcp6RO3tucSW+jcLq24dqdX5MNbCNTw1z4BsGsp4zNmjr/Izm2cs/cEqZPp4kvWSCA==",
+ "dependencies": {
+ "node-fetch": "^3.2.0",
+ "unfetch": "^5.0.0"
+ }
+ },
+ "node_modules/isomorphic-unfetch/node_modules/node-fetch": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.0.tgz",
+ "integrity": "sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==",
+ "dependencies": {
+ "data-uri-to-buffer": "^4.0.0",
+ "fetch-blob": "^3.1.4",
+ "formdata-polyfill": "^4.0.10"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/node-fetch"
+ }
+ },
+ "node_modules/isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g=="
+ },
+ "node_modules/isurl": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+ "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+ "dependencies": {
+ "has-to-string-tag-x": "^1.2.0",
+ "is-object": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/js-base64": {
+ "version": "3.7.4",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-3.7.4.tgz",
+ "integrity": "sha512-wpM/wi20Tl+3ifTyi0RdDckS4YTD4Lf953mBRrpG8547T7hInHNPEj8+ck4gB8VDcGyeAWFK++Wb/fU1BeavKQ=="
+ },
+ "node_modules/js-beautify": {
+ "version": "1.14.9",
+ "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.14.9.tgz",
+ "integrity": "sha512-coM7xq1syLcMyuVGyToxcj2AlzhkDjmfklL8r0JgJ7A76wyGMpJ1oA35mr4APdYNO/o/4YY8H54NQIJzhMbhBg==",
+ "dependencies": {
+ "config-chain": "^1.1.13",
+ "editorconfig": "^1.0.3",
+ "glob": "^8.1.0",
+ "nopt": "^6.0.0"
+ },
+ "bin": {
+ "css-beautify": "js/bin/css-beautify.js",
+ "html-beautify": "js/bin/html-beautify.js",
+ "js-beautify": "js/bin/js-beautify.js"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/js-beautify/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/js-beautify/node_modules/glob": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+ "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/js-beautify/node_modules/minimatch": {
+ "version": "5.1.6",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
+ "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/js-yaml": {
+ "version": "3.14.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz",
+ "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==",
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg=="
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+ "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ=="
+ },
+ "node_modules/json-schema": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz",
+ "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="
+ },
+ "node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="
+ },
+ "node_modules/json-to-pretty-yaml": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/json-to-pretty-yaml/-/json-to-pretty-yaml-1.2.2.tgz",
+ "integrity": "sha512-rvm6hunfCcqegwYaG5T4yKJWxc9FXFgBVrcTZ4XfSVRwa5HA/Xs+vB/Eo9treYYHCeNM0nrSUr82V/M31Urc7A==",
+ "dependencies": {
+ "remedial": "^1.0.7",
+ "remove-trailing-spaces": "^1.0.6"
+ },
+ "engines": {
+ "node": ">= 0.2.0"
+ }
+ },
+ "node_modules/jsonfile": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
+ "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==",
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/jsprim": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz",
+ "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==",
+ "dependencies": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.4.0",
+ "verror": "1.10.0"
+ },
+ "engines": {
+ "node": ">=0.6.0"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.0.0.tgz",
+ "integrity": "sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA==",
+ "dependencies": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "node_modules/kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==",
+ "dependencies": {
+ "is-buffer": "^1.1.5"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/klaw": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
+ "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==",
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "node_modules/linkify-it": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-4.0.1.tgz",
+ "integrity": "sha512-C7bfi1UZmoj8+PQx22XyeXCuBlokoyWQL5pWSP+EI6nzRylyThouddufc2c1NDIcP9k5agmN9fLpA7VNJfIiqw==",
+ "dependencies": {
+ "uc.micro": "^1.0.1"
+ }
+ },
+ "node_modules/live-plugin-manager": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/live-plugin-manager/-/live-plugin-manager-0.17.1.tgz",
+ "integrity": "sha512-gWAjojKD8AWkK8psxpm73q6JiSPeHJwwXjoSJL23CPwp/PejuetQjBWe0hGYBPb9kNYs6s6LA4SZVYuJwXDldg==",
+ "dependencies": {
+ "@types/debug": "^4.1.7",
+ "@types/fs-extra": "^9.0.12",
+ "@types/lockfile": "^1.0.2",
+ "@types/node-fetch": "^2.5.12",
+ "@types/semver": "^7.3.8",
+ "@types/tar": "^4.0.5",
+ "@types/url-join": "4.0.1",
+ "debug": "^4.3.2",
+ "fs-extra": "^10.0.0",
+ "lockfile": "^1.0.4",
+ "node-fetch": "^2.6.1",
+ "semver": "^7.3.5",
+ "tar": "^6.1.10",
+ "url-join": "^4.0.1"
+ }
+ },
+ "node_modules/live-plugin-manager/node_modules/@types/tar": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/@types/tar/-/tar-4.0.5.tgz",
+ "integrity": "sha512-cgwPhNEabHaZcYIy5xeMtux2EmYBitfqEceBUi2t5+ETy4dW6kswt6WX4+HqLeiiKOo42EXbGiDmVJ2x+vi37Q==",
+ "dependencies": {
+ "@types/minipass": "*",
+ "@types/node": "*"
+ }
+ },
+ "node_modules/live-plugin-manager/node_modules/fs-extra": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
+ "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/live-plugin-manager/node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/live-plugin-manager/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/live-plugin-manager/node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lockfile": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz",
+ "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==",
+ "dependencies": {
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "node_modules/lodash._basebind": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash._basebind/-/lodash._basebind-2.3.0.tgz",
+ "integrity": "sha512-SHqM7YCuJ+BeGTs7lqpWnmdHEeF4MWxS3dksJctHFNxR81FXPOzA4bS5Vs5CpcGTkBpM8FCl+YEbQEblRw8ABg==",
+ "dependencies": {
+ "lodash._basecreate": "~2.3.0",
+ "lodash._setbinddata": "~2.3.0",
+ "lodash.isobject": "~2.3.0"
+ }
+ },
+ "node_modules/lodash._basecreate": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-2.3.0.tgz",
+ "integrity": "sha512-vwZaWldZwS2y9b99D8i9+WtgiZXbHKsBsMrpxJEqTsNW20NhJo5W8PBQkeQO9CmxuqEYn8UkMnfEM2MMT4cVrw==",
+ "dependencies": {
+ "lodash._renative": "~2.3.0",
+ "lodash.isobject": "~2.3.0",
+ "lodash.noop": "~2.3.0"
+ }
+ },
+ "node_modules/lodash._basecreatecallback": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash._basecreatecallback/-/lodash._basecreatecallback-2.3.0.tgz",
+ "integrity": "sha512-Ev+pDzzfVfgbiucpXijconLGRBar7/+KNCf05kSnk4CmdDVhAy1RdbU9efCJ/o9GXI08JdUGwZ+5QJ3QX3kj0g==",
+ "dependencies": {
+ "lodash._setbinddata": "~2.3.0",
+ "lodash.bind": "~2.3.0",
+ "lodash.identity": "~2.3.0",
+ "lodash.support": "~2.3.0"
+ }
+ },
+ "node_modules/lodash._basecreatewrapper": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash._basecreatewrapper/-/lodash._basecreatewrapper-2.3.0.tgz",
+ "integrity": "sha512-YLycQ7k8AB9Wc1EOvLNxuRWcqipDkMXq2GCgnLWQR6qtgTb3gY3LELzEpnFshrEO4LOLs+R2EpcY+uCOZaLQ8Q==",
+ "dependencies": {
+ "lodash._basecreate": "~2.3.0",
+ "lodash._setbinddata": "~2.3.0",
+ "lodash._slice": "~2.3.0",
+ "lodash.isobject": "~2.3.0"
+ }
+ },
+ "node_modules/lodash._createwrapper": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash._createwrapper/-/lodash._createwrapper-2.3.0.tgz",
+ "integrity": "sha512-XjaI/rzg9W+WO4WJDQ+PRlHD5sAMJ1RhJLuT65cBxLCb1kIYs4U20jqvTDGAWyVT3c34GYiLd9AreHYuB/8yJA==",
+ "dependencies": {
+ "lodash._basebind": "~2.3.0",
+ "lodash._basecreatewrapper": "~2.3.0",
+ "lodash.isfunction": "~2.3.0"
+ }
+ },
+ "node_modules/lodash._objecttypes": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.3.0.tgz",
+ "integrity": "sha512-jbA6QyHt9cw3BzvbWzIcnU3Z12jSneT6xBgz3Y782CJsN1tV5aTBKrFo2B4AkeHBNaxSrbPYZZpi1Lwj3xjdtg=="
+ },
+ "node_modules/lodash._renative": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash._renative/-/lodash._renative-2.3.0.tgz",
+ "integrity": "sha512-v44MRirqYqZGK/h5UKoVqXWF2L+LUiLTU+Ogu5rHRVWJUA1uWIlHaMpG8f/OA8j++BzPMQij9+erXHtgFcbuwg=="
+ },
+ "node_modules/lodash._setbinddata": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash._setbinddata/-/lodash._setbinddata-2.3.0.tgz",
+ "integrity": "sha512-xMFfbF7dL+sFtrdE49uHFmfpBAEwlFtfgMp86nQRlAF6aizYL+3MTbnYMKJSkP1W501PhsgiBED5kBbZd8kR2g==",
+ "dependencies": {
+ "lodash._renative": "~2.3.0",
+ "lodash.noop": "~2.3.0"
+ }
+ },
+ "node_modules/lodash._shimkeys": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.3.0.tgz",
+ "integrity": "sha512-9Iuyi7TiWMGa/9+2rqEE+Zwye4b/U2w7Saw6UX1h6Xs88mEER+uz9FZcEBPKMVKsad9Pw5GNAcIBRnW2jNpneQ==",
+ "dependencies": {
+ "lodash._objecttypes": "~2.3.0"
+ }
+ },
+ "node_modules/lodash._slice": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash._slice/-/lodash._slice-2.3.0.tgz",
+ "integrity": "sha512-7C61GhzRUv36gTafr+RIb+AomCAYsSATEoK4OP0VkNBcwvsM022Z22AVgqjjzikeNO1U29LzsJZDvLbiNPUYvA=="
+ },
+ "node_modules/lodash.bind": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-2.3.0.tgz",
+ "integrity": "sha512-goakyOo+FMN8lttMPnZ0UNlr5RlzX4IrUXyTJPT2A0tGCMXySupond9wzvDqTvVmYTcQjIKGrj8naJDS2xWAlQ==",
+ "dependencies": {
+ "lodash._createwrapper": "~2.3.0",
+ "lodash._renative": "~2.3.0",
+ "lodash._slice": "~2.3.0"
+ }
+ },
+ "node_modules/lodash.foreach": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.foreach/-/lodash.foreach-2.3.0.tgz",
+ "integrity": "sha512-yLnyptVRJd0//AbGp480grgQG9iaDIV5uOgSbpurRy1dYybPbjNTLQ3FyLEQ84buVLPG7jyaiyvpzgfOutRB3Q==",
+ "dependencies": {
+ "lodash._basecreatecallback": "~2.3.0",
+ "lodash.forown": "~2.3.0"
+ }
+ },
+ "node_modules/lodash.forown": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.forown/-/lodash.forown-2.3.0.tgz",
+ "integrity": "sha512-dUnCsuQTtq3Y7bxPNoEEqjJjPL2ftLtcz2PTeRKvhbpdM514AvnqCjewHGsm/W+dwspIwa14KoWEZeizJ7smxA==",
+ "dependencies": {
+ "lodash._basecreatecallback": "~2.3.0",
+ "lodash._objecttypes": "~2.3.0",
+ "lodash.keys": "~2.3.0"
+ }
+ },
+ "node_modules/lodash.identity": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.identity/-/lodash.identity-2.3.0.tgz",
+ "integrity": "sha512-NYJ2r2cwy3tkx/saqbIZEX6oQUzjWTnGRu7d/zmBjMCZos3eHBxCpbvWFWSetv8jFVrptsp6EbWjzNgBKhUoOA=="
+ },
+ "node_modules/lodash.isfunction": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.isfunction/-/lodash.isfunction-2.3.0.tgz",
+ "integrity": "sha512-X5lteBYlCrVO7Qc00fxP8W90fzRp6Ax9XcHANmU3OsZHdSyIVZ9ZlX5QTTpRq8aGY+9I5Rmd0UTzTIIyWPugEQ=="
+ },
+ "node_modules/lodash.isobject": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.3.0.tgz",
+ "integrity": "sha512-jo1pfV61C4TE8BfEzqaHj6EIKiSkFANJrB6yscwuCJMSRw5tbqjk4Gv7nJzk4Z6nFKobZjGZ8Qd41vmnwgeQqQ==",
+ "dependencies": {
+ "lodash._objecttypes": "~2.3.0"
+ }
+ },
+ "node_modules/lodash.keys": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.3.0.tgz",
+ "integrity": "sha512-c0UW0ffqMxSCtoVbmVt2lERJLkEqgoOn2ejPsWXzr0ZrqRbl3uruGgwHzhtqXxi6K/ei3Ey7zimOqSwXgzazPg==",
+ "dependencies": {
+ "lodash._renative": "~2.3.0",
+ "lodash._shimkeys": "~2.3.0",
+ "lodash.isobject": "~2.3.0"
+ }
+ },
+ "node_modules/lodash.noop": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.noop/-/lodash.noop-2.3.0.tgz",
+ "integrity": "sha512-NpSm8HRm1WkBBWHUveDukLF4Kfb5P5E3fjHc9Qre9A11nNubozLWD2wH3UBTZbu+KSuX8aSUvy9b+PUyEceJ8g=="
+ },
+ "node_modules/lodash.support": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.support/-/lodash.support-2.3.0.tgz",
+ "integrity": "sha512-etc7VWbB0U3Iya8ixj2xy4sDBN3jvPX7ODi8iXtn4KkkjNpdngrdc7Vlt5jub/Vgqx6/dWtp7Ml9awhCQPYKGQ==",
+ "dependencies": {
+ "lodash._renative": "~2.3.0"
+ }
+ },
+ "node_modules/lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/lru-cache": {
+ "version": "7.18.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
+ "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
+ "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==",
+ "dependencies": {
+ "pify": "^4.0.1",
+ "semver": "^5.6.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/make-dir/node_modules/pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/markdown-it": {
+ "version": "13.0.1",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-13.0.1.tgz",
+ "integrity": "sha512-lTlxriVoy2criHP0JKRhO2VDG9c2ypWCsT237eDiLqi09rmbKoUetyGHq2uOIRoRS//kfoJckS0eUzzkDR+k2Q==",
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "~3.0.1",
+ "linkify-it": "^4.0.1",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.js"
+ }
+ },
+ "node_modules/markdown-it/node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
+ },
+ "node_modules/markdown-it/node_modules/entities": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
+ "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/md5": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz",
+ "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==",
+ "dependencies": {
+ "charenc": "0.0.2",
+ "crypt": "0.0.2",
+ "is-buffer": "~1.1.6"
+ }
+ },
+ "node_modules/mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g=="
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
+ "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
+ "bin": {
+ "mime": "cli.js"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
+ "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "3.3.6",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz",
+ "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minipass-collect": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
+ "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/minipass-flush": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
+ "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/minipass-pipeline": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
+ "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/minizlib": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz",
+ "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==",
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/mkdirp": {
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz",
+ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==",
+ "dependencies": {
+ "minimist": "^1.2.6"
+ },
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ }
+ },
+ "node_modules/moment": {
+ "version": "2.29.4",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/mount-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/mount-point/-/mount-point-3.0.0.tgz",
+ "integrity": "sha512-jAhfD7ZCG+dbESZjcY1SdFVFqSJkh/yGbdsifHcPkvuLRO5ugK0Ssmd9jdATu29BTd4JiN+vkpMzVvsUgP3SZA==",
+ "dependencies": {
+ "@sindresorhus/df": "^1.0.1",
+ "pify": "^2.3.0",
+ "pinkie-promise": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mount-point/node_modules/@sindresorhus/df": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/df/-/df-1.0.1.tgz",
+ "integrity": "sha512-1Hyp7NQnD/u4DSxR2DGW78TF9k7R0wZ8ev0BpMAIzA6yTQSHqNb5wTuvtcPYf4FWbVse2rW7RgDsyL8ua2vXHw==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "node_modules/native-promise-pool": {
+ "version": "3.19.0",
+ "resolved": "https://registry.npmjs.org/native-promise-pool/-/native-promise-pool-3.19.0.tgz",
+ "integrity": "sha512-Clf1xJ/qBGZrWeuu1qJ2Ta79L0CC0pANvh5cq2RIwCu4ehcc8W5COA4fwgnaU5a+Cg/QFOBGEuM/5naa9LF+og==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://bevry.me/fund"
+ }
+ },
+ "node_modules/nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ=="
+ },
+ "node_modules/node-domexception": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
+ "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "github",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "engines": {
+ "node": ">=10.5.0"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/node-xlsx": {
+ "version": "0.24.0",
+ "resolved": "https://registry.npmjs.org/node-xlsx/-/node-xlsx-0.24.0.tgz",
+ "integrity": "sha512-1olwK48XK9nXZsyH/FCltvGrQYvXXZuxVitxXXv2GIuRm51aBi1+5KwR4rWM4KeO61sFU+00913WLZTD+AcXEg==",
+ "dependencies": {
+ "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
+ },
+ "bin": {
+ "node-xlsx": "dist/bin/cli.js"
+ },
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
+ "node_modules/node-xlsx/node_modules/xlsx": {
+ "version": "0.20.2",
+ "resolved": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz",
+ "integrity": "sha512-+nKZ39+nvK7Qq6i0PvWWRA4j/EkfWOtkP/YhMtupm+lJIiHxUrgTr1CcKv1nBk1rHtkRRQ3O2+Ih/q/sA+FXZA==",
+ "bin": {
+ "xlsx": "bin/xlsx.njs"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/nopt": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz",
+ "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==",
+ "dependencies": {
+ "abbrev": "^1.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/normalize-path": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
+ "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/normalize-url": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-2.0.1.tgz",
+ "integrity": "sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw==",
+ "dependencies": {
+ "prepend-http": "^2.0.0",
+ "query-string": "^5.0.1",
+ "sort-keys": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+ "dependencies": {
+ "path-key": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-keys": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+ "integrity": "sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw=="
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/p-cancelable": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.4.1.tgz",
+ "integrity": "sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-event": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/p-event/-/p-event-2.3.1.tgz",
+ "integrity": "sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA==",
+ "dependencies": {
+ "p-timeout": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-is-promise": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz",
+ "integrity": "sha512-zL7VE4JVS2IFSkR2GQKDSPEVxkoH43/p7oEnwpdCndKYJO0HVeRB7fA8TJwuLOTBREtK0ea8eHaxdwcpob5dmg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate/node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-map": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
+ "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-timeout": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-2.0.1.tgz",
+ "integrity": "sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==",
+ "dependencies": {
+ "p-finally": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz",
+ "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw=="
+ },
+ "node_modules/parse-glob": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz",
+ "integrity": "sha512-FC5TeK0AwXzq3tUBFtH74naWkPQCEWs4K+xMxWZBlKDWu0bVHXGZa+KKqxKidd7xwhdZ19ZNuF2uO1M/r196HA==",
+ "dependencies": {
+ "glob-base": "^0.3.0",
+ "is-dotfile": "^1.0.0",
+ "is-extglob": "^1.0.0",
+ "is-glob": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/parse-glob/node_modules/is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/parse-glob/node_modules/is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==",
+ "dependencies": {
+ "is-extglob": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
+ "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+ "dependencies": {
+ "entities": "^4.4.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
+ "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
+ "dependencies": {
+ "domhandler": "^5.0.2",
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/path-scurry/node_modules/lru-cache": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz",
+ "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==",
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
+ "node_modules/path-scurry/node_modules/minipass": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz",
+ "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dependencies": {
+ "pify": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-type/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="
+ },
+ "node_modules/performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow=="
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==",
+ "dependencies": {
+ "pinkie": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/prepend-http": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+ "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pretty": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/pretty/-/pretty-2.0.0.tgz",
+ "integrity": "sha512-G9xUchgTEiNpormdYBl+Pha50gOUovT18IvAe7EYMZ1/f9W/WWMPRn+xI68yXNMUk3QXHDwo/1wV/4NejVNe1w==",
+ "dependencies": {
+ "condense-newlines": "^0.2.1",
+ "extend-shallow": "^2.0.1",
+ "js-beautify": "^1.6.12"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
+ },
+ "node_modules/progress-stream": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz",
+ "integrity": "sha512-MIBPjZz6oGNSw5rn2mSp+nP9FGoaVo6QsPyPVEaD4puilz5hZNa3kfnrlqRNYFsugslbU3An4mnkLLtZOaWvrA==",
+ "dependencies": {
+ "speedometer": "~0.1.2",
+ "through2": "~0.2.3"
+ }
+ },
+ "node_modules/promise-inflight": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz",
+ "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g=="
+ },
+ "node_modules/proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA=="
+ },
+ "node_modules/prr": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw=="
+ },
+ "node_modules/pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ=="
+ },
+ "node_modules/psl": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz",
+ "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag=="
+ },
+ "node_modules/pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dependencies": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/q": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+ "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==",
+ "engines": {
+ "node": ">=0.6.0",
+ "teleport": ">=0.2.0"
+ }
+ },
+ "node_modules/query-string": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz",
+ "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==",
+ "dependencies": {
+ "decode-uri-component": "^0.2.0",
+ "object-assign": "^4.1.0",
+ "strict-uri-encode": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/querystring": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz",
+ "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==",
+ "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
+ "engines": {
+ "node": ">=0.4.x"
+ }
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/rage-edit": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/rage-edit/-/rage-edit-1.2.0.tgz",
+ "integrity": "sha512-0RspBRc2s6We4g7hRCvT5mu7YPEnfjvQK8Tt354a2uUNJCMC7MKLvo/1mLvHUCQ/zbP6siQyp5VRZN7UCpMFZg=="
+ },
+ "node_modules/readable-stream": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
+ "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "dependencies": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/readdirp": {
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
+ "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
+ "dependencies": {
+ "picomatch": "^2.2.1"
+ },
+ "engines": {
+ "node": ">=8.10.0"
+ }
+ },
+ "node_modules/remedial": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/remedial/-/remedial-1.0.8.tgz",
+ "integrity": "sha512-/62tYiOe6DzS5BqVsNpH/nkGlX45C/Sp6V+NtiN6JQNS1Viay7cWkazmRkrQrdFj2eshDe96SIQNIoMxqhzBOg==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/remove-trailing-spaces": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/remove-trailing-spaces/-/remove-trailing-spaces-1.0.8.tgz",
+ "integrity": "sha512-O3vsMYfWighyFbTd8hk8VaSj9UAGENxAtX+//ugIst2RMk5e03h6RoIS+0ylsFxY1gvmPuAY/PO4It+gPEeySA=="
+ },
+ "node_modules/request": {
+ "version": "2.88.2",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
+ "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
+ "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142",
+ "dependencies": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.3",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.5.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/request/node_modules/form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 0.12"
+ }
+ },
+ "node_modules/request/node_modules/qs": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz",
+ "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/request/node_modules/tough-cookie": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
+ "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
+ "dependencies": {
+ "psl": "^1.1.28",
+ "punycode": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/request/node_modules/uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
+ "bin": {
+ "uuid": "bin/uuid"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/responselike": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+ "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==",
+ "dependencies": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/rimraf": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
+ "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
+ "dependencies": {
+ "glob": "^7.1.3"
+ },
+ "bin": {
+ "rimraf": "bin.js"
+ }
+ },
+ "node_modules/run-applescript": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-3.2.0.tgz",
+ "integrity": "sha512-Ep0RsvAjnRcBX1p5vogbaBdAGu/8j/ewpvGqnQYunnLd9SM0vWcPJewPKNnWFggf0hF0pwIgwV5XK7qQ7UZ8Qg==",
+ "dependencies": {
+ "execa": "^0.10.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "node_modules/sanitize-filename": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz",
+ "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==",
+ "dependencies": {
+ "truncate-utf8-bytes": "^1.0.0"
+ }
+ },
+ "node_modules/seek-bzip": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.6.tgz",
+ "integrity": "sha512-e1QtP3YL5tWww8uKaOCQ18UxIT2laNBXHjV/S2WYCiK4udiv8lkG89KRIoCjUagnAmCBurjF4zEVX2ByBbnCjQ==",
+ "dependencies": {
+ "commander": "^2.8.1"
+ },
+ "bin": {
+ "seek-bunzip": "bin/seek-bunzip",
+ "seek-table": "bin/seek-bzip-table"
+ }
+ },
+ "node_modules/semver": {
+ "version": "5.7.2",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
+ "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==",
+ "dependencies": {
+ "shebang-regex": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/shell-escape": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/shell-escape/-/shell-escape-0.2.0.tgz",
+ "integrity": "sha512-uRRBT2MfEOyxuECseCZd28jC1AJ8hmqqneWQ4VWUTgCAFvb3wKU1jLqj6egC4Exrr88ogg3dp+zroH4wJuaXzw=="
+ },
+ "node_modules/showdown": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/showdown/-/showdown-2.1.0.tgz",
+ "integrity": "sha512-/6NVYu4U819R2pUIk79n67SYgJHWCce0a5xTP979WbNp0FL9MN1I1QK662IDU1b6JzKTvmhgI7T7JYIxBi3kMQ==",
+ "dependencies": {
+ "commander": "^9.0.0"
+ },
+ "bin": {
+ "showdown": "bin/showdown.js"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://www.paypal.me/tiviesantos"
+ }
+ },
+ "node_modules/showdown/node_modules/commander": {
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
+ "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
+ "engines": {
+ "node": "^12.20.0 || >=14"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+ },
+ "node_modules/simple-git": {
+ "version": "3.19.1",
+ "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.19.1.tgz",
+ "integrity": "sha512-Ck+rcjVaE1HotraRAS8u/+xgTvToTuoMkT9/l9lvuP5jftwnYUp6DwuJzsKErHgfyRk8IB8pqGHWEbM3tLgV1w==",
+ "dependencies": {
+ "@kwsites/file-exists": "^1.1.1",
+ "@kwsites/promise-deferred": "^1.1.1",
+ "debug": "^4.3.4"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/steveukx/git-js?sponsor=1"
+ }
+ },
+ "node_modules/slash": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz",
+ "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/slide": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz",
+ "integrity": "sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/slugify": {
+ "version": "1.6.6",
+ "resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.6.tgz",
+ "integrity": "sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==",
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/sort-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
+ "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==",
+ "dependencies": {
+ "is-plain-obj": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/sort-keys-length": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz",
+ "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==",
+ "dependencies": {
+ "sort-keys": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sort-keys-length/node_modules/sort-keys": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz",
+ "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==",
+ "dependencies": {
+ "is-plain-obj": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/source-map-support": {
+ "version": "0.5.21",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
+ "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
+ "dependencies": {
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
+ }
+ },
+ "node_modules/speedometer": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-0.1.4.tgz",
+ "integrity": "sha512-phdEoDlA6EUIVtzwq1UiNMXDUogczp204aYF/yfOhjNePWFfIpBJ1k5wLMuXQhEOOMjuTJEcc4vdZa+vuP+n/Q=="
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="
+ },
+ "node_modules/sshpk": {
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz",
+ "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==",
+ "dependencies": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ },
+ "bin": {
+ "sshpk-conv": "bin/sshpk-conv",
+ "sshpk-sign": "bin/sshpk-sign",
+ "sshpk-verify": "bin/sshpk-verify"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/ssri": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz",
+ "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==",
+ "dependencies": {
+ "minipass": "^3.1.1"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/stream-parser": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz",
+ "integrity": "sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ==",
+ "dependencies": {
+ "debug": "2"
+ }
+ },
+ "node_modules/stream-parser/node_modules/debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dependencies": {
+ "ms": "2.0.0"
+ }
+ },
+ "node_modules/stream-parser/node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/strict-uri-encode": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+ "integrity": "sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
+ "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
+ "dependencies": {
+ "safe-buffer": "~5.2.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-dirs": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz",
+ "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==",
+ "dependencies": {
+ "is-natural-number": "^4.0.1"
+ }
+ },
+ "node_modules/strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-outer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz",
+ "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/tar": {
+ "version": "6.2.1",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz",
+ "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==",
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/tar-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
+ "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
+ "dependencies": {
+ "bl": "^1.0.0",
+ "buffer-alloc": "^1.2.0",
+ "end-of-stream": "^1.0.0",
+ "fs-constants": "^1.0.0",
+ "readable-stream": "^2.3.0",
+ "to-buffer": "^1.1.1",
+ "xtend": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/tar-stream/node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
+ },
+ "node_modules/tar-stream/node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/tar-stream/node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "node_modules/tar-stream/node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/tar-stream/node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz",
+ "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/tar/node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/throttle": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/throttle/-/throttle-1.0.3.tgz",
+ "integrity": "sha512-VYINSQFQeFdmhCds0tTqvQmLmdAjzGX1D6GnRQa4zlq8OpTtWSMddNyRq8Z4Snw/d6QZrWt9cM/cH8xTiGUkYA==",
+ "dependencies": {
+ "readable-stream": ">= 0.3.0",
+ "stream-parser": ">= 0.0.2"
+ },
+ "engines": {
+ "node": ">= v0.8.0"
+ }
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg=="
+ },
+ "node_modules/through2": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
+ "integrity": "sha512-mLa8Bn2mZurjyomGKWRu3Bo2mvoQojFks9NvOK8H+k4kDJNkdEqG522KFZsEFBEl6rKkxTgFbE5+OPcgfvPEHA==",
+ "dependencies": {
+ "readable-stream": "~1.1.9",
+ "xtend": "~2.1.1"
+ }
+ },
+ "node_modules/through2/node_modules/readable-stream": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
+ "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==",
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "node_modules/through2/node_modules/string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ=="
+ },
+ "node_modules/timed-out": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+ "integrity": "sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/to-buffer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
+ "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg=="
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
+ },
+ "node_modules/trash": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/trash/-/trash-4.3.0.tgz",
+ "integrity": "sha512-f36TKwIaBiXm63xSrn8OTNghg5CYHBsFVJvcObMo76LRpgariuRi2CqXQHw1VzfeximD0igdGaonOG6N760BtQ==",
+ "dependencies": {
+ "escape-string-applescript": "^2.0.0",
+ "fs-extra": "^0.30.0",
+ "globby": "^7.1.1",
+ "p-map": "^1.2.0",
+ "p-try": "^1.0.0",
+ "pify": "^3.0.0",
+ "run-applescript": "^3.0.0",
+ "uuid": "^3.1.0",
+ "xdg-trashdir": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/trash/node_modules/globby": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz",
+ "integrity": "sha512-yANWAN2DUcBtuus5Cpd+SKROzXHs2iVXFZt/Ykrfz6SAXqacLX25NZpltE+39ceMexYF4TtEadjuSTw8+3wX4g==",
+ "dependencies": {
+ "array-union": "^1.0.1",
+ "dir-glob": "^2.0.0",
+ "glob": "^7.1.2",
+ "ignore": "^3.3.5",
+ "pify": "^3.0.0",
+ "slash": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/trash/node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/trash/node_modules/uuid": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
+ "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
+ "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.",
+ "bin": {
+ "uuid": "bin/uuid"
+ }
+ },
+ "node_modules/trim-repeated": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz",
+ "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==",
+ "dependencies": {
+ "escape-string-regexp": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/truncate-utf8-bytes": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
+ "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==",
+ "dependencies": {
+ "utf8-byte-length": "^1.0.1"
+ }
+ },
+ "node_modules/tslog": {
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/tslog/-/tslog-3.3.4.tgz",
+ "integrity": "sha512-N0HHuHE0e/o75ALfkioFObknHR5dVchUad4F0XyFf3gXJYB++DewEzwGI/uIOM216E5a43ovnRNEeQIq9qgm4Q==",
+ "dependencies": {
+ "source-map-support": "^0.5.21"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
+ "dependencies": {
+ "safe-buffer": "^5.0.1"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/turndown": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/turndown/-/turndown-7.1.2.tgz",
+ "integrity": "sha512-ntI9R7fcUKjqBP6QU8rBK2Ehyt8LAzt3UBT9JR9tgo6GtuKvyUzpayWmeMKJw1DPdXzktvtIT8m2mVXz+bL/Qg==",
+ "dependencies": {
+ "domino": "^2.1.6"
+ }
+ },
+ "node_modules/tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA=="
+ },
+ "node_modules/typescript": {
+ "version": "4.9.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz",
+ "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=4.2.0"
+ }
+ },
+ "node_modules/uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
+ },
+ "node_modules/unbzip2-stream": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz",
+ "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==",
+ "dependencies": {
+ "buffer": "^5.2.1",
+ "through": "^2.3.8"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.19.8",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
+ "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
+ "license": "MIT"
+ },
+ "node_modules/unfetch": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/unfetch/-/unfetch-5.0.0.tgz",
+ "integrity": "sha512-3xM2c89siXg0nHvlmYsQ2zkLASvVMBisZm5lF3gFDqfF2xonNStDJyMpvaOBe0a1Edxmqrf2E0HBdmy9QyZaeg=="
+ },
+ "node_modules/unique-filename": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz",
+ "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==",
+ "dependencies": {
+ "unique-slug": "^3.0.0"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/unique-slug": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz",
+ "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==",
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
+ },
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/url-join": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
+ "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA=="
+ },
+ "node_modules/url-parse-lax": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+ "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==",
+ "dependencies": {
+ "prepend-http": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/url-to-options": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+ "integrity": "sha512-0kQLIzG4fdk/G5NONku64rSH/x32NOA39LVQqlK8Le6lvTF6GGRJpqaQFGgU+CLwySIqBSMdwYM0sYcW9f6P4A==",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/user-home": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
+ "integrity": "sha512-KMWqdlOcjCYdtIJpicDSFBQ8nFwS2i9sslAd6f4+CBGcU4gist2REnr2fxj2YocvJFxSF3ZOHLYLVZnUxv4BZQ==",
+ "dependencies": {
+ "os-homedir": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/utf8-byte-length": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
+ "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA=="
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
+ },
+ "node_modules/verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==",
+ "engines": [
+ "node >=0.6.0"
+ ],
+ "dependencies": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "node_modules/verror/node_modules/core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ=="
+ },
+ "node_modules/web-streams-polyfill": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
+ "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "which": "bin/which"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "node_modules/write-file-atomic": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz",
+ "integrity": "sha512-SdrHoC/yVBPpV0Xq/mUZQIpW2sWXAShb/V4pomcJXh92RuaO+f3UTWItiR3Px+pLnV2PvC2/bfn5cwr5X6Vfxw==",
+ "dependencies": {
+ "graceful-fs": "^4.1.11",
+ "imurmurhash": "^0.1.4",
+ "slide": "^1.1.5"
+ }
+ },
+ "node_modules/xdg-basedir": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz",
+ "integrity": "sha512-NF1pPn594TaRSUO/HARoB4jK8I+rWgcpVlpQCK6/6o5PHyLUt2CSiDrpUZbQ6rROck+W2EwF8mBJcTs+W98J9w==",
+ "dependencies": {
+ "os-homedir": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/xdg-trashdir": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/xdg-trashdir/-/xdg-trashdir-2.1.1.tgz",
+ "integrity": "sha512-KcVhPaOu2ZurYNHSRTf1+ZHORkTZGCQ+u0JHN17QixRISJq4pXOnjt/lQcehvtHL5QAKhSzKgyjrcNnPdkPBHA==",
+ "dependencies": {
+ "@sindresorhus/df": "^2.1.0",
+ "mount-point": "^3.0.0",
+ "pify": "^2.2.0",
+ "user-home": "^2.0.0",
+ "xdg-basedir": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/xtend": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+ "integrity": "sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ==",
+ "dependencies": {
+ "object-keys": "~0.4.0"
+ },
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yauzl": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
+ "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
+ "dependencies": {
+ "buffer-crc32": "~0.2.3",
+ "fd-slicer": "~1.1.0"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/packages/discourse/scripts/link-dev.sh b/packages/discourse/scripts/link-dev.sh
new file mode 100644
index 00000000..8ba121ce
--- /dev/null
+++ b/packages/discourse/scripts/link-dev.sh
@@ -0,0 +1 @@
+npm i ../osr-cli-commons/
diff --git a/packages/discourse/scripts/sync-components.sh b/packages/discourse/scripts/sync-components.sh
new file mode 100644
index 00000000..f958e057
--- /dev/null
+++ b/packages/discourse/scripts/sync-components.sh
@@ -0,0 +1 @@
+node ./main.js sync-component --skip=false --src="${OSR_LIBRARY_MACHINES}/extrusion/**/config.+(json)"
diff --git a/packages/discourse/scripts/test.sh b/packages/discourse/scripts/test.sh
new file mode 100644
index 00000000..1a4fe1bb
--- /dev/null
+++ b/packages/discourse/scripts/test.sh
@@ -0,0 +1,14 @@
+curl 'https://forum.osr-plastic.org/t/10028/change-timestamp' \
+ -X 'PUT' \
+ -H 'accept: */*' \
+ -H 'accept-language: en-GB,en-US;q=0.9,en;q=0.8,de;q=0.7,es;q=0.6,fr;q=0.5' \
+ -H 'content-type: application/x-www-form-urlencoded; charset=UTF-8' \
+ -H 'cookie: _bypass_cache=true; _ga_MBZGKNMDWC=GS1.1.1685892974.20.1.1685893082.0.0.0; _ga_P4SR15V1XR=GS1.1.1687459978.51.1.1687460537.0.0.0; _ga_H8W78Y3P2B=GS1.1.1687604701.23.0.1687604701.0.0.0; _ga=GA1.1.401826746.1678337758; _t=xQ05qW5JFxLM9Pq0lIwG6ez74Z1q2OLpak0DzRx8VdFYE5eI3oJXhLURPrdm2zIcHmYcBj9q%2BKdHhGz5N6j9mXitYzcMwkXHL3K9GYKdO4gJ8tBQimpmd1HFaRhB9Ml9aJ8WviqQWDZDOYwEUKFcWw3wbAalfQtbdIbUSX8gH9sG6DLFU3HiEg7tWModRy%2BoFrTm6QOalDuajRW3nBazau%2FiY8ZCVm2g30Y10CBDfqJHL1ztV8XM4kEIeulLNTzGVtSb7uuO1OcjZRSb--aDgCPEalq7SIpnH5--HWCNf5readaeij3oDl9b9w%3D%3D; __profilin=p%3Dt%2Ca%3Deef38e031f99cc8240f3518e1b8811cf; _forum_session=RkEWuzKI1QXBYCnP6KRamD8mweZ3h9%2B6G%2Fi23gAWUgy8gp8FuiyQD5lKU0Fbx3FzzaM4SiQcvnIiEAnb5P4OYjlvstqwWlfRp%2B9is7iX8StwYGiYsncHQ5LrzSbV3y9mR7sj%2F8JZ8evQOe2ZZjZB3iEkppsGrmyFrw5PsUgSphRTZm70SKIw96JrW17yK4hhLqtk%2BaQPgNu4oJl42YfXAr%2FCBldcBUKXFeHppYmv61WECV0531hCo7GcA4t06B9QpSr%2BeoiM1Ok9tpQrAlZf36Ka4lVCTyXXu3SNvbtvfd9tZMJCWDYv69jdMsezuOaEP870pk9qYPaL4x6nAY5EXO3u9usCggqQ1B1EydCK9uMy7ZUCIo9wONw7QOIgEQ%3D%3D--GMqYSb2H7xXVDky6--R9gVciBqwC0IL9LefywrFw%3D%3D; _ga_GVR8PEPG6C=GS1.1.1687710574.106.1.1687710599.0.0.0' \
+ -H 'origin: https://forum.osr-plastic.org' \
+ -H 'Api-Key: 61b2d970483b8dc2d24d5358ce3ec28e6916f5daf4df20074caf18fe8c74096f' \
+ -H 'Api-Username: jerome' \
+ -H 'user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' \
+ -H 'x-2csrf-token: j7oYrkQe5nbnikCNHcfoP2DGtXKV4iHHzDFip8gGatS145g3B65UU6mI09KeFday9mY5HNQnU2jXUTe7LLkP-w' \
+ -H 'x-requested-with: XMLHttpRequest' \
+ --data-raw 'timestamp=1667430000'
+
diff --git a/packages/discourse/src/_cli.ts b/packages/discourse/src/_cli.ts
new file mode 100644
index 00000000..ec697913
--- /dev/null
+++ b/packages/discourse/src/_cli.ts
@@ -0,0 +1,81 @@
+import { sync as exists } from '@plastichub/fs/exists'
+import { IOptions, IOptionsSync } from './types'
+import { logger } from './'
+import * as path from 'path'
+
+import { forward_slash, pathInfo } from "@plastichub/osr-cli-commons"
+import { isFile, resolve } from "@plastichub/osr-commons"
+
+import { substitute } from './index'
+
+const globBase = require('glob-base')
+
+export const defaults = () => {
+ // default command
+ const DefaultCommand = 'info';
+ if (process.argv.length === 2) {
+ process.argv.push(DefaultCommand);
+ }
+
+ process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
+
+ // currently no default handler, display only :
+ process.on('unhandledRejection', (reason: string) => {
+ console.error('Unhandled rejection, reason: ', reason);
+ });
+}
+
+export const sanitize = (argv: any): IOptionsSync | IOptions | boolean => {
+
+ let ret: any = {
+ ...argv
+ }
+
+ ret.src = argv.src
+ let srcInfo
+ let variables = {}
+
+ /*
+ if (ret.src) {
+ ret.src = forward_slash(substitute(ret.alt,ret.src,variables))
+ // in case a file with a glob pattern is provided, strip the glob
+ // this is a special case, enabling shared scripts in Alt-Tap Salamand
+ const glob_base = globBase(ret.src)
+ const file = ret.src.replace(glob_base.glob, '').replace(/\/$/, '')
+
+ if(exists(file) && isFile(file)){
+ ret.src = file
+ }
+
+ srcInfo = pathInfo(resolve(ret.src, ret.alt, variables))
+
+ if (srcInfo && srcInfo.FILES && srcInfo.FILES.length) {
+ ret.srcInfo = srcInfo
+ for (const key in srcInfo) {
+ if (Object.prototype.hasOwnProperty.call(srcInfo, key)) {
+ variables['SRC_' + key] = srcInfo[key];
+ }
+ }
+ } else {
+ ret.src = resolve(ret.src, ret.alt, variables)
+ }
+ }
+ */
+
+ if (argv.cwd) {
+ ret.cwd = path.resolve(argv.cwd);
+ if (!exists((ret.cwd))) {
+ logger.error(`Invalid working directory ${argv.cwd}`)
+ }
+ } else {
+ ret.cwd = process.cwd()
+ }
+
+ ret = {
+ ...ret,
+ variables,
+ srcInfo
+ }
+
+ return ret
+}
\ No newline at end of file
diff --git a/packages/discourse/src/commands/import-oa-howtos.ts b/packages/discourse/src/commands/import-oa-howtos.ts
new file mode 100644
index 00000000..2c6bc677
--- /dev/null
+++ b/packages/discourse/src/commands/import-oa-howtos.ts
@@ -0,0 +1,95 @@
+import * as CLI from 'yargs'
+
+import { defaults, sanitize } from '../_cli'
+import { IOptions } from '../types'
+import { logger, IImportUser } from '../index'
+
+import { Instance } from '../lib/discourse'
+
+import { sync as write } from '@plastichub/fs/write'
+
+import {
+ read_users, filter_invalid,
+ filter_email_missing,
+ updateUsers,
+ filter_email_only,
+ importUsers,
+ filter_accepted,
+ oa_user_email,
+ getDataPath
+} from '../lib/oa/users'
+
+import {
+ read_categories,
+ read_howtos,
+ read_tags,
+ filter_valid
+} from '../lib/oa/commons'
+
+import {
+ importHowtos, updateHowtos
+} from '../lib/oa/howtos'
+
+import {
+ IOAHowtoImport
+} from '../'
+
+import { IUserPP } from '@plastichub/osr-commons'
+
+import * as path from 'path'
+import { resolve } from '@plastichub/osr-commons'
+import { CONFIG_DEFAULT, DEFAULT_ROOTS } from '@plastichub/osr-cli-commons'
+
+const KB_ROOT = '${KB_ROOT}'
+
+import {
+ IOACategory,
+ IOATag,
+ IOAStep
+} from '../lib/oa/types'
+
+import { OA_LATEST } from '@plastichub/osr-commons'
+
+const defaultOptions = (yargs: CLI.Argv) => {
+ return yargs.option('debug', {
+ default: true,
+ describe: 'debug messages',
+ type: 'boolean'
+ }).option('src', {
+ default: OA_LATEST,
+ type: 'string',
+ }).option('track', {
+ default: '${OA_ROOT}/oa-data/howtos/latest_track.json',
+ type: 'string',
+ }).option('env_key', {
+ default: 'OSR-CONFIG',
+ describe: 'Environment key to the config path.'
+ })
+}
+
+let options = (yargs: CLI.Argv) => defaultOptions(yargs)
+
+export const register = (cli: CLI.Argv) => {
+ return cli.command('import-howtos', 'Import oa-howtos', options, async (argv: CLI.Arguments) => {
+ defaults()
+ if (argv.help) { return }
+ let options = (argv as any) as IOptions
+
+ if (!options) {
+ return
+ }
+ options.debug && logger.debug(`CLI Args In`, argv)
+
+ const discourse = Instance()
+
+ const _opts = {
+ src: path.resolve(resolve(options.src)),
+ track: path.resolve(resolve(options.track))
+ } as IOptions
+
+ let howtos = read_howtos(_opts.src)
+ howtos = filter_valid(howtos)
+ await importHowtos(discourse,_opts,howtos)
+ await updateHowtos(discourse,_opts,howtos)
+ })
+}
diff --git a/packages/discourse/src/commands/import-oa-users.ts b/packages/discourse/src/commands/import-oa-users.ts
new file mode 100644
index 00000000..0cefac53
--- /dev/null
+++ b/packages/discourse/src/commands/import-oa-users.ts
@@ -0,0 +1,118 @@
+import * as CLI from 'yargs'
+
+import { defaults, sanitize } from '../_cli'
+import { parse } from '../options'
+import { IOptions } from '../types'
+import { logger, IImportUser } from '../index'
+
+import { Instance } from '../lib/discourse'
+
+import { sync as write } from '@plastichub/fs/write'
+
+import { OA_LATEST, OA_LATEST_MERGED } from '@plastichub/osr-commons'
+
+import {
+ read_users, filter_invalid,
+ filter_email_missing,
+ filter_email_only,
+ importUsers,
+ filter_valid,
+ oa_user_email,
+ getDataPath,
+ updateUsers,
+ indexUsers
+} from '../lib/oa/users'
+
+import * as path from 'path'
+import { resolve } from '@plastichub/osr-commons'
+
+const defaultOptions = (yargs: CLI.Argv) => {
+ return yargs.option('debug', {
+ default: false,
+ describe: 'debug messages',
+ type: 'boolean'
+ }).option('src', {
+ default: '${OA_ROOT}/data/latest.json',
+ type: 'string',
+ }).option('track', {
+ default: '${OSR_ROOT}/osr-directory/pp/merged.json',
+ type: 'string',
+ }).option('env_key', {
+ default: 'OSR-CONFIG',
+ describe: 'Environment key to the config path.'
+ })
+}
+
+let options = (yargs: CLI.Argv) => defaultOptions(yargs)
+
+export const register = (cli: CLI.Argv) => {
+ return cli.command('import-users ', 'Import oa-users', options, async (argv: CLI.Arguments) => {
+
+ defaults()
+
+ if (argv.help) { return }
+ const args: any = argv
+ let options = sanitize(argv as any) as IOptions;
+
+ if (!options) {
+ return
+ }
+ options.debug && logger.debug(`CLI Args In`, argv)
+ let opts = parse(options, args)
+
+ const discourse = Instance()
+
+ const _opts = {
+ verb: argv.verb,
+ src: path.resolve(resolve(options.src)),
+ track: path.resolve(resolve(options.track))
+ }
+
+
+ let users = read_users(_opts.src)
+ users = filter_valid(users as IImportUser[])
+
+ //////////////////////////
+ //
+ // store invalid
+
+ let usersInvalid = read_users(_opts.src)
+ usersInvalid = filter_email_only(usersInvalid)
+ usersInvalid = filter_invalid(usersInvalid)
+
+ logger.debug('write invalidUsers.json : ', getDataPath('/invalidUsers.json'))
+ write(getDataPath('/invalidUsers.json'), usersInvalid.map((u) => {
+ return {
+ ...u.detail,
+ id: u._id,
+ email: oa_user_email(u)
+ }
+ }))
+
+ let usersInvalidEmail = read_users(_opts.src)
+ usersInvalidEmail = filter_email_missing(usersInvalidEmail)
+ logger.debug('write invalidUsersEMail.json : ', getDataPath('/invalidUsersEMail.json'))
+ write(getDataPath('./invalidUsersEMail.json'), usersInvalidEmail.map((u) => {
+ return {
+ ...u.detail,
+ id: u._id
+ }
+ }))
+
+ logger.debug('invalid users email : ', usersInvalidEmail.length)
+ logger.debug('invalid users : ', usersInvalid.length)
+
+ if (opts.verb == 'index') {
+ await indexUsers(discourse, options, users)
+ }
+
+ if (opts.verb == 'import') {
+ await importUsers(discourse, options, users)
+ }
+
+ if (opts.verb == 'update') {
+ await updateUsers(discourse, options, users)
+ }
+ return
+ })
+}
diff --git a/packages/discourse/src/commands/info.ts b/packages/discourse/src/commands/info.ts
new file mode 100644
index 00000000..473c70e8
--- /dev/null
+++ b/packages/discourse/src/commands/info.ts
@@ -0,0 +1,24 @@
+import * as CLI from 'yargs'
+import { CONFIG_DEFAULT } from '@plastichub/osr-cli-commons'
+import { logger } from '../index'
+
+const defaultOptions = (yargs: CLI.Argv) => {
+ return yargs.option('debug', {
+ default: 'false',
+ describe: 'debug messages'
+ }).option('env_key', {
+ default: 'OSR-CONFIG',
+ describe: 'Environment key to the config path'
+ })
+}
+
+let options = (yargs: CLI.Argv) => defaultOptions(yargs);
+
+export const register = (cli: CLI.Argv) => {
+ return cli.command('info', 'info', options, async (argv: CLI.Arguments) => {
+ if (argv.help) { return }
+ const args: any = argv
+ const src = CONFIG_DEFAULT(args.env_key)
+ logger.debug(`Reading OSR Config with key "${argv.env_key}"`, src)
+ })
+}
diff --git a/packages/discourse/src/commands/query.ts b/packages/discourse/src/commands/query.ts
new file mode 100644
index 00000000..5af23c01
--- /dev/null
+++ b/packages/discourse/src/commands/query.ts
@@ -0,0 +1,59 @@
+import * as CLI from 'yargs'
+
+import { defaults, sanitize } from '../_cli'
+import { parse } from '../options'
+import { IOptions } from '../types'
+import { logger } from '../index'
+
+import { Instance } from '../lib/discourse'
+
+const defaultOptions = (yargs: CLI.Argv) => {
+ return yargs.option('debug', {
+ default: false,
+ describe: 'debug messages',
+ type: 'boolean'
+ }).option('short', {
+ default: 'true',
+ describe: 'Emit short info only',
+ type: 'boolean'
+ }).option('disabled', {
+ default: 'false',
+ describe: 'Enumerate disabled products',
+ type: 'boolean'
+ }).option('dry', {
+ default: 'false',
+ describe: 'Process files for debug purposes only.'
+ }).option('env_key', {
+ default: 'OSR-CONFIG',
+ describe: 'Environment key to the config path.'
+ })
+}
+
+let options = (yargs: CLI.Argv) => defaultOptions(yargs)
+
+export const register = (cli: CLI.Argv) => {
+ return cli.command('query ', 'Search namespace', options, async (argv: CLI.Arguments) => {
+ defaults();
+ if (argv.help) { return }
+ const args: any = argv
+
+ let options = sanitize(argv as any) as IOptions
+
+ if (!options) {
+ return
+ }
+ options.debug && logger.debug(`CLI Args In`, argv)
+ let opts = parse(options, args)
+
+ if (!opts.verb) {
+ logger.error('No verb specified')
+ return;
+ }
+ const discourse = Instance()
+ if (opts.verb == 'tags') {
+ const items = await discourse.search('Sheetpress - Cell','tags:sheetpress');
+ logger.info('items',items)
+ }
+ return
+ })
+}
diff --git a/packages/discourse/src/commands/sync-component.ts b/packages/discourse/src/commands/sync-component.ts
new file mode 100644
index 00000000..32a354a9
--- /dev/null
+++ b/packages/discourse/src/commands/sync-component.ts
@@ -0,0 +1,137 @@
+import * as path from 'path'
+import * as CLI from 'yargs'
+
+import { forward_slash, pathInfo } from "@plastichub/osr-cli-commons"
+import { resolve, isFile } from '@plastichub/osr-commons'
+
+import { sync as exists } from '@plastichub/fs/exists'
+
+import { CAT_TEST, DEFAULT_IMPORT_OWNER } from '../lib/discourse/constants'
+
+import { defaults } from '../_cli'
+import { IOptionsSyncComponent } from '../types'
+import { logger } from '../index'
+import { syncComponent } from '../lib/sync/component'
+import { PFilterValid } from '@plastichub/osr-fs-utils'
+const globBase = require('glob-base')
+
+export const parse = (argv: any): IOptionsSyncComponent | boolean => {
+
+ let ret: any = {
+ ...argv
+ }
+
+ let srcInfo
+ let variables = {}
+
+ ret.src = argv.src
+
+ ret.source = resolve(forward_slash(ret.source), ret.alt, variables)
+ ret.root = resolve(forward_slash(ret.root), ret.alt, variables)
+ ret.product_root = resolve(forward_slash(ret.product_root), ret.alt, variables)
+
+ if (ret.src) {
+
+ ret.src = resolve(ret.src, ret.alt, variables)
+ // in case a file with a glob pattern is provided, strip the glob
+ // this is a special case, enabling shared scripts in Alt-Tap Salamand
+ const glob_base = globBase(ret.src)
+ const file = ret.src.replace(glob_base.glob, '').replace(/\/$/, '')
+
+ // case : single file
+ if (exists(file) && isFile(file)) {
+ ret.src = file
+ }
+ const src = resolve(forward_slash(ret.src), ret.alt, variables)
+ srcInfo = pathInfo(src)
+
+ // case : glob pattern
+ if (srcInfo && srcInfo.FILES && srcInfo.FILES.length) {
+ ret.srcInfo = srcInfo
+ for (const key in srcInfo) {
+ if (Object.prototype.hasOwnProperty.call(srcInfo, key)) {
+ variables['SRC_' + key] = srcInfo[key];
+ }
+ }
+ } else {
+ ret.src = resolve(ret.src, ret.alt, variables)
+ }
+ }
+
+ if (argv.cwd) {
+ ret.cwd = path.resolve(argv.cwd);
+ if (!exists((ret.cwd))) {
+ logger.error(`Invalid working directory ${argv.cwd}`)
+ }
+ } else {
+ ret.cwd = process.cwd()
+ }
+
+ ret = {
+ ...ret,
+ variables,
+ srcInfo
+ }
+
+ return ret
+}
+
+const defaultOptions = (yargs: CLI.Argv) => {
+ return yargs
+
+ //standard options
+ .option('alt', { type: 'boolean', default: false, describe: 'alt token (%)' })
+ //discourse
+ .option('yaml', { type: 'boolean', default: false, describe: 'Parse options from YAML header' })
+ .option('skip', { type: 'boolean', default: true, describe: 'Skip existing' })
+ .option('uploadLocal', { type: 'boolean', default: true, describe: 'Upload local images to Discourse' })
+ .option('uploadRemote', { type: 'boolean', default: true, describe: 'Upload remote images to Discourse' })
+ .option('title', { type: 'string', default: 'Title of the Discourse post' })
+ .option('cat', { default: CAT_TEST, type: 'number' })
+ .option('timestamp', { type: 'number', default: Date.now() })
+ .option('owner', { type: 'number', default: DEFAULT_IMPORT_OWNER })
+ .option('config', { type: 'string', default: 'discourse_admin' })
+
+ //osrl
+ .option('src', {
+ default: '${OSR_ROOT}/osr-machines/injection/**/config.json',
+ type: 'string',
+ describe: 'Source : Path|Glob. Supported: HTML|MD|OSR(Options via YAML header)'
+ })
+ .option('src2', {
+ default: '${OSR_ROOT}/osr-machines/sheetpress/cassandra-light/config.json',
+ type: 'string',
+ describe: 'Source : Path|Glob. Supported: HTML|MD|OSR(Options via YAML header)'
+ })
+ .option('env', { type: 'string', default: 'forum' })
+ .option('profile', { type: 'string', default: "${OSR_ROOT}/osr-templates/discourse/base.json" })
+ .option('format', { type: 'string', default: 'md' })
+ .option('source', { type: 'string', default: "${OSR_ROOT}/osr-templates/discourse/root.html" })
+ .option('language', { type: 'string', default: 'osr' })
+ .option('plugins', { type: 'string', default: '${root}/osr/plugins' })
+ .option('root', { type: 'string', default: process.cwd() })
+ .option('product_root', { type: 'string', default: '${PRODUCT_ROOT}/products' })
+ .option('cwd', { type: 'string', default: process.cwd() })
+ .option('module', { type: 'string', default: 'osr-lib-components' })
+ .option('filter', { type: 'string', default: PFilterValid.library_component })
+ .option('cache', { type: 'boolean', default: true })
+ .option('env_key', { type: 'string', default: 'OSR-CONFIG', describe: 'Environment key to the config path.' })
+}
+
+let options = (yargs: CLI.Argv) => defaultOptions(yargs)
+
+export const register = (cli: CLI.Argv) => {
+ return cli.command('sync-component', 'Sync OSR Component', options, async (argv: CLI.Arguments) => {
+ defaults()
+ if (argv.help) { return }
+ let options = parse(argv as any) as IOptionsSyncComponent
+ if (!options) {
+ return
+ }
+ logger.setSettings({ minLevel: argv.logLevel as any })
+ // options.debug && logger.debug(`CLI Args In`, argv)
+ logger.debug('Options', options)
+ let ret = syncComponent(options)
+ return ret
+ })
+}
diff --git a/packages/discourse/src/commands/sync-directory.ts b/packages/discourse/src/commands/sync-directory.ts
new file mode 100644
index 00000000..d61a2bd4
--- /dev/null
+++ b/packages/discourse/src/commands/sync-directory.ts
@@ -0,0 +1,142 @@
+import * as path from 'path'
+import * as CLI from 'yargs'
+
+import { forward_slash, pathInfo } from "@plastichub/osr-cli-commons"
+import { resolve, isFile } from '@plastichub/osr-commons'
+
+import { sync as exists } from '@plastichub/fs/exists'
+
+import { CAT_TEST, DEFAULT_IMPORT_OWNER } from '../lib/discourse/constants'
+
+import { defaults } from '../_cli'
+import { IOptions, IOptionsSyncComponent } from '../types'
+import { logger } from '../index'
+import { syncComponent } from '../lib/sync/component'
+
+import { isValidLibraryComponent, PFilterValid } from '@plastichub/osr-fs-utils'
+
+import { first } from 'ramda'
+
+const globBase = require('glob-base')
+
+export const parse = (argv: any): IOptionsSyncComponent | boolean => {
+
+ let ret: any = {
+ ...argv
+ }
+
+ ret.src = argv.src
+ let srcInfo
+ let variables = {}
+
+ ret.source = resolve(forward_slash(ret.source), ret.alt, variables)
+ ret.root = resolve(forward_slash(ret.root), ret.alt, variables)
+
+ if (ret.src) {
+
+ ret.src = resolve(ret.src, ret.alt, variables)
+ // in case a file with a glob pattern is provided, strip the glob
+ // this is a special case, enabling shared scripts in Alt-Tap Salamand
+ const glob_base = globBase(ret.src)
+ const file = ret.src.replace(glob_base.glob, '').replace(/\/$/, '')
+
+ // case : single file
+ if (exists(file) && isFile(file)) {
+ ret.src = file
+ }
+ const src = resolve(forward_slash(ret.src), ret.alt, variables)
+ srcInfo = pathInfo(src)
+
+ // case : glob pattern
+ if (srcInfo && srcInfo.FILES && srcInfo.FILES.length) {
+ ret.srcInfo = srcInfo
+ for (const key in srcInfo) {
+ if (Object.prototype.hasOwnProperty.call(srcInfo, key)) {
+ variables['SRC_' + key] = srcInfo[key];
+ }
+ }
+ } else {
+ ret.src = resolve(ret.src, ret.alt, variables)
+ }
+ }
+
+ if (argv.cwd) {
+ ret.cwd = path.resolve(argv.cwd);
+ if (!exists((ret.cwd))) {
+ logger.error(`Invalid working directory ${argv.cwd}`)
+ }
+ } else {
+ ret.cwd = process.cwd()
+ }
+
+ ret = {
+ ...ret,
+ variables,
+ srcInfo
+ }
+
+ return ret
+}
+
+const defaultOptions = (yargs: CLI.Argv) => {
+ return yargs
+
+ //standard options
+ .option('debug', { type: 'boolean', default: true, describe: 'debug messages' })
+ .option('verbose', { type: 'boolean', default: true, describe: 'even more debug messages' })
+ .option('alt', { type: 'boolean', default: false, describe: 'alt token (%)' })
+
+ //discourse
+ .option('yaml', { type: 'boolean', default: false, describe: 'Parse options from YAML header' })
+ .option('uploadLocal', { type: 'boolean', default: true, describe: 'Upload local images to Discourse' })
+ .option('uploadRemote', { type: 'boolean', default: true, describe: 'Upload remote images to Discourse' })
+
+ .option('title', { type: 'string', default: 'Title of the Discourse post' })
+
+ .option('cat', { default: CAT_TEST, type: 'number' })
+ .option('timestamp', { type: 'number', default: Date.now() })
+ .option('owner', { type: 'number', default: DEFAULT_IMPORT_OWNER })
+ .option('config', { type: 'string', default: 'discourse_admin' })
+
+ //osrl
+ .option('src2', {
+ default: '${OSR_ROOT}/osr-machines/injection/**/config.json',
+ type: 'string',
+ describe: 'Source : Path|Glob. Supported: HTML|MD|OSR(Options via YAML header)'
+ })
+ .option('src', {
+ default: '${OSR_ROOT}/osr-machines/sheetpress/cassandra-light/config.json',
+ type: 'string',
+ describe: 'Source : Path|Glob. Supported: HTML|MD|OSR(Options via YAML header)'
+ })
+ .option('env', { type: 'string', default: 'forum' })
+ .option('profile', { type: 'string', default: "${OSR_ROOT}/osr-templates/discourse/base.json" })
+ .option('format', { type: 'string', default: 'md' })
+ .option('source', { type: 'string', default: "${OSR_ROOT}/osr-templates/discourse/root.html" })
+ .option('language', { type: 'string', default: 'osr' })
+ .option('plugins', { type: 'string', default: '${root}/osr/plugins' })
+ .option('root', { type: 'string', default: process.cwd() })
+ .option('product_root', { type: 'string', default: '${PRODUCT_ROOT}/products' })
+ .option('cwd', { type: 'string', default: process.cwd() })
+ .option('module', { type: 'string', default: 'osr-lib-components' })
+ .option('filter', { type: 'string', default: PFilterValid.library_component })
+ .option('cache', { type: 'boolean', default: true })
+ .option('env_key', { type: 'string', default: 'OSR-CONFIG', describe: 'Environment key to the config path.' })
+}
+
+let options = (yargs: CLI.Argv) => defaultOptions(yargs)
+
+export const register = (cli: CLI.Argv) => {
+ return cli.command('sync-component', 'Sync OSR Component', options, async (argv: CLI.Arguments) => {
+ defaults()
+ if (argv.help) { return }
+ let options = parse(argv as any) as IOptionsSyncComponent
+ if (!options) {
+ return
+ }
+ // options.debug && logger.debug(`CLI Args In`, argv)
+ // logger.debug('Options', options)
+ let ret = syncComponent(options)
+ return ret
+ })
+}
diff --git a/packages/discourse/src/commands/sync-file.ts b/packages/discourse/src/commands/sync-file.ts
new file mode 100644
index 00000000..68c1fff6
--- /dev/null
+++ b/packages/discourse/src/commands/sync-file.ts
@@ -0,0 +1,64 @@
+import * as CLI from 'yargs'
+
+import { defaults, sanitize } from '../_cli'
+import { IOptions, IOptionsSync } from '../types'
+import { logger } from '../index'
+
+import { Instance } from '../lib/discourse'
+
+import { sync as write } from '@plastichub/fs/write'
+
+import * as path from 'path'
+import { resolve } from '@plastichub/osr-commons'
+
+import { syncYAML } from '../lib/sync/file'
+import { CAT_TEST, DEFAULT_IMPORT_OWNER } from '../lib/discourse/constants'
+
+const defaultOptions = (yargs: CLI.Argv) => {
+ return yargs
+ .option('debug', { type: 'boolean', default: true, describe: 'debug messages' })
+ .option('verbose', { type: 'boolean', default: true, describe: 'even more debug messages' })
+ .option('yaml', { type: 'boolean', default: true, describe: 'Parse options from YAML header'})
+ .option('alt', {type: 'boolean', default: false, describe: 'alt token (%)'})
+ .option('uploadLocal', { type: 'boolean', default: true, describe: 'Upload local images to Discourse'})
+ .option('uploadRemote', { type: 'boolean', default: true, describe: 'Upload remote images to Discourse'})
+ .option('src', {
+ default: './tests/**/*.md',
+ type: 'string',
+ describe: 'Source : Path|Glob. Supported: HTML|MD|OSR(Options via YAML header)'
+ })
+ .option('title', { type: 'string', default: 'Title of the Discourse post' })
+ .option('config', { type: 'string', default: 'osr_admin' })
+ .option('cat', { default: CAT_TEST, type: 'number' })
+ .option('timestamp', { type: 'number', default: Date.now() })
+ .option('owner', { type: 'number', default: DEFAULT_IMPORT_OWNER })
+ .option('config', { type: 'string', default: 'discourse_admin' })
+ .option('env', { type: 'string', default: 'test-import' })
+ .option('profile', { type: 'string', default: "${OSR_ROOT}/osr-profiles/osr/base.json" })
+ .option('format', { type: 'string', default: 'html' })
+ .option('root', { type: 'string', default: process.cwd() })
+ .option('cwd', { type: 'string', default: process.cwd() })
+ .option('cache', { type: 'boolean', default: true })
+ .option('env_key', { type: 'string', default: 'OSR-CONFIG', describe: 'Environment key to the config path.' })
+}
+
+let options = (yargs: CLI.Argv) => defaultOptions(yargs)
+
+export const register = (cli: CLI.Argv) => {
+ return cli.command('sync ', 'Sync file', options, async (argv: CLI.Arguments) => {
+ defaults()
+ if (argv.help) { return }
+ let options = sanitize(argv as any) as IOptionsSync
+
+ if (!options) {
+ return
+ }
+ options.debug && logger.debug(`CLI Args In`, argv)
+
+ if (!options.verb) {
+ logger.error('No verb specified')
+ return;
+ }
+ return syncYAML(options)
+ })
+}
diff --git a/packages/discourse/src/constants.ts b/packages/discourse/src/constants.ts
new file mode 100644
index 00000000..2f24aa3a
--- /dev/null
+++ b/packages/discourse/src/constants.ts
@@ -0,0 +1 @@
+export const MODULE_NAME = `OSR-DISCOURSE`
diff --git a/packages/discourse/src/index.ts b/packages/discourse/src/index.ts
new file mode 100644
index 00000000..7054c193
--- /dev/null
+++ b/packages/discourse/src/index.ts
@@ -0,0 +1,82 @@
+export * from './constants'
+export * from './types'
+export * from './lib'
+export * from './lib/oa/types'
+
+import { logger as _logger } from '@plastichub/core/debug'
+
+import { MODULE_NAME } from './constants'
+import { ISettingsParam, Logger, ILogObject } from "tslog"
+export { Logger } from 'tslog'
+
+let loggers = {};
+
+/*
+const _logger = new Logger({
+ prettyLogTemplate: "{{yyyy}}.{{mm}}.{{dd}} {{hh}}:{{MM}}:{{ss}}:{{ms}}\t{{logLevelName}}\t[{{filePathWithLine}}{{name}}]\t",
+ prettyErrorTemplate: "\n{{errorName}} {{errorMessage}}\nerror stack:\n{{errorStack}}",
+ prettyErrorStackTemplate: " • {{fileName}}\t{{method}}\n\t{{filePathWithLine}}",
+ prettyErrorParentNamesSeparator: ":",
+ prettyErrorLoggerNameDelimiter: "\t",
+ stylePrettyLogs: true,
+ prettyLogTimeZone: "UTC",
+ prettyLogStyles: {
+ logLevelName: {
+ "*": ["bold", "black", "bgWhiteBright", "dim"],
+ SILLY: ["bold", "white"],
+ TRACE: ["bold", "whiteBright"],
+ DEBUG: ["bold", "green"],
+ INFO: ["bold", "blue"],
+ WARN: ["bold", "yellow"],
+ ERROR: ["bold", "red"],
+ FATAL: ["bold", "redBright"],
+ },
+ dateIsoStr: "white",
+ filePathWithLine: "white",
+ name: ["white", "bold"],
+ nameWithDelimiterPrefix: ["white", "bold"],
+ nameWithDelimiterSuffix: ["white", "bold"],
+ errorName: ["bold", "bgRedBright", "whiteBright"],
+ fileName: ["yellow"],
+ fileNameWithLine: "white",
+ },
+ });
+ */
+/*
+export const __logger = (name: string = MODULE_NAME, options: ISettingsParam = {}): Logger => {
+ if (!loggers[name]) {
+ const logger: Logger = new Logger({
+ name: name,
+ type: 'pretty',
+ ...options
+ });
+ // const trans = (transportLogger: LogObj & ILogObjMet)
+ (logger as any).attachTransport((logObj) => {
+ debugger
+ //transports.push(logObj);
+ });
+
+ logger.debug('test')
+
+ loggers[name] = logger;
+ }
+ return loggers[name]
+}*/
+
+
+export const logger = _logger(MODULE_NAME)
+
+/*
+export const log = (msg: string, ...args: any) => logger().info(msg, ...args);
+export const info = (msg: string, ...args: any) => logger().info(msg, ...args);
+export const error = (msg: string, ...args: any) => logger().error(msg, ...args);
+export const warn = (msg: string, ...args: any) => logger().warn(msg, ...args);
+export const debug = (msg: string, ...args: any) => logger().debug(msg, ...args);
+*/
+
+
+import { substitute as _substitute, substituteAlt as _substituteAlt } from "@plastichub/core/strings"
+
+import { IObjectLiteral } from "@plastichub/core"
+
+export const substitute = (alt: boolean, template: string, vars: IObjectLiteral = {}) => alt ? _substituteAlt(template, vars) : _substitute(template, vars)
diff --git a/packages/discourse/src/lib/discourse/cache.ts b/packages/discourse/src/lib/discourse/cache.ts
new file mode 100644
index 00000000..abcb4542
--- /dev/null
+++ b/packages/discourse/src/lib/discourse/cache.ts
@@ -0,0 +1,192 @@
+
+import { Promise as BPromise } from 'bluebird'
+import { sync as read } from '@plastichub/fs/read'
+import { sync as exists } from '@plastichub/fs/exists'
+import { sync as write } from '@plastichub/fs/write'
+import { resolve } from '@plastichub/osr-commons'
+import { sync as mkdir } from '@plastichub/fs/dir'
+import { files } from '@plastichub/osr-cli-commons'
+
+import { IUploadedFileMeta } from '@plastichub/osr-commons'
+import { forward_slash } from '@plastichub/osr-cli-commons'
+
+import {
+ IOptions,
+ IImportUser,
+ IOAHowto,
+ IOACategory,
+ IOATags,
+ IOAHowtoImport,
+ IDiscourseUser
+} from '../../'
+
+import {
+ logger
+} from '../../index'
+
+import {
+ HT_CATS,
+ DISCOURSE_CATEGORY_CACHE,
+ DISCOURSE_TAGS_CACHE,
+ DISCOURSE_TOPICS_CACHE,
+ DISCOURSE_USER_CACHE,
+ OSR_CACHE_ROOT,
+ OSR_DISCOURSE_CACHE,
+} from '../discourse/constants'
+
+
+import { Discourser } from '../index'
+
+import * as path from 'path'
+
+import * as cheerio from 'cheerio'
+
+import { html_beautify } from 'js-beautify'
+import { Converter } from 'showdown'
+
+const escapeHtml = require('escape-html')
+const pretty = require('pretty')
+
+export const fileAsBuffer = (path: string) => read(path, 'buffer') as Buffer || Buffer.from("-")
+
+import { get_cached, set_cached } from '@plastichub/osr-cache/lib'
+import { OSR_CACHE } from '@plastichub/osr-cli-commons'
+
+import * as md5 from 'md5'
+
+import {
+ MODULE_NAME
+} from '../../constants'
+
+
+export const cacheCategories = async (options: any, discourse: Discourser) => {
+
+ const osr_cache = OSR_CACHE()
+
+ const cPath = path.resolve(resolve(DISCOURSE_CATEGORY_CACHE))
+
+ const cached = exists(cPath) ? await get_cached(cPath, {}, MODULE_NAME) : null
+
+ if (osr_cache && cached && options.cache !== false) {
+ return JSON.parse(cached)
+ }
+
+ let cats = await discourse.getCategories({
+ include_subcategories: true
+ })
+
+ write(cPath, cats)
+
+ if (osr_cache && options.cache !== false) {
+ await set_cached(cPath, {}, MODULE_NAME, cats)
+ }
+
+ return cats
+}
+
+export const cacheTopics = async (options:any, discourse: Discourser) => {
+
+}
+
+let uPage = 1
+let usersAll = []
+
+export const _getForumUsers = async (d: Discourser, page, detail) => {
+
+ const uPath = path.resolve(resolve(DISCOURSE_USER_CACHE))
+
+ if (uPage == 1) {
+ usersAll = []
+ }
+ let users: any = await d.getUsers(page)
+ if (users.length) {
+ usersAll = usersAll.concat(users)
+ uPage++
+ return _getForumUsers(d, uPage, detail)
+ } else {
+ uPage = 1
+
+ write(uPath, usersAll)
+
+ let fUsers: IDiscourseUser[] = read(uPath, 'json') || [] as any
+
+ const add = async (u: IDiscourseUser) => {
+ return new Promise((resolve, reject) => {
+ let fUser = fUsers.find((fu) => u.id == fu.id)
+ if (!fUser) {
+ fUsers.push(u)
+ fUser = u
+ }
+
+ if (fUser.detail) {
+ console.log('Retrieve User Detail ' + u.name)
+ setTimeout(() => {
+ d.getUser(fUser.id).then((detail) => {
+ if (detail) {
+ fUser.detail = detail
+ }
+ write(uPath, fUsers)
+ resolve(fUser)
+ })
+ }, 200)
+ } else {
+ resolve(fUser)
+ }
+ })
+ }
+ return await BPromise.resolve(usersAll).map((u: IDiscourseUser) => {
+ return add(u)
+ }, { concurrency: 1 })
+
+ }
+}
+export const getForumUsers = async (d, detail): Promise => {
+ return _getForumUsers(d, uPage, detail)
+}
+
+export const cacheUsers = async (options, discourse: Discourser): Promise => {
+
+ const osr_cache = OSR_CACHE()
+ const uPath = path.resolve(resolve(DISCOURSE_USER_CACHE))
+
+ const cached = exists(uPath) ? await get_cached(uPath, {}, MODULE_NAME) : null
+
+ if (osr_cache && options.cache !== false && exists(uPath)) {
+ return read(uPath, 'json') as any
+ }
+
+ if (osr_cache && cached && options.cache !== false) {
+ return JSON.parse(cached)
+ }
+
+ let users = await getForumUsers(discourse, false)
+
+ write(uPath, users)
+
+ if (osr_cache && options.cache !== false) {
+ await set_cached(uPath, {}, MODULE_NAME, users)
+ }
+
+ return users
+
+}
+
+export const cacheTags = async (options, discourse: Discourser) => {
+ const osr_cache = OSR_CACHE()
+ const tPath = path.resolve(resolve(DISCOURSE_TAGS_CACHE))
+
+ const cached = exists(tPath) ? await get_cached(tPath, {}, MODULE_NAME) : null
+
+ if (osr_cache && cached && options.cache !== false) {
+ return JSON.parse(cached)
+ }
+
+ let tags = await discourse.getTags()
+ write(tPath, tags)
+
+ if (osr_cache && options.cache !== false) {
+ await set_cached(tPath, {}, MODULE_NAME, tags)
+ }
+
+ return tags
+}
\ No newline at end of file
diff --git a/packages/discourse/src/lib/discourse/constants.ts b/packages/discourse/src/lib/discourse/constants.ts
new file mode 100644
index 00000000..2560a124
--- /dev/null
+++ b/packages/discourse/src/lib/discourse/constants.ts
@@ -0,0 +1,119 @@
+
+//////////////////////////////////////////////////////////////
+//
+// Keys
+//
+
+export type EDiscourseConfigKey = 'discourse' | 'discourse_admin'
+
+//////////////////////////////////////////////////////////////
+//
+// Paths
+//
+
+export const SYNC_TRACK_FILENAME = 'discourse-sync.json'
+
+export const OSR_CACHE_ROOT = '${OSR_CACHE}'
+export const OSR_DISCOURSE_CACHE = '${OSR_CACHE}/discourse'
+
+export const DISCOURSE_CATEGORY_CACHE = '${OSR_CACHE}/discourse/cats.json'
+export const DISCOURSE_TOPICS_CACHE = '${OSR_CACHE}/discourse/topics.json'
+export const DISCOURSE_TAGS_CACHE = '${OSR_CACHE}/discourse/tags.json'
+export const DISCOURSE_USER_CACHE = '${OSR_CACHE}/discourse/users.json'
+
+//////////////////////////////////////////////////////////////
+//
+// OA - User Import
+//
+
+export const OA_DIRECTORY_OVERVIEW_TOPIC = 28873
+export const OA_USER_IMPORT_GROUP = 43
+export const KB_USERS = '${KB_ROOT}/static/users'
+export const DATA_PATH = '${OSR_ROOT}/osr-directory/pp'
+
+export const LATEST_TRACK = '${OSR_ROOT}/osr-directory/pp/merged.json'
+export const LATEST_TEST = './latest_test.json'
+export const FETCH_DUSERS = false
+export const F_USERS_NOW = './fusers.json'
+export const F_USERS_ALL = './fusers-all.json'
+
+export const DEFAULT_PASSWORD = () => '4g0&KPN$e*Un'
+
+export const HOWTOS_ASSETS_URL = () => `https://kb.osr-plastic.org/howtos/`
+export const MACHINES_ASSETS_URL = () => `https://assets.osr-plastic.org/machines/`
+
+export const CAT_TEST = 65
+export const TAGS_TEST = 'plastic, meta'
+export const DEFAULT_IMPORT_OWNER = 1
+
+//////////////////////////////////////////////////////////////
+//
+// OA - Directory Import
+//
+export const D_ROOT_CAT = 97
+
+export const D_ROOT_AFRICA = 79
+export const D_ROOT_ASIA = 60
+export const D_ROOT_EUROPE = 59
+export const D_ROOT_AUSTRALIA = 76
+export const D_ROOT_NAMERICA = 101
+export const D_ROOT_SAMERICA = 102
+export const D_ROOT_OCEANIA = 103
+
+//////////////////////////////////////////////////////////////
+//
+// OA - Howto Import
+//
+export const HT_CAT_ROOT = 54
+export const HT_CAT_GUIDES = 86
+export const HT_CAT_MACHINES = 87
+export const HT_CAT_PRODUCTS = 88
+export const HT_CAT_MOULDS = 89
+
+export const HT_CAT_IDS = {
+ HT_CAT_ROOT,
+ HT_CAT_GUIDES,
+ HT_CAT_MACHINES,
+ HT_CAT_PRODUCTS,
+ HT_CAT_MOULDS
+}
+
+
+export const HT_CATS = {
+ 'Guides': HT_CAT_GUIDES,
+ 'Machines': HT_CAT_MACHINES,
+ 'Products': HT_CAT_PRODUCTS,
+ 'Moulds': HT_CAT_MOULDS
+}
+
+//////////////////////////////////////////////////////////////
+//
+// OA - Library Import
+//
+
+export const MACHINE_CAT_INJECTION = 50
+export const MACHINE_CAT_EXTRUSION = 51
+export const MACHINE_CAT_SHREDDER = 52
+export const MACHINE_CAT_SHEETPRESS = 63
+export const MACHINE_CAT_3DPRINT = 70
+export const MACHINE_CAT_MOULDS = 71
+
+export const MACHINE_CAT_IDS = {
+ MACHINE_CAT_INJECTION,
+ MACHINE_CAT_EXTRUSION,
+ MACHINE_CAT_SHREDDER,
+ MACHINE_CAT_SHEETPRESS,
+ MACHINE_CAT_3DPRINT,
+ MACHINE_CAT_MOULDS
+}
+
+export const MACHINE_CATS = {
+ 'Injection': MACHINE_CAT_INJECTION,
+ 'Extrusion': MACHINE_CAT_EXTRUSION,
+ 'Sheetpress': MACHINE_CAT_SHEETPRESS,
+ '3DPrint': MACHINE_CAT_3DPRINT,
+ 'Moulds': HT_CAT_MOULDS
+}
+
+
+
diff --git a/packages/discourse/src/lib/discourse/index.ts b/packages/discourse/src/lib/discourse/index.ts
new file mode 100644
index 00000000..10c0e01b
--- /dev/null
+++ b/packages/discourse/src/lib/discourse/index.ts
@@ -0,0 +1,1295 @@
+import { MODULE_NAME } from '../../constants'
+
+import { CONFIG_DEFAULT } from '@plastichub/osr-cli-commons'
+
+import { IOSRConfig, IDiscourseConfig } from '@plastichub/osr-cli-commons/types'
+
+import { logger as _logger } from '@plastichub/core/debug'
+
+export const logger: any = _logger(MODULE_NAME)
+
+import { sync as write } from '@plastichub/fs/write'
+import { sync as read } from '@plastichub/fs/write'
+import { sync as exists } from '@plastichub/fs/exists'
+
+import PromisePool from 'native-promise-pool'
+
+
+import { join } from 'path'
+import axios from 'axios'
+import * as fs from 'fs'
+import * as path from 'path'
+import * as FormData from 'form-data'
+
+const https = require('https')
+const request = require("request")
+const fetch = require('isomorphic-unfetch')
+
+export const escape = (path: string) =>
+ path.replace(/[^\w]/g, '-').replace(/-+/, '-')
+
+import { generate } from 'generate-password'
+
+import { TPostStatus, TPostStatusUpdate, UserPreferencesUpdate } from './types'
+
+// types
+import {
+ PostUpdateRequest,
+ Category,
+ CategoriesResponse,
+ PostsResponse,
+ PostResponse,
+ TopicResponse,
+ TopicItem,
+ CategoryResponse,
+ PostItem,
+ PostUpdateResponse,
+ PostUpdateItem,
+ TopicUpdateTimestampRequest,
+ TopicUpdateTimestampResponse,
+ IDiscourserConfig,
+ Thread,
+ PostModifier,
+ FetchConfig,
+ FetchOptions,
+ PostConfig,
+ ISearchResult,
+ ICreateUserResponse,
+ IUserDetail,
+ TagsResponse,
+ Tag,
+ TopicUpdateBasicTopic
+} from './types';
+import { IDiscourseUser } from '@plastichub/osr-commons'
+import { EDiscourseConfigKey } from './constants'
+import { IDImage } from '../oa/index'
+
+
+
+/**
+ * Discourser is an API Client for the [Discourse API](https://docs.discourse.org)
+ * It special features are:
+ * - TypeScript Types
+ * - Respecting Rate Limits
+ * - Optional Heavy Caching
+ * - Post Modifiers (can be used for global find and replace across all posts on the forum)
+ */
+export class Discourser {
+ readonly host: string
+ readonly key: string
+ readonly username: string
+ readonly cache?: string
+ readonly useCache?: boolean
+ readonly dry: boolean
+ readonly pool: PromisePool
+
+ /**
+ * Construct our Discourser instance
+ * See {@link IDiscourserConfig} for available configuration.
+ */
+ constructor(config: IDiscourserConfig) {
+ this.host = config.host
+ this.key = config.key
+ this.username = config.username
+ this.cache = config.cache
+ this.useCache = config.useCache
+ this.dry = config.dry || false
+ this.pool = new PromisePool(config.rateLimitConcurrency || 60)
+ }
+
+ /** Get the URL of a topic */
+ getTopicURL(topic: TopicItem | TopicResponse | number): string {
+ if (typeof topic === 'number') {
+ return `${this.host}/t/${topic}`
+ }
+ return `${this.host}/t/${topic.slug}/${topic.id}`
+ }
+
+ /** Fetch a discourse API URL, with rate limit concurrency and optional caching */
+ async fetch({ url, useCache, request }: FetchConfig): Promise {
+ // check if cache is enabled
+ useCache = false
+ const cache =
+ this.cache &&
+ (request?.method || 'get') === 'get' &&
+ join(this.cache, escape(url))
+ // check if we should and can read from cache
+ if (
+ cache &&
+ this.useCache !== false &&
+ useCache !== false &&
+ (exists(cache))
+ ) {
+ const result = read(cache, 'json')
+ return (result as unknown) as T
+ }
+ // fetch
+ const result = await this.pool.open(() => this._fetch({ url, request }))
+ // write to cache if cache is enabled
+ if (cache) {
+ write(cache, result as any)
+ }
+ // return the result
+ return result
+ }
+
+
+ /** Fetch a discourse API URL, with rate limit retries */
+ private async _post(url, data): Promise {
+ const opts: RequestInit = {
+ headers: {
+ 'Api-Key': this.key,
+ 'Api-Username': this.username,
+ },
+ }
+ let d = data;
+ const res = await axios.post(url, d, {
+ headers: opts.headers as any
+ });
+
+ // fetch text then parse as json, so that when errors occur we can output what it was
+ // rather than being stuck with errors like these:
+ // FetchError: invalid json response body at https://discuss.bevry.me/posts/507.json reason: Unexpected token < in JSON at position 0
+ const text = await res.data;
+ // check if there are errors
+ if (typeof (data as any).errors !== 'undefined') {
+ // check if the error is a rate limit
+ const wait: number = (data as any).extras?.wait_seconds
+ if (wait != null) {
+ // if it was, try later
+ // return await retry(wait + 1)
+ }
+
+ // otherwise fail
+ // logger.debug({ data, url, opts })
+ return Promise.reject(
+ new Error(
+ `fetch of [${url}] received failed response:\n${data}`
+ )
+ )
+ }
+ return text;
+ }
+
+
+
+ /** Fetch a discourse API URL, with rate limit retries */
+ private async _fetch({ url, request }: FetchConfig): Promise {
+
+ const httpsAgent = new https.Agent({
+ rejectUnauthorized: false,
+ });
+ const opts = {
+ ...request,
+ headers: {
+ Accept: 'application/json',
+ 'Content-Type': 'application/json',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username,
+ ...request?.headers
+ },
+ rejectUnauthorized: false,
+ agent: httpsAgent
+ }
+
+ const retry = (seconds: number) => {
+ return new Promise((resolve, reject) => {
+ setTimeout(
+ () =>
+ this._fetch({ url, request })
+ .then(resolve)
+ .catch(reject),
+ (seconds || 60) * 1000
+ )
+ })
+ }
+
+ try {
+ const res = await fetch(url, opts);
+ // fetch text then parse as json, so that when errors occur we can output what it was
+ // rather than being stuck with errors like these:
+ // FetchError: invalid json response body at https://discuss.bevry.me/posts/507.json reason: Unexpected token < in JSON at position 0
+ const text = await res.text()
+ let data: T
+
+ try {
+ data = JSON.parse(text) as T
+ } catch (err) {
+ // check if it was cloudflare reporting that the server has been hit too hard
+ if (text.includes('Please try again in a few minutes')) {
+ logger.debug('server has stalled, trying again in a minute')
+ return await retry(60)
+ }
+ // otherwise log the error page and die
+ // logger.debug({ text, url , opts })
+ return Promise.reject(
+ logger.error(text, url, opts, err) &&
+ new Error(`fetch of [${url}] received invalid response:\n${text}`)
+ )
+ }
+
+ // check if there are errors
+ if (typeof (data as any).errors !== 'undefined') {
+ // check if the error is a rate limit
+ const wait: number = (data as any).extras?.wait_seconds
+ if (wait != null) {
+ // if it was, try later
+ return await retry(wait + 1)
+ }
+
+ // otherwise fail
+ // logger.debug({ data, url, opts })
+ return Promise.reject(
+ new Error(
+ `fetch of [${url}] received failed response:\n${data}`
+ )
+ )
+ }
+ return data
+ } catch (err) {
+ // logger.debug({ err, url, opts })
+ return Promise.reject(
+ logger.error(`fetch of [${url}] failed with error`, err)
+ )
+ }
+ }
+
+ // =================================
+ // Search
+
+ /**
+ * API Helper for {@link .search}
+ * https://docs.discourse.org/#tag/Search/operation/search
+ */
+ public async search(
+ query: string,
+ params: string = '',
+ opts: FetchOptions = {}
+ ): Promise {
+ let url = `${this.host}/search.json?q=${encodeURIComponent(query)} ${encodeURIComponent(params)}`;
+ return await this.fetch({ url, ...opts })
+ }
+ // =================================
+ // Tags
+
+ /**
+ * API Helper for {@link .getTags}
+ */
+ protected async getTagsResponse(
+ opts: FetchOptions = {}
+ ): Promise {
+ const url = `${this.host}/tags.json`
+ return await this.fetch({ url, ...opts })
+ }
+
+ /**
+ * Fetch the whole information, for all categories of the forum
+ */
+ async getTags(opts: FetchOptions = {}): Promise {
+ const response = await this.getTagsResponse(opts)
+ const tags = response.tags
+ return tags
+ }
+
+ async createTag(name): Promise {
+ const url = `${this.host}/tag_groups.json`
+ try {
+ return await this._post(url, {
+ name
+ });
+ } catch (error) {
+ debugger
+ }
+
+ }
+
+ // =================================
+ // CATEGORIES
+
+ /**
+ * API Helper for {@link .getCategories}
+ */
+ protected async getCategoriesResponse(
+ opts: FetchOptions = {}
+ ): Promise {
+ const url = `${this.host}/categories.json` +
+ (opts.include_subcategories ? '?include_subcategories=true' : '')
+ return await this.fetch({ url, ...opts })
+ }
+
+ /**
+ * Fetch the whole information, for all categories of the forum
+ */
+ async getCategories(opts: FetchOptions = {}): Promise {
+ const response = await this.getCategoriesResponse(opts)
+ const categories = response.category_list.categories
+ return categories
+ }
+
+ /**
+ * API Helper for {@link .getTopicItemsOfCategory}
+ * Discourse does not provide an API for fetching category information for a specific category.
+ * Instead, all that it provides is a way of getting the topics for a specific category.
+ */
+ protected async getCategoryResponse(
+ categoryID: number,
+ opts: FetchOptions = {}
+ ): Promise {
+ const url =
+ `${this.host}/c/${categoryID}.json` +
+ (opts.page !== 0 ? `?page=${opts.page}` : '')
+ return await this.fetch({ url, ...opts })
+ }
+
+ // =================================
+ // TOPICS
+
+ /**
+ * Fetch the partial information, for all topics of a specific category
+ */
+ async getTopicItemsOfCategory(
+ categoryID: number,
+ opts: FetchOptions = {}
+ ): Promise {
+ // prepare and fetch
+ let page = opts.page || 0
+ const response = await this.getCategoryResponse(categoryID, {
+ ...opts,
+ page,
+ })
+
+ let topics: TopicItem[] = response.topic_list.topics
+
+ // fetch the next page
+ if (topics.length === response.topic_list.per_page) {
+ page += 1
+ const more = await this.getTopicItemsOfCategory(categoryID, {
+ ...opts,
+ page,
+ })
+ topics.push(...more)
+ }
+
+ // if we are the first page, then output count as we now have all of them
+ if (page === 0) {
+ const ids = topics.map((i: TopicItem) => i.id)
+ }
+
+ topics = topics.filter((t) => t.visible === true);
+
+ return topics
+ }
+
+ /**
+ * Fetch the partial information, for all topics of specific categoires
+ */
+ async getTopicItemsOfCategories(
+ categoryIDs: number[],
+ opts: FetchOptions = {}
+ ): Promise {
+ // fetch topic items for specific categories
+ try {
+ const topicsOfCategories = await Promise.all(
+ categoryIDs.map((id) => this.getTopicItemsOfCategory(id, opts))
+ )
+ // @ts-ignore
+ return topicsOfCategories.flat()
+ } catch (error) {
+ logger.error(error);
+ }
+ }
+
+ /**
+ * Fetch the partial information, for all topics of the forum
+ */
+ async getTopicItems(opts: FetchOptions = {}) {
+ const categories = await this.getCategories()
+ const categoryIDs = categories.map((i) => i.id)
+ return this.getTopicItemsOfCategories(categoryIDs, opts)
+ }
+
+ /**
+ * Fetch the whole information, for a specific topic of the forum
+ */
+ getTopic(id: number, opts: FetchOptions = {}): Promise {
+ const url = `${this.host}/t/${id}.json`
+ return this.fetch({ url, ...opts })
+ }
+
+ /**
+ * Fetch the whole information, for all topics, or specific topics, of the forum
+ */
+ async getTopics(
+ topicIDs?: number[] | null,
+ opts: FetchOptions = {}
+ ): Promise {
+ // if no topics, use all topics
+ if (!topicIDs) {
+ const topics = await this.getTopicItems(opts)
+ topicIDs = topics.map((i) => i.id)
+ }
+
+ // fetch whole topics
+ return Promise.all(topicIDs.map((id) => this.getTopic(id, opts)))
+ }
+
+ async updateTopicVisibility(
+ topicID: number,
+ listed: boolean = true,
+ visible: TPostStatus = 'visible'
+ ): Promise {
+ const url = `${this.host}/t/${topicID}/status`
+ let ret = await fetch(url, {
+ "headers": {
+ "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ },
+ "body": `status=${visible}&enabled=${listed}`,
+ "method": "PUT"
+ });
+
+ return ret
+ }
+
+ async updateTopicTimestamp(
+ topicID: number,
+ timestamp: Date | string | number,
+ token: string
+ ): Promise {
+ let time: number
+ if (typeof timestamp === 'number') {
+ time = timestamp
+ } else if (typeof timestamp === 'number') {
+ time = Number(timestamp)
+ } else if (timestamp instanceof Date) {
+ // ms to seconds
+ time = timestamp.getTime() / 1000
+ } else {
+ return Promise.reject(new Error('invalid timestamp format'))
+ }
+
+ const url = `${this.host}/t/${topicID}/change-timestamp`
+
+ let ret = await fetch(url, {
+ "headers": {
+
+ "accept-language": "en-GB,en-US;q=0.9,en;q=0.8,de;q=0.7,es;q=0.6,fr;q=0.5",
+ "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
+ "x-csrf-token": token,
+ "x-requested-with": "XMLHttpRequest",
+ "cookie": "_bypass_cache=true; _ga_MBZGKNMDWC=GS1.1.1685892974.20.1.1685893082.0.0.0; _ga_P4SR15V1XR=GS1.1.1687459978.51.1.1687460537.0.0.0; _ga_H8W78Y3P2B=GS1.1.1687604701.23.0.1687604701.0.0.0; _ga=GA1.1.401826746.1678337758; _t=xQ05qW5JFxLM9Pq0lIwG6ez74Z1q2OLpak0DzRx8VdFYE5eI3oJXhLURPrdm2zIcHmYcBj9q%2BKdHhGz5N6j9mXitYzcMwkXHL3K9GYKdO4gJ8tBQimpmd1HFaRhB9Ml9aJ8WviqQWDZDOYwEUKFcWw3wbAalfQtbdIbUSX8gH9sG6DLFU3HiEg7tWModRy%2BoFrTm6QOalDuajRW3nBazau%2FiY8ZCVm2g30Y10CBDfqJHL1ztV8XM4kEIeulLNTzGVtSb7uuO1OcjZRSb--aDgCPEalq7SIpnH5--HWCNf5readaeij3oDl9b9w%3D%3D; __profilin=p%3Dt%2Ca%3Deef38e031f99cc8240f3518e1b8811cf; _forum_session=RkEWuzKI1QXBYCnP6KRamD8mweZ3h9%2B6G%2Fi23gAWUgy8gp8FuiyQD5lKU0Fbx3FzzaM4SiQcvnIiEAnb5P4OYjlvstqwWlfRp%2B9is7iX8StwYGiYsncHQ5LrzSbV3y9mR7sj%2F8JZ8evQOe2ZZjZB3iEkppsGrmyFrw5PsUgSphRTZm70SKIw96JrW17yK4hhLqtk%2BaQPgNu4oJl42YfXAr%2FCBldcBUKXFeHppYmv61WECV0531hCo7GcA4t06B9QpSr%2BeoiM1Ok9tpQrAlZf36Ka4lVCTyXXu3SNvbtvfd9tZMJCWDYv69jdMsezuOaEP870pk9qYPaL4x6nAY5EXO3u9usCggqQ1B1EydCK9uMy7ZUCIo9wONw7QOIgEQ%3D%3D--GMqYSb2H7xXVDky6--R9gVciBqwC0IL9LefywrFw%3D%3D; _ga_GVR8PEPG6C=GS1.1.1687710574.106.1.1687710599.0.0.0",
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ },
+ "body": `timestamp=${time}`,
+ "method": "PUT"
+ });
+
+ if (ret && ret.status === 200) {
+ return true
+ }
+ return
+
+ /*
+ let data = new FormData();
+ data.append('timestamp', time);
+
+ try {
+ let ret = await axios.put(url, data, {
+ headers: {
+ //'Accept-Language': 'en-US,en;q=0.8',
+ //'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
+ //'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ debugger
+ } catch (error) {
+ debugger
+ }
+
+
+ return
+ */
+
+ /*
+ var options = {
+ method: 'PUT',
+ url: url,
+ headers:
+ {
+ 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ },
+ body: `timestamp=${time}`
+ };
+
+ new Promise((resolve, reject) => {
+ request(options, function (error, response, body) {
+ if (error) {
+ throw new Error(error);
+ } else {
+ resolve(body);
+ }
+ });
+ });
+ */
+
+ /*
+ var options = {
+ method: 'POST',
+ url: url,
+ headers:
+ {
+ 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ },
+ body
+ }
+
+
+ return new Promise((resolve, reject) => {
+ request(options, function (error, response, body) {
+ if (error) {
+ throw new Error(error);
+ } else {
+ resolve(body);
+ }
+ });
+ });
+*/
+
+
+ // prepare the request
+ const request: TopicUpdateTimestampRequest = {
+ timestamp: time,
+ }
+
+ // send the update
+ logger.debug('updating', topicID, 'topic timestamp with', request)
+ //const url = `${this.host}/t/${topicID}/change-timestamp`
+ const response = await this.fetch({
+ url,
+ request: {
+ method: 'put',
+ body: `timestamp=${time}`,
+ headers: {
+ 'Api-Key': this.key,
+ 'Api-Username': this.username,
+ "content-type": "application/x-www-form-urlencoded; charset=UTF-8"
+
+ }
+ }
+ })
+
+ // check it
+ if (response.success !== 'OK') {
+ return Promise.reject(
+ new Error(
+ `timestamp update of topic ${topicID} failed:\n${{
+ url,
+ request,
+ response,
+ }}`
+ )
+ )
+ }
+
+ return response
+ }
+
+ // =================================
+ // POSTS
+
+ /**
+ * API Helper for {@link .getPostItemsOfTopic}
+ */
+ protected async getPostItemsOfTopicResponse(
+ topicID: number,
+ opts: FetchOptions = {}
+ ): Promise {
+ const url = `${this.host}/t/${topicID}/posts.json`
+ const response = await this.fetch({ url, ...opts })
+ return response
+ }
+
+ async _createUser(name, email, pUserGroup): Promise {
+
+ const pwd = generate({
+ length: 10,
+ numbers: true
+ })
+
+ let user = await this.createUser({
+ "name": name,
+ "email": email,
+ "password": pwd,
+ "username": name,
+ "active": true,
+ "approved": true,
+ "user_fields[1]": true
+ }) satisfies ICreateUserResponse;
+
+ if (user && user.user_id) {
+ await this.updateGroup(name, pUserGroup);
+ return { ...user, password: pwd };
+ } else {
+ if (user && user.message && user.message == 'Username must be unique\nPrimary email has already been taken') {
+ return null;
+ } else if (user && user.message && user.message == 'Your account is activated and ready to use.') {
+ if (user.user_id) {
+ return { ...user, password: pwd };
+ }
+ return null;
+ } else {
+ console.log('cant create user ' + name, user);
+ }
+ return null;
+ }
+ }
+
+ async getUsers(page): Promise {
+ const url = `${this.host}/admin/users/list/active.json?page=` + page
+ const response = await this.fetch({ url })
+ return response
+ }
+
+ async getUser(id): Promise {
+ const url = `${this.host}/admin/users/${id}.json`
+ const response = await this.fetch({ url })
+ return response;
+ }
+
+ /**
+ * Fetch the partial information, for all posts of a specific topic
+ */
+ async getPostItemsOfTopic(
+ topicID: number,
+ opts: FetchOptions = {}
+ ): Promise {
+ const response = await this.getPostItemsOfTopicResponse(topicID, opts)
+ const posts: PostItem[] = response.post_stream.posts
+ const ids = posts.map((i) => i.id)
+ return posts
+ }
+
+ /**
+ * Fetch the partial information, for all posts of specific topics
+ */
+ async getPostItemsOfTopics(
+ topicIDs: number[],
+ opts: FetchOptions = {}
+ ): Promise {
+ // fetch post items for specific topics
+ const postItemsOfTopics = await Promise.all(
+ topicIDs.map((id) => this.getPostItemsOfTopic(id, opts))
+ )
+
+ // @ts-ignore
+ return postItemsOfTopics.flat()
+ }
+
+ /**
+ * Fetch the partial information, for all posts of a specific category
+ */
+ async getPostItemsOfCategory(
+ categoryID: number,
+ opts: FetchOptions = {}
+ ): Promise {
+ // fetch topics for the category
+ const topics = await this.getTopicItemsOfCategory(categoryID, opts)
+ const topicIDs = topics.map((i) => i.id)
+
+ // fetch
+ const posts = await this.getPostItemsOfTopics(topicIDs)
+ const ids = posts.map((i) => i.id)
+ return posts
+ }
+
+ /**
+ * Fetch the partial information, for all posts of specific categories
+ */
+ async getPostItemsOfCategories(
+ categoryIDs: number[],
+ opts: FetchOptions = {}
+ ): Promise {
+ // fetch post items for specific categories
+ const postItemsOfCategories = await Promise.all(
+ categoryIDs.map((id) => this.getPostItemsOfCategory(id, opts))
+ )
+
+ // @ts-ignore
+ return postItemsOfCategories.flat()
+ }
+
+ /**
+ * Fetch the partial information, for all posts of the forum
+ */
+ async getPostItems(opts: FetchOptions = {}): Promise {
+ const categories = await this.getCategories()
+ const categoryIDs = categories.map((i) => i.id)
+ return this.getPostItemsOfCategories(categoryIDs, opts)
+ }
+
+ /**
+ * Fetch the whole information, for a specific post of the forum
+ */
+ getPost(id: number, opts: FetchOptions = {}): Promise {
+ const url = `${this.host}/posts/${id}.json`
+ return this.fetch({ url, ...opts })
+ }
+
+ async createReply(postId, raw, category) {
+
+ const url = `${this.host}/posts.json`;
+
+ let data: any = new FormData();
+ data.append('topic_id', '' + postId);
+ data.append('raw', raw);
+ data.append('nested_post', 'true');
+ data.append('category', category);
+ var options = {
+ method: 'POST',
+ url: url,
+ headers:
+ {
+ 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ },
+ "body": `raw=${raw}&unlist_topic=false&category=${category}&topic_id=${postId}&is_warning=false&archetype=regular&featured_link=&shared_draft=false&nested_post=true`,
+ };
+
+ return new Promise((resolve, reject) => {
+ request(options, function (error, response, body) {
+ if (error) {
+ throw new Error(error);
+ } else {
+ resolve(body);
+ }
+ });
+ });
+
+ }
+
+ async changeOwner(postId: string | number, topicId: string | number, owner: string
+ ) {
+ const url = `${this.host}/t/${topicId}/change-owner.json`;
+ var options = {
+ method: 'POST',
+ url: url,
+ headers:
+ {
+ 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ },
+ body: `post_ids%5B%5D=${postId}&username=${owner}`
+ };
+
+
+ return new Promise((resolve, reject) => {
+ request(options, function (error, response, body) {
+ if (error) {
+ throw new Error(error);
+ } else {
+ resolve(body);
+ }
+ });
+ });
+ }
+
+ async createUser(data): Promise {
+ const url = `${this.host}/users`
+ return await this._post(url, data);
+ }
+
+ async getUserByUsername(username): Promise {
+ const url = `${this.host}/u/${username}.json`
+ const response = await this.fetch({ url })
+ return (response as any).user
+ }
+
+ async setUserAvatar(user_name, upload_id): Promise {
+ // fetch whole posts
+ const url = `${this.host}/u/${user_name}/preferences/avatar/pick.json`;
+ return await axios.put(url, {
+ upload_id,
+ username: user_name,
+ type: 'uploaded'
+ }, {
+ headers: {
+ 'accept': 'application/json',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ }
+
+ async updateUser(user_name, args): Promise {
+
+ const url = `${this.host}/u/${user_name}.json`;
+ return await axios.put(url, {
+ ...args
+ }, {
+ headers: {
+ 'accept': 'application/json',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ }
+
+ async updateGroup(user_name, group) {
+ // fetch whole posts
+ const url = `${this.host}/groups/${group}/members.json`;
+ const t = axios.put(url, {
+ usernames: user_name,
+ notify_users: false
+ }, {
+ headers: {
+ 'accept': 'application/json',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ t.then((d) => {
+
+ }).catch((e) => {
+ //debugger;
+ })
+ return t;
+ }
+
+
+
+ async upload(userId, file): Promise {
+ // fetch whole posts
+ const url = `${this.host}/uploads.json`;
+
+ let data: any = new FormData();
+ const fsData = path.parse(file);
+ data.append('file', file, fsData.base);
+ data.append('user_id', userId);
+ data.append('upload_type', 'avatar');
+ data.append('file', fs.createReadStream(file));
+
+ return await axios.post(url, data, {
+ headers: {
+ 'accept': 'application/json',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ 'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ }
+
+ async uploadFile(userId, file): Promise {
+ // fetch whole posts
+ const url = `${this.host}/uploads.json`;
+ let data: any = new FormData();
+ const fsData = path.parse(file);
+ data.append('file', file, fsData.base);
+ data.append('user_id', userId);
+ data.append('upload_type', 'composer');
+ data.append('file', fs.createReadStream(file));
+
+ return await axios.post(url, data, {
+ headers: {
+ 'accept': 'application/json',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ 'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ });
+ }
+
+ // =================================
+ // POSTS: UPDATING
+
+ /**
+ * Fetch the whole information, for all posts, or specific posts, of the forum
+ */
+ async getPosts(
+ postIDs?: number[] | null,
+ opts: FetchOptions = {}
+ ): Promise {
+ // if no posts, use all
+ if (!postIDs) {
+ const posts = await this.getPostItems(opts)
+ postIDs = posts.map((i) => i.id)
+ }
+
+ // fetch whole posts
+ return await Promise.all(postIDs.map((id) => this.getPost(id, opts)))
+ }
+
+ async createPost(
+ title: string,
+ raw: string,
+ category: number
+ ) {
+ // fetch whole posts
+ const url = `${this.host}/posts`
+ return new Promise((resolve) => {
+ return this._post(url, { raw, title, category }).then((d) => {
+ resolve(d);
+ }).catch((e) => {
+ resolve(e.response.data);
+ })
+ });
+ }
+
+ /**
+ * Update a post with the content
+ * @param postID the identifier of the post to update
+ * @param content the new raw content for the post
+ * @param reason the reason, if provided, for modifying the post
+ * @param old if the old raw content is provided, then the update verified that you are working with the latest post content before applying the update
+ */
+ async updatePost(
+ postID: number,
+ content: string,
+ reason: string = 'api update',
+ old?: string
+ ): Promise {
+ // prepare the request
+ const data: PostUpdateRequest = {
+ post: {
+ raw: content,
+ edit_reason: reason,
+ },
+ }
+ if (old) {
+ data.post.raw_old = old
+ }
+
+ // send the update
+ const url = `${this.host}/posts/${postID}.json`
+ const response = await this.fetch({
+ url,
+ request: {
+ method: 'put',
+ body: JSON.stringify(data),
+ },
+ })
+
+ // return the response
+ return response.post
+ }
+
+ /**
+ * Update post meta
+ */
+ async updateTopic(
+ postId: number,
+ category_id: number,
+ title: string,
+ tags?: string[]
+ ): Promise {
+ const data =
+ {
+ title,
+ tags: tags || [],
+ featuredLink: null,
+ category_id
+ }
+
+ const url = `${this.host}/t/${postId}.json`
+ const response = await this.fetch({
+ url,
+ request: {
+ method: 'put',
+ body: JSON.stringify(data),
+ },
+ })
+ return response.basic_topic
+ }
+
+
+
+ async rebakePost(postID: number): Promise {
+
+ const url = `${this.host}/posts/${postID}/rebake`
+ logger.debug('rebaking', postID)
+
+ const response = await this.fetch({
+ url,
+ request: {
+ method: 'put'
+ }
+ })
+ logger.debug('rebaked', postID)
+ return response
+ }
+
+
+
+ /**
+ * Modify a post using a modifier
+ */
+ async modifyPost(
+ post: PostResponse,
+ modifier: PostModifier
+ ): Promise {
+ // check if we received a post item, instead of a post response
+ if (post.raw == null) {
+ post = await this.getPost(post.id)
+ }
+
+ // check
+ if (!post.raw) {
+ return Promise.resolve(null)
+ }
+
+ // replace
+ const { result, reason } = modifier(post)
+ if (result === post.raw) {
+ // if (post.cooked) {
+ // const { result, reason } = modifier(post.cooked)
+ // if (result !== post.cooked) {
+ // logger.debug(
+ // 'replace did have an effect on cooked post',
+ // postID,
+ // 'so rebaking it'
+ // )
+ // return await this.rebakePost(postID)
+ // }
+ // }
+ return Promise.resolve(null)
+ }
+
+ // dry
+ if (this.dry) {
+ return Promise.resolve({
+ ...((post as unknown) as PostUpdateItem),
+ result,
+ reason,
+ })
+ }
+
+ // update
+ try {
+ return await this.updatePost(post.id, result, reason, post.raw)
+ } catch (err) {
+ if (
+ err.message.includes(
+ 'That post was edited by another user and your changes can no longer be saved.'
+ )
+ ) {
+ return this.modifyPost(
+ await this.getPost(post.id, { useCache: false }),
+ modifier
+ )
+ }
+ logger.error(err);
+ return Promise.reject(`modifying post ${post.id} failed`)
+ }
+ }
+
+ /**
+ * Modify a post (via its post identifier) using a modifier
+ */
+ async modifyPostID(post: number, modifier: PostModifier) {
+ return this.modifyPost(await this.getPost(post), modifier)
+ }
+
+ /**
+ * Modify a post (via fetching the whole post from the partial post identifier) using a modifier
+ */
+ async modifyPostItem(post: PostItem, modifier: PostModifier) {
+ return this.modifyPost(await this.getPost(post.id), modifier)
+ }
+
+ /**
+ * Run the post modifier on all specified posts
+ */
+ async modifyPosts(
+ posts: PostResponse[],
+ modifier: PostModifier
+ ): Promise {
+ const updates = await Promise.all(
+ posts.map((post) => this.modifyPost(post, modifier))
+ )
+ const updated = updates.filter((i) => i) as PostUpdateItem[]
+ return updated
+ }
+
+ // =================================
+ // THREADS
+
+ /**
+ * Fetch the partial information, for all posts of a specific topic
+ * Alias of {@link .getPostItemsOfTopic}.
+ */
+ async getThread(topicID: number, opts: FetchOptions = {}): Promise {
+ const topic = await this.getTopic(topicID, opts)
+ const [post, ...replies] = await this.getPostItemsOfTopic(topicID, opts)
+ return {
+ topic,
+ post,
+ replies,
+ }
+ }
+
+ /**
+ * Fetch the partial information, for all posts of specific topics, grouped by topic
+ */
+ async getThreads(
+ topicIDs: number[],
+ opts: FetchOptions = {}
+ ): Promise {
+ return await Promise.all(topicIDs.map((id) => this.getThread(id, opts)))
+ }
+
+ /**
+ * Fetch the partial information, for all posts of specific categories, grouped by topic
+ */
+ async getThreadsOfCategory(
+ categoryID: number,
+ opts: FetchOptions = {}
+ ): Promise {
+ // fetch topics for the category
+ const topics = await this.getTopicItemsOfCategory(categoryID, opts)
+ const topicIDs = topics.map((i) => i.id)
+ // return threads
+ return await this.getThreads(topicIDs)
+ }
+
+ /**
+ * Fetch the partial information, for all posts of specific categories, grouped by category, then topic
+ */
+ async getThreadsOfCategories(
+ categoryIDs: number[],
+ opts: FetchOptions = {}
+ ): Promise {
+ return await Promise.all(
+ categoryIDs.map((id) => this.getThreadsOfCategory(id, opts))
+ )
+ }
+
+ async updateUserProfile(userId, prefs: UserPreferencesUpdate): Promise {
+
+ const url = `${this.host}/u/${userId}.json`
+ let data: any = new FormData()
+
+ data.append('bio_raw', prefs.bio_raw)
+
+ prefs.location && data.append('location', prefs.location)
+ prefs.website && data.append('website', prefs.website)
+
+ return await axios.put(url, data, {
+ headers: {
+ 'accept': 'application/json',
+ 'Accept-Language': 'en-US,en;q=0.8',
+ "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
+ 'Api-Key': this.key,
+ 'Api-Username': this.username
+ }
+ })
+ }
+
+ /*
+ {
+ "bio_raw": "about me\n\ntest",
+ "website": "https://shop.osr-plastic.org",
+ "location": "Barcelona",
+ "custom_fields": {
+ "geo_location": {
+ "lat": "9.4170689",
+ "lon": "123.3351935",
+ "address": "Santander, Cebu, Central Visayas, 6026, Philippines",
+ "countrycode": "ph",
+ "city": "Santander",
+ "state": "Cebu",
+ "country": "Philippines",
+ "postalcode": "6026",
+ "boundingbox": [
+ "9.3630227",
+ "9.491731",
+ "123.2684005",
+ "123.3642727"
+ ],
+ "type": "administrative"
+ }
+ },
+ "timezone": "Europe/Berlin",
+ "default_calendar": "none_selected"
+ }*/
+ /*
+ fetch("https://forum.osr-plastic.org/u/katharinaelleke.json", {
+ "headers": {
+ "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
+ "discourse-logged-in": "true",
+ "discourse-present": "true",
+ "sec-ch-ua": "\"Not.A/Brand\";v=\"8\", \"Chromium\";v=\"114\", \"Google Chrome\";v=\"114\"",
+ "sec-ch-ua-mobile": "?0",
+ "sec-ch-ua-platform": "\"Windows\"",
+ "x-csrf-token": "0Nau_ylBzR68D5OvfxfOHYii6GI_7gSrr_Ci_9S8ZDjqjy5mavF_O_INAPD8xfCQHgJkDH4rdgS0kPfjMAMBFw",
+ "x-requested-with": "XMLHttpRequest",
+ "Referer": "https://forum.osr-plastic.org/u/katharinaelleke/preferences/profile",
+ "Referrer-Policy": "strict-origin-when-cross-origin"
+ },
+ "body": "bio_raw=Curious%2C+serious+and+not+so+serious+%3Aslight_smile%3A+%0A&website=https%3A%2F%2Fwww.theflipflopi.com%2F&custom_fields%5Bnotify_me_when_followed%5D=false&custom_fields%5Bnotify_followed_user_when_followed%5D=false&custom_fields%5Bnotify_me_when_followed_replies%5D=false&custom_fields%5Bnotify_me_when_followed_creates_topic%5D=false&custom_fields%5Ballow_people_to_follow_me%5D=false&custom_fields%5Bgeo_location%5D%5Blat%5D=-2.294164&custom_fields%5Bgeo_location%5D%5Blon%5D=40.91501&custom_fields%5Bgeo_location%5D%5Baddress%5D=African+Corner%2C+Lamu%2C+Coast%2C+Kenya&custom_fields%5Bgeo_location%5D%5Bcountrycode%5D=ke&custom_fields%5Bgeo_location%5D%5Bcity%5D=&custom_fields%5Bgeo_location%5D%5Bstate%5D=Coast&custom_fields%5Bgeo_location%5D%5Bcountry%5D=Kenya&custom_fields%5Bgeo_location%5D%5Bpostalcode%5D=&custom_fields%5Bgeo_location%5D%5Bboundingbox%5D%5B%5D=-2.294164&custom_fields%5Bgeo_location%5D%5Bboundingbox%5D%5B%5D=-2.294164&custom_fields%5Bgeo_location%5D%5Bboundingbox%5D%5B%5D=40.91501&custom_fields%5Bgeo_location%5D%5Bboundingbox%5D%5B%5D=40.91501&custom_fields%5Bgeo_location%5D%5Btype%5D=&user_fields%5B1%5D=https%3A%2F%2Fshop.osr-plastic.org%2Fafrica%2F&user_fields%5B2%5D=https%3A%2F%2Fwww.theflipflopi.com%2F&user_fields%5B3%5D=https%3A%2F%2Fwww.instagram.com%2Fkatatungo%2F&user_fields%5B4%5D=unknown&user_fields%5B5%5D=unknown&profile_background_upload_url=https%3A%2F%2Fforum.osr-plastic.org%2Fuploads%2Fdefault%2Foriginal%2F2X%2F0%2F0875e1aea65f41172b9c4ad60b1a372cbaa72b2b.jpeg&card_background_upload_url=https%3A%2F%2Fforum.osr-plastic.org%2Fuploads%2Fdefault%2Foriginal%2F2X%2F3%2F357088c493bd0f66e651211853fb18beee2ec2e4.jpeg&timezone=Africa%2FNairobi&default_calendar=none_selected",
+ "method": "PUT"
+ });
+
+
+ fetch("https://forum.osr-plastic.org/u/admin-osr.json", {
+ "headers": {
+ "accept-language": "en-GB,en-US;q=0.9,en;q=0.8",
+ "content-type": "application/x-www-form-urlencoded; charset=UTF-8",
+ "discourse-logged-in": "true",
+ "discourse-present": "true",
+ "sec-ch-ua": "\"Not/A)Brand\";v=\"99\", \"Google Chrome\";v=\"115\", \"Chromium\";v=\"115\"",
+ "sec-ch-ua-mobile": "?0",
+ "sec-ch-ua-platform": "\"Windows\"",
+ "sec-fetch-dest": "empty",
+ "sec-fetch-mode": "cors",
+ "sec-fetch-site": "same-origin",
+ "x-csrf-token": "gjd-DOi_nULFDhLyUh4igqFZENxL6B4rufR3dfbY9H9Soc-YDwOQS1SYSwJlj6f2f7BpDf5CO9y-zyOPBj-E1Q",
+ "x-requested-with": "XMLHttpRequest",
+ "cookie": "_ga=GA1.1.983567986.1691921410; _t=onvQ4UWFfLfjFsFkmebQdDot6JXW8%2FAWgFEtJUZ51AqXbTKnI%2BPF80usnZkhYqyYYW9Q%2B1fuMyEy5bDXc9AJpwwkcVIg%2Fu1DTE39y3nGdpXMiiVsmkMqBkyGA%2FvpvZUrM23CDS0xT%2B09VSSlNUbu8lZY27hYWXio4ETx7DRTmBk0xY52d3R6bcmtofynfxldP5KceF0APNtl9AV6iUhWloQ32CK6PmzpSFq4E3hstsS1WPTf7SwLGvESWm4tn3M4EQ2v4RHuLiHaAj%2F0--mv8Byxo5aHGcgKPO--%2F9eiy%2B24FCNmiLF3%2FpGZag%3D%3D; _ga_GVR8PEPG6C=GS1.1.1691940751.2.1.1691940775.0.0.0; _forum_session=bLbNekWpq6fkdK%2B19Nw6ZoKeEk9Ijp8LPfmQAjBiGK0TcnIYzMhZ5LJmLrxmG39e85SgUz%2F7NMI3NXZM9j%2F35eJuO3hxnUAkFvBNwjwwS9LGhDB4kB3ebAjjcBpoLPzUMWqyslQuR9RM8JcjZ%2FfX%2FWw0E61l9jhfrG0dr8Ds97IW7XedjKCmI7x7xinv10R2bRb51%2F72t2Z4dVG86wyCAtI5Spom0yjHoWPHwWBZ7VPYtOCmSBVygusuF%2FW5hpO9wgn1oqc0ZZ%2BXj%2FPiFc0FsADEcKYh3Q%3D%3D--xdEsXmADtTKkFGSc--x%2Fd9m02lRNk0uH%2BPxZTNwQ%3D%3D",
+ "Referer": "https://forum.osr-plastic.org/u/admin-osr/preferences/profile",
+ "Referrer-Policy": "strict-origin-when-cross-origin"
+ },
+ "body": "bio_raw=%23%23+Test%0A%0A%60%60%60js%0Aconst+t+%3D+0%0A%60%60%60%0A%0A%5Btest%5D(www.test.com)%0A%0A&website=www.test-site.com&location=test-loc&profile_background_upload_url=https%3A%2F%2Fforum.osr-plastic.org%2Fuploads%2Fdefault%2Foriginal%2F2X%2Fd%2Fd097423e34a6c677cdb0933d091fb84bcfbcec2e.jpeg&card_background_upload_url=https%3A%2F%2Fforum.osr-plastic.org%2Fuploads%2Fdefault%2Foriginal%2F2X%2Fb%2Fb4c30d1b981964fd6f936ebaac0f86ad4dc01209.png&timezone=Europe%2FBerlin&default_calendar=none_selected",
+ "method": "PUT"
+});
+
+
+ */
+
+
+}
+
+
+export const Instance = (config?: IDiscourseConfig, key: EDiscourseConfigKey = 'discourse_admin') => {
+
+ return new Discourser(config || (CONFIG_DEFAULT() as IOSRConfig)[key])
+
+ /*
+
+ d.getTopicItemsOfCategories([cat]).then(posts => {
+ //console.log('posts', posts)
+ let content = ""
+ posts = posts.map((p) => {
+ const url = `${config.discourse.host}/t/${p.id}`;
+ const title = `${p.fancy_title}`;
+ return `${title} `;
+ }).join('\n');
+ content += posts + " ";
+ resolve(content);
+
+ });
+ */
+}
\ No newline at end of file
diff --git a/packages/discourse/src/lib/discourse/types.ts b/packages/discourse/src/lib/discourse/types.ts
new file mode 100644
index 00000000..dc7e3502
--- /dev/null
+++ b/packages/discourse/src/lib/discourse/types.ts
@@ -0,0 +1,761 @@
+// Attempt at TypeScript Types for the Discourse API
+// https://docs.discourse.org
+
+
+export interface Failure {
+ success: 'OK' // docs say lowercase, reality is uppercase
+}
+export interface Success {
+ failed: 'FAILED'
+}
+export type Response = Failure & Success
+
+export interface Action {
+ can_act: boolean
+ id: number
+ count?: number
+ hidden?: boolean
+}
+export interface Poster {
+ description: string
+ extras: string
+ user_id: number
+}
+export interface Person {
+ avatar_template: string
+ id: number
+ username: string
+}
+export interface Participant extends Person {
+ post_count: number
+}
+
+// This isn't documented, but is is there on
+// https://docs.discourse.org/#tag/Topics/paths/~1t~1{id}.json/get
+export interface Link {
+ url: string
+ internal: boolean
+ reflection: boolean
+ title: string
+ clicks: number
+}
+
+/**
+ * Update a Topic Timestamp
+ * https://docs.discourse.org/#tag/Topics/paths/~1t~1{id}~1change-timestamp/put
+ */
+export interface TopicUpdateTimestampRequest {
+ timestamp: number
+}
+export type TopicUpdateTimestampResponse = Response
+
+/**
+ * Update a Post
+ * https://docs.discourse.org/#tag/Posts/paths/~1posts~1{id}.json/put
+ */
+export interface PostUpdateResponse {
+ post: PostUpdateItem
+}
+
+export interface TopicUpdateBasicTopic {
+ fancy_title: string
+ id: number
+ posts_count: number
+ slug: string
+ title: string
+}
+
+export interface TopicUpdateResponse{
+ basic_topic: TopicUpdateBasicTopic
+}
+
+export interface PostUpdateItem {
+ actions_summary: Array
+ admin: boolean
+ avatar_template: string
+ avg_time: object
+ can_delete: boolean
+ can_edit: boolean
+ can_recover: boolean
+ can_view_edit_history: boolean
+ can_wiki: boolean
+ cooked: string
+ created_at: string
+ deleted_at: object
+ display_username: string
+ draft_sequence: number
+ edit_reason: object
+ hidden_reason_id: object
+ hidden: boolean
+ id: number
+ incoming_link_count: number
+ moderator: boolean
+ name: string
+ post_number: number
+ post_type: number
+ primary_group_flair_bg_color: object
+ primary_group_flair_color: object
+ primary_group_flair_url: object
+ primary_group_name: object
+ quote_count: number
+ reads: number
+ reply_count: number
+ reply_to_post_number: object
+ score: number
+ staff: boolean
+ topic_id: number
+ topic_slug: string
+ trust_level: number
+ updated_at: string
+ user_deleted: boolean
+ user_id: number
+ user_title: object
+ username: string
+ version: number
+ wiki: boolean
+ yours: boolean
+}
+export interface PostUpdateRequest {
+ post: {
+ raw: string
+ raw_old?: string
+ edit_reason?: string
+ cooked?: string
+ }
+}
+
+// https://docs.discourse.org/#tag/Tags/operation/listTags
+
+export interface TagsResponse {
+ tags: Tag[]
+ extras: TagsExtras
+}
+
+export interface TagsExtras {
+ categories: any[]
+}
+
+export interface Tag {
+ count: number
+ description: null
+ id: string
+ name: string
+ pm_only: boolean
+ target_tag: null
+ text: string
+}
+
+
+/** https://docs.discourse.org/#tag/Categories/paths/~1categories.json/get */
+export interface CategoriesResponse {
+ category_list: {
+ can_create_category: boolean
+ can_create_topic: boolean
+ categories: Category[]
+ draft_key: string
+ draft_sequence: number
+ draft: boolean
+ }
+}
+export interface Category {
+ background_url: string
+ can_edit: boolean
+ color: string
+ description_excerpt: string
+ description_text: string
+ description: string
+ has_children: boolean
+ id: number
+ logo_url: string
+ name: string
+ notification_level: string
+ permission: number
+ position: number
+ post_count: number
+ read_restricted: boolean
+ slug: string
+ text_color: string
+ topic_count: number
+ topic_template: string
+ topic_url: string
+ topics_all_time: number
+ topics_day: number
+ topics_month: number
+ topics_week: number
+ topics_year: number
+}
+
+/**
+ * Get Single Topic
+ * https://docs.discourse.org/#tag/Topics/paths/~1t~1{id}.json/get
+ */
+export interface TopicResponse {
+ actions_summary: Array
+ archetype: string
+ archived: boolean
+ bookmarked: object
+ category_id: number
+ chunk_size: number
+ closed: boolean
+ created_at: string
+ deleted_at: object
+ deleted_by: object
+ details: TopicDetails
+ draft_key: string
+ draft_sequence: object
+ draft: object
+ fancy_title: string
+ has_summary: boolean
+ highest_post_number: number
+ id: number
+ last_posted_at: object
+ like_count: number
+ participant_count: number
+ pinned_at: string
+ pinned_globally: boolean
+ pinned_until: object
+ pinned: boolean
+ posts_count: number
+ reply_count: number
+ slug: string
+ tags: string[] // not part of the api docs, but is there
+ title: string
+ unpinned: object
+ user_id: number
+ views: number
+ visible: boolean
+ word_count: object
+ post_stream: {
+ posts: Array
+ // not sure what this is
+ stream: Array
+ }
+ // not sure what this is
+ timeline_lookup: [
+ {
+ '0': Array
+ }
+ ]
+}
+export interface TopicDetails {
+ auto_close_at: object
+ auto_close_based_on_last_post: boolean
+ auto_close_hours: object
+ can_flag_topic: boolean
+ created_by: Person
+ last_poster: Person
+ notification_level: number
+ participants: Array
+ suggested_topics: Array
+}
+export interface TopicItem {
+ archetype: string
+ archived: boolean
+ bookmarked: object
+ bumped_at: string
+ bumped: boolean
+ category_id: number
+ closed: boolean
+ created_at: string
+ excerpt: string
+ fancy_title: string
+ has_summary: boolean
+ highest_post_number: number
+ id: number
+ image_url: string
+ last_posted_at: string
+ last_poster_username: string
+ like_count: number
+ liked: object
+ pinned_globally: boolean
+ pinned: boolean
+ posters: Array
+ posts_count: number
+ reply_count: number
+ slug: string
+ title: string
+ unpinned: boolean
+ unseen: boolean
+ views: number
+ visible: boolean
+}
+
+/**
+ * Get Topics for Category
+ * https://docs.discourse.org/#tag/Categories/paths/~1c~1{id}.json/get
+ */
+export interface CategoryResponse {
+ users: Person[]
+ topic_list: {
+ can_create_topic: boolean
+ draft: boolean
+ draft_key: string
+ draft_sequence: number
+ per_page: number
+ topics: Array
+ }
+}
+
+/**
+ * Whole Post Information
+ * As returned by getting a single Post
+ * https://docs.discourse.org/#tag/Posts/paths/~1posts~1{id}.json/get
+ */
+export interface PostResponse {
+ actions_summary: Array
+ admin: boolean
+ avatar_template: string
+ avg_time: object
+ can_delete: boolean
+ can_edit: boolean
+ can_recover: boolean
+ can_view_edit_history: boolean
+ can_wiki: boolean
+ cooked: string
+ created_at: string
+ deleted_at: object
+ display_username: string
+ edit_reason: object
+ hidden_reason_id: object
+ hidden: boolean
+ id: number
+ incoming_link_count: number
+ moderator: boolean
+ name: string
+ post_number: number
+ post_type: number
+ primary_group_flair_bg_color: object
+ primary_group_flair_color: object
+ primary_group_flair_url: object
+ primary_group_name: object
+ quote_count: number
+ raw: string
+ reads: number
+ reply_count: number
+ reply_to_post_number: object
+ score: number
+ staff: boolean
+ topic_id: number
+ topic_slug: string
+ trust_level: number
+ updated_at: string
+ user_deleted: boolean
+ user_id: number
+ user_title: object
+ username: string
+ version: number
+ wiki: boolean
+ yours: boolean
+}
+
+export interface ICreateUserResponse {
+ success: boolean;
+ active: boolean;
+ message: string;
+ user_id: number;
+ password: string;
+}
+
+
+
+/**
+ * Get the Posts of a Topic
+ * https://docs.discourse.org/#tag/Topics/paths/~1t~1{id}~1posts.json/get
+ */
+export interface PostsResponse {
+ post_stream: {
+ posts: Array
+ }
+ id: number
+}
+/**
+ * Partial Post Information
+ * As returned by a listing
+ */
+export interface PostItem {
+ accepted_answer: boolean
+ actions_summary: Array
+ admin: boolean
+ avatar_template: string
+ can_accept_answer: boolean
+ can_delete: boolean
+ can_edit: boolean
+ can_recover: boolean
+ can_unaccept_answer: boolean
+ can_view_edit_history: boolean
+ can_wiki: boolean
+ cooked: string
+ created_at: string
+ deleted_at: null
+ display_username: string
+ edit_reason: null
+ hidden: boolean
+ id: number
+ incoming_link_count: number
+ link_counts: Array
+ moderator: boolean
+ name: string
+ post_number: number
+ post_type: number
+ primary_group_flair_bg_color: null | object
+ primary_group_flair_color: null | object
+ primary_group_flair_url: null | object
+ primary_group_name: null | object
+ quote_count: number
+ read: boolean
+ readers_count: number
+ reads: number
+ reply_count: number
+ reply_to_post_number: null | number
+ reviewable_id: number
+ reviewable_score_count: number
+ reviewable_score_pending_count: number
+ score: number
+ staff: boolean
+ topic_id: number
+ topic_slug: string
+ trust_level: number
+ updated_at: string
+ user_deleted: boolean
+ user_id: number
+ user_title: null | object
+ username: string
+ version: number
+ wiki: boolean
+ yours: boolean
+}
+export type Thread = {
+ topic: TopicResponse
+ post: PostItem
+ replies: PostItem[]
+}
+
+// import { post } from 'request';
+
+/** When finding and replacing, determine replacements using a method that matches this */
+export type PostModifier = (
+ post: PostResponse
+) => { result: string; reason?: string }
+
+/** Configuration for Discourser */
+export interface IDiscourserConfig {
+ /** the discourse hostname to connect to, including protocol */
+ host: string
+ /** the API key to connect with */
+ key: string
+ /** the username to behave as */
+ username: string
+ /** the cache directory to use, if we are caching */
+ cache?: string
+ /** Whether or not we should read from the cache */
+ useCache?: boolean
+ /** whether or not updates should be dry (non-applying) */
+ dry?: boolean
+ /** how many concurrency requests to send to the server at once */
+ rateLimitConcurrency?: number
+}
+
+export interface FetchOptions {
+ /** Whether or not we should read from the cache */
+ useCache?: boolean
+ /** Only applicable to fetching topics of category */
+ page?: number
+ /** Any thing to init the fetch call with? */
+ request?: RequestInit
+
+ include_subcategories?: boolean
+}
+
+
+
+
+
+export interface FetchConfig extends FetchOptions {
+ url: string
+}
+
+export interface PostConfig extends FetchOptions {
+ url: string,
+ data: any
+}
+
+
+export interface ISearchPost {
+ id: number;
+ name: string;
+ username: string;
+ avatar_template: string;
+ created_at: Date;
+ like_count: number;
+ blurb: string;
+ post_number: number;
+ topic_id: number;
+}
+
+export interface ISearchTagsDescriptions {
+}
+
+export interface ISearchTopic {
+ id: number;
+ title: string;
+ fancy_title: string;
+ slug: string;
+ posts_count: number;
+ reply_count: number;
+ highest_post_number: number;
+ created_at: Date;
+ last_posted_at: Date;
+ bumped: boolean;
+ bumped_at: Date;
+ archetype: string;
+ unseen: boolean;
+ pinned: boolean;
+ unpinned?: any;
+ excerpt: string;
+ visible: boolean;
+ closed: boolean;
+ archived: boolean;
+ bookmarked?: any;
+ liked?: any;
+ tags: any[];
+ tags_descriptions: ISearchTagsDescriptions;
+ category_id: number;
+ has_accepted_answer: boolean;
+}
+
+export interface IGroupedSearchResult {
+ more_posts?: any;
+ more_users?: any;
+ more_categories?: any;
+ term: string;
+ search_log_id: number;
+ more_full_page_results?: any;
+ can_create_topic: boolean;
+ error?: any;
+ post_ids: number[];
+ user_ids: any[];
+ category_ids: any[];
+ tag_ids: any[];
+ group_ids: any[];
+}
+
+export interface ISearchResult {
+ posts: ISearchPost[];
+ topics: ISearchTopic[];
+ users: any[];
+ categories: any[];
+ tags: any[];
+ groups: any[];
+ grouped_search_result: IGroupedSearchResult;
+}
+
+
+export interface IUserDetail {
+ id: number
+ username: string
+ name: string
+ avatar_template: string
+ email: string
+ secondary_emails: any[]
+ active: boolean
+ admin: boolean
+ moderator: boolean
+ last_seen_at: string
+ last_emailed_at: string
+ created_at: string
+ last_seen_age: number
+ last_emailed_age: number
+ created_at_age: number
+ trust_level: number
+ manual_locked_trust_level: any
+ flag_level: number
+ title: string
+ time_read: number
+ staged: boolean
+ days_visited: number
+ posts_read_count: number
+ topics_entered: number
+ post_count: number
+ associated_accounts: AssociatedAccount[]
+ can_send_activation_email: boolean
+ can_activate: boolean
+ can_deactivate: boolean
+ ip_address: string
+ registration_ip_address: string
+ can_grant_admin: boolean
+ can_revoke_admin: boolean
+ can_grant_moderation: boolean
+ can_revoke_moderation: boolean
+ can_impersonate: boolean
+ like_count: number
+ like_given_count: number
+ topic_count: number
+ post_edits_count: number
+ flags_given_count: number
+ flags_received_count: number
+ private_topics_count: number
+ can_delete_all_posts: boolean
+ can_be_deleted: boolean
+ can_be_anonymized: boolean
+ can_be_merged: boolean
+ full_suspend_reason: any
+ silence_reason: any
+ penalty_counts: PenaltyCounts
+ next_penalty: string
+ primary_group_id: any
+ badge_count: number
+ warnings_received_count: number
+ user_fields: UserFields
+ bounce_score: number
+ reset_bounce_score_after: any
+ can_view_action_logs: boolean
+ can_disable_second_factor: boolean
+ can_delete_sso_record: boolean
+ api_key_count: number
+ external_ids: ExternalIds
+ single_sign_on_record: any
+ approved_by: ApprovedBy
+ suspended_by: any
+ silenced_by: any
+ tl3_requirements: Tl3Requirements
+ groups: Group[]
+}
+
+export interface AssociatedAccount {
+ name: string
+ description: string
+}
+
+export interface PenaltyCounts {
+ silenced: number
+ suspended: number
+}
+
+export interface UserFields {
+ "1": string
+ "2": string
+ "3": string
+ "4": string
+ "5": string
+}
+
+export interface ExternalIds {
+ google_oauth2: string
+}
+
+export interface ApprovedBy {
+ id: number
+ username: string
+ name: string
+ avatar_template: string
+}
+
+export interface Tl3Requirements {
+ time_period: number
+ requirements_met: boolean
+ requirements_lost: boolean
+ trust_level_locked: boolean
+ on_grace_period: boolean
+ days_visited: number
+ min_days_visited: number
+ num_topics_replied_to: number
+ min_topics_replied_to: number
+ topics_viewed: number
+ min_topics_viewed: number
+ posts_read: number
+ min_posts_read: number
+ topics_viewed_all_time: number
+ min_topics_viewed_all_time: number
+ posts_read_all_time: number
+ min_posts_read_all_time: number
+ num_flagged_posts: number
+ max_flagged_posts: number
+ num_flagged_by_users: number
+ max_flagged_by_users: number
+ num_likes_given: number
+ min_likes_given: number
+ num_likes_received: number
+ min_likes_received: number
+ num_likes_received_days: number
+ min_likes_received_days: number
+ num_likes_received_users: number
+ min_likes_received_users: number
+ penalty_counts: PenaltyCounts2
+}
+
+export interface PenaltyCounts2 {
+ silenced: number
+ suspended: number
+ total: number
+}
+
+export interface Group {
+ id: number
+ automatic: boolean
+ name: string
+ display_name?: string
+ user_count: number
+ mentionable_level: number
+ messageable_level: number
+ visibility_level: number
+ primary_group: boolean
+ title: any
+ grant_trust_level?: number
+ incoming_email: any
+ has_messages: boolean
+ flair_url: any
+ flair_bg_color?: string
+ flair_color?: string
+ bio_raw?: string
+ bio_cooked?: string
+ bio_excerpt?: string
+ public_admission: boolean
+ public_exit: boolean
+ allow_membership_requests: boolean
+ full_name?: string
+ default_notification_level: number
+ membership_request_template: any
+ members_visibility_level: number
+ can_see_members: boolean
+ can_admin_group: boolean
+ publish_read_state: boolean
+ can_edit_group?: boolean
+}
+
+export type TPostStatus = 'visible' | 'archived' | 'pinned' | 'closed'
+
+export interface TPostStatusUpdate {
+ success:string,
+ topic_status_update: any
+}
+
+export interface UserPreferencesUpdate {
+ bio_raw?: string
+ website?: string
+ location?: string
+ custom_fields?: CustomFields
+ timezone?: string
+ default_calendar?: string
+ // https://forum.osr-plastic.org/uploads/default/original/2X/4/476f01418c38779ac641bb45e985ad4097c7d175.jpeg
+ profile_background_upload_url?: string
+ card_background_upload_url?: string
+ }
+
+ export interface CustomFields {
+ geo_location: GeoLocation
+ }
+
+ export interface GeoLocation {
+ lat: string
+ lon: string
+ address: string
+ countrycode: string
+ city: string
+ state: string
+ country: string
+ postalcode: string
+ boundingbox: string[]
+ type: string
+ }
+
+
\ No newline at end of file
diff --git a/packages/discourse/src/lib/git/index.ts b/packages/discourse/src/lib/git/index.ts
new file mode 100644
index 00000000..c239350a
--- /dev/null
+++ b/packages/discourse/src/lib/git/index.ts
@@ -0,0 +1,42 @@
+
+import {logger} from '../../index'
+
+const GIT_CHANGELOG_MESSAGE_PREFIX = ''
+
+import * as path from 'path';
+
+import * as simpleGit from 'simple-git/promise';
+import { SimpleGit } from 'simple-git';
+import * as moment from 'moment';
+
+export async function git_status(cwd, dir) {
+
+ const git: SimpleGit = simpleGit(cwd);
+ let statusSummary:any = null;
+ try {
+ statusSummary = await git.log(['--stat', dir]);
+ }
+ catch (e) {
+ logger.error('Error Git', e);
+ }
+ return statusSummary;
+}
+
+export async function git_log(cwd, dir) {
+ const stats = await git_status(cwd, dir);
+ logger.info(`Reading Git log at ${cwd}/${dir}`);
+ let changelogs = stats.all.filter((e) => e.message.trim().toLowerCase().startsWith(GIT_CHANGELOG_MESSAGE_PREFIX.toLowerCase()));
+ if (!changelogs.length) {
+ return { files: [], last:stats.latest }
+ }
+ let pretty = changelogs.map((e) => {
+ return {
+ files: e.diff.files.map((f) => { return { path: f.file } }),
+ msg: e.message.toLowerCase().replace(GIT_CHANGELOG_MESSAGE_PREFIX.toLowerCase(), '').trim(),
+ hash: e.hash,
+ date: moment(e.date).format('LLLL')
+ }
+ });
+
+ return { files: pretty, last: stats.latest };
+};
\ No newline at end of file
diff --git a/packages/discourse/src/lib/index.ts b/packages/discourse/src/lib/index.ts
new file mode 100644
index 00000000..80bc51e3
--- /dev/null
+++ b/packages/discourse/src/lib/index.ts
@@ -0,0 +1,3 @@
+export * from './discourse'
+export * from './discourse/types'
+
diff --git a/packages/discourse/src/lib/markdown/Pattern.ts b/packages/discourse/src/lib/markdown/Pattern.ts
new file mode 100644
index 00000000..a1bfc465
--- /dev/null
+++ b/packages/discourse/src/lib/markdown/Pattern.ts
@@ -0,0 +1,13 @@
+import { RegExCallback } from './types'
+export class Pattern {
+ regex: RegExp;
+ replacement: RegExCallback
+ constructor(regex: RegExp, replacement: any) {
+ this.regex = regex
+ this.replacement = replacement
+ }
+
+ apply(raw: string): string {
+ return raw.replace(this.regex, this.replacement)
+ }
+}
diff --git a/packages/discourse/src/lib/markdown/Rule.ts b/packages/discourse/src/lib/markdown/Rule.ts
new file mode 100644
index 00000000..73c296cc
--- /dev/null
+++ b/packages/discourse/src/lib/markdown/Rule.ts
@@ -0,0 +1,17 @@
+import { Pattern } from './Pattern';
+
+export class Rule {
+ name: string;
+ patterns: Pattern[];
+ constructor(name: string, patterns: Pattern[]) {
+ this.name = name;
+ this.patterns = patterns;
+ }
+
+ apply(raw: string): string {
+ return this.patterns.reduce(
+ (result, pattern) => pattern.apply(result),
+ raw
+ );
+ }
+}
diff --git a/packages/discourse/src/lib/markdown/index.test.ts b/packages/discourse/src/lib/markdown/index.test.ts
new file mode 100644
index 00000000..929727f5
--- /dev/null
+++ b/packages/discourse/src/lib/markdown/index.test.ts
@@ -0,0 +1,144 @@
+import { Pattern, RMark, Rule } from './index';
+
+const sampleText = `# Header 1
+## Header 2
+### Header 3
+#### Header 4
+##### Header 5
+###### Header 6
+
+**Bold**
+*Italic*
+
+[Link](https://github.com/tlylt/rmark)
+
+
+This is **Bold** and this is *Italic*.
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ornare erat facilisis odio viverra gravida. Phasellus in finibus libero. Duis eget pellentesque arcu, ut lobortis mi. Praesent vitae nulla sed leo dignissim finibus eget hendrerit arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vestibulum enim nibh, eu pellentesque tellus fermentum venenatis. Nam consectetur sem a magna mattis, sed luctus purus tincidunt. Nam faucibus tellus sed ligula molestie pulvinar. Mauris facilisis felis ex, eu tempor justo commodo et. Aenean lobortis dignissim diam eget tempor.
+
+Sed pellentesque nulla sit amet tincidunt sagittis. Phasellus eget justo nulla. Cras nisi odio, lobortis nec ante eget, commodo euismod
+turpis. Cras id orci dolor. Etiam auctor, nisl luctus volutpat lacinia, turpis orci euismod magna, pharetra eleifend massa metus aliquet
+`;
+
+const sampleHtml = `
+
Header 1
+
+
+
Header 2
+
+
+
Header 3
+
+
+
Header 4
+
+
+
Header 5
+
+
+
Header 6
+
+
+
+Bold
+
+
+Italic
+
+
+
+Link
+
+
+
+
+
+
+This is Bold and this is Italic .
+
+
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ornare erat facilisis odio viverra gravida. Phasellus in finibus libero. Duis eget pellentesque arcu, ut lobortis mi. Praesent vitae nulla sed leo dignissim finibus eget hendrerit arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vestibulum enim nibh, eu pellentesque tellus fermentum venenatis. Nam consectetur sem a magna mattis, sed luctus purus tincidunt. Nam faucibus tellus sed ligula molestie pulvinar. Mauris facilisis felis ex, eu tempor justo commodo et. Aenean lobortis dignissim diam eget tempor.
+
+
+
+Sed pellentesque nulla sit amet tincidunt sagittis. Phasellus eget justo nulla. Cras nisi odio, lobortis nec ante eget, commodo euismod
+
+
+turpis. Cras id orci dolor. Etiam auctor, nisl luctus volutpat lacinia, turpis orci euismod magna, pharetra eleifend massa metus aliquet
+
+`;
+
+describe('testing index file', () => {
+ test('empty string should render nothing', () => {
+ expect(new RMark().render('')).toBe('');
+ });
+ test('should render paragraph', () => {
+ expect(
+ new RMark().render(
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'
+ )
+ ).toBe(
+ '\nLorem ipsum dolor sit amet, consectetur adipiscing elit.
\n'
+ );
+ });
+ test('should render header', () => {
+ expect(new RMark().render('# Header 1')).toBe(
+ '\n
Header 1 \n'
+ );
+ expect(new RMark().render('## Header 2')).toBe(
+ '\n
Header 2 \n'
+ );
+ expect(new RMark().render('### Header 3')).toBe(
+ '\n
Header 3 \n'
+ );
+ expect(new RMark().render('#### Header 4')).toBe(
+ '\n
Header 4 \n'
+ );
+ expect(new RMark().render('##### Header 5')).toBe(
+ '\n
Header 5 \n'
+ );
+ expect(new RMark().render('###### Header 6')).toBe(
+ '\n
Header 6 \n'
+ );
+ });
+ test('should render bold', () => {
+ expect(new RMark().render('**Bold**')).toBe('\nBold
\n');
+ expect(new RMark().render('__Bold__')).toBe('\nBold
\n');
+ expect(new RMark().render('This is **Bold**')).toBe(
+ '\nThis is Bold
\n'
+ );
+ });
+ test('should render italic', () => {
+ expect(new RMark().render('*Italic*')).toBe('\nItalic
\n');
+ expect(new RMark().render('_Italic_')).toBe('\nItalic
\n');
+ });
+ test('should render image', () => {
+ expect(
+ new RMark().render(
+ ''
+ )
+ ).toBe(
+ '\n
\n'
+ );
+ });
+ test('should render link', () => {
+ expect(new RMark().render('[Link](https://github.com)')).toBe(
+ '\nLink
\n'
+ );
+ });
+ test('should render paragraph with multiple lines', () => {
+ expect(new RMark().render(sampleText)).toBe(sampleHtml);
+ });
+ test('should work with adding rules', () => {
+ const rmark = new RMark();
+ rmark.addRule(
+ new Rule('horizontal', [
+ new Pattern(/^(-{3})/gm, ' '),
+ new Pattern(/^(_{3})/gm, ' '),
+ ])
+ );
+ expect(rmark.render('---')).toBe('\n
\n');
+ });
+});
diff --git a/packages/discourse/src/lib/markdown/index.ts b/packages/discourse/src/lib/markdown/index.ts
new file mode 100644
index 00000000..02014e13
--- /dev/null
+++ b/packages/discourse/src/lib/markdown/index.ts
@@ -0,0 +1,125 @@
+import { Rule } from './Rule'
+import { Pattern } from './Pattern'
+
+import { RMarkOptions } from './types'
+
+export const RE_IMAGES: RegExp = /\!\[([^\]]+)\]\((\S+)\)/g
+export const RE_LINKS: RegExp = /\[([^\n]+)\]\(([^\n]+)\)/g
+
+import * as markdown from 'markdown-it'
+import Token from "markdown-it/lib/token"
+import Renderer from "markdown-it/lib/renderer"
+
+const defaultRules: Rule[] = [
+ new Rule('header', [
+ new Pattern(/^#{6}\s?([^\n]+)/gm, '$1 '),
+ new Pattern(/^#{5}\s?([^\n]+)/gm, '$1 '),
+ new Pattern(/^#{4}\s?([^\n]+)/gm, '$1 '),
+ new Pattern(/^#{3}\s?([^\n]+)/gm, '$1 '),
+ new Pattern(/^#{2}\s?([^\n]+)/gm, '$1 '),
+ new Pattern(/^#{1}\s?([^\n]+)/gm, '$1 '),
+ ]),
+ new Rule('bold', [
+ new Pattern(/\*\*\s?([^\n]+)\*\*/g, '$1 '),
+ new Pattern(/\_\_\s?([^\n]+)\_\_/g, '$1 '),
+ ]),
+ new Rule('italic', [
+ new Pattern(/\*\s?([^\n]+)\*/g, '$1 '),
+ new Pattern(/\_\s?([^\n]+)\_/g, '$1 '),
+ ]),
+ new Rule('image', [
+ new Pattern(/\!\[([^\]]+)\]\((\S+)\)/g, ' '),
+ ]),
+ new Rule('link', [
+ new Pattern(
+ /\[([^\n]+)\]\(([^\n]+)\)/g,
+ '$1 '
+ ),
+ ]),
+ new Rule('paragraph', [
+ // this regex can't skip processed HTML
+ new Pattern(/([^\n]+\n?)/g, '\n$1
\n'),
+ // another possible regex that can't skip processed HTML
+ // new Pattern(/(?:^|\n)([^\n\<]+(?:\n[^\n\>]+)*)(?:\n|$)/gm, '\n$1
\n'),
+ ])
+]
+
+const defaultRulesDiscourse = (images, links) => {
+ return [
+ new Rule('image', [
+ new Pattern(RE_LINKS, images)
+ ])/*,
+ new Rule('link', [
+ new Pattern(
+ RE_LINKS,
+ links
+ )
+ ])*/
+ ]
+}
+
+export class RMark {
+
+ constructor(options: RMarkOptions) {
+ this.rules = defaultRulesDiscourse(options.images, options.links)
+ }
+
+ private rules: Rule[]
+
+ public addRuleBefore(rule: Rule, before: string): RMark {
+ const index = this.rules.findIndex((r) => r.name === before);
+ if (index !== -1) {
+ this.rules.splice(index, 0, rule);
+ }
+ return this;
+ }
+
+ public addRule(rule: Rule): RMark {
+ this.addRuleBefore(rule, 'paragraph');
+ return this;
+ }
+
+ public render(raw: string) {
+ let result = raw;
+ this.rules.forEach((rule) => {
+ result = rule.apply(result);
+ });
+ return result;
+ }
+}
+
+export { Rule } from './Rule';
+export { Pattern } from './Pattern';
+
+// export const find = (content:string, reg:RegExp) => content.match(reg)
+
+
+
+
+export const toHTML = (content) => {
+
+ const md = new markdown({
+ html: true,
+ breaks:true
+ })
+
+ return md.render(content)
+}
+
+function image_urls(input: string): string[] {
+ const regex = /https?:\/\/(?:[a-z0-9\-]+\.)+[a-z]{2,}(?:\/[^\/#\s]*)*\.(?:jpe?g|gif|png|webp)/g
+ const matches = input.match(regex)
+ return matches || []
+}
+
+function image_urls_local(input: string): string[] {
+ const regex = /\/(?:[^\/#\s]+\/)*[^\/#\s]+\.(?:jpe?g|gif|png|webp)/g
+ const matches = input.match(regex)
+ return matches || []
+}
+
+function findUploadImageUrls(input: string): string[] {
+ const regex = /upload:\/\/[^\s]+?\.(?:jpe?g|gif|png)/gi;
+ const matches = input.match(regex);
+ return matches || [];
+}
\ No newline at end of file
diff --git a/packages/discourse/src/lib/markdown/page.ts b/packages/discourse/src/lib/markdown/page.ts
new file mode 100644
index 00000000..049c2ee4
--- /dev/null
+++ b/packages/discourse/src/lib/markdown/page.ts
@@ -0,0 +1,28 @@
+import { RMark } from '.';
+
+const sampleText = `# Header 1
+## Header 2
+### Header 3
+#### Header 4
+##### Header 5
+###### Header 6
+
+**Bold**
+*Italic*
+
+[Link](https://github.com/tlylt/rmark)
+
+
+This is **Bold** and this is *Italic*.
+
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam ornare erat facilisis odio viverra gravida. Phasellus in finibus libero. Duis eget pellentesque arcu, ut lobortis mi. Praesent vitae nulla sed leo dignissim finibus eget hendrerit arcu. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc vestibulum enim nibh, eu pellentesque tellus fermentum venenatis. Nam consectetur sem a magna mattis, sed luctus purus tincidunt. Nam faucibus tellus sed ligula molestie pulvinar. Mauris facilisis felis ex, eu tempor justo commodo et. Aenean lobortis dignissim diam eget tempor.
+
+Sed pellentesque nulla sit amet tincidunt sagittis. Phasellus eget justo nulla. Cras nisi odio, lobortis nec ante eget, commodo euismod
+turpis. Cras id orci dolor. Etiam auctor, nisl luctus volutpat lacinia, turpis orci euismod magna, pharetra eleifend massa metus aliquet
+`;
+
+const page = document.getElementById('page');
+
+if (page) {
+ page.innerHTML = new RMark().render(sampleText);
+}
diff --git a/packages/discourse/src/lib/markdown/types.ts b/packages/discourse/src/lib/markdown/types.ts
new file mode 100644
index 00000000..20331a2e
--- /dev/null
+++ b/packages/discourse/src/lib/markdown/types.ts
@@ -0,0 +1,6 @@
+export type RegExCallback = (match, capture, arg1, arg2) => string
+
+export interface RMarkOptions {
+ images: RegExCallback,
+ links?: RegExCallback
+}
\ No newline at end of file
diff --git a/packages/discourse/src/lib/oa/commons.ts b/packages/discourse/src/lib/oa/commons.ts
new file mode 100644
index 00000000..fe27340c
--- /dev/null
+++ b/packages/discourse/src/lib/oa/commons.ts
@@ -0,0 +1,141 @@
+
+import { Promise as BPromise } from 'bluebird'
+import { IUploadedFileMeta } from '@plastichub/osr-commons'
+import { forward_slash } from '@plastichub/osr-cli-commons'
+
+import {
+ IOptions,
+ IImportUser,
+ IOAHowto,
+ IOACategory,
+ IOATags,
+ IOAHowtoImport
+} from '../../'
+
+import {
+ logger
+} from '../../index'
+
+import {
+ HT_CATS
+} from '../discourse/constants'
+
+
+import { Discourser } from '../index'
+import { sanitize, convert } from './lib'
+
+import * as path from 'path'
+import { sync as read } from '@plastichub/fs/read'
+import { sync as exists } from '@plastichub/fs/exists'
+
+import { sync as write } from '@plastichub/fs/write'
+
+import { resolve } from '@plastichub/osr-commons'
+
+import * as cheerio from 'cheerio'
+import { getUsers, get_user_name } from './users'
+
+import { html_beautify } from 'js-beautify'
+import { Converter } from 'showdown'
+var escapeHtml = require('escape-html');
+import { sync as mkdir } from '@plastichub/fs/dir'
+import { files } from '@plastichub/osr-cli-commons'
+const pretty = require('pretty')
+
+
+const TEST = false
+
+export const DEFAULT_HT_CATEGORY = {
+ "_modified": "2022-09-18T08:51:47.196Z",
+ "label": "Guides",
+ "_id": "CrZjHORWfxEl6iDrrPIO",
+ "_created": "2022-09-18T08:51:47.196Z",
+ "_deleted": false
+}
+
+
+export const LATEST_TRACK = '${OSR_ROOT}/oa-data/howtos/latest_track.json'
+export const LATEST_TEST = './latest_test.json'
+
+export const DEFAULT_USER = 'katharinaelleke'
+
+export const getDataPath = (_path = '') => path.resolve(path.join(resolve('${OSR_ROOT}/oa-data/howtos/'), _path))
+export const getHowtosPath = () => path.resolve(resolve(TEST ? LATEST_TEST : LATEST_TRACK))
+export const getHowtos = () => (read(path.resolve(getHowtosPath()), 'json') as any) as IOAHowtoImport[] || []
+
+export const read_howtos = (src: string): IOAHowtoImport[] => {
+ const raw = read(src, 'json') as any
+ return raw.v3_howtos
+}
+
+export const read_categories = (src: string): IOACategory[] => {
+ const raw = read(src, 'json') as any
+ return raw.v3_categories
+}
+
+export const read_tags = (src: string): IOATags[] => {
+ const raw = read(src, 'json') as any
+ return raw.v3_tags
+}
+
+export const filter_valid = (users: IOAHowtoImport[]) => {
+ return users.filter((user) => {
+ if(user.title==='Build a Fishing Canoe'){
+ //debugger
+ }
+ if (user.moderation.toLowerCase() !== 'accepted') {
+ return false
+ }
+ return true;
+ })
+}
+
+export const kb_howto_folder = (howto) => path.resolve(path.join(resolve("${KB_ROOT}/src/howtos/"), howto.slug))
+export const kb_howto_file = (howto, filename) => path.resolve(path.join(resolve("${KB_ROOT}/src/howtos/"), howto.slug, sanitize(filename)))
+
+export const getHowtoUser = (howto: IOAHowto) => {
+ const users = getUsers()
+ let user = users.find((u) => u._id == howto._createdBy)
+ if (user && user.f_id) {
+ return user
+ } else {
+ user = users.find((u) => u._id == DEFAULT_USER)
+ if (user && user.f_id) {
+ console.error('using default user : ' + DEFAULT_USER + ' : for' + howto.slug)
+ return user
+ }
+ }
+}
+
+export const toMDImage = (image: IUploadedFileMeta) => ``
+
+export const md_edit_wrap = (content, f, prefix = '', context = '') =>
+ html_beautify(`${content}
`)
+
+export const removeEmojis = (string) => {
+ return string.replace(/([#0-9]\u20E3)|[\xA9\xAE\u203C\u2047-\u2049\u2122\u2139\u3030\u303D\u3297\u3299][\uFE00-\uFEFF]?|[\u2190-\u21FF][\uFE00-\uFEFF]?|[\u2300-\u23FF][\uFE00-\uFEFF]?|[\u2460-\u24FF][\uFE00-\uFEFF]?|[\u25A0-\u25FF][\uFE00-\uFEFF]?|[\u2600-\u27BF][\uFE00-\uFEFF]?|[\u2900-\u297F][\uFE00-\uFEFF]?|[\u2B00-\u2BF0][\uFE00-\uFEFF]?|(?:\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDEFF])[\uFE00-\uFEFF]?/g, '');
+}
+
+export const toHTML = (path, markdown) => {
+ const content = read(path, 'string') as string;
+ if (!markdown) {
+ let converter = new Converter({ tables: true });
+ converter.setOption('literalMidWordUnderscores', 'true');
+ return converter.makeHtml(content);
+ } else {
+ return content;
+ }
+}
+
+export const createTextLinks_ = (text) => {
+ return (text || "").replace(
+ /([^\S]|^)(((https?\:\/\/)|(www\.))(\S+))/gi,
+ function (match, space, url) {
+ var hyperlink = url
+ if (!hyperlink.match('^https?:\/\/')) {
+ hyperlink = 'http://' + hyperlink
+ }
+ return space + '' + url + ' '
+ }
+ )
+}
\ No newline at end of file
diff --git a/packages/discourse/src/lib/oa/howtos.ts b/packages/discourse/src/lib/oa/howtos.ts
new file mode 100644
index 00000000..55e81b56
--- /dev/null
+++ b/packages/discourse/src/lib/oa/howtos.ts
@@ -0,0 +1,607 @@
+import { Promise as BPromise } from 'bluebird'
+import { IUploadedFileMeta } from '@plastichub/osr-commons'
+import { forward_slash } from '@plastichub/osr-cli-commons'
+import { resolveConfig } from '@plastichub/core'
+import { substitute } from '@plastichub/core/strings'
+
+import {
+ IOptions,
+ IImportUser,
+ IOAHowto,
+ IOACategory,
+ IOATags,
+ IOAHowtoImport
+} from '../../'
+
+import {
+ logger
+} from '../../index'
+
+import {
+ HT_CATS
+} from '../discourse/constants'
+
+
+import { Discourser } from '../index'
+import { sanitize, convert } from './lib'
+
+import * as path from 'path'
+import { sync as read } from '@plastichub/fs/read'
+import { sync as exists } from '@plastichub/fs/exists'
+
+import { sync as write } from '@plastichub/fs/write'
+
+import { resolve } from '@plastichub/osr-commons'
+
+import * as cheerio from 'cheerio'
+import { getUsers, get_user_name } from './users'
+
+var escapeHtml = require('escape-html');
+import { sync as mkdir } from '@plastichub/fs/dir'
+import { files } from '@plastichub/osr-cli-commons'
+
+import * as moment from 'moment'
+
+const FUCKING_TOKEN = 'j7oYrkQe5nbnikCNHcfoP2DGtXKV4iHHzDFip8gGatS145g3B65UU6mI09KeFday9mY5HNQnU2jXUTe7LLkP-w'
+
+import {
+ read_categories,
+ kb_howto_file,
+ kb_howto_folder,
+ getHowtos,
+ getHowtosPath,
+ getHowtoUser,
+ md_edit_wrap,
+ toHTML,
+ toMDImage,
+ createTextLinks_,
+ removeEmojis,
+ DEFAULT_HT_CATEGORY,
+ read_tags
+} from './commons'
+
+export const mergeLatest = (discorse, options: IOptions, oa_howtos: IOAHowtoImport[]): IOAHowtoImport[] => {
+
+ const howtos: any[] = getHowtos()
+ oa_howtos.forEach((h) => {
+ const howto = howtos.find((tu) => {
+ return tu._id === h._id
+ })
+ if (!howto) {
+ howtos.push(h)
+ }
+
+ })
+ write(getHowtosPath(), howtos)
+ return howtos
+}
+
+const updateHowtoFile = (howto) => {
+ const howtos: any[] = getHowtos()
+ const index = howtos.findIndex((u) => u._id == howto._id)
+ howtos[index] = howto
+ write(getHowtosPath(), howtos)
+}
+
+
+const uploadImage = async (discourse: Discourser, user: IImportUser, image: IUploadedFileMeta, localPath) => {
+ if (image.data) {
+ return image
+ }
+ logger.debug('uploading image:', image.name)
+ const upped: any = await discourse.uploadFile(user.f_id, localPath)
+ const data = upped.data;
+ if (data && data.id) {
+ image.data = data
+ } else {
+ logger.error('error uploading image')
+ }
+ return image
+}
+
+
+export const read_fragments = (src, config, prefix = '', context = '') => {
+ if (!exists(src)) {
+ mkdir(src);
+ }
+ let fragments = files(src, '*.html');
+ fragments.map((f) => {
+ config[path.parse(f).name] = md_edit_wrap(toHTML(f, true), f, prefix, context);
+ });
+
+ fragments = files(src, '*.md');
+ fragments.map((f) => {
+ config[path.parse(f).name] = md_edit_wrap(toHTML(f, false), f, prefix, context);
+ });
+ return config;
+}
+
+export async function howto_content(howto: IOAHowtoImport, folder: string, fragments, templates: any) {
+
+ //const tags = data.v3_tags;
+ const howtoTags = [];
+ /*
+ for (const ht in howto.tags) {
+ const gt = tags.find((t) => t._id === ht);
+ if (gt) {
+ howtoTags.push(gt.label);
+ // logger.debug('resolved ' + ht + ' to ' + gt.label);
+ } else {
+ // logger.error('Cant resolve tag : ' + ht);
+ }
+ }
+*/
+
+ howto.slug = howto.slug.trim();
+
+ let s: string = '';
+
+ let step_template = "" + templates.step;
+
+ let invalid_step_images = false
+
+ const step_image = (i: IUploadedFileMeta) => {
+ if (!i.data || !i.data.short_url) {
+ logger.error('invalid image : ' + i.downloadUrl + ' : ' + howto.slug)
+ invalid_step_images = true
+ return '\n'
+ }
+ return `\n${toMDImage(i)}`
+ }
+
+ const step_file = (i) => {
+ const image = `/howtos/${howto.slug}/${encodeURIComponent(sanitize(i.name))}`;
+ return ``
+ }
+
+ const step_files = (s) => {
+ const files = s.files.map(step_file).join('\n');
+ return `
+ ${files}
+
+ `
+ }
+
+ const step_images = (s) => {
+ const images = s.images.map(step_image).join('\n');
+ return `${images}`
+ }
+
+ const step_images_gallery = (s) => {
+ const images = s.images.map(step_image).join('');
+ return `\n${images}
`
+ }
+
+ const step = (s, i) => {
+ const t = substitute(step_template, {
+ title: s.title,
+ text: createTextLinks_(escapeHtml(s.text.trim()).replace(/(?:\r\n|\r|\n)/g, '\n\n')),
+ step_number: i + 1,
+ images: s.images.length > 1 ? step_images_gallery(s) : step_images(s)
+ });
+ return t;
+ }
+
+ const steps = howto.steps.map((s, i) => step(s, i)).join('\n\n');
+
+ const attachments = howto.files.map((f) => {
+ return `[${sanitize(f.name)}](${f.downloadUrl})`
+ })
+
+ howto.description = removeEmojis(howto.description);
+ howto.description = createTextLinks_(howto.description);
+
+ let authorName = (howto.user && howto.user.data && howto.user.data && howto.user.data.title) ? howto.user.data.title : (howto.user ? howto.user._id : 'OSR-Plastic');
+ if (authorName === 'Precious Plastic Headquarters') {
+ authorName = 'Precious Plastic Nantes';
+ }
+
+ let _3dFiles: any = [...files(path.resolve(`${folder}`), '**/**/*.step'), ...files(path.resolve(`${folder}`), '**/**/*.STEP'), ...files(path.resolve(`${folder}`), '**/**/*.stp')];
+
+ _3dFiles = _3dFiles.map((f) => {
+ return forward_slash(`${howto.slug}/${path.relative(path.resolve(folder), f)}`);
+ })
+
+ let previews = '';
+ if (_3dFiles.length) {
+ previews += '';
+ previews += '
';
+
+ _3dFiles = _3dFiles.map((f) => {
+ return `
+
+ 3D Step File: ${f.replace(howto.slug, '')} -
+
+ Preview
+
+ `
+ })
+
+ previews += _3dFiles.join('');
+ previews += ' ';
+ }
+
+ if (invalid_step_images) {
+ return false
+ }
+
+ let index = substitute(templates.howto, {
+ ...fragments,
+ image: `/howtos/${howto.slug}/${encodeURIComponent(sanitize(howto.cover_image.name))}`,
+ title: howto.title.trim(),
+ description: escapeHtml(howto.description.trim()) || "",
+ enabled: howto.moderation == "accepted" ? true : false,
+ steps: steps,
+ keywords: ['Precious plastic', 'Preciousplastic', 'plastichub', 'osr', ...howtoTags].join(','),
+ user: howto._createdBy,
+ files: `${attachments.join('\n')}`,
+ authorName: authorName,
+ authorUrl: `https://osr-plastic.org/users/${howto.user ? howto.user._id : 'https://osr-plastic.org/users/plastichub'}.html`,
+ // short: escapeHtml(howto.description.trim()).substring(0, 100) + '....',
+ slug: howto.slug,
+ previews3D: previews
+ });
+
+ const $ = cheerio.load(index as string, {
+ xmlMode: true
+ });
+
+ /*
+ $('a').each(function () {
+ const url = $(this).attr("href");
+ logger.debug('url : ' + url);
+ if(url.indexOf('dropbox')){
+
+ }
+ });*/
+
+ //write(index_md, pretty(index, { ocd: true }));
+
+ return removeEmojis(index)
+
+}
+
+export const createHowtoTopic = async (discourse, howto: IOAHowtoImport, create = true) => {
+
+ if (!howto.category || !howto.category.label) {
+ howto.category = DEFAULT_HT_CATEGORY
+ logger.error(`create howto : invalid category: ${howto.category} : ${howto.slug}`)
+ }
+
+ const user = getHowtoUser(howto)
+ if (!user) {
+ logger.error(`create howto : invalid user : ${howto._createdBy} :: ${howto.title}`)
+ }
+
+ const howto_folder = kb_howto_folder(howto)
+
+ const howto_cover_image = kb_howto_file(howto, howto.cover_image.name)
+
+ if (!exists(howto_folder)) {
+ logger.error('howto folder doesnt exists', howto.title)
+ }
+
+ if (!exists(howto_cover_image)) {
+ logger.error('howto cover image doesnt exists', howto.title)
+ }
+
+ if (!user || !user.f_id) {
+ logger.error(`create howto : invalid user : ${howto._createdBy} :: ${howto.title}`)
+ return false
+ }
+
+ howto.cover_image = await uploadImage(discourse, user, howto.cover_image, howto_cover_image)
+
+ updateHowtoFile(howto)
+
+ let invalid_images = false
+
+ for (const step of howto.steps) {
+ let i = 0
+ for await (const image of step.images) {
+ const image_name = sanitize(image.name)
+
+ const imagePath = path.resolve(path.join(howto_folder, sanitize(image_name)))
+
+ if (!exists(imagePath)) {
+ logger.error('step image doesnt exists : ' + image.name + ' in ' + howto.slug)
+ invalid_images = true
+ continue
+ }
+
+ step.images[i] = await uploadImage(discourse, user, step.images[i], imagePath)
+ updateHowtoFile(howto)
+ i++
+ }
+ }
+
+ if (invalid_images) {
+ logger.error('invalid images : ' + howto.slug)
+ return false
+ }
+
+ const cat = HT_CATS[howto.category.label]
+
+ if (!cat) {
+ logger.error('invalid kat')
+ return false
+ }
+
+ const templatesRoot = path.resolve(resolve("${OSR_ROOT}/osr-templates/discourse"))
+ const cPath = path.resolve(`${templatesRoot}/base.json`)
+
+ logger.debug(`read config at ${cPath}`)
+
+ const config = read(cPath, 'json') as any
+
+ const templates = path.resolve(`${templatesRoot}/howto`)
+
+ if (!exists(templates)) {
+ logger.error(`\t Cant find templates at ${templates}, path doesn't exists`)
+ return;
+ }
+
+ let fragments: any = { ...config.variables }
+
+ read_fragments(templates, fragments, "product_rel_path_name", "machine")
+
+ let template = read(path.resolve(`${templates}/howto.md`), 'string')
+
+ let step = read(path.resolve(`${templates}/step.md`), 'string')
+
+ resolveConfig(fragments);
+
+ const content = await howto_content(
+ howto,
+ howto_folder,
+ fragments,
+ {
+ howto: template,
+ step: '' + step
+ });
+
+ if (!content) {
+ logger.error('invalid content : ' + howto.slug)
+ return
+ }
+
+ let data
+ if (create) {
+ data = await discourse.createPost(sanitize(howto.title), content, cat);
+ if (data) {
+ logger.debug('created topic : ' + howto.title + ' : ' + data.id);
+ if (data && data.id) {
+ howto.post_id = data.id;
+ howto.topic_id = data.topic_id
+ updateHowtoFile(howto)
+ try {
+ logger.debug('change user to ', user._id)
+ await discourse.changeOwner(howto.post_id, howto.topic_id, get_user_name(user));
+ } catch (e) {
+ logger.debug('changing owner ' + howto.title + ' failed!');
+ howto.oF = true;
+ updateHowtoFile(howto)
+ }
+ } else {
+ logger.debug('creating ' + howto.title + ' failed!', data.errors);
+ howto.post_id = 'failed';
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ logger.error('title already used : ' + howto.slug)
+ howto.post_id = 'already';
+ }
+ }
+ updateHowtoFile(howto)
+ }
+ }
+ } else {
+ data = await discourse.updatePost(howto.post_id, content)
+ howto._updatedContent1 = true
+ updateHowtoFile(howto)
+ }
+}
+
+
+
+export const importHowto = async (discorse, howto: IOAHowtoImport) => {
+ //const howtos = getHowtos()
+ //const index = howtos.findIndex((u) => u._id == howto._id)
+ const ret = await createHowtoTopic(discorse, howto)
+ return ret
+}
+
+export const importHowtos = async (discorse, options: IOptions, howtos: IOAHowtoImport[]) => {
+
+ logger.debug('read howtos from ', path.resolve(getHowtosPath()))
+
+ howtos = mergeLatest(discorse, options, howtos)
+
+ howtos = howtos.filter((h) => {
+
+ if (h.title === 'Build a Fishing Canoe') {
+ //debugger
+ }
+
+ if (h.post_id || h.post_id as number < 0) {
+ return false;
+ }
+
+ if (h.post_id === 'failed') {
+ logger.debug('skip failed : ' + h.slug)
+ return false
+ }
+
+ //if (u.alreadyExists || u.invalidData) {
+ // return false;
+ //}
+ return true
+ })
+
+ return await BPromise.resolve(howtos).map((h: IOAHowtoImport) => {
+ try {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ const d = importHowto(discorse, h)
+ if (d) {
+ d.then(resolve)
+ } else {
+ reject()
+ }
+ }, 500)
+
+ })
+
+ } catch (e) {
+ debugger;
+ logger.error('error creating howto ' + h._id, e)
+ }
+ }, { concurrency: 1 })
+}
+
+/////////////////////////////////////////////////////////////////////////
+//
+// Update Howtos
+//
+let _discorseTags
+
+const getDiscourseTags = async (discourse: Discourser) => {
+ if (!_discorseTags) {
+ _discorseTags = await discourse.getTags()
+ }
+
+ return _discorseTags
+}
+
+export const updateHowto = async (discourse: Discourser, howto: IOAHowtoImport, options: IOptions) => {
+
+ const tags = read_tags(options.src)
+ let howtoTags = []
+
+ for (const ht in howto.tags) {
+ const t = ht
+ const gt = tags.find((t: any) => {
+ return t._id === ht
+ });
+ if (gt) {
+ howtoTags.push(gt.label);
+ } else {
+ // logger.error('Cant resolve tag : ' + ht);
+ }
+ }
+
+ howtoTags.push('oa-import')
+
+ let discorseTags = await getDiscourseTags(discourse)
+
+ const cat = HT_CATS[howto.category.label]
+
+ if (howtoTags && howtoTags.length) {
+ try {
+ const ret = await discourse.updateTopic(howto.topic_id, cat as number, sanitize(howto.title), howtoTags)
+ logger.debug('Updating howto tags : ' + howto.title)
+ } catch (error) {
+ logger.error('Error updating post' + howto.title, howto.topic_id, cat, howtoTags,error)
+ howto['updateFailed1']=1
+ updateHowtoFile(howto)
+ //debugger
+ }
+
+ }
+ howto.updatedTags = true
+ updateHowtoFile(howto)
+
+ const _date = howto._modified || howto._created
+
+ if (_date) {
+ let date: Date = new Date(_date)
+ logger.debug('update ts ' + howto.slug + ' : ' + new Date(date).toLocaleDateString())
+ let offset = 0
+ const valueOf = date.valueOf() - (offset) * 60000
+ let ts = Math.floor(valueOf / 1000)
+ const tUpdate = await discourse.updateTopicTimestamp(howto.topic_id, ts, FUCKING_TOKEN)
+ if (tUpdate) {
+ howto.updatedTime8 = true
+ updateHowtoFile(howto)
+ return true
+ }
+ } else {
+ logger.error('Have no ts : ' + howto.slug)
+ }
+}
+
+export const updateHowtos = async (discorse, options: IOptions, howtos: IOAHowtoImport[]) => {
+
+ logger.debug('update howtos from ', path.resolve(getHowtosPath()))
+
+ howtos = mergeLatest(discorse, options, howtos)
+
+ const forceUpdateContent = true
+ const forceUpdateMeta = true
+
+ const updateContent = true
+ const updateMeta = true
+
+ howtos = howtos.filter((h) => {
+
+ if (!h.post_id || !h.topic_id) {
+ return false
+ }
+
+ if (h.post_id === 'failed') {
+ logger.debug('skip failed : ' + h.slug)
+ return false
+ }
+
+ if (forceUpdateContent || forceUpdateMeta) {
+ return true
+ }
+
+ if (!h._updatedContent1) {
+ return true
+ }
+
+ if (h.updatedTags && h.updatedTime8) {
+ return false
+ }
+
+ if (!h.updatedTags || !h.updatedTime8) {
+ return true
+ }
+
+ return true
+ })
+
+ return await BPromise.resolve(howtos).map((h: IOAHowtoImport) => {
+ try {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ if (updateContent) {
+ logger.debug('\t recook howto content', h.title)
+ let d = createHowtoTopic(discorse, h, false)
+ d.then(() => {
+ if (updateMeta) {
+ d = updateHowto(discorse, h, options)
+ if (d) {
+ d.then(resolve)
+ } else {
+ reject()
+ }
+ } else {
+ resolve(1)
+ }
+ })
+ }
+ }, 500)
+ })
+
+ } catch (e) {
+ debugger;
+ logger.error('error creating howto ' + h._id, e)
+ }
+ }, { concurrency: 1 })
+}
\ No newline at end of file
diff --git a/packages/discourse/src/lib/oa/index.ts b/packages/discourse/src/lib/oa/index.ts
new file mode 100644
index 00000000..1e889f46
--- /dev/null
+++ b/packages/discourse/src/lib/oa/index.ts
@@ -0,0 +1,4 @@
+export * from './lib'
+export * from './users'
+export * from './types'
+
diff --git a/packages/discourse/src/lib/oa/lib.ts b/packages/discourse/src/lib/oa/lib.ts
new file mode 100644
index 00000000..de5db8dd
--- /dev/null
+++ b/packages/discourse/src/lib/oa/lib.ts
@@ -0,0 +1,194 @@
+const _sanitize = require("sanitize-filename")
+const URI = require("uri-js")
+import * as path from 'path'
+const filenamify = require('filenamify')
+var TurndownService = require('turndown');
+export const sanitize = (f) => {
+ let str: string = filenamify(_sanitize(f)).replace(/[^\x00-\x7F]/g, "");
+ if (str.startsWith('_')) {
+ str = str.substring(1)
+ }
+ return str
+}
+
+
+export const getImageName = (url) => {
+ const parsed = URI.parse(decodeURIComponent(url));
+ const pParsed = path.parse(parsed.path);
+ const fileName = sanitize(decodeURIComponent(pParsed.base))
+ return fileName
+}
+
+export const convert = (input: string) => {
+ var turndownService = new TurndownService()
+ return turndownService.turndown(input);
+}
+
+/*
+
+
+const getFUser = (users, user_name) => {
+ return users.find((u) => {
+ return u.name == user_name
+ })
+}
+
+
+const indexUsers = async (d, forum: string, detail) => {
+
+ const forumUsers = await getForumUsers(d, detail)
+ const raw = (read(path.resolve(forum + '/index.json'), 'json') as any)
+ const users_raw = raw.users
+ let users = []
+ for (let u in users_raw) {
+ const user = users_raw[u];
+ const avatar = getOAvatar(raw, u);
+ let aFileName = '';
+ let fUser = getFUser(forumUsers, u);
+ if (avatar) {
+ const parsed = URI.parse(avatar);
+ const pParsed = path.parse(parsed.path);
+ aFileName = pParsed.base;
+ }
+ users.push({
+ name: u,
+ avatar: avatar,
+ avatarFileName: aFileName,
+ user_id: fUser ? fUser.id : -1
+ });
+ }
+ write(path.resolve(forum + '/user.json'), users);
+}
+
+const _createUser = async (discorse, forum, name, email) => {
+
+ const users = getUsers()
+ const index = users.findIndex((u) => u.detail.name == name)
+ let user = await createUser(discorse, null)
+
+
+ if (user && users[index].upload_id) {
+ await discorse.setUserAvatar(name, users[index].upload_id);
+ //return users;
+ }
+
+ if (user > 0 && index) {
+ users[index].f_id = user;
+ console.log('created ' + name + ' ' + user);
+ write(getUsersPath(), users);
+ } else {
+ console.error('cant create user - error', name, user)
+ }
+}
+
+
+const _updateGroup = async (discorse, forum, name, id, forumUsers) => {
+ const users = (read(path.resolve(forum + '/user.json'), 'json') as any);
+ const index = users.findIndex((u) => u.name == name);
+ try {
+ const d = await discorse.updateGroup(name, pUserGroup);
+ console.log('updated user group for ' + name);
+ users[index].g_id = pUserGroup;
+ write(path.resolve(forum + '/user.json'), users);
+ if (users[index].upload_id) {
+ //await discorse.setUserAvatar(name, users[index].upload_id);
+ }
+ } catch (e) {
+ if (e.data && e.data.status == 422) {
+ users[index].g_id = pUserGroup;
+ write(path.resolve(forum + '/user.json'), users);
+ console.log('updated user group for ' + name);
+ }
+ }
+}
+
+const _updateAvatar = async (discorse, forum, name) => {
+ const users = (read(path.resolve(forum + '/user.json'), 'json') as any);
+ const index = users.findIndex((u) => u.name == name);
+ return new Promise((resolve, reject) => {
+ try {
+ setTimeout(() => {
+ discorse.setUserAvatar(name, users[index].upload_id).then(() => {
+ console.log('updated avatar for ' + name);
+ users[index].avatarSet = true;
+ write(path.resolve(forum + '/user.json'), users);
+ resolve(1);
+ });
+ }, 200);
+ } catch (e) {
+ console.error('-error setting avatar', e);
+ debugger;
+ }
+ });
+}
+
+
+const createUsers = async (d, forum) => {
+
+ const forumUsers = await getForumUsers(d, true)
+ const users = (read(path.resolve(forum + '/user.json'), 'json') as any);
+ const toBeCreated = users.filter((u) => {
+ if (u.f_id || u.f_id < 0) {
+ return false;
+ }
+ if (u.name === 'plastichub' || u.name === 'lu' || u.name === 'timberstar' || u.name === 'nickname') {
+ return false
+ }
+ return true;
+ });
+
+ console.log('Create Users ' + users.length + ' Total | Left: ' + toBeCreated.length);
+
+ return await BPromise.resolve(toBeCreated).map((u: any) => {
+ const t = _createUser(d, forum, u.name, u.email);
+ return t;
+ }, { concurrency: 1 })
+
+}
+
+const updateUserGroups = async (forum) => {
+ const forumUsers = (read(path.resolve(forum + '/fusers.json'), 'json') as any);
+ const users = (read(path.resolve(forum + '/user.json'), 'json') as any);
+ const toBeUpdated = users.filter((u) => {
+ if (u.g_id) {
+ return false;
+ }
+ if (u.name === 'plastichub' || u.name === 'lu' || u.name === 'timberstar' || u.name === 'nickname') {
+ return false
+ }
+ return true;
+ });
+ const d = getDiscourse();
+ console.log('Update Users ' + users.length + ' Total | Left: ' + toBeUpdated.length);
+ return await BPromise.resolve(toBeUpdated).map((u: any) => {
+ const t = _updateGroup(d, forum, u.name, u.f_id, forumUsers);
+ return t;
+ }, { concurrency: 1 })
+
+}
+
+const updateUserAvatars = async (forum) => {
+ const users = (read(path.resolve(forum + '/user.json'), 'json') as any);
+ const toBeUpdated = users.filter((u) => {
+ if (!u.upload_id) {
+ return false;
+ }
+
+ if (u.avatarSet) {
+ return false;
+ }
+
+ if (u.name === 'plastichub' || u.name === 'lu' || u.name === 'timberstar' || u.name === 'nickname') {
+ return false
+ }
+ return true;
+ });
+ const d = getDiscourse();
+ console.log('Update User Avatar ' + users.length + ' Total | Left: ' + toBeUpdated.length);
+ return await BPromise.resolve(toBeUpdated).map((u: any) => {
+ const t = _updateAvatar(d, forum, u.name);
+ return t;
+ }, { concurrency: 1 })
+
+}
+*/
\ No newline at end of file
diff --git a/packages/discourse/src/lib/oa/types.ts b/packages/discourse/src/lib/oa/types.ts
new file mode 100644
index 00000000..a7c99c4a
--- /dev/null
+++ b/packages/discourse/src/lib/oa/types.ts
@@ -0,0 +1,120 @@
+import {
+ IImage,
+ IModerationStatus,
+ IOpeningHours,
+ IConvertedFileMeta,
+ IModerable,
+ IPlasticType,
+ IUploadedFileMeta,
+ I_OSR_USER
+} from '@plastichub/osr-commons'
+
+
+
+/// Taxonomy
+export interface IOACategory {
+ _created: string
+ _id: string
+ _deleted: boolean
+ label: string
+ _modified: string
+}
+
+export interface IOATag {
+ categories: string[]
+ image: string
+ _created: string
+ _deleted: boolean
+ label: string
+ _createdBy: string
+ _modified: string
+ _id: string
+}
+
+// Howtos
+
+export type IOADifficultyLevel = 'Easy' | 'Medium' | 'Hard' | 'Very Hard'
+
+export interface IDImage {
+ id: number
+ url: string
+ original_filename: string
+ filesize: number
+ width: number
+ height: number
+ thumbnail_width: number
+ thumbnail_height: number
+ extension: string
+ short_url: string
+ short_path: string
+ retain_hours: any
+ human_filesize: string
+ }
+
+
+export interface IOAHowto {
+ moderation: string
+ category: IOACategory
+ previousSlugs: string[]
+ total_downloads: number
+ _createdBy: string
+ slug: string
+ cover_image: IUploadedFileMeta
+ _modified: string
+ files: any[]
+ description: string
+ mentions: any[]
+ time: string
+ _created: string
+ fileLink: string
+ steps: IOAStep[]
+ creatorCountry: string
+ title: string
+ tags: IOATags
+ _id: string
+ _deleted: boolean
+ total_views: number
+ difficulty_level: IOADifficultyLevel
+ comments: any[]
+ user: IImportUser
+ pics?:string[]
+}
+
+export interface IOAStep {
+ _animationKey: string
+ images: IUploadedFileMeta[]
+ text: string
+ title: string
+}
+export interface IOATags {
+ [key: string]: boolean
+}
+
+
+export type IOAHowtoImport = IOAHowto &
+{
+ post_id?:number | string
+ topic_id?:number
+ oF?:boolean
+ updatedTags?:boolean
+
+ updatedTime8?:boolean
+ _updatedContent1? : boolean
+
+}
+
+
+export interface IImportUser extends I_OSR_USER {
+ f_id: number
+ upload_id: number
+ avatar: string
+ _didSetAvatar: boolean
+ _didSetGroup: boolean
+ alreadyExists: boolean
+ invalidData: boolean
+ didUpdateName: boolean
+
+ profileHeader?: IDImage
+ cardBackground?: IDImage
+ avatarImage?: IDImage
+}
\ No newline at end of file
diff --git a/packages/discourse/src/lib/oa/users.ts b/packages/discourse/src/lib/oa/users.ts
new file mode 100644
index 00000000..b0887cf4
--- /dev/null
+++ b/packages/discourse/src/lib/oa/users.ts
@@ -0,0 +1,1090 @@
+
+import { Promise as BPromise } from 'bluebird'
+import { I_OSR_USER } from '@plastichub/osr-commons'
+
+import { IOptions, IImportUser, IDiscourseUser } from '../../'
+import { Discourser } from '../index'
+import { getImageName, sanitize } from './lib'
+
+import { capitalize, replace, replaceAll } from '@plastichub/core/utils'
+import * as path from 'path'
+import { sync as read } from '@plastichub/fs/read'
+import { sync as exists } from '@plastichub/fs/exists'
+import { sync as write } from '@plastichub/fs/write'
+
+import { resolve } from '@plastichub/osr-commons'
+
+import { logger } from '../../index'
+
+const slugify = require('slugify')
+
+import { resolveConfig, substitute } from '@plastichub/core'
+
+import { html_beautify } from 'js-beautify'
+import { sync as mkdir } from '@plastichub/fs/dir'
+import { files, forward_slash } from '@plastichub/osr-cli-commons'
+import { Converter } from 'showdown'
+const URI = require("uri-js")
+
+import {
+ OA_USER_IMPORT_GROUP,
+ LATEST_TEST,
+ LATEST_TRACK,
+ FETCH_DUSERS,
+ F_USERS_ALL,
+ F_USERS_NOW,
+ DEFAULT_PASSWORD,
+ DATA_PATH,
+ HT_CATS,
+ OA_DIRECTORY_OVERVIEW_TOPIC
+} from '../discourse/constants'
+
+import { IOSRConfig } from '@plastichub/osr-cli-commons'
+
+
+const filenamify = require('filenamify')
+const fg = require('fast-glob')
+
+
+const TEST = false
+
+
+
+export const read_users = (src: string): I_OSR_USER[] => {
+ const raw = read(src, 'json') as any
+ return raw.v3_mappins.filter((f) => f.data != null)
+}
+
+export const filter_valid = (users: IImportUser[]) => {
+ return users.filter((user) => {
+ if (!user.data) {
+ return false
+ }
+ if (!user.geo) {
+ return false
+ }
+
+ if (!user.data.urls) {
+ return false
+ }
+
+ if (!user.data.title) {
+ return false
+ }
+
+ if (!user.detail) {
+ return false
+ }
+
+ if (!user.detail.heroImageUrl) {
+ return false
+ }
+
+ if (user.data && user.data.jsError) {
+ return false
+ }
+
+ if (user.moderation !== 'accepted') {
+ //return false
+ }
+
+ return true;
+ })
+}
+
+export const filter_email_only = (users: any[]) => {
+ return users.filter((user) => {
+ if (!user.data) {
+ return false;
+ }
+ if (!user.geo) {
+ return false;
+ }
+ if (!user.data.urls) {
+ return false;
+ }
+ if (user.data && user.data.jsError) {
+ return false;
+ }
+
+ if (!user.detail) {
+ return false
+ }
+
+ if (!user.detail.name) {
+ return false
+ }
+
+ if (user.data.urls.find((l) => l.name == 'Email') == undefined) {
+ return false;
+ }
+ return true;
+ })
+}
+
+export const filter_invalid = (users: any[]) => {
+
+ return users.filter((user) => {
+ if (!user.data) {
+ return false;
+ }
+ if (!user.geo) {
+ return false;
+ }
+ if (!user.data.urls) {
+ return false;
+ }
+ if (user.data && user.data.jsError) {
+ return false;
+ }
+
+
+ if (!user.detail.name) {
+ return true
+ }
+
+ if (user.data.urls.find((l) => l.name == 'Email') == undefined) {
+ return true;
+ }
+
+ if (user.moderation !== 'accepted') {
+ return true;
+ }
+
+ return false;
+ })
+}
+
+export const filter_email_missing = (users: any[]) => {
+
+ return users.filter((user) => {
+ if (!user.data) {
+ return false;
+ }
+ if (!user.geo) {
+ return false;
+ }
+ if (!user.data.urls) {
+ return false;
+ }
+ if (user.data && user.data.jsError) {
+ return false;
+ }
+ if (!user.detail) {
+ return false
+ }
+
+ if (!user.detail.name) {
+ return false
+ }
+
+ if (user.moderation !== 'accepted') {
+ return false;
+ }
+ if (!user.data.urls.find((l) => l.name == 'Email')) {
+ return true;
+ }
+ return false;
+ })
+}
+
+export const filter_accepted = (users: IImportUser[]) => {
+ return users.filter((user) => {
+ if (!user.data) {
+ return false
+ }
+ if (!user.geo) {
+ return false
+ }
+ if (!user.data.urls) {
+ return false
+ }
+
+ if (!user.detail.heroImageUrl) {
+ return false
+ }
+
+ if (user.data && user.data.jsError) {
+ return false
+ }
+
+ if (user.moderation !== 'accepted') {
+ return false
+ }
+
+ return true;
+ })
+}
+
+export const oa_user_email = (user: I_OSR_USER) => {
+ if (!user.data) {
+ return false;
+ }
+ if (!user.geo) {
+ return false;
+ }
+ if (!user.data.urls) {
+ return false;
+ }
+ if (user.data && user.data.jsError) {
+ return false;
+ }
+ let u = user.data.urls.find((l) => l.name == 'Email')
+ if (u) {
+ return u.url.replace('mailto:', '')
+ }
+
+}
+
+export const get_user_name = (user: IImportUser) => {
+ let ret = replaceAll('--', '-', sanitize(filenamify(user._id)).replace(/^\-+/g, '').replace(/\-$/, ''))
+
+ ret = ret.replace(/\-$/, '')
+ ret = ret.replace(/\_$/, '')
+
+ if (!oa_user_email(user)) {
+ ret += '-uc'
+ }
+
+ return ret
+}
+
+export const get_user_display_name = (user: IImportUser) => replaceAll('--', '-', sanitize(filenamify(user.data.title)).replace(/^\-+/g, '').replace(/\-$/, ''));
+
+export const getDataPath = (_path = '') => path.resolve(path.join(resolve(DATA_PATH), _path))
+
+export const getUsersPath = () => path.resolve(resolve(TEST ? LATEST_TEST : LATEST_TRACK))
+
+export const getUsers = () => (read(path.resolve(getUsersPath()), 'json') as any) as IImportUser[] || []
+
+let uPage = 1
+let usersAll = []
+
+export const _getForumUsers = async (d: Discourser, page, detail) => {
+
+ if (uPage == 1) {
+ usersAll = []
+ }
+ let users: any = await d.getUsers(page);
+ if (users.length) {
+ usersAll = usersAll.concat(users);
+ uPage++;
+ return _getForumUsers(d, uPage, detail);
+ } else {
+ uPage = 1;
+
+ write(path.resolve(F_USERS_NOW), usersAll);
+
+ let fUsers: IDiscourseUser[] = read(path.resolve(F_USERS_ALL), 'json') || [] as any;
+
+ const add = async (u: IDiscourseUser) => {
+ return new Promise((resolve, reject) => {
+ let fUser = fUsers.find((fu) => u.id == fu.id)
+ if (!fUser) {
+ fUsers.push(u)
+ fUser = u
+ }
+
+ if (!fUser.detail) {
+ logger.debug('Retrieve User Detail ' + u.name)
+ setTimeout(() => {
+ d.getUser(fUser.id).then((detail) => {
+ if (detail) {
+ fUser.detail = detail
+ }
+ write(path.resolve('./fusers-all.json'), fUsers)
+ resolve(fUser)
+ })
+ }, 200)
+ } else {
+ resolve(fUser)
+ }
+ })
+ }
+ return await BPromise.resolve(usersAll).map((u: IDiscourseUser) => {
+ return add(u)
+ }, { concurrency: 1 })
+
+ }
+}
+export const getForumUsers = async (d, detail): Promise => {
+ if (!FETCH_DUSERS) {
+ return read(getDataPath(F_USERS_ALL), 'json') || [] as any
+ }
+ return _getForumUsers(d, uPage, detail)
+}
+
+export const createUser = async (discourse: Discourser, oa_user: IImportUser) => {
+ /*
+ Bazar
+ https://shop.osr-plastic.org
+ Website
+ website2
+ Instagram
+ https://www.instagram.com/osr_plastic/
+ Directory / Map Url
+ https://www.google.com/maps/contrib/117674167598277014013
+ OSR - Marketplace Url
+ https://shop.osr-plastic.org/plastichub/
+ */
+ if (!oa_user.data.title) {
+ return -120
+ }
+
+ let name = replaceAll('--', '-', get_user_display_name(oa_user).replace(/^\-+/g, '').replace(/\-$/, ''))
+ let user_name = get_user_name(oa_user)
+
+ name = user_name.replace(/\-$/, '')
+ name = user_name.replace(/\_$/, '')
+
+ let opts = {
+ "name": name,
+ "email": oa_user_email(oa_user) || `${user_name}_uc@osr-plastic.org`,
+ "password": DEFAULT_PASSWORD(),
+ "username": user_name,
+ "active": true,
+ "approved": true,
+ "user_fields[1]": true
+ }
+
+ let user: any = await discourse.createUser(opts)
+
+ if (name.length < 4) {
+ return -120
+ }
+
+ if (user_name.length > 50) {
+ return -120
+ }
+
+ if (user && user.errors) {
+
+
+ if (user.message === "Username must be no more than 50 characters" ||
+ user.message === 'Username must not contain a sequence of 2 or more special chars (.-_)') {
+ return -120
+ }
+
+ if (user.message === "Username must be unique" || user.message === "Primary email has already been taken") {
+ return -100
+ }
+
+ if (user.errors.email && user.errors.username) {
+ user = await discourse.getUserByUsername(user_name)
+ if (user && user.id && !oa_user._didSetGroup) {
+ try {
+ let gret = await discourse.updateGroup(user_name, OA_USER_IMPORT_GROUP);
+ } catch (e) {
+ logger.error('error adding to group', user_name)
+ }
+ return user.id
+ };
+ }
+ logger.error('Error creating user ' + user_name, user.errors)
+ }
+ if (user && user.user_id) {
+ try {
+ await discourse.updateGroup(user_name, OA_USER_IMPORT_GROUP);
+ return user.user_id;
+ } catch (e) {
+ logger.error('error adding to group', user_name)
+ return user.user_id;
+ }
+
+ } else {
+ if (user && user.message && user.message == 'Username must be unique\nPrimary email has already been taken') {
+ logger.error('already created', oa_user.detail.name)
+ return -10;
+ } else if (user && user.message && user.message == 'Your account is activated and ready to use.') {
+ if (user.user_id) {
+ return user.user_id;
+ }
+ return -10;
+ } else {
+ logger.debug('cant create user ' + oa_user.detail.name, user);
+ }
+ return null;
+ }
+ return null;
+}
+
+export const uploadAvatar = async (discourse, name, filePath) => {
+ const users = getUsers()
+ const index = users.findIndex((u) => u.detail.name == name)
+ try {
+ const upped = await discourse.upload(1, filePath)
+ const data = upped.data
+
+ if (data && data.id) {
+ users[index].upload_id = data.id
+ logger.debug('uploaded avatar ' + name + ' ' + data.id)
+ write(getUsersPath(), users)
+ } else {
+ logger.error('upload - error', name)
+ }
+ return users
+ } catch (error) {
+ users[index].upload_id = -1
+ logger.error('error uploading avatar', name)
+ write(getUsersPath(), users)
+ }
+
+}
+
+const uploadAvatars = async (discourse: Discourser, users: IImportUser[]) => {
+
+ const toBeUploaded = users.filter((u) => {
+ if (u.upload_id) {
+ return false
+ }
+
+ const hero = getImageName(u.detail.heroImageUrl)
+ const avatar = findAvatar(u, hero)
+ if (!avatar) {
+ logger.error('cant find avatar : ', u._id, hero)
+ return false
+ }
+ u.avatar = avatar
+ return true
+ })
+
+ return await BPromise.resolve(toBeUploaded).map((u: IImportUser) => {
+ if (!u.detail.name) {
+ return
+ }
+ logger.debug('upload avatar : ' + u._id)
+ const t = uploadAvatar(discourse, u.detail.name, u.avatar)
+ return t;
+ }, { concurrency: 1 })
+
+}
+
+const findAvatar = (user: IImportUser, filename) => {
+
+ const root = path.resolve(resolve(DATA_PATH))
+
+ const _path = path.resolve(`${root}/${user._id}/${filename}`)
+ if (exists(_path)) {
+ return _path
+ }
+ const files = fg.sync('**/**/*' + filename + '*', { dot: true, cwd: root, absolute: true });
+ if (files.length == 0) {
+ return false;
+
+ }
+ return files[0];
+}
+
+/////////////////////////////////////////////////////
+//
+// users
+//
+export const updateUser = async (discorse: Discourser, oa_user: IImportUser) => {
+
+ const users = getUsers()
+
+ const index = users.findIndex((u) => u.detail.name == oa_user.detail.name)
+
+ const user_name = replaceAll('--', '-', get_user_name(oa_user).replace(/^\-+/g, '').replace(/\-$/, ''))
+
+ let ret: any = null;
+
+ try {
+
+ ret = await discorse.updateUser(user_name, {
+ name: oa_user.data.title
+ })
+
+
+ try {
+
+ let location
+ if (oa_user.geo) {
+ location = `${oa_user.geo.continent} / ${oa_user.geo.countryName} / ${oa_user.geo.city} `
+ }
+
+
+ let website
+ if (oa_user.data) {
+ website = oa_user.data.urls.find((l) => l.name == 'Website')
+ if (website) {
+ website = website.url
+ }
+ }
+
+
+ let description
+ if (oa_user.data) {
+ if (oa_user.data.description) {
+ description += oa_user.data.description
+ }
+
+ description += '\n'
+
+ if (oa_user.data.services) {
+ let services = `### Services \n`;
+ let hasServices = false;
+ for (let s in oa_user.data.services[0]) {
+ if (oa_user.data.services[0][s]) {
+ services += `- [x] ${capitalize(s)}\n`
+ hasServices = true;
+ }
+ }
+ if (hasServices) {
+ description += services
+ }
+ }
+ }
+
+ let links = ''
+ if (oa_user.data.urls) {
+ links = oa_user.data.urls.filter(
+
+ (r) => r.name !== 'Bazar' && r.name !== 'sponsor the work'
+
+ ).map((l) => {
+ let label = '' + l.name;
+
+ if (label === 'Social media') {
+ if (l.url.indexOf('facebook') !== -1) {
+ label = 'Facebook';
+ }
+ if (l.url.indexOf('instagram') !== -1) {
+ label = 'Instagram';
+ }
+ }
+
+ label += " - " + l.url;
+ label = label.replace("https://", "");
+ label = label.replace("http://", "");
+ label = label.replace("mailto:", "");
+
+ return `${label} `
+ }).join(" \n")
+
+ description += '\n### Links\n'
+ description += links
+ }
+
+ if (oa_user.location) {
+ description += `\n\n Get Directions \n`
+ }
+
+
+ let updatePrefs = await discorse.updateUserProfile(user_name, {
+ bio_raw: replaceAll('undefined', '', description),
+ location,
+ website
+ })
+
+
+ } catch (error) {
+ logger.error(`Error updating user prefs : ${user_name}`)
+ }
+
+ } catch (error) {
+ logger.error('error updating user', oa_user._id, error.message)
+ return
+ }
+
+
+ if (ret.status === 200) {
+ users[index].didUpdateName = true
+ logger.debug('did update user', oa_user._id, ' # ', oa_user.data.title)
+ write(getUsersPath(), users)
+ } else {
+ logger.error('did update user failed ', oa_user._id)
+ }
+}
+export const importUser = async (discorse: Discourser, oa_user: IImportUser) => {
+
+ const users = getUsers()
+
+ const index = users.findIndex((u) => u._id == oa_user._id)
+
+ let user = null
+
+ try {
+ user = await createUser(discorse, oa_user)
+ } catch (error) {
+ debugger
+ logger.error('error creating user', error)
+ return false
+ }
+
+ if (user === -100) {
+ users[index].alreadyExists = true
+ write(getUsersPath(), users)
+ return
+ }
+
+ if (user === -120) {
+ users[index].invalidData = true
+ write(getUsersPath(), users)
+ return
+ }
+
+
+ if (user && users[index].upload_id && !users[index]._didSetAvatar) {
+ try {
+ await discorse.setUserAvatar(get_user_name(oa_user), users[index].upload_id)
+ } catch (e) {
+ logger.error('error setting avatar', get_user_name(oa_user))
+ }
+ }
+
+ const _t = users[index];
+
+ if (user > 0) {
+ users[index].f_id = user
+ users[index]._didSetAvatar = true
+ users[index]._didSetGroup = true
+ logger.debug('\t created ' + oa_user.data.title)
+ write(getUsersPath(), users)
+ } else {
+ logger.error('cant create user - error', oa_user.detail.name, user)
+ }
+ return users[index]
+}
+
+export const mergeLatestUsers = (discorse, options: IOptions, oa_users: I_OSR_USER[]): IImportUser[] => {
+ const users: any[] = getUsers()
+ oa_users.forEach((u) => {
+ const tUser = users.find((tu) => {
+ return tu._id === u._id
+ })
+ if (!tUser) {
+ users.push(u)
+ }
+
+ })
+ logger.debug(`Merged users to ${getUsersPath()}`)
+ write(getUsersPath(), users)
+ return users
+}
+
+export const mergeLatestUsersTest = (discorse, options: IOptions, oa_users: I_OSR_USER[]): IImportUser[] => {
+ const users: any[] = (read(LATEST_TEST, 'json') as [] || [])
+ oa_users.forEach((u) => {
+ const tUser = users.find((u) => {
+ return u._id === u._id
+ })
+ if (!tUser) {
+ users.push(u)
+ }
+ })
+ write(options.track, users)
+ return users
+}
+
+export const importUsers = async (discorse, options: IOptions, oa_users: I_OSR_USER[]) => {
+
+ logger.debug('read users from ', path.resolve(getUsersPath()))
+
+ let users = mergeLatestUsers(discorse, options, oa_users)
+ //const users = mergeLatestUsersTest(discorse, options, oa_users)
+
+ users = users.filter((u) => {
+ if (u.f_id || u.f_id < 0) {
+ return false;
+ }
+ if (u.detail.name === 'plastichub' || u.detail.name === 'lu' || u.detail.name === 'timberstar' || u.detail.name === 'nickname') {
+ return false
+ }
+ if (u.alreadyExists || u.invalidData) {
+ return false;
+ }
+ return true
+ })
+
+ logger.debug('Create Users ' + users.length + ' Total | Left: ' + users.length)
+
+ await uploadAvatars(discorse, users)
+
+ return await BPromise.resolve(users).map((u: IImportUser) => {
+ logger.debug('import user ' + get_user_name(u))
+ try {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ const d = importUser(discorse, u)
+ if (d) {
+ d.then(resolve)
+ } else {
+ reject()
+ }
+ }, 500)
+
+ })
+
+ } catch (e) {
+ debugger;
+ logger.error('error creating user ' + u._id, e)
+ }
+ }, { concurrency: 1 })
+
+}
+
+export const updateUsers = async (discorse, options: IOptions, oa_users: I_OSR_USER[]) => {
+ // https://forum.osr-plastic.org/u/easymoulds/preferences/profile
+ const users = mergeLatestUsers(discorse, options, oa_users)
+ //const users = mergeLatestUsersTest(discorse, options, oa_users)
+
+ let toBeCreated = users.filter((u) => {
+ if (u.f_id || u.f_id < 0) {
+ return true;
+ }
+ if (u.didUpdateName) {
+ return false
+ }
+ return true
+ })
+
+ const testUser = 'easymoulds'
+
+ const test = toBeCreated.find((u) => {
+ return u._id === testUser
+ })
+
+ // toBeCreated = [test]
+
+ return await BPromise.resolve(toBeCreated).map((u: IImportUser) => {
+ /*
+ if (u.didUpdateName) {
+ return false
+ }
+ */
+
+ try {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ const d = updateUser(discorse, u)
+ if (d) {
+ d.then(resolve)
+ } else {
+ reject()
+ }
+ }, 200)
+
+ })
+
+ } catch (e) {
+ debugger;
+ logger.error('error creating user ' + u._id, e)
+ }
+ }, { concurrency: 1 })
+}
+
+export const md_edit_wrap = (content, f, prefix = '', context = '') => {
+ return html_beautify(`${content}
`);
+}
+export const toHTML = (path, markdown) => {
+ const content = read(path, 'string') as string;
+ if (!markdown) {
+ let converter = new Converter({ tables: true });
+ converter.setOption('literalMidWordUnderscores', 'true');
+ return converter.makeHtml(content);
+ } else {
+ return content;
+ }
+}
+export const imageName = (url) => {
+ if (!url) {
+ return ""
+ }
+ try {
+ const parsed = URI.parse(decodeURIComponent(url));
+ const pParsed = path.parse(parsed.path);
+ return sanitize(decodeURIComponent(pParsed.base));
+ } catch (error) {
+ logger.error('error image name : ', url)
+ return ""
+ }
+}
+export const read_fragments = (src, config, prefix = '', context = '') => {
+
+ if (!exists(src)) {
+ //debug.warn(`Create template folder ${src}`);
+ mkdir(src);
+ }
+ let fragments = files(src, '*.html');
+ fragments.map((f) => {
+ config[path.parse(f).name] = md_edit_wrap(toHTML(f, true), f, prefix, context);
+ });
+
+ fragments = files(src, '*.md');
+ fragments.map((f) => {
+ config[path.parse(f).name] = md_edit_wrap(toHTML(f, false), f, prefix, context);
+ });
+ return config;
+}
+
+export const indexUsers = async (discorse, options: IOptions, oa_users: I_OSR_USER[]) => {
+
+ let users = mergeLatestUsers(discorse, options, oa_users)
+
+ users = users.filter((u) => {
+ if (u.f_id && u.data && u.geo) {
+ return true;
+ }
+ return false
+ })
+
+ const continents = []
+ const countries = []
+ const navIndex: any[] = []
+
+ users.forEach((u) => {
+ if (!u.geo || !u.data || u.data.jsError || !u.detail || !u.detail.heroImageUrl) {
+ return;
+ }
+ if (!u.detail.heroImageUrl) {
+ return;
+ }
+ let code = null;
+
+ if (u.geo.continent && continents.indexOf(u.geo.continent) == -1) {
+ continents.push(u.geo.continent);
+ navIndex.push({
+ title: u.geo.continent,
+ url: `/users/${slugify(u.geo.continent)}.html`,
+ children: [],
+ code: u.geo.continentCode
+ // code:u.geo.continentCode
+ })
+ }
+
+ if (countries.indexOf(u.geo.countryName) == -1) {
+ countries.push(u.geo.countryName);
+ }
+ const c = navIndex.find((c) => c.title === u.geo.continent);
+ if (c) {
+ const cc = c.children.find((i) => i.title == u.geo.countryName);
+ if (!cc) {
+ c.children.push({
+ title: u.geo.countryName,
+ url: `/users/${slugify(c.title)}.html#${slugify((u.geo.countryName as string).toLocaleLowerCase())}`,
+ postTitle: `Directory - ${u.geo.countryName}`
+ })
+ }
+ }
+ });
+
+ navIndex.sort((a, b) => {
+ if (a.title < b.title) { return -1; }
+ if (a.title > b.title) { return 1; }
+ return 0;
+ });
+
+ navIndex.forEach((c) => {
+ c.children.sort((a, b) => {
+ if (a.title < b.title) { return -1; }
+ if (a.title > b.title) { return 1; }
+ return 0;
+ });
+ });
+
+ const directoryRoot = path.resolve(resolve('${OSR_ROOT}/osr-directory/pp'))
+
+ const createContinentPage = (continent) => {
+
+ const templates_path = path.resolve(`${directoryRoot}/templates`);
+ if (!exists(templates_path)) {
+ logger.error(`\t Cant find templates at ${templates_path}, path doesn't exists`);
+ return;
+ }
+ const cPath = path.resolve(`${directoryRoot}/templates/config.json`)
+ const config = read(cPath, 'json') as IOSRConfig
+ let fragments: any = { ...config }
+
+ read_fragments(templates_path, fragments, "product_rel_path_name", "machine");
+
+ let templateCountry = read(path.resolve(`${templates_path}/country_users.md`), 'string');
+ const ccountries = {};
+
+ let code = null;
+
+
+ users.forEach((u) => {
+
+ if (!u.geo || !u.data || u.data.jsError || !u.detail || !u.detail.heroImageUrl) {
+ return;
+ }
+ if (!u.detail.heroImageUrl) {
+ return;
+ }
+ if (u.geo.continent && u.geo.continent === continent) {
+ if (!code) {
+ code = u.geo.continentCode;
+ }
+ if (!ccountries[u.geo.countryName]) {
+ ccountries[u.geo.countryName] = [];
+ }
+
+ ccountries[u.geo.countryName].push(u);
+ }
+ });
+
+ if (continent === 'Africa') {
+ //debugger;
+ }
+
+ let weight = 100;
+ for (var country in ccountries) {
+
+ let cPage = "";
+
+ if (country === 'Kenya') {
+ //debugger;
+ }
+
+ cPage += `\n#### ${slugify(country)}\n\n`;
+ if (country === 'undefined' || country === 'unknown' || !country) {
+ return;
+ }
+ cPage += '';
+ cPage += '
';
+
+ let cusers = ccountries[country];
+ cusers = cusers.sort((a, b) => a.type === b.type ? 1 : -1);
+ const cUsersC = cusers.map((u) => {
+ const prefix = u.moderation === 'rejected' ? "
Censored " : "";
+ const image = `/users/${u._id}/${encodeURIComponent(sanitize(imageName(u.detail.heroImageUrl)))}`;
+ const title = u.data && u.data.title ? u.data.title : u._id;
+ const uUrl = `/directory/users/${u._id}`;
+ let censored = u.moderation === 'rejected' ? '
Yes ' : 'No'
+ return `
+
+
+
+
${title}
+
Type: ${u.type}
+
Censored: ${censored}
+
+
${u.geo.principalSubdivision} / ${u.geo.locality} - ${u.geo.principalSubdivisionCode} - ${u.geo.postcode}
+
+
`;
+ })
+ cPage += cUsersC.join('');
+ cPage += '
';
+
+ country = country.replace(' (the)', '');
+
+ /*
+ const cPagePath = path.resolve(`${kb}/src/directory/users_${sanitize(slugify(country))}-${code}.md`)
+
+ const title = 'Users - ' + country;
+
+ cPage = substitute(templateCountry, {
+ ...fragments,
+ title: title,
+ keywords: 'Precious Plastic, Precious Plastic Users - ' + country,
+ content: html_beautify(cPage),
+ continent: slugify(continent),
+ country: slugify(country),
+ identifier: country + "-" + continent,
+ weight: weight
+ });
+
+ weight++;
+ write(cPagePath, cPage);
+ console.log('write ' + cPagePath);
+ */
+ }
+
+
+ /*
+ content = substitute(template, {
+ ...fragments,
+ title: 'Precious Plastic - Users ' + continent,
+ keywords: 'Precious Plastic, Precious Plastic Users - ' + continent,
+ content: content,
+ continent: slugify(continent)
+ });
+ */
+
+ //const index_md = path.resolve(`${root}/_pages/users_${code}.md`);
+ //write(index_md, content);
+ }
+
+ const templates_path = path.resolve(`${directoryRoot}/templates`);
+
+ const createCountryPages = async (index: any[], indexPath: string) => {
+ let i = 0;
+ for await (const continent of index) {
+ const countries = continent.children
+ for await (const country of countries as any) {
+ const d=0
+ }
+
+ }
+ }
+
+ await createCountryPages(navIndex,'./')
+
+ const createIntroPage = async (users, index: any[], dst: string) => {
+
+ let template = read(path.resolve(`${templates_path}/intro_users.md`))
+
+ let content = ""
+
+ const usersPerCountry = (country: string) => {
+ return users.filter((u) => u.geo.countryName === country)
+ }
+
+ index.forEach((i) => {
+ const heading = `## ${i.title}`
+ let countries = ''
+ i.children.forEach((c) => {
+ let title = c.title.replace(/ *\([^)]*\) */g, "")
+ const nb = usersPerCountry(c.title).length
+ title = `${title} \(${nb}\)`
+ const cPagePath = `/directory/users_${sanitize(slugify(c.title))}-${i.code}`
+ countries += `- [${(title)}](${cPagePath.toLowerCase()})\n`
+ })
+ content += `${heading}\n ${countries}`
+ })
+
+ write(dst, substitute(template, {
+ content: content,
+ /*hidden: data.v3_mappins.filter((u) => u.moderation !== "accepted").length,
+ total: data.v3_mappins.length*/
+ }))
+
+ let data: any
+ try {
+ data = await discorse.updatePost(OA_DIRECTORY_OVERVIEW_TOPIC, content)
+ debugger
+ //logger.debug('update post : ' + options.title + ' : ' + data.id + ' | topic id ' + data.topic_id)
+ } catch (e) {
+ return false
+ }
+
+ }
+
+ // await createIntroPage(users, navIndex, './index.md')
+
+
+ /*
+
+ return await BPromise.resolve(users).map((u: IImportUser) => {
+ try {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => {
+ const d = updateUser(discorse, u)
+ if (d) {
+ d.then(resolve)
+ } else {
+ reject()
+ }
+ }, 200)
+
+ })
+
+ } catch (e) {
+ debugger;
+ logger.error('error creating user ' + u._id, e)
+ }
+ }, { concurrency: 1 })
+
+ */
+}
\ No newline at end of file
diff --git a/packages/discourse/src/lib/oa/utils.ts b/packages/discourse/src/lib/oa/utils.ts
new file mode 100644
index 00000000..113ac6b0
--- /dev/null
+++ b/packages/discourse/src/lib/oa/utils.ts
@@ -0,0 +1,180 @@
+import fs from 'fs'
+import { inspect as utilInspect } from 'util'
+import { resolve, dirname } from 'path'
+const cwd = process.cwd()
+var TurndownService = require('turndown')
+import { Discourser } from '../index'
+
+
+import * as path from 'path'
+const fg = require('fast-glob')
+import slugify from "slugify"
+
+var sanitize = require("sanitize-filename")
+
+import { sync as read } from '@plastichub/fs/read'
+import { sync as write } from '@plastichub/fs/write'
+
+//import { replaceAll } from '../../lib';
+
+
+var mom = require('moment')
+
+export const uploadFile = async (discourse, forum, name, filePath) => {
+ return await discourse.upload(1, filePath);
+}
+
+export const findReplyPage = (b, pages) => {
+ return pages.find((p) => {
+ return p.replies.find((r) => {
+ return r.replyBody == b;
+ })
+ })
+}
+
+export const findReplyUpload = (u, page) => {
+ const f_pics = page.f_pics || [];
+ return f_pics.find((p) => {
+ return p.url === u;
+ })
+}
+
+export const getPages = (topics, topic) => {
+ return topics.filter((t) => {
+ return t.title == topic.title;
+ });
+};
+
+export const getReplies = (topics, topic) => {
+ if (topic.nextPages) {
+ const all = topics.filter((t) => {
+ return t.title == topic.title;
+ });
+ let replies: [] = all.map((t) => t.replies);
+ replies = [].concat.apply([], replies);
+ replies = replies.sort((a: any, b: any) => {
+ const d1 = mom(a.replyDate,'DD/MM/YYYY AT HH:mm').toDate()
+ const d2 = mom(b.replyDate,'DD/MM/YYYY AT HH:mm').toDate()
+ return new Date(d1).getTime() > new Date(d2).getTime() ? 1 : -1;
+ });
+
+ return replies;
+ /*
+ const findReply = (b, pages) => {
+ return pages.find((p) => {
+ return p.replies.find((r) => {
+ return r.replyBody == b;
+ })
+ })
+ }
+ const p = findReply('\n\n\nsounds great, let me get Old Tony´s Schaeubling 13 and a surface grinder first, after that I can do the parts for the espresso machine in the best maker porn fashion possible, no seriously, every time I thought I know something, there’s just another video around the next corner making me cry like a baby, incl. the coffee machine
\n', all);
+ debugger;
+ */
+ }
+ return [];
+}
+
+export const findFile = (folder, filename) => {
+ const files = fg.sync('**/**/*' + filename + '*', { dot: true, cwd: folder, absolute: true });
+ if (files.length == 0) {
+ return false;
+
+ }
+ return files[0];
+}
+
+export const topicFolder = (forum, folder, title) => {
+ const _title = sanitize(slugify(title));
+ const tf = path.resolve(forum + '/' + folder + '/' + _title);
+ return tf;
+}
+
+export const getFUser = (users, user_name) => {
+ return users.find((u) => {
+ return u.name == user_name
+ })
+}
+
+export const dOptions = {
+ host: 'https://forum.osr-plastic.org',
+ key: 'f624b8385fb2219cb49de63d1e22883afdf7b7367a0bebf822523f49f2678031',
+ username: 'admin',
+ rateLimitConcurrency: 1
+}
+
+export const getOAvatar = (index, user) => {
+ const topics = getTopics(index);
+ let topic: any = topics.find((t:any) => {
+ return t.authorName == user;
+ });
+ if (topic) {
+ return topic.authorImage;
+ }
+ for (let i = 0; i < topics.length; i++) {
+ const t: any = topics[i]
+ if (t.replies) {
+ const r = (t.replies as any[]).find((r) => {
+ return r.user == user;
+ })
+ if (r) {
+ return r.avatar;
+ }
+ }
+ }
+ return null;
+}
+
+export const getTopics = (index:any) => {
+ let topics = [];
+ for (let t in index) {
+ topics.push(index[t]);
+ }
+ return topics;
+}
+
+export const convert = (input: string) => {
+ var turndownService = new TurndownService()
+ return turndownService.turndown(input);
+}
+
+export const getDiscourse = () => {
+ return new Discourser(dOptions);
+}
+
+export function inspect(arg: any) {
+ return utilInspect(arg, {
+ depth: 5,
+ colors: true,
+ })
+}
+
+export function log(...args: any[]) {
+ console.log(...args.map((arg) => inspect(arg)))
+}
+
+export async function mkdirp(path: string) {
+ try {
+ await fs.promises.mkdir(path)
+ } catch (err) {
+ // don't care if it already exists
+ }
+}
+
+export async function readJSON(path: string): Promise {
+ const text = await fs.promises.readFile(path, 'utf8')
+ return JSON.parse(text)
+}
+
+export function writeJSON(path: string, data: object) {
+ return fs.promises.writeFile(path, JSON.stringify(data))
+}
+
+export function exists(path: string): Promise {
+ return new Promise(function (resolve) {
+ fs.exists(path, resolve)
+ })
+}
+
+export function escape(path: string): string {
+ return path.replace(/[^\w]/g, '-').replace(/-+/, '-')
+}
diff --git a/packages/discourse/src/lib/osr/index.ts b/packages/discourse/src/lib/osr/index.ts
new file mode 100644
index 00000000..4036bcd4
--- /dev/null
+++ b/packages/discourse/src/lib/osr/index.ts
@@ -0,0 +1 @@
+export * from './urls'
diff --git a/packages/discourse/src/lib/osr/urls.ts b/packages/discourse/src/lib/osr/urls.ts
new file mode 100644
index 00000000..5bccb065
--- /dev/null
+++ b/packages/discourse/src/lib/osr/urls.ts
@@ -0,0 +1,2 @@
+export const marketplaceUrl = (store, product_id) =>
+ `${store}/dispatch=products.view&product_id=${product_id}`
\ No newline at end of file
diff --git a/packages/discourse/src/lib/sync/commons.ts b/packages/discourse/src/lib/sync/commons.ts
new file mode 100644
index 00000000..68c541d4
--- /dev/null
+++ b/packages/discourse/src/lib/sync/commons.ts
@@ -0,0 +1,204 @@
+import * as path from 'path'
+import { IOptions } from '@plastichub/osrl/types'
+import { Engine as engine } from '@plastichub/osrl/Engine'
+import { parse } from '@plastichub/osrl/options'
+
+import { pathInfo } from '@plastichub/osr-cli-commons/glob'
+import { resolve } from '@plastichub/osr-commons'
+import { IOptionsSync, IOptionsSyncComponent, logger } from '../../'
+import { sync as exists } from '@plastichub/fs/exists'
+import { sync as read } from '@plastichub/fs/read'
+import { sync as write } from '@plastichub/fs/write'
+
+import { Promise as BPromise } from 'bluebird'
+
+import {
+ MODULE_NAME
+} from '../../constants'
+
+const chokidar = require("chokidar")
+const cheerio = require('cheerio')
+const frontMatter = require('front-matter')
+
+
+export const fileAsBuffer = (path: string) => read(path, 'buffer') as Buffer || Buffer.from("-")
+
+import { get_cached, set_cached } from '@plastichub/osr-cache/lib'
+import { OSR_CACHE } from '@plastichub/osr-cli-commons'
+
+import * as md5 from 'md5'
+
+import { RMark, toHTML } from '../markdown'
+export const images_urls = (content: string) => {
+
+ const html = toHTML(content)
+ const $ = cheerio.load(html, {
+ xmlMode: true
+ });
+
+ const images = []
+ const links = []
+ $('img').each(function () {
+ images.push($(this).attr('src'))
+ })
+
+ return images
+}
+
+export const adjustUrls = (content: string, options: IOptionsSync) => {
+ let ret = new RMark(
+ {
+ images: (match, capture, arg1, arg2) => ``,
+ //links: (match, capture, arg1, arg2) => `[${capture}](${arg1})`
+ }
+ ).render(content)
+ return ret
+}
+export const fromJSON = (content: string, file:string, options: IOptionsSyncComponent) => {
+
+}
+export const fromYAML = (content: string, options: IOptionsSync) => {
+ if (frontMatter.test(content)) {
+ const fm = frontMatter(content)
+ return {
+ attributes: fm.attributes,
+ body: fm.body
+ }
+ } else {
+ return {
+ attributes: {},
+ body: content
+ }
+ }
+}
+
+// to be changed to osr-defaults
+export const option = (option: string, taskOptions: any, col, _default?: any) => {
+
+ // support grunt or yargs
+ const val = col.option ? col.option : (option) => col[option]
+
+ let ret = taskOptions[option] !== undefined ? taskOptions[option] : _default;
+ if (val(option) !== undefined) {
+ ret = val(option)
+ }
+ return ret
+}
+
+export const createContent = async (file, _options) => {
+ const parts = path.parse(file);
+ const rel = path.relative(_options.root, file);
+
+ let output = _options.output;
+ let outputInfo = pathInfo(_options.output)
+ const variables = {
+ root: '.',
+ cwd: _options.cwd || path.resolve('.'),
+ ..._options.variables
+ }
+
+ if (!outputInfo.FILE_EXT) {
+ output = path.resolve(`${_options.output}/${path.parse(rel).dir}/${parts.name}.md`)
+ } else {
+ output = path.resolve(resolve(output, false, variables));
+ }
+
+ const defaults: any = {
+ language: _options.lang,
+ debug: _options.debug,
+ profile: _options.profile,
+ output: output,
+ plugins: _options.plugins,
+ env: _options.env || 'library',
+ cwd: _options.cwd || path.resolve('.'),
+ source: file,
+ variables
+ }
+
+
+ const options = parse(defaults, defaults);
+ const eOptions = {
+ ...options,
+ root: [
+ ...options.profile.includes,
+ path.parse(file).dir
+ ],
+ toHTML: false,
+ cache: false,
+ keepOutputType: true,
+ trimTagRight: false,
+ trimTagLeft: false,
+ trimOutputRight: false,
+ trimOutputLeft: false,
+ greedy: false
+ } as IOptions
+
+ const Engine = new engine(eOptions)
+
+ options.source = path.resolve(options.source)
+
+ const osr_cache = OSR_CACHE()
+ const cached = await get_cached(options.source, eOptions, _options.module || MODULE_NAME)
+
+ if (osr_cache && cached && _options.cache !== false) {
+ options.debug && logger.info('Compile file serving from cache: ' + options.source)
+
+ let md5Src = md5(Buffer.from(cached));
+ let md5Dst = md5(fileAsBuffer(options.output));
+ if (!exists(options.output) || md5Src !== md5Dst) {
+ write(options.output, cached);
+ }
+ return cached
+ }
+
+ options.debug && logger.info('Compile file ' + file, eOptions)
+
+ let content = await Engine.render(options.source, options.variables)
+
+ if (_options.onCompiled) {
+ content = await _options.onCompiled(options.source, output, content)
+ }
+
+ if (osr_cache && _options.cache !== false) {
+ options.debug && logger.info('Write output to cache', output)
+ await set_cached(options.source, eOptions, _options.module || MODULE_NAME, content)
+ }
+
+ let dst = path.resolve(resolve(output, false, options.variables))
+ _options.debug && logger.info('Write output to: ', dst)
+ write(dst, content)
+
+ if (_options.onCompileDone) {
+ await _options.onCompileDone(options.source, dst, options, content)
+ }
+
+ return content
+}
+
+const watch = async (src, options) => {
+ src = path.resolve(src);
+ const watcher = chokidar.watch(`${src}`, {
+ ignored: /(^|[\/\\])\../,
+ persistent: true
+ });
+ watcher.on('change', async path => {
+ await createContent(path, options)
+ });
+ return watcher
+}
+
+const compileAll = async (files, options) => {
+ return await BPromise.resolve(files).map((f) => {
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ createContent(f, options).then(() => resolve(true))
+ }, 50)
+ });
+ }, { concurrency: 1 });
+}
+
+const compileAllEx = async (files, options) => {
+ return await BPromise.resolve(files).map((f) => {
+ return createContent(f, options)
+ }, { concurrency: 1 });
+}
diff --git a/packages/discourse/src/lib/sync/component.ts b/packages/discourse/src/lib/sync/component.ts
new file mode 100644
index 00000000..07236dd5
--- /dev/null
+++ b/packages/discourse/src/lib/sync/component.ts
@@ -0,0 +1,454 @@
+import * as path from 'path'
+import { sync as exists } from "@plastichub/fs/exists"
+import { async as move } from "@plastichub/fs/move"
+import { sync as dir } from "@plastichub/fs/dir"
+import { sync as write } from "@plastichub/fs/write"
+import { sync as read } from "@plastichub/fs/read"
+
+import { resolve } from "@plastichub/osr-commons"
+
+import { Promise as BPromise } from 'bluebird'
+import { IOptionsSync, IDiscoursePostBaseOptions } from '../../types'
+
+import { createContent } from './osrl'
+
+const YAML = require('json-to-pretty-yaml')
+const cheerio = require('cheerio')
+const findUp = require('find-up')
+const frontMatter = require('front-matter')
+const md5 = require('md5')
+
+import { imageName, downloadFile } from './download'
+
+import { toHTML } from '../markdown'
+import { isNumber } from '@plastichub/core/primitives'
+
+import { defaultConfig, fromJSON, tracking, trackingPath } from './'
+
+import {
+ SYNC_TRACK_FILENAME,
+ EDiscourseConfigKey
+} from '../discourse/constants'
+
+import {
+ cacheCategories,
+ cacheTags,
+ cacheTopics,
+ cacheUsers
+} from '../discourse/cache'
+
+
+import {
+ Discourser,
+ Instance
+} from '../discourse'
+
+import {
+ images_urls
+} from './commons'
+
+
+import { ISearchPost, ISearchTopic } from "../.."
+
+import * as md5 from 'md5'
+
+import { IComponentConfig } from '@plastichub/osr-commons'
+import { marketplaceUrl } from '../osr'
+
+import { isValidLibraryComponent, readOSRConfig } from '@plastichub/osr-fs-utils'
+
+import { logger } from '../../index'
+import { forward_slash } from '@plastichub/osr-cli-commons'
+
+const CONTENT_TEST = false
+const SKIP_EXISTING = false
+
+export const createPost = async (discourse: Discourser, options: IOptionsSync, content) => {
+
+ if (!isNumber(options.cat)) {
+ logger.error(`category not a number! ${options.title} `)
+ }
+
+ let data: any
+ try {
+ data = await discourse.createPost(options.title, content, options.cat as number)
+ } catch (e) {
+ debugger
+ }
+
+ if (data) {
+ if (data && data.id) {
+ try {
+ options.post_id = data.id;
+ options.topic_id = data.topic_id
+ await discourse.changeOwner(options.post_id, options.topic_id, options.user_name)
+ logger.debug('created topic : ' + options.title + ' : ' + data.id + ' | topic id :' + data.topic_id)
+ return true
+ } catch (e) {
+ logger.error('changing owner ' + options.title + ' failed!', e)
+ }
+ } else {
+ logger.debug('creating ' + options.title + ' failed!', data.errors, data);
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ logger.error('title already used : ' + options.title)
+ }
+ }
+ }
+ } else {
+ return false
+ }
+}
+
+export const updatePost = async (discourse: Discourser, options: IOptionsSync, topic_id, content) => {
+
+ let data: any
+ try {
+ data = await discourse.updatePost(topic_id, content)
+ logger.debug('update post : ' + options.title + ' : ' + data.id + ' | topic id ' + data.topic_id)
+ } catch (e) {
+ return false
+ }
+
+ if (data) {
+ if (data && data.id) {
+ try {
+ // logger.debug('change user to ', options.owner);
+ options.post_id = data.id;
+ options.topic_id = data.topic_id
+ await new Promise(f => setTimeout(f, 1000));
+ await discourse.changeOwner(topic_id, topic_id, options.user_name)
+ return true
+ } catch (e) {
+ logger.debug('changing owner ' + options.title + ' failed!')
+ return false
+ }
+ } else {
+ logger.debug('creating ' + options.title + ' failed!', data.errors)
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ logger.error('title already used : ' + options.title)
+ }
+ return false
+ }
+ }
+ }
+}
+
+
+
+const uploadImages = async (content: string, discourse: Discourser, options: IOptionsSync) => {
+
+ const root = path.resolve(resolve(options.root))
+ if (!exists(root)) {
+ return false
+ }
+
+ const track_path = trackingPath(root)
+ const track = tracking(root)
+
+ const html = toHTML(content)
+ const $ = cheerio.load(html, {
+ xmlMode: true
+ });
+
+ const images = images_urls(content)
+
+ $('img').each(function () {
+ if ($(this).attr('src') && $(this).attr('src').length > 5) {
+ images.push($(this).attr('src'))
+ }
+ })
+
+ for await (const image of Object.entries(images)) {
+ const url: string = image[1]
+
+ if (url.length < 10) {
+ continue
+ }
+
+ if (url.startsWith('upload:')) {
+ continue
+ }
+ if (options.uploadRemote && url.startsWith('http')) {
+
+ const contentHash = md5(content).substring(0, 5)
+ const cache_path = path.resolve(resolve('${OSR_CACHE}/discourse-downloads/' + contentHash))
+ if (!exists(cache_path)) {
+ dir(cache_path)
+ }
+ const image_name = imageName(url)
+ const image_local = path.join(cache_path, image_name)
+ if (!exists(image_local)) {
+ try {
+ await downloadFile(url, cache_path)
+ } catch (e) {
+ continue
+ }
+ }
+ if (!exists(image_local)) {
+ continue
+ }
+
+ if (!track[url]) {
+ const upped: any = await discourse.uploadFile(options.owner, image_local)
+ const data = upped.data;
+ if (data && data.id) {
+ track[url] = data
+ write(track_path, track)
+ } else {
+ console.error('error uploading image')
+ }
+ }
+
+ continue
+ }
+
+ if (options.uploadLocal) {
+ const image_path = path.join(root, url)
+ if (exists(image_path) && (!track[url] || options.cache === false)) {
+ const upped: any = await discourse.uploadFile(options.owner, image_path)
+ const data = upped.data;
+ if (data && data.id) {
+ track[url] = data
+ write(track_path, track)
+ } else {
+ console.error('error uploading image')
+ }
+ }
+ }
+ }
+
+ return track
+}
+
+const syncFile = async (file: string, options: IOptionsSync) => {
+
+ const discourse = Instance(null, options.config as EDiscourseConfigKey)
+
+ let config = fromJSON(file, options) || {} as IComponentConfig
+
+ const componentDir = path.parse(file).dir
+
+ // ph3 back sync
+ const rel = forward_slash(path.relative(options.root, componentDir))
+ const productConfigPath = path.join(options.product_root, rel, 'config.json')
+
+ let body = await createContent(componentDir, options)
+
+ let images_track
+
+ if (options.uploadLocal || options.uploadRemote) {
+ images_track = await uploadImages(body, discourse, options)
+ const image_urls = images_urls(body)
+ image_urls.forEach((i) => {
+ if (images_track[i]) {
+ body = body.replace(i, images_track[i].short_url)
+ } else {
+ logger.warn(`Cant resolve image url : ${i} - ${componentDir} ! Image Upload track invalid`)
+ }
+ })
+ }
+
+
+
+ logger.debug(`Processing ${componentDir}`);
+
+ const output = path.join(componentDir, '.osr/discourse_raw.md')
+ let dst = path.resolve(resolve(output))
+ options.debug && logger.info('Write output to: ', dst)
+ write(dst, body)
+
+ let post_id, topic_id
+
+ let dOpts: IDiscoursePostBaseOptions = {
+ ...options,
+ cat: config.forumCategory,
+ id: options.id,
+ owner: config.forumUserId || 1,
+ tags: config.forumTags as string,
+ title: config.name,
+ topic_id: config.forumTopicId,
+ post_id: config.forumPostId
+ }
+
+ options = {
+ ...options,
+ ...dOpts
+ }
+
+ const hash = md5(JSON.stringify({
+ cat: dOpts.cat,
+ tags: dOpts.tags,
+ owner: dOpts.owner,
+ body,
+ title: dOpts.title
+ }, null))
+
+
+
+
+ // const cats = await cacheCategories(options, discourse)
+ // const tags = await cacheTags(options, discourse)
+
+ const users = await cacheUsers(options, discourse)
+ await new Promise(f => setTimeout(f, 1000));
+ let search = await discourse.search(dOpts.title)
+ await new Promise(f => setTimeout(f, 2000));
+
+ let dTopic: ISearchTopic
+ let dPost: ISearchPost
+
+ if (search && search.posts && search.topics) {
+ search.topics.forEach((t, i) => {
+ if (t.title === dOpts.title) {
+ dTopic = t
+ dPost = search.posts[i]
+ topic_id = dTopic.id
+ post_id = dPost.id
+ }
+ })
+ }
+
+ if (!dTopic || !dPost) {
+ console.error('!dTopic || !dPost : cant find ' + dOpts.title)
+ // return
+ }
+
+ const user = users.find((u) => {
+ return u.id === dOpts.owner
+ })
+
+ if (!user) {
+ logger.error('Invalid user : ', dOpts.owner)
+ return false
+ }
+
+ options.user_name = user.username
+
+ if (SKIP_EXISTING && hash === config.forumPostHash &&
+ config.forumTopicId && config.forumPostId) {
+ return
+ }
+
+ if (CONTENT_TEST) {
+ return
+ }
+
+ if (post_id) {
+ if (await updatePost(discourse, options, post_id, body)) {
+ if (topic_id) {
+ await new Promise(f => setTimeout(f, 2000));
+ await discourse.updateTopic(topic_id, dOpts.cat as number, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : [])
+ }
+ } else {
+ logger.error(`Error updating post ${dOpts.title}`)
+ }
+ } else {
+ if (await createPost(discourse, options, body)) {
+ await new Promise(f => setTimeout(f, 1000));
+ await discourse.updateTopic(options.topic_id, dOpts.cat as number, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : [])
+ } else {
+ logger.error('Creating post failed !', dOpts.title)
+ }
+ }
+
+ // const visStatus = await discourse.updateTopicVisibility(topic_id, true)
+
+ // re-read without defaults
+ config = readOSRConfig(file)
+
+ config.forumPostHash = hash
+
+ if (dTopic) {
+ config.forumTopicId = dTopic.id
+ }else if(topic_id){
+ config.forumTopicId = topic_id
+ }
+
+ if (dPost) {
+ config.forumPostId = dPost.id
+ }else if(post_id){
+ config.forumPostId = post_id
+ }
+
+ write(file, config)
+
+ //ph3 products
+ if (exists(productConfigPath)) {
+ let pConfig = readOSRConfig(productConfigPath)
+ logger.debug(`Updating product config ${productConfigPath}`)
+ pConfig = {
+ ...config
+ //...pConfig,
+ //...
+ /*
+ forumTopicId:config.forumTopicId,
+ forumPostId:config.forumPostId,
+ forumPostHash: config.forumPostHash
+ */
+ }
+ write(productConfigPath, pConfig)
+ }
+ return body
+}
+
+export const syncComponent = async (options: IOptionsSync) => {
+
+ let components = options.srcInfo.FILES.filter(isValidLibraryComponent)
+ //let components = options.srcInfo.FILES.filter((c) => {
+ //components = components.filter((c) => {
+ /*
+try {
+ const config = readOSRConfig(c) as IComponentConfig
+ if (config) {
+ if (config.forum === false) {
+ return false
+ }
+ // return !config.code && !config.cscartId && !config.steps
+ return !!config.name
+ }
+ return false
+} catch (error) {
+ logger.error(`Invalid config : ${c}`)
+}
+})*/
+
+ const skipExisting = options.skip
+ /*
+ [
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/asterix-pp/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/asterix-sm-morren/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/bicycle-shredder/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/idefix/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/obelix/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/pp-v3.3/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/components/shredder_v21-light-ex/config.json",
+ "C:/Users/mc007/Desktop/osr/osr-machines/shredder/components/shredder_v31-light/config.json",
+ ]
+ */
+ if (skipExisting) {
+ components = components.filter((f) => {
+ const config = readOSRConfig(f) as IComponentConfig
+ if (config.forumPostId && config.forumTopicId) {
+ return false
+ }
+ return true
+ })
+ }
+
+ //components = [components[0]]
+ logger.info(`Syncing ${components.length} components`, components)
+ await BPromise.resolve(components).map((f) => {
+ try {
+ return syncFile(f, options)
+ } catch (error) {
+ debugger
+ }
+ }, { concurrency: 1 })
+
+}
+
+export const sync = async (options: IOptionsSync) => {
+ return syncComponent(options)
+}
diff --git a/packages/discourse/src/lib/sync/directory.ts b/packages/discourse/src/lib/sync/directory.ts
new file mode 100644
index 00000000..e33194de
--- /dev/null
+++ b/packages/discourse/src/lib/sync/directory.ts
@@ -0,0 +1,400 @@
+import * as path from 'path'
+import { sync as exists } from "@plastichub/fs/exists"
+import { async as move } from "@plastichub/fs/move"
+import { sync as dir } from "@plastichub/fs/dir"
+import { sync as write } from "@plastichub/fs/write"
+import { sync as read } from "@plastichub/fs/read"
+
+import { resolve } from "@plastichub/osr-commons"
+
+import { Promise as BPromise } from 'bluebird'
+import { IOptionsSync, IDiscoursePostBaseOptions } from '../../types'
+
+import { createContent } from './osrl'
+
+const YAML = require('json-to-pretty-yaml')
+const cheerio = require('cheerio')
+const findUp = require('find-up')
+const frontMatter = require('front-matter')
+
+import { imageName, downloadFile } from './download'
+
+import { toHTML } from '../markdown'
+
+import { defaultConfig, fromJSON, tracking, trackingPath } from './'
+
+import {
+
+ SYNC_TRACK_FILENAME,
+ EDiscourseConfigKey
+} from '../discourse/constants'
+
+import {
+ cacheCategories,
+ cacheTags,
+ cacheTopics,
+ cacheUsers
+} from '../discourse/cache'
+
+
+import {
+ Discourser,
+ Instance
+} from '../discourse'
+
+import {
+ images_urls
+} from './commons'
+
+
+import { ISearchPost, ISearchTopic } from "../.."
+
+import * as md5 from 'md5'
+
+import { IComponentConfig } from '@plastichub/osr-commons'
+
+import { isValidLibraryComponent, readOSRConfig } from '@plastichub/osr-fs-utils'
+
+import { logger } from '../../index'
+
+
+const fromYAML = (content: string, options: IOptionsSync) => {
+ if (frontMatter.test(content)) {
+ const fm = frontMatter(content)
+ return {
+ attributes: fm.attributes,
+ body: fm.body
+ }
+ } else {
+ return {
+ attributes: {},
+ body: content
+ }
+ }
+}
+
+
+
+export const createTopic = async (discourse: Discourser, options: IOptionsSync, content) => {
+
+ let data: any
+ try {
+ data = await discourse.createPost(options.title, content, options.cat as number)
+ } catch (e) {
+ debugger
+ }
+
+ if (data) {
+ logger.debug('created topic : ' + options.title + ' : ' + data.id)
+ if (data && data.id) {
+
+ try {
+ options.post_id = data.id;
+ options.topic_id = data.topic_id
+ await discourse.changeOwner(options.post_id, options.topic_id, options.user_name)
+ } catch (e) {
+ logger.error('changing owner ' + options.title + ' failed!', e)
+ }
+ } else {
+ logger.debug('creating ' + options.title + ' failed!', data.errors);
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ logger.error('title already used : ' + options.title)
+ }
+ }
+ }
+ }
+}
+
+export const updateTopic = async (discourse: Discourser, options: IOptionsSync, topic_id, content) => {
+
+ let data: any
+ try {
+ data = await discourse.updatePost(topic_id, content)
+ } catch (e) {
+ return false
+ }
+
+ if (data) {
+ logger.debug('created topic : ' + options.title + ' : ' + data.id)
+ if (data && data.id) {
+ try {
+ logger.debug('change user to ', options.owner);
+ options.post_id = data.id;
+ options.topic_id = data.topic_id
+ await discourse.changeOwner(topic_id, topic_id, options.user_name)
+ return true
+ } catch (e) {
+ logger.debug('changing owner ' + options.title + ' failed!')
+ return false
+ }
+ } else {
+ logger.debug('creating ' + options.title + ' failed!', data.errors)
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ logger.error('title already used : ' + options.title)
+ }
+ return false
+ }
+ }
+ }
+}
+
+
+
+const uploadImages = async (content: string, discourse: Discourser, options: IOptionsSync) => {
+
+ const root = path.resolve(resolve(options.root))
+ if (!exists(root)) {
+ return false
+ }
+
+ const track_path = trackingPath(root)
+ const track = tracking(root)
+
+ const html = toHTML(content)
+ const $ = cheerio.load(html, {
+ xmlMode: true
+ });
+
+ const images = images_urls(content)
+
+ $('img').each(function () {
+ if ($(this).attr('src') && $(this).attr('src').length > 5) {
+ images.push($(this).attr('src'))
+ }
+ })
+
+ for await (const image of Object.entries(images)) {
+ const url: string = image[1]
+
+ if (url.length < 10) {
+ continue
+ }
+
+ if (url.startsWith('upload:')) {
+ continue
+ }
+ if (options.uploadRemote && url.startsWith('http')) {
+
+ const contentHash = md5(content).substring(0, 5)
+ const cache_path = path.resolve(resolve('${OSR_CACHE}/discourse-downloads/' + contentHash))
+ if (!exists(cache_path)) {
+ dir(cache_path)
+ }
+ const image_name = imageName(url)
+ const image_local = path.join(cache_path, image_name)
+ if (!exists(image_local)) {
+ try {
+ await downloadFile(url, cache_path)
+ } catch (e) {
+ continue
+ }
+ }
+ if (!exists(image_local)) {
+ continue
+ }
+
+ if (!track[url]) {
+ const upped: any = await discourse.uploadFile(options.owner, image_local)
+ const data = upped.data;
+ if (data && data.id) {
+ track[url] = data
+ write(track_path, track)
+ } else {
+ console.error('error uploading image')
+ }
+ }
+
+ continue
+ }
+
+ if (options.uploadLocal) {
+ const image_path = path.join(root, url)
+ if (exists(image_path) && !track[url]) {
+ const upped: any = await discourse.uploadFile(options.owner, image_path)
+ const data = upped.data;
+ if (data && data.id) {
+ track[url] = data
+ write(track_path, track)
+ } else {
+ console.error('error uploading image')
+ }
+ }
+ }
+ }
+
+ return track
+}
+
+const syncFile = async (file: string, options: IOptionsSync) => {
+
+ const discourse = Instance(null, options.config as EDiscourseConfigKey)
+
+ let config = fromJSON(file, options) || {} as IComponentConfig
+
+ const componentDir = path.parse(file).dir
+
+ let body = await createContent(componentDir, options)
+
+ let images_track
+
+ if (options.uploadLocal || options.uploadRemote) {
+ images_track = await uploadImages(body, discourse, options)
+ const image_urls = images_urls(body)
+ image_urls.forEach((i) => {
+ if (images_track[i]) {
+ body = body.replace(i, images_track[i].short_url)
+ } else {
+ logger.warn(`Cant resolve image url : ${i}`)
+ }
+ })
+ }
+
+
+
+ const output = path.join(componentDir, '.osr/discourse_raw.md')
+ let dst = path.resolve(resolve(output))
+ options.debug && logger.info('Write output to: ', dst)
+ write(dst, body)
+
+ let dOpts: IDiscoursePostBaseOptions = {
+ ...options,
+ cat: config.forumCategory,
+ id: options.id,
+ owner: config.forumUserId || 1,
+ tags: config.forumTags as string,
+ title: config.name
+ }
+
+ options = {
+ ...options,
+ ...dOpts
+ }
+
+ // const cats = await cacheCategories(options, discourse)
+ // const tags = await cacheTags(options, discourse)
+
+ const users = await cacheUsers(options, discourse)
+ let search = await discourse.search(dOpts.title)
+
+ let post_id, topic_id
+
+ if (options.yaml) {
+ post_id = dOpts.post_id
+ topic_id = dOpts.topic_id
+ }
+
+ let dTopic: ISearchTopic
+ let dPost: ISearchPost
+
+ if (search && search.posts && search.topics
+ && search.posts[0] && search.topics[0]
+ && search.topics[0].title === dOpts.title) {
+ dPost = search.posts[0]
+ dTopic = search.topics[0]
+ topic_id = dTopic.id
+ post_id = dPost.id
+ } else if (post_id && topic_id) {
+
+ }
+
+ if (!dTopic || !dPost) {
+ console.error('cant find ' + dOpts.title)
+ // return
+ }
+
+ const user = users.find((u) => {
+ return u.id === dOpts.owner
+ })
+
+ if (!user) {
+ logger.error('Invalid user : ', dOpts.owner)
+ return false
+ }
+
+ options.user_name = user.username
+
+ let topic = null
+ if (post_id) {
+ await updateTopic(discourse, options, post_id, body)
+ if (topic_id) {
+ topic = await discourse.updateTopic(topic_id, dOpts.cat as number, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : [])
+ }
+ } else {
+ const d = await createTopic(discourse, options, body)
+ if (options.topic_id) {
+ topic_id = options.topic_id
+ post_id = options.post_id
+ await discourse.updateTopic(topic_id, dOpts.cat as number, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : [])
+ }else{
+ logger.error('Creating topic failed !')
+ }
+ }
+
+ // const visStatus = await discourse.updateTopicVisibility(topic_id, true)
+
+ // re-read without defaults
+ config = readOSRConfig(file)
+
+ if (dTopic) {
+ options.topic_id = dTopic.id
+ config.forumTopicId = dTopic.id
+ }
+ if (dPost) {
+ options.post_id = dPost.id
+ config.forumPostId = dPost.id
+ }
+
+ write(file, config)
+
+ return body
+}
+
+export const syncComponent = async (options: IOptionsSync) => {
+
+ // let components = options.srcInfo.FILES.filter(isValidLibraryComponent)
+
+ let components = options.srcInfo.FILES.filter(isValidLibraryComponent)
+ //components = options.srcInfo.FILES.filter((c) => {
+ components = components.filter((c) => {
+ try {
+ const config = readOSRConfig(c) as any
+ if (config) {
+ // return !config.code && !config.cscartId && !config.steps
+ return !!config.name
+ }
+ return false
+ } catch (error) {
+ logger.error(`Invalid config : ${c}`)
+ }
+ })
+
+ const skipExisting = false
+
+ if (skipExisting) {
+ components = components.filter((f) => {
+ const config = readOSRConfig(f) as IComponentConfig
+ if (config.forumPostId && config.forumTopicId) {
+ return false
+ }
+ return true
+ })
+ }
+
+ //components = [components[0]]
+
+ await BPromise.resolve(components).map((f) => {
+ try {
+ return syncFile(f, options)
+ } catch (error) {
+ debugger
+ }
+
+ }, { concurrency: 1 })
+
+}
+
+export const sync = async (options: IOptionsSync) => {
+ return syncComponent(options)
+}
diff --git a/packages/discourse/src/lib/sync/download.ts b/packages/discourse/src/lib/sync/download.ts
new file mode 100644
index 00000000..7b6fe966
--- /dev/null
+++ b/packages/discourse/src/lib/sync/download.ts
@@ -0,0 +1,46 @@
+import * as path from 'path'
+
+const _sanitize = require("sanitize-filename")
+
+const filenamify = require('filenamify')
+import * as download from 'download'
+const URI = require("uri-js")
+
+import * as url from 'url'
+
+export const sanitize = (f) => {
+ let str: string = filenamify(_sanitize(f)).replace(/[^\x00-\x7F]/g, "");
+ if (str.startsWith('_')) {
+ str = str.substring(1);
+ }
+ return str;
+}
+
+export const sanitize_ex = (f) => {
+ let str: string = filenamify(_sanitize(f)).replace(/[^\x00-\x7F]/g, "").replace('_', '');
+ return str;
+}
+
+export const filename = (_url) => {
+ return path.basename(url.parse(_url).path);
+}
+
+
+export const imageName = (url) => {
+ if(!url){
+ return ""
+ }
+ try {
+ const parsed = URI.parse(decodeURIComponent(url));
+ const pParsed = path.parse(parsed.path);
+ return sanitize(decodeURIComponent(pParsed.base));
+ } catch (error) {
+ console.error('error image name : ',url)
+ return ""
+ }
+}
+export const downloadFile = async (_url:string, dir:string) =>{
+ return download(_url, dir, {
+ filename: imageName(_url)
+ })
+}
\ No newline at end of file
diff --git a/packages/discourse/src/lib/sync/file.ts b/packages/discourse/src/lib/sync/file.ts
new file mode 100644
index 00000000..52565697
--- /dev/null
+++ b/packages/discourse/src/lib/sync/file.ts
@@ -0,0 +1,314 @@
+import * as path from 'path'
+import { sync as exists } from "@plastichub/fs/exists"
+import { async as move } from "@plastichub/fs/move"
+import { sync as dir } from "@plastichub/fs/dir"
+import { sync as write } from "@plastichub/fs/write"
+import { sync as read } from "@plastichub/fs/read"
+
+import { resolve } from "@plastichub/osr-commons"
+
+import { Promise as BPromise } from 'bluebird'
+import { IOptionsSync, IDiscoursePostBaseOptions } from '../../types'
+import { imageName, downloadFile } from './download'
+
+
+const YAML = require('json-to-pretty-yaml')
+const cheerio = require('cheerio');
+
+import { toHTML } from '../markdown'
+
+import {
+ SYNC_TRACK_FILENAME
+} from '../discourse/constants'
+
+import {
+ cacheCategories,
+ cacheTags,
+ cacheTopics,
+ cacheUsers
+} from '../discourse/cache'
+
+import {
+ Discourser,
+ Instance
+} from '../discourse'
+
+import {
+ fromYAML
+} from './commons'
+
+import { EDiscourseConfigKey } from "lib/discourse/constants"
+import { ISearchPost, ISearchTopic, logger } from "../../index"
+
+import * as md5 from 'md5'
+
+export const createTopic = async (discourse: Discourser, options: IOptionsSync, content) => {
+
+ let data: any
+ try {
+ data = await discourse.createPost(options.title, content, options.cat as number)
+ } catch (e) {
+ debugger
+ }
+
+ if (data) {
+ logger.debug('created topic : ' + options.title + ' : ' + data.id)
+ if (data && data.id) {
+
+ try {
+ options.post_id = data.id;
+ options.topic_id = data.topic_id
+ await discourse.changeOwner(options.post_id, options.topic_id, options.user_name)
+ } catch (e) {
+ logger.error('changing owner ' + options.title + ' failed!', e)
+ }
+ } else {
+ logger.debug('creating ' + options.title + ' failed!', data.errors);
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ logger.error('title already used : ' + options.title)
+ }
+ }
+ }
+ }
+}
+
+export const updateTopic = async (discourse: Discourser, options: IOptionsSync, topic_id, content) => {
+
+ let data: any
+ try {
+ data = await discourse.updatePost(topic_id, content)
+ } catch (e) {
+
+ }
+
+ if (data) {
+ logger.debug('created topic : ' + options.title + ' : ' + data.id)
+ if (data && data.id) {
+ try {
+ logger.debug('change user to ', options.owner);
+ options.post_id = data.id;
+ options.topic_id = data.topic_id
+ await discourse.changeOwner(topic_id, topic_id, options.user_name)
+ } catch (e) {
+ logger.debug('changing owner ' + options.title + ' failed!')
+
+ }
+ } else {
+ logger.debug('creating ' + options.title + ' failed!', data.errors)
+ if (data.errors) {
+ if (data.errors[0] && data.errors[0] === 'Title has already been used') {
+ logger.error('title already used : ' + options.title)
+ }
+ }
+ }
+ }
+}
+
+const images_urls = (content: string) => {
+ const html = toHTML(content)
+ const $ = cheerio.load(html, {
+ xmlMode: true
+ });
+
+ const images = []
+ const links = []
+ $('img').each(function () {
+ images.push($(this).attr('src'))
+ })
+
+ return images
+}
+
+const uploadImages = async (content: string, discourse: Discourser, options: IOptionsSync) => {
+
+ const root = path.resolve(resolve(options.root))
+ if (!exists(root)) {
+ return false
+ }
+
+ const track_path = path.join(root, SYNC_TRACK_FILENAME)
+ const track = read(track_path, 'json') || {}
+
+ const html = toHTML(content)
+ const $ = cheerio.load(html, {
+ xmlMode: true
+ });
+
+ const images = images_urls(content)
+
+ $('img').each(function () {
+ images.push($(this).attr('src'))
+ })
+
+ for await (const image of Object.entries(images)) {
+
+ const url: string = image[1]
+
+ if (url.startsWith('upload:')) {
+ continue
+ }
+ if (options.uploadRemote && url.startsWith('http')) {
+
+ const contentHash = md5(content).substring(0, 5)
+ const cache_path = path.resolve(resolve('${OSR_CACHE}/discourse-downloads/' + contentHash))
+ if (!exists(cache_path)) {
+ dir(cache_path)
+ }
+ const image_name = imageName(url)
+ const image_local = path.join(cache_path, image_name)
+ if (!exists(image_local)) {
+ await downloadFile(url, cache_path)
+ }
+
+ if (exists(image_local)) {
+ const upped: any = await discourse.uploadFile(options.owner, image_local)
+ const data = upped.data;
+ if (data && data.id) {
+ track[url] = data
+ write(track_path, track)
+ } else {
+ console.error('error uploading image')
+ }
+ }
+
+ continue
+ }
+
+ if (options.uploadLocal) {
+ const image_path = path.join(root, url)
+ if (exists(image_path) && !track[url]) {
+ const upped: any = await discourse.uploadFile(options.owner, image_path)
+ const data = upped.data;
+ if (data && data.id) {
+ track[url] = data
+ write(track_path, track)
+ } else {
+ console.error('error uploading image')
+ }
+ }
+ }
+ }
+
+ return track
+}
+
+const syncFile = async (file: string, options: IOptionsSync) => {
+
+ const discourse = Instance(null, options.config as EDiscourseConfigKey)
+
+ let content = read(file) as string
+
+ const fm: any = fromYAML(content, options) || {}
+
+ let body = "" + fm.body
+
+ let images_track
+
+ if (options.uploadLocal || options.uploadRemote) {
+ images_track = await uploadImages(body, discourse, options)
+ const image_urls = images_urls(body)
+ image_urls.forEach((i) => {
+ if (images_track[i])
+ body = body.replace(i, images_track[i].short_url)
+ })
+ }
+ write('./out/md.md', body)
+
+ let dOpts: IDiscoursePostBaseOptions = options.yaml ? fm.attributes : {
+ cat: options.cat,
+ id: options.id,
+ owner: options.owner,
+ tags: options.tags,
+ title: options.title
+ }
+
+ options = {
+ ...options,
+ ...dOpts
+ }
+
+ const cats = await cacheCategories(options, discourse)
+ const tags = await cacheTags(options, discourse)
+ const users = await cacheUsers(options, discourse)
+ const search = await discourse.search(dOpts.title)
+
+ let post_id, topic_id
+ if (options.yaml) {
+ post_id = dOpts.post_id
+ topic_id = dOpts.topic_id
+ }
+
+
+ let dTopic: ISearchTopic
+ let dPost: ISearchPost
+
+ if (search.posts && search.topics
+ && search.posts[0] && search.topics[0]
+ && search.topics[0].title === dOpts.title) {
+ dPost = search.posts[0]
+ dTopic = search.topics[0]
+ topic_id = dTopic.id
+ post_id = dPost.id
+ } else if (post_id && topic_id) {
+
+ }
+
+ const user = users.find((u) => {
+ return u.id === dOpts.owner
+ })
+
+ if (!user) {
+ logger.error('Invalid user : ', dOpts.owner)
+ return false
+ }
+
+ options.user_name = user.username
+
+ let topic = null
+ if (post_id) {
+ topic = await updateTopic(discourse, options, post_id, body)
+ if (topic_id) {
+ topic = await discourse.updateTopic(topic_id, dOpts.cat as number, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : [])
+ }
+ } else {
+ await createTopic(discourse, options, body)
+ topic_id = options.topic_id
+ post_id = options.post_id
+
+ await discourse.updateTopic(topic_id, dOpts.cat as number, dOpts.title, dOpts.tags ? dOpts.tags.split(',') : [])
+ }
+
+ if (dTopic) {
+ options.topic_id = dTopic.id
+ }
+ if (dPost) {
+ options.post_id = dPost.id
+ }
+
+
+ if (options.yaml) {
+ let contentOut = `---\n`
+ contentOut += YAML.stringify({
+ ...fm.attributes,
+ topic_id: topic_id,
+ post_id: post_id
+ })
+ contentOut += `---\n`
+ contentOut += fm.body
+ write(file, contentOut)
+ }
+ return content
+
+}
+
+export const syncYAML = async (options: IOptionsSync) => {
+ await BPromise.resolve(options.srcInfo.FILES).map((f) => {
+ return syncFile(f, options)
+ }, { concurrency: 1 })
+
+}
+
+export const sync = async (options: IOptionsSync) => {
+ return syncYAML(options)
+}
diff --git a/packages/discourse/src/lib/sync/index.ts b/packages/discourse/src/lib/sync/index.ts
new file mode 100644
index 00000000..54f1fc40
--- /dev/null
+++ b/packages/discourse/src/lib/sync/index.ts
@@ -0,0 +1,55 @@
+import * as path from 'path'
+import { sync as read } from "@plastichub/fs/read"
+import {
+ SYNC_TRACK_FILENAME
+} from '../discourse/constants'
+
+import { sync as exists } from "@plastichub/fs/exists"
+import { async as move } from "@plastichub/fs/move"
+import { sync as dir } from "@plastichub/fs/dir"
+import { sync as write } from "@plastichub/fs/write"
+
+import { resolve } from "@plastichub/osr-commons"
+
+import { Promise as BPromise } from 'bluebird'
+import { IOptionsSync, IDiscoursePostBaseOptions } from '../../types'
+
+import { createContent } from './osrl'
+
+const YAML = require('json-to-pretty-yaml')
+const cheerio = require('cheerio')
+const findUp = require('find-up')
+const frontMatter = require('front-matter')
+
+import { imageName, downloadFile } from './download'
+import { IComponentConfig } from '@plastichub/osr-commons'
+import { isValidLibraryComponent, readOSRConfig } from '@plastichub/osr-fs-utils'
+
+export const trackingPath = (root) =>
+ path.join(root, SYNC_TRACK_FILENAME)
+
+
+export const tracking = (root) =>
+ read(trackingPath(root), 'json') || {}
+
+export const defaultConfig = (configFile: string, options: IOptionsSync): IComponentConfig => {
+ let defaultsJSON = findUp.sync('defaults.json', {
+ cwd: path.parse(configFile).dir,
+ stopAt: options.root
+ })
+ if (defaultsJSON) {
+ return readOSRConfig(defaultsJSON)
+ }
+ return {
+
+ } as IComponentConfig
+}
+
+export const fromJSON = (configFile: string, options: IOptionsSync): IComponentConfig => {
+ const defaults = defaultConfig(configFile, options)
+ const config = readOSRConfig(configFile)
+ return {
+ ...defaults,
+ ...config
+ }
+}
\ No newline at end of file
diff --git a/packages/discourse/src/lib/sync/osrl.ts b/packages/discourse/src/lib/sync/osrl.ts
new file mode 100644
index 00000000..5156341e
--- /dev/null
+++ b/packages/discourse/src/lib/sync/osrl.ts
@@ -0,0 +1,80 @@
+import * as path from 'path'
+import { IOptions } from '@plastichub/osrl/types'
+import { Engine as engine } from '@plastichub/osrl/Engine'
+import { parse } from '@plastichub/osrl/options'
+
+import { forward_slash } from '@plastichub/osr-cli-commons/glob'
+
+import { resolve } from '@plastichub/osr-commons'
+
+import { IOptionsSyncComponent } from '../../'
+import { logger } from '../../index'
+import { git_status } from '../git'
+import * as moment from 'moment'
+import { sync as read } from '@plastichub/fs/read'
+
+export const fileAsBuffer = (path: string) => read(path, 'buffer') as Buffer || Buffer.from("-")
+const variable_extras = async (component, rel, options: IOptionsSyncComponent) => {
+ const root = path.resolve(resolve('${OSR_LIBRARY_MACHINES}'))
+ const gitStats = await git_status(root, rel)
+ const latest = gitStats.latest
+ return {
+ "GIT_LAST": moment(latest.date ).format('LLLL'),
+ "GIT_AUTHOR" : latest.author_name,
+ "GIT_MESSAGE": latest.message,
+ "GIT_COMMIT" : latest.hash
+ }
+}
+
+export const createContent = async (component, _options: IOptionsSyncComponent) => {
+
+ const parts = path.parse(component)
+ const rel = forward_slash(path.relative(_options.root, component))
+ const extras = await variable_extras(component,rel, _options)
+ const variables = {
+ root: _options.root,
+ cwd: _options.cwd,
+ ..._options.variables,
+ product: rel,
+ product_rel: rel,
+ product_rel_min: rel,
+ ...extras
+ }
+ const defaults: any = {
+ language: _options.language,
+ debug: false,
+ profile: _options.profile,
+ // output: output,
+ plugins: [],
+ env: _options.env || 'forum',
+ cwd: _options.cwd,
+ source: _options.src,
+ variables
+ }
+ const options = parse(defaults, defaults);
+ const eOptions = {
+ ...options,
+ root: [
+ ...options.profile.includes,
+ component
+ ],
+ toHTML: false,
+ cache: false,
+ keepOutputType: true,
+ trimTagRight: false,
+ trimTagLeft: false,
+ trimOutputRight: false,
+ trimOutputLeft: false,
+ greedy: false
+ } as IOptions
+
+ const Engine = new engine(eOptions);
+
+ options.debug && logger.info('Compile file ' + component, eOptions)
+
+ let content = await Engine.render(options.source, {
+ ...options.variables,
+ ...extras
+ })
+ return content
+}
diff --git a/packages/discourse/src/main.ts b/packages/discourse/src/main.ts
new file mode 100644
index 00000000..1d3d991a
--- /dev/null
+++ b/packages/discourse/src/main.ts
@@ -0,0 +1,22 @@
+#!/usr/bin/env node
+process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
+
+import { defaults } from './_cli'; defaults();
+import * as cli from 'yargs';
+import { register as registerInfo } from './commands/info'; registerInfo(cli)
+import { register as registerQuery } from './commands/query'; registerQuery(cli)
+
+import { register as registerOAImport } from './commands/import-oa-users'; registerOAImport(cli)
+import { register as registerOAImportHowtos } from './commands/import-oa-howtos'; registerOAImportHowtos(cli)
+
+import { register as registerSync } from './commands/sync-file'; registerSync(cli)
+import { register as registerSyncComponent } from './commands/sync-component'; registerSyncComponent(cli)
+
+const argv: any = cli.argv;
+
+if (argv.help) {
+ cli.showHelp();
+ process.exit();
+} else if (argv.v || argv.version) {
+ process.exit();
+}
diff --git a/packages/discourse/src/options.ts b/packages/discourse/src/options.ts
new file mode 100644
index 00000000..e526b3df
--- /dev/null
+++ b/packages/discourse/src/options.ts
@@ -0,0 +1,33 @@
+import * as path from 'path'
+
+import { resolveConfig } from '@plastichub/core'
+
+// import * as deepmerge from '@plastichub/core/deepmerge'
+
+import { clone, deepClone } from '@plastichub/core/objects'
+
+export * from './lib'
+
+import { IOptions } from './types'
+
+
+export const parse = (options: IOptions, argv: any): IOptions => {
+
+ for (const k in argv) {
+ if (!(k in options.variables) && k !== '_'
+ && k !== '$0'
+ && k !== 'variables'
+ && k !== 'src'
+ && k !== 'format'
+ && k !== 'profile'
+ && k !== 'output') {
+ options.variables[k] = argv[k];
+ }
+ }
+
+ options.variables['cwd'] = options.variables['cwd'] ? options.variables['cwd'] : options.cwd
+ resolveConfig(options.variables)
+ let variables = {}
+ options.pathVariables = variables
+ return options
+}
\ No newline at end of file
diff --git a/packages/discourse/src/types.ts b/packages/discourse/src/types.ts
new file mode 100644
index 00000000..0cdd8642
--- /dev/null
+++ b/packages/discourse/src/types.ts
@@ -0,0 +1,214 @@
+import { IObjectLiteral } from '@plastichub/core';
+
+import { I_OSR_USER } from '@plastichub/osr-commons'
+
+import { PATH_INFO, PATH_VARIABLES, SRC_VARIABLES } from '@plastichub/osr-cli-commons'
+
+import { IDiscourseConfig } from '@plastichub/osr-cli-commons/types'
+
+import {
+ IBaseOptions as IOSRLBaseOptions,
+ IProfile as IOSRLProfile
+
+} from '@plastichub/osrl'
+
+import { EDiscourseConfigKey } from 'lib/discourse/constants'
+import { IProcessingNode } from '@plastichub/fs/interfaces'
+import { TFindFilter } from '@plastichub/osr-fs-utils'
+
+export interface Hash {
+ [id: string]: T
+}
+
+export type IOptions = {
+ src: string
+ id: string
+ cat: string
+ track: string
+ variables: Hash
+ cwd: string
+ env: string
+ verb: string
+ debug: boolean
+ disabled: boolean
+ dry?: boolean
+ all?: boolean
+ stdout: boolean
+ pathVariables: Hash
+}
+
+///////////////////////////////////////////////////////
+//
+// Sync Types
+//
+
+/**
+ * An enumeration to narrow a conflict resolve to a single item or for all following conflicts.
+ *
+ * @export
+ * @enum {number}
+ */
+export enum EResolve {
+ /**
+ * Always will use the chose conflict settings for all following conflicts.
+ */
+ ALWAYS,
+ /**
+ * 'This' will use the conflict settings for a single conflict so the conflict callback will be triggered again for the next conflict.
+ */
+ THIS
+}
+
+/**
+ * The possible modes to resolve a conflict during a sync
+ *
+ * @export
+ * @enum {number}
+ */
+export enum EResolveMode {
+ SKIP = 0,
+ OVERWRITE,
+ IF_NEWER,
+ IF_SIZE_DIFFERS,
+ THROW,
+ RETRY,
+ ABORT
+}
+export interface IConflictSettings {
+ /**
+ * How to resolve this conflict/error.
+ *
+ * @type {EResolveMode}
+ * @memberOf IConflictSettings
+ */
+ overwrite: EResolveMode
+ /**
+ * The scope of this conflict resolver: always or this.
+ *
+ * @type {EResolve}
+ * @memberOf IConflictSettings
+ */
+ mode: EResolve
+ /**
+ * Track the origin error type for this settings.
+ *
+ * @type {string}
+ * @memberOf IConflictSettings
+ */
+ error?: string
+}
+
+export type EMergeConflictMode = 'theirs' | 'mine'
+
+export type EPostType = 'post' | 'reply'
+
+export type ISyncNodeReport = IProcessingNode & {
+
+}
+
+export interface IDiscoursePostBaseOptions {
+ title?: string
+ id?: string
+ cat?: string | number
+ tags?: string
+ owner?: string | number
+ timestamp?: string | number | Date
+ uploadLocal?: boolean
+ uploadRemote?: boolean
+ yaml?: boolean
+ post_id?: number
+ topic_id?: number
+ type?: EPostType
+ user_name?: string
+}
+
+export type IOptionsSync = IDiscoursePostBaseOptions & IOSRLBaseOptions & {
+
+ // common options
+ debug?: boolean
+ verbose?: boolean
+ logLevel?: string
+ skip?: boolean
+ alt?: boolean
+ src?: string
+ verb: string
+
+ // cache options
+ cache?: boolean
+
+ filter?: TFindFilter | string
+
+ // OSR - Config Discorse Key
+ config?: string | EDiscourseConfigKey
+
+ // internals
+ pathVariables?: Hash
+ variables?: SRC_VARIABLES
+
+ repo?: string
+ root?: string
+
+ product_root?: string
+
+ // parsed options
+ srcInfo?: PATH_INFO
+
+ //tracking
+ post_id?: number
+ topic_id?: number
+
+}
+
+export type IOptionsSyncComponent = IOptionsSync &
+{
+ format?:string
+ module?:string
+ plugins?:string
+ onCompiled?: () => void
+ onCompileDone?: () => void
+ cache?: boolean
+ skip?: boolean
+
+}
+
+
+//////////////////////////////////////////////////////////////////
+//
+// Basic types
+//
+
+export interface IDBConfig {
+ user: string
+ password: string
+ database: string
+ host: string
+ prefix: string
+}
+
+
+export interface IDiscourseUser {
+ id: number
+ username: string
+ name: string
+ avatar_template: string
+ active: boolean
+ admin: boolean
+ moderator: boolean
+ last_seen_at: any
+ last_emailed_at: string
+ created_at: string
+ last_seen_age: any
+ last_emailed_age: number
+ created_at_age: number
+ trust_level: number
+ manual_locked_trust_level: any
+ flag_level: number
+ title: any
+ time_read: number
+ staged: boolean
+ days_visited: number
+ posts_read_count: number
+ topics_entered: number
+ post_count: number
+ detail: any
+}
diff --git a/packages/discourse/temp/h.json b/packages/discourse/temp/h.json
new file mode 100644
index 00000000..3c3190ec
--- /dev/null
+++ b/packages/discourse/temp/h.json
@@ -0,0 +1 @@
+"{\"env\":\"forum\",\"forumTags\":\"extrusion\",\"forumCategory\":51,\"Preview3d\":true,\"howtoSection\":\"https://forum.osr-plastic.org/tags/c/kb/54/injection\",\"download\":\"${OSR_FILES_WEB}/${product_rel_min}\",\"product_dimensions\":\"${OSR_MACHINES_ASSETS_URL}/${product_rel}/drawings/dimensions.jpg\",\"preview\":\"${OSR_MACHINES_ASSETS_URL}/${product_rel}/media/latest.jpg\",\"product_parts\":\"${OSR_MACHINES_ASSETS_URL}/${product_rel_min}/drawings/parts.jpg\",\"edrawings\":\"${OSR_MACHINES_ASSETS_URL}/${product_rel_min}/resources/edrawings.html\",\"forumUserId\":1,\"hasSpecs\":true,\"slug\":\"lydia-mini\",\"version\":\"1.0\",\"category\":\"extrusion\",\"code\":\"LMI\",\"name\":\"Lydia-Mini\",\"parts\":\"parts.csv\",\"opensource\":true,\"bestseller\":true,\"showDimensions\":false,\"showParts\":false,\"cscartId\":13,\"authors\":[{\"name\":\"PlasticHub S.L.\",\"url\":\"${author_link}\"},{\"name\":\"Jason Knight\",\"url\":\"https://www.mandin.earth/\"}],\"forumTopicId\":10117,\"forumPostId\":27525,\"forumPostHash\":\"7473a5ff4f3b11604d0b4f1dee24c4dc\",\"image\":\"${product_rel}/renderings/perspective.jpg\",\"config\":{\"includes\":[\"${root}/osr\",\"${root}/osr/widgets\",\"${OSR_ROOT}/osr-templates/commons\",\"${OSR_ROOT}/osr-templates/discourse\",\"${OSR_ROOT}/osr-templates/discourse/commons\",\"${OSR_ROOT}/osr-templates/discourse/widgets\",\"${PRODUCT_ROOT}\",\"${PRODUCT_ROOT}/templates/site/\",\"${PRODUCT_ROOT}/templates/shared/\"],\"variables\":{\"PRODUCT_ROOT\":\"${root}/${product}/\",\"abs_url\":\"https://assets.osr-plastic.org\",\"CACHE\":\"${root}/cache/\",\"GIT_REPO\":\"https://git.osr-plastic.org/osr-plastic/osr-machines\",\"OSR_MACHINES_ASSETS_URL\":\"https://assets.osr-plastic.org/machines/\",\"PRODUCTS_ASSETS_URL\":\"https://assets.osr-plastic.org/machines/${product}\",\"OSR_FILES_WEB\":\"http://files.osr-plastic.org/files/osr-machines\",\"PRODUCTS_FILES_URL\":\"${OSR_FILES_WEB}/${product_rel}\",\"vendor_name\":\"Plastic Hub\",\"vendor_website\":\"https://osr-plastic.org/\",\"vendor_products_external\":\"https://plastic-hub.com/products/\",\"vendor_instagram\":\"https://www.instagram.com/osr_plastic/\",\"_vendor_youtube\":\"https://www.youtube.com/channel/UCuWDxJtV2pf5BefHEy09Cew/featured?view_as=subscriber\",\"vendor_github\":\"https://git.osr-plastic.org/osr-plastic\",\"vendor_contact_email\":\"mailto:sales2@plastic-hub.com\",\"vendor_whatsapp\":\"tel:0034691952287\",\"vendor_facebook\":\"https://www.facebook.com/plastichubcat/\",\"vendor_discord\":\"https://discord.gg/vR5d6ShTez\",\"author_link_pp\":\"https://preciousplastic.com/\",\"author_link\":\"https://osr-plastic.org\",\"vendor_forum\":\"https://forum.osr-plastic.org\",\"OSR_HOWTOS_ROOT_URL\":\"${vendor_forum}/c/wiki/howtos/72\",\"OSR_HOWTOS_PATH\":\"../../ph3/pp-next2/howtos\",\"show\":{\"badges\":false,\"authors\":true,\"head\":true,\"debug\":false,\"wiki\":false,\"forum\":false,\"others\":false,\"howtos\":false,\"instagram\":false,\"shipping\":false,\"payment_terms\":false,\"components\":true,\"marketplaceLinks\":true,\"productDump\":true,\"configDump\":false,\"issues\":false,\"alternatives\":true,\"replacedBy\":true,\"meta\":true}},\"env\":{\"bazar\":{\"includes\":[],\"variables\":{\"abs_url\":\"https://dev.osr-plastic.org/\"}},\"bazar-release\":{\"includes\":[],\"variables\":{\"abs_url\":\"https://shop.osr-plastic.org/\"}},\"test-import\":{},\"forum\":{\"includes\":[],\"variables\":{\"forum_url\":\"https://forum.osr-plastic.org/\",\"show\":{\"badges\":true,\"authors\":true,\"head\":true,\"debug\":false,\"wiki\":false,\"forum\":false,\"others\":false,\"howtos\":true,\"instagram\":false,\"shipping\":false,\"payment_terms\":false,\"components\":true,\"marketplaceLinks\":true,\"meta\":true,\"productDump\":true,\"configDump\":false}}}}},\"OSR_ROOT\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr\",\"OSR_TEMP\":\"C:\\\\Users\\\\mc007\\\\AppData\\\\Local\\\\Temp\\\\osr\",\"PRODUCT_ROOT\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr\\\\osr-machines/extrusion/lydia-mini/\",\"OA_ROOT\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\ph3\\\\pp-next2\",\"KB_ROOT\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr\\\\osr-kb-next\",\"OSR_CACHE\":\"C:\\\\Users\\\\mc007\\\\.osr\\\\cache\",\"OSR_LIBRARY_MACHINES\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr\\\\osr-machines\",\"OSR_USER_ASSETS\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr\\\\osr-user-assets\",\"OSR_PRIVATE\":\"C:\\\\Users\\\\mc007\\\\.osr\\\\\",\"OSR_TEMPLATES\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr\\\\osr-templates\",\"OSR_CONTENT\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr\\\\osr-content\",\"OSR_PROFILES\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr\\\\osr-profiles\",\"root\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr\\\\osr-machines\",\"cwd\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr\\\\osr-discourse\",\"SRC_PATH\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr/osr-templates/discourse/root.html\",\"SRC_DIR\":\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr/osr-templates/discourse\",\"SRC_NAME\":\"root\",\"SRC_FILE_NAME\":\"root.html\",\"SRC_FILE_EXT\":\"html\",\"SRC_IS_FILE\":true,\"SRC_IS_FOLDER\":false,\"SRC_IS_EXPRESSION\":false,\"SRC_IS_GLOB\":false,\"SRC_GLOB\":\"**/config.+(json)\",\"SRC_GLOB_EXTENSIONS\":[\"json\"],\"SRC_FILES\":[\"C:\\\\Users\\\\mc007\\\\Desktop\\\\osr/osr-templates/discourse/root.html\"],\"product\":\"extrusion/lydia-mini\",\"product_rel\":\"extrusion/lydia-mini\",\"product_rel_min\":\"extrusion/lydia-mini\",\"GIT_LAST\":\"Thursday, July 27, 2023 6:34 AM\",\"GIT_AUTHOR\":\"lovebird\",\"GIT_MESSAGE\":\"extrusion : meta | Filament :)\",\"GIT_COMMIT\":\"4f02ac6173b6aac8022600d4cfcf424d1121c61d\",\"debug\":false}"
\ No newline at end of file
diff --git a/packages/discourse/temp/l.md b/packages/discourse/temp/l.md
new file mode 100644
index 00000000..7d45fb64
--- /dev/null
+++ b/packages/discourse/temp/l.md
@@ -0,0 +1 @@
+"In this How-to we’re going to guide you through all the steps to set up an Extrusion Workspace. Learn about plastic, how to find a space, get the Extrusion machine, find customers and connect to the Precious Plastic Universe. Step 1-3: Intro Step 4-9: Learn Step 10-19: Set up Step 20-25: Run Step 26-29: Share\n\n\n\n---\n\n\n\n#### Attachments\n\n\n\n#### Resources\n\n- [Browse Files](http://files.osr-plastic.org/files/howtos/set-up-an-extrusion-workspace/)\n\n#### 3D Files\n\n\n\n---\n\nStep 1 - Role \n\n\n First of all, make sure you had a look at the showcase page of this Starterkit! \n\n preciousplastic.com/starterkits/showcase/extrusion \n\n \n\nNow about your Role: \n\n \n\nExtrusion workspaces buy recycled shredded plastic (from Shredder Workspaces or from the Bazar) and transform it into recycled beams and bricks, or whatever other useful material and products you can come up with. \n\n \n\nThe recycled plastic material can then be sold as raw material for others to create, or maybe you even turn them into valuable objects yourself. \n\n \n\nExtrusion workspaces should also reach out to Community Point to connect with the local Precious Plastic community and, maybe, get help selling their materials.\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 2 - Outcomes \n\n\n The outcome of an Extrusion Workspace can be recycled plastic beams, bricks or other material (there are a lot of possibilites). \n\n \n\nThe beams can be of various sizes and shapes, and as long as needed. Make sure you don't miss playing around with different gradients and colours to make create a playful variety of outcomes.\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 3 - Is this for you? \n\n\n For the Extrusion Workspace you will have to be quite technical as you have to understand how the Extrusion machine works, ideally know how to maintain it and, as a plus, know how to fix it when it needs a bit of extra love. \n\n \n\nAttention to details is also a nice, and some creativity to come up with new patterns and techniques.\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 4 - Learn about Precious Plastic \n\n\n As a start, it’s super important to really know and understand Precious Plastic. What drives the project, how it works, its philosophy and solutions. \n\n \n\nIf you haven’t already, dig our website, community platform and Bazar to have a deep understanding of the project. \n\n preciousplastic.com \n\n community.preciousplastic.com \n\n bazar.preciousplastic.com \n\n \n\nAlso, make sure to check the Universe chapter to fully understand how the Precious Plastic Universe works. \n\n community.preciousplastic.com/academy/universe\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 5 - Check out your area \n\n\n Get an overview of who and what is already existing in your area. \n\n \n\nHave a look on the Precious Plastic Map to see the activity around you. You can also search for more people on the Precious Plastic Bazar or search for #preciousplastic on social media. \n\n \n\nMake sure not to jam the local network, if there are already many Extrusion Workspaces around, have a chat about collaboration with them first, or maybe consider starting another type of space. \n\n \n\n community.preciousplastic.com/map\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 6 - Find a Community Point near you \n\n\n Community Points are the glue of the Precious Plastic Universe. They know the ins and outs of your local network. They can help you in multiple ways but they generally have a very in-depth overview of local Precious Plastic spaces, people, useful shops, resources and can help you with planning out your project. You can find them on the map here. \n\n \n\n community.preciousplastic.com/map\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 7 - Find your plastic supply \n\n\n You can use the Precious Plastic Map and the Bazar to find Shredder workspaces around you that can provide you with the raw material: shredded plastic waste. \n\n \n\nIf you have a local Community Point, they might be able to give you a hand with this as well. \n\n \n\n community.preciousplastic.com/map \n\n bazar.preciousplastic.com\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 8 - Get on Discord \n\n\n Day to day discussions in the Precious Plastic Universe happen on Discord. \n\n \n\nIntroduce yourself, say hi in your country channel and start to discover the different channels where people go deep into specific topics (building, collection, design etc..) \n\n \n\nJoin the Discord: \n\n discordapp.com/invite/rnx7m4t\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 9 - Learn the basics of plastic \n\n\n Before you start it is crucial to get a solid understanding of plastic. How it works, the different types, melting temperatures and so on. Head over to our Academy and dive into the plastic chapters to learn about the different types and properties etc. \n\n \n\n community.preciousplastic.com/academy/plastic/basics\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 10 - Fill in the Action Plan \n\n\n Before jumping into making machines or finding a space it is smart to sit down and properly plan your project and shape your vision. \n\n \n\nTo help you plan we’ve made a graphic tool called the Action Plan that helps you to craft your mission, understand your customers, revenue streams, costs and much more. With this tool, you should get a step closer to create a successful project. \n\n \n\nYou can find the Action Plan in the Download Kit or learn more in the Academy \n\n community.preciousplastic.com/academy/business/actionplan\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 11 - Workspace Calculator \n\n\n Now you have your project nicely planned out and it’s starting to take shape in your mind. \n\n \n\nIt is important at this stage to make a serious estimation of how much it will cost you to set up and run your workspace. Otherwise, you might run out of money halfway. The Workspace Calculator is a spreadsheet that helps you do just that. \n\n \n\nYou can find the Workspace Calculator in the Download Kit or learn more in the Academy: \n\n community.preciousplastic.com/academy/business/workspacecalculator\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 12 - Business Plan Template \n\n\n To help you pitch your idea to potential partners, financial institutions or investors we made a Business Plan Template (and a specific example for the Extrusion Workspace) for you to use. \n\n \n\nThis template helps you to talk the business language and should help you access the necessary money to begin. \n\n \n\nFor more explanation check out the video in the Academy: \n\n community.preciousplastic.com/academy/business/businessplan\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 13 - Tool list \n\n\n Alongside your Extrusion machine, you will need a number of other tools and machines to help you with the operations of the Extrusion Workspace. \n\n \n\nIn the Download Kit, you will find a tool list with all the necessary tools to run your workspace.\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 14 - Find the space \n\n\n To help you find the perfect place for your workspace you can use the floor plan in the Download Kit, with all the minimum requirements and a little cardboard tool to place your machines and tools in the workspace.\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 15 - Get your extrusion \n\n\n Cool, now you have a space it’s time to get hold of your Extrusion machine. There are three ways to do that: \n\n \n\n1 Build it yourself following our tutorials \n\n community.preciousplastic.com/academy/build/extrusionprobuild \n\n \n\n2 Buy it on the Bazar. \n\n bazar.preciousplastic.com \n\n \n\n3 Find a Machine Shop near you on the map that can build it for you. \n\n community.preciousplastic.com/map\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 16 - Build your space \n\n\n Super, you’ve got your Extrusion! But an Extrusion alone is not enough. \n\n \n\nYou can watch our video on how to fully set up your Extrusion workspace with all the additional tools, furniture and posters needed to make your space ready. \n\n \n\n community.preciousplastic.com/academy/spaces/extrusion\n
\n\n \n\n\n\n \n\n \n\n\nStep 17 - Safety \n\n\n Always stay safe! \n\n \n\nOf course, Extrusion machines get hot. And can cause a hazard in different ways. \n\n \n\nSo before starting to melt, please check out our safety video to learn about dangers and how to stay safe when working with plastic. \n\n \n\n community.preciousplastic.com/academy/plastic/safety\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 18 - Buy shredded plastic \n\n\n Buy shredded plastic \n\n- from a local Shredder Workspace \n\ncommunity.preciousplastic.com/map \n\n- or from the Bazar \n\nbazar.preciousplastic.com \n\n \n\nMake sure to specify your preferred shreds size (small, medium or large) and to have a variety of colours and types.\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 19 - Time to produce! \n\n\n Now that you have all the things in place it’s time to start making your recycled plastic material. Watch this video to learn how to make beams and adopt the best practices. \n\n \n\nYou can also find tutorials and ideas for other products in the How-to's under the tag "extrusion".\n
\n\n \n\n\n\n \n\n \n\n\nStep 20 - Make a variety \n\n\n Once you get a grasp on the process make sure to make a nice variety of colours, sizes and thicknesses to attract different customers.\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 21 - Maintenance \n\n\n As you run your Extrusion Workspace it is crucial that you maintain the Extrusion machines in order to prevent failures. Find out here how to best maintain the Extrusion.\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 22 - Sell your beams \n\n\n You can now make beautiful beams. Many every day. Now is crucial to find people and organisations that want to buy your recycled beams. \n\n \n\nFirst, you should put them on the Precious Plastic Bazar to access an audience that is already interested in recycled products. Then you have to get creative on how to sell your beams locally. Shops, design studios, online stores and more.\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 23 - Create your profile \n\n\n If you haven’t already, it’s time to create your profile on the Precious Plastic Community Platform to connect with people. Follow this link and sign up with your email, pick your role, put your pin on the map and upload nice pics to show the world what you’re doing.\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 24 - Create How-tos! \n\n\n Share to the world how you run your Extrusion Workspace so other people can learn from you and start using your solution to tackle the plastic problem. \n\n \n\nMake sure to only create How-tos for your best processes and techniques, not tryouts or one-offs. This can also help you create a name for yourself in the Precious Plastic community. \n\n \n\n community.preciousplastic.com/how-to\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 25 - Stay active on Discord \n\n\n Precious Plastic is people. People working together and helping each other. Go to Discord and connect with people.\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 26 - Good things take time \n\n\n Starting off will take some time in the beginning. It’s normal. Be patience, work smart and reach out to your Precious Plastic community if you need help. Everything will take off. \n\nYou’re changing the world.\n
\n\n \n\n\n\n\n\n \n\n \n\n\nStep 27 - Download and start! \n\n\n Ready and excited to start? \n\nYou're a hero! \n\n \n\nIf you haven't done it yet, click on the yellow download button (in the top section of this page) to get the package with all the files you need to set up your Extrusion Workspace. \n\n \n\nDownload and start your recycling journey! :)\n
\n\n \n\n\n\n\n\n \n\n\n---\n\n\n\n---\n\n\n---\n"
\ No newline at end of file
diff --git a/packages/discourse/temp/post.html b/packages/discourse/temp/post.html
new file mode 100644
index 00000000..4402dbe1
--- /dev/null
+++ b/packages/discourse/temp/post.html
@@ -0,0 +1,969 @@
+
+
+
+
+
+ User & Service Directory Germany - Europe - OSR - Forum
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jerom
+ (Jerome)
+
+
+
+
+
+
+
+ 23 July 2023 09:44
+
+
+ 1
+
+
+
+
User & Service Directory Germany
+
Machine Builders
+
+
Services
+
Producers
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jerom
+ (Jerome)
+ Unlisted
+
+
+
+
+
+
+
+ 23 July 2023 14:23
+
+
+ 2
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ jerom
+ (Jerome)
+ Tags updated
+
+
+
+
+
+
+
+ 13 August 2023 15:07
+
+
+ 3
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/discourse/temp/t.json b/packages/discourse/temp/t.json
new file mode 100644
index 00000000..773dd4bf
--- /dev/null
+++ b/packages/discourse/temp/t.json
@@ -0,0 +1,7 @@
+{
+ "id": 10045,
+ "title": "OSR - Discourse Test sync:fs",
+ "fancy_title": "OSR - Discourse Test sync:fs",
+ "slug": "osr-discourse-test-sync-fs",
+ "posts_count": 3
+}
\ No newline at end of file
diff --git a/packages/discourse/temp/user.json b/packages/discourse/temp/user.json
new file mode 100644
index 00000000..1ccd8d76
--- /dev/null
+++ b/packages/discourse/temp/user.json
@@ -0,0 +1,447 @@
+{
+ id: 1000,
+ username: "grydis",
+ name: "grydis",
+ avatar_template: "/letter_avatar_proxy/v4/letter/g/7c8e57/{size}.png",
+ active: true,
+ admin: false,
+ moderator: false,
+ last_seen_at: null,
+ last_emailed_at: null,
+ created_at: "2022-02-20T11:40:17.110Z",
+ last_seen_age: null,
+ last_emailed_age: null,
+ created_at_age: 41038738.66242003,
+ trust_level: 1,
+ manual_locked_trust_level: null,
+ flag_level: 0,
+ title: null,
+ time_read: 0,
+ staged: false,
+ days_visited: 0,
+ posts_read_count: 0,
+ topics_entered: 0,
+ post_count: 8,
+ can_send_activation_email: true,
+ can_activate: false,
+ can_deactivate: true,
+ ip_address: "79.155.255.123",
+ registration_ip_address: "79.155.255.123",
+ can_grant_admin: true,
+ can_revoke_admin: false,
+ can_grant_moderation: true,
+ can_revoke_moderation: false,
+ can_impersonate: true,
+ like_count: 0,
+ like_given_count: 0,
+ topic_count: 0,
+ post_edits_count: null,
+ flags_given_count: 0,
+ flags_received_count: 0,
+ private_topics_count: 1,
+ can_delete_all_posts: true,
+ can_be_deleted: true,
+ can_be_anonymized: true,
+ can_be_merged: true,
+ full_suspend_reason: null,
+ silence_reason: null,
+ penalty_counts: {
+ silenced: 0,
+ suspended: 0
+ },
+ next_penalty: "2023-06-11T11:19:15.821Z",
+ primary_group_id: null,
+ badge_count: 2,
+ warnings_received_count: 0,
+ user_fields: {
+ 1: null,
+ 2: null,
+ 3: null,
+ 4: null,
+ 5: null
+ },
+ bounce_score: 0,
+ reset_bounce_score_after: null,
+ can_view_action_logs: true,
+ can_disable_second_factor: true,
+ can_delete_sso_record: false,
+ api_key_count: 0,
+ external_ids: { },
+ similar_users: [
+ {
+ id: 57,
+ username: "soumyaadhikary",
+ name: "soumyaadhikary",
+ avatar_template: "/letter_avatar_proxy/v4/letter/s/4491bb/{size}.png",
+ active: true,
+ admin: false,
+ moderator: false,
+ last_seen_at: null,
+ last_emailed_at: null,
+ created_at: "2022-02-19T19:46:37.993Z",
+ last_seen_age: null,
+ last_emailed_age: null,
+ created_at_age: 41095957.85595296,
+ trust_level: 1,
+ manual_locked_trust_level: null,
+ flag_level: 0,
+ title: null,
+ time_read: 0,
+ staged: false,
+ days_visited: 0,
+ posts_read_count: 0,
+ topics_entered: 0,
+ post_count: 1,
+ can_be_suspended: true,
+ can_be_silenced: true
+ },
+ {
+ id: 2851,
+ username: "katharinaelleke",
+ name: "katharinaelleke",
+ avatar_template: "/user_avatar/forum.osr-plastic.org/katharinaelleke/{size}/743_2.png",
+ active: true,
+ admin: false,
+ moderator: false,
+ last_seen_at: null,
+ last_emailed_at: "2023-03-05T09:53:16.582Z",
+ created_at: "2022-02-20T12:12:40.403Z",
+ last_seen_age: null,
+ last_emailed_age: 8385959.269099995,
+ created_at_age: 41036795.44807909,
+ trust_level: 2,
+ manual_locked_trust_level: null,
+ flag_level: 0,
+ title: null,
+ time_read: 0,
+ staged: false,
+ days_visited: 0,
+ posts_read_count: 0,
+ topics_entered: 0,
+ post_count: 53,
+ can_be_suspended: true,
+ can_be_silenced: true
+ },
+ {
+ id: 929,
+ username: "johnbusch",
+ name: "johnbusch",
+ avatar_template: "/user_avatar/forum.osr-plastic.org/johnbusch/{size}/323_2.png",
+ active: true,
+ admin: false,
+ moderator: false,
+ last_seen_at: null,
+ last_emailed_at: null,
+ created_at: "2022-02-20T11:39:46.879Z",
+ last_seen_age: null,
+ last_emailed_age: null,
+ created_at_age: 41038768.97448851,
+ trust_level: 1,
+ manual_locked_trust_level: null,
+ flag_level: 0,
+ title: null,
+ time_read: 0,
+ staged: false,
+ days_visited: 0,
+ posts_read_count: 0,
+ topics_entered: 0,
+ post_count: 3,
+ can_be_suspended: true,
+ can_be_silenced: true
+ },
+ {
+ id: 663,
+ username: "waxfoot",
+ name: "waxfoot",
+ avatar_template: "/user_avatar/forum.osr-plastic.org/waxfoot/{size}/179_2.png",
+ active: true,
+ admin: false,
+ moderator: false,
+ last_seen_at: null,
+ last_emailed_at: "2022-02-27T17:23:20.455Z",
+ created_at: "2022-02-19T20:53:26.355Z",
+ last_seen_age: null,
+ last_emailed_age: 40413355.39907482,
+ created_at_age: 41091949.49975334,
+ trust_level: 1,
+ manual_locked_trust_level: null,
+ flag_level: 0,
+ title: null,
+ time_read: 0,
+ staged: false,
+ days_visited: 0,
+ posts_read_count: 0,
+ topics_entered: 0,
+ post_count: 0,
+ can_be_suspended: true,
+ can_be_silenced: true
+ },
+ {
+ id: 494,
+ username: "ebrad",
+ name: "ebrad",
+ avatar_template: "/letter_avatar_proxy/v4/letter/e/13edae/{size}.png",
+ active: true,
+ admin: false,
+ moderator: false,
+ last_seen_at: null,
+ last_emailed_at: null,
+ created_at: "2022-02-19T20:51:18.529Z",
+ last_seen_age: null,
+ last_emailed_age: null,
+ created_at_age: 41092077.32719634,
+ trust_level: 1,
+ manual_locked_trust_level: null,
+ flag_level: 0,
+ title: null,
+ time_read: 0,
+ staged: false,
+ days_visited: 0,
+ posts_read_count: 0,
+ topics_entered: 0,
+ post_count: 1,
+ can_be_suspended: true,
+ can_be_silenced: true
+ },
+ {
+ id: 535,
+ username: "shadabz",
+ name: "shadabz",
+ avatar_template: "/letter_avatar_proxy/v4/letter/s/c0e974/{size}.png",
+ active: true,
+ admin: false,
+ moderator: false,
+ last_seen_at: null,
+ last_emailed_at: null,
+ created_at: "2022-02-19T20:51:36.412Z",
+ last_seen_age: null,
+ last_emailed_age: null,
+ created_at_age: 41092059.44598454,
+ trust_level: 1,
+ manual_locked_trust_level: null,
+ flag_level: 0,
+ title: null,
+ time_read: 0,
+ staged: false,
+ days_visited: 0,
+ posts_read_count: 0,
+ topics_entered: 0,
+ post_count: 1,
+ can_be_suspended: true,
+ can_be_silenced: true
+ },
+ {
+ id: 567,
+ username: "jmwombacher",
+ name: "jmwombacher",
+ avatar_template: "/letter_avatar_proxy/v4/letter/j/ba9def/{size}.png",
+ active: true,
+ admin: false,
+ moderator: false,
+ last_seen_at: null,
+ last_emailed_at: null,
+ created_at: "2022-02-19T20:51:50.381Z",
+ last_seen_age: null,
+ last_emailed_age: null,
+ created_at_age: 41092045.47811591,
+ trust_level: 1,
+ manual_locked_trust_level: null,
+ flag_level: 0,
+ title: null,
+ time_read: 0,
+ staged: false,
+ days_visited: 0,
+ posts_read_count: 0,
+ topics_entered: 0,
+ post_count: 1,
+ can_be_suspended: true,
+ can_be_silenced: true
+ },
+ {
+ id: 1552,
+ username: "ettejah",
+ name: "ettejah",
+ avatar_template: "/letter_avatar_proxy/v4/letter/e/dc4da7/{size}.png",
+ active: true,
+ admin: false,
+ moderator: false,
+ last_seen_at: null,
+ last_emailed_at: null,
+ created_at: "2022-02-20T12:01:01.251Z",
+ last_seen_age: null,
+ last_emailed_age: null,
+ created_at_age: 41037494.60984397,
+ trust_level: 0,
+ manual_locked_trust_level: null,
+ flag_level: 0,
+ title: null,
+ time_read: 0,
+ staged: false,
+ days_visited: 0,
+ posts_read_count: 0,
+ topics_entered: 0,
+ post_count: 1,
+ can_be_suspended: true,
+ can_be_silenced: true
+ },
+ {
+ id: 761,
+ username: "raffiki",
+ name: "raffiki",
+ avatar_template: "/letter_avatar_proxy/v4/letter/r/7ab992/{size}.png",
+ active: true,
+ admin: false,
+ moderator: false,
+ last_seen_at: null,
+ last_emailed_at: null,
+ created_at: "2022-02-20T11:38:38.473Z",
+ last_seen_age: null,
+ last_emailed_age: null,
+ created_at_age: 41038837.38932683,
+ trust_level: 1,
+ manual_locked_trust_level: null,
+ flag_level: 0,
+ title: null,
+ time_read: 0,
+ staged: false,
+ days_visited: 0,
+ posts_read_count: 0,
+ topics_entered: 0,
+ post_count: 0,
+ can_be_suspended: true,
+ can_be_silenced: true
+ },
+ {
+ id: 1811,
+ username: "lael",
+ name: "lael",
+ avatar_template: "/letter_avatar_proxy/v4/letter/l/5f8ce5/{size}.png",
+ active: true,
+ admin: false,
+ moderator: false,
+ last_seen_at: null,
+ last_emailed_at: null,
+ created_at: "2022-02-20T12:02:57.464Z",
+ last_seen_age: null,
+ last_emailed_age: null,
+ created_at_age: 41037378.40062601,
+ trust_level: 1,
+ manual_locked_trust_level: null,
+ flag_level: 0,
+ title: null,
+ time_read: 0,
+ staged: false,
+ days_visited: 0,
+ posts_read_count: 0,
+ topics_entered: 0,
+ post_count: 1,
+ can_be_suspended: true,
+ can_be_silenced: true
+ }
+ ],
+ similar_users_count: 2888,
+ single_sign_on_record: null,
+ approved_by: {
+ id: 1,
+ username: "jerom",
+ name: "Jerome",
+ avatar_template: "/user_avatar/forum.osr-plastic.org/jerom/{size}/5655_2.png"
+ },
+ suspended_by: null,
+ silenced_by: null,
+ groups: [
+ {
+ id: 10,
+ automatic: true,
+ name: "trust_level_0",
+ display_name: "trust_level_0",
+ user_count: 2945,
+ mentionable_level: 0,
+ messageable_level: 0,
+ visibility_level: 1,
+ primary_group: false,
+ title: null,
+ grant_trust_level: null,
+ incoming_email: null,
+ has_messages: false,
+ flair_url: null,
+ flair_bg_color: null,
+ flair_color: null,
+ bio_raw: null,
+ bio_cooked: null,
+ bio_excerpt: null,
+ public_admission: false,
+ public_exit: false,
+ allow_membership_requests: false,
+ full_name: null,
+ default_notification_level: 3,
+ membership_request_template: null,
+ members_visibility_level: 0,
+ can_see_members: true,
+ can_admin_group: true,
+ publish_read_state: false
+ },
+ {
+ id: 11,
+ automatic: true,
+ name: "trust_level_1",
+ display_name: "trust_level_1",
+ user_count: 2655,
+ mentionable_level: 0,
+ messageable_level: 0,
+ visibility_level: 1,
+ primary_group: false,
+ title: null,
+ grant_trust_level: null,
+ incoming_email: null,
+ has_messages: false,
+ flair_url: null,
+ flair_bg_color: null,
+ flair_color: null,
+ bio_raw: null,
+ bio_cooked: null,
+ bio_excerpt: null,
+ public_admission: false,
+ public_exit: false,
+ allow_membership_requests: false,
+ full_name: null,
+ default_notification_level: 3,
+ membership_request_template: null,
+ members_visibility_level: 0,
+ can_see_members: true,
+ can_admin_group: true,
+ publish_read_state: false
+ },
+ {
+ id: 41,
+ automatic: false,
+ name: "OldForum",
+ user_count: 2605,
+ mentionable_level: 0,
+ messageable_level: 0,
+ visibility_level: 0,
+ primary_group: false,
+ title: "",
+ grant_trust_level: 1,
+ incoming_email: null,
+ has_messages: false,
+ flair_url: null,
+ flair_bg_color: "",
+ flair_color: "",
+ bio_raw: "",
+ bio_cooked: null,
+ bio_excerpt: null,
+ public_admission: true,
+ public_exit: true,
+ allow_membership_requests: false,
+ full_name: "OldForum",
+ default_notification_level: 3,
+ membership_request_template: "",
+ members_visibility_level: 0,
+ can_see_members: true,
+ can_admin_group: true,
+ can_edit_group: true,
+ publish_read_state: false
+ }
+ ]
+ }
\ No newline at end of file
diff --git a/packages/discourse/templates/discourse/machines/debug.osr b/packages/discourse/templates/discourse/machines/debug.osr
new file mode 100644
index 00000000..f1db6cc9
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/debug.osr
@@ -0,0 +1,6 @@
+## Product
+[% js %]
+ if(debug){
+ return "" + prettyJSON(store.product) + " ";
+ }
+[%endjs%]
diff --git a/packages/discourse/templates/discourse/machines/global.json b/packages/discourse/templates/discourse/machines/global.json
new file mode 100644
index 00000000..32cf6363
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/global.json
@@ -0,0 +1,33 @@
+{
+ "vendor_name": "Plastic Hub",
+ "vendor_website": "https://plastic-hub.com/",
+ "vendor_products_external": "https://plastic-hub.com/products/",
+ "vendor_instagram": "https://www.instagram.com/osr_plastic/",
+ "_vendor_youtube": "https://www.youtube.com/channel/UCuWDxJtV2pf5BefHEy09Cew/featured?view_as=subscriber",
+ "vendor_github": "https://git.osr-plastic.org/osr-plastic",
+ "vendor_contact_email": "mailto:sales2@plastic-hub.com",
+ "vendor_whatsapp": "tel:0034691952287",
+ "vendor_facebook": "https://www.facebook.com/plastichubcat/",
+ "vendor_blog": "https://precious-plastic.org/",
+ "vendor_discord": "https://discord.gg/vR5d6ShTez",
+ "author_link_pp": "https://preciousplastic.com/",
+ "author_link": "https://osr-plastic.org",
+ "site": "https://precious-plastic.org/",
+ "OSR_HOWTOS_ROOT_URL": "https://osr-plastic.org/howtos/",
+ "OSR_HOWTOS_PATH": "../../ph3/pp-next2/howtos",
+ "OSR_FILES_WEB":"http://files.osr-plastic.org/files/osr-machines/",
+ "OSR_MACHINES_ASSETS_URL":"https://assets.osr-plastic.org/machines/",
+ "show": {
+ "badges": false,
+ "authors": true,
+ "head": true,
+ "debug": false,
+ "wiki": false,
+ "forum": false,
+ "others": false,
+ "howtos":false,
+ "instagram":false,
+ "shipping":true,
+ "payment_terms":true
+ }
+}
\ No newline at end of file
diff --git a/packages/discourse/templates/discourse/machines/header_jekyll.osr b/packages/discourse/templates/discourse/machines/header_jekyll.osr
new file mode 100644
index 00000000..d3632bfe
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/header_jekyll.osr
@@ -0,0 +1,95 @@
+[% capture config %][% js %]
+const globalVariables = readJSON('${root}/osr/global.json');
+addGlobal({config:globalVariables});
+return globalVariables;
+[%endjs%][% endcapture %]
+[% capture product %][% js %]
+
+ let globalVariables = readJSON('${root}/osr/global.json');
+ let localVariables = readJSON('${PRODUCT_ROOT}/config.json');
+ let localYAML = readFile('${PRODUCT_ROOT}/config.yaml');
+
+ let defaultsYAML = fs.findUp.sync('defaults.yaml', {
+ cwd:PRODUCT_ROOT,
+ stopAt:root
+ });
+
+ if(defaultsYAML){
+ defaultsYAML = readFile(defaultsYAML).trim();
+ localYAML = `${defaultsYAML}\n${localYAML}`;
+ }
+
+ let defaultsJSON = fs.findUp.sync('defaults.json', {
+ cwd:PRODUCT_ROOT,
+ stopAt:root
+ });
+
+ if(defaultsJSON){
+ defaultsJSON = readJSON(defaultsJSON);
+ localVariables = {
+ ...defaultsJSON,
+ ...localVariables
+ }
+ }
+
+
+ let allVariables = {
+ ...localVariables,
+ ...globalVariables,
+ ...scope
+ }
+ let all = substitute(JSON.stringify(allVariables,null,2),allVariables);
+ allVariables = JSON.parse(all);
+ resolveConfig(allVariables);
+ return allVariables;
+
+[%endjs%][% endcapture %]
+---
+[% js %]
+let globalVariables = readJSON('${root}/osr/global.json');
+resolveConfig(globalVariables);
+addGlobal(globalVariables);
+let localVariables = readJSON('${PRODUCT_ROOT}/config.json');
+let localYAML = readFile('${PRODUCT_ROOT}/config.yaml');
+
+let defaultsYAML = fs.findUp.sync('defaults.yaml', {
+ cwd:PRODUCT_ROOT,
+ stopAt:root
+});
+
+if(defaultsYAML){
+ defaultsYAML = readFile(defaultsYAML).trim();
+ localYAML = `${defaultsYAML}\n${localYAML}`;
+}
+
+let defaultsJSON = fs.findUp.sync('defaults.json', {
+ cwd:PRODUCT_ROOT,
+ stopAt:root
+});
+
+if(defaultsJSON){
+ defaultsJSON = readJSON(defaultsJSON);
+ localVariables = {
+ ...defaultsJSON,
+ ...localVariables
+ }
+}
+localVariables['rel']=product.replace('products/','');
+localVariables['image']='${abs_url}/${product_rel}/renderings/perspective.jpg';
+let allVariables = {
+ ...localVariables,
+ ...globalVariables,
+ ...scope
+
+}
+
+let all = substitute(JSON.stringify(allVariables, null, 2), allVariables);
+allVariables = JSON.parse(all);
+resolveConfig(allVariables);
+store.product = allVariables;
+addGlobal(allVariables);
+register('product', allVariables);
+const yaml = substitute(localYAML, allVariables);
+return (YAML.stringify(allVariables) + yaml).trim();
+[%endjs%]
+---
diff --git a/packages/discourse/templates/discourse/machines/plugins/html.js b/packages/discourse/templates/discourse/machines/plugins/html.js
new file mode 100644
index 00000000..9ba73ea7
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/plugins/html.js
@@ -0,0 +1,50 @@
+const path = require('path');
+
+const link = (name, link, _class) => `${name} `;
+const wrap = (content) => `
+
+`;
+
+const image = (src, link, style) => ` `;
+
+const item = (content, style = 'border-color: #c5c5c5;width: 300px;display: inline-block', title) =>
+ `
+ ${content}
+
${title||''}
+`;
+
+const styles = {
+ thumb: 'border:none; width:200px;max-height:200px'
+};
+
+const center_caption = (el = 'h5', text) => `<${el} style="text-align:center">${text}${el}>`;
+
+const thumbs = (url, folder) => {
+ const context = require('@plastichub/osrl/library').getContext();
+ folder = path.resolve(folder);
+ let images = context.fs.images(folder, {
+ absolute: false
+ });
+ images = images.map((i) => item(image(`${url}/${i}`), 'border:none; width:200px;max-height:200px'));
+ images = wrap(images.join('\n'));
+ return images;
+}
+module.exports = {
+ html: {
+ link: link,
+ caption: {
+ center: center_caption
+ },
+ container: {
+ wrap: wrap,
+ item: item
+ },
+ image: image,
+ styles: styles,
+ thumbs: thumbs
+ }
+};
\ No newline at end of file
diff --git a/packages/discourse/templates/discourse/machines/root.html b/packages/discourse/templates/discourse/machines/root.html
new file mode 100644
index 00000000..ef5b6fc9
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/root.html
@@ -0,0 +1,54 @@
+[% include "product_variables.osr" %]
+[% include "body.md" %]
+[% include "header_notice.osr" %]
+[%- include "product_overview_drawings.osr" -%]
+
+[%- if product.showSpecs !=false || config.show.authors -%]
+
+
+ [%- if product.showSpecs !=false -%]
+
+
Specification
+ [% include "product_specs.osr" html:false %]
+
+ [%endif%]
+
+ [% if config.show.authors %]
+ [%- if product.showAuthors !=false -%]
+ [% include "authors_html.osr" authors:product.authors showHeader:true %]
+ [%endif%]
+ [%endif%]
+
+
+
+[%endif%]
+
+[%- if product.showResources !=false %]
+ [% include "product_resources.osr" %]
+[%endif%]
+
+
+
+[% if config.show.shipping %]
+ [% include "product_shipping.osr" %]
+[% endif -%]
+
+[% if config.show.payment_terms %]
+ [% include "payment_terms.osr" %]
+[% endif -%]
+
+
+
+[% if config.show.others %]
+ [% include "other_products.osr" %]
+[%endif%]
+[% if config.show.howtos %]
+ [% include "product_howtos.osr" %]
+[%endif%]
+[% include "social_links.osr" %]
+[% if config.show.instagram %]
+[% include "vendor_instagram.osr" %]
+[%endif%]
+[% if config.show.debug %]
+ [% include "product_debug.osr" %]
+[%endif%]
diff --git a/packages/discourse/templates/discourse/machines/variables.osr b/packages/discourse/templates/discourse/machines/variables.osr
new file mode 100644
index 00000000..c0ec07cf
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/variables.osr
@@ -0,0 +1,56 @@
+[% capture config %][% js %]
+const globalVariables = readJSON('${root}/osr/global.json');
+addGlobal({config:globalVariables});
+return globalVariables;
+[%endjs%][% endcapture %]
+
+[% capture product %][% js %]
+
+ let globalVariables = readJSON('${root}/osr/global.json');
+ let localVariables = readJSON('${PRODUCT_ROOT}/config.json');
+ localVariables['image']='${product_rel}/renderings/perspective.jpg';
+ localVariables['rel']=product.replace('products/','');
+ localVariables['sidebar'] = {
+ nav: "machines"
+ };
+
+ let localYAML = readFile('${PRODUCT_ROOT}/config.yaml');
+
+ let defaultsYAML = fs.findUp.sync('defaults.yaml', {
+ cwd:PRODUCT_ROOT,
+ stopAt:root
+ });
+
+ if(defaultsYAML){
+ defaultsYAML = readFile(defaultsYAML).trim();
+ localYAML = `${defaultsYAML}\n${localYAML}`;
+ }
+
+ let defaultsJSON = fs.findUp.sync('defaults.json', {
+ cwd:PRODUCT_ROOT,
+ stopAt:root
+ });
+
+ if(defaultsJSON){
+ defaultsJSON = readJSON(defaultsJSON);
+ localVariables = {
+ ...defaultsJSON,
+ ...localVariables
+ }
+ }
+
+
+ let allVariables = {
+ ...localVariables,
+ ...globalVariables,
+ ...scope
+ }
+ allVariables.product_rel = product;
+ allVariables.product_rel_min = product.replace('products/','')
+ let all = substitute(JSON.stringify(allVariables,null,2),allVariables);
+ allVariables = JSON.parse(all);
+ resolveConfig(allVariables);
+ addGlobal({product:allVariables});
+ return allVariables;
+
+[%endjs%][% endcapture %]
diff --git a/packages/discourse/templates/discourse/machines/widgets/authors.osr b/packages/discourse/templates/discourse/machines/widgets/authors.osr
new file mode 100644
index 00000000..b1877bb8
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/authors.osr
@@ -0,0 +1,10 @@
+[%if showHeader %]
+## Authors
+[%endif%]
+
+[% for author in authors %]
+- [ [[author.name]] ]( [[author.url]] )
+[% endfor %]
+
+[% js %]
+[%endjs%]
diff --git a/packages/discourse/templates/discourse/machines/widgets/authors_html.osr b/packages/discourse/templates/discourse/machines/widgets/authors_html.osr
new file mode 100644
index 00000000..9e64af50
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/authors_html.osr
@@ -0,0 +1,8 @@
+[%if showHeader %]
+ Authors
+[%endif%]
+
diff --git a/packages/discourse/templates/discourse/machines/widgets/extra_resources.md b/packages/discourse/templates/discourse/machines/widgets/extra_resources.md
new file mode 100644
index 00000000..e69de29b
diff --git a/packages/discourse/templates/discourse/machines/widgets/forum.osr b/packages/discourse/templates/discourse/machines/widgets/forum.osr
new file mode 100644
index 00000000..d1990202
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/forum.osr
@@ -0,0 +1,25 @@
+[%js%]
+try{
+ return new Promise((resolve, reject) => {
+ const d = new Discourse.Discourser({
+ host: config.discourse.host,
+ key: config.discourse.key,
+ username: config.discourse.username,
+ rateLimitConcurrency: 1
+ });
+ d.getTopicItemsOfCategories([category]).then((posts) => {
+ if(!posts.length){
+ return '';
+ }
+ posts = posts.map((p)=>{
+ const url = `${config.discourse.host}/t/${p.id}`;
+ const title = `${p.fancy_title}`;
+ return `${title} `;
+ }).join('\n');
+ resolve(posts);
+ });
+ });
+}catch(e){
+ debugger;
+}
+[%endjs%]
diff --git a/packages/discourse/templates/discourse/machines/widgets/gallery.osr b/packages/discourse/templates/discourse/machines/widgets/gallery.osr
new file mode 100644
index 00000000..b4fda644
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/gallery.osr
@@ -0,0 +1,10 @@
+[%js%]
+const _path = substitute(`${cwd}/${product_rel}/${path}`)
+if(fs.images(_path).length)
+{
+ const t = html.thumbs(`${abs_url}/${product_rel}/${path}`,_path);
+ return `${name} ${t}`;
+}else{
+ console.log(_path + 'doesnt exists');
+}
+[%endjs%]
diff --git a/packages/discourse/templates/discourse/machines/widgets/howtos.osr b/packages/discourse/templates/discourse/machines/widgets/howtos.osr
new file mode 100644
index 00000000..79207c4b
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/howtos.osr
@@ -0,0 +1,12 @@
+[%js%]
+if(store.product.howtos && store.product.howtos.length){
+ return store.product.howtos.map((i)=>{
+ return i
+ }).join('\n ');
+ /*
+ const t = html.thumbs(`${abs_url}/${product}/media/products`,`${PRODUCT_ROOT}/media/products`);
+ return `Products done with ${store.product.name}
+ ${t}`;
+ */
+}
+[%endjs%]
diff --git a/packages/discourse/templates/discourse/machines/widgets/other_products.osr b/packages/discourse/templates/discourse/machines/widgets/other_products.osr
new file mode 100644
index 00000000..0b87ed16
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/other_products.osr
@@ -0,0 +1,25 @@
+
+
See our other products
+
+[%js%]
+const template = readFile('${root}/osr/bazar/other_item.html');
+let product = store.product;
+let all = config.all.filter((p)=>{
+ return p.slug !== product.slug;
+})
+const ret = all.map((p)=>{
+ const vars = {
+ ...p,
+ image: p.image || substitute('${abs_url}/' + p.rel + '/renderings/perspective.jpg',global)
+ }
+ return substitute(template,vars);
+})
+return ret;
+[%endjs%]
+
+
+
diff --git a/packages/discourse/templates/discourse/machines/widgets/overview_drawings.osr b/packages/discourse/templates/discourse/machines/widgets/overview_drawings.osr
new file mode 100644
index 00000000..9ed438a8
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/overview_drawings.osr
@@ -0,0 +1,27 @@
+[%- if product.showDimensions !=false -%]
+ Dimensions
+
+
+
+
+
+
+[%- endif -%]
+[%- if product.showParts !=false -%]
+
+
+
+
+
[% include 'product_parts.osr' %]
+
+
+
+
+[%- endif -%]
diff --git a/packages/discourse/templates/discourse/machines/widgets/parts.osr b/packages/discourse/templates/discourse/machines/widgets/parts.osr
new file mode 100644
index 00000000..46f60401
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/parts.osr
@@ -0,0 +1,7 @@
+[%js%]
+let p = PRODUCT_ROOT;
+const _path = path.resolve(PRODUCT_ROOT + './parts.xlsx');
+const data = xlsx.parse(_path);
+data[0].data = data[0].data.filter((d) => !!d.length);
+return md2html(markdownTable(data[0].data));
+[%endjs%]
diff --git a/packages/discourse/templates/discourse/machines/widgets/resources.osr b/packages/discourse/templates/discourse/machines/widgets/resources.osr
new file mode 100644
index 00000000..4ee51d6e
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/resources.osr
@@ -0,0 +1,45 @@
+
+### Resources
+
+[% if product.forum -%]
+- [Forum]([[product.forum]])
+[% endif %]
+[%- if product.download -%]
+- [Download]([[product.download]])
+[% endif %]
+[%- if product.firmware -%]
+- [Firmware]([[product.firmware]])
+[%- endif %]
+[%- if product.Preview3d -%]
+[%- if product.edrawings -%]
+- [3D-Preview]([[product.edrawings]])
+[% else %]
+- [3D-Preview]([[OSR_MACHINES_ASSETS_URL]]/[[product.product_rel_min]]/resources/edrawings.html)
+[% endif -%]
+- [Source Code Repository]([[GIT_REPO]]/src/branch/master/[[product.rel]])
+[%-endif-%]
+[%- if product.hasSpec -%]
+- [Specification PDF]([[OSR_MACHINES_ASSETS_URL]]/[[product.product_rel_min]]/resources/spec.pdf)
+[%- endif -%]
+[% if product.howtoSection %]
+- [How-tos]([[product.howtoSection]])
+[%- endif -%]
+[% if product.library %]
+- [Library]([[product.library]])
+[% endif %]
+
+[%- if config.show.wiki -%]
+ [%- if product.wiki_articles -%]
+Wiki Articles
+[%- include "product_wiki.osr" category:product.wiki_articles -%]
+ [%- else -%]
+ [%- endif -%]
+[%- else -%]
+[%- endif -%]
+[%- if config.show.forum -%]
+ [%- if product.forumCategory -%]
+Forum Posts
+[%- include "product_forum.osr" category:product.forumCategory -%]
+ [%- endif -%]
+[%- endif -%]
+[%- include "extra_resources.md" -%]
\ No newline at end of file
diff --git a/packages/discourse/templates/discourse/machines/widgets/showreel.osr b/packages/discourse/templates/discourse/machines/widgets/showreel.osr
new file mode 100644
index 00000000..7bd0337a
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/showreel.osr
@@ -0,0 +1,7 @@
+[%js%]
+if(fs.images(`${PRODUCT_ROOT}/media/products`).length){
+ const t = html.thumbs(`${abs_url}/${product}/media/products`,`${PRODUCT_ROOT}/media/products`);
+ return `Products done with ${store.product.name}
+ ${t}`;
+}
+[%endjs%]
diff --git a/packages/discourse/templates/discourse/machines/widgets/social_links.osr b/packages/discourse/templates/discourse/machines/widgets/social_links.osr
new file mode 100644
index 00000000..50856ea2
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/social_links.osr
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+ [%- if config.vendor_youtube -%]
+
+
+
+
+
+ [% endif %]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/discourse/templates/discourse/machines/widgets/specs.osr b/packages/discourse/templates/discourse/machines/widgets/specs.osr
new file mode 100644
index 00000000..562482cb
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/specs.osr
@@ -0,0 +1,18 @@
+[%js%]
+let p = PRODUCT_ROOT;
+const _path = path.resolve(PRODUCT_ROOT + './specs.xlsx');
+if(!fs.exists(_path)){
+ console.warn('cant find specs', _path)
+ return
+}
+let data = xlsx.parse(_path);
+data[0].data = data[0].data.filter((d)=>d.length >0);
+data = markdownTable(data[0].data);
+if(html){
+ return md2html(data);
+}else{
+
+ data;
+
+}
+[%endjs%]
diff --git a/packages/discourse/templates/discourse/machines/widgets/table.osr b/packages/discourse/templates/discourse/machines/widgets/table.osr
new file mode 100644
index 00000000..47f97278
--- /dev/null
+++ b/packages/discourse/templates/discourse/machines/widgets/table.osr
@@ -0,0 +1,16 @@
+[%js%]
+const _path = path.resolve(`${PRODUCT_ROOT}/${table}`)
+if(!fs.exists(_path)){
+ console.warn('cant find table', _path)
+ return
+}
+console.log(' table path ' + _path)
+let data = xlsx.parse(_path)
+data[0].data = data[0].data.filter((d)=>d.length >0)
+data = markdownTable(data[0].data)
+if(html){
+ return md2html(data)
+}else{
+ data
+}
+[%endjs%]
diff --git a/packages/discourse/tests/image.jpg b/packages/discourse/tests/image.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d779835c79068dac67578e4b87d43753abd4319b
GIT binary patch
literal 130249
zcmdqI1yo$kvM4+ROM)awaCZ;xk_2}M?!n#NNw5$+xCb5F8C-(9!{7v$VIVNLl{cD}K)~lYqt9DiG?&_ZIYTNy1?$0m4YZ(b?2>=`%008$80DqtWA0-QW
z7kg(5dj~QO7FGc72Wfc(1i&MFB6>y#(3bchFUHQn%F4>eZNkd-fLRUMIQSkhI|tVz
zpOuS^+xQWiv2pM`YH;#!nLS}PL!(E`ZesGpH|8-jetb4D<1%DrXJrNaSpj`ilf#5&jF%mcg1cZl|Q67GTn6EGi|BvBM
zCjjF)Vh6k+JRAk!83r6Y2Hc-+0Lfz^A;3SD*53gc0TJmr+_M+(FCXMY50YmO;(w6C
zAv}XeL_&W4X90i;{~&!0|N7z8@$8ttNAT~&2mj8*{;#G5U-O;U=^;Q?i#ntLfM>Ep
zcT9`9D%6WT;`eU2&ut>>&4exHeAQvrNi$s`t@)D3KfS8~#P>byH%i9u-rhxc0Ptz}
zT~$>Ah^w)P{##a%&8ZwVAH%bEaNv5C0MzdMoHLDKxn#}m<^^siV^_AcS!3fg&Q8A5
zv=b563K16Ddx087jA72z{5IuHjmbUp?Xx?S(6Y*Wl=!q)Qy(!_2R{{4F8R5Fa;W+Wp8L$B$}$A2xLnTDh#J&{v8!=iKVK|q
zqRn|$+PH%>ZzN=)`dQEL-2YltuRXf)a6nbCjGA!70
zKx)c0D|XV_5~^eFgCe0JXeQC&m$BIr8N~uByK(Ynem(5HW~AHc7#q82+r?>U?C|UB
z2-8#nQBe4C2hz56w+n}WP>lXPPL=-{#d~J6>!o<;s|BU>oFTxl!;=M%Ry^2|Cu~pM
z*f3g(HZi#laDU?QpYJ;W-m0FDKU=dW>An@*J{8Fxfnw{ilK^P~$$M&uI7ZL>WMDjT
zbG^Z`)pa4|+maeuFW2atW>|Y;YKJklM~ASY7-?1HyPu-_?>B*fM-H*KEAIn>=ldD5
z-M`|-G<#}>Im6ATYug+7ODefF!eAE8uQKpKI%&iz^NHf!gYG}Ue~Iazr2oi(TYAVU
zOSh{Vv0kWtmO;uiRh;7@KbxeW`U;#^oq2S>VGKOQ7?CTTvB0TOxkt$-b-9TO?D@5K
zT-&DZ&0HI?+8qzkwQog!b^_(;SEVr=n?Lwxef4-Eq@Z`(qNU+Q>xEk
zYKg1Q_2#0=yGkne9~wFG*d9z#IbDI6zni#CY(U;}jK`|eP8Ff-TrS
zc+ssyud{2G781Mh2Y^Ketlfk~XwltPVD_<9hBGK$32#zsOnm8=D=V|Y`P>b7Id}(UC^>i
zRJ{HJK+EgO>mU3$tYJPc`n;Q)Qh#vKmUyYjF>XZ}xersHFrv5B`xF3p@!`t2?REdV
z2kI%~`~g%uK}1VsDS@~wn9e`pB0i5H*?AxfvN?C|px6s(iDqJuqkF(PGnccZh}Q(-
zn7@I0u>oqIG9{}2t?DQiyL{^14-)f5~V#74GY^X;jx0nlT00rU-jh?Wl{OM_UzD!
zx2&ZckPpw!)60}I4-}JssvWE*s@tLYc7YH`*;E!CWL-|^Se!ytnv>hcBw-WjB$r4;
z%8*p`eqL9N$^`mZ3R8}fC{;94PLgEUjt0YZfVr}ZH6_geEw^ej*(R3(zwuQRIjas0
z6F1SfRI|*V)VJhew>2!!C(}%tQm;-j9X55&YE0`2Xq4JCkAm1AvkmaM&*CV2dv`n$
zZ?3dE#BbCoRkdye%j#ZV^XTc$Htm!!wyk`D*%cAyjMCGcKoH_-REZk?HavKHYTTr?
z>NCv-UVqEo@iFtS(XoIo*JB+lsGU$v|bAvhXd{3t%_8w!&7
zGQ=dgsi#wq=h9nRpsj26Cgn#)*}zN58%#3Y)Qd~yzDvCd;bh(l(j=B?~iZ!N;&ix<`$U~-NP$6qnk
zm%LIfeH2Em9Uo-YxiMSMQLvaV48&>{sE9_!1LmIt5i#G+a$(|#qlH1RBM>(HXOH!m
zx}LcN35%Mr?Y@&&K4hWtq}Ayz3NwZ`c6i<`tDQ2F*naBgD`Xv)H|xNpJU`(En1j@
zV?BLb>)}Gcg8~7*un{jteb4>D*wT2{#?}Y-i+*HF#Ckf5in@D=lx>R|dSpn_nK4x&
z$LD`F+WX6I%{^KHcXE9j74S&?f587={ZQvz7jjQgA$K0FwP0>^LCSNDh%Blx-S=`Q
z@5qFmB15@E!*t>!Y-=XTOUvPX4y8>_t~{Gt6#LOuLrg>wHQ6#}
z3HE`RMl!BTjiLE$SQ@8@5rZb*lE-faiXtg0PXxbp%6?8&(TGdqwf@q)8Uw(B8;7&)
zkSNasNm1x6b*!7%dy!|*h<|=X^T^AAax>Hg62#dqcz9K=0@Uf;1A$sRF%{F<^>9^lzP$*
ziz*u~K|a>O>Ji@nX)Cj-+YBuEHrDyDWP>$KCs_j`nh^}99sZFExxhH{@z{vrR46Sa
zJuu2|iVwU(w1YG3T!v}W6Ug?toQ;E8f{$dg6QrYUBKI+p)89OCV8c59d-k%-#U}g-5sHMltMt9`<@(Ig)%USrZb?(`dpBKan003eDD$^<%
z&wQyT8OtCvBSuw;Y#3xFP0fiZc4}7HVf`h>J`7sWZQ*T9)w+W3wKX2VGEbe`)B7c$RoS$xCCS`d3wbMM
zFK1ZhA^{Ui-SSA8A8Jc+@1<#=$;lA0Bw^oChk|A;afr$+-a2>u%T%BI|35
z=PM3V{Y$m~WImOr82MKK05t$kR!zpI<3DBplEMr=>GPp@{V02uSR8*9@GrIgllfNy
zWRDEQoFhE^Z_FQ5Q(RS+(dIl`PtO=O?Aqg3->T-?IKkTH_cUZ~S~fSP(Nm1KCBc(S
z?h1accS0Bqs>?gL!f}pl+hdE93MVk*y*=|z+7b7>Ghp&*a|+R3%`=zN>w5KeCTk(N
zhP|m;kY+anpN{A$}7ot$mw|6_uED|<{?S)QK4%ZhfN3%7a
z!k`>muxXOyzN9-}0bo*$y6%{M>Ro8$oll)T5XyB
zY{ZY&H2>5RhZV2CS`9xK*rKyCAF9*8yB
zs#eCPq}s04(|MmevH{yM4{y~BSd2fD8_h93e)OSTFmul9r4kdAcg~ZW6J;WrQV4a|
zA~lzfBTA@(&hMj-@iouZ9dTo8$qpEDN^cs$uDP{1cR;ac_nQPLQB8O5Q&Zu0cxfhC
z;7UsdP7ieUs)N~_?qIk3!JNVP;TNRnm!=iXXzS7WDH5HIKU8S2K-e)vm)1*KO{tU-
z{ch<38~c|j(LU;1iF`t4B5EOvU~6W!7}bqc3zIA#nFRa_3k{uG+ts9$lziWqww4j4
zGD4?A>B!C0lX}zu0P?490ESC0uGmH=P4nW|>(-xB8Ita^ps^%x@lNN$ovo7yt9v1S
zIq;O)E$~%sAHl#1PsMf+c_aVE5^%rWEA$)WN`4>w?Y`?`&&n?7I$_6Lq0M=}{)_O&
z)Z*emyRl&YM9oa$x@5rRxlj1wyrh;8kP$rd#{4r>yQS@2Io+CQx|r}9wG
z@{aQ4MsjxTWLG1nQHk88xYut6ba-c*%6>Ig7FTDFJ_zcyuUe>zeQl>xiFv4UKHvhn
zh~lmg{b9N7R0J85(^rtLGXFv7IJ+=nGI!Z$nzssSGt8X%<)9iHqFoby&;~m9T($0n
zcR%$>`F4h49)DnJpu=UBkrY)+WXR}xfeZeP^GdnOZYp`}bj#UOp>}qi%PIXU-!fBXjq4B1Xl%hzs~*jI{VlxH!5n@te07g!_Kd!
z{{Z--cpyNCO1CM)T=5?wzs;rR)ARl71<+t{vWh=f<}uZl|VrAb3{{TC}Xmk*sm_nP^Id
zoR!biw+Y1EaqjE@*<0khcCY2PN47_zLL8D-5Q-*N|woV<8(E(od!D;-yznZ<3XA72FpB!wHfQX
zF@)7JO!PpViMEs0rk&na=|X`7*@f)wSGud{cknR9Xzkz(4%G~#AySTW}C+
z>R%~zoOPd2?co?Q?DuL(#U~La<*z%g?3{HmB70wq;vMzTh`tFqr!6%HULAJb)opFY
zqf|DX4YjgtCa*|WFu)~}J&wZ>^yqrV`+^wn8jcB<2of3hPEa|v?!oy(D1(>6->A6jzC$4G
z)O#UetMhxI2GDG!KfM_(1P7yacWqj^-8wbW2JVH%5(Z;=PcP?onsNJUTv$b88@zr;
z6WPSggY>F!=vMdXQjk{{T)=j^aeA%hDn_
z`jnmcUJ`J$7}#-A(%AcTRf}l-Tn9T`%Nf^R2Hd
zPIC5CQ`G?`kL~fV>ejfCtZ|dQ<`42Qkp8A^!&4FKOCedOw-4K1JfY*hGj_G9M_=c1
zSP`b*Zzkc*A9jlGK_eF&1cxYK~O77(eB;xm~g=jT$yKqbuMsKZd
z$nn3ZoAcw@t!V}h=_`kHeOi^HSo5n?TdS@hX>tBS(M`iEu8@wCP5M3?$T1>MuVMRaYOlzBhhreAK6eghP&dT*lrrrUrAMJ4J@y8bW59G5
zce~ByVnW3VA)fgoRw0Mx+2?38v@+MgZ}Ebok>N)W?sSD
zHXtNeOt;c1!2vwSPc=Q8iV-#NmU?f^+DaTwoup2F_H5SJ+yJ
z80{I_QMV>`-fN=ixxaWB6*4mXinaN6r>G|LOZQ3N7_cDf=xw|^y|lntZW?X9LB>k-
zE-6sptnc34%YPGTZeD0*V)cEYJ*>~F7Cb3`x#uPjHsa=TAefbt2JURnXUod-({{DI
zPU_|Qel?mjCh1P7a9_2)d$j>M9i#pYQ5vPsa(f%<4|M6(q7lNr-IzZJ4vc7u%y1~3
zZ&u-j*-#ROl>TVSsOi73o|4ZQIfPa0<)`JEB-$2wyUyiKkMxy?y0=4h_i+FqM9
z!oYhN=a;362VoO39$ARNRv1wu$B;r=-^a*BeZ3gNg#Xor_k0kJ+fjAS@5SuYu
zZ8uGNm`+AUX8fS`MWr8lbFaUdU`e~=%O&YQ0O>=^ocaECN^s`9hvd<#_@IQ{iun7C
z-T5tpVuD5>7_uV}e44atKP|Kf6ZM#o-d?#ft>=`Palj^3G-=1sI&QD_um;(F+a~tH
zUbe>NRA%s`_blAP@i7qjDX5VL?7!*LW$DhK?!XG_mDV!6*&m}D%54N(>DksbTK^a-
z)uLAuJ-N2gWhhG$d_%lf{0g|Zb2`X)U;9S+&A82K>Ba5=i6pj66AvV@_FD7@;Ysy*
z(ay4`wtbo8B<-3q7*v+&`F={3alMtZ`Ma?vwQsyJ(>nk_3P3TSz!cW^-eI*}xS-j!
z;*?MRTgL9bPLxS%TPV)pfm(x0c>{LFH+k>i67zG+BT}s4JUVc8?^hm;F|>i5g4UM{
zOSr?QG|Pl@x8K|QAh4J>jQ|gsmKO3mDpZ!4n@1$y29TUor%BB5D|KL
zt-J*duP~{(7&gRz$@Zh~8JWAbCE
zn_49|=It3YB50DvqiNQ%ogHw5wWZ3mZ-6Y)XLq9Xs=?_>#yp<-^!EmWNzEBNy+$BV
zAT&b5ckez$_-xu$a#73846RuL$}aJdn~>$VO{>nw)y!4hZxaU|r08DLc2ly8MTb>PuI;q8X{OSdeI;vaD9AoY7(RFdY^AnsN%uDv0QtU5{9
zWFoEGT$48A7$PvcWu#~@Em7zGKoV8hs<#uSF-DG?%rxQq
zdua#hK`0r%Mu6EXmpFQh%U4yyvsQw!oXbG!Te!5c!pp8~`Nb-Y62}H4{rt>&ZT{K}
ziAKxbik$_IzqT40tLAP^=sSMltS;?44R+D2nMEj{f}MUqgx`6O7Cp9;*#*{
zD(O`VKATx=JqO0pD!6lL+3Af@a=V0>jZ9Y+CYgL%avI%t!Mt)G9vbf%dh@MOA2E6E
zLTO;{sNrzo4WT4(ezYy>_QUn+Tjx6i=^^a261RIEl4SLT@dC7Je&w#SG)d&UlHz?Z
z?~#!Mv_CQGeZ9Q)+lWZBnQCy&b#(2e`iMixS+v9-K#2AC+POd@`5%$owtXJ4)lIDy
z=G?JIH=MiogucDL(WBL+lYGUE223%Ax1)6_oiJ2mmnLs~$~|IQ`{5%Iu-rBh2ed}_
zK)_)Ur668?x3yKvJgbg?-U|^0LX=>w(W%mTP=98Mna8|RRwT>vxzH25&A)3Ga>jsH
z!ynC?ARG9A
z-}Hk?z^Q;jD`{j@TebeM>#o+-&$?Xkh*0`ym~bdVdBIOfuMl6?ZYNayHIYbk^yFPyy6(SwZh%f)g9bn5f(p`w(KD0}#|0dX#y01f8+Y=kPFHy0T-|mS!P`
zN2*!qruw1X!)M0@?=$qdqODHV$55U%O}h>y`TYQ`xJ}mjT2mcL+QH{#(*6PPLF@KK
z(wVfJ*aR8z#)P6{^M;tY(*%d3#KXK)_o4BT8ks8R9xL*)NTLw9yH61U{zN#^3Hx>-
z$BW$3>aBhpHaD|1-&U$DduIfVKy8VRB`I9(&R2D~rJ2#UXSn|u$oI3C~0xXBJLm+yFcO1v5)Th8!sf4w0zk-0FK0by&+TZlWj
zNUJ-JV4g&~h@Oq)!IBoT*>$c$qg-ug0+}`~*V^0i3Xnao8TUXD@@j4Ox~U<$UtKW!
z;v6NJomJ;<%OzT}b(Uo3;%zS+w{Fgiy4u9(dK=p~(h!;gHPqEuv{h}@`yE|A!oe(P
zEuC1py@&7Pu*|$f7XAkynZ{$jP$wPbTu%IT-hFmH>NmIf@c!zi1;6-?3r(ptVT0b5
z7KAN2`p1S;92187$x4Y_-MwLGqfpA@fI_}$@4u8{rhwQ*CRs)-7@WP*sxq&`dmxEN
zyivb(;^PitohryuOu}uUm0=1^^hb*Yqa_@#G}SACGRM~aB6pHxeRuXrJ|_8}Dq8UJ
zoLA_dqY(aXjTFB!Ygeqj{Qw42-puV75n4VsuWRL+QU|?KvA)(x^vAv9Iy&QE>Z-wk
z*ywR-ZwtB>rmwS@EvGN0nW@>ajeJEwBe(Bb
zrluMNjcSj5=CW#hX;*~%_zU)qZ%!@N7k28VZ%VFs>bQNdGMdCf4r98hS`4U;`0que
zOUisJdx||;ZKlc%@K<&~WW$TXb;A;x@qI5f!FbS3LUQYf>-SS(vL?`cY&~;urmtDA
z-GgHt7U%jfZ~o-!GO@cJ#~3Dn=f!H@vZLG}!@}Q(H5fJ~6M=V>a|vNaP2gxZ!P_p`
zsBJcWz3ynjmE$YsF5;p3lVkc+hUAB-m@{kM$gZ&InLRJF_ZiB~Dqoon9O#XY?7WyO
znKh!m8;45Pk-IQcSRR=pN&qwI}j9R8eO(p-GtRZ}%Al7u;2fyIpa;t|`D(VEv*ZE&<(v
z$BHIbS@5*I4EIK+N|kNYW1G~{j4Fle%(P_K*rPAIT|K>-`c(KW>cC;*?HMG34@6+;
z-Z!hucAq?ZBR?eRKOE^Z|qYW*PZ)X
zpoPMj$3-zy4XTD;>O}li#SOg*5O=8(5?stZk~{Mv+ASls{e=Ai<)m{B*!eNH
zb)Rgf!SP@?ONoeg-QgHlS&BY=szQr9S=R~uym7-F^xA#Pt(a)Gk3nFJ)~7G!aGs^r
zY(`)a(KYl$@NCmf6ZnbldMt$Ay?ocR^kZ8N49I9J)b(p{%XFyn&JpoSeBVA{;iScu
z1Y}FCTaALSs-wQ0D4~OeaC$YD9vZN@=n9>sOrQ6@xB3Hsvk{{idsY@vcF#B~Zvnc}
zakD+^Ehm5t9D0nnyd~8UQpeX=6rR1^XkA%c;pm6aZLm#b+B@bn@B6~|WuVs#rQlM%
z;56O!i0fMes{V^-vkMIy8=?D+yu*d?P
zS@h0YLN*)fr|>7hm$p$E(l}NJ_wH`Z?zjHqBmJuwF}-&d2vEpOIR
zCWbt6`nh4h1^xiko3EJLSw`oqSN60V?abR2nF!lV`8x63eoAP=fS>JBTL(|QNq60|
z{Nf~?$XmykyoGVr6kUslh}=OUZWZmpU3iAbSA>whm{g|`P>GJ4dzzhpm8R1*$gy3>
z7X$Wv+0ScgwJH7XD0C}2G#jSQ_-X~#tY0dABl+A@QRVBjFt)93xtrIm*_Bs!3D-{I
z65F?B=lGAB70P_rp+Tl^&Nq`5Ugg_@hqrT%2@+1#RLTS8Dqe?567d^`bD%5$TZ%Cf
z=njH58{+m7=k~dVe-9;4FFhVsfBFmzL#zT@Y~u?pgt5EkR;y88K$qcK!4dTc
zS8JiQ@MP8U`rh2cNGC+VK0JD*Dt$+PI7hF#uen5PT}uO^JuBdlX5~fVt=?o>IbwYi
zn;>}-1pUlL-$q;He?(_p8kxw^M*iB`FRFk~I_8(Ih%IO(*qXb`i@`R{LCIoiBwb2s`2U=qu$HY<1WqUGw9O3cFjvWJkI&g&$B?b$`UDP@~Z#1=ERTl2LP^G07n
zO`%YJXd)iEdyJVDWPlGc+2${0Ksg(Ex#&a`vQ}gEB2$yGDt$C*9h`^}CVQsCx!e1O
zPW;ZxY5QS=BQCn*Z|l%u20Kpx}T`cwI4%EoER7*%AV-h-SlJmxFD-51O^T#Qrk-I2z`Wt
zgmd%VRBHNKj`=4genvan0vU!!eS}>Dl8Lz|+kkpEW&J;Gc2xOIckL-vG)iuNQ
zzU}o%YFIuKw3-)m4YpG|mlyHiX_12|KF_6#Vx40k36_O|Qae5Y*~=B}oympPUo`yZkPP?bQxT_=-0Y_o3t^{F4kKwQ@WgY}cg+>jmK
z>me(LSjzEF8}x0Gq6|j44E-DAe(T+D-QN9A@ja7io2w}LqW9NV6>fk4fQAy7$XD3d
z)F#Oykouf$m3NS!dO7(=RF(9;IAk^v3Esyxw&WnRX}T`1RAn*&Ge{035DaZ!8AIwso#dqlK~YpYMA=jJlK
z8+$*=p8U|GjnW#6Z_ZdX-#yZdg?_;@$*M*FrkjlWTOWqjPn;Y@g)EE%U5
zkx+drtC04#YklZmu8sy)>YdA!leHG)Y^HI5FH2$06+KGpd}cYLQ8FZ5s{U#UBE!z8
zdJbFrVufbyeQ`F0Z-*5VlUD>yYL2Zeqy{B1
zH|A@k&EVTaleeA*Z_fSzK0UNKI)wjT=Pp8j9(fp<2vIG!%AK~USaL3Se?K#~sp}%-
z(_WHgCAv?NXIT~^JQX%Oqh90KTF|~?vMji>FDZ6XwXKUI$ZgT4Z}nLLeYabA_~Ap^
z%)?BuFu7_ld+1y!$|`2i=J%XVFHC;$9TCB7Xt_ImR)JvRgaEg!@vBzqxLkUk`k(z&
z2NFsr!eh_DBVU4=mOK@(7j2n`bi?A;Pxzf$!lPDH=5j2}C}!GwnhUH`uM{mwWw{UD
z3j36OTRTs0z^^FtBe)5ji5Pa}ysW6WfvdQB_xH;9_q-yv2*2`f#-bVrV-#KXLY(&m
zYc&{%NJYn3IJF@~&8B^#379fvN#HI(OjSBHhegmNQoLe$+P1
z2$XDVC*H{wXf9lQUU#BD0FOTqf7pSwYMPqbl_t*^Uz@YhNaW&KHHsnZ*mrPymSvv2
z^Stw>WK1*-NT}kcUcUl%acb5Mjka5T1F@zmqvST1R$H#IEw4BfKzOhnb_)Nv6Z;oD
z^gK^MlHgggbcflZ(r@G&?y)QMAJ;~o@_|m@`vaA~;YV6SnE#d0*yP&hhyFc;WU%
z<<8Yd1wLJEg03VzEiV6j_4#SP4;Bha{+k&9bm_JJe@ED4`+JK22bckZ^6p6;E++Z+
z6Y;ElR|lZC`%MX;2N^cikU}{&^cDW}B>GD+;pm=TfJSgSTAZoqq%Cl9u8nd?j&|7>
zkMnTsAUGo87us4F)(#?WCD_GdM0vj_Q(sHnTSf2Hi<+|g0qR0Nh5lcb<3sM%?w8S6
zndN=eu*~{Nw4BgjwVT+slVfDMGlFyu#&2kY}ub?QQm3){AdE3z}JP
zsue%x&`0xd8|bu}v09t;d=$IF7%LOeiYE4T>!IDvqG8?JnH=yCO1(y`t0JK~RPe9j
z5cc0uX~UEyk@Z%7)rs__l{mz7NB(Wq!gb_}jU`{!kXc9&^hBXZY8DzJsJGf2GA!G>
zd%tJ>v^Dm(tlK1BUER@D&+m$2T;g+H-8{|Cvx
z&KLcgGxm5+PzvMWm>?YdGk64KL?n2`7Y`d!59b0g5D+oR+1|g#Qbxk2FeGDTcl?}P
z_2!*Y>~D?_A02*9P&ywY<4}EC(s{67z6o@Zo479GnQ?4*=#GJICSqyPuL-&;5ckScDg>tkn5SVBjF
zHw87BYt)7H62qX}xj9=Qf*C(1EN`z1v(ObNX+w%S`zmCA3klLcYxbC|Ko_Lf_y66S6xIRj*M8qL*8!gLXzioX@pVu|r4xt-FcHV(_Oz{VN
zslO&y6vd^UNx|VQ5jI34tqpH`Mp{rAjK_0$jDUFxVw+tEJ$##%Yq5IeJjw
z0{~YB`bALtZbOUZKBVY31Mo*mRU!3oZXQq_cwiIbZgen?G`zO
z&YNDvQTq!_LdA3wb7^V4V3C#6qN*!1XjG1
ztSV*a%IPN#^=qL`&Y(=y1|Vn^coWz
zyBfhBA1i<|2_DC5`q)JuH!dUZd_6RReff{`4HR0eI}<#>0b&ftqzwkYW$$|19v*}J
zpSKgLKcw+hWYgh#|91s}+AY%6H4)33%Y}AvKkjeHy)!wXpEXXI4aVD19#&0bpa!3X
zaVmNzgmKCYCfiTM8qnK2_cX>UvP&AS0+drBD;Ls~zGy4%0k40zKNTn4!=3sD>FqJ;
zfcc)|Pn0}MZrpUQkC<8F+wuD9C-rZ(-)v)>(hVPpM-n-KjuH-S&h)oe)ehy(B+=Rm
z4Qns-H^)>R7WZ2x+KSdA8LtD^*eH@xf3^O~s%_oNt;RRbajY?wkLlOeJ-rXsjz__n<`gS-PfYt5)D}5*R>h~Vt
zXstVy`;A8WdGUVK57SIO>Ro!P%aey=3Sp6p$^O)V@wb*~oMvCOeKshGJ
zC7l`F{pw?v@3$^PH&GqE&NT8AmN?X?ZxXhS)~)K_=MgYd8Vrf(a$TywZV<)2w`5Ib
zUH^LiazICBAObJ_>t(+@!W;F?om<%^Pk9B0-(>N|m9;)UkQ2xyxF^4}qXqriI;Is)
zvmB+G7bh(e#so-G^TK30^iRh3>0XJ+JJiiRj~jsx&fUiQow+tsq7s5niLZ1jB$+eR
zYo|bEZ{634gQSAQRMjwXP;-W3@~bZIR#s-n1T(2U|6_03P(MsmI@gLRrS)L5E?71)
zmUA?rwB%z?28SqVmwMojH6x7JI69Vtw>ft0U%(ov*!XP2%g1TY=>bgSCST@tUwaqX
z@mLKmsc&ppy9Ws9li<+kP=BSEjr~*t0Jcx?YLZKJc8O#ALBFh`?X?brhOSoX7-Cr5RiahVx+-Z+6lbwzkOYU0}MjwZSeb!}cKx
z6sMd~7B^HdO0#aFxZWhefhceWP9=k*zmiAd@yOVN9x`LvKeyO=hg-*=YZh%onWgq4
zEX{O#u*X?*d;qZ&gz71pYmZ#)(`-VWflZ)VV+>N47F$I@CLJ5FVgJrwCc)$;G89;^
zqowpS{Oc^v;_}EfGlQV#g(%%+^oP2yI+2k?03R7kbm1&QMZvu2bMRFUQi*#Lw52cyx%Dza(8SYJEbzep?tNV`7z8`-yr8COketWWsr8kjrqP}DCoN>&udh-
zxx>nAzE?IM3F^Y~#6w2Fb}z0YDw6BUe$nn9rh6hd36u!UMs?9J*^w?&8_S>r8{Da_
z#z9Q=0LWoohkk$F*-H)u?7ACa)pn}OD24PcQuQ*VUWKluH&K1YJGFuuf^@nRGkU(W
z+}6ZI4U;6|WgP4@T$fY6-)r)M8%BBp4tI*r{pWp3_q2C-tdU(&(L%VpM+1X>!L?}h
zFJ8w4k*MFS;S%IG0C~%{xIctdrdmEsb?J$*JG_9;URGjxzL?tt8iU1S@3ODs*2<-8
zh~ls2v9piQv}mO5{{n_T2&-;^s6&w)iwRv2s2m`kK}{CKs7
zeWIVrM(1jqG+I3P7s?Nr@#TZtwNht*`-o`Xr%E3-g#IpZ?tm-GwepRlK=+(a2-? q+@wy)_LJ@aX)#9Eq0;OTx=|hcxS;Nm4
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