visuamitra 0.1.0__tar.gz

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.
Files changed (30) hide show
  1. visuamitra-0.1.0/PKG-INFO +25 -0
  2. visuamitra-0.1.0/README.md +10 -0
  3. visuamitra-0.1.0/pyproject.toml +30 -0
  4. visuamitra-0.1.0/setup.cfg +4 -0
  5. visuamitra-0.1.0/src/visuamitra/__init__.py +3 -0
  6. visuamitra-0.1.0/src/visuamitra/main.py +93 -0
  7. visuamitra-0.1.0/src/visuamitra/routes.py +163 -0
  8. visuamitra-0.1.0/src/visuamitra/static/asset-manifest.json +16 -0
  9. visuamitra-0.1.0/src/visuamitra/static/favicon.png +0 -0
  10. visuamitra-0.1.0/src/visuamitra/static/index.html +1 -0
  11. visuamitra-0.1.0/src/visuamitra/static/logo192.png +0 -0
  12. visuamitra-0.1.0/src/visuamitra/static/logo512.png +0 -0
  13. visuamitra-0.1.0/src/visuamitra/static/manifest.json +25 -0
  14. visuamitra-0.1.0/src/visuamitra/static/robots.txt +3 -0
  15. visuamitra-0.1.0/src/visuamitra/static/static/css/main.f5222080.css +2 -0
  16. visuamitra-0.1.0/src/visuamitra/static/static/css/main.f5222080.css.map +1 -0
  17. visuamitra-0.1.0/src/visuamitra/static/static/js/453.81164ae2.chunk.js +2 -0
  18. visuamitra-0.1.0/src/visuamitra/static/static/js/453.81164ae2.chunk.js.map +1 -0
  19. visuamitra-0.1.0/src/visuamitra/static/static/js/main.e7e8d878.js +3 -0
  20. visuamitra-0.1.0/src/visuamitra/static/static/js/main.e7e8d878.js.LICENSE.txt +60 -0
  21. visuamitra-0.1.0/src/visuamitra/static/static/js/main.e7e8d878.js.map +1 -0
  22. visuamitra-0.1.0/src/visuamitra/static/static/media/favicon.c56df8822a1f426656bb.png +0 -0
  23. visuamitra-0.1.0/src/visuamitra/vcf_service.py +7 -0
  24. visuamitra-0.1.0/src/visuamitra/visuamitra_script.py +938 -0
  25. visuamitra-0.1.0/src/visuamitra.egg-info/PKG-INFO +25 -0
  26. visuamitra-0.1.0/src/visuamitra.egg-info/SOURCES.txt +28 -0
  27. visuamitra-0.1.0/src/visuamitra.egg-info/dependency_links.txt +1 -0
  28. visuamitra-0.1.0/src/visuamitra.egg-info/entry_points.txt +2 -0
  29. visuamitra-0.1.0/src/visuamitra.egg-info/requires.txt +7 -0
  30. visuamitra-0.1.0/src/visuamitra.egg-info/top_level.txt +1 -0
