Compare commits
4
Commits
7b67897612
...
8e7070cbaf
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e7070cbaf | ||
|
|
a8d7db562d | ||
|
|
e220f46d35 | ||
|
|
93460ece19 |
No files matched your search
@@ -1,11 +1,11 @@
|
|||||||
# Graph Report - 2e709500-79ab-403f-9ca0-3f027ac9f36e (2026-06-19)
|
# Graph Report - 2e709500-79ab-403f-9ca0-3f027ac9f36e (2026-06-24)
|
||||||
|
|
||||||
## Corpus Check
|
## Corpus Check
|
||||||
- 61 files · ~611,807 words
|
- 64 files · ~615,668 words
|
||||||
- Verdict: corpus is large enough that graph structure adds value.
|
- Verdict: corpus is large enough that graph structure adds value.
|
||||||
|
|
||||||
## Summary
|
## Summary
|
||||||
- 596 nodes · 620 edges · 114 communities (87 shown, 27 thin omitted)
|
- 619 nodes · 640 edges · 117 communities (90 shown, 27 thin omitted)
|
||||||
- Extraction: 99% EXTRACTED · 1% INFERRED · 0% AMBIGUOUS · INFERRED: 4 edges (avg confidence: 0.8)
|
- Extraction: 99% EXTRACTED · 1% INFERRED · 0% AMBIGUOUS · INFERRED: 4 edges (avg confidence: 0.8)
|
||||||
- Token cost: 0 input · 0 output
|
- Token cost: 0 input · 0 output
|
||||||
|
|
||||||
@@ -50,9 +50,8 @@
|
|||||||
- [[_COMMUNITY_Community 34|Community 34]]
|
- [[_COMMUNITY_Community 34|Community 34]]
|
||||||
- [[_COMMUNITY_Community 35|Community 35]]
|
- [[_COMMUNITY_Community 35|Community 35]]
|
||||||
- [[_COMMUNITY_Community 36|Community 36]]
|
- [[_COMMUNITY_Community 36|Community 36]]
|
||||||
- [[_COMMUNITY_Community 41|Community 41]]
|
- [[_COMMUNITY_Community 37|Community 37]]
|
||||||
- [[_COMMUNITY_Community 42|Community 42]]
|
- [[_COMMUNITY_Community 38|Community 38]]
|
||||||
- [[_COMMUNITY_Community 43|Community 43]]
|
|
||||||
- [[_COMMUNITY_Community 44|Community 44]]
|
- [[_COMMUNITY_Community 44|Community 44]]
|
||||||
- [[_COMMUNITY_Community 45|Community 45]]
|
- [[_COMMUNITY_Community 45|Community 45]]
|
||||||
- [[_COMMUNITY_Community 46|Community 46]]
|
- [[_COMMUNITY_Community 46|Community 46]]
|
||||||
@@ -71,6 +70,9 @@
|
|||||||
- [[_COMMUNITY_Community 59|Community 59]]
|
- [[_COMMUNITY_Community 59|Community 59]]
|
||||||
- [[_COMMUNITY_Community 60|Community 60]]
|
- [[_COMMUNITY_Community 60|Community 60]]
|
||||||
- [[_COMMUNITY_Community 61|Community 61]]
|
- [[_COMMUNITY_Community 61|Community 61]]
|
||||||
|
- [[_COMMUNITY_Community 62|Community 62]]
|
||||||
|
- [[_COMMUNITY_Community 63|Community 63]]
|
||||||
|
- [[_COMMUNITY_Community 64|Community 64]]
|
||||||
|
|
||||||
## God Nodes (most connected - your core abstractions)
|
## God Nodes (most connected - your core abstractions)
|
||||||
1. `Performance Testing Scripts` - 12 edges
|
1. `Performance Testing Scripts` - 12 edges
|
||||||
@@ -94,7 +96,7 @@
|
|||||||
- `POST()` --calls--> `logApiRequest()` [INFERRED]
|
- `POST()` --calls--> `logApiRequest()` [INFERRED]
|
||||||
src/pages/api/newsletter.ts → src/utils/logger.ts
|
src/pages/api/newsletter.ts → src/utils/logger.ts
|
||||||
|
|
||||||
## Communities (114 total, 27 thin omitted)
|
## Communities (117 total, 27 thin omitted)
|
||||||
|
|
||||||
### Community 0 - "Community 0"
|
### Community 0 - "Community 0"
|
||||||
Cohesion: 0.05
|
Cohesion: 0.05
|
||||||
@@ -144,49 +146,49 @@ Nodes (11): Code Example, code:astro (---), code:javascript (// Traditional SPA:
|
|||||||
Cohesion: 0.18
|
Cohesion: 0.18
|
||||||
Nodes (10): code:hcl (# Define AWS EC2 instance), code:dockerfile (# Multi-stage build for a Go application), code:yaml (# AWS Cost allocation tags), Common Pitfalls, Conclusion, Containerization as a Migration Strategy, Cost Optimization Strategies, Infrastructure as Code (+2 more)
|
Nodes (10): code:hcl (# Define AWS EC2 instance), code:dockerfile (# Multi-stage build for a Go application), code:yaml (# AWS Cost allocation tags), Common Pitfalls, Conclusion, Containerization as a Migration Strategy, Cost Optimization Strategies, Infrastructure as Code (+2 more)
|
||||||
|
|
||||||
### Community 18 - "Community 18"
|
### Community 16 - "Community 16"
|
||||||
Cohesion: 0.43
|
Cohesion: 0.2
|
||||||
Nodes (6): trackCaseStudyView(), trackEvent(), trackExternalLink(), trackFormSubmit(), trackNewsletterSignup(), trackPortfolioFilter()
|
Nodes (9): Catalogue Listing vs Bidding: How You Actually Win, Common Reasons Software Vendors Get Rejected or Delayed, Document Checklist, Fees, Caution Money, and Timelines, Frequently Asked Questions, MSME and Startup Benefits Worth Claiming, Step-by-Step Registration Process, Turning GeM Access Into Government Contracts (+1 more)
|
||||||
|
|
||||||
### Community 19 - "Community 19"
|
### Community 18 - "Community 18"
|
||||||
Cohesion: 0.36
|
Cohesion: 0.22
|
||||||
Nodes (7): extract_scores(), get_issues(), main(), Run Lighthouse audit on a URL, Extract key scores from Lighthouse data, Extract issues from Lighthouse audit, run_lighthouse()
|
Nodes (8): 2026 Cost Ranges by Project Tier, A Simple Way to Estimate Your Own Cost, Build vs Buy: When Custom Actually Pays Off, Frequently Asked Questions, Getting an Accurate Number for Your Project, Hidden Costs Buyers Forget to Budget, The Biggest Cost Driver: The Team, What "Custom ERP" Actually Means for Pricing
|
||||||
|
|
||||||
### Community 20 - "Community 20"
|
### Community 20 - "Community 20"
|
||||||
Cohesion: 0.46
|
Cohesion: 0.43
|
||||||
Nodes (7): captureScreenshot(), ensureDir(), generateIndex(), main(), screenshotPath(), setTheme(), waitForPageReady()
|
Nodes (6): trackCaseStudyView(), trackEvent(), trackExternalLink(), trackFormSubmit(), trackNewsletterSignup(), trackPortfolioFilter()
|
||||||
|
|
||||||
### Community 21 - "Community 21"
|
### Community 21 - "Community 21"
|
||||||
Cohesion: 0.36
|
Cohesion: 0.36
|
||||||
Nodes (4): deleteFromDB(), getAllFromDB(), openDB(), processSyncQueue()
|
|
||||||
|
|
||||||
### Community 22 - "Community 22"
|
|
||||||
Cohesion: 0.43
|
|
||||||
Nodes (6): trackCaseStudyView(), trackEvent(), trackExternalLink(), trackFormSubmit(), trackNewsletterSignup(), trackPortfolioFilter()
|
|
||||||
|
|
||||||
### Community 23 - "Community 23"
|
|
||||||
Cohesion: 0.46
|
|
||||||
Nodes (7): checkRateLimit(), corsHeaders(), escapeHtml(), OPTIONS(), POST(), sendContactEmail(), validateContactForm()
|
|
||||||
|
|
||||||
### Community 24 - "Community 24"
|
|
||||||
Cohesion: 0.36
|
|
||||||
Nodes (7): extract_scores(), get_issues(), main(), Run Lighthouse audit on a URL, Extract key scores from Lighthouse data, Extract issues from Lighthouse audit, run_lighthouse()
|
Nodes (7): extract_scores(), get_issues(), main(), Run Lighthouse audit on a URL, Extract key scores from Lighthouse data, Extract issues from Lighthouse audit, run_lighthouse()
|
||||||
|
|
||||||
### Community 25 - "Community 25"
|
### Community 22 - "Community 22"
|
||||||
Cohesion: 0.46
|
Cohesion: 0.46
|
||||||
Nodes (7): captureScreenshot(), ensureDir(), generateIndex(), main(), screenshotPath(), setTheme(), waitForPageReady()
|
Nodes (7): captureScreenshot(), ensureDir(), generateIndex(), main(), screenshotPath(), setTheme(), waitForPageReady()
|
||||||
|
|
||||||
### Community 26 - "Community 26"
|
### Community 23 - "Community 23"
|
||||||
Cohesion: 0.36
|
Cohesion: 0.36
|
||||||
Nodes (4): deleteFromDB(), getAllFromDB(), openDB(), processSyncQueue()
|
Nodes (4): deleteFromDB(), getAllFromDB(), openDB(), processSyncQueue()
|
||||||
|
|
||||||
|
### Community 24 - "Community 24"
|
||||||
|
Cohesion: 0.46
|
||||||
|
Nodes (7): checkRateLimit(), corsHeaders(), escapeHtml(), OPTIONS(), POST(), sendContactEmail(), validateContactForm()
|
||||||
|
|
||||||
|
### Community 25 - "Community 25"
|
||||||
|
Cohesion: 0.43
|
||||||
|
Nodes (6): trackCaseStudyView(), trackEvent(), trackExternalLink(), trackFormSubmit(), trackNewsletterSignup(), trackPortfolioFilter()
|
||||||
|
|
||||||
|
### Community 26 - "Community 26"
|
||||||
|
Cohesion: 0.36
|
||||||
|
Nodes (7): extract_scores(), get_issues(), main(), Run Lighthouse audit on a URL, Extract key scores from Lighthouse data, Extract issues from Lighthouse audit, run_lighthouse()
|
||||||
|
|
||||||
### Community 27 - "Community 27"
|
### Community 27 - "Community 27"
|
||||||
Cohesion: 0.48
|
Cohesion: 0.46
|
||||||
Nodes (5): initAllAnimations(), initButtonRipple(), initCounters(), initProgressBars(), initScrollReveal()
|
Nodes (7): captureScreenshot(), ensureDir(), generateIndex(), main(), screenshotPath(), setTheme(), waitForPageReady()
|
||||||
|
|
||||||
### Community 28 - "Community 28"
|
### Community 28 - "Community 28"
|
||||||
Cohesion: 0.48
|
Cohesion: 0.36
|
||||||
Nodes (5): extractJsonLd(), main(), validateOpenGraph(), validatePage(), validateTwitterCard()
|
Nodes (4): deleteFromDB(), getAllFromDB(), openDB(), processSyncQueue()
|
||||||
|
|
||||||
### Community 29 - "Community 29"
|
### Community 29 - "Community 29"
|
||||||
Cohesion: 0.48
|
Cohesion: 0.48
|
||||||
@@ -197,23 +199,31 @@ Cohesion: 0.48
|
|||||||
Nodes (5): extractJsonLd(), main(), validateOpenGraph(), validatePage(), validateTwitterCard()
|
Nodes (5): extractJsonLd(), main(), validateOpenGraph(), validatePage(), validateTwitterCard()
|
||||||
|
|
||||||
### Community 31 - "Community 31"
|
### Community 31 - "Community 31"
|
||||||
Cohesion: 0.47
|
Cohesion: 0.48
|
||||||
Nodes (5): main(), measure_response_time(), print_stats(), Measure response time for a URL over multiple iterations, Print statistics for response times
|
Nodes (5): initAllAnimations(), initButtonRipple(), initCounters(), initProgressBars(), initScrollReveal()
|
||||||
|
|
||||||
|
### Community 32 - "Community 32"
|
||||||
|
Cohesion: 0.48
|
||||||
|
Nodes (5): extractJsonLd(), main(), validateOpenGraph(), validatePage(), validateTwitterCard()
|
||||||
|
|
||||||
### Community 33 - "Community 33"
|
### Community 33 - "Community 33"
|
||||||
Cohesion: 0.47
|
Cohesion: 0.47
|
||||||
Nodes (5): main(), measure_response_time(), print_stats(), Measure response time for a URL over multiple iterations, Print statistics for response times
|
Nodes (5): main(), measure_response_time(), print_stats(), Measure response time for a URL over multiple iterations, Print statistics for response times
|
||||||
|
|
||||||
### Community 35 - "Community 35"
|
### Community 35 - "Community 35"
|
||||||
|
Cohesion: 0.47
|
||||||
|
Nodes (5): main(), measure_response_time(), print_stats(), Measure response time for a URL over multiple iterations, Print statistics for response times
|
||||||
|
|
||||||
|
### Community 37 - "Community 37"
|
||||||
Cohesion: 0.6
|
Cohesion: 0.6
|
||||||
Nodes (3): formatUptime(), GET(), percentile()
|
Nodes (3): formatUptime(), GET(), percentile()
|
||||||
|
|
||||||
### Community 36 - "Community 36"
|
### Community 38 - "Community 38"
|
||||||
Cohesion: 0.6
|
Cohesion: 0.6
|
||||||
Nodes (3): formatUptime(), GET(), percentile()
|
Nodes (3): formatUptime(), GET(), percentile()
|
||||||
|
|
||||||
## Knowledge Gaps
|
## Knowledge Gaps
|
||||||
- **140 isolated node(s):** `Run Lighthouse audit on a URL`, `Extract key scores from Lighthouse data`, `Extract issues from Lighthouse audit`, `Measure response time for a URL over multiple iterations`, `Print statistics for response times` (+135 more)
|
- **156 isolated node(s):** `Run Lighthouse audit on a URL`, `Extract key scores from Lighthouse data`, `Extract issues from Lighthouse audit`, `Measure response time for a URL over multiple iterations`, `Print statistics for response times` (+151 more)
|
||||||
These have ≤1 connection - possible missing edges or undocumented components.
|
These have ≤1 connection - possible missing edges or undocumented components.
|
||||||
- **27 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
- **27 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes.
|
||||||
|
|
||||||
@@ -223,7 +233,7 @@ _Questions this graph is uniquely positioned to answer:_
|
|||||||
- **Are the 2 inferred relationships involving `captureException()` (e.g. with `sendContactEmail()` and `subscribeToNewsletter()`) actually correct?**
|
- **Are the 2 inferred relationships involving `captureException()` (e.g. with `sendContactEmail()` and `subscribeToNewsletter()`) actually correct?**
|
||||||
_`captureException()` has 2 INFERRED edges - model-reasoned connections that need verification._
|
_`captureException()` has 2 INFERRED edges - model-reasoned connections that need verification._
|
||||||
- **What connects `Run Lighthouse audit on a URL`, `Extract key scores from Lighthouse data`, `Extract issues from Lighthouse audit` to the rest of the system?**
|
- **What connects `Run Lighthouse audit on a URL`, `Extract key scores from Lighthouse data`, `Extract issues from Lighthouse audit` to the rest of the system?**
|
||||||
_140 weakly-connected nodes found - possible documentation gaps or missing edges._
|
_156 weakly-connected nodes found - possible documentation gaps or missing edges._
|
||||||
- **Should `Community 0` be split into smaller, more focused modules?**
|
- **Should `Community 0` be split into smaller, more focused modules?**
|
||||||
_Cohesion score 0.05 - nodes in this community are weakly interconnected._
|
_Cohesion score 0.05 - nodes in this community are weakly interconnected._
|
||||||
- **Should `Community 1` be split into smaller, more focused modules?**
|
- **Should `Community 1` be split into smaller, more focused modules?**
|
||||||
|
|||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{"nodes": [{"id": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_utils_seo_ts", "label": "seo.ts", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L1"}, {"id": "utils_seo_generatepagetitle", "label": "generatePageTitle()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L21"}, {"id": "utils_seo_generatekeywords", "label": "generateKeywords()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L31"}, {"id": "utils_seo_generatebreadcrumbschema", "label": "generateBreadcrumbSchema()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L47"}, {"id": "utils_seo_generatearticleschema", "label": "generateArticleSchema()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L63"}, {"id": "utils_seo_generatefaqschema", "label": "generateFAQSchema()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L104"}, {"id": "utils_seo_generateserviceschema", "label": "generateServiceSchema()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L122"}, {"id": "utils_seo_generatecanonicalurl", "label": "generateCanonicalUrl()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L164"}, {"id": "utils_seo_truncatedescription", "label": "truncateDescription()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L173"}, {"id": "utils_seo_generateogimageurl", "label": "generateOGImageUrl()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L188"}, {"id": "utils_seo_shouldindexpage", "label": "shouldIndexPage()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L198"}, {"id": "utils_seo_generateshareurls", "label": "generateShareUrls()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L213"}], "edges": [{"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_utils_seo_ts", "target": "utils_seo_generatepagetitle", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L21", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_utils_seo_ts", "target": "utils_seo_generatekeywords", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L31", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_utils_seo_ts", "target": "utils_seo_generatebreadcrumbschema", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L47", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_utils_seo_ts", "target": "utils_seo_generatearticleschema", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L63", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_utils_seo_ts", "target": "utils_seo_generatefaqschema", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L104", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_utils_seo_ts", "target": "utils_seo_generateserviceschema", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/utils/seo.ts", "source_location": "L122", "weight": 1.0}, {"source": "hoLine truncated
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{"nodes": [{"id": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_content_blog_gem_empanelment_process_software_vendors_md", "label": "gem-empanelment-process-software-vendors.md", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-vendors.md", "source_location": "L1"}, {"id": "blog_gem_empanelment_process_software_vendors_who_should_register_product_vendor_vs_service_provider", "label": "Who Should Register: Product Vendor vs Service Provider", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-vendors.md", "source_location": "L20"}, {"id": "blog_gem_empanelment_process_software_vendors_step_by_step_registration_process", "label": "Step-by-Step Registration Process", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-vendors.md", "source_location": "L32"}, {"id": "blog_gem_empanelment_process_software_vendors_document_checklist", "label": "Document Checklist", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-vendors.md", "source_location": "L44"}, {"id": "blog_gem_empanelment_process_software_vendors_fees_caution_money_and_timelines", "label": "Fees, Caution Money, and Timelines", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-vendors.md", "source_location": "L57"}, {"id": "blog_gem_empanelment_process_software_vendors_catalogue_listing_vs_bidding_how_you_actually_win", "label": "Catalogue Listing vs Bidding: How You Actually Win", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-vendors.md", "source_location": "L70"}, {"id": "blog_gem_empanelment_process_software_vendors_msme_and_startup_benefits_worth_claiming", "label": "MSME and Startup Benefits Worth Claiming", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-vendors.md", "source_location": "L82"}, {"id": "blog_gem_empanelment_process_software_vendors_common_reasons_software_vendors_get_rejected_or_delayed", "label": "Common Reasons Software Vendors Get Rejected or Delayed", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-vendors.md", "source_location": "L93"}, {"id": "blog_gem_empanelment_process_software_vendors_frequently_asked_questions", "label": "Frequently Asked Questions", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-vendors.md", "source_location": "L103"}, {"id": "blog_gem_empanelment_process_software_vendors_turning_gem_access_into_government_contracts", "label": "Turning GeM Access Into Government Contracts", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-vendors.md", "source_location": "L123"}], "edges": [{"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_content_blog_gem_empanelment_process_software_vendors_md", "target": "blog_gem_empanelment_process_software_vendors_who_should_register_product_vendor_vs_service_provider", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-vendors.md", "source_location": "L20", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_content_blog_gem_empanelment_process_software_vendors_md", "target": "blog_gem_empanelment_process_software_vendors_step_by_step_registration_process", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-vendors.md", "source_location": "L32", "weight": 1.0}, {"source": "blog_gem_empanelment_process_software_vendors_step_by_step_registration_process", "target": "blog_gem_empanelment_process_software_vendors_document_checklist", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/gem-empanelment-process-software-Line truncated
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{"nodes": [{"id": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_content_blog_how_much_custom_erp_cost_india_2026_md", "label": "how-much-custom-erp-cost-india-2026.md", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-cost-india-2026.md", "source_location": "L1"}, {"id": "blog_how_much_custom_erp_cost_india_2026_what_custom_erp_actually_means_for_pricing", "label": "What \"Custom ERP\" Actually Means for Pricing", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-cost-india-2026.md", "source_location": "L20"}, {"id": "blog_how_much_custom_erp_cost_india_2026_2026_cost_ranges_by_project_tier", "label": "2026 Cost Ranges by Project Tier", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-cost-india-2026.md", "source_location": "L32"}, {"id": "blog_how_much_custom_erp_cost_india_2026_the_biggest_cost_driver_the_team", "label": "The Biggest Cost Driver: The Team", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-cost-india-2026.md", "source_location": "L45"}, {"id": "blog_how_much_custom_erp_cost_india_2026_build_vs_buy_when_custom_actually_pays_off", "label": "Build vs Buy: When Custom Actually Pays Off", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-cost-india-2026.md", "source_location": "L59"}, {"id": "blog_how_much_custom_erp_cost_india_2026_hidden_costs_buyers_forget_to_budget", "label": "Hidden Costs Buyers Forget to Budget", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-cost-india-2026.md", "source_location": "L74"}, {"id": "blog_how_much_custom_erp_cost_india_2026_a_simple_way_to_estimate_your_own_cost", "label": "A Simple Way to Estimate Your Own Cost", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-cost-india-2026.md", "source_location": "L85"}, {"id": "blog_how_much_custom_erp_cost_india_2026_frequently_asked_questions", "label": "Frequently Asked Questions", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-cost-india-2026.md", "source_location": "L97"}, {"id": "blog_how_much_custom_erp_cost_india_2026_getting_an_accurate_number_for_your_project", "label": "Getting an Accurate Number for Your Project", "file_type": "document", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-cost-india-2026.md", "source_location": "L117"}], "edges": [{"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_content_blog_how_much_custom_erp_cost_india_2026_md", "target": "blog_how_much_custom_erp_cost_india_2026_what_custom_erp_actually_means_for_pricing", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-cost-india-2026.md", "source_location": "L20", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_content_blog_how_much_custom_erp_cost_india_2026_md", "target": "blog_how_much_custom_erp_cost_india_2026_2026_cost_ranges_by_project_tier", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-cost-india-2026.md", "source_location": "L32", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_content_blog_how_much_custom_erp_cost_india_2026_md", "target": "blog_how_much_custom_erp_cost_india_2026_the_biggest_cost_driver_the_team", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-cost-india-2026.md", "source_location": "L45", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_content_blog_how_much_custom_erp_cost_india_2026_md", "target": "blog_how_much_custom_erp_cost_india_2026_build_vs_buy_when_custom_actually_pays_off", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/content/blog/how-much-custom-erp-coLine truncated
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{"nodes": [{"id": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_public_wrnexus_push_sw_js", "label": "wrnexus-push-sw.js", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L1"}, {"id": "public_wrnexus_push_sw_postreceipt", "label": "postReceipt()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L47"}, {"id": "public_wrnexus_push_sw_urlbase64touint8array", "label": "urlBase64ToUint8Array()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L58"}, {"id": "public_wrnexus_push_sw_keytob64", "label": "keyToB64()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L67"}], "edges": [{"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_public_wrnexus_push_sw_js", "target": "public_wrnexus_push_sw_postreceipt", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L47", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_public_wrnexus_push_sw_js", "target": "public_wrnexus_push_sw_urlbase64touint8array", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L58", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_public_wrnexus_push_sw_js", "target": "public_wrnexus_push_sw_keytob64", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L67", "weight": 1.0}], "raw_calls": [{"caller_nid": "public_wrnexus_push_sw_postreceipt", "callee": "resolve", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L48"}, {"caller_nid": "public_wrnexus_push_sw_postreceipt", "callee": "catch", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L49"}, {"caller_nid": "public_wrnexus_push_sw_postreceipt", "callee": "fetch", "is_member_call": false, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L49"}, {"caller_nid": "public_wrnexus_push_sw_urlbase64touint8array", "callee": "repeat", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L59"}, {"caller_nid": "public_wrnexus_push_sw_urlbase64touint8array", "callee": "replace", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L60"}, {"caller_nid": "public_wrnexus_push_sw_urlbase64touint8array", "callee": "replace", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L60"}, {"caller_nid": "public_wrnexus_push_sw_urlbase64touint8array", "callee": "atob", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L61"}, {"caller_nid": "public_wrnexus_push_sw_urlbase64touint8array", "callee": "charCodeAt", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L63"}, {"caller_nid": "public_wrnexus_push_sw_keytob64", "callee": "fromCharCode", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L71"}, {"caller_nid": "public_wrnexus_push_sw_keytob64", "callee": "replace", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L72"}, {"caller_nid": "public_wrnexus_push_sw_keytob64", "callee": "replace", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/public/wrnexus-push-sw.js", "source_location": "L72"}, {"caller_nid": "public_wrnexus_push_sw_keytob64", Line truncated
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{"nodes": [{"id": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_middleware_ts", "label": "middleware.ts", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L1"}, {"id": "src_middleware_validatecsrforigin", "label": "validateCsrfOrigin()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L19"}], "edges": [{"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_middleware_ts", "target": "astro_middleware", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L1", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_middleware_ts", "target": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_utils_logger_ts", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L2", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_middleware_ts", "target": "utils_logger_logger", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L2", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_middleware_ts", "target": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_utils_sentry_ts", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L3", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_middleware_ts", "target": "utils_sentry_captureexception", "relation": "imports", "context": "import", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L3", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_middleware_ts", "target": "src_middleware_validatecsrforigin", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L19", "weight": 1.0}], "raw_calls": [{"caller_nid": "src_middleware_validatecsrforigin", "callee": "includes", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L24"}, {"caller_nid": "src_middleware_validatecsrforigin", "callee": "startsWith", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L25"}, {"caller_nid": "src_middleware_validatecsrforigin", "callee": "get", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L36"}, {"caller_nid": "src_middleware_validatecsrforigin", "callee": "get", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L37"}, {"caller_nid": "src_middleware_validatecsrforigin", "callee": "startsWith", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L52"}, {"caller_nid": "src_middleware_validatecsrforigin", "callee": "startsWith", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/middleware.ts", "source_location": "L52"}]}
|
||||||
Vendored
+1
@@ -0,0 +1 @@
|
|||||||
|
{"nodes": [{"id": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_pages_sitemap_xml_ts", "label": "sitemap.xml.ts", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/pages/sitemap.xml.ts", "source_location": "L1"}, {"id": "pages_sitemap_xml_get", "label": "GET()", "file_type": "code", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/pages/sitemap.xml.ts", "source_location": "L13"}], "edges": [{"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_pages_sitemap_xml_ts", "target": "astro", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/pages/sitemap.xml.ts", "source_location": "L1", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_pages_sitemap_xml_ts", "target": "astro_content", "relation": "imports_from", "context": "import", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/pages/sitemap.xml.ts", "source_location": "L2", "weight": 1.0}, {"source": "home_agent_ai_agent_backend_workspace_2e709500_79ab_403f_9ca0_3f027ac9f36e_src_pages_sitemap_xml_ts", "target": "pages_sitemap_xml_get", "relation": "contains", "confidence": "EXTRACTED", "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/pages/sitemap.xml.ts", "source_location": "L13", "weight": 1.0}], "raw_calls": [{"caller_nid": "pages_sitemap_xml_get", "callee": "getCollection", "is_member_call": false, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/pages/sitemap.xml.ts", "source_location": "L15"}, {"caller_nid": "pages_sitemap_xml_get", "callee": "getCollection", "is_member_call": false, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/pages/sitemap.xml.ts", "source_location": "L20"}, {"caller_nid": "pages_sitemap_xml_get", "callee": "map", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/pages/sitemap.xml.ts", "source_location": "L43"}, {"caller_nid": "pages_sitemap_xml_get", "callee": "map", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/pages/sitemap.xml.ts", "source_location": "L52"}, {"caller_nid": "pages_sitemap_xml_get", "callee": "join", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/pages/sitemap.xml.ts", "source_location": "L69"}, {"caller_nid": "pages_sitemap_xml_get", "callee": "map", "is_member_call": true, "source_file": "/home/agent/ai-agent/backend/workspace/2e709500-79ab-403f-9ca0-3f027ac9f36e/src/pages/sitemap.xml.ts", "source_location": "L69"}]}
|
||||||
@@ -61,12 +61,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="legend"></div>
|
<div id="legend"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="stats">596 nodes · 620 edges · 114 communities</div>
|
<div id="stats">619 nodes · 640 edges · 117 communities</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
const RAW_NODES = [{"id": "astro_config_mjs", "label": "astro.config.mjs", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 12.3, "font": {"size": 0, "color": "#ffffff"}, "title": "astro.config.mjs", "community": 62, "community_name": "Community 62", "source_file": "astro.config.mjs", "file_type": "code", "degree": 1}, {"id": "playwright_config_ts", "label": "playwright.config.ts", "color": {"background": "#BAB0AC", "border": "#BAB0AC", "highlight": {"background": "#ffffff", "border": "#BAB0AC"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "playwright.config.ts", "community": 69, "community_name": "Community 69", "source_file": "playwright.config.ts", "file_type": "code", "degree": 0}, {"id": "tailwind_config_mjs", "label": "tailwind.config.mjs", "color": {"background": "#4E79A7", "border": "#4E79A7", "highlight": {"background": "#ffffff", "border": "#4E79A7"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "tailwind.config.mjs", "community": 70, "community_name": "Community 70", "source_file": "tailwind.config.mjs", "file_type": "code", "degree": 0}, {"id": "server_mjs", "label": "server.mjs", "color": {"background": "#F28E2B", "border": "#F28E2B", "highlight": {"background": "#ffffff", "border": "#F28E2B"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "server.mjs", "community": 71, "community_name": "Community 71", "source_file": "server.mjs", "file_type": "code", "degree": 0}, {"id": "src_env_d_ts", "label": "env.d.ts", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 72, "community_name": "Community 72", "source_file": "src/env.d.ts", "file_type": "code", "degree": 0}, {"id": "src_middleware_ts", "label": "middleware.ts", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 19.2, "font": {"size": 12, "color": "#ffffff"}, "title": "middleware.ts", "community": 2, "community_name": "Community 2", "source_file": "src/middleware.ts", "file_type": "code", "degree": 4}, {"id": "src_middleware_validatecsrforigin", "label": "validateCsrfOrigin()", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 12.3, "font": {"size": 0, "color": "#ffffff"}, "title": "validateCsrfOrigin()", "community": 2, "community_name": "Community 2", "source_file": "src/middleware.ts", "file_type": "code", "degree": 1}, {"id": "src_content_config_ts", "label": "config.ts", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "config.ts", "community": 73, "community_name": "Community 73", "source_file": "src/content/config.ts", "file_type": "code", "degree": 0}, {"id": "src_pages_sitemap_xml_ts", "label": "sitemap.xml.ts", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 12.3, "font": {"size": 0, "color": "#ffffff"}, "title": "sitemap.xml.ts", "community": 63, "community_name": "Community 63", "source_file": "src/pages/sitemap.xml.ts", "file_type": "code", "degree": 1}, {"id": "pages_sitemap_xml_get", "label": "GET()", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 12.3, "font": {"size": 0, "color": "#ffffff"}, "title": "GET()", "community": 63, "community_name": "Community 63", "source_file": "src/pages/sitemap.xml.ts", "file_type": "code", "degree": 1}, {"id": "src_pages_sitemap_index_xml_ts", "label": "sitemap-index.xml.ts", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 12.3, "font": {"size": 0, "color": "#ffffff"}, "title": "sitemap-index.xml.ts", "community": 64, "community_name": "Community 64", "source_file": "src/pages/sitemap-index.xml.ts", "file_type": "code", "degree": 1}, {"id": "pages_sitemap_index_xml_get", "label": "GET()", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 12.3, "font": {"size": 0, "color": "#ffffff"}, "title": "GET()", "community": 64, "community_name": "Community 64", "source_file": "src/pages/sitemap-index.xml.ts", "file_type": "code", "degree": 1}, {"id": "src_pages_api_contact_ts", "label": "contact.ts", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 40.0, "font": {"size": 12, "color": "#ffffff"}, "title": "contact.ts", "community": 2, "community_name": "Community 2", "source_file": "src/pages/api/contact.ts", "file_type": "code", "degree": 13}, {"id": "api_Line truncated
|
const RAW_NODES = [{"id": "astro_config_mjs", "label": "astro.config.mjs", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 12.3, "font": {"size": 0, "color": "#ffffff"}, "title": "astro.config.mjs", "community": 65, "community_name": "Community 65", "source_file": "astro.config.mjs", "file_type": "code", "degree": 1}, {"id": "playwright_config_ts", "label": "playwright.config.ts", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "playwright.config.ts", "community": 72, "community_name": "Community 72", "source_file": "playwright.config.ts", "file_type": "code", "degree": 0}, {"id": "tailwind_config_mjs", "label": "tailwind.config.mjs", "color": {"background": "#76B7B2", "border": "#76B7B2", "highlight": {"background": "#ffffff", "border": "#76B7B2"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "tailwind.config.mjs", "community": 73, "community_name": "Community 73", "source_file": "tailwind.config.mjs", "file_type": "code", "degree": 0}, {"id": "server_mjs", "label": "server.mjs", "color": {"background": "#59A14F", "border": "#59A14F", "highlight": {"background": "#ffffff", "border": "#59A14F"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "server.mjs", "community": 74, "community_name": "Community 74", "source_file": "server.mjs", "file_type": "code", "degree": 0}, {"id": "src_env_d_ts", "label": "env.d.ts", "color": {"background": "#EDC948", "border": "#EDC948", "highlight": {"background": "#ffffff", "border": "#EDC948"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "env.d.ts", "community": 75, "community_name": "Community 75", "source_file": "src/env.d.ts", "file_type": "code", "degree": 0}, {"id": "src_middleware_ts", "label": "middleware.ts", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 19.2, "font": {"size": 12, "color": "#ffffff"}, "title": "middleware.ts", "community": 2, "community_name": "Community 2", "source_file": "src/middleware.ts", "file_type": "code", "degree": 4}, {"id": "src_middleware_validatecsrforigin", "label": "validateCsrfOrigin()", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 12.3, "font": {"size": 0, "color": "#ffffff"}, "title": "validateCsrfOrigin()", "community": 2, "community_name": "Community 2", "source_file": "src/middleware.ts", "file_type": "code", "degree": 1}, {"id": "src_content_config_ts", "label": "config.ts", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 10.0, "font": {"size": 0, "color": "#ffffff"}, "title": "config.ts", "community": 76, "community_name": "Community 76", "source_file": "src/content/config.ts", "file_type": "code", "degree": 0}, {"id": "src_pages_sitemap_xml_ts", "label": "sitemap.xml.ts", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 12.3, "font": {"size": 0, "color": "#ffffff"}, "title": "sitemap.xml.ts", "community": 66, "community_name": "Community 66", "source_file": "src/pages/sitemap.xml.ts", "file_type": "code", "degree": 1}, {"id": "pages_sitemap_xml_get", "label": "GET()", "color": {"background": "#B07AA1", "border": "#B07AA1", "highlight": {"background": "#ffffff", "border": "#B07AA1"}}, "size": 12.3, "font": {"size": 0, "color": "#ffffff"}, "title": "GET()", "community": 66, "community_name": "Community 66", "source_file": "src/pages/sitemap.xml.ts", "file_type": "code", "degree": 1}, {"id": "src_pages_sitemap_index_xml_ts", "label": "sitemap-index.xml.ts", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 12.3, "font": {"size": 0, "color": "#ffffff"}, "title": "sitemap-index.xml.ts", "community": 67, "community_name": "Community 67", "source_file": "src/pages/sitemap-index.xml.ts", "file_type": "code", "degree": 1}, {"id": "pages_sitemap_index_xml_get", "label": "GET()", "color": {"background": "#FF9DA7", "border": "#FF9DA7", "highlight": {"background": "#ffffff", "border": "#FF9DA7"}}, "size": 12.3, "font": {"size": 0, "color": "#ffffff"}, "title": "GET()", "community": 67, "community_name": "Community 67", "source_file": "src/pages/sitemap-index.xml.ts", "file_type": "code", "degree": 1}, {"id": "src_pages_api_contact_ts", "label": "contact.ts", "color": {"background": "#E15759", "border": "#E15759", "highlight": {"background": "#ffffff", "border": "#E15759"}}, "size": 40.0, "font": {"size": 12, "color": "#ffffff"}, "title": "contact.ts", "community": 2, "community_name": "Community 2", "source_file": "src/pages/api/contact.ts", "file_type": "code", "degree": 13}, {"id": "api_Line truncated
|
||||||
const RAW_EDGES = [{"from": "astro_config_mjs", "to": "config", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_middleware_ts", "to": "src_utils_logger_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_middleware_ts", "to": "src_utils_sentry_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_middleware_ts", "to": "utils_sentry_captureexception", "label": "imports", "title": "imports [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_middleware_ts", "to": "src_middleware_validatecsrforigin", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_sitemap_xml_ts", "to": "pages_sitemap_xml_get", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_sitemap_index_xml_ts", "to": "pages_sitemap_index_xml_get", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "src_utils_logger_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "utils_logger_logapirequest", "label": "imports", "title": "imports [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "src_utils_sentry_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "utils_sentry_captureexception", "label": "imports", "title": "imports [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_checkratelimit", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_validatecontactform", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_readsmtpconfig", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_gettransporter", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_sendcontactemail", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_escapehtml", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_corsheaders", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_options", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_post", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "api_contact_post", "to": "api_contact_checkratelimit", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "api_contact_post", "to": "api_contact_validatecontactform", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "api_contact_sendcontactemail", "to": "api_contact_readsmtpconfig", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "api_contact_sendcontactemail", "to": "api_contact_gettransporter", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTELine truncated
|
const RAW_EDGES = [{"from": "astro_config_mjs", "to": "config", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_middleware_ts", "to": "src_utils_logger_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_middleware_ts", "to": "src_utils_sentry_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_middleware_ts", "to": "utils_sentry_captureexception", "label": "imports", "title": "imports [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_middleware_ts", "to": "src_middleware_validatecsrforigin", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_sitemap_xml_ts", "to": "pages_sitemap_xml_get", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_sitemap_index_xml_ts", "to": "pages_sitemap_index_xml_get", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "src_utils_logger_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "utils_logger_logapirequest", "label": "imports", "title": "imports [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "src_utils_sentry_ts", "label": "imports_from", "title": "imports_from [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "utils_sentry_captureexception", "label": "imports", "title": "imports [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_checkratelimit", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_validatecontactform", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_readsmtpconfig", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_gettransporter", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_sendcontactemail", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_escapehtml", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_corsheaders", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_options", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "src_pages_api_contact_ts", "to": "api_contact_post", "label": "contains", "title": "contains [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "api_contact_post", "to": "api_contact_checkratelimit", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "api_contact_post", "to": "api_contact_validatecontactform", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "api_contact_sendcontactemail", "to": "api_contact_readsmtpconfig", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTED"}, {"from": "api_contact_sendcontactemail", "to": "api_contact_gettransporter", "label": "calls", "title": "calls [EXTRACTED]", "dashes": false, "width": 2, "color": {"opacity": 0.7}, "confidence": "EXTRACTELine truncated
|
||||||
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 38}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 38}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 35}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 25}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 23}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 22}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 16}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 14}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 14}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 12}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 12}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 12}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 12}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 11}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 11}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 11}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 9}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 9}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 8}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 8}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 8}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 8}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 8}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 8}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 8}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 8}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 8}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 7}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 7}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 7}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 7}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 6}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 6}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 6}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 6}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 5}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 5}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 4}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 4}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 4}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 4}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 3}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 3}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 3}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 3}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 3}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 3}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 3}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 3}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 3}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 3}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 3}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 3}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 3}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 3}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 3}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 3}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 3}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 3}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 3}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 3}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 3}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 2}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 2}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 2}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 2}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 2}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 2}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 2}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 1}, {"cid": 70, "color": "#4E79A7", "label": "Community 70", "count": 1}, {"cid": 71, "coloLine truncated
|
const LEGEND = [{"cid": 0, "color": "#4E79A7", "label": "Community 0", "count": 38}, {"cid": 1, "color": "#F28E2B", "label": "Community 1", "count": 38}, {"cid": 2, "color": "#E15759", "label": "Community 2", "count": 35}, {"cid": 3, "color": "#76B7B2", "label": "Community 3", "count": 25}, {"cid": 4, "color": "#59A14F", "label": "Community 4", "count": 23}, {"cid": 5, "color": "#EDC948", "label": "Community 5", "count": 22}, {"cid": 6, "color": "#B07AA1", "label": "Community 6", "count": 16}, {"cid": 7, "color": "#FF9DA7", "label": "Community 7", "count": 14}, {"cid": 8, "color": "#9C755F", "label": "Community 8", "count": 14}, {"cid": 9, "color": "#BAB0AC", "label": "Community 9", "count": 12}, {"cid": 10, "color": "#4E79A7", "label": "Community 10", "count": 12}, {"cid": 11, "color": "#F28E2B", "label": "Community 11", "count": 12}, {"cid": 12, "color": "#E15759", "label": "Community 12", "count": 12}, {"cid": 13, "color": "#76B7B2", "label": "Community 13", "count": 11}, {"cid": 14, "color": "#59A14F", "label": "Community 14", "count": 11}, {"cid": 15, "color": "#EDC948", "label": "Community 15", "count": 11}, {"cid": 16, "color": "#B07AA1", "label": "Community 16", "count": 10}, {"cid": 17, "color": "#FF9DA7", "label": "Community 17", "count": 9}, {"cid": 18, "color": "#9C755F", "label": "Community 18", "count": 9}, {"cid": 19, "color": "#BAB0AC", "label": "Community 19", "count": 9}, {"cid": 20, "color": "#4E79A7", "label": "Community 20", "count": 8}, {"cid": 21, "color": "#F28E2B", "label": "Community 21", "count": 8}, {"cid": 22, "color": "#E15759", "label": "Community 22", "count": 8}, {"cid": 23, "color": "#76B7B2", "label": "Community 23", "count": 8}, {"cid": 24, "color": "#59A14F", "label": "Community 24", "count": 8}, {"cid": 25, "color": "#EDC948", "label": "Community 25", "count": 8}, {"cid": 26, "color": "#B07AA1", "label": "Community 26", "count": 8}, {"cid": 27, "color": "#FF9DA7", "label": "Community 27", "count": 8}, {"cid": 28, "color": "#9C755F", "label": "Community 28", "count": 8}, {"cid": 29, "color": "#BAB0AC", "label": "Community 29", "count": 7}, {"cid": 30, "color": "#4E79A7", "label": "Community 30", "count": 7}, {"cid": 31, "color": "#F28E2B", "label": "Community 31", "count": 7}, {"cid": 32, "color": "#E15759", "label": "Community 32", "count": 7}, {"cid": 33, "color": "#76B7B2", "label": "Community 33", "count": 6}, {"cid": 34, "color": "#59A14F", "label": "Community 34", "count": 6}, {"cid": 35, "color": "#EDC948", "label": "Community 35", "count": 6}, {"cid": 36, "color": "#B07AA1", "label": "Community 36", "count": 6}, {"cid": 37, "color": "#FF9DA7", "label": "Community 37", "count": 5}, {"cid": 38, "color": "#9C755F", "label": "Community 38", "count": 5}, {"cid": 39, "color": "#BAB0AC", "label": "Community 39", "count": 4}, {"cid": 40, "color": "#4E79A7", "label": "Community 40", "count": 4}, {"cid": 41, "color": "#F28E2B", "label": "Community 41", "count": 4}, {"cid": 42, "color": "#E15759", "label": "Community 42", "count": 4}, {"cid": 43, "color": "#76B7B2", "label": "Community 43", "count": 4}, {"cid": 44, "color": "#59A14F", "label": "Community 44", "count": 3}, {"cid": 45, "color": "#EDC948", "label": "Community 45", "count": 3}, {"cid": 46, "color": "#B07AA1", "label": "Community 46", "count": 3}, {"cid": 47, "color": "#FF9DA7", "label": "Community 47", "count": 3}, {"cid": 48, "color": "#9C755F", "label": "Community 48", "count": 3}, {"cid": 49, "color": "#BAB0AC", "label": "Community 49", "count": 3}, {"cid": 50, "color": "#4E79A7", "label": "Community 50", "count": 3}, {"cid": 51, "color": "#F28E2B", "label": "Community 51", "count": 3}, {"cid": 52, "color": "#E15759", "label": "Community 52", "count": 3}, {"cid": 53, "color": "#76B7B2", "label": "Community 53", "count": 3}, {"cid": 54, "color": "#59A14F", "label": "Community 54", "count": 3}, {"cid": 55, "color": "#EDC948", "label": "Community 55", "count": 3}, {"cid": 56, "color": "#B07AA1", "label": "Community 56", "count": 3}, {"cid": 57, "color": "#FF9DA7", "label": "Community 57", "count": 3}, {"cid": 58, "color": "#9C755F", "label": "Community 58", "count": 3}, {"cid": 59, "color": "#BAB0AC", "label": "Community 59", "count": 3}, {"cid": 60, "color": "#4E79A7", "label": "Community 60", "count": 3}, {"cid": 61, "color": "#F28E2B", "label": "Community 61", "count": 3}, {"cid": 62, "color": "#E15759", "label": "Community 62", "count": 3}, {"cid": 63, "color": "#76B7B2", "label": "Community 63", "count": 3}, {"cid": 64, "color": "#59A14F", "label": "Community 64", "count": 3}, {"cid": 65, "color": "#EDC948", "label": "Community 65", "count": 2}, {"cid": 66, "color": "#B07AA1", "label": "Community 66", "count": 2}, {"cid": 67, "color": "#FF9DA7", "label": "Community 67", "count": 2}, {"cid": 68, "color": "#9C755F", "label": "Community 68", "count": 2}, {"cid": 69, "color": "#BAB0AC", "label": "Community 69", "count": 2}, {"cid": 70, "color": "#4E79A7", "label": "Community 70", "count": 2}, {"cid": 71, "colLine truncated
|
||||||
|
|
||||||
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
|
// HTML-escape helper — prevents XSS when injecting graph data into innerHTML
|
||||||
function esc(s) {
|
function esc(s) {
|
||||||
|
|||||||
+697
-290
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,166 @@
|
|||||||
|
/*!
|
||||||
|
* WRNexus Web Push — service worker.
|
||||||
|
*
|
||||||
|
* ┌─────────────────────────────────────────────────────────────────────────┐
|
||||||
|
* │ HOST THIS FILE ON YOUR OWN ORIGIN. │
|
||||||
|
* │ │
|
||||||
|
* │ A service worker can only control the origin it is served from, so the │
|
||||||
|
* │ browser will NOT let wrnexus.com register a worker for your site. Copy │
|
||||||
|
* │ this file to the ROOT of your site and serve it at: │
|
||||||
|
* │ │
|
||||||
|
* │ https://your-domain.example/wrnexus-push-sw.js │
|
||||||
|
* │ │
|
||||||
|
* │ It must be served same-origin, over HTTPS, with │
|
||||||
|
* │ `Content-Type: text/javascript`. To control the whole site from a │
|
||||||
|
* │ non-root path, also send `Service-Worker-Allowed: /`. │
|
||||||
|
* └─────────────────────────────────────────────────────────────────────────┘
|
||||||
|
*
|
||||||
|
* Core behaviour needs NO configuration — the click/delivery tracking URLs are
|
||||||
|
* carried inside each push payload built by the WRNexus API. The optional
|
||||||
|
* CONFIG block below is only used to silently re-subscribe after the browser
|
||||||
|
* rotates a subscription (`pushsubscriptionchange`); leave it blank to skip
|
||||||
|
* that.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* eslint-disable no-restricted-globals */
|
||||||
|
|
||||||
|
// ── OPTIONAL: only needed for automatic re-subscription on key rotation ──────
|
||||||
|
var WRNEXUS_PUSH_CONFIG = {
|
||||||
|
// Your site's publicKey (the same value as data-site-id in the snippet).
|
||||||
|
siteKey: '',
|
||||||
|
// The WRNexus API origin (e.g. 'https://api.wrnexus.com').
|
||||||
|
apiBase: '',
|
||||||
|
// Your site's VAPID public key (shown in Push → Settings).
|
||||||
|
vapidPublicKey: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
self.addEventListener('install', function () {
|
||||||
|
self.skipWaiting();
|
||||||
|
});
|
||||||
|
|
||||||
|
self.addEventListener('activate', function (event) {
|
||||||
|
event.waitUntil(self.clients.claim());
|
||||||
|
});
|
||||||
|
|
||||||
|
// CORS-simple POST (text/plain, no custom headers, no credentials) so the
|
||||||
|
// receipt reaches the WRNexus API cross-origin without a preflight.
|
||||||
|
function postReceipt(url) {
|
||||||
|
if (!url) return Promise.resolve();
|
||||||
|
return fetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'text/plain;charset=UTF-8' },
|
||||||
|
credentials: 'omit',
|
||||||
|
keepalive: true,
|
||||||
|
mode: 'cors',
|
||||||
|
}).catch(function () {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function urlBase64ToUint8Array(base64String) {
|
||||||
|
var padding = '='.repeat((4 - (base64String.length % 4)) % 4);
|
||||||
|
var base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/');
|
||||||
|
var raw = self.atob(base64);
|
||||||
|
var out = new Uint8Array(raw.length);
|
||||||
|
for (var i = 0; i < raw.length; ++i) out[i] = raw.charCodeAt(i);
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
function keyToB64(buf) {
|
||||||
|
if (!buf) return '';
|
||||||
|
var bytes = new Uint8Array(buf);
|
||||||
|
var binary = '';
|
||||||
|
for (var i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
||||||
|
return self
|
||||||
|
.btoa(binary)
|
||||||
|
.replace(/\+/g, '-')
|
||||||
|
.replace(/\//g, '_')
|
||||||
|
.replace(/=+$/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Incoming notification ─────────────────────────────────────────────────
|
||||||
|
self.addEventListener('push', function (event) {
|
||||||
|
var data = {};
|
||||||
|
try {
|
||||||
|
data = event.data ? event.data.json() : {};
|
||||||
|
} catch (_e) {
|
||||||
|
try {
|
||||||
|
data = { title: event.data && event.data.text() };
|
||||||
|
} catch (_e2) {
|
||||||
|
data = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var title = data.title || 'Notification';
|
||||||
|
var options = {
|
||||||
|
body: data.body || '',
|
||||||
|
icon: data.icon || undefined,
|
||||||
|
image: data.image || undefined,
|
||||||
|
badge: data.badge || undefined,
|
||||||
|
tag: data.tag || data.campaignId || undefined,
|
||||||
|
requireInteraction: !!data.requireInteraction,
|
||||||
|
data: {
|
||||||
|
clickUrl: data.clickUrl || data.url || '/',
|
||||||
|
url: data.url || '/',
|
||||||
|
openUrl: data.openUrl || '',
|
||||||
|
campaignId: data.campaignId || '',
|
||||||
|
subscriptionId: data.subscriptionId || '',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
event.waitUntil(
|
||||||
|
Promise.all([
|
||||||
|
self.registration.showNotification(title, options),
|
||||||
|
// Delivery receipt — records a `delivered` event for analytics.
|
||||||
|
postReceipt(data.deliveredUrl),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── Click → record + open the destination ─────────────────────────────────
|
||||||
|
self.addEventListener('notificationclick', function (event) {
|
||||||
|
var d = (event.notification && event.notification.data) || {};
|
||||||
|
event.notification.close();
|
||||||
|
|
||||||
|
// `clickUrl` is a signed WRNexus redirect: hitting it records the `clicked`
|
||||||
|
// event and 302s to the real destination, so tracking fires from the open.
|
||||||
|
var target = d.clickUrl || d.url || '/';
|
||||||
|
|
||||||
|
event.waitUntil(
|
||||||
|
self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function (list) {
|
||||||
|
// Reuse an existing tab on the destination when possible.
|
||||||
|
for (var i = 0; i < list.length; i++) {
|
||||||
|
var client = list[i];
|
||||||
|
if (d.url && client.url === d.url && 'focus' in client) return client.focus();
|
||||||
|
}
|
||||||
|
if (self.clients.openWindow) return self.clients.openWindow(target);
|
||||||
|
return undefined;
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ── Optional: re-subscribe after the browser rotates the subscription ──────
|
||||||
|
self.addEventListener('pushsubscriptionchange', function (event) {
|
||||||
|
var cfg = WRNEXUS_PUSH_CONFIG || {};
|
||||||
|
if (!cfg.siteKey || !cfg.apiBase || !cfg.vapidPublicKey) return;
|
||||||
|
event.waitUntil(
|
||||||
|
self.registration.pushManager
|
||||||
|
.subscribe({ userVisibleOnly: true, applicationServerKey: urlBase64ToUint8Array(cfg.vapidPublicKey) })
|
||||||
|
.then(function (sub) {
|
||||||
|
return fetch(cfg.apiBase.replace(/\/+$/, '') + '/api/push/subscriptions', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'text/plain;charset=UTF-8' },
|
||||||
|
credentials: 'omit',
|
||||||
|
mode: 'cors',
|
||||||
|
body: JSON.stringify({
|
||||||
|
key: cfg.siteKey,
|
||||||
|
endpoint: sub.endpoint,
|
||||||
|
keys: {
|
||||||
|
p256dh: keyToB64(sub.getKey('p256dh')),
|
||||||
|
auth: keyToB64(sub.getKey('auth')),
|
||||||
|
},
|
||||||
|
metadata: { source: 'pushsubscriptionchange' },
|
||||||
|
}),
|
||||||
|
}).catch(function () {});
|
||||||
|
})
|
||||||
|
.catch(function () {})
|
||||||
|
);
|
||||||
|
});
|
||||||
+106
-6
@@ -167,16 +167,21 @@ const currentYear = new Date().getFullYear();
|
|||||||
<a href="/privacy" class="text-primary hover:underline">Privacy Policy</a>.
|
<a href="/privacy" class="text-primary hover:underline">Privacy Policy</a>.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- Web push opt-in (WRNexus). User-gesture subscribe control. -->
|
<!-- Web push opt-in (WRNexus). User-gesture subscribe control.
|
||||||
|
Hidden by default; the client script below reveals it only when the
|
||||||
|
WRNexus SDK + browser push support are available, and sets the
|
||||||
|
correct label based on the visitor's current subscription state. -->
|
||||||
<button
|
<button
|
||||||
id="wrnexus-subscribe"
|
id="wrnexus-subscribe"
|
||||||
type="button"
|
type="button"
|
||||||
class="mt-6 w-full px-4 py-3 bg-secondary-800 border border-secondary-700 text-white font-medium rounded-lg hover:bg-secondary-700 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-secondary-900 transition-all duration-200 text-sm flex items-center justify-center gap-2"
|
hidden
|
||||||
|
aria-label="Enable notifications"
|
||||||
|
class="mt-6 w-full px-4 py-3 bg-secondary-800 border border-secondary-700 text-white font-medium rounded-lg hover:bg-secondary-700 focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2 focus:ring-offset-secondary-900 transition-all duration-200 text-sm flex items-center justify-center gap-2 disabled:opacity-60 disabled:cursor-not-allowed"
|
||||||
>
|
>
|
||||||
<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
|
<svg class="w-4 h-4 flex-shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
|
||||||
</svg>
|
</svg>
|
||||||
<span>Enable notifications</span>
|
<span id="wrnexus-subscribe-label">Enable notifications</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -205,9 +210,104 @@ const currentYear = new Date().getFullYear();
|
|||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
<!-- WRNexus push subscribe: wired via addEventListener (Astro strips inline on* handlers). -->
|
<!-- WRNexus push subscribe: state-aware control wired via addEventListener
|
||||||
|
(Astro strips inline on* handlers). The button reflects whether the
|
||||||
|
visitor is already subscribed and lets them toggle the subscription. -->
|
||||||
<script is:inline>
|
<script is:inline>
|
||||||
document.getElementById('wrnexus-subscribe')?.addEventListener('click', () => window.WRNexusPush?.subscribe());
|
(function () {
|
||||||
|
function init() {
|
||||||
|
var btn = document.getElementById('wrnexus-subscribe');
|
||||||
|
var label = document.getElementById('wrnexus-subscribe-label');
|
||||||
|
if (!btn || !label) return;
|
||||||
|
|
||||||
|
var push = window.WRNexusPush;
|
||||||
|
var supported =
|
||||||
|
push &&
|
||||||
|
'Notification' in window &&
|
||||||
|
'serviceWorker' in navigator &&
|
||||||
|
'PushManager' in window;
|
||||||
|
|
||||||
|
// No SDK or no browser push support: keep the button hidden entirely.
|
||||||
|
if (!supported) {
|
||||||
|
btn.hidden = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Permission permanently blocked by the user: the SDK can't re-prompt,
|
||||||
|
// so surface a clear, non-actionable disabled state instead of a button
|
||||||
|
// that silently does nothing.
|
||||||
|
if (window.Notification && Notification.permission === 'denied') {
|
||||||
|
label.textContent = 'Notifications blocked';
|
||||||
|
btn.setAttribute('aria-label', 'Notifications are blocked in your browser settings');
|
||||||
|
btn.disabled = true;
|
||||||
|
btn.hidden = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the button for a given subscription state.
|
||||||
|
// Default UX: subscribed users get an actionable "Unsubscribe" toggle
|
||||||
|
// rather than a dead "Already subscribed" label.
|
||||||
|
// (Alternative: render a disabled "Already subscribed" indicator instead
|
||||||
|
// of the Unsubscribe toggle if product prefers a non-actionable state.)
|
||||||
|
function render(subscribed) {
|
||||||
|
if (subscribed) {
|
||||||
|
label.textContent = 'Unsubscribe';
|
||||||
|
btn.setAttribute('aria-label', 'Unsubscribe from notifications');
|
||||||
|
} else {
|
||||||
|
label.textContent = 'Enable notifications';
|
||||||
|
btn.setAttribute('aria-label', 'Enable notifications');
|
||||||
|
}
|
||||||
|
btn.dataset.subscribed = subscribed ? 'true' : 'false';
|
||||||
|
btn.disabled = false;
|
||||||
|
btn.hidden = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refresh() {
|
||||||
|
try {
|
||||||
|
var subscribed = await push.isSubscribed();
|
||||||
|
render(!!subscribed);
|
||||||
|
} catch (err) {
|
||||||
|
// On error, fall back to the unsubscribed label so the control stays usable.
|
||||||
|
console.error('[wrnexus-push] isSubscribed() failed:', err);
|
||||||
|
render(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.addEventListener('click', async function () {
|
||||||
|
if (btn.disabled) return;
|
||||||
|
|
||||||
|
var wasSubscribed = btn.dataset.subscribed === 'true';
|
||||||
|
var busyLabel = wasSubscribed ? 'Unsubscribing…' : 'Enabling…';
|
||||||
|
|
||||||
|
// In-progress state to prevent double-clicks while the promise is pending.
|
||||||
|
btn.disabled = true;
|
||||||
|
label.textContent = busyLabel;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (wasSubscribed) {
|
||||||
|
await push.unsubscribe();
|
||||||
|
} else {
|
||||||
|
// prompt() must run from this real user gesture.
|
||||||
|
await push.prompt();
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error('[wrnexus-push] toggle failed:', err);
|
||||||
|
} finally {
|
||||||
|
// Re-read the authoritative state and re-render the label.
|
||||||
|
await refresh();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Determine and render the initial state.
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (document.readyState === 'loading') {
|
||||||
|
document.addEventListener('DOMContentLoaded', init);
|
||||||
|
} else {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
Reference in new issue
Block a user