Spaces:
Sleeping
Sleeping
Sunhey Cho
commited on
Commit
Β·
207f9e0
1
Parent(s):
3fa2249
Update vision LLM agent with React Product Comparison integration
Browse files- Fixed product comparison module import errors (langchain-experimental)
- Integrated React ProductComparison component with Flask backend
- Removed Product Comparison button from main index UI
- Updated frontend build and deployment
- All models loading successfully (YOLO, DETR, ViT, LLM)
- API endpoints working for product comparison functionality
- Removed large binary files (test images and model weights) for HF compatibility
- .gitattributes +3 -0
- api.py +248 -8
- frontend/package-lock.json +0 -0
- frontend/src/App.js +2 -1
- frontend/src/components/ImageUploader.js +6 -5
- frontend/src/components/ProductComparison.js +13 -1
- product_comparison.py +3 -3
- requirements.txt +6 -3
- static/asset-manifest.json +16 -16
- static/index.html +1 -1
- static/precache-manifest.1c7268aa430373f290bea946575b07d5.js +30 -0
- static/precache-manifest.6c81b79ee3d0b098eec2157ddef3be2b.js +30 -0
- static/service-worker.js +1 -1
- static/static/css/main.3b4eede1.chunk.css +2 -0
- static/static/css/main.3b4eede1.chunk.css.map +1 -0
- static/static/{static/css β css}/main.59c2a54e.chunk.css +0 -0
- static/static/{static/css β css}/main.59c2a54e.chunk.css.map +0 -0
- static/static/{static/js β js}/2.abf91741.chunk.js +0 -0
- static/static/{static/js β js}/2.abf91741.chunk.js.LICENSE.txt +0 -0
- static/static/{static/js β js}/2.abf91741.chunk.js.map +0 -0
- static/static/js/2.e4d49f63.chunk.js +0 -0
- static/static/js/2.e4d49f63.chunk.js.LICENSE.txt +58 -0
- static/static/js/2.e4d49f63.chunk.js.map +0 -0
- static/static/js/3.10abbce4.chunk.js +2 -0
- static/static/js/3.10abbce4.chunk.js.map +1 -0
- static/static/{static/js β js}/3.9013e23f.chunk.js +0 -0
- static/static/{static/js β js}/3.9013e23f.chunk.js.map +0 -0
- static/static/js/main.3e9c0e32.chunk.js +2 -0
- static/static/js/main.3e9c0e32.chunk.js.map +0 -0
- static/static/js/main.7fd2b13c.chunk.js +2 -0
- static/static/js/main.7fd2b13c.chunk.js.map +0 -0
- static/static/{static/js β js}/main.db88b5b1.chunk.js +0 -0
- static/static/{static/js β js}/main.db88b5b1.chunk.js.map +0 -0
- static/static/js/runtime-main.1d79dee9.js +2 -0
- static/static/js/runtime-main.1d79dee9.js.map +1 -0
- static/static/{static/js β js}/runtime-main.25710301.js +0 -0
- static/static/{static/js β js}/runtime-main.25710301.js.map +0 -0
.gitattributes
CHANGED
@@ -33,3 +33,6 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
*.jpg filter=lfs diff=lfs merge=lfs -text
|
37 |
+
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
38 |
+
*.png filter=lfs diff=lfs merge=lfs -text
|
api.py
CHANGED
@@ -75,13 +75,13 @@ app.secret_key = secret_key # μΈμ
μνΈνλ₯Ό μν λΉλ° ν€
|
|
75 |
app.config['CORS_HEADERS'] = 'Content-Type'
|
76 |
# Remember cookie (Flask-Login) β minimize duration to prevent auto re-login
|
77 |
app.config['REMEMBER_COOKIE_DURATION'] = timedelta(seconds=1)
|
78 |
-
app.config['REMEMBER_COOKIE_SECURE'] =
|
79 |
app.config['REMEMBER_COOKIE_HTTPONLY'] = True
|
80 |
-
app.config['REMEMBER_COOKIE_SAMESITE'] = '
|
81 |
-
# Session cookie (Flask-Session)
|
82 |
-
app.config['SESSION_COOKIE_SECURE'] =
|
83 |
app.config['SESSION_COOKIE_HTTPONLY'] = True
|
84 |
-
app.config['SESSION_COOKIE_SAMESITE'] = '
|
85 |
app.config['SESSION_COOKIE_PATH'] = '/'
|
86 |
CORS(app) # Enable CORS for all routes
|
87 |
|
@@ -985,8 +985,13 @@ def start_product_comparison():
|
|
985 |
|
986 |
# Start processing in a background thread
|
987 |
def run_async_task(loop):
|
988 |
-
|
989 |
-
|
|
|
|
|
|
|
|
|
|
|
990 |
|
991 |
loop = asyncio.new_event_loop()
|
992 |
thread = Thread(target=run_async_task, args=(loop,))
|
@@ -1002,6 +1007,8 @@ def start_product_comparison():
|
|
1002 |
|
1003 |
except Exception as e:
|
1004 |
print(f"Error starting product comparison: {e}")
|
|
|
|
|
1005 |
return jsonify({"error": str(e)}), 500
|
1006 |
|
1007 |
|
@@ -1426,6 +1433,182 @@ def logout():
|
|
1426 |
print(f"[DEBUG] Error deleting remember_token cookie: {e}")
|
1427 |
return resp
|
1428 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1429 |
# μ μ νμΌ μλΉμ μν λΌμ°νΈ (λ‘κ·ΈμΈ λΆνμ)
|
1430 |
@app.route('/static/<path:filename>')
|
1431 |
def serve_static(filename):
|
@@ -1439,6 +1622,7 @@ def serve_static(filename):
|
|
1439 |
|
1440 |
# μΈλ±μ€ HTML μ§μ μλΉ (λ‘κ·ΈμΈ νμ)
|
1441 |
@app.route('/index.html')
|
|
|
1442 |
def serve_index_html():
|
1443 |
# μΈμ
λ° μΏ ν€ λλ²κ·Έ μ 보
|
1444 |
print(f"Request to /index.html - Session data: {dict(session)}")
|
@@ -1467,6 +1651,16 @@ def serve_index_html():
|
|
1467 |
return send_from_directory(app.static_folder, 'index.html')
|
1468 |
|
1469 |
heartbeat_script = """
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1470 |
<script>
|
1471 |
(function(){
|
1472 |
// 1) μΈμ
μν μ£ΌκΈ° μ²΄ν¬ (λ§λ£μ λ‘κ·ΈμΈμΌλ‘)
|
@@ -1499,6 +1693,19 @@ def serve_index_html():
|
|
1499 |
window.addEventListener(evt, resetIdle, {passive:true});
|
1500 |
});
|
1501 |
resetIdle();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1502 |
})();
|
1503 |
</script>
|
1504 |
"""
|
@@ -1573,6 +1780,17 @@ def static_js_files(filename):
|
|
1573 |
def serve_react(path):
|
1574 |
"""Serve React frontend"""
|
1575 |
print(f"Serving React frontend for path: {path}, user: {current_user.username if current_user.is_authenticated else 'not authenticated'}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1576 |
# μ μ νμΌ μ²λ¦¬λ μ΄μ λ³λ λΌμ°νΈμμ μ²λ¦¬
|
1577 |
if path != "" and os.path.exists(os.path.join(app.static_folder, path)):
|
1578 |
resp = send_from_directory(app.static_folder, path)
|
@@ -1595,6 +1813,15 @@ def serve_react(path):
|
|
1595 |
return resp
|
1596 |
|
1597 |
heartbeat_script = """
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1598 |
<script>
|
1599 |
(function(){
|
1600 |
// 1) μΈμ
μν μ£ΌκΈ° μ²΄ν¬ (λ§λ£μ λ‘κ·ΈμΈμΌλ‘)
|
@@ -1625,6 +1852,19 @@ def serve_react(path):
|
|
1625 |
window.addEventListener(evt, resetIdle, {passive:true});
|
1626 |
});
|
1627 |
resetIdle();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1628 |
})();
|
1629 |
</script>
|
1630 |
"""
|
@@ -1972,5 +2212,5 @@ def index_page():
|
|
1972 |
|
1973 |
if __name__ == "__main__":
|
1974 |
# νκΉ
νμ΄μ€ Spaceμμλ PORT νκ²½ λ³μλ₯Ό μ¬μ©ν©λλ€
|
1975 |
-
port = int(os.environ.get("PORT", 7860))
|
1976 |
app.run(debug=False, host='0.0.0.0', port=port)
|
|
|
75 |
app.config['CORS_HEADERS'] = 'Content-Type'
|
76 |
# Remember cookie (Flask-Login) β minimize duration to prevent auto re-login
|
77 |
app.config['REMEMBER_COOKIE_DURATION'] = timedelta(seconds=1)
|
78 |
+
app.config['REMEMBER_COOKIE_SECURE'] = False # Allow HTTP for local dev
|
79 |
app.config['REMEMBER_COOKIE_HTTPONLY'] = True
|
80 |
+
app.config['REMEMBER_COOKIE_SAMESITE'] = 'Lax'
|
81 |
+
# Session cookie (Flask-Session) - relaxed for local dev
|
82 |
+
app.config['SESSION_COOKIE_SECURE'] = False # Allow HTTP for local dev
|
83 |
app.config['SESSION_COOKIE_HTTPONLY'] = True
|
84 |
+
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax' # More permissive for local dev
|
85 |
app.config['SESSION_COOKIE_PATH'] = '/'
|
86 |
CORS(app) # Enable CORS for all routes
|
87 |
|
|
|
985 |
|
986 |
# Start processing in a background thread
|
987 |
def run_async_task(loop):
|
988 |
+
try:
|
989 |
+
asyncio.set_event_loop(loop)
|
990 |
+
loop.run_until_complete(coordinator.process_images(session_id, images, session_metadata))
|
991 |
+
except Exception as e:
|
992 |
+
print(f"Error in async task: {e}")
|
993 |
+
import traceback
|
994 |
+
traceback.print_exc()
|
995 |
|
996 |
loop = asyncio.new_event_loop()
|
997 |
thread = Thread(target=run_async_task, args=(loop,))
|
|
|
1007 |
|
1008 |
except Exception as e:
|
1009 |
print(f"Error starting product comparison: {e}")
|
1010 |
+
import traceback
|
1011 |
+
traceback.print_exc()
|
1012 |
return jsonify({"error": str(e)}), 500
|
1013 |
|
1014 |
|
|
|
1433 |
print(f"[DEBUG] Error deleting remember_token cookie: {e}")
|
1434 |
return resp
|
1435 |
|
1436 |
+
@app.route('/product-comparison-lite', methods=['GET'])
|
1437 |
+
@login_required
|
1438 |
+
def product_comparison_lite_page():
|
1439 |
+
"""Serve a lightweight two-image Product Comparison page (no React build required)."""
|
1440 |
+
html = '''<!DOCTYPE html>
|
1441 |
+
<html lang="en">
|
1442 |
+
<head>
|
1443 |
+
<meta charset="UTF-8">
|
1444 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
1445 |
+
<title>Product Comparison (Lite)</title>
|
1446 |
+
<style>
|
1447 |
+
body { font-family: Arial, sans-serif; margin: 16px; }
|
1448 |
+
.row { display: flex; gap: 16px; flex-wrap: wrap; }
|
1449 |
+
.col { flex: 1 1 320px; min-width: 280px; }
|
1450 |
+
.card { border: 1px solid #ddd; border-radius: 8px; padding: 12px; }
|
1451 |
+
.preview-box { width: 100%; height: 45vh; max-height: 520px; border: 1px dashed #ccc; display:flex; align-items:center; justify-content:center; overflow:hidden; border-radius:6px; background:#fafafa; }
|
1452 |
+
.preview-box img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
|
1453 |
+
input[type="file"] { display: none; }
|
1454 |
+
.file-button { padding: 8px 12px; background: #3f51b5; color: white; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; }
|
1455 |
+
.file-button:hover { background: #303f9f; }
|
1456 |
+
.controls { margin-top: 12px; display:flex; gap: 8px; align-items:center; }
|
1457 |
+
button { padding: 10px 14px; background: #3f51b5; color: #fff; border: none; border-radius: 4px; cursor: pointer; }
|
1458 |
+
button:disabled { background: #9aa0c3; cursor: not-allowed; }
|
1459 |
+
.log { white-space: pre-wrap; background:#fff; color:#333; border: 1px solid #ddd; padding:10px; border-radius:6px; height:180px; overflow:auto; font-size: 12px; }
|
1460 |
+
.result { margin-top: 12px; }
|
1461 |
+
</style>
|
1462 |
+
</head>
|
1463 |
+
<body>
|
1464 |
+
<h2>Product Comparison (Lite)</h2>
|
1465 |
+
<div class="row">
|
1466 |
+
<div class="col">
|
1467 |
+
<div class="card">
|
1468 |
+
<h3>Product Image 1</h3>
|
1469 |
+
<div class="preview-box"><img id="img1" alt="Product 1 Preview" style="display:none;" /></div>
|
1470 |
+
<div class="controls">
|
1471 |
+
<input type="file" id="file1" accept="image/*" />
|
1472 |
+
<button type="button" class="file-button" onclick="document.getElementById('file1').click()">Choose Image File</button>
|
1473 |
+
</div>
|
1474 |
+
</div>
|
1475 |
+
</div>
|
1476 |
+
<div class="col">
|
1477 |
+
<div class="card">
|
1478 |
+
<h3>Product Image 2</h3>
|
1479 |
+
<div class="preview-box"><img id="img2" alt="Product 2 Preview" style="display:none;" /></div>
|
1480 |
+
<div class="controls">
|
1481 |
+
<input type="file" id="file2" accept="image/*" />
|
1482 |
+
<button type="button" class="file-button" onclick="document.getElementById('file2').click()">Choose Image File</button>
|
1483 |
+
</div>
|
1484 |
+
</div>
|
1485 |
+
</div>
|
1486 |
+
</div>
|
1487 |
+
<div class="controls" style="margin-top:16px;">
|
1488 |
+
<button id="compareBtn" disabled onclick="startCompare()">Compare Products</button>
|
1489 |
+
<a href="/index.html" style="margin-left:8px;">Back to App</a>
|
1490 |
+
</div>
|
1491 |
+
<h3>Analysis Progress</h3>
|
1492 |
+
<div id="log" class="log"></div>
|
1493 |
+
<h3>Comparison Results</h3>
|
1494 |
+
<pre id="result" class="result"></pre>
|
1495 |
+
|
1496 |
+
<script>
|
1497 |
+
// Proactively unregister any active service workers
|
1498 |
+
(function(){
|
1499 |
+
if ('serviceWorker' in navigator) {
|
1500 |
+
try {
|
1501 |
+
navigator.serviceWorker.getRegistrations().then(function(regs){
|
1502 |
+
regs.forEach(function(r){ r.unregister(); });
|
1503 |
+
});
|
1504 |
+
} catch (e) { /* ignore */ }
|
1505 |
+
}
|
1506 |
+
})();
|
1507 |
+
|
1508 |
+
let file1 = null, file2 = null;
|
1509 |
+
|
1510 |
+
function handleFile(i, input) {
|
1511 |
+
console.log('handleFile called for image', i, 'with input:', input);
|
1512 |
+
const f = input.files && input.files[0];
|
1513 |
+
if (!f) {
|
1514 |
+
console.log('No file selected');
|
1515 |
+
return;
|
1516 |
+
}
|
1517 |
+
console.log('File selected:', f.name, 'size:', f.size, 'type:', f.type);
|
1518 |
+
|
1519 |
+
const url = URL.createObjectURL(f);
|
1520 |
+
console.log('Object URL created:', url);
|
1521 |
+
|
1522 |
+
const img = document.getElementById('img'+i);
|
1523 |
+
console.log('Image element found:', img);
|
1524 |
+
|
1525 |
+
if (img) {
|
1526 |
+
img.src = url;
|
1527 |
+
img.style.display = 'block';
|
1528 |
+
img.style.visibility = 'visible';
|
1529 |
+
console.log('Image src set and display changed to block');
|
1530 |
+
|
1531 |
+
img.onload = function() {
|
1532 |
+
console.log('Image ' + i + ' loaded successfully, dimensions:', img.naturalWidth, 'x', img.naturalHeight);
|
1533 |
+
};
|
1534 |
+
img.onerror = function() {
|
1535 |
+
console.error('Failed to load image ' + i);
|
1536 |
+
};
|
1537 |
+
}
|
1538 |
+
|
1539 |
+
if (i === 1) {
|
1540 |
+
file1 = f;
|
1541 |
+
console.log('File1 set:', f.name);
|
1542 |
+
} else {
|
1543 |
+
file2 = f;
|
1544 |
+
console.log('File2 set:', f.name);
|
1545 |
+
}
|
1546 |
+
updateButton();
|
1547 |
+
}
|
1548 |
+
|
1549 |
+
function updateButton(){
|
1550 |
+
const btn = document.getElementById('compareBtn');
|
1551 |
+
const enabled = file1 && file2;
|
1552 |
+
btn.disabled = !enabled;
|
1553 |
+
console.log('Button state updated. File1:', !!file1, 'File2:', !!file2, 'Enabled:', enabled);
|
1554 |
+
}
|
1555 |
+
|
1556 |
+
async function startCompare() {
|
1557 |
+
if (!file1 || !file2) return;
|
1558 |
+
const formData = new FormData();
|
1559 |
+
formData.append('image1', file1);
|
1560 |
+
formData.append('image2', file2);
|
1561 |
+
try {
|
1562 |
+
const response = await fetch('/api/product/compare/start', {
|
1563 |
+
method: 'POST',
|
1564 |
+
body: formData
|
1565 |
+
});
|
1566 |
+
const data = await response.json();
|
1567 |
+
if (data.session_id) {
|
1568 |
+
streamResults(data.session_id);
|
1569 |
+
}
|
1570 |
+
} catch (error) {
|
1571 |
+
console.error('Error starting comparison:', error);
|
1572 |
+
}
|
1573 |
+
}
|
1574 |
+
|
1575 |
+
function streamResults(sessionId) {
|
1576 |
+
const eventSource = new EventSource('/api/product/compare/stream/' + sessionId);
|
1577 |
+
const logDiv = document.getElementById('log');
|
1578 |
+
const resultDiv = document.getElementById('result');
|
1579 |
+
eventSource.onmessage = function(event) {
|
1580 |
+
const data = JSON.parse(event.data);
|
1581 |
+
if (data.type === 'log') {
|
1582 |
+
logDiv.textContent += data.message + '\\n';
|
1583 |
+
logDiv.scrollTop = logDiv.scrollHeight;
|
1584 |
+
} else if (data.type === 'result') {
|
1585 |
+
resultDiv.textContent = JSON.stringify(data.data, null, 2);
|
1586 |
+
eventSource.close();
|
1587 |
+
}
|
1588 |
+
};
|
1589 |
+
eventSource.onerror = function() {
|
1590 |
+
eventSource.close();
|
1591 |
+
};
|
1592 |
+
}
|
1593 |
+
|
1594 |
+
// Add event listeners after DOM loads
|
1595 |
+
document.addEventListener('DOMContentLoaded', function() {
|
1596 |
+
document.getElementById('file1').addEventListener('change', function() {
|
1597 |
+
handleFile(1, this);
|
1598 |
+
});
|
1599 |
+
document.getElementById('file2').addEventListener('change', function() {
|
1600 |
+
handleFile(2, this);
|
1601 |
+
});
|
1602 |
+
});
|
1603 |
+
</script>
|
1604 |
+
</body>
|
1605 |
+
</html>'''
|
1606 |
+
resp = make_response(html)
|
1607 |
+
resp.headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0'
|
1608 |
+
resp.headers['Pragma'] = 'no-cache'
|
1609 |
+
resp.headers['Expires'] = '0'
|
1610 |
+
return resp
|
1611 |
+
|
1612 |
# μ μ νμΌ μλΉμ μν λΌμ°νΈ (λ‘κ·ΈμΈ λΆνμ)
|
1613 |
@app.route('/static/<path:filename>')
|
1614 |
def serve_static(filename):
|
|
|
1622 |
|
1623 |
# μΈλ±μ€ HTML μ§μ μλΉ (λ‘κ·ΈμΈ νμ)
|
1624 |
@app.route('/index.html')
|
1625 |
+
@fresh_login_required
|
1626 |
def serve_index_html():
|
1627 |
# μΈμ
λ° μΏ ν€ λλ²κ·Έ μ 보
|
1628 |
print(f"Request to /index.html - Session data: {dict(session)}")
|
|
|
1651 |
return send_from_directory(app.static_folder, 'index.html')
|
1652 |
|
1653 |
heartbeat_script = """
|
1654 |
+
<style>
|
1655 |
+
/* Override preview image sizing from old builds without rebuild */
|
1656 |
+
.preview-image { max-width: 100% !important; max-height: 100% !important; width: auto !important; height: auto !important; object-fit: contain !important; }
|
1657 |
+
/* Ensure container is not too tall on desktop */
|
1658 |
+
.preview-image-container, .image-container { height: 45vh !important; }
|
1659 |
+
@media (max-width: 600px) { .preview-image-container, .image-container { height: 35vh !important; } }
|
1660 |
+
/* Product Comparison navigation button */
|
1661 |
+
.product-comparison-nav { position: fixed; top: 20px; right: 20px; z-index: 9999; background: #3f51b5; color: white; padding: 12px 16px; border-radius: 8px; text-decoration: none; font-weight: bold; box-shadow: 0 4px 8px rgba(0,0,0,0.2); transition: background 0.3s; }
|
1662 |
+
.product-comparison-nav:hover { background: #303f9f; color: white; text-decoration: none; }
|
1663 |
+
</style>
|
1664 |
<script>
|
1665 |
(function(){
|
1666 |
// 1) μΈμ
μν μ£ΌκΈ° μ²΄ν¬ (λ§λ£μ λ‘κ·ΈμΈμΌλ‘)
|
|
|
1693 |
window.addEventListener(evt, resetIdle, {passive:true});
|
1694 |
});
|
1695 |
resetIdle();
|
1696 |
+
|
1697 |
+
// 3) Add Product Comparison navigation button - DISABLED
|
1698 |
+
function addProductComparisonButton() {
|
1699 |
+
// Disabled - no longer adding Product Comparison button to main UI
|
1700 |
+
return;
|
1701 |
+
}
|
1702 |
+
|
1703 |
+
// Add button after DOM is ready
|
1704 |
+
if (document.readyState === 'loading') {
|
1705 |
+
document.addEventListener('DOMContentLoaded', addProductComparisonButton);
|
1706 |
+
} else {
|
1707 |
+
addProductComparisonButton();
|
1708 |
+
}
|
1709 |
})();
|
1710 |
</script>
|
1711 |
"""
|
|
|
1780 |
def serve_react(path):
|
1781 |
"""Serve React frontend"""
|
1782 |
print(f"Serving React frontend for path: {path}, user: {current_user.username if current_user.is_authenticated else 'not authenticated'}")
|
1783 |
+
|
1784 |
+
# Skip specific routes that have their own handlers (but not index.html)
|
1785 |
+
if path in ['product-comparison-lite', 'login', 'logout', 'similar-images', 'object-detection-search', 'model-vector-db', 'openai-chat']:
|
1786 |
+
# Let Flask find the specific route handler
|
1787 |
+
from flask import abort
|
1788 |
+
abort(404) # This will cause Flask to try other routes
|
1789 |
+
|
1790 |
+
# For root path, redirect to index.html to ensure consistent behavior
|
1791 |
+
if path == "":
|
1792 |
+
return redirect('/index.html')
|
1793 |
+
|
1794 |
# μ μ νμΌ μ²λ¦¬λ μ΄μ λ³λ λΌμ°νΈμμ μ²λ¦¬
|
1795 |
if path != "" and os.path.exists(os.path.join(app.static_folder, path)):
|
1796 |
resp = send_from_directory(app.static_folder, path)
|
|
|
1813 |
return resp
|
1814 |
|
1815 |
heartbeat_script = """
|
1816 |
+
<style>
|
1817 |
+
/* Override preview image sizing from old builds without rebuild */
|
1818 |
+
.preview-image { max-width: 100% !important; max-height: 100% !important; width: auto !important; height: auto !important; object-fit: contain !important; }
|
1819 |
+
.preview-image-container, .image-container { height: 45vh !important; }
|
1820 |
+
@media (max-width: 600px) { .preview-image-container, .image-container { height: 35vh !important; } }
|
1821 |
+
/* Product Comparison navigation button */
|
1822 |
+
.product-comparison-nav { position: fixed; top: 20px; right: 20px; z-index: 9999; background: #3f51b5; color: white; padding: 12px 16px; border-radius: 8px; text-decoration: none; font-weight: bold; box-shadow: 0 4px 8px rgba(0,0,0,0.2); transition: background 0.3s; }
|
1823 |
+
.product-comparison-nav:hover { background: #303f9f; color: white; text-decoration: none; }
|
1824 |
+
</style>
|
1825 |
<script>
|
1826 |
(function(){
|
1827 |
// 1) μΈμ
μν μ£ΌκΈ° μ²΄ν¬ (λ§λ£μ λ‘κ·ΈμΈμΌλ‘)
|
|
|
1852 |
window.addEventListener(evt, resetIdle, {passive:true});
|
1853 |
});
|
1854 |
resetIdle();
|
1855 |
+
|
1856 |
+
// 3) Add Product Comparison navigation button - DISABLED
|
1857 |
+
function addProductComparisonButton() {
|
1858 |
+
// Disabled - no longer adding Product Comparison button to main UI
|
1859 |
+
return;
|
1860 |
+
}
|
1861 |
+
|
1862 |
+
// Add button after DOM is ready
|
1863 |
+
if (document.readyState === 'loading') {
|
1864 |
+
document.addEventListener('DOMContentLoaded', addProductComparisonButton);
|
1865 |
+
} else {
|
1866 |
+
addProductComparisonButton();
|
1867 |
+
}
|
1868 |
})();
|
1869 |
</script>
|
1870 |
"""
|
|
|
2212 |
|
2213 |
if __name__ == "__main__":
|
2214 |
# νκΉ
νμ΄μ€ Spaceμμλ PORT νκ²½ λ³μλ₯Ό μ¬μ©ν©λλ€
|
2215 |
+
port = int(os.environ.get("FLASK_PORT", os.environ.get("PORT", 7860)))
|
2216 |
app.run(debug=False, host='0.0.0.0', port=port)
|
frontend/package-lock.json
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
frontend/src/App.js
CHANGED
@@ -11,7 +11,8 @@ import {
|
|
11 |
ThemeProvider,
|
12 |
createMuiTheme,
|
13 |
Tabs,
|
14 |
-
Tab
|
|
|
15 |
} from '@material-ui/core';
|
16 |
import ImageUploader from './components/ImageUploader';
|
17 |
import ModelSelector from './components/ModelSelector';
|
|
|
11 |
ThemeProvider,
|
12 |
createMuiTheme,
|
13 |
Tabs,
|
14 |
+
Tab,
|
15 |
+
Button
|
16 |
} from '@material-ui/core';
|
17 |
import ImageUploader from './components/ImageUploader';
|
18 |
import ModelSelector from './components/ModelSelector';
|
frontend/src/components/ImageUploader.js
CHANGED
@@ -56,10 +56,10 @@ const useStyles = makeStyles((theme) => ({
|
|
56 |
imageContainer: {
|
57 |
position: 'relative',
|
58 |
width: '100%',
|
59 |
-
// Use viewport-based height so any aspect ratio fits inside
|
60 |
-
height: '
|
61 |
[theme.breakpoints.down('sm')]: {
|
62 |
-
height: '
|
63 |
},
|
64 |
display: 'flex',
|
65 |
justifyContent: 'center',
|
@@ -180,9 +180,10 @@ const ImageUploader = ({ onImageUpload }) => {
|
|
180 |
alt="Preview"
|
181 |
className="preview-image"
|
182 |
style={{
|
183 |
-
|
184 |
-
height: 'auto',
|
185 |
maxHeight: '100%',
|
|
|
|
|
186 |
objectFit: 'contain',
|
187 |
display: 'block'
|
188 |
}}
|
|
|
56 |
imageContainer: {
|
57 |
position: 'relative',
|
58 |
width: '100%',
|
59 |
+
// Use a smaller viewport-based height so any aspect ratio fits inside
|
60 |
+
height: '45vh',
|
61 |
[theme.breakpoints.down('sm')]: {
|
62 |
+
height: '35vh',
|
63 |
},
|
64 |
display: 'flex',
|
65 |
justifyContent: 'center',
|
|
|
180 |
alt="Preview"
|
181 |
className="preview-image"
|
182 |
style={{
|
183 |
+
maxWidth: '100%',
|
|
|
184 |
maxHeight: '100%',
|
185 |
+
width: 'auto',
|
186 |
+
height: 'auto',
|
187 |
objectFit: 'contain',
|
188 |
display: 'block'
|
189 |
}}
|
frontend/src/components/ProductComparison.js
CHANGED
@@ -282,13 +282,25 @@ const ProductComparison = () => {
|
|
282 |
|
283 |
// λ°±μλ API νΈμΆ (μΈμ
μμ)
|
284 |
addLog('Initializing analysis session...', 'system');
|
|
|
|
|
|
|
|
|
|
|
|
|
285 |
const response = await fetch('/api/product/compare/start', {
|
286 |
method: 'POST',
|
287 |
body: formData,
|
|
|
288 |
});
|
289 |
|
|
|
|
|
|
|
290 |
if (!response.ok) {
|
291 |
-
|
|
|
|
|
292 |
}
|
293 |
|
294 |
const data = await response.json();
|
|
|
282 |
|
283 |
// λ°±μλ API νΈμΆ (μΈμ
μμ)
|
284 |
addLog('Initializing analysis session...', 'system');
|
285 |
+
|
286 |
+
// Debug FormData contents
|
287 |
+
for (let [key, value] of formData.entries()) {
|
288 |
+
console.log('FormData:', key, value);
|
289 |
+
}
|
290 |
+
|
291 |
const response = await fetch('/api/product/compare/start', {
|
292 |
method: 'POST',
|
293 |
body: formData,
|
294 |
+
credentials: 'include', // μΈμ
μΏ ν€ ν¬ν¨
|
295 |
});
|
296 |
|
297 |
+
console.log('Response status:', response.status);
|
298 |
+
console.log('Response headers:', response.headers);
|
299 |
+
|
300 |
if (!response.ok) {
|
301 |
+
const errorText = await response.text();
|
302 |
+
console.error('Error response:', errorText);
|
303 |
+
throw new Error(`HTTP error! Status: ${response.status} - ${errorText}`);
|
304 |
}
|
305 |
|
306 |
const data = await response.json();
|
product_comparison.py
CHANGED
@@ -38,11 +38,11 @@ try:
|
|
38 |
from langchain.memory import ConversationBufferMemory
|
39 |
from langchain.tools.render import format_tool_to_openai_function
|
40 |
from langchain_community.chat_models import ChatOpenAI
|
41 |
-
from
|
42 |
except ImportError:
|
43 |
print("Warning: LangChain components not available. Installing required packages...")
|
44 |
import subprocess
|
45 |
-
subprocess.run(["pip", "install", "langchain", "langchain-openai", "langchain-community"])
|
46 |
from langchain_core.prompts import ChatPromptTemplate
|
47 |
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
|
48 |
from langchain.agents import create_openai_functions_agent
|
@@ -50,7 +50,7 @@ except ImportError:
|
|
50 |
from langchain.memory import ConversationBufferMemory
|
51 |
from langchain.tools.render import format_tool_to_openai_function
|
52 |
from langchain_community.chat_models import ChatOpenAI
|
53 |
-
from
|
54 |
|
55 |
# Import vision models if available
|
56 |
try:
|
|
|
38 |
from langchain.memory import ConversationBufferMemory
|
39 |
from langchain.tools.render import format_tool_to_openai_function
|
40 |
from langchain_community.chat_models import ChatOpenAI
|
41 |
+
from langchain_experimental.tools.python.tool import PythonAstREPLTool
|
42 |
except ImportError:
|
43 |
print("Warning: LangChain components not available. Installing required packages...")
|
44 |
import subprocess
|
45 |
+
subprocess.run(["pip", "install", "langchain", "langchain-openai", "langchain-community", "langchain-experimental"])
|
46 |
from langchain_core.prompts import ChatPromptTemplate
|
47 |
from langchain_core.output_parsers import StrOutputParser, JsonOutputParser
|
48 |
from langchain.agents import create_openai_functions_agent
|
|
|
50 |
from langchain.memory import ConversationBufferMemory
|
51 |
from langchain.tools.render import format_tool_to_openai_function
|
52 |
from langchain_community.chat_models import ChatOpenAI
|
53 |
+
from langchain_experimental.tools.python.tool import PythonAstREPLTool
|
54 |
|
55 |
# Import vision models if available
|
56 |
try:
|
requirements.txt
CHANGED
@@ -25,8 +25,10 @@ python-multipart>=0.0.5
|
|
25 |
requests>=2.31.0
|
26 |
|
27 |
# Llama 4 integration
|
28 |
-
accelerator
|
29 |
-
|
|
|
|
|
30 |
sentencepiece>=0.1.99
|
31 |
protobuf>=4.23.0
|
32 |
|
@@ -36,7 +38,8 @@ chromadb>=0.4.18
|
|
36 |
scipy>=1.10.0,<1.14.0; python_version < '3.12'
|
37 |
scipy>=1.14.1,<1.15.0; python_version >= '3.12'
|
38 |
open-clip-torch>=2.20.0
|
39 |
-
pysqlite3-binary
|
|
|
40 |
|
41 |
# OpenAI Python SDK
|
42 |
openai>=1.30.0
|
|
|
25 |
requests>=2.31.0
|
26 |
|
27 |
# Llama 4 integration
|
28 |
+
# Use Hugging Face accelerate; "accelerator" was a typo and can cause install issues
|
29 |
+
accelerate>=0.20.0
|
30 |
+
# bitsandbytes is only supported on Linux x86_64; avoid install on macOS/ARM
|
31 |
+
bitsandbytes>=0.41.0; platform_system == 'Linux' and platform_machine == 'x86_64'
|
32 |
sentencepiece>=0.1.99
|
33 |
protobuf>=4.23.0
|
34 |
|
|
|
38 |
scipy>=1.10.0,<1.14.0; python_version < '3.12'
|
39 |
scipy>=1.14.1,<1.15.0; python_version >= '3.12'
|
40 |
open-clip-torch>=2.20.0
|
41 |
+
# pysqlite3-binary needed for some Linux environments; skip on macOS
|
42 |
+
pysqlite3-binary>=0.5.0; sys_platform == 'linux'
|
43 |
|
44 |
# OpenAI Python SDK
|
45 |
openai>=1.30.0
|
static/asset-manifest.json
CHANGED
@@ -1,24 +1,24 @@
|
|
1 |
{
|
2 |
"files": {
|
3 |
-
"main.css": "/static/css/main.
|
4 |
-
"main.js": "/static/js/main.
|
5 |
-
"main.js.map": "/static/js/main.
|
6 |
-
"runtime-main.js": "/static/js/runtime-main.
|
7 |
-
"runtime-main.js.map": "/static/js/runtime-main.
|
8 |
-
"static/js/2.
|
9 |
-
"static/js/2.
|
10 |
-
"static/js/3.
|
11 |
-
"static/js/3.
|
12 |
"index.html": "/index.html",
|
13 |
-
"precache-manifest.
|
14 |
"service-worker.js": "/service-worker.js",
|
15 |
-
"static/css/main.
|
16 |
-
"static/js/2.
|
17 |
},
|
18 |
"entrypoints": [
|
19 |
-
"static/js/runtime-main.
|
20 |
-
"static/js/2.
|
21 |
-
"static/css/main.
|
22 |
-
"static/js/main.
|
23 |
]
|
24 |
}
|
|
|
1 |
{
|
2 |
"files": {
|
3 |
+
"main.css": "/static/css/main.3b4eede1.chunk.css",
|
4 |
+
"main.js": "/static/js/main.3e9c0e32.chunk.js",
|
5 |
+
"main.js.map": "/static/js/main.3e9c0e32.chunk.js.map",
|
6 |
+
"runtime-main.js": "/static/js/runtime-main.1d79dee9.js",
|
7 |
+
"runtime-main.js.map": "/static/js/runtime-main.1d79dee9.js.map",
|
8 |
+
"static/js/2.e4d49f63.chunk.js": "/static/js/2.e4d49f63.chunk.js",
|
9 |
+
"static/js/2.e4d49f63.chunk.js.map": "/static/js/2.e4d49f63.chunk.js.map",
|
10 |
+
"static/js/3.10abbce4.chunk.js": "/static/js/3.10abbce4.chunk.js",
|
11 |
+
"static/js/3.10abbce4.chunk.js.map": "/static/js/3.10abbce4.chunk.js.map",
|
12 |
"index.html": "/index.html",
|
13 |
+
"precache-manifest.6c81b79ee3d0b098eec2157ddef3be2b.js": "/precache-manifest.6c81b79ee3d0b098eec2157ddef3be2b.js",
|
14 |
"service-worker.js": "/service-worker.js",
|
15 |
+
"static/css/main.3b4eede1.chunk.css.map": "/static/css/main.3b4eede1.chunk.css.map",
|
16 |
+
"static/js/2.e4d49f63.chunk.js.LICENSE.txt": "/static/js/2.e4d49f63.chunk.js.LICENSE.txt"
|
17 |
},
|
18 |
"entrypoints": [
|
19 |
+
"static/js/runtime-main.1d79dee9.js",
|
20 |
+
"static/js/2.e4d49f63.chunk.js",
|
21 |
+
"static/css/main.3b4eede1.chunk.css",
|
22 |
+
"static/js/main.3e9c0e32.chunk.js"
|
23 |
]
|
24 |
}
|
static/index.html
CHANGED
@@ -1 +1 @@
|
|
1 |
-
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Multi-Model Object Detection Demo"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>Vision Web App</title><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/><link href="/static/css/main.
|
|
|
1 |
+
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Multi-Model Object Detection Demo"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>Vision Web App</title><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/><link href="/static/css/main.3b4eede1.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,i,a=r[0],c=r[1],l=r[2],f=0,s=[];f<a.length;f++)i=a[f],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,l||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var c=t[a];0!==o[c]&&(n=!1)}n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={1:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"10abbce4"}[e]+".chunk.js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,function(r){return e[r]}.bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this["webpackJsonpvision-web-app"]=this["webpackJsonpvision-web-app"]||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var l=0;l<a.length;l++)r(a[l]);var p=c;t()}([])</script><script src="/static/js/2.e4d49f63.chunk.js"></script><script src="/static/js/main.3e9c0e32.chunk.js"></script></body></html>
|
static/precache-manifest.1c7268aa430373f290bea946575b07d5.js
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
self.__precacheManifest = (self.__precacheManifest || []).concat([
|
2 |
+
{
|
3 |
+
"revision": "6d3f2e82abbfb9305604907a27067ac8",
|
4 |
+
"url": "/index.html"
|
5 |
+
},
|
6 |
+
{
|
7 |
+
"revision": "16539bb2eb1bee3f18d9",
|
8 |
+
"url": "/static/css/main.3b4eede1.chunk.css"
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"revision": "8c82444e1d7d7382cb08",
|
12 |
+
"url": "/static/js/2.e4d49f63.chunk.js"
|
13 |
+
},
|
14 |
+
{
|
15 |
+
"revision": "89a1b2dcd30c03705b2bceeb141b76b6",
|
16 |
+
"url": "/static/js/2.e4d49f63.chunk.js.LICENSE.txt"
|
17 |
+
},
|
18 |
+
{
|
19 |
+
"revision": "3e950a8ed9ea38f208da",
|
20 |
+
"url": "/static/js/3.10abbce4.chunk.js"
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"revision": "16539bb2eb1bee3f18d9",
|
24 |
+
"url": "/static/js/main.7fd2b13c.chunk.js"
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"revision": "154c4b0ed16fd7552969",
|
28 |
+
"url": "/static/js/runtime-main.1d79dee9.js"
|
29 |
+
}
|
30 |
+
]);
|
static/precache-manifest.6c81b79ee3d0b098eec2157ddef3be2b.js
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
self.__precacheManifest = (self.__precacheManifest || []).concat([
|
2 |
+
{
|
3 |
+
"revision": "bbb36010f0040b79c203295da54a1c3b",
|
4 |
+
"url": "/index.html"
|
5 |
+
},
|
6 |
+
{
|
7 |
+
"revision": "f7e4eae0b4827cd78d54",
|
8 |
+
"url": "/static/css/main.3b4eede1.chunk.css"
|
9 |
+
},
|
10 |
+
{
|
11 |
+
"revision": "8c82444e1d7d7382cb08",
|
12 |
+
"url": "/static/js/2.e4d49f63.chunk.js"
|
13 |
+
},
|
14 |
+
{
|
15 |
+
"revision": "89a1b2dcd30c03705b2bceeb141b76b6",
|
16 |
+
"url": "/static/js/2.e4d49f63.chunk.js.LICENSE.txt"
|
17 |
+
},
|
18 |
+
{
|
19 |
+
"revision": "3e950a8ed9ea38f208da",
|
20 |
+
"url": "/static/js/3.10abbce4.chunk.js"
|
21 |
+
},
|
22 |
+
{
|
23 |
+
"revision": "f7e4eae0b4827cd78d54",
|
24 |
+
"url": "/static/js/main.3e9c0e32.chunk.js"
|
25 |
+
},
|
26 |
+
{
|
27 |
+
"revision": "154c4b0ed16fd7552969",
|
28 |
+
"url": "/static/js/runtime-main.1d79dee9.js"
|
29 |
+
}
|
30 |
+
]);
|
static/service-worker.js
CHANGED
@@ -14,7 +14,7 @@
|
|
14 |
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
|
15 |
|
16 |
importScripts(
|
17 |
-
"/precache-manifest.
|
18 |
);
|
19 |
|
20 |
self.addEventListener('message', (event) => {
|
|
|
14 |
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
|
15 |
|
16 |
importScripts(
|
17 |
+
"/precache-manifest.6c81b79ee3d0b098eec2157ddef3be2b.js"
|
18 |
);
|
19 |
|
20 |
self.addEventListener('message', (event) => {
|
static/static/css/main.3b4eede1.chunk.css
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","Roboto","Oxygen","Ubuntu","Cantarell","Fira Sans","Droid Sans","Helvetica Neue",sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background-color:#f5f5f5}code{font-family:source-code-pro,Menlo,Monaco,Consolas,"Courier New",monospace}.App{text-align:center}.preview-image{width:100%;height:auto;max-height:100%;object-fit:contain;display:block;margin-top:0}.result-image{max-width:100%;border:1px solid #ddd;border-radius:4px;padding:4px}.detection-list{margin-top:16px;text-align:left}.model-card{cursor:pointer;transition:all .3s}.model-card:hover{transform:translateY(-5px);box-shadow:0 10px 20px rgba(0,0,0,.1)}.model-card.selected{border:2px solid #3f51b5;background-color:#e8eaf6}.model-card.disabled{opacity:.6;cursor:not-allowed}.performance-info{margin-top:16px;font-size:.9rem;color:#666}
|
2 |
+
/*# sourceMappingURL=main.3b4eede1.chunk.css.map */
|
static/static/css/main.3b4eede1.chunk.css.map
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"version":3,"sources":["index.css","App.css"],"names":[],"mappings":"AAAA,KACE,QAAS,CACT,mJAEY,CACZ,kCAAmC,CACnC,iCAAkC,CAClC,wBACF,CAEA,KACE,yEAEF,CCbA,KACE,iBACF,CAEA,eACE,UAAW,CACX,WAAY,CACZ,eAAgB,CAChB,kBAAmB,CACnB,aAAc,CACd,YACF,CAEA,cACE,cAAe,CACf,qBAAsB,CACtB,iBAAkB,CAClB,WACF,CAEA,gBACE,eAAgB,CAChB,eACF,CAEA,YACE,cAAe,CACf,kBACF,CAEA,kBACE,0BAA2B,CAC3B,qCACF,CAEA,qBACE,wBAAyB,CACzB,wBACF,CAEA,qBACE,UAAY,CACZ,kBACF,CAEA,kBACE,eAAgB,CAChB,eAAiB,CACjB,UACF","file":"main.3b4eede1.chunk.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 background-color: #f5f5f5;\n}\n\ncode {\n font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',\n monospace;\n}\n",".App {\n text-align: center;\n}\n\n.preview-image {\n width: 100%;\n height: auto;\n max-height: 100%;\n object-fit: contain;\n display: block;\n margin-top: 0;\n}\n\n.result-image {\n max-width: 100%;\n border: 1px solid #ddd;\n border-radius: 4px;\n padding: 4px;\n}\n\n.detection-list {\n margin-top: 16px;\n text-align: left;\n}\n\n.model-card {\n cursor: pointer;\n transition: all 0.3s;\n}\n\n.model-card:hover {\n transform: translateY(-5px);\n box-shadow: 0 10px 20px rgba(0,0,0,0.1);\n}\n\n.model-card.selected {\n border: 2px solid #3f51b5;\n background-color: #e8eaf6;\n}\n\n.model-card.disabled {\n opacity: 0.6;\n cursor: not-allowed;\n}\n\n.performance-info {\n margin-top: 16px;\n font-size: 0.9rem;\n color: #666;\n}\n"]}
|
static/static/{static/css β css}/main.59c2a54e.chunk.css
RENAMED
File without changes
|
static/static/{static/css β css}/main.59c2a54e.chunk.css.map
RENAMED
File without changes
|
static/static/{static/js β js}/2.abf91741.chunk.js
RENAMED
File without changes
|
static/static/{static/js β js}/2.abf91741.chunk.js.LICENSE.txt
RENAMED
File without changes
|
static/static/{static/js β js}/2.abf91741.chunk.js.map
RENAMED
File without changes
|
static/static/js/2.e4d49f63.chunk.js
ADDED
The diff for this file is too large to render.
See raw diff
|
|
static/static/js/2.e4d49f63.chunk.js.LICENSE.txt
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
object-assign
|
3 |
+
(c) Sindre Sorhus
|
4 |
+
@license MIT
|
5 |
+
*/
|
6 |
+
|
7 |
+
/**
|
8 |
+
* A better abstraction over CSS.
|
9 |
+
*
|
10 |
+
* @copyright Oleg Isonen (Slobodskoi) / Isonen 2014-present
|
11 |
+
* @website https://github.com/cssinjs/jss
|
12 |
+
* @license MIT
|
13 |
+
*/
|
14 |
+
|
15 |
+
/** @license React v0.19.1
|
16 |
+
* scheduler.production.min.js
|
17 |
+
*
|
18 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
19 |
+
*
|
20 |
+
* This source code is licensed under the MIT license found in the
|
21 |
+
* LICENSE file in the root directory of this source tree.
|
22 |
+
*/
|
23 |
+
|
24 |
+
/** @license React v16.13.1
|
25 |
+
* react-is.production.min.js
|
26 |
+
*
|
27 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
28 |
+
*
|
29 |
+
* This source code is licensed under the MIT license found in the
|
30 |
+
* LICENSE file in the root directory of this source tree.
|
31 |
+
*/
|
32 |
+
|
33 |
+
/** @license React v16.14.0
|
34 |
+
* react-dom.production.min.js
|
35 |
+
*
|
36 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
37 |
+
*
|
38 |
+
* This source code is licensed under the MIT license found in the
|
39 |
+
* LICENSE file in the root directory of this source tree.
|
40 |
+
*/
|
41 |
+
|
42 |
+
/** @license React v16.14.0
|
43 |
+
* react.production.min.js
|
44 |
+
*
|
45 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
46 |
+
*
|
47 |
+
* This source code is licensed under the MIT license found in the
|
48 |
+
* LICENSE file in the root directory of this source tree.
|
49 |
+
*/
|
50 |
+
|
51 |
+
/** @license React v17.0.2
|
52 |
+
* react-is.production.min.js
|
53 |
+
*
|
54 |
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
55 |
+
*
|
56 |
+
* This source code is licensed under the MIT license found in the
|
57 |
+
* LICENSE file in the root directory of this source tree.
|
58 |
+
*/
|
static/static/js/2.e4d49f63.chunk.js.map
ADDED
The diff for this file is too large to render.
See raw diff
|
|
static/static/js/3.10abbce4.chunk.js
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
(this["webpackJsonpvision-web-app"]=this["webpackJsonpvision-web-app"]||[]).push([[3],{181:function(t,n,e){"use strict";e.r(n),e.d(n,"getCLS",(function(){return l})),e.d(n,"getFCP",(function(){return g})),e.d(n,"getFID",(function(){return h})),e.d(n,"getLCP",(function(){return y})),e.d(n,"getTTFB",(function(){return F}));var i,a,r=function(){return"".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12)},o=function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1;return{name:t,value:n,delta:0,entries:[],id:r(),isFinal:!1}},u=function(t,n){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var e=new PerformanceObserver((function(t){return t.getEntries().map(n)}));return e.observe({type:t,buffered:!0}),e}}catch(t){}},s=!1,c=!1,p=function(t){s=!t.persisted},d=function(){addEventListener("pagehide",p),addEventListener("beforeunload",(function(){}))},f=function(t){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];c||(d(),c=!0),addEventListener("visibilitychange",(function(n){var e=n.timeStamp;"hidden"===document.visibilityState&&t({timeStamp:e,isUnloading:s})}),{capture:!0,once:n})},v=function(t,n,e,i){var a;return function(){e&&n.isFinal&&e.disconnect(),n.value>=0&&(i||n.isFinal||"hidden"===document.visibilityState)&&(n.delta=n.value-(a||0),(n.delta||n.isFinal||void 0===a)&&(t(n),a=n.value))}},l=function(t){var n,e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=o("CLS",0),a=function(t){t.hadRecentInput||(i.value+=t.value,i.entries.push(t),n())},r=u("layout-shift",a);r&&(n=v(t,i,r,e),f((function(t){var e=t.isUnloading;r.takeRecords().map(a),e&&(i.isFinal=!0),n()})))},m=function(){return void 0===i&&(i="hidden"===document.visibilityState?0:1/0,f((function(t){var n=t.timeStamp;return i=n}),!0)),{get timeStamp(){return i}}},g=function(t){var n,e=o("FCP"),i=m(),a=u("paint",(function(t){"first-contentful-paint"===t.name&&t.startTime<i.timeStamp&&(e.value=t.startTime,e.isFinal=!0,e.entries.push(t),n())}));a&&(n=v(t,e,a))},h=function(t){var n=o("FID"),e=m(),i=function(t){t.startTime<e.timeStamp&&(n.value=t.processingStart-t.startTime,n.entries.push(t),n.isFinal=!0,r())},a=u("first-input",i),r=v(t,n,a);a?f((function(){a.takeRecords().map(i),a.disconnect()}),!0):window.perfMetrics&&window.perfMetrics.onFirstInputDelay&&window.perfMetrics.onFirstInputDelay((function(t,i){i.timeStamp<e.timeStamp&&(n.value=t,n.isFinal=!0,n.entries=[{entryType:"first-input",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+t}],r())}))},S=function(){return a||(a=new Promise((function(t){return["scroll","keydown","pointerdown"].map((function(n){addEventListener(n,t,{once:!0,passive:!0,capture:!0})}))}))),a},y=function(t){var n,e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],i=o("LCP"),a=m(),r=function(t){var e=t.startTime;e<a.timeStamp?(i.value=e,i.entries.push(t)):i.isFinal=!0,n()},s=u("largest-contentful-paint",r);if(s){n=v(t,i,s,e);var c=function(){i.isFinal||(s.takeRecords().map(r),i.isFinal=!0,n())};S().then(c),f(c,!0)}},F=function(t){var n,e=o("TTFB");n=function(){try{var n=performance.getEntriesByType("navigation")[0]||function(){var t=performance.timing,n={entryType:"navigation",startTime:0};for(var e in t)"navigationStart"!==e&&"toJSON"!==e&&(n[e]=Math.max(t[e]-t.navigationStart,0));return n}();e.value=e.delta=n.responseStart,e.entries=[n],e.isFinal=!0,t(e)}catch(t){}},"complete"===document.readyState?setTimeout(n,0):addEventListener("pageshow",n)}}}]);
|
2 |
+
//# sourceMappingURL=3.10abbce4.chunk.js.map
|
static/static/js/3.10abbce4.chunk.js.map
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"version":3,"sources":["../node_modules/web-vitals/dist/web-vitals.es5.min.js"],"names":["v","t","n","e","concat","Date","now","Math","floor","random","i","arguments","length","name","value","delta","entries","id","isFinal","a","PerformanceObserver","supportedEntryTypes","includes","getEntries","map","observe","type","buffered","r","o","s","persisted","u","addEventListener","c","timeStamp","document","visibilityState","isUnloading","capture","once","l","disconnect","p","hadRecentInput","push","takeRecords","d","startTime","f","processingStart","window","perfMetrics","onFirstInputDelay","entryType","target","cancelable","m","Promise","passive","g","then","h","performance","getEntriesByType","timing","max","navigationStart","responseStart","readyState","setTimeout"],"mappings":"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","file":"static/js/3.10abbce4.chunk.js","sourcesContent":["var t,n,e=function(){return\"\".concat(Date.now(),\"-\").concat(Math.floor(8999999999999*Math.random())+1e12)},i=function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:-1;return{name:t,value:n,delta:0,entries:[],id:e(),isFinal:!1}},a=function(t,n){try{if(PerformanceObserver.supportedEntryTypes.includes(t)){var e=new PerformanceObserver((function(t){return t.getEntries().map(n)}));return e.observe({type:t,buffered:!0}),e}}catch(t){}},r=!1,o=!1,s=function(t){r=!t.persisted},u=function(){addEventListener(\"pagehide\",s),addEventListener(\"beforeunload\",(function(){}))},c=function(t){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1];o||(u(),o=!0),addEventListener(\"visibilitychange\",(function(n){var e=n.timeStamp;\"hidden\"===document.visibilityState&&t({timeStamp:e,isUnloading:r})}),{capture:!0,once:n})},l=function(t,n,e,i){var a;return function(){e&&n.isFinal&&e.disconnect(),n.value>=0&&(i||n.isFinal||\"hidden\"===document.visibilityState)&&(n.delta=n.value-(a||0),(n.delta||n.isFinal||void 0===a)&&(t(n),a=n.value))}},p=function(t){var n,e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=i(\"CLS\",0),o=function(t){t.hadRecentInput||(r.value+=t.value,r.entries.push(t),n())},s=a(\"layout-shift\",o);s&&(n=l(t,r,s,e),c((function(t){var e=t.isUnloading;s.takeRecords().map(o),e&&(r.isFinal=!0),n()})))},d=function(){return void 0===t&&(t=\"hidden\"===document.visibilityState?0:1/0,c((function(n){var e=n.timeStamp;return t=e}),!0)),{get timeStamp(){return t}}},v=function(t){var n,e=i(\"FCP\"),r=d(),o=a(\"paint\",(function(t){\"first-contentful-paint\"===t.name&&t.startTime<r.timeStamp&&(e.value=t.startTime,e.isFinal=!0,e.entries.push(t),n())}));o&&(n=l(t,e,o))},f=function(t){var n=i(\"FID\"),e=d(),r=function(t){t.startTime<e.timeStamp&&(n.value=t.processingStart-t.startTime,n.entries.push(t),n.isFinal=!0,s())},o=a(\"first-input\",r),s=l(t,n,o);o?c((function(){o.takeRecords().map(r),o.disconnect()}),!0):window.perfMetrics&&window.perfMetrics.onFirstInputDelay&&window.perfMetrics.onFirstInputDelay((function(t,i){i.timeStamp<e.timeStamp&&(n.value=t,n.isFinal=!0,n.entries=[{entryType:\"first-input\",name:i.type,target:i.target,cancelable:i.cancelable,startTime:i.timeStamp,processingStart:i.timeStamp+t}],s())}))},m=function(){return n||(n=new Promise((function(t){return[\"scroll\",\"keydown\",\"pointerdown\"].map((function(n){addEventListener(n,t,{once:!0,passive:!0,capture:!0})}))}))),n},g=function(t){var n,e=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=i(\"LCP\"),o=d(),s=function(t){var e=t.startTime;e<o.timeStamp?(r.value=e,r.entries.push(t)):r.isFinal=!0,n()},u=a(\"largest-contentful-paint\",s);if(u){n=l(t,r,u,e);var p=function(){r.isFinal||(u.takeRecords().map(s),r.isFinal=!0,n())};m().then(p),c(p,!0)}},h=function(t){var n,e=i(\"TTFB\");n=function(){try{var n=performance.getEntriesByType(\"navigation\")[0]||function(){var t=performance.timing,n={entryType:\"navigation\",startTime:0};for(var e in t)\"navigationStart\"!==e&&\"toJSON\"!==e&&(n[e]=Math.max(t[e]-t.navigationStart,0));return n}();e.value=e.delta=n.responseStart,e.entries=[n],e.isFinal=!0,t(e)}catch(t){}},\"complete\"===document.readyState?setTimeout(n,0):addEventListener(\"pageshow\",n)};export{p as getCLS,v as getFCP,f as getFID,g as getLCP,h as getTTFB};\n"],"sourceRoot":""}
|
static/static/{static/js β js}/3.9013e23f.chunk.js
RENAMED
File without changes
|
static/static/{static/js β js}/3.9013e23f.chunk.js.map
RENAMED
File without changes
|
static/static/js/main.3e9c0e32.chunk.js
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
(this["webpackJsonpvision-web-app"]=this["webpackJsonpvision-web-app"]||[]).push([[0],{104:function(e,a,t){},105:function(e,a,t){"use strict";t.r(a);var n=t(0),r=t.n(n),l=t(11),o=t.n(l),c=(t(99),t(79)),i=t(165),s=t(169),m=t(166),d=t(167),u=t(49),g=t(171),p=t(161),E=t(168),y=t(142),b=t(83),f=t(147),h=t(140),v=t(141),x=t(65),S=t.n(x),C=t(76),j=t.n(C),w=t(137);const P=Object(w.a)(e=>({paper:{padding:e.spacing(2),display:"flex",flexDirection:"column",alignItems:"center",height:"100%",minHeight:300,transition:"all 0.3s ease"},dragActive:{border:"2px dashed #3f51b5",backgroundColor:"rgba(63, 81, 181, 0.05)"},dragInactive:{border:"2px dashed #ccc",backgroundColor:"white"},uploadBox:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",height:"100%",width:"100%",cursor:"pointer"},uploadIcon:{fontSize:60,color:"#3f51b5",marginBottom:e.spacing(2)},supportText:{marginTop:e.spacing(2)},previewBox:{display:"flex",flexDirection:"column",alignItems:"center",width:"100%",height:"100%",position:"relative"},imageContainer:{position:"relative",width:"100%",height:"45vh",[e.breakpoints.down("sm")]:{height:"35vh"},display:"flex",justifyContent:"center",alignItems:"center",overflow:"hidden",marginTop:e.spacing(2)},deleteButton:{position:"absolute",top:0,right:0,backgroundColor:"rgba(255, 255, 255, 0.7)","&:hover":{backgroundColor:"rgba(255, 255, 255, 0.9)"}}}));var I=e=>{let{onImageUpload:a}=e;const t=P(),[l,o]=Object(n.useState)(null),[c,i]=Object(n.useState)(!1),m=Object(n.useRef)(null),d=e=>{e.preventDefault(),e.stopPropagation(),"dragenter"===e.type||"dragover"===e.type?i(!0):"dragleave"===e.type&&i(!1)},g=e=>{e.type.startsWith("image/")?(o(URL.createObjectURL(e)),a(e)):alert("Please upload an image file")};return r.a.createElement(b.a,{className:"".concat(t.paper," ").concat(c?t.dragActive:t.dragInactive),onDragEnter:d,onDragLeave:d,onDragOver:d,onDrop:e=>{e.preventDefault(),e.stopPropagation(),i(!1),e.dataTransfer.files&&e.dataTransfer.files[0]&&g(e.dataTransfer.files[0])}},r.a.createElement("input",{ref:m,type:"file",accept:"image/*",onChange:e=>{e.preventDefault(),e.target.files&&e.target.files[0]&&g(e.target.files[0])},style:{display:"none"}}),l?r.a.createElement(s.a,{className:t.previewBox},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Preview"),r.a.createElement(s.a,{className:t.imageContainer},r.a.createElement("img",{src:l,alt:"Preview",className:"preview-image",style:{maxWidth:"100%",maxHeight:"100%",width:"auto",height:"auto",objectFit:"contain",display:"block"}}),r.a.createElement(v.a,{"aria-label":"delete",className:t.deleteButton,onClick:()=>{o(null),a(null),m.current.value=""}},r.a.createElement(j.a,null)))):r.a.createElement(s.a,{className:t.uploadBox,onClick:()=>{m.current.click()}},r.a.createElement(S.a,{className:t.uploadIcon}),r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Drag & Drop an image here"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary",gutterBottom:!0},"or"),r.a.createElement(h.a,{variant:"contained",color:"primary",component:"span",startIcon:r.a.createElement(S.a,null)},"Browse Files"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary",className:t.supportText},"Supported formats: JPG, PNG, GIF")))},N=t(143),T=t(144),O=t(176),B=t(145),A=t(66),k=t.n(A),D=t(77),R=t.n(D),F=t(78),L=t.n(F);const z=Object(w.a)(e=>({card:{height:"100%",display:"flex",flexDirection:"column"},selectedCard:{border:"2px solid #3f51b5"},unavailableCard:{opacity:.6},cardContent:{flexGrow:1},chipContainer:{marginBottom:e.spacing(1.5)},successChip:{backgroundColor:"#34C759",color:"#fff"},errorChip:{backgroundColor:"#FF3B3F",color:"#fff"},modelType:{marginTop:e.spacing(1)},processButton:{marginTop:e.spacing(3),textAlign:"center"}}));var _=e=>{let{onModelSelect:a,onProcess:t,isProcessing:n,modelsStatus:l,selectedModel:o,imageSelected:c}=e;const i=z(),m=[{id:"yolo",name:"YOLOv8",description:"Fast and accurate object detection",icon:r.a.createElement(k.a,null),available:l.yolo},{id:"detr",name:"DETR",description:"DEtection TRansformer for object detection",icon:r.a.createElement(k.a,null),available:l.detr},{id:"vit",name:"ViT",description:"Vision Transformer for image classification",icon:r.a.createElement(R.a,null),available:l.vit}],d=e=>{m.find(a=>a.id===e).available&&a(e)};return r.a.createElement(s.a,{sx:{p:2,height:"100%"}},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Select Model"),r.a.createElement(y.a,{container:!0,spacing:2},m.map(e=>r.a.createElement(y.a,{item:!0,xs:12,sm:4,key:e.id},r.a.createElement(N.a,{className:"\n ".concat(i.card," \n ").concat(o===e.id?i.selectedCard:""," \n ").concat(e.available?"":i.unavailableCard,"\n "),onClick:()=>d(e.id)},r.a.createElement(T.a,{className:i.cardContent},r.a.createElement(s.a,{sx:{mb:2,color:"primary"}},e.icon),r.a.createElement(u.a,{variant:"h5",component:"div",gutterBottom:!0},e.name),r.a.createElement("div",{className:i.chipContainer},e.available?r.a.createElement(O.a,{label:"Available",className:i.successChip,size:"small"}):r.a.createElement(O.a,{label:"Not Available",className:i.errorChip,size:"small"})),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},e.description)),r.a.createElement(B.a,null,r.a.createElement(h.a,{size:"small",onClick:()=>d(e.id),disabled:!e.available,color:o===e.id?"primary":"default",variant:o===e.id?"contained":"outlined",fullWidth:!0},o===e.id?"Selected":"Select")))))),r.a.createElement("div",{className:i.processButton},r.a.createElement(h.a,{variant:"contained",color:"primary",size:"large",startIcon:r.a.createElement(L.a,null),onClick:t,disabled:!o||!c||n},n?"Processing...":"Process Image")))},W=t(157),M=t(154),V=t(107),U=t(158),H=t(146),J=t(174),G=t(175),Y=t(149),q=t(150),K=t(151),Q=t(177),X=t(170),Z=t(155),$=t(179),ee=t(156),ae=t(173);const te=Object(w.a)(e=>({root:{marginTop:e.spacing(2),marginBottom:e.spacing(2),padding:e.spacing(2),backgroundColor:"#f5f5f5",borderRadius:e.shape.borderRadius},button:{marginRight:e.spacing(2)},searchDialog:{minWidth:"500px"},formControl:{marginBottom:e.spacing(2),minWidth:"100%"},searchResults:{marginTop:e.spacing(2)},resultCard:{marginBottom:e.spacing(2)},resultImage:{height:140,objectFit:"contain"},chip:{margin:e.spacing(.5)},similarityChip:{backgroundColor:e.palette.primary.main,color:"white"}}));var ne=e=>{let{results:a}=e;const t=te(),[l,o]=Object(n.useState)(!1),[c,i]=Object(n.useState)(!1),[m,d]=Object(n.useState)(null),[g,p]=Object(n.useState)(!1),[E,b]=Object(n.useState)("image"),[v,x]=Object(n.useState)(""),[S,C]=Object(n.useState)([]),[j,w]=Object(n.useState)(!1),[P,I]=Object(n.useState)(null),{model:B,data:A}=a,k=()=>{p(!1)},D=()=>"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(e){const a=16*Math.random()|0;return("x"===e?a:3&a|8).toString(16)}));return r.a.createElement(s.a,{className:t.root},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Vector Database Actions"),r.a.createElement(s.a,{display:"flex",alignItems:"center",mb:2},r.a.createElement(h.a,{variant:"contained",color:"primary",onClick:async()=>{o(!0),d(null);try{let e;if(e="vit"===B?await fetch("/api/add-to-collection",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image:A.image,metadata:{model:"vit",classifications:A.classifications}})}):await fetch("/api/add-detected-objects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image:A.image,objects:A.detections,imageId:D()})}),!e.ok)throw new Error("HTTP error! Status: ".concat(e.status));const a=await e.json();if(a.error)throw new Error(a.error);i(!0),setTimeout(()=>i(!1),5e3)}catch(e){console.error("Error saving to vector DB:",e),d("Error saving to vector DB: ".concat(e.message))}finally{o(!1)}},disabled:l,className:t.button},l?r.a.createElement(r.a.Fragment,null,r.a.createElement(f.a,{size:20,color:"inherit",style:{marginRight:8}}),"Saving..."):"Save to Vector DB"),r.a.createElement(h.a,{variant:"outlined",color:"primary",onClick:()=>{p(!0),C([]),I(null)},className:t.button},"Search Similar")),m&&r.a.createElement(ae.a,{severity:"error",style:{marginTop:8}},m),r.a.createElement(J.a,{open:c,autoHideDuration:5e3,onClose:()=>i(!1)},r.a.createElement(ae.a,{severity:"success"},"vit"===B?"Image and classifications successfully saved to vector DB!":"Detected objects successfully saved to vector DB!")),r.a.createElement(G.a,{open:g,onClose:k,maxWidth:"md",fullWidth:!0},r.a.createElement(Y.a,null,"Search Vector Database"),r.a.createElement(q.a,null,r.a.createElement(K.a,{className:t.formControl},r.a.createElement(Q.a,{id:"search-type-label"},"Search Type"),r.a.createElement(X.a,{labelId:"search-type-label",id:"search-type",value:E,onChange:e=>{b(e.target.value),C([]),I(null)}},r.a.createElement(Z.a,{value:"image"},"Search by Current Image"),r.a.createElement(Z.a,{value:"class"},"Search by Class Name"))),"class"===E&&r.a.createElement(K.a,{className:t.formControl},r.a.createElement($.a,{label:"Class Name",value:v,onChange:e=>{x(e.target.value)},placeholder:"e.g. person, car, dog...",fullWidth:!0})),P&&r.a.createElement(ae.a,{severity:"error",style:{marginBottom:16}},P),r.a.createElement(s.a,{className:t.searchResults},j?r.a.createElement(s.a,{display:"flex",justifyContent:"center",alignItems:"center",p:4},r.a.createElement(f.a,null),r.a.createElement(u.a,{variant:"body1",style:{marginLeft:16}},"Searching...")):r.a.createElement(r.a.Fragment,null,console.log("Search dialog render - searchResults:",S),S.length>0?(console.log("Rendering search results:",S),console.log("Search results length:",S.length),0===S.length?(console.log("No results to render"),r.a.createElement(u.a,{variant:"body1"},"No results found.")):r.a.createElement(y.a,{container:!0,spacing:2},S.map((e,a)=>{const n=100*(1-e.distance);return r.a.createElement(y.a,{item:!0,xs:12,sm:6,key:a},r.a.createElement(N.a,{className:t.resultCard},e.metadata&&e.metadata.image_data?r.a.createElement(H.a,{className:t.resultImage,component:"img",height:"200",image:"data:image/jpeg;base64,".concat(e.metadata.image_data),alt:e.metadata&&e.metadata.class?e.metadata.class:"Object"}):r.a.createElement(s.a,{className:t.resultImage,style:{backgroundColor:"#f0f0f0",display:"flex",alignItems:"center",justifyContent:"center",height:200}},r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},e.metadata&&e.metadata.class?e.metadata.class:"Object"," Image")),r.a.createElement(T.a,null,r.a.createElement(s.a,{display:"flex",justifyContent:"space-between",alignItems:"center",mb:1},r.a.createElement(u.a,{variant:"subtitle1"},"Result #",a+1),r.a.createElement(O.a,{label:"Similarity: ".concat(n.toFixed(2),"%"),className:t.similarityChip,size:"small"})),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},r.a.createElement("strong",null,"Class:")," ",e.metadata.class||"N/A"),e.metadata.confidence&&r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},r.a.createElement("strong",null,"Confidence:")," ",(100*e.metadata.confidence).toFixed(2),"%"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},r.a.createElement("strong",null,"Object ID:")," ",e.id))))}))):r.a.createElement(u.a,{variant:"body1"},"No results found. Please try another search.")))),r.a.createElement(ee.a,null,r.a.createElement(h.a,{onClick:k,color:"default"},"Close"),r.a.createElement(h.a,{onClick:async()=>{w(!0),I(null);try{let e={};if("image"===E)e={searchType:"image",image:A.image,n_results:5};else{if(!v.trim())throw new Error("Please enter a class name");e={searchType:"class",class_name:v.trim(),n_results:5}}const a=await fetch("/api/search-similar-objects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!a.ok)throw new Error("HTTP error! Status: ".concat(a.status));const t=await a.json();if(t.error)throw new Error(t.error);if(console.log("Search API response:",t),!t.success||!Array.isArray(t.results))throw console.error("Unexpected API response format:",t),new Error("Unexpected API response format");console.log("Setting search results array:",t.results),console.log("Results array length:",t.results.length),console.log("First result item:",t.results[0]),C(t.results)}catch(e){console.error("Error searching vector DB:",e),I("Error searching vector DB: ".concat(e.message))}finally{w(!1)}},color:"primary",variant:"contained",disabled:j||"class"===E&&!v.trim()},"Search"))))};const re=Object(w.a)(e=>({paper:{padding:e.spacing(2)},marginBottom:{marginBottom:e.spacing(2)},resultImage:{maxWidth:"100%",maxHeight:"400px",objectFit:"contain"},dividerMargin:{margin:"".concat(e.spacing(2),"px 0")},chipContainer:{display:"flex",gap:e.spacing(1),flexWrap:"wrap"}}));var le=e=>{let{results:a}=e;const t=re();if(!a)return null;const{model:n,data:l}=a;if(l.error)return r.a.createElement(b.a,{sx:{p:2,bgcolor:"#ffebee"}},r.a.createElement(u.a,{color:"error"},l.error));const o=()=>l.performance?r.a.createElement(s.a,{className:"performance-info"},r.a.createElement(W.a,{className:t.dividerMargin}),r.a.createElement(u.a,{variant:"body2"},"Inference time: ",(e=>{if(void 0===e||null===e||isNaN(e))return"-";const a=Number(e);return a<1e3?"".concat(a.toFixed(2)," ms"):"".concat((a/1e3).toFixed(2)," s")})(l.performance.inference_time)," on ",l.performance.device)):null;return"yolo"===n||"detr"===n?r.a.createElement(b.a,{className:t.paper},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"yolo"===n?"YOLOv8":"DETR"," Detection Results"),r.a.createElement(y.a,{container:!0,spacing:3},r.a.createElement(y.a,{item:!0,xs:12,md:6},l.image&&r.a.createElement(s.a,{className:t.marginBottom},r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Detection Result"),r.a.createElement("img",{src:"data:image/png;base64,".concat(l.image),alt:"Detection Result",className:t.resultImage}))),r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement(s.a,{className:t.marginBottom},r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Detected Objects:"),l.detections&&l.detections.length>0?r.a.createElement(M.a,null,l.detections.map((e,a)=>r.a.createElement(r.a.Fragment,{key:a},r.a.createElement(V.a,null,r.a.createElement(U.a,{primary:r.a.createElement(s.a,{style:{display:"flex",alignItems:"center"}},r.a.createElement(u.a,{variant:"body1",component:"span"},e.class),r.a.createElement(O.a,{label:"".concat((100*e.confidence).toFixed(0),"%"),size:"small",color:"primary",style:{marginLeft:8}})),secondary:"Bounding Box: [".concat(e.bbox.join(", "),"]")})),a<l.detections.length-1&&r.a.createElement(W.a,null)))):r.a.createElement(u.a,{variant:"body1"},"No objects detected")))),o(),r.a.createElement(ne,{results:a})):"vit"===n?r.a.createElement(b.a,{className:t.paper},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"ViT Classification Results"),r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Top Predictions:"),l.top_predictions&&l.top_predictions.length>0?r.a.createElement(M.a,null,l.top_predictions.map((e,a)=>r.a.createElement(r.a.Fragment,{key:a},r.a.createElement(V.a,null,r.a.createElement(U.a,{primary:r.a.createElement(s.a,{style:{display:"flex",alignItems:"center"}},r.a.createElement(u.a,{variant:"body1",component:"span"},e.rank,". ",e.class),r.a.createElement(O.a,{label:"".concat((100*e.probability).toFixed(1),"%"),size:"small",color:0===a?"primary":"default",style:{marginLeft:8}}))})),a<l.top_predictions.length-1&&r.a.createElement(W.a,null)))):r.a.createElement(u.a,{variant:"body1"},"No classifications available"),o(),r.a.createElement(ne,{results:a})):null};const oe=Object(w.a)(e=>({paper:{padding:e.spacing(2),marginTop:e.spacing(2)},marginBottom:{marginBottom:e.spacing(2)},dividerMargin:{margin:"".concat(e.spacing(2),"px 0")},responseBox:{padding:e.spacing(2),backgroundColor:"#f5f5f5",borderRadius:e.shape.borderRadius,marginTop:e.spacing(2),whiteSpace:"pre-wrap"},buttonProgress:{marginLeft:e.spacing(1)}}));var ce=e=>{let{visionResults:a,model:t}=e;const l=oe(),[o,c]=Object(n.useState)(""),[i,m]=Object(n.useState)(!1),[d,g]=Object(n.useState)(null),[p,E]=Object(n.useState)(null);return a?r.a.createElement(b.a,{className:l.paper},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Ask AI about the ","vit"===t?"Classification":"Detection"," Results"),r.a.createElement(u.a,{variant:"body2",className:l.marginBottom},"Ask a question about the detected objects or classifications to get an AI-powered analysis."),r.a.createElement($.a,{fullWidth:!0,label:"Your question about the image",variant:"outlined",value:o,onChange:e=>c(e.target.value),disabled:i,className:l.marginBottom,placeholder:"vit"===t?"E.g., What category does this image belong to?":"E.g., How many people are in this image?"}),r.a.createElement(h.a,{variant:"contained",color:"primary",onClick:async()=>{if(o.trim()){m(!0),E(null);try{const e=await fetch("/api/analyze",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({visionResults:a,userQuery:o})});if(!e.ok)throw new Error("HTTP error! Status: ".concat(e.status));const t=await e.json();t.error?E(t.error):g(t)}catch(e){console.error("Error analyzing with LLM:",e),E("Error analyzing with LLM: ".concat(e.message))}finally{m(!1)}}},disabled:i||!o.trim()},"Analyze with AI",i&&r.a.createElement(f.a,{size:24,className:l.buttonProgress})),p&&r.a.createElement(s.a,{mt:2},r.a.createElement(u.a,{color:"error"},p)),d&&r.a.createElement(r.a.Fragment,null,r.a.createElement(W.a,{className:l.dividerMargin}),r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"AI Analysis:"),r.a.createElement(s.a,{className:l.responseBox},r.a.createElement(u.a,{variant:"body1"},d.response)),d.performance&&r.a.createElement(s.a,{mt:1},r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},"Analysis time: ",(e=>{if(void 0===e||null===e||isNaN(e))return"-";const a=Number(e);return a<1e3?"".concat(a.toFixed(2)," ms"):"".concat((a/1e3).toFixed(2)," s")})(d.performance.inference_time)," on ",d.performance.device)))):null};var ie=function(e){let{imageBase64:a}=e;const[t,l]=Object(n.useState)(""),[o,c]=Object(n.useState)(""),[i,s]=Object(n.useState)(""),[m,d]=Object(n.useState)(!1),[g,p]=Object(n.useState)(""),[E,f]=Object(n.useState)("image"),[v,x]=Object(n.useState)(""),[S,C]=Object(n.useState)(""),[j,w]=Object(n.useState)(5);return r.a.createElement(b.a,{style:{padding:16}},r.a.createElement(u.a,{variant:"h5",gutterBottom:!0},"Vision RAG (LangChain)"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary",gutterBottom:!0},"If OPENAI_API_KEY is set on the server, API Key is optional. Select a search type and send a question to get answers based on context retrieved from the vector DB."),r.a.createElement(y.a,{container:!0,spacing:2},r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement(K.a,{fullWidth:!0,variant:"outlined",size:"small"},r.a.createElement(Q.a,{id:"search-type-label"},"Search Type"),r.a.createElement(X.a,{labelId:"search-type-label",value:E,onChange:e=>f(e.target.value),label:"Search Type"},r.a.createElement(Z.a,{value:"image"},"image (current upload)"),r.a.createElement(Z.a,{value:"object"},"object (objectId)"),r.a.createElement(Z.a,{value:"class"},"class (class_name)")))),r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement($.a,{label:"OpenAI API Key (optional)",value:t,onChange:e=>l(e.target.value),fullWidth:!0,variant:"outlined",size:"small",type:"password",placeholder:"sk-..."})),"object"===E&&r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement($.a,{label:"objectId",value:v,onChange:e=>x(e.target.value),fullWidth:!0,variant:"outlined",size:"small"})),"class"===E&&r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement($.a,{label:"class_name",value:S,onChange:e=>C(e.target.value),fullWidth:!0,variant:"outlined",size:"small",placeholder:"e.g. person, car, dog"})),r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement($.a,{label:"n_results",value:j,onChange:e=>w(e.target.value),fullWidth:!0,variant:"outlined",size:"small",type:"number",inputProps:{min:1,max:50}})),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement($.a,{label:"User Question",value:o,onChange:e=>c(e.target.value),fullWidth:!0,multiline:!0,rows:4,variant:"outlined",placeholder:"image"===E?"Answer based on the uploaded image":"Answer using the retrieved object context"})),g&&r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(u.a,{color:"error"},g)),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement("div",{style:{display:"flex",gap:8}},r.a.createElement(h.a,{color:"primary",variant:"contained",onClick:async()=>{p(""),s("");const e=(o||"").trim();if(!e)return void p("Please enter a question.");const n={userQuery:e,searchType:E,n_results:Number(j)||5};if(t&&(n.api_key=t),"image"===E){if(!a)return void p("Image is required. Please upload an image first.");n.image=a}else if("object"===E){if(!v.trim())return void p("Please enter an objectId.");n.objectId=v.trim()}else if("class"===E){if(!S.trim())return void p("Please enter a class_name.");n.class_name=S.trim()}d(!0);try{const e=await fetch("/api/vision-rag/query",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(n)});if(!e.ok){let a=await e.text();try{a=JSON.stringify(JSON.parse(a),null,2)}catch(r){}throw new Error(a)}const a=await e.json(),t="Model: ".concat(a.model||"-"," | Latency: ").concat(a.latency_sec||"-","s");let l="";a.retrieved&&a.retrieved.length>0&&(l="\n\nSearch Results:\n",a.retrieved.forEach((e,a)=>{l+="".concat(a+1,". ID: ").concat(e.id||"-","\n"),e.meta&&(l+=" Class: ".concat(e.meta.class||"-","\n"),l+=" Confidence: ".concat(e.meta.confidence||"-","\n")),l+=" Similarity: ".concat(e.distance?e.distance.toFixed(4):"-","\n")})),s((a.answer||"(No response)")+l+"\n\n---\n"+t)}catch(l){p("Error: "+l.message)}finally{d(!1)}},disabled:m},m?"Sending...":"Send Question"),r.a.createElement(h.a,{variant:"outlined",onClick:()=>{c(""),s(""),p("")}},"Clear"))),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(W.a,{style:{margin:"12px 0"}}),r.a.createElement(u.a,{variant:"subtitle2",color:"textSecondary"},"Response"),r.a.createElement("pre",{style:{whiteSpace:"pre-wrap",fontFamily:"ui-monospace, monospace"}},i))))},se=(t(80),t(159)),me=t(160),de=t(162),ue=t(163),ge=t(164);const pe=Object(w.a)(e=>({root:{marginTop:e.spacing(3),marginBottom:e.spacing(3)},imageContainer:{position:"relative",minHeight:"360px",display:"flex",justifyContent:"center",alignItems:"center",border:"2px dashed #ccc",borderRadius:"8px",margin:e.spacing(1),padding:e.spacing(1),backgroundColor:"#fafafa",overflow:"hidden"},progressLog:{marginTop:e.spacing(2),height:"200px",overflowY:"auto",backgroundColor:"#f8f9fa",padding:e.spacing(1),borderRadius:"4px",fontFamily:"monospace",fontSize:"0.9rem"},logEntry:{margin:"4px 0",padding:"2px 5px",borderLeft:"3px solid #ccc"},logEntryAgent:{borderLeft:"3px solid #2196f3"},logEntrySystem:{borderLeft:"3px solid #4caf50"},logEntryError:{borderLeft:"3px solid #f44336"},logTime:{color:"#666",fontSize:"0.8rem",marginRight:e.spacing(1)},imagePreview:{width:"100%",height:"auto",maxHeight:"60vh",objectFit:"contain"},uploadIcon:{fontSize:"3rem",color:"#aaa"},uploadInput:{display:"none"},deleteButton:{position:"absolute",top:"8px",right:"8px",backgroundColor:"rgba(255, 255, 255, 0.8)","&:hover":{backgroundColor:"rgba(255, 255, 255, 0.9)"}},tabPanel:{padding:e.spacing(2)},resultCard:{marginTop:e.spacing(2),marginBottom:e.spacing(2)},comparisonTable:{width:"100%",borderCollapse:"collapse","& th, & td":{border:"1px solid #ddd",padding:"8px",textAlign:"left"},"& th":{backgroundColor:"#f2f2f2"},"& tr:nth-child(even)":{backgroundColor:"#f9f9f9"}},loadingContainer:{display:"flex",flexDirection:"column",alignItems:"center",padding:e.spacing(4)},highlight:{backgroundColor:"#e3f2fd",padding:e.spacing(1),borderRadius:"4px",fontWeight:"bold"}}));var Ee=()=>{const e=pe(),[a,t]=Object(n.useState)([null,null]),[l,o]=Object(n.useState)([null,null]),[c,i]=Object(n.useState)(!1),[m,d]=Object(n.useState)(null),[E,x]=Object(n.useState)(null),[S,C]=Object(n.useState)(0),[j,w]=Object(n.useState)([]),P=Object(n.useRef)(null),I=function(e){let a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"info";const t=new Date,n=t.toLocaleTimeString(),r={time:n,message:e,type:a};w(e=>[...e,r])};Object(n.useEffect)(()=>{P.current&&P.current.scrollIntoView({behavior:"smooth"})},[j]);const O=e=>{const a=new EventSource("/api/product/compare/stream/".concat(e));return a.onmessage=e=>{try{const t=JSON.parse(e.data);t.message&&I(t.message,t.agent||"info"),t.final_result&&(d(t.final_result),i(!1),a.close())}catch(t){I("Event processing error: ".concat(t.message),"error")}},a.onerror=e=>{I("Server connection lost. Please try again in a moment.","error"),a.close(),i(!1)},a},B=async function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;if(a[0]||a[1]){i(!0),x(null),w([]),I("Starting product analysis...","system");try{const t=new FormData;a[0]&&(t.append("image1",a[0]),I("Product A image uploaded.","info")),a[1]&&(t.append("image2",a[1]),I("Product B image uploaded.","info"));const n=["info","compare","value","recommend"],r=e||n[S];t.append("analysisType",r),I("Analysis type: ".concat("info"===r?"Product Information":"compare"===r?"Performance Comparison":"value"===r?"Value Analysis":"Purchase Recommendation"),"system"),I("Initializing analysis session...","system");for(let[e,a]of t.entries())console.log("FormData:",e,a);const l=await fetch("/api/product/compare/start",{method:"POST",body:t,credentials:"include"});if(console.log("Response status:",l.status),console.log("Response headers:",l.headers),!l.ok){const e=await l.text();throw console.error("Error response:",e),new Error("HTTP error! Status: ".concat(l.status," - ").concat(e))}const o=(await l.json()).session_id;if(!o)throw new Error("Failed to receive session ID");I("Analysis session started. (Session ID: ".concat(o.substring(0,8),"...)"),"system"),I("Agents are collaborating to analyze products. Please wait a moment...","system");const c=O(o);return()=>{c.close()}}catch(t){console.error("\uc81c\ud488 \ubd84\uc11d \uc624\ub958:",t),I("Error occurred: ".concat(t.message),"error"),x("Error during analysis: ".concat(t.message)),i(!1)}}else x("Please upload at least one product image for analysis")};return r.a.createElement(b.a,{className:e.root},r.a.createElement(s.a,{p:3},r.a.createElement(u.a,{variant:"h5",gutterBottom:!0},"Product Comparison Analysis"),r.a.createElement(u.a,{variant:"body1",paragraph:!0},"Upload product images to receive detailed information and comparison analysis. You can analyze various products including cars, smartphones, laptops, and more."),r.a.createElement(y.a,{container:!0,spacing:3},[0,1].map(n=>r.a.createElement(y.a,{item:!0,xs:12,md:6,key:n},r.a.createElement(s.a,{className:e.imageContainer},l[n]?r.a.createElement(r.a.Fragment,null,r.a.createElement("img",{src:l[n],alt:"Product ".concat(n+1),className:e.imagePreview}),r.a.createElement(v.a,{className:e.deleteButton,onClick:()=>(e=>{const n=[...a],r=[...l];n[e]=null,r[e]=null,t(n),o(r),d(null)})(n)},r.a.createElement(se.a,null))):r.a.createElement(r.a.Fragment,null,r.a.createElement("input",{accept:"image/*",className:e.uploadInput,id:"upload-image-".concat(n),type:"file",onChange:e=>((e,n)=>{const r=e.target.files[0];if(r){const e=new FileReader;e.onload=e=>{const a=[...l];a[n]=e.target.result,o(a)},e.readAsDataURL(r);const c=[...a];c[n]=r,t(c),d(null),x(null)}})(e,n)}),r.a.createElement("label",{htmlFor:"upload-image-".concat(n)},r.a.createElement(s.a,{display:"flex",flexDirection:"column",alignItems:"center"},r.a.createElement(me.a,{className:e.uploadIcon}),r.a.createElement(u.a,{variant:"body2",style:{marginTop:"8px"}},"Upload ",0===n?"Product A":"Product B"," Image"))))))),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement("input",{accept:"image/*",className:e.uploadInput,id:"upload-both-images",type:"file",multiple:!0,onChange:e=>{const n=Array.from(e.target.files||[]);if(!n.length)return;const r=[...a],c=[...l];n.slice(0,2).forEach((e,a)=>{const t=a;r[t]=e;const n=new FileReader;n.onload=e=>{c[t]=e.target.result,o([...c])},n.readAsDataURL(e)}),t(r),d(null),x(null)}}),r.a.createElement("label",{htmlFor:"upload-both-images"},r.a.createElement(h.a,{variant:"text",color:"default",component:"span"},"Or select two files at once"))),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(b.a,null,r.a.createElement(g.a,{value:S,onChange:(e,a)=>{C(a)},indicatorColor:"primary",textColor:"primary",centered:!0},r.a.createElement(p.a,{icon:r.a.createElement(de.a,null),label:"Product Info"}),r.a.createElement(p.a,{icon:r.a.createElement(ue.a,null),label:"Performance",disabled:!a[0]||!a[1]}),r.a.createElement(p.a,{icon:r.a.createElement(ge.a,null),label:"Value Analysis"}),r.a.createElement(p.a,{label:"Recommendations"})),r.a.createElement(s.a,{p:2,display:"flex",justifyContent:"center",gridGap:12},r.a.createElement(h.a,{variant:"contained",color:"primary",onClick:()=>B(null),disabled:c||!a[0]&&!a[1],startIcon:c?r.a.createElement(f.a,{size:24}):null},c?"Analyzing...":"Start Analysis"),r.a.createElement(h.a,{variant:"outlined",color:"secondary",onClick:()=>B("compare"),disabled:c||!a[0]||!a[1],startIcon:r.a.createElement(ue.a,null)},"Compare Products")),E&&r.a.createElement(s.a,{p:2,bgcolor:"#ffebee",borderRadius:"4px",mb:2},r.a.createElement(u.a,{color:"error"},E)))),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(b.a,null,r.a.createElement(s.a,{p:2},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Analysis Progress"),r.a.createElement(s.a,{className:e.progressLog},0===j.length?r.a.createElement(u.a,{variant:"body2",color:"textSecondary",style:{padding:"10px"}},"Progress details will appear here when analysis starts."):j.map((a,t)=>r.a.createElement(s.a,{key:t,className:"".concat(e.logEntry," ").concat("agent"===a.type?e.logEntryAgent:"system"===a.type?e.logEntrySystem:"error"===a.type?e.logEntryError:"")},r.a.createElement("span",{className:e.logTime},"[",a.time,"]"),a.message)),r.a.createElement("div",{ref:P}))))),r.a.createElement(y.a,{item:!0,xs:12},c?r.a.createElement(s.a,{className:e.loadingContainer},r.a.createElement(f.a,null),r.a.createElement(u.a,{variant:"h6",style:{marginTop:"16px"}},"Analyzing Products..."),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},"Product recognition, information retrieval, and comparison analysis in progress.")):(()=>{if(!m)return null;switch(S){case 0:return r.a.createElement(N.a,{className:e.resultCard},r.a.createElement(T.a,null,r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Product Information"),r.a.createElement(W.a,{style:{margin:"8px 0 16px"}}),m.productInfo&&r.a.createElement("div",null,r.a.createElement(u.a,{variant:"subtitle1"},r.a.createElement("strong",null,"Product Name:")," ",m.productInfo.name),r.a.createElement(u.a,{variant:"body1"},r.a.createElement("strong",null,"Brand:")," ",m.productInfo.brand),r.a.createElement(u.a,{variant:"body1"},r.a.createElement("strong",null,"Category:")," ",m.productInfo.category),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Key Specifications"),r.a.createElement("ul",null,m.productInfo.specs.map((e,a)=>r.a.createElement("li",{key:a},r.a.createElement(u.a,{variant:"body2"},r.a.createElement("strong",null,e.name,":")," ",e.value)))),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Pros"),r.a.createElement("ul",null,m.productInfo.pros.map((e,a)=>r.a.createElement("li",{key:a},r.a.createElement(u.a,{variant:"body2"},e)))),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Cons"),r.a.createElement("ul",null,m.productInfo.cons.map((e,a)=>r.a.createElement("li",{key:a},r.a.createElement(u.a,{variant:"body2"},e)))))));case 1:return r.a.createElement(N.a,{className:e.resultCard},r.a.createElement(T.a,null,r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Product Comparison Analysis"),r.a.createElement(W.a,{style:{margin:"8px 0 16px"}}),m.comparison&&r.a.createElement("div",null,r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Product Specification Comparison"),r.a.createElement("table",{className:e.comparisonTable},r.a.createElement("thead",null,r.a.createElement("tr",null,r.a.createElement("th",null,"Feature"),r.a.createElement("th",null,"Product A"),r.a.createElement("th",null,"Product B"),r.a.createElement("th",null,"Comparison"))),r.a.createElement("tbody",null,m.comparison.specs.map((a,t)=>r.a.createElement("tr",{key:t},r.a.createElement("td",null,r.a.createElement("strong",null,a.name)),r.a.createElement("td",null,a.valueA),r.a.createElement("td",null,a.valueB),r.a.createElement("td",null,r.a.createElement("span",{className:"A"===a.winner?e.highlight:""},a.comparison)))))),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Overall Comparison"),r.a.createElement(u.a,{variant:"body1"},m.comparison.summary))));case 2:return r.a.createElement(N.a,{className:e.resultCard},r.a.createElement(T.a,null,r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Price-to-Value Analysis"),r.a.createElement(W.a,{style:{margin:"8px 0 16px"}}),m.valueAnalysis&&r.a.createElement("div",null,r.a.createElement(u.a,{variant:"subtitle1"},"Price Information"),r.a.createElement(u.a,{variant:"body1"},r.a.createElement("strong",null,"Product A:")," ",m.valueAnalysis.priceA),m.valueAnalysis.priceB&&r.a.createElement(u.a,{variant:"body1"},r.a.createElement("strong",null,"Product B:")," ",m.valueAnalysis.priceB),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Value Analysis"),r.a.createElement(u.a,{variant:"body1"},m.valueAnalysis.analysis),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Price-to-Performance Score"),r.a.createElement(u.a,{variant:"body1"},r.a.createElement("strong",null,"Product A:")," ",m.valueAnalysis.valueScoreA,"/10"),m.valueAnalysis.valueScoreB&&r.a.createElement(u.a,{variant:"body1"},r.a.createElement("strong",null,"Product B:")," ",m.valueAnalysis.valueScoreB,"/10"))));case 3:return r.a.createElement(N.a,{className:e.resultCard},r.a.createElement(T.a,null,r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Purchase Recommendations"),r.a.createElement(W.a,{style:{margin:"8px 0 16px"}}),m.recommendation&&r.a.createElement("div",null,r.a.createElement(u.a,{variant:"subtitle1",className:e.highlight},"Recommended Product: ",m.recommendation.recommendedProduct),r.a.createElement(u.a,{variant:"body1",style:{marginTop:"16px"}},m.recommendation.reason),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Alternative Products"),r.a.createElement("ul",null,m.recommendation.alternatives.map((e,a)=>r.a.createElement("li",{key:a},r.a.createElement(u.a,{variant:"body2"},r.a.createElement("strong",null,e.name),": ",e.reason)))),m.recommendation.buyingTips&&r.a.createElement(r.a.Fragment,null,r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Buying Tips"),r.a.createElement("ul",null,m.recommendation.buyingTips.map((e,a)=>r.a.createElement("li",{key:a},r.a.createElement(u.a,{variant:"body2"},e))))))));default:return null}})()))))};t(104);const ye=Object(c.a)({palette:{primary:{main:"#3f51b5"},secondary:{main:"#f50057"}},typography:{fontFamily:"Roboto, Arial, sans-serif"}});var be=function(){const[e,a]=Object(n.useState)(null),[t,l]=Object(n.useState)(""),[o,c]=Object(n.useState)(""),[h,v]=Object(n.useState)(!1),[x,S]=Object(n.useState)(null),[C,j]=Object(n.useState)(null),[w,P]=Object(n.useState)({yolo:!1,detr:!1,vit:!1}),[N,T]=Object(n.useState)(0);return Object(n.useEffect)(()=>{fetch("/api/status").then(e=>e.json()).then(e=>{P(e.models)}).catch(e=>{console.error("Error checking API status:",e),j("Error connecting to the backend API. Please make sure the server is running.")})},[]),r.a.createElement(i.a,{theme:ye},r.a.createElement(s.a,{style:{flexGrow:1}},r.a.createElement(m.a,{position:"static"},r.a.createElement(d.a,null,r.a.createElement(u.a,{variant:"h6",style:{flexGrow:1}},"Vision LLM Multi-Agent System")),r.a.createElement(g.a,{value:N,onChange:(e,a)=>T(a),indicatorColor:"secondary",textColor:"inherit",centered:!0},r.a.createElement(p.a,{label:"Object Detection"}),r.a.createElement(p.a,{label:"Product Comparison"}))),r.a.createElement(E.a,{maxWidth:"lg",style:{marginTop:ye.spacing(4),marginBottom:ye.spacing(4)}},0===N?r.a.createElement(y.a,{container:!0,spacing:3},r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(b.a,{style:{padding:ye.spacing(2)}},r.a.createElement(u.a,{variant:"h5",gutterBottom:!0},"Upload an image to see how each model performs!"),r.a.createElement(u.a,{variant:"body1",paragraph:!0},"This demo showcases three different object detection and image classification models:"),r.a.createElement(u.a,{variant:"body1",component:"div"},r.a.createElement("ul",null,r.a.createElement("li",null,r.a.createElement("strong",null,"YOLOv8"),": Fast and accurate object detection"),r.a.createElement("li",null,r.a.createElement("strong",null,"DETR"),": DEtection TRansformer for object detection"),r.a.createElement("li",null,r.a.createElement("strong",null,"ViT"),": Vision Transformer for image classification"))))),r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement(I,{onImageUpload:e=>{if(a(e),S(null),j(null),e instanceof File){const a=new FileReader;a.onload=()=>{const e=a.result;l("string"===typeof e?e:"")},a.onerror=()=>l(""),a.readAsDataURL(e)}else l("")}})),r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement(_,{onModelSelect:e=>{c(e),S(null),j(null)},onProcess:async()=>{if(!e||!o)return void j("Please select both an image and a model");v(!0),j(null);const a=new FormData;a.append("image",e);let t="";switch(o){case"yolo":t="/api/detect/yolo";break;case"detr":t="/api/detect/detr";break;case"vit":t="/api/classify/vit";break;default:return j("Invalid model selection"),void v(!1)}try{const e=await fetch(t,{method:"POST",body:a});if(!e.ok)throw new Error("HTTP error! Status: ".concat(e.status));const n=await e.json();S({model:o,data:n})}catch(n){console.error("Error processing image:",n),j("Error processing image: ".concat(n.message))}finally{v(!1)}},isProcessing:h,modelsStatus:w,selectedModel:o,imageSelected:!!e})),C&&r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(b.a,{style:{padding:ye.spacing(2),backgroundColor:"#ffebee"}},r.a.createElement(u.a,{color:"error"},C))),h&&r.a.createElement(y.a,{item:!0,xs:12,style:{textAlign:"center",margin:"".concat(ye.spacing(4),"px 0")}},r.a.createElement(f.a,null),r.a.createElement(u.a,{variant:"h6",style:{marginTop:ye.spacing(2)}},"Processing image...")),x&&r.a.createElement(r.a.Fragment,null,r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(le,{results:x})),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(ce,{visionResults:x.data,model:x.model}))),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(ie,{imageBase64:t}))):r.a.createElement(Ee,null))))};var fe=e=>{e&&e instanceof Function&&t.e(3).then(t.bind(null,181)).then(a=>{let{getCLS:t,getFID:n,getFCP:r,getLCP:l,getTTFB:o}=a;t(e),n(e),r(e),l(e),o(e)})};o.a.render(r.a.createElement(r.a.StrictMode,null,r.a.createElement(be,null)),document.getElementById("root")),fe()},94:function(e,a,t){e.exports=t(105)},99:function(e,a,t){}},[[94,1,2]]]);
|
2 |
+
//# sourceMappingURL=main.3e9c0e32.chunk.js.map
|
static/static/js/main.3e9c0e32.chunk.js.map
ADDED
The diff for this file is too large to render.
See raw diff
|
|
static/static/js/main.7fd2b13c.chunk.js
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
(this["webpackJsonpvision-web-app"]=this["webpackJsonpvision-web-app"]||[]).push([[0],{104:function(e,a,t){},105:function(e,a,t){"use strict";t.r(a);var n=t(0),r=t.n(n),l=t(11),o=t.n(l),c=(t(99),t(79)),i=t(165),s=t(169),m=t(166),d=t(167),u=t(49),g=t(171),p=t(161),E=t(168),y=t(142),b=t(83),f=t(147),h=t(140),v=t(141),x=t(65),S=t.n(x),C=t(76),j=t.n(C),w=t(137);const P=Object(w.a)(e=>({paper:{padding:e.spacing(2),display:"flex",flexDirection:"column",alignItems:"center",height:"100%",minHeight:300,transition:"all 0.3s ease"},dragActive:{border:"2px dashed #3f51b5",backgroundColor:"rgba(63, 81, 181, 0.05)"},dragInactive:{border:"2px dashed #ccc",backgroundColor:"white"},uploadBox:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",height:"100%",width:"100%",cursor:"pointer"},uploadIcon:{fontSize:60,color:"#3f51b5",marginBottom:e.spacing(2)},supportText:{marginTop:e.spacing(2)},previewBox:{display:"flex",flexDirection:"column",alignItems:"center",width:"100%",height:"100%",position:"relative"},imageContainer:{position:"relative",width:"100%",height:"45vh",[e.breakpoints.down("sm")]:{height:"35vh"},display:"flex",justifyContent:"center",alignItems:"center",overflow:"hidden",marginTop:e.spacing(2)},deleteButton:{position:"absolute",top:0,right:0,backgroundColor:"rgba(255, 255, 255, 0.7)","&:hover":{backgroundColor:"rgba(255, 255, 255, 0.9)"}}}));var I=e=>{let{onImageUpload:a}=e;const t=P(),[l,o]=Object(n.useState)(null),[c,i]=Object(n.useState)(!1),m=Object(n.useRef)(null),d=e=>{e.preventDefault(),e.stopPropagation(),"dragenter"===e.type||"dragover"===e.type?i(!0):"dragleave"===e.type&&i(!1)},g=e=>{e.type.startsWith("image/")?(o(URL.createObjectURL(e)),a(e)):alert("Please upload an image file")};return r.a.createElement(b.a,{className:"".concat(t.paper," ").concat(c?t.dragActive:t.dragInactive),onDragEnter:d,onDragLeave:d,onDragOver:d,onDrop:e=>{e.preventDefault(),e.stopPropagation(),i(!1),e.dataTransfer.files&&e.dataTransfer.files[0]&&g(e.dataTransfer.files[0])}},r.a.createElement("input",{ref:m,type:"file",accept:"image/*",onChange:e=>{e.preventDefault(),e.target.files&&e.target.files[0]&&g(e.target.files[0])},style:{display:"none"}}),l?r.a.createElement(s.a,{className:t.previewBox},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Preview"),r.a.createElement(s.a,{className:t.imageContainer},r.a.createElement("img",{src:l,alt:"Preview",className:"preview-image",style:{maxWidth:"100%",maxHeight:"100%",width:"auto",height:"auto",objectFit:"contain",display:"block"}}),r.a.createElement(v.a,{"aria-label":"delete",className:t.deleteButton,onClick:()=>{o(null),a(null),m.current.value=""}},r.a.createElement(j.a,null)))):r.a.createElement(s.a,{className:t.uploadBox,onClick:()=>{m.current.click()}},r.a.createElement(S.a,{className:t.uploadIcon}),r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Drag & Drop an image here"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary",gutterBottom:!0},"or"),r.a.createElement(h.a,{variant:"contained",color:"primary",component:"span",startIcon:r.a.createElement(S.a,null)},"Browse Files"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary",className:t.supportText},"Supported formats: JPG, PNG, GIF")))},N=t(143),T=t(144),O=t(176),B=t(145),A=t(66),k=t.n(A),D=t(77),R=t.n(D),F=t(78),L=t.n(F);const z=Object(w.a)(e=>({card:{height:"100%",display:"flex",flexDirection:"column"},selectedCard:{border:"2px solid #3f51b5"},unavailableCard:{opacity:.6},cardContent:{flexGrow:1},chipContainer:{marginBottom:e.spacing(1.5)},successChip:{backgroundColor:"#34C759",color:"#fff"},errorChip:{backgroundColor:"#FF3B3F",color:"#fff"},modelType:{marginTop:e.spacing(1)},processButton:{marginTop:e.spacing(3),textAlign:"center"}}));var _=e=>{let{onModelSelect:a,onProcess:t,isProcessing:n,modelsStatus:l,selectedModel:o,imageSelected:c}=e;const i=z(),m=[{id:"yolo",name:"YOLOv8",description:"Fast and accurate object detection",icon:r.a.createElement(k.a,null),available:l.yolo},{id:"detr",name:"DETR",description:"DEtection TRansformer for object detection",icon:r.a.createElement(k.a,null),available:l.detr},{id:"vit",name:"ViT",description:"Vision Transformer for image classification",icon:r.a.createElement(R.a,null),available:l.vit}],d=e=>{m.find(a=>a.id===e).available&&a(e)};return r.a.createElement(s.a,{sx:{p:2,height:"100%"}},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Select Model"),r.a.createElement(y.a,{container:!0,spacing:2},m.map(e=>r.a.createElement(y.a,{item:!0,xs:12,sm:4,key:e.id},r.a.createElement(N.a,{className:"\n ".concat(i.card," \n ").concat(o===e.id?i.selectedCard:""," \n ").concat(e.available?"":i.unavailableCard,"\n "),onClick:()=>d(e.id)},r.a.createElement(T.a,{className:i.cardContent},r.a.createElement(s.a,{sx:{mb:2,color:"primary"}},e.icon),r.a.createElement(u.a,{variant:"h5",component:"div",gutterBottom:!0},e.name),r.a.createElement("div",{className:i.chipContainer},e.available?r.a.createElement(O.a,{label:"Available",className:i.successChip,size:"small"}):r.a.createElement(O.a,{label:"Not Available",className:i.errorChip,size:"small"})),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},e.description)),r.a.createElement(B.a,null,r.a.createElement(h.a,{size:"small",onClick:()=>d(e.id),disabled:!e.available,color:o===e.id?"primary":"default",variant:o===e.id?"contained":"outlined",fullWidth:!0},o===e.id?"Selected":"Select")))))),r.a.createElement("div",{className:i.processButton},r.a.createElement(h.a,{variant:"contained",color:"primary",size:"large",startIcon:r.a.createElement(L.a,null),onClick:t,disabled:!o||!c||n},n?"Processing...":"Process Image")))},W=t(157),M=t(154),V=t(107),U=t(158),H=t(146),J=t(174),G=t(175),Y=t(149),q=t(150),K=t(151),Q=t(177),X=t(170),Z=t(155),$=t(179),ee=t(156),ae=t(173);const te=Object(w.a)(e=>({root:{marginTop:e.spacing(2),marginBottom:e.spacing(2),padding:e.spacing(2),backgroundColor:"#f5f5f5",borderRadius:e.shape.borderRadius},button:{marginRight:e.spacing(2)},searchDialog:{minWidth:"500px"},formControl:{marginBottom:e.spacing(2),minWidth:"100%"},searchResults:{marginTop:e.spacing(2)},resultCard:{marginBottom:e.spacing(2)},resultImage:{height:140,objectFit:"contain"},chip:{margin:e.spacing(.5)},similarityChip:{backgroundColor:e.palette.primary.main,color:"white"}}));var ne=e=>{let{results:a}=e;const t=te(),[l,o]=Object(n.useState)(!1),[c,i]=Object(n.useState)(!1),[m,d]=Object(n.useState)(null),[g,p]=Object(n.useState)(!1),[E,b]=Object(n.useState)("image"),[v,x]=Object(n.useState)(""),[S,C]=Object(n.useState)([]),[j,w]=Object(n.useState)(!1),[P,I]=Object(n.useState)(null),{model:B,data:A}=a,k=()=>{p(!1)},D=()=>"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(e){const a=16*Math.random()|0;return("x"===e?a:3&a|8).toString(16)}));return r.a.createElement(s.a,{className:t.root},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Vector Database Actions"),r.a.createElement(s.a,{display:"flex",alignItems:"center",mb:2},r.a.createElement(h.a,{variant:"contained",color:"primary",onClick:async()=>{o(!0),d(null);try{let e;if(e="vit"===B?await fetch("/api/add-to-collection",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image:A.image,metadata:{model:"vit",classifications:A.classifications}})}):await fetch("/api/add-detected-objects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image:A.image,objects:A.detections,imageId:D()})}),!e.ok)throw new Error("HTTP error! Status: ".concat(e.status));const a=await e.json();if(a.error)throw new Error(a.error);i(!0),setTimeout(()=>i(!1),5e3)}catch(e){console.error("Error saving to vector DB:",e),d("Error saving to vector DB: ".concat(e.message))}finally{o(!1)}},disabled:l,className:t.button},l?r.a.createElement(r.a.Fragment,null,r.a.createElement(f.a,{size:20,color:"inherit",style:{marginRight:8}}),"Saving..."):"Save to Vector DB"),r.a.createElement(h.a,{variant:"outlined",color:"primary",onClick:()=>{p(!0),C([]),I(null)},className:t.button},"Search Similar")),m&&r.a.createElement(ae.a,{severity:"error",style:{marginTop:8}},m),r.a.createElement(J.a,{open:c,autoHideDuration:5e3,onClose:()=>i(!1)},r.a.createElement(ae.a,{severity:"success"},"vit"===B?"Image and classifications successfully saved to vector DB!":"Detected objects successfully saved to vector DB!")),r.a.createElement(G.a,{open:g,onClose:k,maxWidth:"md",fullWidth:!0},r.a.createElement(Y.a,null,"Search Vector Database"),r.a.createElement(q.a,null,r.a.createElement(K.a,{className:t.formControl},r.a.createElement(Q.a,{id:"search-type-label"},"Search Type"),r.a.createElement(X.a,{labelId:"search-type-label",id:"search-type",value:E,onChange:e=>{b(e.target.value),C([]),I(null)}},r.a.createElement(Z.a,{value:"image"},"Search by Current Image"),r.a.createElement(Z.a,{value:"class"},"Search by Class Name"))),"class"===E&&r.a.createElement(K.a,{className:t.formControl},r.a.createElement($.a,{label:"Class Name",value:v,onChange:e=>{x(e.target.value)},placeholder:"e.g. person, car, dog...",fullWidth:!0})),P&&r.a.createElement(ae.a,{severity:"error",style:{marginBottom:16}},P),r.a.createElement(s.a,{className:t.searchResults},j?r.a.createElement(s.a,{display:"flex",justifyContent:"center",alignItems:"center",p:4},r.a.createElement(f.a,null),r.a.createElement(u.a,{variant:"body1",style:{marginLeft:16}},"Searching...")):r.a.createElement(r.a.Fragment,null,console.log("Search dialog render - searchResults:",S),S.length>0?(console.log("Rendering search results:",S),console.log("Search results length:",S.length),0===S.length?(console.log("No results to render"),r.a.createElement(u.a,{variant:"body1"},"No results found.")):r.a.createElement(y.a,{container:!0,spacing:2},S.map((e,a)=>{const n=100*(1-e.distance);return r.a.createElement(y.a,{item:!0,xs:12,sm:6,key:a},r.a.createElement(N.a,{className:t.resultCard},e.metadata&&e.metadata.image_data?r.a.createElement(H.a,{className:t.resultImage,component:"img",height:"200",image:"data:image/jpeg;base64,".concat(e.metadata.image_data),alt:e.metadata&&e.metadata.class?e.metadata.class:"Object"}):r.a.createElement(s.a,{className:t.resultImage,style:{backgroundColor:"#f0f0f0",display:"flex",alignItems:"center",justifyContent:"center",height:200}},r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},e.metadata&&e.metadata.class?e.metadata.class:"Object"," Image")),r.a.createElement(T.a,null,r.a.createElement(s.a,{display:"flex",justifyContent:"space-between",alignItems:"center",mb:1},r.a.createElement(u.a,{variant:"subtitle1"},"Result #",a+1),r.a.createElement(O.a,{label:"Similarity: ".concat(n.toFixed(2),"%"),className:t.similarityChip,size:"small"})),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},r.a.createElement("strong",null,"Class:")," ",e.metadata.class||"N/A"),e.metadata.confidence&&r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},r.a.createElement("strong",null,"Confidence:")," ",(100*e.metadata.confidence).toFixed(2),"%"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},r.a.createElement("strong",null,"Object ID:")," ",e.id))))}))):r.a.createElement(u.a,{variant:"body1"},"No results found. Please try another search.")))),r.a.createElement(ee.a,null,r.a.createElement(h.a,{onClick:k,color:"default"},"Close"),r.a.createElement(h.a,{onClick:async()=>{w(!0),I(null);try{let e={};if("image"===E)e={searchType:"image",image:A.image,n_results:5};else{if(!v.trim())throw new Error("Please enter a class name");e={searchType:"class",class_name:v.trim(),n_results:5}}const a=await fetch("/api/search-similar-objects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!a.ok)throw new Error("HTTP error! Status: ".concat(a.status));const t=await a.json();if(t.error)throw new Error(t.error);if(console.log("Search API response:",t),!t.success||!Array.isArray(t.results))throw console.error("Unexpected API response format:",t),new Error("Unexpected API response format");console.log("Setting search results array:",t.results),console.log("Results array length:",t.results.length),console.log("First result item:",t.results[0]),C(t.results)}catch(e){console.error("Error searching vector DB:",e),I("Error searching vector DB: ".concat(e.message))}finally{w(!1)}},color:"primary",variant:"contained",disabled:j||"class"===E&&!v.trim()},"Search"))))};const re=Object(w.a)(e=>({paper:{padding:e.spacing(2)},marginBottom:{marginBottom:e.spacing(2)},resultImage:{maxWidth:"100%",maxHeight:"400px",objectFit:"contain"},dividerMargin:{margin:"".concat(e.spacing(2),"px 0")},chipContainer:{display:"flex",gap:e.spacing(1),flexWrap:"wrap"}}));var le=e=>{let{results:a}=e;const t=re();if(!a)return null;const{model:n,data:l}=a;if(l.error)return r.a.createElement(b.a,{sx:{p:2,bgcolor:"#ffebee"}},r.a.createElement(u.a,{color:"error"},l.error));const o=()=>l.performance?r.a.createElement(s.a,{className:"performance-info"},r.a.createElement(W.a,{className:t.dividerMargin}),r.a.createElement(u.a,{variant:"body2"},"Inference time: ",(e=>{if(void 0===e||null===e||isNaN(e))return"-";const a=Number(e);return a<1e3?"".concat(a.toFixed(2)," ms"):"".concat((a/1e3).toFixed(2)," s")})(l.performance.inference_time)," on ",l.performance.device)):null;return"yolo"===n||"detr"===n?r.a.createElement(b.a,{className:t.paper},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"yolo"===n?"YOLOv8":"DETR"," Detection Results"),r.a.createElement(y.a,{container:!0,spacing:3},r.a.createElement(y.a,{item:!0,xs:12,md:6},l.image&&r.a.createElement(s.a,{className:t.marginBottom},r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Detection Result"),r.a.createElement("img",{src:"data:image/png;base64,".concat(l.image),alt:"Detection Result",className:t.resultImage}))),r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement(s.a,{className:t.marginBottom},r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Detected Objects:"),l.detections&&l.detections.length>0?r.a.createElement(M.a,null,l.detections.map((e,a)=>r.a.createElement(r.a.Fragment,{key:a},r.a.createElement(V.a,null,r.a.createElement(U.a,{primary:r.a.createElement(s.a,{style:{display:"flex",alignItems:"center"}},r.a.createElement(u.a,{variant:"body1",component:"span"},e.class),r.a.createElement(O.a,{label:"".concat((100*e.confidence).toFixed(0),"%"),size:"small",color:"primary",style:{marginLeft:8}})),secondary:"Bounding Box: [".concat(e.bbox.join(", "),"]")})),a<l.detections.length-1&&r.a.createElement(W.a,null)))):r.a.createElement(u.a,{variant:"body1"},"No objects detected")))),o(),r.a.createElement(ne,{results:a})):"vit"===n?r.a.createElement(b.a,{className:t.paper},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"ViT Classification Results"),r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Top Predictions:"),l.top_predictions&&l.top_predictions.length>0?r.a.createElement(M.a,null,l.top_predictions.map((e,a)=>r.a.createElement(r.a.Fragment,{key:a},r.a.createElement(V.a,null,r.a.createElement(U.a,{primary:r.a.createElement(s.a,{style:{display:"flex",alignItems:"center"}},r.a.createElement(u.a,{variant:"body1",component:"span"},e.rank,". ",e.class),r.a.createElement(O.a,{label:"".concat((100*e.probability).toFixed(1),"%"),size:"small",color:0===a?"primary":"default",style:{marginLeft:8}}))})),a<l.top_predictions.length-1&&r.a.createElement(W.a,null)))):r.a.createElement(u.a,{variant:"body1"},"No classifications available"),o(),r.a.createElement(ne,{results:a})):null};const oe=Object(w.a)(e=>({paper:{padding:e.spacing(2),marginTop:e.spacing(2)},marginBottom:{marginBottom:e.spacing(2)},dividerMargin:{margin:"".concat(e.spacing(2),"px 0")},responseBox:{padding:e.spacing(2),backgroundColor:"#f5f5f5",borderRadius:e.shape.borderRadius,marginTop:e.spacing(2),whiteSpace:"pre-wrap"},buttonProgress:{marginLeft:e.spacing(1)}}));var ce=e=>{let{visionResults:a,model:t}=e;const l=oe(),[o,c]=Object(n.useState)(""),[i,m]=Object(n.useState)(!1),[d,g]=Object(n.useState)(null),[p,E]=Object(n.useState)(null);return a?r.a.createElement(b.a,{className:l.paper},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Ask AI about the ","vit"===t?"Classification":"Detection"," Results"),r.a.createElement(u.a,{variant:"body2",className:l.marginBottom},"Ask a question about the detected objects or classifications to get an AI-powered analysis."),r.a.createElement($.a,{fullWidth:!0,label:"Your question about the image",variant:"outlined",value:o,onChange:e=>c(e.target.value),disabled:i,className:l.marginBottom,placeholder:"vit"===t?"E.g., What category does this image belong to?":"E.g., How many people are in this image?"}),r.a.createElement(h.a,{variant:"contained",color:"primary",onClick:async()=>{if(o.trim()){m(!0),E(null);try{const e=await fetch("/api/analyze",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({visionResults:a,userQuery:o})});if(!e.ok)throw new Error("HTTP error! Status: ".concat(e.status));const t=await e.json();t.error?E(t.error):g(t)}catch(e){console.error("Error analyzing with LLM:",e),E("Error analyzing with LLM: ".concat(e.message))}finally{m(!1)}}},disabled:i||!o.trim()},"Analyze with AI",i&&r.a.createElement(f.a,{size:24,className:l.buttonProgress})),p&&r.a.createElement(s.a,{mt:2},r.a.createElement(u.a,{color:"error"},p)),d&&r.a.createElement(r.a.Fragment,null,r.a.createElement(W.a,{className:l.dividerMargin}),r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"AI Analysis:"),r.a.createElement(s.a,{className:l.responseBox},r.a.createElement(u.a,{variant:"body1"},d.response)),d.performance&&r.a.createElement(s.a,{mt:1},r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},"Analysis time: ",(e=>{if(void 0===e||null===e||isNaN(e))return"-";const a=Number(e);return a<1e3?"".concat(a.toFixed(2)," ms"):"".concat((a/1e3).toFixed(2)," s")})(d.performance.inference_time)," on ",d.performance.device)))):null};var ie=function(e){let{imageBase64:a}=e;const[t,l]=Object(n.useState)(""),[o,c]=Object(n.useState)(""),[i,s]=Object(n.useState)(""),[m,d]=Object(n.useState)(!1),[g,p]=Object(n.useState)(""),[E,f]=Object(n.useState)("image"),[v,x]=Object(n.useState)(""),[S,C]=Object(n.useState)(""),[j,w]=Object(n.useState)(5);return r.a.createElement(b.a,{style:{padding:16}},r.a.createElement(u.a,{variant:"h5",gutterBottom:!0},"Vision RAG (LangChain)"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary",gutterBottom:!0},"If OPENAI_API_KEY is set on the server, API Key is optional. Select a search type and send a question to get answers based on context retrieved from the vector DB."),r.a.createElement(y.a,{container:!0,spacing:2},r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement(K.a,{fullWidth:!0,variant:"outlined",size:"small"},r.a.createElement(Q.a,{id:"search-type-label"},"Search Type"),r.a.createElement(X.a,{labelId:"search-type-label",value:E,onChange:e=>f(e.target.value),label:"Search Type"},r.a.createElement(Z.a,{value:"image"},"image (current upload)"),r.a.createElement(Z.a,{value:"object"},"object (objectId)"),r.a.createElement(Z.a,{value:"class"},"class (class_name)")))),r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement($.a,{label:"OpenAI API Key (optional)",value:t,onChange:e=>l(e.target.value),fullWidth:!0,variant:"outlined",size:"small",type:"password",placeholder:"sk-..."})),"object"===E&&r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement($.a,{label:"objectId",value:v,onChange:e=>x(e.target.value),fullWidth:!0,variant:"outlined",size:"small"})),"class"===E&&r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement($.a,{label:"class_name",value:S,onChange:e=>C(e.target.value),fullWidth:!0,variant:"outlined",size:"small",placeholder:"e.g. person, car, dog"})),r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement($.a,{label:"n_results",value:j,onChange:e=>w(e.target.value),fullWidth:!0,variant:"outlined",size:"small",type:"number",inputProps:{min:1,max:50}})),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement($.a,{label:"User Question",value:o,onChange:e=>c(e.target.value),fullWidth:!0,multiline:!0,rows:4,variant:"outlined",placeholder:"image"===E?"Answer based on the uploaded image":"Answer using the retrieved object context"})),g&&r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(u.a,{color:"error"},g)),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement("div",{style:{display:"flex",gap:8}},r.a.createElement(h.a,{color:"primary",variant:"contained",onClick:async()=>{p(""),s("");const e=(o||"").trim();if(!e)return void p("Please enter a question.");const n={userQuery:e,searchType:E,n_results:Number(j)||5};if(t&&(n.api_key=t),"image"===E){if(!a)return void p("Image is required. Please upload an image first.");n.image=a}else if("object"===E){if(!v.trim())return void p("Please enter an objectId.");n.objectId=v.trim()}else if("class"===E){if(!S.trim())return void p("Please enter a class_name.");n.class_name=S.trim()}d(!0);try{const e=await fetch("/api/vision-rag/query",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(n)});if(!e.ok){let a=await e.text();try{a=JSON.stringify(JSON.parse(a),null,2)}catch(r){}throw new Error(a)}const a=await e.json(),t="Model: ".concat(a.model||"-"," | Latency: ").concat(a.latency_sec||"-","s");let l="";a.retrieved&&a.retrieved.length>0&&(l="\n\nSearch Results:\n",a.retrieved.forEach((e,a)=>{l+="".concat(a+1,". ID: ").concat(e.id||"-","\n"),e.meta&&(l+=" Class: ".concat(e.meta.class||"-","\n"),l+=" Confidence: ".concat(e.meta.confidence||"-","\n")),l+=" Similarity: ".concat(e.distance?e.distance.toFixed(4):"-","\n")})),s((a.answer||"(No response)")+l+"\n\n---\n"+t)}catch(l){p("Error: "+l.message)}finally{d(!1)}},disabled:m},m?"Sending...":"Send Question"),r.a.createElement(h.a,{variant:"outlined",onClick:()=>{c(""),s(""),p("")}},"Clear"))),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(W.a,{style:{margin:"12px 0"}}),r.a.createElement(u.a,{variant:"subtitle2",color:"textSecondary"},"Response"),r.a.createElement("pre",{style:{whiteSpace:"pre-wrap",fontFamily:"ui-monospace, monospace"}},i))))},se=(t(80),t(159)),me=t(160),de=t(162),ue=t(163),ge=t(164);const pe=Object(w.a)(e=>({root:{marginTop:e.spacing(3),marginBottom:e.spacing(3)},imageContainer:{position:"relative",minHeight:"360px",display:"flex",justifyContent:"center",alignItems:"center",border:"2px dashed #ccc",borderRadius:"8px",margin:e.spacing(1),padding:e.spacing(1),backgroundColor:"#fafafa",overflow:"hidden"},progressLog:{marginTop:e.spacing(2),height:"200px",overflowY:"auto",backgroundColor:"#f8f9fa",padding:e.spacing(1),borderRadius:"4px",fontFamily:"monospace",fontSize:"0.9rem"},logEntry:{margin:"4px 0",padding:"2px 5px",borderLeft:"3px solid #ccc"},logEntryAgent:{borderLeft:"3px solid #2196f3"},logEntrySystem:{borderLeft:"3px solid #4caf50"},logEntryError:{borderLeft:"3px solid #f44336"},logTime:{color:"#666",fontSize:"0.8rem",marginRight:e.spacing(1)},imagePreview:{width:"100%",height:"auto",maxHeight:"60vh",objectFit:"contain"},uploadIcon:{fontSize:"3rem",color:"#aaa"},uploadInput:{display:"none"},deleteButton:{position:"absolute",top:"8px",right:"8px",backgroundColor:"rgba(255, 255, 255, 0.8)","&:hover":{backgroundColor:"rgba(255, 255, 255, 0.9)"}},tabPanel:{padding:e.spacing(2)},resultCard:{marginTop:e.spacing(2),marginBottom:e.spacing(2)},comparisonTable:{width:"100%",borderCollapse:"collapse","& th, & td":{border:"1px solid #ddd",padding:"8px",textAlign:"left"},"& th":{backgroundColor:"#f2f2f2"},"& tr:nth-child(even)":{backgroundColor:"#f9f9f9"}},loadingContainer:{display:"flex",flexDirection:"column",alignItems:"center",padding:e.spacing(4)},highlight:{backgroundColor:"#e3f2fd",padding:e.spacing(1),borderRadius:"4px",fontWeight:"bold"}}));var Ee=()=>{const e=pe(),[a,t]=Object(n.useState)([null,null]),[l,o]=Object(n.useState)([null,null]),[c,i]=Object(n.useState)(!1),[m,d]=Object(n.useState)(null),[E,x]=Object(n.useState)(null),[S,C]=Object(n.useState)(0),[j,w]=Object(n.useState)([]),P=Object(n.useRef)(null),I=function(e){let a=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"info";const t=new Date,n=t.toLocaleTimeString(),r={time:n,message:e,type:a};w(e=>[...e,r])};Object(n.useEffect)(()=>{P.current&&P.current.scrollIntoView({behavior:"smooth"})},[j]);const O=e=>{const a=new EventSource("/api/product/compare/stream/".concat(e));return a.onmessage=e=>{try{const t=JSON.parse(e.data);t.message&&I(t.message,t.agent||"info"),t.final_result&&(d(t.final_result),i(!1),a.close())}catch(t){I("Event processing error: ".concat(t.message),"error")}},a.onerror=e=>{I("Server connection lost. Please try again in a moment.","error"),a.close(),i(!1)},a},B=async function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:null;if(a[0]||a[1]){i(!0),x(null),w([]),I("Starting product analysis...","system");try{const t=new FormData;a[0]&&(t.append("image1",a[0]),I("Product A image uploaded.","info")),a[1]&&(t.append("image2",a[1]),I("Product B image uploaded.","info"));const n=["info","compare","value","recommend"],r=e||n[S];t.append("analysisType",r),I("Analysis type: ".concat("info"===r?"Product Information":"compare"===r?"Performance Comparison":"value"===r?"Value Analysis":"Purchase Recommendation"),"system"),I("Initializing analysis session...","system");const l=await fetch("/api/product/compare/start",{method:"POST",body:t});if(!l.ok)throw new Error("HTTP error! Status: ".concat(l.status));const o=(await l.json()).session_id;if(!o)throw new Error("Failed to receive session ID");I("Analysis session started. (Session ID: ".concat(o.substring(0,8),"...)"),"system"),I("Agents are collaborating to analyze products. Please wait a moment...","system");const c=O(o);return()=>{c.close()}}catch(t){console.error("\uc81c\ud488 \ubd84\uc11d \uc624\ub958:",t),I("Error occurred: ".concat(t.message),"error"),x("Error during analysis: ".concat(t.message)),i(!1)}}else x("Please upload at least one product image for analysis")};return r.a.createElement(b.a,{className:e.root},r.a.createElement(s.a,{p:3},r.a.createElement(u.a,{variant:"h5",gutterBottom:!0},"Product Comparison Analysis"),r.a.createElement(u.a,{variant:"body1",paragraph:!0},"Upload product images to receive detailed information and comparison analysis. You can analyze various products including cars, smartphones, laptops, and more."),r.a.createElement(y.a,{container:!0,spacing:3},[0,1].map(n=>r.a.createElement(y.a,{item:!0,xs:12,md:6,key:n},r.a.createElement(s.a,{className:e.imageContainer},l[n]?r.a.createElement(r.a.Fragment,null,r.a.createElement("img",{src:l[n],alt:"Product ".concat(n+1),className:e.imagePreview}),r.a.createElement(v.a,{className:e.deleteButton,onClick:()=>(e=>{const n=[...a],r=[...l];n[e]=null,r[e]=null,t(n),o(r),d(null)})(n)},r.a.createElement(se.a,null))):r.a.createElement(r.a.Fragment,null,r.a.createElement("input",{accept:"image/*",className:e.uploadInput,id:"upload-image-".concat(n),type:"file",onChange:e=>((e,n)=>{const r=e.target.files[0];if(r){const e=new FileReader;e.onload=e=>{const a=[...l];a[n]=e.target.result,o(a)},e.readAsDataURL(r);const c=[...a];c[n]=r,t(c),d(null),x(null)}})(e,n)}),r.a.createElement("label",{htmlFor:"upload-image-".concat(n)},r.a.createElement(s.a,{display:"flex",flexDirection:"column",alignItems:"center"},r.a.createElement(me.a,{className:e.uploadIcon}),r.a.createElement(u.a,{variant:"body2",style:{marginTop:"8px"}},"Upload ",0===n?"Product A":"Product B"," Image"))))))),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement("input",{accept:"image/*",className:e.uploadInput,id:"upload-both-images",type:"file",multiple:!0,onChange:e=>{const n=Array.from(e.target.files||[]);if(!n.length)return;const r=[...a],c=[...l];n.slice(0,2).forEach((e,a)=>{const t=a;r[t]=e;const n=new FileReader;n.onload=e=>{c[t]=e.target.result,o([...c])},n.readAsDataURL(e)}),t(r),d(null),x(null)}}),r.a.createElement("label",{htmlFor:"upload-both-images"},r.a.createElement(h.a,{variant:"text",color:"default",component:"span"},"Or select two files at once"))),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(b.a,null,r.a.createElement(g.a,{value:S,onChange:(e,a)=>{C(a)},indicatorColor:"primary",textColor:"primary",centered:!0},r.a.createElement(p.a,{icon:r.a.createElement(de.a,null),label:"Product Info"}),r.a.createElement(p.a,{icon:r.a.createElement(ue.a,null),label:"Performance",disabled:!a[0]||!a[1]}),r.a.createElement(p.a,{icon:r.a.createElement(ge.a,null),label:"Value Analysis"}),r.a.createElement(p.a,{label:"Recommendations"})),r.a.createElement(s.a,{p:2,display:"flex",justifyContent:"center",gridGap:12},r.a.createElement(h.a,{variant:"contained",color:"primary",onClick:()=>B(null),disabled:c||!a[0]&&!a[1],startIcon:c?r.a.createElement(f.a,{size:24}):null},c?"Analyzing...":"Start Analysis"),r.a.createElement(h.a,{variant:"outlined",color:"secondary",onClick:()=>B("compare"),disabled:c||!a[0]||!a[1],startIcon:r.a.createElement(ue.a,null)},"Compare Products")),E&&r.a.createElement(s.a,{p:2,bgcolor:"#ffebee",borderRadius:"4px",mb:2},r.a.createElement(u.a,{color:"error"},E)))),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(b.a,null,r.a.createElement(s.a,{p:2},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Analysis Progress"),r.a.createElement(s.a,{className:e.progressLog},0===j.length?r.a.createElement(u.a,{variant:"body2",color:"textSecondary",style:{padding:"10px"}},"Progress details will appear here when analysis starts."):j.map((a,t)=>r.a.createElement(s.a,{key:t,className:"".concat(e.logEntry," ").concat("agent"===a.type?e.logEntryAgent:"system"===a.type?e.logEntrySystem:"error"===a.type?e.logEntryError:"")},r.a.createElement("span",{className:e.logTime},"[",a.time,"]"),a.message)),r.a.createElement("div",{ref:P}))))),r.a.createElement(y.a,{item:!0,xs:12},c?r.a.createElement(s.a,{className:e.loadingContainer},r.a.createElement(f.a,null),r.a.createElement(u.a,{variant:"h6",style:{marginTop:"16px"}},"Analyzing Products..."),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},"Product recognition, information retrieval, and comparison analysis in progress.")):(()=>{if(!m)return null;switch(S){case 0:return r.a.createElement(N.a,{className:e.resultCard},r.a.createElement(T.a,null,r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Product Information"),r.a.createElement(W.a,{style:{margin:"8px 0 16px"}}),m.productInfo&&r.a.createElement("div",null,r.a.createElement(u.a,{variant:"subtitle1"},r.a.createElement("strong",null,"Product Name:")," ",m.productInfo.name),r.a.createElement(u.a,{variant:"body1"},r.a.createElement("strong",null,"Brand:")," ",m.productInfo.brand),r.a.createElement(u.a,{variant:"body1"},r.a.createElement("strong",null,"Category:")," ",m.productInfo.category),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Key Specifications"),r.a.createElement("ul",null,m.productInfo.specs.map((e,a)=>r.a.createElement("li",{key:a},r.a.createElement(u.a,{variant:"body2"},r.a.createElement("strong",null,e.name,":")," ",e.value)))),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Pros"),r.a.createElement("ul",null,m.productInfo.pros.map((e,a)=>r.a.createElement("li",{key:a},r.a.createElement(u.a,{variant:"body2"},e)))),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Cons"),r.a.createElement("ul",null,m.productInfo.cons.map((e,a)=>r.a.createElement("li",{key:a},r.a.createElement(u.a,{variant:"body2"},e)))))));case 1:return r.a.createElement(N.a,{className:e.resultCard},r.a.createElement(T.a,null,r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Product Comparison Analysis"),r.a.createElement(W.a,{style:{margin:"8px 0 16px"}}),m.comparison&&r.a.createElement("div",null,r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Product Specification Comparison"),r.a.createElement("table",{className:e.comparisonTable},r.a.createElement("thead",null,r.a.createElement("tr",null,r.a.createElement("th",null,"Feature"),r.a.createElement("th",null,"Product A"),r.a.createElement("th",null,"Product B"),r.a.createElement("th",null,"Comparison"))),r.a.createElement("tbody",null,m.comparison.specs.map((a,t)=>r.a.createElement("tr",{key:t},r.a.createElement("td",null,r.a.createElement("strong",null,a.name)),r.a.createElement("td",null,a.valueA),r.a.createElement("td",null,a.valueB),r.a.createElement("td",null,r.a.createElement("span",{className:"A"===a.winner?e.highlight:""},a.comparison)))))),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Overall Comparison"),r.a.createElement(u.a,{variant:"body1"},m.comparison.summary))));case 2:return r.a.createElement(N.a,{className:e.resultCard},r.a.createElement(T.a,null,r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Price-to-Value Analysis"),r.a.createElement(W.a,{style:{margin:"8px 0 16px"}}),m.valueAnalysis&&r.a.createElement("div",null,r.a.createElement(u.a,{variant:"subtitle1"},"Price Information"),r.a.createElement(u.a,{variant:"body1"},r.a.createElement("strong",null,"Product A:")," ",m.valueAnalysis.priceA),m.valueAnalysis.priceB&&r.a.createElement(u.a,{variant:"body1"},r.a.createElement("strong",null,"Product B:")," ",m.valueAnalysis.priceB),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Value Analysis"),r.a.createElement(u.a,{variant:"body1"},m.valueAnalysis.analysis),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Price-to-Performance Score"),r.a.createElement(u.a,{variant:"body1"},r.a.createElement("strong",null,"Product A:")," ",m.valueAnalysis.valueScoreA,"/10"),m.valueAnalysis.valueScoreB&&r.a.createElement(u.a,{variant:"body1"},r.a.createElement("strong",null,"Product B:")," ",m.valueAnalysis.valueScoreB,"/10"))));case 3:return r.a.createElement(N.a,{className:e.resultCard},r.a.createElement(T.a,null,r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Purchase Recommendations"),r.a.createElement(W.a,{style:{margin:"8px 0 16px"}}),m.recommendation&&r.a.createElement("div",null,r.a.createElement(u.a,{variant:"subtitle1",className:e.highlight},"Recommended Product: ",m.recommendation.recommendedProduct),r.a.createElement(u.a,{variant:"body1",style:{marginTop:"16px"}},m.recommendation.reason),r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Alternative Products"),r.a.createElement("ul",null,m.recommendation.alternatives.map((e,a)=>r.a.createElement("li",{key:a},r.a.createElement(u.a,{variant:"body2"},r.a.createElement("strong",null,e.name),": ",e.reason)))),m.recommendation.buyingTips&&r.a.createElement(r.a.Fragment,null,r.a.createElement(u.a,{variant:"subtitle1",style:{marginTop:"16px"}},"Buying Tips"),r.a.createElement("ul",null,m.recommendation.buyingTips.map((e,a)=>r.a.createElement("li",{key:a},r.a.createElement(u.a,{variant:"body2"},e))))))));default:return null}})()))))};t(104);const ye=Object(c.a)({palette:{primary:{main:"#3f51b5"},secondary:{main:"#f50057"}},typography:{fontFamily:"Roboto, Arial, sans-serif"}});var be=function(){const[e,a]=Object(n.useState)(null),[t,l]=Object(n.useState)(""),[o,c]=Object(n.useState)(""),[h,v]=Object(n.useState)(!1),[x,S]=Object(n.useState)(null),[C,j]=Object(n.useState)(null),[w,P]=Object(n.useState)({yolo:!1,detr:!1,vit:!1}),[N,T]=Object(n.useState)(0);return Object(n.useEffect)(()=>{fetch("/api/status").then(e=>e.json()).then(e=>{P(e.models)}).catch(e=>{console.error("Error checking API status:",e),j("Error connecting to the backend API. Please make sure the server is running.")})},[]),r.a.createElement(i.a,{theme:ye},r.a.createElement(s.a,{style:{flexGrow:1}},r.a.createElement(m.a,{position:"static"},r.a.createElement(d.a,null,r.a.createElement(u.a,{variant:"h6",style:{flexGrow:1}},"Vision LLM Multi-Agent System")),r.a.createElement(g.a,{value:N,onChange:(e,a)=>T(a),indicatorColor:"secondary",textColor:"inherit",centered:!0},r.a.createElement(p.a,{label:"Object Detection"}),r.a.createElement(p.a,{label:"Product Comparison"}))),r.a.createElement(E.a,{maxWidth:"lg",style:{marginTop:ye.spacing(4),marginBottom:ye.spacing(4)}},0===N?r.a.createElement(y.a,{container:!0,spacing:3},r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(b.a,{style:{padding:ye.spacing(2)}},r.a.createElement(u.a,{variant:"h5",gutterBottom:!0},"Upload an image to see how each model performs!"),r.a.createElement(u.a,{variant:"body1",paragraph:!0},"This demo showcases three different object detection and image classification models:"),r.a.createElement(u.a,{variant:"body1",component:"div"},r.a.createElement("ul",null,r.a.createElement("li",null,r.a.createElement("strong",null,"YOLOv8"),": Fast and accurate object detection"),r.a.createElement("li",null,r.a.createElement("strong",null,"DETR"),": DEtection TRansformer for object detection"),r.a.createElement("li",null,r.a.createElement("strong",null,"ViT"),": Vision Transformer for image classification"))))),r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement(I,{onImageUpload:e=>{if(a(e),S(null),j(null),e instanceof File){const a=new FileReader;a.onload=()=>{const e=a.result;l("string"===typeof e?e:"")},a.onerror=()=>l(""),a.readAsDataURL(e)}else l("")}})),r.a.createElement(y.a,{item:!0,xs:12,md:6},r.a.createElement(_,{onModelSelect:e=>{c(e),S(null),j(null)},onProcess:async()=>{if(!e||!o)return void j("Please select both an image and a model");v(!0),j(null);const a=new FormData;a.append("image",e);let t="";switch(o){case"yolo":t="/api/detect/yolo";break;case"detr":t="/api/detect/detr";break;case"vit":t="/api/classify/vit";break;default:return j("Invalid model selection"),void v(!1)}try{const e=await fetch(t,{method:"POST",body:a});if(!e.ok)throw new Error("HTTP error! Status: ".concat(e.status));const n=await e.json();S({model:o,data:n})}catch(n){console.error("Error processing image:",n),j("Error processing image: ".concat(n.message))}finally{v(!1)}},isProcessing:h,modelsStatus:w,selectedModel:o,imageSelected:!!e})),C&&r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(b.a,{style:{padding:ye.spacing(2),backgroundColor:"#ffebee"}},r.a.createElement(u.a,{color:"error"},C))),h&&r.a.createElement(y.a,{item:!0,xs:12,style:{textAlign:"center",margin:"".concat(ye.spacing(4),"px 0")}},r.a.createElement(f.a,null),r.a.createElement(u.a,{variant:"h6",style:{marginTop:ye.spacing(2)}},"Processing image...")),x&&r.a.createElement(r.a.Fragment,null,r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(le,{results:x})),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(ce,{visionResults:x.data,model:x.model}))),r.a.createElement(y.a,{item:!0,xs:12},r.a.createElement(ie,{imageBase64:t}))):r.a.createElement(Ee,null))))};var fe=e=>{e&&e instanceof Function&&t.e(3).then(t.bind(null,181)).then(a=>{let{getCLS:t,getFID:n,getFCP:r,getLCP:l,getTTFB:o}=a;t(e),n(e),r(e),l(e),o(e)})};o.a.render(r.a.createElement(r.a.StrictMode,null,r.a.createElement(be,null)),document.getElementById("root")),fe()},94:function(e,a,t){e.exports=t(105)},99:function(e,a,t){}},[[94,1,2]]]);
|
2 |
+
//# sourceMappingURL=main.7fd2b13c.chunk.js.map
|
static/static/js/main.7fd2b13c.chunk.js.map
ADDED
The diff for this file is too large to render.
See raw diff
|
|
static/static/{static/js β js}/main.db88b5b1.chunk.js
RENAMED
File without changes
|
static/static/{static/js β js}/main.db88b5b1.chunk.js.map
RENAMED
File without changes
|
static/static/js/runtime-main.1d79dee9.js
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
!function(e){function r(r){for(var n,i,a=r[0],c=r[1],l=r[2],f=0,s=[];f<a.length;f++)i=a[f],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(p&&p(r);s.length;)s.shift()();return u.push.apply(u,l||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var c=t[a];0!==o[c]&&(n=!1)}n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={1:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"10abbce4"}[e]+".chunk.js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"===typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,function(r){return e[r]}.bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this["webpackJsonpvision-web-app"]=this["webpackJsonpvision-web-app"]||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var l=0;l<a.length;l++)r(a[l]);var p=c;t()}([]);
|
2 |
+
//# sourceMappingURL=runtime-main.1d79dee9.js.map
|
static/static/js/runtime-main.1d79dee9.js.map
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"version":3,"sources":["../webpack/bootstrap"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","1","exports","module","l","e","promises","installedChunkData","promise","Promise","resolve","reject","onScriptComplete","script","document","createElement","charset","timeout","nc","setAttribute","src","p","jsonpScriptSrc","error","Error","event","onerror","onload","clearTimeout","chunk","errorType","type","realSrc","target","message","name","request","undefined","setTimeout","head","appendChild","all","m","c","d","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","oe","err","console","jsonpArray","this","oldJsonpFunction","slice"],"mappings":"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","file":"static/js/runtime-main.1d79dee9.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t1: 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// script path function\n \tfunction jsonpScriptSrc(chunkId) {\n \t\treturn __webpack_require__.p + \"static/js/\" + ({}[chunkId]||chunkId) + \".\" + {\"3\":\"10abbce4\"}[chunkId] + \".chunk.js\"\n \t}\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tvar promises = [];\n\n\n \t\t// JSONP chunk loading for javascript\n\n \t\tvar installedChunkData = installedChunks[chunkId];\n \t\tif(installedChunkData !== 0) { // 0 means \"already installed\".\n\n \t\t\t// a Promise means \"currently loading\".\n \t\t\tif(installedChunkData) {\n \t\t\t\tpromises.push(installedChunkData[2]);\n \t\t\t} else {\n \t\t\t\t// setup Promise in chunk cache\n \t\t\t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n \t\t\t\t});\n \t\t\t\tpromises.push(installedChunkData[2] = promise);\n\n \t\t\t\t// start chunk loading\n \t\t\t\tvar script = document.createElement('script');\n \t\t\t\tvar onScriptComplete;\n\n \t\t\t\tscript.charset = 'utf-8';\n \t\t\t\tscript.timeout = 120;\n \t\t\t\tif (__webpack_require__.nc) {\n \t\t\t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t\t\t}\n \t\t\t\tscript.src = jsonpScriptSrc(chunkId);\n\n \t\t\t\t// create error before stack unwound to get useful stacktrace later\n \t\t\t\tvar error = new Error();\n \t\t\t\tonScriptComplete = function (event) {\n \t\t\t\t\t// avoid mem leaks in IE.\n \t\t\t\t\tscript.onerror = script.onload = null;\n \t\t\t\t\tclearTimeout(timeout);\n \t\t\t\t\tvar chunk = installedChunks[chunkId];\n \t\t\t\t\tif(chunk !== 0) {\n \t\t\t\t\t\tif(chunk) {\n \t\t\t\t\t\t\tvar errorType = event && (event.type === 'load' ? 'missing' : event.type);\n \t\t\t\t\t\t\tvar realSrc = event && event.target && event.target.src;\n \t\t\t\t\t\t\terror.message = 'Loading chunk ' + chunkId + ' failed.\\n(' + errorType + ': ' + realSrc + ')';\n \t\t\t\t\t\t\terror.name = 'ChunkLoadError';\n \t\t\t\t\t\t\terror.type = errorType;\n \t\t\t\t\t\t\terror.request = realSrc;\n \t\t\t\t\t\t\tchunk[1](error);\n \t\t\t\t\t\t}\n \t\t\t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t\t\t}\n \t\t\t\t};\n \t\t\t\tvar timeout = setTimeout(function(){\n \t\t\t\t\tonScriptComplete({ type: 'timeout', target: script });\n \t\t\t\t}, 120000);\n \t\t\t\tscript.onerror = script.onload = onScriptComplete;\n \t\t\t\tdocument.head.appendChild(script);\n \t\t\t}\n \t\t}\n \t\treturn Promise.all(promises);\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n \tvar jsonpArray = this[\"webpackJsonpvision-web-app\"] = this[\"webpackJsonpvision-web-app\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// run deferred modules from other chunks\n \tcheckDeferredModules();\n"],"sourceRoot":""}
|
static/static/{static/js β js}/runtime-main.25710301.js
RENAMED
File without changes
|
static/static/{static/js β js}/runtime-main.25710301.js.map
RENAMED
File without changes
|