@@ -0,0 +1,25 @@
1
+ Metadata-Version: 2.4
2
+ Name: visuamitra
3
+ Version: 0.1.0
4
+ Summary: A Tandem Repeats visualization tool for Decomposition of Motifs and Methylation across alleles.
5
+ License: MIT
6
+ Requires-Python: >=3.8
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: fastapi
9
+ Requires-Dist: uvicorn
10
+ Requires-Dist: pysam
11
+ Requires-Dist: pandas
12
+ Requires-Dist: python-multipart
13
+ Requires-Dist: bitarray
14
+ Requires-Dist: regex
15
+
16
+ # VisuaMiTRA
17
+ Visualisation of Motif / Methylation in Tandem Repeat Alleles
18
+
19
+ ## Table of contents
20
+
21
+ ## Installation
22
+
23
+ ## Usage
24
+
25
+ ## Contacts
@@ -0,0 +1,10 @@
1
+ # VisuaMiTRA
2
+ Visualisation of Motif / Methylation in Tandem Repeat Alleles
3
+
4
+ ## Table of contents
5
+
6
+ ## Installation
7
+
8
+ ## Usage
9
+
10
+ ## Contacts
@@ -0,0 +1,30 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "visuamitra"
7
+ version = "0.1.0"
8
+ description = "A Tandem Repeats visualization tool for Decomposition of Motifs and Methylation across alleles."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = {text = "MIT"}
12
+ dependencies = [
13
+ "fastapi",
14
+ "uvicorn",
15
+ "pysam",
16
+ "pandas",
17
+ "python-multipart",
18
+ "bitarray",
19
+ "regex"
20
+ ]
21
+
22
+ [project.scripts]
23
+ visuamitra = "visuamitra.main:run_server"
24
+
25
+ [tool.setuptools.packages.find]
26
+ where = ["src"]
27
+
28
+ [tool.setuptools.package-data]
29
+ # This ensures all your React build files are included in the pip wheel
30
+ visuamitra = ["static/**/*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ from .main import run_server
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,93 @@
1
+ import os
2
+ import time
3
+ import logging
4
+ import uvicorn
5
+ from fastapi import FastAPI, Request
6
+ from fastapi.middleware.cors import CORSMiddleware
7
+ from fastapi.staticfiles import StaticFiles
8
+ from fastapi.responses import FileResponse
9
+ from .routes import router
10
+ from pathlib import Path
11
+
12
+ # Setup Logging
13
+ logging.basicConfig(level=logging.INFO)
14
+ logger = logging.getLogger("timing")
15
+
16
+ app = FastAPI(
17
+ title="Visuamitra Backend",
18
+ version="0.1.0"
19
+ )
20
+
21
+ # Timing Middleware
22
+ @app.middleware("http")
23
+ async def timing_middleware(request: Request, call_next):
24
+ start = time.perf_counter()
25
+ response = await call_next(request)
26
+ duration = time.perf_counter() - start
27
+ logger.info(f"{request.method} {request.url.path} took {duration:.3f}s")
28
+ return response
29
+
30
+ # CORS Middleware (Keep this for local development)
31
+ origins = ["http://localhost:3000", "http://127.0.0.1:3000", "http://192.168.14.145:3000"]
32
+ app.add_middleware(
33
+ CORSMiddleware,
34
+ allow_origins=origins,
35
+ allow_credentials=True,
36
+ allow_methods=["*"],
37
+ allow_headers=["*"],
38
+ expose_headers=["X-Next-Cursor"],
39
+ )
40
+
41
+ # Include your API routes
42
+ app.include_router(router, prefix="/api")
43
+
44
+ # --- NEW: STATIC FILE SERVING LOGIC ---
45
+
46
+ # 1. Determine where the static files are located
47
+ # This assumes you copied the 'build' folder into 'backend/static'
48
+ # In main.py
49
+ from pathlib import Path
50
+
51
+ # Use Pathlib for cleaner cross-platform path handling
52
+ package_dir = Path(__file__).parent.resolve()
53
+ static_dir = package_dir / "static"
54
+
55
+ if static_dir.exists():
56
+ # Mount the /static/static subfolder
57
+ app.mount("/static", StaticFiles(directory=str(static_dir / "static")), name="static")
58
+
59
+ @app.get("/{rest_of_path:path}")
60
+ async def serve_frontend(rest_of_path: str):
61
+ if rest_of_path.startswith("api/"):
62
+ return {"error": "API route not found"}
63
+ return FileResponse(str(static_dir / "index.html"))
64
+ else:
65
+ # Fallback for development if static folder isn't built yet
66
+ @app.get("/")
67
+ def health_check():
68
+ return {"status": "Visuamitra backend running (Frontend build missing)"}
69
+
70
+ # --- NEW: ENTRY POINT FOR PIP ---
71
+
72
+ def run_server():
73
+ """Launcher for the visuamitra CLI command."""
74
+ import uvicorn
75
+ import webbrowser
76
+ from threading import Timer
77
+
78
+ port = 8088
79
+ url = f"http://127.0.0.1:{port}"
80
+
81
+ def open_browser():
82
+ webbrowser.open_new(url)
83
+
84
+ print(f"Starting VisuaMiTRa on {url}")
85
+
86
+ # Optional: Automatically open the browser after 1.5 seconds
87
+ Timer(1.5, open_browser).start()
88
+
89
+ # We use the string import to avoid issues with signal handlers in some OS
90
+ uvicorn.run("visuamitra.main:app", host="127.0.0.1", port=port, reload=False)
91
+
92
+ if __name__ == "__main__":
93
+ run_server()
@@ -0,0 +1,163 @@
1
+ import os
2
+ import shutil
3
+ import tempfile
4
+ from fastapi import APIRouter, UploadFile, File, Form, HTTPException
5
+ from fastapi.responses import StreamingResponse
6
+ import pysam
7
+ from typing import Optional
8
+ import base64
9
+
10
+ from .visuamitra_script import visuamitra_data_extract_stream
11
+
12
+ router = APIRouter()
13
+
14
+ def encode_cursor(chr, pos):
15
+ raw = f"{chr}:{pos}"
16
+ return base64.urlsafe_b64encode(raw.encode()).decode()
17
+
18
+ def decode_cursor(cursor):
19
+ try:
20
+ decoded = base64.urlsafe_b64decode(cursor.encode()).decode()
21
+ c, p = decoded.split(":")
22
+ return c, int(p)
23
+ except Exception:
24
+ raise HTTPException(status_code=400, detail="Invalid cursor format")
25
+
26
+ @router.post("/vcf-to-tsv-cursor")
27
+ async def vcf_to_tsv_cursor(
28
+ vcf: UploadFile = File(...),
29
+ tbi: UploadFile = File(...),
30
+ last_cursor: Optional[str] = Form(None),
31
+ page_size: int = Form(100),
32
+ chr: Optional[str] = Form(None),
33
+ start: Optional[int] = Form(None),
34
+ end: Optional[int] = Form(None),
35
+ ):
36
+ tmpdir = tempfile.mkdtemp(prefix="vcf_")
37
+ vcf_path = f"{tmpdir}/{vcf.filename}"
38
+ tbi_path = f"{tmpdir}/{tbi.filename}"
39
+
40
+ with open(vcf_path, "wb") as f:
41
+ shutil.copyfileobj(vcf.file, f)
42
+ with open(tbi_path, "wb") as f:
43
+ shutil.copyfileobj(tbi.file, f)
44
+
45
+ try:
46
+ tabix = pysam.TabixFile(vcf_path)
47
+ except Exception:
48
+ raise HTTPException(status_code=400, detail="Could not open VCF or index")
49
+
50
+ contigs = set(tabix.contigs)
51
+
52
+ # BASIC VALIDATION
53
+ if chr and chr not in contigs:
54
+ raise HTTPException(
55
+ status_code=400,
56
+ detail=f"Chromosome '{chr}' not found in VCF"
57
+ )
58
+
59
+ if start is not None and start < 1:
60
+ raise HTTPException(status_code=400, detail="Start must be >= 1")
61
+ if end is not None and end < 1:
62
+ raise HTTPException(status_code=400, detail="End must be >= 1")
63
+ if start is not None and end is not None and start > end:
64
+ raise HTTPException(status_code=400, detail="Start must be <= End")
65
+
66
+ fetch_start = 0 if start is None else start - 1
67
+ fetch_end = end
68
+
69
+ # CRITICAL PREFLIGHT CHECK
70
+ try:
71
+ if chr:
72
+ # MUST run before streaming
73
+ has_any = False
74
+ for _ in tabix.fetch(chr, fetch_start, fetch_end):
75
+ has_any = True
76
+ break
77
+ if not has_any:
78
+ raise HTTPException(
79
+ status_code=404,
80
+ detail=f"No data found in range {start}-{end} on chromosome {chr}"
81
+ )
82
+
83
+ elif start is not None or end is not None:
84
+ found = False
85
+ for c in contigs:
86
+ try:
87
+ for _ in tabix.fetch(c, fetch_start, fetch_end):
88
+ found = True
89
+ break
90
+ except ValueError:
91
+ continue
92
+ if found:
93
+ break
94
+
95
+ if not found:
96
+ raise HTTPException(
97
+ status_code=404,
98
+ detail=f"No data found in range {start}-{end} across all chromosomes"
99
+ )
100
+
101
+ except ValueError:
102
+ # pysam throws this for invalid regions
103
+ raise HTTPException(
104
+ status_code=400,
105
+ detail=f"Invalid genomic region: chr={chr}, start={start}, end={end}"
106
+ )
107
+
108
+ # CURSOR
109
+ cursor_chr, cursor_pos = (None, None)
110
+ if last_cursor:
111
+ cursor_chr, cursor_pos = decode_cursor(last_cursor)
112
+
113
+ collected = []
114
+ next_cursor = None
115
+ seen_header = False
116
+ count = 0
117
+
118
+ # SAFE STREAMING (no errors possible now)
119
+ for raw_line in visuamitra_data_extract_stream(vcf_path, chr, start, end):
120
+ if isinstance(raw_line, bytes):
121
+ raw_line = raw_line.decode("utf-8")
122
+
123
+ if not raw_line.strip():
124
+ continue
125
+
126
+ if raw_line.startswith("Chrom") and not seen_header:
127
+ collected.append(raw_line)
128
+ seen_header = True
129
+ continue
130
+
131
+ parts = raw_line.split("\t")
132
+ if len(parts) < 2:
133
+ continue
134
+
135
+ row_chr = parts[0]
136
+ try:
137
+ row_pos = int(parts[1])
138
+ except:
139
+ continue
140
+
141
+ if cursor_chr and row_pos <= cursor_pos and row_chr == cursor_chr:
142
+ continue
143
+
144
+ if count >= page_size:
145
+ next_cursor = encode_cursor(row_chr, row_pos)
146
+ break
147
+
148
+ collected.append(raw_line)
149
+ count += 1
150
+
151
+ def stream_rows():
152
+ for row in collected:
153
+ yield row
154
+
155
+ headers = {}
156
+ if next_cursor:
157
+ headers["X-Next-Cursor"] = next_cursor
158
+
159
+ return StreamingResponse(
160
+ stream_rows(),
161
+ media_type="text/tab-separated-values",
162
+ headers=headers,
163
+ )
@@ -0,0 +1,16 @@
1
+ {
2
+ "files": {
3
+ "main.css": "/static/css/main.f5222080.css",
4
+ "main.js": "/static/js/main.e7e8d878.js",
5
+ "static/js/453.81164ae2.chunk.js": "/static/js/453.81164ae2.chunk.js",
6
+ "static/media/favicon.png": "/static/media/favicon.c56df8822a1f426656bb.png",
7
+ "index.html": "/index.html",
8
+ "main.f5222080.css.map": "/static/css/main.f5222080.css.map",
9
+ "main.e7e8d878.js.map": "/static/js/main.e7e8d878.js.map",
10
+ "453.81164ae2.chunk.js.map": "/static/js/453.81164ae2.chunk.js.map"
11
+ },
12
+ "entrypoints": [
13
+ "static/css/main.f5222080.css",
14
+ "static/js/main.e7e8d878.js"
15
+ ]
16
+ }
@@ -0,0 +1 @@
1
+ <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" type="image/png" href="/favicon.png?v=2"/><title>Visuamitra-Atharva</title><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>React App</title><script defer="defer" src="/static/js/main.e7e8d878.js"></script><link href="/static/css/main.f5222080.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
@@ -0,0 +1,25 @@
1
+ {
2
+ "short_name": "React App",
3
+ "name": "Create React App Sample",
4
+ "icons": [
5
+ {
6
+ "src": "favicon.ico",
7
+ "sizes": "64x64 32x32 24x24 16x16",
8
+ "type": "image/x-icon"
9
+ },
10
+ {
11
+ "src": "logo192.png",
12
+ "type": "image/png",
13
+ "sizes": "192x192"
14
+ },
15
+ {
16
+ "src": "logo512.png",
17
+ "type": "image/png",
18
+ "sizes": "512x512"
19
+ }
20
+ ],
21
+ "start_url": ".",
22
+ "display": "standalone",
23
+ "theme_color": "#000000",
24
+ "background_color": "#ffffff"
25
+ }
@@ -0,0 +1,3 @@
1
+ # https://www.robotstxt.org/robotstxt.html
2
+ User-agent: *
3
+ Disallow:
@@ -0,0 +1,2 @@
1
+ body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;margin:0}code{font-family:source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace}#root,body,html{height:100%;margin:0;padding:0}.App{text-align:center}.App-logo{height:40vmin;pointer-events:none}@media (prefers-reduced-motion:no-preference){.App-logo{animation:App-logo-spin 20s linear infinite}}.App-header{align-items:center;background-color:#282c34;color:#fff;display:flex;flex-direction:column;font-size:calc(10px + 2vmin);justify-content:center;min-height:100vh}.App-link{color:#61dafb}@keyframes App-logo-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}#ideogram-container,#ideogram-container svg,#ideogram-container svg *{cursor:default!important}
2
+ /*# sourceMappingURL=main.f5222080.css.map*/
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static/css/main.f5222080.css","mappings":"AAAA,KAKE,kCAAmC,CACnC,iCAAkC,CAJlC,mIAEY,CAHZ,QAMF,CAEA,KACE,uEAEF,CAEA,gBACE,WAAY,CACZ,QAAS,CACT,SACF,CClBA,KACE,iBACF,CAEA,UACE,aAAc,CACd,mBACF,CAEA,8CACE,UACE,2CACF,CACF,CAEA,YAKE,kBAAmB,CAJnB,wBAAyB,CAOzB,UAAY,CALZ,YAAa,CACb,qBAAsB,CAGtB,4BAA6B,CAD7B,sBAAuB,CAJvB,gBAOF,CAEA,UACE,aACF,CAEA,yBACE,GACE,sBACF,CACA,GACE,uBACF,CACF,CAEA,sEAGE,wBACF","sources":["index.css","App.css"],"sourcesContent":["body {\n margin: 0;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',\n 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',\n sans-serif;\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n monospace;\n}\n\nhtml, body, #root {\n height: 100%;\n margin: 0;\n padding: 0;\n}\n",".App {\n text-align: center;\n}\n\n.App-logo {\n height: 40vmin;\n pointer-events: none;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .App-logo {\n animation: App-logo-spin infinite 20s linear;\n }\n}\n\n.App-header {\n background-color: #282c34;\n min-height: 100vh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n font-size: calc(10px + 2vmin);\n color: white;\n}\n\n.App-link {\n color: #61dafb;\n}\n\n@keyframes App-logo-spin {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n\n#ideogram-container,\n#ideogram-container svg,\n#ideogram-container svg * {\n cursor: default !important; /* always use the normal arrow cursor */\n}\n"],"names":[],"sourceRoot":""}
@@ -0,0 +1,2 @@
1
+ "use strict";(self.webpackChunkvisuamitra_1=self.webpackChunkvisuamitra_1||[]).push([[453],{453(e,t,n){n.d(t,{getCLS:()=>y,getFCP:()=>g,getFID:()=>C,getLCP:()=>P,getTTFB:()=>D});var i,r,a,o,u=function(e,t){return{name:e,value:void 0===t?-1:t,delta:0,entries:[],id:"v2-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)}},c=function(e,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){if("first-input"===e&&!("PerformanceEventTiming"in self))return;var n=new PerformanceObserver(function(e){return e.getEntries().map(t)});return n.observe({type:e,buffered:!0}),n}}catch(e){}},s=function(e,t){var n=function n(i){"pagehide"!==i.type&&"hidden"!==document.visibilityState||(e(i),t&&(removeEventListener("visibilitychange",n,!0),removeEventListener("pagehide",n,!0)))};addEventListener("visibilitychange",n,!0),addEventListener("pagehide",n,!0)},f=function(e){addEventListener("pageshow",function(t){t.persisted&&e(t)},!0)},m=function(e,t,n){var i;return function(r){t.value>=0&&(r||n)&&(t.delta=t.value-(i||0),(t.delta||void 0===i)&&(i=t.value,e(t)))}},v=-1,p=function(){return"hidden"===document.visibilityState?0:1/0},d=function(){s(function(e){var t=e.timeStamp;v=t},!0)},l=function(){return v<0&&(v=p(),d(),f(function(){setTimeout(function(){v=p(),d()},0)})),{get firstHiddenTime(){return v}}},g=function(e,t){var n,i=l(),r=u("FCP"),a=function(e){"first-contentful-paint"===e.name&&(s&&s.disconnect(),e.startTime<i.firstHiddenTime&&(r.value=e.startTime,r.entries.push(e),n(!0)))},o=window.performance&&performance.getEntriesByName&&performance.getEntriesByName("first-contentful-paint")[0],s=o?null:c("paint",a);(o||s)&&(n=m(e,r,t),o&&a(o),f(function(i){r=u("FCP"),n=m(e,r,t),requestAnimationFrame(function(){requestAnimationFrame(function(){r.value=performance.now()-i.timeStamp,n(!0)})})}))},h=!1,T=-1,y=function(e,t){h||(g(function(e){T=e.value}),h=!0);var n,i=function(t){T>-1&&e(t)},r=u("CLS",0),a=0,o=[],v=function(e){if(!e.hadRecentInput){var t=o[0],i=o[o.length-1];a&&e.startTime-i.startTime<1e3&&e.startTime-t.startTime<5e3?(a+=e.value,o.push(e)):(a=e.value,o=[e]),a>r.value&&(r.value=a,r.entries=o,n())}},p=c("layout-shift",v);p&&(n=m(i,r,t),s(function(){p.takeRecords().map(v),n(!0)}),f(function(){a=0,T=-1,r=u("CLS",0),n=m(i,r,t)}))},E={passive:!0,capture:!0},w=new Date,L=function(e,t){i||(i=t,r=e,a=new Date,F(removeEventListener),S())},S=function(){if(r>=0&&r<a-w){var e={entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+r};o.forEach(function(t){t(e)}),o=[]}},b=function(e){if(e.cancelable){var t=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;"pointerdown"==e.type?function(e,t){var n=function(){L(e,t),r()},i=function(){r()},r=function(){removeEventListener("pointerup",n,E),removeEventListener("pointercancel",i,E)};addEventListener("pointerup",n,E),addEventListener("pointercancel",i,E)}(t,e):L(t,e)}},F=function(e){["mousedown","keydown","touchstart","pointerdown"].forEach(function(t){return e(t,b,E)})},C=function(e,t){var n,a=l(),v=u("FID"),p=function(e){e.startTime<a.firstHiddenTime&&(v.value=e.processingStart-e.startTime,v.entries.push(e),n(!0))},d=c("first-input",p);n=m(e,v,t),d&&s(function(){d.takeRecords().map(p),d.disconnect()},!0),d&&f(function(){var a;v=u("FID"),n=m(e,v,t),o=[],r=-1,i=null,F(addEventListener),a=p,o.push(a),S()})},k={},P=function(e,t){var n,i=l(),r=u("LCP"),a=function(e){var t=e.startTime;t<i.firstHiddenTime&&(r.value=t,r.entries.push(e),n())},o=c("largest-contentful-paint",a);if(o){n=m(e,r,t);var v=function(){k[r.id]||(o.takeRecords().map(a),o.disconnect(),k[r.id]=!0,n(!0))};["keydown","click"].forEach(function(e){addEventListener(e,v,{once:!0,capture:!0})}),s(v,!0),f(function(i){r=u("LCP"),n=m(e,r,t),requestAnimationFrame(function(){requestAnimationFrame(function(){r.value=performance.now()-i.timeStamp,k[r.id]=!0,n(!0)})})})}},D=function(e){var t,n=u("TTFB");t=function(){try{var t=performance.getEntriesByType("navigation")[0]||function(){var e=performance.timing,t={entryType:"navigation",startTime:0};for(var n in e)"navigationStart"!==n&&"toJSON"!==n&&(t[n]=Math.max(e[n]-e.navigationStart,0));return t}();if(n.value=n.delta=t.responseStart,n.value<0||n.value>performance.now())return;n.entries=[t],e(n)}catch(e){}},"complete"===document.readyState?setTimeout(t,0):addEventListener("load",function(){return setTimeout(t,0)})}}}]);
2
+ //# sourceMappingURL=453.81164ae2.chunk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"static/js/453.81164ae2.chunk.js","mappings":"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","sources":["../node_modules/web-vitals/dist/web-vitals.js"],"sourcesContent":["var e,t,n,i,r=function(e,t){return{name:e,value:void 0===t?-1:t,delta:0,entries:[],id:\"v2-\".concat(Date.now(),\"-\").concat(Math.floor(8999999999999*Math.random())+1e12)}},a=function(e,t){try{if(PerformanceObserver.supportedEntryTypes.includes(e)){if(\"first-input\"===e&&!(\"PerformanceEventTiming\"in self))return;var n=new PerformanceObserver((function(e){return e.getEntries().map(t)}));return n.observe({type:e,buffered:!0}),n}}catch(e){}},o=function(e,t){var n=function n(i){\"pagehide\"!==i.type&&\"hidden\"!==document.visibilityState||(e(i),t&&(removeEventListener(\"visibilitychange\",n,!0),removeEventListener(\"pagehide\",n,!0)))};addEventListener(\"visibilitychange\",n,!0),addEventListener(\"pagehide\",n,!0)},u=function(e){addEventListener(\"pageshow\",(function(t){t.persisted&&e(t)}),!0)},c=function(e,t,n){var i;return function(r){t.value>=0&&(r||n)&&(t.delta=t.value-(i||0),(t.delta||void 0===i)&&(i=t.value,e(t)))}},f=-1,s=function(){return\"hidden\"===document.visibilityState?0:1/0},m=function(){o((function(e){var t=e.timeStamp;f=t}),!0)},v=function(){return f<0&&(f=s(),m(),u((function(){setTimeout((function(){f=s(),m()}),0)}))),{get firstHiddenTime(){return f}}},d=function(e,t){var n,i=v(),o=r(\"FCP\"),f=function(e){\"first-contentful-paint\"===e.name&&(m&&m.disconnect(),e.startTime<i.firstHiddenTime&&(o.value=e.startTime,o.entries.push(e),n(!0)))},s=window.performance&&performance.getEntriesByName&&performance.getEntriesByName(\"first-contentful-paint\")[0],m=s?null:a(\"paint\",f);(s||m)&&(n=c(e,o,t),s&&f(s),u((function(i){o=r(\"FCP\"),n=c(e,o,t),requestAnimationFrame((function(){requestAnimationFrame((function(){o.value=performance.now()-i.timeStamp,n(!0)}))}))})))},p=!1,l=-1,h=function(e,t){p||(d((function(e){l=e.value})),p=!0);var n,i=function(t){l>-1&&e(t)},f=r(\"CLS\",0),s=0,m=[],v=function(e){if(!e.hadRecentInput){var t=m[0],i=m[m.length-1];s&&e.startTime-i.startTime<1e3&&e.startTime-t.startTime<5e3?(s+=e.value,m.push(e)):(s=e.value,m=[e]),s>f.value&&(f.value=s,f.entries=m,n())}},h=a(\"layout-shift\",v);h&&(n=c(i,f,t),o((function(){h.takeRecords().map(v),n(!0)})),u((function(){s=0,l=-1,f=r(\"CLS\",0),n=c(i,f,t)})))},T={passive:!0,capture:!0},y=new Date,g=function(i,r){e||(e=r,t=i,n=new Date,w(removeEventListener),E())},E=function(){if(t>=0&&t<n-y){var r={entryType:\"first-input\",name:e.type,target:e.target,cancelable:e.cancelable,startTime:e.timeStamp,processingStart:e.timeStamp+t};i.forEach((function(e){e(r)})),i=[]}},S=function(e){if(e.cancelable){var t=(e.timeStamp>1e12?new Date:performance.now())-e.timeStamp;\"pointerdown\"==e.type?function(e,t){var n=function(){g(e,t),r()},i=function(){r()},r=function(){removeEventListener(\"pointerup\",n,T),removeEventListener(\"pointercancel\",i,T)};addEventListener(\"pointerup\",n,T),addEventListener(\"pointercancel\",i,T)}(t,e):g(t,e)}},w=function(e){[\"mousedown\",\"keydown\",\"touchstart\",\"pointerdown\"].forEach((function(t){return e(t,S,T)}))},L=function(n,f){var s,m=v(),d=r(\"FID\"),p=function(e){e.startTime<m.firstHiddenTime&&(d.value=e.processingStart-e.startTime,d.entries.push(e),s(!0))},l=a(\"first-input\",p);s=c(n,d,f),l&&o((function(){l.takeRecords().map(p),l.disconnect()}),!0),l&&u((function(){var a;d=r(\"FID\"),s=c(n,d,f),i=[],t=-1,e=null,w(addEventListener),a=p,i.push(a),E()}))},b={},F=function(e,t){var n,i=v(),f=r(\"LCP\"),s=function(e){var t=e.startTime;t<i.firstHiddenTime&&(f.value=t,f.entries.push(e),n())},m=a(\"largest-contentful-paint\",s);if(m){n=c(e,f,t);var d=function(){b[f.id]||(m.takeRecords().map(s),m.disconnect(),b[f.id]=!0,n(!0))};[\"keydown\",\"click\"].forEach((function(e){addEventListener(e,d,{once:!0,capture:!0})})),o(d,!0),u((function(i){f=r(\"LCP\"),n=c(e,f,t),requestAnimationFrame((function(){requestAnimationFrame((function(){f.value=performance.now()-i.timeStamp,b[f.id]=!0,n(!0)}))}))}))}},P=function(e){var t,n=r(\"TTFB\");t=function(){try{var t=performance.getEntriesByType(\"navigation\")[0]||function(){var e=performance.timing,t={entryType:\"navigation\",startTime:0};for(var n in e)\"navigationStart\"!==n&&\"toJSON\"!==n&&(t[n]=Math.max(e[n]-e.navigationStart,0));return t}();if(n.value=n.delta=t.responseStart,n.value<0||n.value>performance.now())return;n.entries=[t],e(n)}catch(e){}},\"complete\"===document.readyState?setTimeout(t,0):addEventListener(\"load\",(function(){return setTimeout(t,0)}))};export{h as getCLS,d as getFCP,L as getFID,F as getLCP,P as getTTFB};\n"],"names":["e","t","n","i","r","name","value","delta","entries","id","concat","Date","now","Math","floor","random","a","PerformanceObserver","supportedEntryTypes","includes","self","getEntries","map","observe","type","buffered","o","document","visibilityState","removeEventListener","addEventListener","u","persisted","c","f","s","m","timeStamp","v","setTimeout","firstHiddenTime","d","disconnect","startTime","push","window","performance","getEntriesByName","requestAnimationFrame","p","l","h","hadRecentInput","length","takeRecords","T","passive","capture","y","g","w","E","entryType","target","cancelable","processingStart","forEach","S","L","b","F","once","P","getEntriesByType","timing","max","navigationStart","responseStart","readyState"],"sourceRoot":""}