@zenalexa/unicli 0.220.1 → 0.221.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +35 -13
- package/README.md +18 -16
- package/README.zh-CN.md +18 -16
- package/dist/adapters/acl-anthology/papers.d.ts +16 -0
- package/dist/adapters/acl-anthology/papers.d.ts.map +1 -0
- package/dist/adapters/acl-anthology/papers.js +135 -0
- package/dist/adapters/acl-anthology/papers.js.map +1 -0
- package/dist/adapters/arxiv/papers.js +2 -0
- package/dist/adapters/arxiv/papers.js.map +1 -1
- package/dist/adapters/baidu-scholar/search.js +5 -0
- package/dist/adapters/baidu-scholar/search.js.map +1 -1
- package/dist/adapters/bilibili/comments.js +66 -4
- package/dist/adapters/bilibili/comments.js.map +1 -1
- package/dist/adapters/bilibili/compat.js +2 -2
- package/dist/adapters/bilibili/compat.js.map +1 -1
- package/dist/adapters/bilibili/download.js +4 -4
- package/dist/adapters/bilibili/download.js.map +1 -1
- package/dist/adapters/bilibili/wbi.d.ts.map +1 -1
- package/dist/adapters/bilibili/wbi.js +3 -3
- package/dist/adapters/bilibili/wbi.js.map +1 -1
- package/dist/adapters/cipo/_shared.d.ts +21 -0
- package/dist/adapters/cipo/_shared.d.ts.map +1 -0
- package/dist/adapters/cipo/_shared.js +67 -0
- package/dist/adapters/cipo/_shared.js.map +1 -0
- package/dist/adapters/cipo/get.d.ts +19 -0
- package/dist/adapters/cipo/get.d.ts.map +1 -0
- package/dist/adapters/cipo/get.js +140 -0
- package/dist/adapters/cipo/get.js.map +1 -0
- package/dist/adapters/cipo/legal-status.d.ts +19 -0
- package/dist/adapters/cipo/legal-status.d.ts.map +1 -0
- package/dist/adapters/cipo/legal-status.js +111 -0
- package/dist/adapters/cipo/legal-status.js.map +1 -0
- package/dist/adapters/cipo/search.d.ts +20 -0
- package/dist/adapters/cipo/search.d.ts.map +1 -0
- package/dist/adapters/cipo/search.js +148 -0
- package/dist/adapters/cipo/search.js.map +1 -0
- package/dist/adapters/cnipa/_shared.d.ts +47 -0
- package/dist/adapters/cnipa/_shared.d.ts.map +1 -0
- package/dist/adapters/cnipa/_shared.js +97 -0
- package/dist/adapters/cnipa/_shared.js.map +1 -0
- package/dist/adapters/cnipa/get.d.ts +19 -0
- package/dist/adapters/cnipa/get.d.ts.map +1 -0
- package/dist/adapters/cnipa/get.js +149 -0
- package/dist/adapters/cnipa/get.js.map +1 -0
- package/dist/adapters/cnipa/legal-status.d.ts +19 -0
- package/dist/adapters/cnipa/legal-status.d.ts.map +1 -0
- package/dist/adapters/cnipa/legal-status.js +119 -0
- package/dist/adapters/cnipa/legal-status.js.map +1 -0
- package/dist/adapters/cnipa/search.d.ts +21 -0
- package/dist/adapters/cnipa/search.d.ts.map +1 -0
- package/dist/adapters/cnipa/search.js +170 -0
- package/dist/adapters/cnipa/search.js.map +1 -0
- package/dist/adapters/crossref/works.d.ts +42 -0
- package/dist/adapters/crossref/works.d.ts.map +1 -0
- package/dist/adapters/crossref/works.js +157 -0
- package/dist/adapters/crossref/works.js.map +1 -0
- package/dist/adapters/cvf/papers.d.ts +17 -0
- package/dist/adapters/cvf/papers.d.ts.map +1 -0
- package/dist/adapters/cvf/papers.js +124 -0
- package/dist/adapters/cvf/papers.js.map +1 -0
- package/dist/adapters/dblp/publications.js +4 -0
- package/dist/adapters/dblp/publications.js.map +1 -1
- package/dist/adapters/espacenet/_shared.d.ts +21 -0
- package/dist/adapters/espacenet/_shared.d.ts.map +1 -0
- package/dist/adapters/espacenet/_shared.js +67 -0
- package/dist/adapters/espacenet/_shared.js.map +1 -0
- package/dist/adapters/espacenet/family.d.ts +19 -0
- package/dist/adapters/espacenet/family.d.ts.map +1 -0
- package/dist/adapters/espacenet/family.js +118 -0
- package/dist/adapters/espacenet/family.js.map +1 -0
- package/dist/adapters/espacenet/get.d.ts +19 -0
- package/dist/adapters/espacenet/get.d.ts.map +1 -0
- package/dist/adapters/espacenet/get.js +130 -0
- package/dist/adapters/espacenet/get.js.map +1 -0
- package/dist/adapters/espacenet/legal-status.d.ts +19 -0
- package/dist/adapters/espacenet/legal-status.d.ts.map +1 -0
- package/dist/adapters/espacenet/legal-status.js +110 -0
- package/dist/adapters/espacenet/legal-status.js.map +1 -0
- package/dist/adapters/espacenet/search.d.ts +20 -0
- package/dist/adapters/espacenet/search.d.ts.map +1 -0
- package/dist/adapters/espacenet/search.js +165 -0
- package/dist/adapters/espacenet/search.js.map +1 -0
- package/dist/adapters/facebook/subtitles.d.ts +9 -0
- package/dist/adapters/facebook/subtitles.d.ts.map +1 -0
- package/dist/adapters/facebook/subtitles.js +42 -0
- package/dist/adapters/facebook/subtitles.js.map +1 -0
- package/dist/adapters/fips/_shared.d.ts +21 -0
- package/dist/adapters/fips/_shared.d.ts.map +1 -0
- package/dist/adapters/fips/_shared.js +77 -0
- package/dist/adapters/fips/_shared.js.map +1 -0
- package/dist/adapters/fips/get.d.ts +19 -0
- package/dist/adapters/fips/get.d.ts.map +1 -0
- package/dist/adapters/fips/get.js +139 -0
- package/dist/adapters/fips/get.js.map +1 -0
- package/dist/adapters/fips/search.d.ts +20 -0
- package/dist/adapters/fips/search.d.ts.map +1 -0
- package/dist/adapters/fips/search.js +148 -0
- package/dist/adapters/fips/search.js.map +1 -0
- package/dist/adapters/freepatentsonline-web/_shared.d.ts +72 -0
- package/dist/adapters/freepatentsonline-web/_shared.d.ts.map +1 -0
- package/dist/adapters/freepatentsonline-web/_shared.js +216 -0
- package/dist/adapters/freepatentsonline-web/_shared.js.map +1 -0
- package/dist/adapters/freepatentsonline-web/get.d.ts +21 -0
- package/dist/adapters/freepatentsonline-web/get.d.ts.map +1 -0
- package/dist/adapters/freepatentsonline-web/get.js +127 -0
- package/dist/adapters/freepatentsonline-web/get.js.map +1 -0
- package/dist/adapters/freepatentsonline-web/search.d.ts +22 -0
- package/dist/adapters/freepatentsonline-web/search.d.ts.map +1 -0
- package/dist/adapters/freepatentsonline-web/search.js +149 -0
- package/dist/adapters/freepatentsonline-web/search.js.map +1 -0
- package/dist/adapters/google-patents-web/_shared.d.ts +110 -0
- package/dist/adapters/google-patents-web/_shared.d.ts.map +1 -0
- package/dist/adapters/google-patents-web/_shared.js +164 -0
- package/dist/adapters/google-patents-web/_shared.js.map +1 -0
- package/dist/adapters/google-patents-web/get.d.ts +36 -0
- package/dist/adapters/google-patents-web/get.d.ts.map +1 -0
- package/dist/adapters/google-patents-web/get.js +187 -0
- package/dist/adapters/google-patents-web/get.js.map +1 -0
- package/dist/adapters/google-patents-web/search.d.ts +23 -0
- package/dist/adapters/google-patents-web/search.d.ts.map +1 -0
- package/dist/adapters/google-patents-web/search.js +169 -0
- package/dist/adapters/google-patents-web/search.js.map +1 -0
- package/dist/adapters/google-scholar/cite.js +1 -0
- package/dist/adapters/google-scholar/cite.js.map +1 -1
- package/dist/adapters/google-scholar/profile.js +5 -0
- package/dist/adapters/google-scholar/profile.js.map +1 -1
- package/dist/adapters/google-scholar/search.js +5 -0
- package/dist/adapters/google-scholar/search.js.map +1 -1
- package/dist/adapters/hf/paper.js +1 -0
- package/dist/adapters/hf/paper.js.map +1 -1
- package/dist/adapters/inpi-br/_shared.d.ts +21 -0
- package/dist/adapters/inpi-br/_shared.d.ts.map +1 -0
- package/dist/adapters/inpi-br/_shared.js +67 -0
- package/dist/adapters/inpi-br/_shared.js.map +1 -0
- package/dist/adapters/inpi-br/get.d.ts +19 -0
- package/dist/adapters/inpi-br/get.d.ts.map +1 -0
- package/dist/adapters/inpi-br/get.js +142 -0
- package/dist/adapters/inpi-br/get.js.map +1 -0
- package/dist/adapters/inpi-br/search.d.ts +20 -0
- package/dist/adapters/inpi-br/search.d.ts.map +1 -0
- package/dist/adapters/inpi-br/search.js +154 -0
- package/dist/adapters/inpi-br/search.js.map +1 -0
- package/dist/adapters/instagram/subtitles.d.ts +9 -0
- package/dist/adapters/instagram/subtitles.d.ts.map +1 -0
- package/dist/adapters/instagram/subtitles.js +42 -0
- package/dist/adapters/instagram/subtitles.js.map +1 -0
- package/dist/adapters/mastodon/statuses.d.ts +40 -0
- package/dist/adapters/mastodon/statuses.d.ts.map +1 -0
- package/dist/adapters/mastodon/statuses.js +153 -0
- package/dist/adapters/mastodon/statuses.js.map +1 -0
- package/dist/adapters/neurips/proceedings.d.ts +17 -0
- package/dist/adapters/neurips/proceedings.d.ts.map +1 -0
- package/dist/adapters/neurips/proceedings.js +112 -0
- package/dist/adapters/neurips/proceedings.js.map +1 -0
- package/dist/adapters/openalex/works.d.ts.map +1 -1
- package/dist/adapters/openalex/works.js +32 -0
- package/dist/adapters/openalex/works.js.map +1 -1
- package/dist/adapters/openreview/papers.js +5 -0
- package/dist/adapters/openreview/papers.js.map +1 -1
- package/dist/adapters/pmlr/proceedings.d.ts +35 -0
- package/dist/adapters/pmlr/proceedings.d.ts.map +1 -0
- package/dist/adapters/pmlr/proceedings.js +139 -0
- package/dist/adapters/pmlr/proceedings.js.map +1 -0
- package/dist/adapters/pubmed/articles.js +5 -0
- package/dist/adapters/pubmed/articles.js.map +1 -1
- package/dist/adapters/reddit/comments.d.ts +9 -0
- package/dist/adapters/reddit/comments.d.ts.map +1 -0
- package/dist/adapters/reddit/comments.js +124 -0
- package/dist/adapters/reddit/comments.js.map +1 -0
- package/dist/adapters/semantic-scholar/papers.d.ts +36 -0
- package/dist/adapters/semantic-scholar/papers.d.ts.map +1 -0
- package/dist/adapters/semantic-scholar/papers.js +214 -0
- package/dist/adapters/semantic-scholar/papers.js.map +1 -0
- package/dist/adapters/threads/post.d.ts +32 -0
- package/dist/adapters/threads/post.d.ts.map +1 -0
- package/dist/adapters/threads/post.js +287 -0
- package/dist/adapters/threads/post.js.map +1 -0
- package/dist/adapters/tiktok/subtitles.d.ts +9 -0
- package/dist/adapters/tiktok/subtitles.d.ts.map +1 -0
- package/dist/adapters/tiktok/subtitles.js +42 -0
- package/dist/adapters/tiktok/subtitles.js.map +1 -0
- package/dist/adapters/twitter/accept.js +2 -2
- package/dist/adapters/twitter/accept.js.map +1 -1
- package/dist/adapters/twitter/browser-fallback.d.ts +26 -0
- package/dist/adapters/twitter/browser-fallback.d.ts.map +1 -0
- package/dist/adapters/twitter/browser-fallback.js +93 -0
- package/dist/adapters/twitter/browser-fallback.js.map +1 -0
- package/dist/adapters/twitter/browser-state.d.ts +11 -0
- package/dist/adapters/twitter/browser-state.d.ts.map +1 -0
- package/dist/adapters/twitter/browser-state.js +46 -0
- package/dist/adapters/twitter/browser-state.js.map +1 -0
- package/dist/adapters/twitter/client.d.ts.map +1 -1
- package/dist/adapters/twitter/client.js +36 -13
- package/dist/adapters/twitter/client.js.map +1 -1
- package/dist/adapters/twitter/reply-dm.js +2 -2
- package/dist/adapters/twitter/reply-dm.js.map +1 -1
- package/dist/adapters/twitter/reply.js +1 -0
- package/dist/adapters/twitter/reply.js.map +1 -1
- package/dist/adapters/twitter/search.js +11 -18
- package/dist/adapters/twitter/search.js.map +1 -1
- package/dist/adapters/twitter/thread.d.ts +14 -0
- package/dist/adapters/twitter/thread.d.ts.map +1 -1
- package/dist/adapters/twitter/thread.js +28 -2
- package/dist/adapters/twitter/thread.js.map +1 -1
- package/dist/adapters/twitter/trending.js +13 -59
- package/dist/adapters/twitter/trending.js.map +1 -1
- package/dist/adapters/unpaywall/works.d.ts +33 -0
- package/dist/adapters/unpaywall/works.d.ts.map +1 -0
- package/dist/adapters/unpaywall/works.js +101 -0
- package/dist/adapters/unpaywall/works.js.map +1 -0
- package/dist/adapters/xiaohongshu/browser-state.d.ts +19 -0
- package/dist/adapters/xiaohongshu/browser-state.d.ts.map +1 -0
- package/dist/adapters/xiaohongshu/browser-state.js +67 -0
- package/dist/adapters/xiaohongshu/browser-state.js.map +1 -0
- package/dist/adapters/xiaohongshu/comments.js +28 -5
- package/dist/adapters/xiaohongshu/comments.js.map +1 -1
- package/dist/adapters/xiaohongshu/download.js +49 -11
- package/dist/adapters/xiaohongshu/download.js.map +1 -1
- package/dist/adapters/xiaohongshu/search.d.ts.map +1 -1
- package/dist/adapters/xiaohongshu/search.js +11 -5
- package/dist/adapters/xiaohongshu/search.js.map +1 -1
- package/dist/adapters/xiaohongshu/trending.d.ts +9 -0
- package/dist/adapters/xiaohongshu/trending.d.ts.map +1 -0
- package/dist/adapters/xiaohongshu/trending.js +94 -0
- package/dist/adapters/xiaohongshu/trending.js.map +1 -0
- package/dist/adapters/youtube/comments.d.ts +80 -0
- package/dist/adapters/youtube/comments.d.ts.map +1 -1
- package/dist/adapters/youtube/comments.js +108 -12
- package/dist/adapters/youtube/comments.js.map +1 -1
- package/dist/adapters/youtube/subtitles.d.ts +9 -0
- package/dist/adapters/youtube/subtitles.d.ts.map +1 -0
- package/dist/adapters/youtube/subtitles.js +42 -0
- package/dist/adapters/youtube/subtitles.js.map +1 -0
- package/dist/adapters/yt-dlp/subtitles.d.ts +9 -0
- package/dist/adapters/yt-dlp/subtitles.d.ts.map +1 -0
- package/dist/adapters/yt-dlp/subtitles.js +41 -0
- package/dist/adapters/yt-dlp/subtitles.js.map +1 -0
- package/dist/adapters/zhihu/answer-detail.d.ts +39 -0
- package/dist/adapters/zhihu/answer-detail.d.ts.map +1 -0
- package/dist/adapters/zhihu/answer-detail.js +204 -0
- package/dist/adapters/zhihu/answer-detail.js.map +1 -0
- package/dist/adapters/zhihu/comment.d.ts +9 -0
- package/dist/adapters/zhihu/comment.d.ts.map +1 -0
- package/dist/adapters/zhihu/comment.js +149 -0
- package/dist/adapters/zhihu/comment.js.map +1 -0
- package/dist/adapters/zhihu/recommend.d.ts +36 -0
- package/dist/adapters/zhihu/recommend.d.ts.map +1 -0
- package/dist/adapters/zhihu/recommend.js +151 -0
- package/dist/adapters/zhihu/recommend.js.map +1 -0
- package/dist/browser/bridge.d.ts.map +1 -1
- package/dist/browser/bridge.js +14 -3
- package/dist/browser/bridge.js.map +1 -1
- package/dist/browser/daemon-client.d.ts +6 -0
- package/dist/browser/daemon-client.d.ts.map +1 -1
- package/dist/browser/daemon-client.js +75 -15
- package/dist/browser/daemon-client.js.map +1 -1
- package/dist/browser/daemon.js +39 -15
- package/dist/browser/daemon.js.map +1 -1
- package/dist/browser/protocol.d.ts +1 -0
- package/dist/browser/protocol.d.ts.map +1 -1
- package/dist/browser/protocol.js +1 -0
- package/dist/browser/protocol.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +21 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/approvals.d.ts.map +1 -1
- package/dist/commands/approvals.js +1 -37
- package/dist/commands/approvals.js.map +1 -1
- package/dist/commands/browser/index.d.ts.map +1 -1
- package/dist/commands/browser/index.js +7 -2
- package/dist/commands/browser/index.js.map +1 -1
- package/dist/commands/daemon.d.ts.map +1 -1
- package/dist/commands/daemon.js +7 -3
- package/dist/commands/daemon.js.map +1 -1
- package/dist/commands/dispatch.d.ts.map +1 -1
- package/dist/commands/dispatch.js +27 -3
- package/dist/commands/dispatch.js.map +1 -1
- package/dist/commands/do.d.ts +30 -0
- package/dist/commands/do.d.ts.map +1 -0
- package/dist/commands/do.js +248 -0
- package/dist/commands/do.js.map +1 -0
- package/dist/commands/extract.d.ts +34 -0
- package/dist/commands/extract.d.ts.map +1 -0
- package/dist/commands/extract.js +316 -0
- package/dist/commands/extract.js.map +1 -0
- package/dist/commands/patent-doctor.d.ts +48 -0
- package/dist/commands/patent-doctor.d.ts.map +1 -0
- package/dist/commands/patent-doctor.js +109 -0
- package/dist/commands/patent-doctor.js.map +1 -0
- package/dist/commands/patent.d.ts +78 -0
- package/dist/commands/patent.d.ts.map +1 -0
- package/dist/commands/patent.js +919 -0
- package/dist/commands/patent.js.map +1 -0
- package/dist/commands/scholar.d.ts +33 -0
- package/dist/commands/scholar.d.ts.map +1 -0
- package/dist/commands/scholar.js +494 -0
- package/dist/commands/scholar.js.map +1 -0
- package/dist/commands/search.d.ts.map +1 -1
- package/dist/commands/search.js +2 -5
- package/dist/commands/search.js.map +1 -1
- package/dist/commands/social.d.ts +19 -0
- package/dist/commands/social.d.ts.map +1 -0
- package/dist/commands/social.js +236 -0
- package/dist/commands/social.js.map +1 -0
- package/dist/core/registry.d.ts +1 -1
- package/dist/core/registry.d.ts.map +1 -1
- package/dist/core/registry.js +11 -2
- package/dist/core/registry.js.map +1 -1
- package/dist/discovery/aliases.d.ts +2 -2
- package/dist/discovery/aliases.d.ts.map +1 -1
- package/dist/discovery/aliases.js +182 -11
- package/dist/discovery/aliases.js.map +1 -1
- package/dist/discovery/intents.d.ts +10 -0
- package/dist/discovery/intents.d.ts.map +1 -0
- package/dist/discovery/intents.js +255 -0
- package/dist/discovery/intents.js.map +1 -0
- package/dist/discovery/loader.d.ts.map +1 -1
- package/dist/discovery/loader.js +4 -0
- package/dist/discovery/loader.js.map +1 -1
- package/dist/discovery/search.d.ts +4 -1
- package/dist/discovery/search.d.ts.map +1 -1
- package/dist/discovery/search.js +28 -140
- package/dist/discovery/search.js.map +1 -1
- package/dist/engine/approval-presenter.d.ts +10 -0
- package/dist/engine/approval-presenter.d.ts.map +1 -0
- package/dist/engine/approval-presenter.js +45 -0
- package/dist/engine/approval-presenter.js.map +1 -0
- package/dist/engine/approval-store.d.ts +4 -0
- package/dist/engine/approval-store.d.ts.map +1 -1
- package/dist/engine/approval-store.js +85 -11
- package/dist/engine/approval-store.js.map +1 -1
- package/dist/engine/auth/oauth2-cc.d.ts +67 -0
- package/dist/engine/auth/oauth2-cc.d.ts.map +1 -0
- package/dist/engine/auth/oauth2-cc.js +120 -0
- package/dist/engine/auth/oauth2-cc.js.map +1 -0
- package/dist/engine/cookies.d.ts +10 -0
- package/dist/engine/cookies.d.ts.map +1 -1
- package/dist/engine/cookies.js +64 -0
- package/dist/engine/cookies.js.map +1 -1
- package/dist/engine/download.d.ts +5 -0
- package/dist/engine/download.d.ts.map +1 -1
- package/dist/engine/download.js +11 -4
- package/dist/engine/download.js.map +1 -1
- package/dist/engine/executor.d.ts +1 -0
- package/dist/engine/executor.d.ts.map +1 -1
- package/dist/engine/executor.js +25 -0
- package/dist/engine/executor.js.map +1 -1
- package/dist/engine/framework.d.ts +5 -5
- package/dist/engine/framework.js +5 -5
- package/dist/engine/harden.d.ts +1 -1
- package/dist/engine/harden.js +1 -1
- package/dist/engine/kernel/stages.d.ts.map +1 -1
- package/dist/engine/kernel/stages.js +2 -1
- package/dist/engine/kernel/stages.js.map +1 -1
- package/dist/engine/normalizer/patent-envelope.d.ts +61 -0
- package/dist/engine/normalizer/patent-envelope.d.ts.map +1 -0
- package/dist/engine/normalizer/patent-envelope.js +132 -0
- package/dist/engine/normalizer/patent-envelope.js.map +1 -0
- package/dist/engine/research.d.ts +5 -7
- package/dist/engine/research.d.ts.map +1 -1
- package/dist/engine/research.js +6 -9
- package/dist/engine/research.js.map +1 -1
- package/dist/engine/steps/browser-helpers.d.ts +2 -2
- package/dist/engine/steps/browser-helpers.d.ts.map +1 -1
- package/dist/engine/steps/browser-helpers.js +39 -16
- package/dist/engine/steps/browser-helpers.js.map +1 -1
- package/dist/engine/steps/download.d.ts +1 -0
- package/dist/engine/steps/download.d.ts.map +1 -1
- package/dist/engine/steps/download.js +3 -1
- package/dist/engine/steps/download.js.map +1 -1
- package/dist/engine/steps/index.d.ts +2 -0
- package/dist/engine/steps/index.d.ts.map +1 -1
- package/dist/engine/steps/index.js +2 -0
- package/dist/engine/steps/index.js.map +1 -1
- package/dist/engine/steps/oauth2-token.d.ts +41 -0
- package/dist/engine/steps/oauth2-token.d.ts.map +1 -0
- package/dist/engine/steps/oauth2-token.js +115 -0
- package/dist/engine/steps/oauth2-token.js.map +1 -0
- package/dist/engine/steps/select-xml.d.ts +34 -0
- package/dist/engine/steps/select-xml.d.ts.map +1 -0
- package/dist/engine/steps/select-xml.js +222 -0
- package/dist/engine/steps/select-xml.js.map +1 -0
- package/dist/engine/template.d.ts.map +1 -1
- package/dist/engine/template.js +7 -0
- package/dist/engine/template.js.map +1 -1
- package/dist/engine/transport/mcp-browser.d.ts +128 -0
- package/dist/engine/transport/mcp-browser.d.ts.map +1 -0
- package/dist/engine/transport/mcp-browser.js +120 -0
- package/dist/engine/transport/mcp-browser.js.map +1 -0
- package/dist/fast-path/handlers/approvals.d.ts +11 -0
- package/dist/fast-path/handlers/approvals.d.ts.map +1 -0
- package/dist/fast-path/handlers/approvals.js +136 -0
- package/dist/fast-path/handlers/approvals.js.map +1 -0
- package/dist/fast-path/handlers/discovery.d.ts.map +1 -1
- package/dist/fast-path/handlers/discovery.js +17 -3
- package/dist/fast-path/handlers/discovery.js.map +1 -1
- package/dist/fast-path/manifest.d.ts +1 -0
- package/dist/fast-path/manifest.d.ts.map +1 -1
- package/dist/fast-path/manifest.js.map +1 -1
- package/dist/fast-path.d.ts.map +1 -1
- package/dist/fast-path.js +3 -0
- package/dist/fast-path.js.map +1 -1
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest-compact.txt +13 -11
- package/dist/manifest-search.json +1 -1
- package/dist/manifest.json +2560 -103
- package/dist/mcp/handler.d.ts.map +1 -1
- package/dist/mcp/handler.js +14 -2
- package/dist/mcp/handler.js.map +1 -1
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +11 -3
- package/dist/mcp/tools.js.map +1 -1
- package/dist/output/auth-guidance.d.ts +14 -0
- package/dist/output/auth-guidance.d.ts.map +1 -0
- package/dist/output/auth-guidance.js +50 -0
- package/dist/output/auth-guidance.js.map +1 -0
- package/dist/output/error-map.d.ts +1 -1
- package/dist/output/error-map.d.ts.map +1 -1
- package/dist/output/error-map.js +28 -4
- package/dist/output/error-map.js.map +1 -1
- package/dist/output/next-actions.d.ts.map +1 -1
- package/dist/output/next-actions.js +19 -3
- package/dist/output/next-actions.js.map +1 -1
- package/dist/registry.d.ts +19 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +10 -0
- package/dist/registry.js.map +1 -1
- package/dist/social/browser-errors.d.ts +13 -0
- package/dist/social/browser-errors.d.ts.map +1 -0
- package/dist/social/browser-errors.js +36 -0
- package/dist/social/browser-errors.js.map +1 -0
- package/dist/social/capabilities.d.ts +29 -0
- package/dist/social/capabilities.d.ts.map +1 -0
- package/dist/social/capabilities.js +448 -0
- package/dist/social/capabilities.js.map +1 -0
- package/dist/social/comments.d.ts +26 -0
- package/dist/social/comments.d.ts.map +1 -0
- package/dist/social/comments.js +97 -0
- package/dist/social/comments.js.map +1 -0
- package/dist/social/video-text.d.ts +27 -0
- package/dist/social/video-text.d.ts.map +1 -0
- package/dist/social/video-text.js +140 -0
- package/dist/social/video-text.js.map +1 -0
- package/dist/types/patent.d.ts +160 -0
- package/dist/types/patent.d.ts.map +1 -0
- package/dist/types/patent.js +16 -0
- package/dist/types/patent.js.map +1 -0
- package/dist/types/scholarly.d.ts +49 -0
- package/dist/types/scholarly.d.ts.map +1 -0
- package/dist/types/scholarly.js +16 -0
- package/dist/types/scholarly.js.map +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +9 -4
- package/server.json +3 -3
- package/skills/unicli/SKILL.md +1 -1
- package/skills/unicli-claude-code/SKILL.md +1 -1
- package/skills/unicli-hermes/SKILL.md +1 -1
- package/src/adapters/acl-anthology/papers.ts +157 -0
- package/src/adapters/arxiv/download.yaml +1 -1
- package/src/adapters/arxiv/paper.yaml +1 -1
- package/src/adapters/arxiv/papers.ts +2 -0
- package/src/adapters/arxiv/search.yaml +1 -1
- package/src/adapters/arxiv/trending.yaml +1 -1
- package/src/adapters/baidu-scholar/search.ts +5 -0
- package/src/adapters/bilibili/comments-tree.test.ts +41 -0
- package/src/adapters/bilibili/comments.ts +78 -4
- package/src/adapters/bilibili/compat.ts +5 -2
- package/src/adapters/bilibili/download.ts +7 -4
- package/src/adapters/bilibili/wbi.ts +6 -3
- package/src/adapters/brave/search.yaml +53 -0
- package/src/adapters/cipo/_shared.ts +98 -0
- package/src/adapters/cipo/get.ts +188 -0
- package/src/adapters/cipo/legal-status.ts +148 -0
- package/src/adapters/cipo/search.ts +195 -0
- package/src/adapters/cnipa/_shared.ts +138 -0
- package/src/adapters/cnipa/get.ts +199 -0
- package/src/adapters/cnipa/legal-status.ts +162 -0
- package/src/adapters/cnipa/search.ts +229 -0
- package/src/adapters/crossref/works.ts +209 -0
- package/src/adapters/cvf/papers.ts +136 -0
- package/src/adapters/dblp/publications.ts +4 -0
- package/src/adapters/dpma/get.yaml +67 -0
- package/src/adapters/dpma/search.yaml +77 -0
- package/src/adapters/duckduckgo/search.yaml +54 -0
- package/src/adapters/duckduckgo/suggest.yaml +52 -0
- package/src/adapters/epo/family.yaml +69 -0
- package/src/adapters/epo/get.yaml +74 -0
- package/src/adapters/epo/legal-status.yaml +63 -0
- package/src/adapters/epo/search.yaml +84 -0
- package/src/adapters/espacenet/_shared.ts +98 -0
- package/src/adapters/espacenet/family.ts +161 -0
- package/src/adapters/espacenet/get.ts +185 -0
- package/src/adapters/espacenet/legal-status.ts +151 -0
- package/src/adapters/espacenet/search.ts +229 -0
- package/src/adapters/facebook/subtitles.ts +44 -0
- package/src/adapters/fips/_shared.ts +109 -0
- package/src/adapters/fips/get.ts +186 -0
- package/src/adapters/fips/search.ts +195 -0
- package/src/adapters/freepatentsonline-web/_shared.ts +273 -0
- package/src/adapters/freepatentsonline-web/get.ts +144 -0
- package/src/adapters/freepatentsonline-web/search.ts +170 -0
- package/src/adapters/google-patents-bq/prior-art.yaml +80 -0
- package/src/adapters/google-patents-bq/search.yaml +97 -0
- package/src/adapters/google-patents-web/_shared.ts +242 -0
- package/src/adapters/google-patents-web/get.ts +224 -0
- package/src/adapters/google-patents-web/search.ts +196 -0
- package/src/adapters/google-scholar/cite.ts +1 -0
- package/src/adapters/google-scholar/profile.ts +5 -0
- package/src/adapters/google-scholar/search.ts +5 -0
- package/src/adapters/hf/paper.test.ts +10 -0
- package/src/adapters/hf/paper.ts +1 -0
- package/src/adapters/hf/top.yaml +1 -1
- package/src/adapters/huggingface-papers/daily.yaml +1 -1
- package/src/adapters/huggingface-papers/search.yaml +1 -1
- package/src/adapters/inpi-br/_shared.ts +98 -0
- package/src/adapters/inpi-br/get.ts +193 -0
- package/src/adapters/inpi-br/search.ts +206 -0
- package/src/adapters/inpi-fr/get.yaml +62 -0
- package/src/adapters/inpi-fr/search.yaml +74 -0
- package/src/adapters/instagram/subtitles.ts +44 -0
- package/src/adapters/ipaustralia/get.yaml +67 -0
- package/src/adapters/ipaustralia/search.yaml +74 -0
- package/src/adapters/jpo/get.yaml +63 -0
- package/src/adapters/jpo/search.yaml +76 -0
- package/src/adapters/kipris/get.yaml +69 -0
- package/src/adapters/kipris/legal-status.yaml +58 -0
- package/src/adapters/kipris/search.yaml +79 -0
- package/src/adapters/lens/get.yaml +64 -0
- package/src/adapters/lens/search.yaml +82 -0
- package/src/adapters/mastodon/statuses.test.ts +82 -0
- package/src/adapters/mastodon/statuses.ts +208 -0
- package/src/adapters/neurips/proceedings.ts +126 -0
- package/src/adapters/openalex/works.ts +33 -0
- package/src/adapters/openreview/papers.ts +5 -0
- package/src/adapters/patsnap/get.yaml +65 -0
- package/src/adapters/patsnap/search.yaml +77 -0
- package/src/adapters/pmlr/proceedings.ts +167 -0
- package/src/adapters/pqai/prior-art.yaml +59 -0
- package/src/adapters/pqai/search.yaml +60 -0
- package/src/adapters/pubmed/articles.ts +5 -0
- package/src/adapters/reddit/comments-tree.test.ts +79 -0
- package/src/adapters/reddit/comments.ts +159 -0
- package/src/adapters/semantic-scholar/papers.ts +268 -0
- package/src/adapters/threads/post.test.ts +64 -0
- package/src/adapters/threads/post.ts +366 -0
- package/src/adapters/threads/user.yaml +73 -0
- package/src/adapters/tiktok/subtitles.ts +44 -0
- package/src/adapters/twitter/accept.ts +5 -2
- package/src/adapters/twitter/browser-fallback.ts +138 -0
- package/src/adapters/twitter/browser-state.ts +74 -0
- package/src/adapters/twitter/client.ts +51 -21
- package/src/adapters/twitter/reply-dm.ts +5 -2
- package/src/adapters/twitter/reply.ts +1 -0
- package/src/adapters/twitter/search.ts +12 -38
- package/src/adapters/twitter/thread.test.ts +43 -0
- package/src/adapters/twitter/thread.ts +44 -2
- package/src/adapters/twitter/trending.ts +14 -95
- package/src/adapters/ukipo/info.yaml +43 -0
- package/src/adapters/unpaywall/works.ts +138 -0
- package/src/adapters/uspto/get.yaml +67 -0
- package/src/adapters/uspto/legal-status.yaml +58 -0
- package/src/adapters/uspto/search.yaml +88 -0
- package/src/adapters/wipo-patentscope/info.yaml +43 -0
- package/src/adapters/xiaohongshu/browser-state.ts +95 -0
- package/src/adapters/xiaohongshu/comments.ts +29 -6
- package/src/adapters/xiaohongshu/download.ts +60 -11
- package/src/adapters/xiaohongshu/search.ts +18 -6
- package/src/adapters/xiaohongshu/trending.ts +112 -0
- package/src/adapters/yahoo/search.yaml +52 -0
- package/src/adapters/youtube/comments-microformat.test.ts +35 -0
- package/src/adapters/youtube/comments-tree.test.ts +74 -0
- package/src/adapters/youtube/comments.ts +166 -12
- package/src/adapters/youtube/subtitles.ts +44 -0
- package/src/adapters/yt-dlp/subtitles.ts +43 -0
- package/src/adapters/zhihu/answer-detail.test.ts +83 -0
- package/src/adapters/zhihu/answer-detail.ts +275 -0
- package/src/adapters/zhihu/comment-tree.test.ts +57 -0
- package/src/adapters/zhihu/comment.ts +186 -0
- package/src/adapters/zhihu/recommend.test.ts +65 -0
- package/src/adapters/zhihu/recommend.ts +207 -0
- package/src/adapters/zotero/search.yaml +1 -1
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @owner src/commands/extract.ts
|
|
3
|
+
* @does One-shot URL → cleaned Markdown/text/HTML extraction without
|
|
4
|
+
* adapter awareness. Stateless agent verb: fetch + render in a
|
|
5
|
+
* single CLI call, no browser session, no auth, no pipeline
|
|
6
|
+
* composition required.
|
|
7
|
+
* @needs turndown, commander, src/engine/ssrf, src/engine/proxy,
|
|
8
|
+
* src/output/{envelope,formatter}, src/constants
|
|
9
|
+
* @feeds src/cli.ts agent entrypoint; agents that want "fetch this URL
|
|
10
|
+
* as Markdown" without composing a fetch_text + html_to_md
|
|
11
|
+
* pipeline themselves.
|
|
12
|
+
* @breaks Emits structured envelopes. Codes:
|
|
13
|
+
* invalid_input — non-http(s) URL, SSRF block, body cap
|
|
14
|
+
* not_found — 404
|
|
15
|
+
* auth_required — 401/403
|
|
16
|
+
* rate_limited — 429
|
|
17
|
+
* api_error — other 4xx
|
|
18
|
+
* upstream_error — 5xx
|
|
19
|
+
* network_error — DNS/TCP/TLS failure or timeout
|
|
20
|
+
* Each error envelope carries next_actions with a retry hint,
|
|
21
|
+
* a `describe` link, and a `do` link.
|
|
22
|
+
* @invariants Truncates rendered content at --max-chars; never holds more
|
|
23
|
+
* than HARD_MAX_BYTES of upstream body in memory.
|
|
24
|
+
* @side-effects HTTP GET to user-supplied URL with proxy if configured.
|
|
25
|
+
* No local filesystem writes.
|
|
26
|
+
* @perf O(N) in body bytes for Turndown; N capped by HARD_MAX_BYTES.
|
|
27
|
+
* @concurrency Pure async; no shared state.
|
|
28
|
+
* @test tests/unit/commands/extract.test.ts
|
|
29
|
+
* @stability experimental
|
|
30
|
+
* @since 2026-05-18
|
|
31
|
+
*/
|
|
32
|
+
import TurndownService from "turndown";
|
|
33
|
+
import { assertSafeRequestUrl } from "../engine/ssrf.js";
|
|
34
|
+
import { getProxyAgent } from "../engine/proxy.js";
|
|
35
|
+
import { USER_AGENT } from "../constants.js";
|
|
36
|
+
import { format, detectFormat } from "../output/formatter.js";
|
|
37
|
+
const DEFAULT_MAX_CHARS = 50_000;
|
|
38
|
+
const HARD_MAX_BYTES = 5_000_000;
|
|
39
|
+
export function registerExtractCommand(program) {
|
|
40
|
+
program
|
|
41
|
+
.command("extract <url>")
|
|
42
|
+
.description("Fetch a URL and return cleaned Markdown (one-shot, no browser/auth)")
|
|
43
|
+
.option("--max-chars <n>", `Truncate rendered content at N chars (default ${DEFAULT_MAX_CHARS})`, String(DEFAULT_MAX_CHARS))
|
|
44
|
+
.option("--as <format>", "Render content as markdown|text|html (default markdown)", "markdown")
|
|
45
|
+
.action(async (url, opts) => {
|
|
46
|
+
const startedAt = Date.now();
|
|
47
|
+
const fmt = detectFormat(program.opts().format);
|
|
48
|
+
let maxChars;
|
|
49
|
+
try {
|
|
50
|
+
maxChars = parseMaxChars(opts.maxChars);
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
emitError(baseCtx(startedAt), {
|
|
54
|
+
code: "invalid_input",
|
|
55
|
+
message: e instanceof Error ? e.message : "invalid --max-chars value",
|
|
56
|
+
suggestion: `Pass a positive integer up to ${MAX_CHARS_HARD_LIMIT}`,
|
|
57
|
+
retryable: false,
|
|
58
|
+
}, fmt, url);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const renderAs = parseExtractFormat(opts.as);
|
|
62
|
+
try {
|
|
63
|
+
assertSafeRequestUrl(url);
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
emitError(baseCtx(startedAt), {
|
|
67
|
+
code: "invalid_input",
|
|
68
|
+
message: e instanceof Error ? e.message : "URL failed safety validation",
|
|
69
|
+
suggestion: "Use an http(s) URL; loopback / link-local / private ranges are blocked",
|
|
70
|
+
retryable: false,
|
|
71
|
+
}, fmt, url);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
let html;
|
|
75
|
+
let httpStatus = 0;
|
|
76
|
+
try {
|
|
77
|
+
const init = {
|
|
78
|
+
method: "GET",
|
|
79
|
+
headers: { "User-Agent": USER_AGENT },
|
|
80
|
+
};
|
|
81
|
+
const agent = getProxyAgent();
|
|
82
|
+
if (agent)
|
|
83
|
+
init.dispatcher = agent;
|
|
84
|
+
const resp = await fetch(url, init);
|
|
85
|
+
httpStatus = resp.status;
|
|
86
|
+
if (!resp.ok) {
|
|
87
|
+
emitError(baseCtx(startedAt), {
|
|
88
|
+
code: mapStatus(resp.status),
|
|
89
|
+
message: `HTTP ${resp.status} ${resp.statusText} from ${url}`,
|
|
90
|
+
suggestion: resp.status >= 500
|
|
91
|
+
? "Upstream 5xx — retry after a short delay"
|
|
92
|
+
: resp.status === 429
|
|
93
|
+
? "Rate-limited — back off and retry"
|
|
94
|
+
: resp.status === 401 || resp.status === 403
|
|
95
|
+
? "Authenticated endpoint — try `unicli auth setup <site>`"
|
|
96
|
+
: `Check that ${url} is the canonical URL`,
|
|
97
|
+
retryable: resp.status >= 500 || resp.status === 429,
|
|
98
|
+
}, fmt, url);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
const lenHeader = resp.headers.get("content-length");
|
|
102
|
+
if (lenHeader && Number(lenHeader) > HARD_MAX_BYTES) {
|
|
103
|
+
emitError(baseCtx(startedAt), {
|
|
104
|
+
// REASON: oversized upstream payload is an upstream property,
|
|
105
|
+
// not caller error — surface as `upstream_error` (exit 69) so
|
|
106
|
+
// agent retry policy knows the URL itself cannot be re-fetched
|
|
107
|
+
// smaller. retryable=false because shrink-on-retry is unlikely.
|
|
108
|
+
code: "upstream_error",
|
|
109
|
+
message: `Content-Length ${lenHeader} exceeds hard cap ${HARD_MAX_BYTES}`,
|
|
110
|
+
suggestion: "Target a smaller URL or use a streaming adapter via `unicli search`",
|
|
111
|
+
retryable: false,
|
|
112
|
+
}, fmt, url);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
html = await resp.text();
|
|
116
|
+
if (html.length > HARD_MAX_BYTES) {
|
|
117
|
+
html = html.slice(0, HARD_MAX_BYTES);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
emitError(baseCtx(startedAt), {
|
|
122
|
+
code: "network_error",
|
|
123
|
+
message: e instanceof Error ? e.message : String(e),
|
|
124
|
+
suggestion: `Network fetch failed for ${url} — verify connectivity`,
|
|
125
|
+
retryable: true,
|
|
126
|
+
}, fmt, url);
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
let content;
|
|
130
|
+
if (renderAs === "markdown") {
|
|
131
|
+
const turndown = new TurndownService({
|
|
132
|
+
headingStyle: "atx",
|
|
133
|
+
codeBlockStyle: "fenced",
|
|
134
|
+
});
|
|
135
|
+
content = turndown.turndown(html);
|
|
136
|
+
}
|
|
137
|
+
else if (renderAs === "text") {
|
|
138
|
+
content = stripTags(html);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
content = html;
|
|
142
|
+
}
|
|
143
|
+
const originalLength = content.length;
|
|
144
|
+
const truncated = originalLength > maxChars;
|
|
145
|
+
if (truncated)
|
|
146
|
+
content = content.slice(0, maxChars);
|
|
147
|
+
const ctx = {
|
|
148
|
+
command: "core.extract",
|
|
149
|
+
duration_ms: Date.now() - startedAt,
|
|
150
|
+
surface: "web",
|
|
151
|
+
next_actions: successNextActions(url, renderAs, truncated, originalLength),
|
|
152
|
+
};
|
|
153
|
+
const data = {
|
|
154
|
+
url,
|
|
155
|
+
format: renderAs,
|
|
156
|
+
http_status: httpStatus,
|
|
157
|
+
length: content.length,
|
|
158
|
+
original_length: originalLength,
|
|
159
|
+
truncated,
|
|
160
|
+
content,
|
|
161
|
+
};
|
|
162
|
+
console.log(format(data, undefined, fmt, ctx));
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
// ── helpers ──────────────────────────────────────────────────────────────────
|
|
166
|
+
function baseCtx(startedAt) {
|
|
167
|
+
return {
|
|
168
|
+
command: "core.extract",
|
|
169
|
+
duration_ms: Date.now() - startedAt,
|
|
170
|
+
surface: "web",
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Parse `--max-chars`. Throws on invalid input — caller is responsible for
|
|
175
|
+
* converting the throw into a structured `invalid_input` envelope. This is
|
|
176
|
+
* the rule-02 contract: bad CLI input is a caller bug, not a system state
|
|
177
|
+
* to silently recover from.
|
|
178
|
+
*/
|
|
179
|
+
const MAX_CHARS_HARD_LIMIT = 1_000_000;
|
|
180
|
+
function parseMaxChars(raw) {
|
|
181
|
+
const n = Number(raw);
|
|
182
|
+
if (!Number.isFinite(n) || !Number.isInteger(n) || n <= 0) {
|
|
183
|
+
throw new Error(`--max-chars must be a positive integer (got "${raw}")`);
|
|
184
|
+
}
|
|
185
|
+
if (n > MAX_CHARS_HARD_LIMIT) {
|
|
186
|
+
throw new Error(`--max-chars ${n} exceeds hard limit ${MAX_CHARS_HARD_LIMIT}`);
|
|
187
|
+
}
|
|
188
|
+
return n;
|
|
189
|
+
}
|
|
190
|
+
function parseExtractFormat(raw) {
|
|
191
|
+
const v = raw.toLowerCase();
|
|
192
|
+
if (v === "text" || v === "txt" || v === "plain")
|
|
193
|
+
return "text";
|
|
194
|
+
if (v === "html" || v === "raw")
|
|
195
|
+
return "html";
|
|
196
|
+
return "markdown";
|
|
197
|
+
}
|
|
198
|
+
function mapStatus(status) {
|
|
199
|
+
if (status === 404)
|
|
200
|
+
return "not_found";
|
|
201
|
+
if (status === 401 || status === 403)
|
|
202
|
+
return "auth_required";
|
|
203
|
+
if (status === 429)
|
|
204
|
+
return "rate_limited";
|
|
205
|
+
if (status >= 500)
|
|
206
|
+
return "upstream_error";
|
|
207
|
+
return "api_error";
|
|
208
|
+
}
|
|
209
|
+
// REASON: intentionally minimal HTML stripper for `--as text` mode. Strips
|
|
210
|
+
// scripts, styles, tags, and 5 common entities. Does NOT handle CDATA,
|
|
211
|
+
// HTML comments, numeric character references, or HTML5 `<template>` —
|
|
212
|
+
// agents post-process the output anyway. NOT a safe-HTML sanitizer.
|
|
213
|
+
function stripTags(html) {
|
|
214
|
+
return html
|
|
215
|
+
.replace(/<script[\s\S]*?<\/script>/gi, " ")
|
|
216
|
+
.replace(/<style[\s\S]*?<\/style>/gi, " ")
|
|
217
|
+
.replace(/<[^>]+>/g, " ")
|
|
218
|
+
.replace(/ /g, " ")
|
|
219
|
+
.replace(/&/g, "&")
|
|
220
|
+
.replace(/</g, "<")
|
|
221
|
+
.replace(/>/g, ">")
|
|
222
|
+
.replace(/"/g, '"')
|
|
223
|
+
.replace(/\s+/g, " ")
|
|
224
|
+
.trim();
|
|
225
|
+
}
|
|
226
|
+
function successNextActions(url, as, truncated, originalLength) {
|
|
227
|
+
const actions = [];
|
|
228
|
+
if (truncated) {
|
|
229
|
+
const fullCap = Math.min(originalLength, 1_000_000);
|
|
230
|
+
actions.push({
|
|
231
|
+
command: `unicli extract ${url} --max-chars ${fullCap}`,
|
|
232
|
+
description: `Re-extract with larger limit (full rendered length ${originalLength})`,
|
|
233
|
+
params: {
|
|
234
|
+
"max-chars": {
|
|
235
|
+
value: fullCap,
|
|
236
|
+
description: "Truncation cap in characters",
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
if (as !== "text") {
|
|
242
|
+
actions.push({
|
|
243
|
+
command: `unicli extract ${url} --as text`,
|
|
244
|
+
description: "Re-extract as plain text (no Markdown formatting)",
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
if (as !== "html") {
|
|
248
|
+
actions.push({
|
|
249
|
+
command: `unicli extract ${url} --as html`,
|
|
250
|
+
description: "Re-extract as raw HTML (no cleaning)",
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
actions.push({
|
|
254
|
+
command: `unicli do "<natural-language intent>"`,
|
|
255
|
+
description: "Route a natural-language intent to the best-matching adapter (e.g. structured site fetch instead of a raw URL)",
|
|
256
|
+
});
|
|
257
|
+
return actions;
|
|
258
|
+
}
|
|
259
|
+
function errorNextActions(url, errCode) {
|
|
260
|
+
const actions = [
|
|
261
|
+
{
|
|
262
|
+
command: `unicli extract ${url}`,
|
|
263
|
+
description: "Retry the same extraction",
|
|
264
|
+
},
|
|
265
|
+
];
|
|
266
|
+
if (errCode === "auth_required") {
|
|
267
|
+
actions.push({
|
|
268
|
+
command: `unicli auth setup <site>`,
|
|
269
|
+
description: "Authenticate before retrying",
|
|
270
|
+
params: {
|
|
271
|
+
site: {
|
|
272
|
+
description: "Short site name (e.g. `twitter`, `github`)",
|
|
273
|
+
},
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
if (errCode === "not_found" ||
|
|
278
|
+
errCode === "api_error" ||
|
|
279
|
+
errCode === "invalid_input") {
|
|
280
|
+
actions.push({
|
|
281
|
+
command: `unicli do "<natural-language intent>"`,
|
|
282
|
+
description: "Try a structured adapter instead of a raw URL fetch",
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
actions.push({
|
|
286
|
+
command: `unicli describe`,
|
|
287
|
+
description: "Inspect available commands and adapters",
|
|
288
|
+
});
|
|
289
|
+
return actions;
|
|
290
|
+
}
|
|
291
|
+
function emitError(baseCtxValue, err, fmt, url) {
|
|
292
|
+
const ctx = {
|
|
293
|
+
...baseCtxValue,
|
|
294
|
+
next_actions: errorNextActions(url, err.code),
|
|
295
|
+
error: err,
|
|
296
|
+
};
|
|
297
|
+
process.exitCode = mapExitCode(err.code);
|
|
298
|
+
console.log(format(null, undefined, fmt, ctx));
|
|
299
|
+
}
|
|
300
|
+
function mapExitCode(code) {
|
|
301
|
+
switch (code) {
|
|
302
|
+
case "auth_required":
|
|
303
|
+
return 77;
|
|
304
|
+
case "rate_limited":
|
|
305
|
+
case "network_error":
|
|
306
|
+
return 75;
|
|
307
|
+
case "upstream_error":
|
|
308
|
+
return 69;
|
|
309
|
+
case "not_found":
|
|
310
|
+
case "invalid_input":
|
|
311
|
+
return 2;
|
|
312
|
+
default:
|
|
313
|
+
return 1;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
//# sourceMappingURL=extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extract.js","sourceRoot":"","sources":["../../src/commands/extract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @owner src::commands::patent-doctor
|
|
3
|
+
* @does Parse the `@verification` header line from a YAML or TS adapter source file and resolve it to the canonical PatentVerificationStatus value; surfaces "unknown" when no header is present rather than fabricating a status.
|
|
4
|
+
* @needs node:fs, node:path, src/discovery/loader.ts (getBuiltinDirs), src/types/patent.ts
|
|
5
|
+
* @feeds src/commands/patent.ts (runDoctor — uses parseVerificationStatus to populate the doctor row); never invoked outside the patent vertical.
|
|
6
|
+
* @breaks returns "unknown" when a header is missing, malformed, or the file cannot be read; throws no errors. The honesty contract is that "unknown" is a valid, surfaced state — never silently collapsed to "verified".
|
|
7
|
+
* @invariants the parser reads only the leading two-kilobyte window of each source file; YAML/TS headers always live in the first few comment lines so this bound keeps the doctor probe fast without missing the field.
|
|
8
|
+
* @side-effects synchronous file read on the adapter's source file
|
|
9
|
+
* @perf sub-millisecond per adapter (read + regex)
|
|
10
|
+
* @concurrency safe — pure read; no mutable state
|
|
11
|
+
* @test tests/unit/commands/patent-properties.test.ts (F2 honesty gate)
|
|
12
|
+
* @stability stable — public API of the patent doctor surface
|
|
13
|
+
* @since 2026-05-18
|
|
14
|
+
*/
|
|
15
|
+
import type { PatentVerificationStatus } from "../types/patent.js";
|
|
16
|
+
/**
|
|
17
|
+
* Verification status enriched with the "unknown" fallback. The base
|
|
18
|
+
* PatentVerificationStatus enum is the published contract; "unknown" is
|
|
19
|
+
* the honest state when no header was found.
|
|
20
|
+
*/
|
|
21
|
+
export type ResolvedVerificationStatus = PatentVerificationStatus | "unknown";
|
|
22
|
+
/**
|
|
23
|
+
* Parse a single source file's verification status. Reads only the leading
|
|
24
|
+
* window (HEADER_BYTES); never invents a status. Returns "unknown" when the
|
|
25
|
+
* header is absent or unreadable, "verified" / "blocked-by-key" / etc. when
|
|
26
|
+
* the header is present and well-formed.
|
|
27
|
+
*/
|
|
28
|
+
export declare function parseVerificationStatusFromFile(filePath: string): ResolvedVerificationStatus;
|
|
29
|
+
/**
|
|
30
|
+
* Locate the YAML source file for a given adapter command. Returns
|
|
31
|
+
* `undefined` when no file is found — the caller surfaces this as
|
|
32
|
+
* "unknown" verification.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveAdapterSourcePath(adapterName: string, commandName: string): string | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Locate any source file for an adapter (any command). Used when the adapter
|
|
37
|
+
* exposes multiple commands and the doctor only needs a single verification
|
|
38
|
+
* declaration — adapter authors typically copy the same `@verification` line
|
|
39
|
+
* across every YAML in a directory. We pick the first that resolves.
|
|
40
|
+
*/
|
|
41
|
+
export declare function findAdapterSourceFile(adapterName: string, commandNames: readonly string[]): string | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Resolve an adapter's verification status by reading any of its source
|
|
44
|
+
* files. Returns "unknown" when no source file carries a verification
|
|
45
|
+
* header — never invents a state.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveAdapterVerificationStatus(adapterName: string, commandNames: readonly string[]): ResolvedVerificationStatus;
|
|
48
|
+
//# sourceMappingURL=patent-doctor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patent-doctor.d.ts","sourceRoot":"","sources":["../../src/commands/patent-doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAMH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAEnE;;;;GAIG;AACH,MAAM,MAAM,0BAA0B,GAAG,wBAAwB,GAAG,SAAS,CAAC;AAuB9E;;;;;GAKG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,MAAM,GACf,0BAA0B,CAqB5B;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CAWpB;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,SAAS,MAAM,EAAE,GAC9B,MAAM,GAAG,SAAS,CAMpB;AAED;;;;GAIG;AACH,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,SAAS,MAAM,EAAE,GAC9B,0BAA0B,CAI5B"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @owner src::commands::patent-doctor
|
|
3
|
+
* @does Parse the `@verification` header line from a YAML or TS adapter source file and resolve it to the canonical PatentVerificationStatus value; surfaces "unknown" when no header is present rather than fabricating a status.
|
|
4
|
+
* @needs node:fs, node:path, src/discovery/loader.ts (getBuiltinDirs), src/types/patent.ts
|
|
5
|
+
* @feeds src/commands/patent.ts (runDoctor — uses parseVerificationStatus to populate the doctor row); never invoked outside the patent vertical.
|
|
6
|
+
* @breaks returns "unknown" when a header is missing, malformed, or the file cannot be read; throws no errors. The honesty contract is that "unknown" is a valid, surfaced state — never silently collapsed to "verified".
|
|
7
|
+
* @invariants the parser reads only the leading two-kilobyte window of each source file; YAML/TS headers always live in the first few comment lines so this bound keeps the doctor probe fast without missing the field.
|
|
8
|
+
* @side-effects synchronous file read on the adapter's source file
|
|
9
|
+
* @perf sub-millisecond per adapter (read + regex)
|
|
10
|
+
* @concurrency safe — pure read; no mutable state
|
|
11
|
+
* @test tests/unit/commands/patent-properties.test.ts (F2 honesty gate)
|
|
12
|
+
* @stability stable — public API of the patent doctor surface
|
|
13
|
+
* @since 2026-05-18
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
16
|
+
import { join } from "node:path";
|
|
17
|
+
import { getBuiltinDirs } from "../discovery/loader.js";
|
|
18
|
+
const VERIFICATION_VALUES = [
|
|
19
|
+
"verified",
|
|
20
|
+
"blocked-by-key",
|
|
21
|
+
"blocked-by-subscription",
|
|
22
|
+
"waiting-for-api",
|
|
23
|
+
"browser-only",
|
|
24
|
+
];
|
|
25
|
+
const HEADER_BYTES = 2048;
|
|
26
|
+
/**
|
|
27
|
+
* Match an `@verification <value>` declaration in the header of a YAML or TS
|
|
28
|
+
* source file. Accepts either `# @verification …` (YAML), `// @verification …`
|
|
29
|
+
* (TS), or `* @verification …` (TS JSDoc). Also accepts `verification_status:`
|
|
30
|
+
* which appears as a YAML field in some early adapters.
|
|
31
|
+
*/
|
|
32
|
+
const HEADER_PATTERNS = [
|
|
33
|
+
/^[ \t]*(?:#|\/\/|\*)\s*@verification[ \t]+([a-z][a-z0-9-]+(?:-[a-z]+)*)/im,
|
|
34
|
+
/^[ \t]*(?:#|\/\/|\*)\s*verification_status:[ \t]+([a-z][a-z0-9-]+(?:-[a-z]+)*)/im,
|
|
35
|
+
];
|
|
36
|
+
/**
|
|
37
|
+
* Parse a single source file's verification status. Reads only the leading
|
|
38
|
+
* window (HEADER_BYTES); never invents a status. Returns "unknown" when the
|
|
39
|
+
* header is absent or unreadable, "verified" / "blocked-by-key" / etc. when
|
|
40
|
+
* the header is present and well-formed.
|
|
41
|
+
*/
|
|
42
|
+
export function parseVerificationStatusFromFile(filePath) {
|
|
43
|
+
if (!existsSync(filePath))
|
|
44
|
+
return "unknown";
|
|
45
|
+
let raw;
|
|
46
|
+
try {
|
|
47
|
+
// Reading the whole file is fine — every adapter file is <4 KiB. We
|
|
48
|
+
// could read only HEADER_BYTES via createReadStream but the synchronous
|
|
49
|
+
// path is dramatically simpler and the budget is comfortable.
|
|
50
|
+
raw = readFileSync(filePath, "utf-8");
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return "unknown";
|
|
54
|
+
}
|
|
55
|
+
const head = raw.slice(0, HEADER_BYTES);
|
|
56
|
+
for (const pattern of HEADER_PATTERNS) {
|
|
57
|
+
const match = pattern.exec(head);
|
|
58
|
+
if (!match)
|
|
59
|
+
continue;
|
|
60
|
+
const value = match[1].toLowerCase();
|
|
61
|
+
if (VERIFICATION_VALUES.includes(value)) {
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return "unknown";
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Locate the YAML source file for a given adapter command. Returns
|
|
69
|
+
* `undefined` when no file is found — the caller surfaces this as
|
|
70
|
+
* "unknown" verification.
|
|
71
|
+
*/
|
|
72
|
+
export function resolveAdapterSourcePath(adapterName, commandName) {
|
|
73
|
+
const { yamlDir, tsDir } = getBuiltinDirs();
|
|
74
|
+
const candidates = [
|
|
75
|
+
join(yamlDir, adapterName, `${commandName}.yaml`),
|
|
76
|
+
join(yamlDir, adapterName, `${commandName}.yml`),
|
|
77
|
+
join(tsDir, adapterName, `${commandName}.ts`),
|
|
78
|
+
join(tsDir, adapterName, `${commandName}.js`),
|
|
79
|
+
join(tsDir, `${adapterName}.ts`),
|
|
80
|
+
join(tsDir, `${adapterName}.js`),
|
|
81
|
+
];
|
|
82
|
+
return candidates.find((p) => existsSync(p));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Locate any source file for an adapter (any command). Used when the adapter
|
|
86
|
+
* exposes multiple commands and the doctor only needs a single verification
|
|
87
|
+
* declaration — adapter authors typically copy the same `@verification` line
|
|
88
|
+
* across every YAML in a directory. We pick the first that resolves.
|
|
89
|
+
*/
|
|
90
|
+
export function findAdapterSourceFile(adapterName, commandNames) {
|
|
91
|
+
for (const cmd of commandNames) {
|
|
92
|
+
const path = resolveAdapterSourcePath(adapterName, cmd);
|
|
93
|
+
if (path)
|
|
94
|
+
return path;
|
|
95
|
+
}
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolve an adapter's verification status by reading any of its source
|
|
100
|
+
* files. Returns "unknown" when no source file carries a verification
|
|
101
|
+
* header — never invents a state.
|
|
102
|
+
*/
|
|
103
|
+
export function resolveAdapterVerificationStatus(adapterName, commandNames) {
|
|
104
|
+
const source = findAdapterSourceFile(adapterName, commandNames);
|
|
105
|
+
if (!source)
|
|
106
|
+
return "unknown";
|
|
107
|
+
return parseVerificationStatusFromFile(source);
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=patent-doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patent-doctor.js","sourceRoot":"","sources":["../../src/commands/patent-doctor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @owner src::commands::patent
|
|
3
|
+
* @does Top-level `unicli patent` meta-command — fans out search / get / family / citations / legal-status / prior-art / doctor across every registered patent adapter (discovered via the `patent.*` capability convention), normalises into PatentRecord, dedupes by family, and emits the standard agent envelope.
|
|
4
|
+
* @needs src/registry.ts, src/types/patent.ts, src/engine/normalizer/patent-envelope.ts, src/engine/kernel/execute.ts, src/output/formatter.ts
|
|
5
|
+
* @feeds src/cli.ts (registerPatentCommand wiring)
|
|
6
|
+
* @breaks emits PATENT_INVALID_NUMBER envelope on unknown publication-number prefix; PATENT_NOT_FOUND when every fan-out source returns empty; never falls back to a non-patent adapter (rule 02)
|
|
7
|
+
* @invariants --sources default = uspto,epo,jpo; --sources all = every registered adapter whose `capabilities[]` carries any `patent.*` tag; routing by publication-number prefix uses an explicit jurisdiction → adapter table — no fuzzy matching
|
|
8
|
+
* @side-effects spawns adapter pipelines via engine kernel; reads env for adapter-specific API keys; writes to stdout/stderr only
|
|
9
|
+
* @perf O(N · M) where N = sources, M = result rows per source — fan-out is sequential today; can move to parallel once the engine kernel proves reentrant under load
|
|
10
|
+
* @concurrency safe — Commander handlers run one at a time per process
|
|
11
|
+
* @test tests/unit/commands/patent.test.ts
|
|
12
|
+
* @stability experimental — wave-1 surface; field names locked, behaviour evolves with adapters
|
|
13
|
+
* @since 2026-05-18
|
|
14
|
+
*
|
|
15
|
+
* Capability convention introduced here:
|
|
16
|
+
*
|
|
17
|
+
* patent.search — adapter exposes a free-text + filter search
|
|
18
|
+
* patent.get — adapter retrieves one record by publication-number
|
|
19
|
+
* patent.family — adapter returns DOCDB / INPADOC family members
|
|
20
|
+
* patent.citations — adapter returns citing / cited records
|
|
21
|
+
* patent.legal-status — adapter resolves prosecution / grant status
|
|
22
|
+
* patent.fulltext — adapter delivers description + claims text
|
|
23
|
+
* patent.prior-art — adapter performs semantic prior-art retrieval
|
|
24
|
+
*
|
|
25
|
+
* Each patent-vertical YAML adapter must include the relevant tags in its
|
|
26
|
+
* `capabilities:` array so this meta-command discovers it without
|
|
27
|
+
* hard-coding a site list.
|
|
28
|
+
*/
|
|
29
|
+
import type { Command } from "commander";
|
|
30
|
+
import { type AgentContext } from "../output/envelope.js";
|
|
31
|
+
import type { AdapterCommand, AdapterManifest } from "../types.js";
|
|
32
|
+
import type { PatentRecord } from "../types/patent.js";
|
|
33
|
+
declare const JURISDICTION_ADAPTERS: Record<string, string>;
|
|
34
|
+
declare const FAMILY_BROKER = "epo";
|
|
35
|
+
declare const DEFAULT_SOURCES: readonly ["uspto", "epo", "jpo"];
|
|
36
|
+
export declare const PATENT_CAPABILITIES: readonly ["patent.search", "patent.get", "patent.family", "patent.citations", "patent.legal-status", "patent.fulltext", "patent.prior-art"];
|
|
37
|
+
export type PatentCapability = (typeof PATENT_CAPABILITIES)[number];
|
|
38
|
+
/**
|
|
39
|
+
* Find every registered adapter whose command set carries any patent.* tag.
|
|
40
|
+
* Returns a stable alphabetical ordering so output is deterministic.
|
|
41
|
+
*/
|
|
42
|
+
export declare function listPatentAdapters(): AdapterManifest[];
|
|
43
|
+
/**
|
|
44
|
+
* Filter the list of adapter names by a `--sources` string. `all` expands to
|
|
45
|
+
* every patent-capable adapter discovered in the registry.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveSources(sourcesArg: string | undefined, fallback?: readonly string[]): string[];
|
|
48
|
+
/**
|
|
49
|
+
* Map a publication number to the adapter that should serve `get`/`family`
|
|
50
|
+
* for it. Returns `undefined` when the prefix is not recognised — callers
|
|
51
|
+
* surface PATENT_INVALID_NUMBER in that case.
|
|
52
|
+
*/
|
|
53
|
+
export declare function routeByPublicationPrefix(publicationNumber: string): string | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Find the first command on `adapter` that carries the requested patent.*
|
|
56
|
+
* capability tag. Adapters may name their command anything; the capability
|
|
57
|
+
* tag is what wires them up.
|
|
58
|
+
*/
|
|
59
|
+
export declare function findCommandByCapability(adapter: AdapterManifest, capability: PatentCapability): {
|
|
60
|
+
name: string;
|
|
61
|
+
command: AdapterCommand;
|
|
62
|
+
} | undefined;
|
|
63
|
+
/**
|
|
64
|
+
* Reciprocal-rank fusion across ranked result lists. The scoring follows
|
|
65
|
+
* Cormack/Clarke/Buettcher 2009 (`score = Σ 1 / (k + rank)` with k = 60).
|
|
66
|
+
* Records are keyed by `family_id` when present, falling back to
|
|
67
|
+
* canonical publication_number — that is the dedupe axis required by the
|
|
68
|
+
* patent vertical (different offices issue separate publication numbers
|
|
69
|
+
* for the same invention).
|
|
70
|
+
*/
|
|
71
|
+
export declare function reciprocalRankFusion(rankedLists: PatentRecord[][], options?: {
|
|
72
|
+
k?: number;
|
|
73
|
+
topN?: number;
|
|
74
|
+
}): PatentRecord[];
|
|
75
|
+
export declare function registerPatentCommand(program: Command): void;
|
|
76
|
+
export { JURISDICTION_ADAPTERS, FAMILY_BROKER, DEFAULT_SOURCES };
|
|
77
|
+
export type { AgentContext };
|
|
78
|
+
//# sourceMappingURL=patent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"patent.d.ts","sourceRoot":"","sources":["../../src/commands/patent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQzC,OAAO,EAAW,KAAK,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAEhB,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAavD,QAAA,MAAM,qBAAqB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAcjD,CAAC;AAEF,QAAA,MAAM,aAAa,QAAQ,CAAC;AAC5B,QAAA,MAAM,eAAe,kCAAmC,CAAC;AAGzD,eAAO,MAAM,mBAAmB,6IAQtB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAC;AAYpE;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,EAAE,CAItD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,QAAQ,GAAE,SAAS,MAAM,EAAoB,GAC5C,MAAM,EAAE,CAWV;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,iBAAiB,EAAE,MAAM,GACxB,MAAM,GAAG,SAAS,CAIpB;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,eAAe,EACxB,UAAU,EAAE,gBAAgB,GAC3B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,GAAG,SAAS,CAMvD;AAID;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,YAAY,EAAE,EAAE,EAC7B,OAAO,GAAE;IAAE,CAAC,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC1C,YAAY,EAAE,CAyBhB;AA60BD,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwG5D;AAID,OAAO,EAAE,qBAAqB,EAAE,aAAa,EAAE,eAAe,EAAE,CAAC;AACjE,YAAY,EAAE,YAAY,EAAE,CAAC"}
|