{"id":2196,"date":"2026-08-15T14:03:05","date_gmt":"2026-08-15T14:03:05","guid":{"rendered":"https:\/\/proptrustverified.com\/es\/?page_id=2196"},"modified":"2026-08-15T17:37:15","modified_gmt":"2026-08-15T17:37:15","slug":"PTVS-SandBox","status":"publish","type":"page","link":"https:\/\/proptrustverified.com\/en\/PTVS-SandBox\/","title":{"rendered":"PTVS SandBox"},"content":{"rendered":"<!DOCTYPE html>\n<?xml encoding=\"UTF-8\"?><html lang=\"en\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>PTVS Sandbox &mdash; Try Prop Trust Verified Standard in 5 Minutes<\/title>\n<meta name=\"description\" content=\"Interactive sandbox for the Prop Trust Verified Standard (PTVS v1.0). Create a mock asset, generate forensic evidence, compute SHA-256 hash, and simulate on-chain Verifiable Claim injection. No backend required.\">\n<meta name=\"author\" content=\"Forensics Oracle Initiative\">\n<meta property=\"og:title\" content=\"PTVS Sandbox &mdash; Interactive Playground\">\n<meta property=\"og:description\" content=\"Try PTVS v1.0 in your browser. Create mock assets, generate forensic evidence, compute hashes, and simulate on-chain claims.\">\n<meta property=\"og:type\" content=\"website\">\n<meta property=\"og:site_name\" content=\"Prop Trust Verified\">\n<link rel=\"canonical\" href=\"https:\/\/proptrustverified.com\/sandbox\/\">\n<link rel=\"icon\" type=\"image\/png\" href=\"https:\/\/forensics-oracle.org\/wp-content\/uploads\/2026\/08\/cropped-cropped_circle_image.png\">\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Cinzel:wght@400;600;700;800;900&amp;family=Inter:wght@300;400;500;600;700&amp;family=Cormorant+Garamond:ital,wght@0,400;0,600;1,400;1,600&amp;family=JetBrains+Mono:wght@400;500&amp;display=swap\" rel=\"stylesheet\">\n\n<style>\n:root {\n--navy: #0B132B;\n--navy-light: #1C2541;\n--navy-deep: #070E1F;\n--gold: #D4AF37;\n--gold-dark: #AA8C2C;\n--gold-light: #F4E5C2;\n--cream: #FAF7F0;\n--text: #1A202C;\n--muted: #4A5568;\n--border: #E2E8F0;\n--bg: #F8FAFC;\n--green: #2F855A;\n--red: #C53030;\n--amber: #B7791F;\n--blue: #2B6CB0;\n}\n* { margin: 0; padding: 0; box-sizing: border-box; }\nbody {\nfont-family: 'Inter', sans-serif;\nbackground: var(--cream);\ncolor: var(--text);\nline-height: 1.65;\n}\n\n\/* HEADER NAV *\/\n.site-header {\nbackground: var(--navy);\nborder-bottom: 3px solid var(--gold);\npadding: 16px 5%;\nposition: sticky;\ntop: 0;\nz-index: 100;\n}\n.header-container {\nmax-width: 1400px;\nmargin: 0 auto;\ndisplay: flex;\njustify-content: space-between;\nalign-items: center;\nflex-wrap: wrap;\ngap: 16px;\n}\n.brand-link {\ndisplay: flex;\nalign-items: center;\ngap: 12px;\ntext-decoration: none;\n}\n.brand-seal {\nwidth: 46px; height: 46px;\nborder-radius: 50%;\nborder: 2px solid var(--gold);\noverflow: hidden;\nbackground: var(--navy-deep);\nflex-shrink: 0;\n}\n.brand-seal img { width: 100%; height: 100%; object-fit: cover; }\n.brand-text {\nfont-family: 'Cinzel', serif;\nfont-size: 10pt;\nfont-weight: 700;\ncolor: var(--gold);\nletter-spacing: 1px;\nline-height: 1.2;\n}\n.brand-sub {\ndisplay: block;\nfont-size: 6.5pt;\ncolor: #A0AEC0;\nletter-spacing: 2px;\ntext-transform: uppercase;\nmargin-top: 2px;\n}\n.nav-links {\ndisplay: flex;\ngap: 20px;\nlist-style: none;\nflex-wrap: wrap;\n}\n.nav-links a {\ncolor: #E2E8F0;\ntext-decoration: none;\nfont-size: 8pt;\nletter-spacing: 1.5px;\ntext-transform: uppercase;\nfont-weight: 500;\ntransition: color 0.3s;\npadding: 4px 0;\nborder-bottom: 1px solid transparent;\n}\n.nav-links a:hover,\n.nav-links a.active {\ncolor: var(--gold);\nborder-bottom-color: var(--gold);\n}\n\n\/* HERO *\/\n.page-hero {\nbackground: linear-gradient(135deg, var(--navy) 0%, var(--navy-light) 60%, var(--navy-deep) 100%);\ncolor: white;\npadding: 70px 5% 60px;\nposition: relative;\noverflow: hidden;\nborder-bottom: 4px solid var(--gold);\n}\n.page-hero::before {\ncontent: '';\nposition: absolute;\ntop: -50%; right: -10%;\nwidth: 700px; height: 700px;\nbackground: radial-gradient(circle, rgba(212,175,55,0.08) 0%, transparent 70%);\n}\n.hero-container {\nmax-width: 1200px;\nmargin: 0 auto;\nposition: relative;\nz-index: 1;\n}\n.hero-eyebrow {\ndisplay: inline-block;\nfont-size: 7pt;\nletter-spacing: 4px;\ntext-transform: uppercase;\ncolor: var(--gold);\nfont-weight: 700;\nmargin-bottom: 18px;\npadding: 5px 14px;\nborder: 1px solid var(--gold);\nbackground: rgba(212,175,55,0.08);\n}\n.hero-title {\nfont-family: 'Cinzel', serif;\nfont-size: clamp(2rem, 4.5vw, 3.2rem);\nfont-weight: 800;\ncolor: var(--gold);\nline-height: 1.1;\nmargin-bottom: 14px;\nletter-spacing: 0.5px;\n}\n.hero-subtitle {\nfont-family: 'Cormorant Garamond', serif;\nfont-size: 1.25rem;\ncolor: var(--gold-light);\nfont-style: italic;\nmax-width: 680px;\nline-height: 1.5;\nletter-spacing: 0.3px;\nmargin-bottom: 24px;\n}\n.hero-chips {\ndisplay: flex;\ngap: 12px;\nflex-wrap: wrap;\nmargin-bottom: 20px;\n}\n.hero-chip {\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 7.5pt;\nletter-spacing: 1.5px;\ntext-transform: uppercase;\ncolor: #CBD5E0;\npadding: 6px 14px;\nbackground: rgba(255,255,255,0.05);\nborder: 1px solid rgba(212,175,55,0.3);\n}\n.hero-chip strong { color: var(--gold); font-weight: 600; }\n\n\/* MAIN *\/\nmain {\nmax-width: 1200px;\nmargin: 0 auto;\npadding: 60px 5% 100px;\n}\n\n\/* SECTIONS *\/\n.section {\nmargin-bottom: 55px;\n}\n.section-num {\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 8pt;\nletter-spacing: 3px;\ntext-transform: uppercase;\ncolor: var(--gold-dark);\nfont-weight: 700;\nmargin-bottom: 8px;\ndisplay: block;\n}\n.section h2 {\nfont-family: 'Cinzel', serif;\nfont-size: 1.75rem;\nfont-weight: 700;\ncolor: var(--navy);\nline-height: 1.25;\nmargin-bottom: 20px;\npadding-bottom: 12px;\nborder-bottom: 3px solid var(--gold);\nletter-spacing: 0.3px;\n}\n.section h3 {\nfont-family: 'Cinzel', serif;\nfont-size: 1.15rem;\nfont-weight: 700;\ncolor: var(--navy);\nmargin: 26px 0 12px 0;\nletter-spacing: 0.3px;\nborder-left: 3px solid var(--gold);\npadding-left: 14px;\n}\n.section p {\nfont-size: 1rem;\nline-height: 1.75;\nmargin-bottom: 14px;\ntext-align: justify;\ncolor: #2D3748;\n}\n.section p strong { color: var(--navy); font-weight: 600; }\n\n\/* LEAD *\/\n.lead {\nfont-family: 'Cormorant Garamond', serif;\nfont-size: 1.25rem;\nline-height: 1.65;\ncolor: var(--navy);\nmargin-bottom: 40px;\npadding: 26px 30px;\nborder-top: 2px solid var(--gold);\nborder-bottom: 2px solid var(--gold);\nbackground: linear-gradient(180deg, rgba(212,175,55,0.04) 0%, transparent 100%);\nfont-style: italic;\n}\n\n\/* SANDBOX CONTAINER *\/\n.sandbox-container {\nbackground: white;\nborder: 2px solid var(--gold);\nborder-top: 5px solid var(--gold);\npadding: 0;\nmargin: 30px 0;\nbox-shadow: 0 10px 40px rgba(11,19,43,0.1);\n}\n.sandbox-header {\nbackground: var(--navy);\ncolor: white;\npadding: 24px 32px;\nborder-bottom: 2px solid var(--gold);\n}\n.sandbox-header h3 {\nfont-family: 'Cinzel', serif;\ncolor: var(--gold);\nfont-size: 1.3rem;\nmargin-bottom: 6px;\nborder: none;\npadding: 0;\nletter-spacing: 0.5px;\n}\n.sandbox-header p {\ncolor: #CBD5E0;\nfont-size: 0.9rem;\nmargin: 0;\n}\n.sandbox-body {\npadding: 32px;\n}\n\n\/* STEPS INDICATOR *\/\n.steps-indicator {\ndisplay: flex;\njustify-content: space-between;\nmargin-bottom: 40px;\nposition: relative;\npadding: 0 20px;\n}\n.steps-indicator::before {\ncontent: '';\nposition: absolute;\ntop: 20px;\nleft: 40px;\nright: 40px;\nheight: 2px;\nbackground: var(--border);\nz-index: 0;\n}\n.step-dot {\nposition: relative;\nz-index: 1;\ndisplay: flex;\nflex-direction: column;\nalign-items: center;\ngap: 8px;\nflex: 1;\n}\n.step-circle {\nwidth: 42px; height: 42px;\nborder-radius: 50%;\nbackground: white;\nborder: 3px solid var(--border);\ndisplay: flex;\nalign-items: center;\njustify-content: center;\nfont-family: 'Cinzel', serif;\nfont-weight: 700;\ncolor: var(--muted);\nfont-size: 1rem;\ntransition: all 0.3s;\n}\n.step-dot.active .step-circle {\nbackground: var(--gold);\nborder-color: var(--gold);\ncolor: var(--navy);\n}\n.step-dot.completed .step-circle {\nbackground: var(--green);\nborder-color: var(--green);\ncolor: white;\n}\n.step-label {\nfont-size: 0.72rem;\nletter-spacing: 1px;\ntext-transform: uppercase;\ncolor: var(--muted);\nfont-weight: 600;\ntext-align: center;\n}\n.step-dot.active .step-label { color: var(--gold-dark); }\n.step-dot.completed .step-label { color: var(--green); }\n\n\/* FORM SECTIONS *\/\n.form-section {\nmargin-bottom: 32px;\npadding-bottom: 32px;\nborder-bottom: 1px solid var(--border);\n}\n.form-section:last-child { border-bottom: none; }\n.form-section h4 {\nfont-family: 'Cinzel', serif;\nfont-size: 1.1rem;\ncolor: var(--navy);\nmargin-bottom: 16px;\nletter-spacing: 0.3px;\n}\n.form-grid {\ndisplay: grid;\ngrid-template-columns: 1fr 1fr;\ngap: 16px;\nmargin-bottom: 16px;\n}\n.form-group {\ndisplay: flex;\nflex-direction: column;\ngap: 6px;\n}\n.form-group label {\nfont-size: 0.78rem;\nletter-spacing: 1px;\ntext-transform: uppercase;\ncolor: var(--muted);\nfont-weight: 600;\n}\n.form-group input,\n.form-group select,\n.form-group textarea {\npadding: 10px 14px;\nborder: 1px solid var(--border);\nfont-family: 'Inter', sans-serif;\nfont-size: 0.9rem;\ncolor: var(--text);\nbackground: white;\ntransition: border-color 0.2s;\n}\n.form-group input:focus,\n.form-group select:focus,\n.form-group textarea:focus {\noutline: none;\nborder-color: var(--gold);\n}\n.form-group textarea {\nmin-height: 80px;\nresize: vertical;\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.82rem;\n}\n\n\/* SCORE DISPLAY *\/\n.score-display {\nbackground: linear-gradient(135deg, var(--navy) 0%, var(--navy-light) 100%);\ncolor: white;\npadding: 28px;\nmargin: 24px 0;\nborder-left: 5px solid var(--gold);\ntext-align: center;\n}\n.score-label {\nfont-size: 0.78rem;\nletter-spacing: 2px;\ntext-transform: uppercase;\ncolor: var(--gold);\nfont-weight: 700;\nmargin-bottom: 8px;\n}\n.score-value {\nfont-family: 'Cinzel', serif;\nfont-size: 4rem;\nfont-weight: 800;\ncolor: var(--gold-light);\nline-height: 1;\nmargin-bottom: 8px;\n}\n.score-status {\nfont-family: 'Cinzel', serif;\nfont-size: 1.1rem;\nletter-spacing: 2px;\ntext-transform: uppercase;\nfont-weight: 700;\npadding: 6px 16px;\ndisplay: inline-block;\nborder-radius: 2px;\n}\n.score-status.verified {\nbackground: rgba(47,133,90,0.2);\ncolor: #68D391;\nborder: 1px solid var(--green);\n}\n.score-status.conditional {\nbackground: rgba(183,121,31,0.2);\ncolor: var(--gold-light);\nborder: 1px solid var(--amber);\n}\n.score-status.revoked {\nbackground: rgba(197,48,48,0.2);\ncolor: #FC8181;\nborder: 1px solid var(--red);\n}\n.score-breakdown {\nmargin-top: 20px;\ndisplay: grid;\ngrid-template-columns: repeat(5, 1fr);\ngap: 10px;\n}\n.breakdown-item {\ntext-align: center;\n}\n.breakdown-label {\nfont-size: 0.68rem;\ncolor: #CBD5E0;\nletter-spacing: 1px;\ntext-transform: uppercase;\nmargin-bottom: 4px;\n}\n.breakdown-value {\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 1.1rem;\ncolor: white;\nfont-weight: 700;\n}\n.breakdown-weight {\nfont-size: 0.65rem;\ncolor: var(--gold-dark);\nmargin-top: 2px;\n}\n\n\/* CODE OUTPUT *\/\n.code-output {\nbackground: var(--navy-deep);\ncolor: #E2E8F0;\npadding: 20px 24px;\nmargin: 16px 0;\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.82rem;\nline-height: 1.6;\noverflow-x: auto;\nborder-left: 4px solid var(--gold);\nwhite-space: pre;\nmax-height: 400px;\n}\n.code-output .kw { color: var(--gold); }\n.code-output .str { color: #68D391; }\n.code-output .num { color: #F6AD55; }\n.code-output .cm { color: #718096; }\n\n\/* HASH DISPLAY *\/\n.hash-display {\nbackground: var(--bg);\nborder: 2px solid var(--gold);\npadding: 20px;\nmargin: 16px 0;\ntext-align: center;\n}\n.hash-label {\nfont-size: 0.75rem;\nletter-spacing: 2px;\ntext-transform: uppercase;\ncolor: var(--gold-dark);\nfont-weight: 700;\nmargin-bottom: 10px;\n}\n.hash-value {\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.85rem;\ncolor: var(--navy);\nword-break: break-all;\nline-height: 1.5;\nfont-weight: 600;\n}\n\n\/* CLAIM CARD *\/\n.claim-card {\nbackground: linear-gradient(135deg, var(--navy) 0%, var(--navy-deep) 100%);\ncolor: white;\npadding: 28px;\nmargin: 24px 0;\nborder-top: 4px solid var(--gold);\nborder-bottom: 4px solid var(--gold);\n}\n.claim-header {\ndisplay: flex;\njustify-content: space-between;\nalign-items: center;\nmargin-bottom: 20px;\npadding-bottom: 16px;\nborder-bottom: 1px solid rgba(212,175,55,0.3);\n}\n.claim-title {\nfont-family: 'Cinzel', serif;\ncolor: var(--gold);\nfont-size: 1.2rem;\nletter-spacing: 0.5px;\n}\n.claim-status {\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.78rem;\npadding: 4px 12px;\nbackground: rgba(47,133,90,0.2);\ncolor: #68D391;\nborder: 1px solid var(--green);\nletter-spacing: 1px;\ntext-transform: uppercase;\nfont-weight: 700;\n}\n.claim-grid {\ndisplay: grid;\ngrid-template-columns: 1fr 1fr;\ngap: 16px;\n}\n.claim-field {\npadding: 10px 0;\nborder-bottom: 1px dashed rgba(255,255,255,0.1);\n}\n.claim-field:last-child { border-bottom: none; }\n.claim-field-label {\nfont-size: 0.68rem;\nletter-spacing: 1.5px;\ntext-transform: uppercase;\ncolor: var(--gold-dark);\nmargin-bottom: 4px;\nfont-weight: 700;\n}\n.claim-field-value {\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.82rem;\ncolor: #E2E8F0;\nword-break: break-all;\nline-height: 1.4;\n}\n\n\/* BUTTONS *\/\n.btn {\ndisplay: inline-block;\npadding: 14px 32px;\nfont-family: 'Cinzel', serif;\nfont-weight: 700;\nfont-size: 9pt;\nletter-spacing: 2px;\ntext-transform: uppercase;\ntext-decoration: none;\ntransition: all 0.3s;\ncursor: pointer;\nborder: 2px solid;\n}\n.btn-primary {\nbackground: var(--gold);\ncolor: var(--navy);\nborder-color: var(--gold);\n}\n.btn-primary:hover {\nbackground: var(--gold-light);\ntransform: translateY(-2px);\nbox-shadow: 0 8px 24px rgba(212,175,55,0.3);\n}\n.btn-secondary {\nbackground: white;\ncolor: var(--navy);\nborder-color: var(--navy);\n}\n.btn-secondary:hover {\nbackground: var(--navy);\ncolor: var(--gold);\n}\n.btn-danger {\nbackground: var(--red);\ncolor: white;\nborder-color: var(--red);\n}\n.btn-danger:hover {\nbackground: #9B2C2C;\n}\n.button-group {\ndisplay: flex;\ngap: 12px;\nmargin-top: 24px;\nflex-wrap: wrap;\n}\n\n\/* CODE EXAMPLES *\/\n.code-examples {\nmargin: 30px 0;\n}\n.code-tabs {\ndisplay: flex;\ngap: 4px;\nmargin-bottom: 0;\nborder-bottom: 2px solid var(--gold);\n}\n.code-tab {\npadding: 10px 20px;\nbackground: var(--bg);\nborder: 1px solid var(--border);\nborder-bottom: none;\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.82rem;\ncolor: var(--muted);\ncursor: pointer;\ntransition: all 0.2s;\n}\n.code-tab.active {\nbackground: var(--navy);\ncolor: var(--gold);\nborder-color: var(--gold);\n}\n.code-tab:hover:not(.active) {\nbackground: white;\n}\n.code-panel {\ndisplay: none;\nbackground: var(--navy-deep);\npadding: 24px;\nborder: 1px solid var(--border);\nborder-top: none;\n}\n.code-panel.active { display: block; }\n.code-panel pre {\nmargin: 0;\nfont-family: 'JetBrains Mono', monospace;\nfont-size: 0.82rem;\nline-height: 1.6;\ncolor: #E2E8F0;\nwhite-space: pre;\noverflow-x: auto;\n}\n\n\/* NEXT STEPS *\/\n.next-steps {\nbackground: var(--bg);\nborder: 2px solid var(--gold);\npadding: 32px;\nmargin: 40px 0;\n}\n.next-steps h3 {\nfont-family: 'Cinzel', serif;\ncolor: var(--navy);\nfont-size: 1.3rem;\nmargin-bottom: 16px;\nborder: none;\npadding: 0;\n}\n.next-steps-grid {\ndisplay: grid;\ngrid-template-columns: repeat(auto-fit, minmax(240px, 1fr));\ngap: 16px;\nmargin-top: 20px;\n}\n.next-step-card {\nbackground: white;\nborder: 1px solid var(--border);\nborder-top: 3px solid var(--gold);\npadding: 20px;\n}\n.next-step-card h4 {\nfont-family: 'Cinzel', serif;\nfont-size: 1rem;\ncolor: var(--navy);\nmargin-bottom: 8px;\n}\n.next-step-card p {\nfont-size: 0.88rem;\ncolor: var(--muted);\nline-height: 1.5;\nmargin-bottom: 12px;\n}\n.next-step-card a {\ncolor: var(--gold-dark);\nfont-weight: 600;\ntext-decoration: none;\nfont-size: 0.85rem;\n}\n.next-step-card a:hover { text-decoration: underline; }\n\n\/* ECOSYSTEM FOOTER *\/\n.ecosystem-footer {\nbackground: var(--navy-deep);\ncolor: #A0AEC0;\npadding: 50px 5% 30px;\nborder-top: 3px solid var(--gold);\n}\n.ecosystem-container { max-width: 1200px; margin: 0 auto; }\n.ecosystem-label { text-align: center; margin-bottom: 30px; }\n.ecosystem-motto {\ndisplay: block;\nfont-family: 'Cinzel', serif;\ncolor: var(--gold);\nletter-spacing: 4px;\nfont-style: italic;\nfont-size: 0.9rem;\nmargin-bottom: 10px;\n}\n.ecosystem-title {\ndisplay: block;\nfont-family: 'Cinzel', serif;\ncolor: white;\nfont-size: 1.2rem;\nletter-spacing: 2px;\n}\n.ecosystem-grid {\ndisplay: grid;\ngrid-template-columns: repeat(auto-fit, minmax(220px, 1fr));\ngap: 16px;\nmargin-bottom: 30px;\n}\n.eco-link {\ndisplay: block;\nbackground: rgba(255,255,255,0.03);\nborder: 1px solid rgba(212,175,55,0.2);\nborder-left: 3px solid var(--gold);\npadding: 18px 20px;\ntext-decoration: none;\ncolor: inherit;\ntransition: all 0.3s;\n}\n.eco-link:hover {\nbackground: rgba(212,175,55,0.08);\ntransform: translateX(4px);\n}\n.eco-role {\ndisplay: block;\nfont-size: 0.62rem;\nletter-spacing: 2px;\ntext-transform: uppercase;\ncolor: var(--gold-dark);\nmargin-bottom: 4px;\nfont-weight: 700;\n}\n.eco-link strong {\ndisplay: block;\ncolor: white;\nfont-family: 'Cinzel', serif;\nfont-size: 0.9rem;\nmargin-bottom: 4px;\n}\n.eco-desc {\ndisplay: block;\nfont-size: 0.75rem;\ncolor: #CBD5E0;\nline-height: 1.4;\n}\n.ecosystem-footnote {\ntext-align: center;\nfont-size: 0.72rem;\ncolor: #718096;\nline-height: 1.6;\npadding-top: 20px;\nborder-top: 1px solid rgba(212,175,55,0.15);\n}\n.ecosystem-footnote a { color: var(--gold); text-decoration: none; }\n\n\/* RESPONSIVE *\/\n@media (max-width: 768px) {\n.form-grid { grid-template-columns: 1fr; }\n.score-breakdown { grid-template-columns: repeat(2, 1fr); }\n.claim-grid { grid-template-columns: 1fr; }\n.steps-indicator { flex-wrap: wrap; }\n.step-dot { flex: 0 0 calc(33% - 10px); margin-bottom: 10px; }\n.sandbox-body { padding: 20px; }\nmain { padding: 40px 6%; }\n.section h2 { font-size: 1.4rem; }\n}\n<\/style>\n<\/head>\n<body>\n\n<!-- HEADER NAV -->\n<header class=\"site-header\">\n<div class=\"header-container\">\n<a href=\"\/\" class=\"brand-link\">\n<div class=\"brand-seal\"><img decoding=\"async\" src=\"https:\/\/forensics-oracle.org\/wp-content\/uploads\/2026\/08\/cropped-cropped_circle_image.png\" alt=\"Sello FOI\"><\/div>\n<div class=\"brand-text\">Prop Trust Verified<span class=\"brand-sub\">Certification &middot; PTCE Network<\/span><\/div>\n<\/a>\n<nav>\n<ul class=\"nav-links\">\n<li><a href=\"\/\">Home<\/a><\/li>\n<li><a href=\"\/standard\/\">PTVS Standard<\/a><\/li>\n<li><a href=\"\/ptce-registry\/\">PTCE Registry<\/a><\/li>\n<li><a href=\"\/sandbox\/\" class=\"active\">Sandbox<\/a><\/li>\n<li><a href=\"\/vendor-register\/\">Register<\/a><\/li>\n<\/ul>\n<\/nav>\n<\/div>\n<\/header>\n\n<!-- HERO -->\n<section class=\"page-hero\">\n<div class=\"hero-container\">\n<span class=\"hero-eyebrow\">Interactive Playground &middot; No Backend Required<\/span>\n<h1 class=\"hero-title\">PTVS Sandbox<\/h1>\n<p class=\"hero-subtitle\">Experience the Prop Trust Verified Standard in your browser. Create a mock asset, generate forensic evidence, compute cryptographic hashes, and simulate on-chain Verifiable Claim injection &mdash; all in 5 minutes.\n<\/p>\n<div class=\"hero-chips\">\n<span class=\"hero-chip\">Standard <strong>PTVS v1.0<\/strong><\/span>\n<span class=\"hero-chip\">Environment <strong>Browser-based<\/strong><\/span>\n<span class=\"hero-chip\">Time &middot; <strong>~5 minutes<\/strong><\/span>\n<\/div>\n<\/div>\n<\/section>\n\n<!-- MAIN -->\n<main>\n\n<!-- LEAD -->\n<p class=\"lead\">This sandbox demonstrates the complete PTVS v1.0 verification flow: from physical asset inspection to on-chain Verifiable Claim injection. All computations happen in your browser using the Web Crypto API. No data is sent to any server. When you&#8217;re ready to integrate PTVS into production, visit our <a href=\"\/standard\/\" style=\"color: var(--gold-dark); font-weight: 600;\">documentation<\/a> or contact our technical team.\n<\/p>\n\n<!-- SECTION 1: SANDBOX -->\n<section class=\"section\">\n<span class=\"section-num\">Section I<\/span>\n<h2>Interactive Playground<\/h2>\n\n<div class=\"sandbox-container\">\n<div class=\"sandbox-header\">\n<h3>PTVS v1.0 Verification Flow Simulator<\/h3>\n<p>Complete the 6 steps below to generate a mock Verifiable Claim<\/p>\n<\/div>\n\n<div class=\"sandbox-body\">\n\n<!-- STEPS INDICATOR -->\n<div class=\"steps-indicator\">\n<div class=\"step-dot active\" data-step=\"1\">\n<div class=\"step-circle\">1<\/div>\n<div class=\"step-label\">Asset<\/div>\n<\/div>\n<div class=\"step-dot\" data-step=\"2\">\n<div class=\"step-circle\">2<\/div>\n<div class=\"step-label\">Evidence<\/div>\n<\/div>\n<div class=\"step-dot\" data-step=\"3\">\n<div class=\"step-circle\">3<\/div>\n<div class=\"step-label\">Score<\/div>\n<\/div>\n<div class=\"step-dot\" data-step=\"4\">\n<div class=\"step-circle\">4<\/div>\n<div class=\"step-label\">Hash<\/div>\n<\/div>\n<div class=\"step-dot\" data-step=\"5\">\n<div class=\"step-circle\">5<\/div>\n<div class=\"step-label\">Claim<\/div>\n<\/div>\n<div class=\"step-dot\" data-step=\"6\">\n<div class=\"step-circle\">6<\/div>\n<div class=\"step-label\">Verify<\/div>\n<\/div>\n<\/div>\n\n<!-- STEP 1: ASSET -->\n<div class=\"form-section\" id=\"step1\">\n<h4>Step 1: Define the Asset<\/h4>\n<div class=\"form-grid\">\n<div class=\"form-group\">\n<label>Asset Type<\/label>\n<select id=\"assetType\">\n<option value=\"real_estate\">Real Estate<\/option>\n<option value=\"naval\">Naval Vessel<\/option>\n<option value=\"infrastructure\">Infrastructure<\/option>\n<option value=\"agricultural\">Agricultural Land<\/option>\n<option value=\"industrial\">Industrial Facility<\/option>\n<\/select>\n<\/div>\n<div class=\"form-group\">\n<label>Asset ID (bytes32)<\/label>\n<input type=\"text\" id=\"assetId\" value=\"0x1a2b3c4d5e6f7890abcdef1234567890abcdef1234567890abcdef12345678\" readonly>\n<\/div>\n<div class=\"form-group\">\n<label>Asset Name<\/label>\n<input type=\"text\" id=\"assetName\" value=\"Edificio residencial &middot; Calle Mayor 42, Valencia\">\n<\/div>\n<div class=\"form-group\">\n<label>Jurisdiction<\/label>\n<select id=\"jurisdiction\">\n<option value=\"ES-VC\">Spain &middot; Comunitat Valenciana<\/option>\n<option value=\"ES-M\">Spain &middot; Madrid<\/option>\n<option value=\"ES-CT\">Spain &middot; Catalonia<\/option>\n<option value=\"DE-BY\">Germany &middot; Bavaria<\/option>\n<option value=\"FR-IDF\">France &middot; &Icirc;le-de-France<\/option>\n<option value=\"IT-LM\">Italy &middot; Lombardia<\/option>\n<option value=\"NL-NH\">Netherlands &middot; Noord-Holland<\/option>\n<option value=\"CH-ZH\">Switzerland &middot; Z&uuml;rich<\/option>\n<\/select>\n<\/div>\n<\/div>\n<div class=\"button-group\">\n<button class=\"btn btn-primary\" onclick=\"nextStep(2)\">Continue to Evidence &rarr;<\/button>\n<\/div>\n<\/div>\n\n<!-- STEP 2: EVIDENCE -->\n<div class=\"form-section\" id=\"step2\" style=\"display: none;\">\n<h4>Step 2: Forensic Inspection Findings<\/h4>\n<p style=\"font-size: 0.88rem; color: var(--muted); margin-bottom: 16px;\">Rate each category from 0-100. These scores will be weighted to calculate the final PTVS Score.\n<\/p>\n\n<div class=\"form-grid\">\n<div class=\"form-group\">\n<label>Structural Score (40% weight)<\/label>\n<input type=\"range\" id=\"structuralScore\" min=\"0\" max=\"100\" value=\"85\" oninput=\"updateScoreDisplay()\">\n<span id=\"structuralValue\" style=\"font-family: 'JetBrains Mono', monospace; color: var(--gold-dark);\">85<\/span>\n<\/div>\n<div class=\"form-group\">\n<label>Legal score (25% weight)<\/label>\n<input type=\"range\" id=\"legalScore\" min=\"0\" max=\"100\" value=\"92\" oninput=\"updateScoreDisplay()\">\n<span id=\"legalValue\" style=\"font-family: 'JetBrains Mono', monospace; color: var(--gold-dark);\">92<\/span>\n<\/div>\n<div class=\"form-group\">\n<label>Environmental Score (20% weight)<\/label>\n<input type=\"range\" id=\"environmentalScore\" min=\"0\" max=\"100\" value=\"78\" oninput=\"updateScoreDisplay()\">\n<span id=\"environmentalValue\" style=\"font-family: 'JetBrains Mono', monospace; color: var(--gold-dark);\">78<\/span>\n<\/div>\n<div class=\"form-group\">\n<label>Documentation Score (10% weight)<\/label>\n<input type=\"range\" id=\"documentationScore\" min=\"0\" max=\"100\" value=\"95\" oninput=\"updateScoreDisplay()\">\n<span id=\"documentationValue\" style=\"font-family: 'JetBrains Mono', monospace; color: var(--gold-dark);\">95<\/span>\n<\/div>\n<div class=\"form-group\">\n<label>Insurance Score (5% weight)<\/label>\n<input type=\"range\" id=\"insuranceScore\" min=\"0\" max=\"100\" value=\"88\" oninput=\"updateScoreDisplay()\">\n<span id=\"insuranceValue\" style=\"font-family: 'JetBrains Mono', monospace; color: var(--gold-dark);\">88<\/span>\n<\/div>\n<\/div>\n\n<div class=\"form-group\" style=\"margin-top: 16px;\">\n<label>Inspector Notes (optional)<\/label>\n<textarea id=\"inspectorNotes\" placeholder=\"e.g., Minor corrosion detected on balcony railings. Recommend treatment within 6 months.\">Minor corrosion detected on balcony railings. Recommend treatment within 6 months. All structural elements sound. Title clear, don&#8217;t break up.<\/textarea>\n<\/div>\n\n<div class=\"button-group\">\n<button class=\"btn btn-secondary\" onclick=\"prevStep(1)\">&larr; Back<\/button>\n<button class=\"btn btn-primary\" onclick=\"nextStep(3)\">Calculate PTVS Score &rarr;<\/button>\n<\/div>\n<\/div>\n\n<!-- STEP 3: SCORE -->\n<div class=\"form-section\" id=\"step3\" style=\"display: none;\">\n<h4>Step 3: PTVS Score Calculation<\/h4>\n\n<div class=\"score-display\">\n<div class=\"score-label\">PTVS Score<\/div>\n<div class=\"score-value\" id=\"ptvsScoreDisplay\">0<\/div>\n<div class=\"score-status\" id=\"scoreStatus\">CALCULATING<\/div>\n\n<div class=\"score-breakdown\">\n<div class=\"breakdown-item\">\n<div class=\"breakdown-label\">Structural<\/div>\n<div class=\"breakdown-value\" id=\"breakdownStructural\">0<\/div>\n<div class=\"breakdown-weight\">40%<\/div>\n<\/div>\n<div class=\"breakdown-item\">\n<div class=\"breakdown-label\">Legal<\/div>\n<div class=\"breakdown-value\" id=\"breakdownLegal\">0<\/div>\n<div class=\"breakdown-weight\">25%<\/div>\n<\/div>\n<div class=\"breakdown-item\">\n<div class=\"breakdown-label\">Environmental<\/div>\n<div class=\"breakdown-value\" id=\"breakdownEnvironmental\">0<\/div>\n<div class=\"breakdown-weight\">20%<\/div>\n<\/div>\n<div class=\"breakdown-item\">\n<div class=\"breakdown-label\">Documentation<\/div>\n<div class=\"breakdown-value\" id=\"breakdownDocumentation\">0<\/div>\n<div class=\"breakdown-weight\">10%<\/div>\n<\/div>\n<div class=\"breakdown-item\">\n<div class=\"breakdown-label\">Insurance<\/div>\n<div class=\"breakdown-value\" id=\"breakdownInsurance\">0<\/div>\n<div class=\"breakdown-weight\">5%<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"button-group\">\n<button class=\"btn btn-secondary\" onclick=\"prevStep(2)\">&larr; Back<\/button>\n<button class=\"btn btn-primary\" onclick=\"nextStep(4)\">Generate Canonical JSON &rarr;<\/button>\n<\/div>\n<\/div>\n\n<!-- STEP 4: HASH -->\n<div class=\"form-section\" id=\"step4\" style=\"display: none;\">\n<h4>Step 4: Canonical JSON &amp; SHA-256 Hash<\/h4>\n\n<p style=\"font-size: 0.88rem; color: var(--muted); margin-bottom: 16px;\">The inspection findings are serialized into canonical JSON (deterministic format) and hashed using SHA-256. This hash will be anchored on-chain.\n<\/p>\n\n<div class=\"code-output\" id=\"canonicalJsonOutput\"><\/div>\n\n<div class=\"hash-display\">\n<div class=\"hash-label\">SHA-256 Hash (forensicHash)<\/div>\n<div class=\"hash-value\" id=\"hashValue\">Computing. ..<\/div>\n<\/div>\n\n<div class=\"button-group\">\n<button class=\"btn btn-secondary\" onclick=\"prevStep(3)\">&larr; Back<\/button>\n<button class=\"btn btn-primary\" onclick=\"nextStep(5)\">Inject Claim On-Chain &rarr;<\/button>\n<\/div>\n<\/div>\n\n<!-- STEP 5: CLAIM -->\n<div class=\"form-section\" id=\"step5\" style=\"display: none;\">\n<h4>Step 5: On-Chain Verifiable Claim<\/h4>\n\n<p style=\"font-size: 0.88rem; color: var(--muted); margin-bottom: 16px;\">The Verifiable Claim is injected into the PTVSClaimInjector smart contract. In production, this would be a real Ethereum transaction. Here we simulate it.\n<\/p>\n\n<div class=\"claim-card\">\n<div class=\"claim-header\">\n<div class=\"claim-title\">Verifiable Claim #<span id=\"claimId\">001<\/span><\/div>\n<div class=\"claim-status\">INJECTED<\/div>\n<\/div>\n<div class=\"claim-grid\">\n<div class=\"claim-field\">\n<div class=\"claim-field-label\">Asset ID<\/div>\n<div class=\"claim-field-value\" id=\"claimAssetId\"><\/div>\n<\/div>\n<div class=\"claim-field\">\n<div class=\"claim-field-label\">PTVS Score<\/div>\n<div class=\"claim-field-value\" id=\"claimScore\"><\/div>\n<\/div>\n<div class=\"claim-field\">\n<div class=\"claim-field-label\">Forensic Hash<\/div>\n<div class=\"claim-field-value\" id=\"claimHash\"><\/div>\n<\/div>\n<div class=\"claim-field\">\n<div class=\"claim-field-label\">Inspection Timestamp<\/div>\n<div class=\"claim-field-value\" id=\"claimTimestamp\"><\/div>\n<\/div>\n<div class=\"claim-field\">\n<div class=\"claim-field-label\">PTCE Address<\/div>\n<div class=\"claim-field-value\">0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb<\/div>\n<\/div>\n<div class=\"claim-field\">\n<div class=\"claim-field-label\">Status<\/div>\n<div class=\"claim-field-value\" id=\"claimStatus\">VERIFIED<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div class=\"code-output\" id=\"solidityEventOutput\"><\/div>\n\n<div class=\"button-group\">\n<button class=\"btn btn-secondary\" onclick=\"prevStep(4)\">&larr; Back<\/button>\n<button class=\"btn btn-primary\" onclick=\"nextStep(6)\">Verify Claim &rarr;<\/button>\n<\/div>\n<\/div>\n\n<!-- STEP 6: VERIFY -->\n<div class=\"form-section\" id=\"step6\" style=\"display: none;\">\n<h4>Step 6: Independent Verification<\/h4>\n\n<p style=\"font-size: 0.88rem; color: var(--muted); margin-bottom: 16px;\">Any third party can verify this claim by recomputing the SHA-256 hash from the canonical JSON and comparing it with the on-chain forensicHash.\n<\/p>\n\n<div style=\"background: var(--bg); padding: 24px; border: 2px solid var(--green); margin: 20px 0;\">\n<div style=\"display: flex; align-items: center; gap: 12px; margin-bottom: 16px;\">\n<div style=\"width: 40px; height: 40px; background: var(--green); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-size: 1.5rem;\">&#10003;<\/div>\n<div>\n<div style=\"font-family: 'Cinzel', serif; font-size: 1.1rem; color: var(--green); font-weight: 700;\">Verification Successful<\/div>\n<div style=\"font-size: 0.88rem; color: var(--muted);\">The on-chain claim matches the original inspection report<\/div>\n<\/div>\n<\/div>\n\n<div style=\"font-family: 'JetBrains Mono', monospace; font-size: 0.82rem; line-height: 1.6;\">\n<div><span style=\"color: var(--muted);\">Recomputed hash:<\/span> <span id=\"verifyHash1\" style=\"color: var(--navy); font-weight: 600;\"><\/span><\/div>\n<div><span style=\"color: var(--muted);\">On-chain hash:<\/span> <span id=\"verifyHash2\" style=\"color: var(--navy); font-weight: 600;\"><\/span><\/div>\n<div style=\"margin-top: 8px; color: var(--green); font-weight: 700;\">&#10003; MATCH<\/div>\n<\/div>\n<\/div>\n\n<div class=\"button-group\">\n<button class=\"btn btn-secondary\" onclick=\"resetSandbox()\">&#8635; Start Over<\/button>\n<button class=\"btn btn-primary\" onclick=\"window.location.href='\/vendor-register\/'\">Become a PTCE &rarr;<\/button>\n<\/div>\n<\/div>\n\n<\/div>\n<\/div>\n<\/section>\n\n<!-- SECTION 2: CODE EXAMPLES -->\n<section class=\"section\">\n<span class=\"section-num\">Section II<\/span>\n<h2>Integration Examples<\/h2>\n\n<p>Ready to integrate PTVS into your platform? Here are code examples in Python, JavaScript, and Solidity.<\/p>\n\n<div class=\"code-examples\">\n<div class=\"code-tabs\">\n<div class=\"code-tab active\" onclick=\"switchTab('python')\">Python<\/div>\n<div class=\"code-tab\" onclick=\"switchTab('javascript')\">JavaScript<\/div>\n<div class=\"code-tab\" onclick=\"switchTab('solidity')\">Solidity<\/div>\n<\/div>\n\n<div class=\"code-panel active\" id=\"panel-python\">\n<pre><span style=\"color: #718096;\"># Install: pip install pycryptodome web3<\/span>\n\n<span style=\"color: #F6AD55;\">from<\/span> Crypto.Hash <span style=\"color: #F6AD55;\">import<\/span> SHA256\n<span style=\"color: #F6AD55;\">import<\/span> json\n<span style=\"color: #F6AD55;\">from<\/span> web3 <span style=\"color: #F6AD55;\">import<\/span> Web3\n\n<span style=\"color: #718096;\"># 1. Create canonical JSON<\/span>\ninspection_data = {\n    <span style=\"color: #68D391;\">\"assetId\"<\/span>: <span style=\"color: #68D391;\">\"0x1a2b3c4d5e6f\"<\/span>,\n    <span style=\"color: #68D391;\">\"inspectionDate\"<\/span>: <span style=\"color: #68D391;\">\"2026-08-15T10:30:00Z\"<\/span>,\n    <span style=\"color: #68D391;\">\"ptceId\"<\/span>: <span style=\"color: #68D391;\">\"PTCE-0161\"<\/span>,\n    <span style=\"color: #68D391;\">\"ptvsScore\"<\/span>: <span style=\"color: #F6AD55;\">85<\/span>,\n    <span style=\"color: #68D391;\">\"findings\"<\/span>: {\n        <span style=\"color: #68D391;\">\"structural\"<\/span>: {<span style=\"color: #68D391;\">\"cracks\"<\/span>: <span style=\"color: #F6AD55;\">0<\/span>, <span style=\"color: #68D391;\">\"corrosion\"<\/span>: <span style=\"color: #F6AD55;\">1<\/span>},\n        <span style=\"color: #68D391;\">\"legal\"<\/span>: {<span style=\"color: #68D391;\">\"encumbrances\"<\/span>: <span style=\"color: #F6AD55;\">0<\/span>, <span style=\"color: #68D391;\">\"titleClear\"<\/span>: <span style=\"color: #F6AD55;\">True<\/span>}\n    }\n}\n\n<span style=\"color: #718096;\"># 2. Canonicalize (sorted keys, no whitespace)<\/span>\ncanonical_json = json.dumps(inspection_data, sort_keys=<span style=\"color: #F6AD55;\">True<\/span>, separators=(<span style=\"color: #68D391;\">','<\/span>, <span style=\"color: #68D391;\">':'<\/span>))\n\n<span style=\"color: #718096;\"># 3. Compute SHA-256 hash<\/span>\nhash_obj = SHA256.new(canonical_json.encode(<span style=\"color: #68D391;\">'utf-8'<\/span>))\nforensic_hash = hash_obj.hexdigest()\n\n<span style=\"color: #718096;\"># 4. Inject claim on-chain<\/span>\nw3 = Web3(Web3.HTTPProvider(<span style=\"color: #68D391;\">'https:\/\/mainnet.infura.io\/v3\/YOUR_KEY'<\/span>))\ncontract = w3.eth.contract(address=<span style=\"color: #68D391;\">'0x...'<\/span>, abi=PTVS_ABI)\n\ntx_hash = contract.functions.injectClaim(\n    inspection_data[<span style=\"color: #68D391;\">'assetId'<\/span>],\n    inspection_data[<span style=\"color: #68D391;\">'ptvsScore'<\/span>],\n    bytes.fromhex(forensic_hash),\n    <span style=\"color: #F6AD55;\">1692095400<\/span>,\n    b<span style=\"color: #68D391;\">''<\/span>\n).transact({<span style=\"color: #68D391;\">'from'<\/span>: ptce_address})<\/pre>\n<\/div>\n\n<div class=\"code-panel\" id=\"panel-javascript\">\n<pre><span style=\"color: #718096;\">\/\/ Install: npm install web3<\/span>\n\n<span style=\"color: #F6AD55;\">const<\/span> Web3 = require(<span style=\"color: #68D391;\">'web3'<\/span>);\n<span style=\"color: #F6AD55;\">const<\/span> crypto = require(<span style=\"color: #68D391;\">'crypto'<\/span>);\n\n<span style=\"color: #718096;\">\/\/ 1. Create canonical JSON<\/span>\n<span style=\"color: #F6AD55;\">const<\/span> inspectionData = {\n  assetId: <span style=\"color: #68D391;\">'0x1a2b3c4d5e6f'<\/span>,\n  inspectionDate: <span style=\"color: #68D391;\">'2026-08-15T10:30:00Z'<\/span>,\n  ptceId: <span style=\"color: #68D391;\">'PTCE-0161'<\/span>,\n  ptvsScore: <span style=\"color: #F6AD55;\">85<\/span>,\n  findings: {\n    structural: { cracks: <span style=\"color: #F6AD55;\">0<\/span>, corrosion: <span style=\"color: #F6AD55;\">1<\/span> },\n    legal: { encumbrances: <span style=\"color: #F6AD55;\">0<\/span>, titleClear: <span style=\"color: #F6AD55;\">true<\/span> }\n  }\n};\n\n<span style=\"color: #718096;\">\/\/ 2. Canonicalize (sorted keys, no whitespace)<\/span>\n<span style=\"color: #F6AD55;\">const<\/span> canonicalJson = JSON.stringify(inspectionData, \n  Object.keys(inspectionData).sort().reduce((obj, key) =&gt; {\n    obj[key] = inspectionData[key];\n    <span style=\"color: #F6AD55;\">return<\/span> obj;\n  }, {}), \n  <span style=\"color: #F6AD55;\">null<\/span>, \n  <span style=\"color: #F6AD55;\">0<\/span>\n);\n\n<span style=\"color: #718096;\">\/\/ 3. Compute SHA-256 hash<\/span>\n<span style=\"color: #F6AD55;\">const<\/span> forensicHash = crypto\n  .createHash(<span style=\"color: #68D391;\">'sha256'<\/span>)\n  .update(canonicalJson)\n  .digest(<span style=\"color: #68D391;\">'hex'<\/span>);\n\n<span style=\"color: #718096;\">\/\/ 4. Inject claim on-chain<\/span>\n<span style=\"color: #F6AD55;\">const<\/span> web3 = <span style=\"color: #F6AD55;\">new<\/span> Web3(<span style=\"color: #68D391;\">'https:\/\/mainnet.infura.io\/v3\/YOUR_KEY'<\/span>);\n<span style=\"color: #F6AD55;\">const<\/span> contract = <span style=\"color: #F6AD55;\">new<\/span> web3.eth.Contract(PTVS_ABI, <span style=\"color: #68D391;\">'0x...'<\/span>);\n\n<span style=\"color: #F6AD55;\">const<\/span> tx = <span style=\"color: #F6AD55;\">await<\/span> contract.methods.injectClaim(\n  inspectionData.assetId,\n  inspectionData.ptvsScore,\n  <span style=\"color: #68D391;\">'0x'<\/span> + forensicHash,\n  Math.floor(Date.now() \/ <span style=\"color: #F6AD55;\">1000<\/span>),\n  <span style=\"color: #68D391;\">'0x'<\/span>\n).send({ from: ptceAddress });<\/pre>\n<\/div>\n\n<div class=\"code-panel\" id=\"panel-solidity\">\n<pre><span style=\"color: #718096;\">\/\/ SPDX-License-Identifier: MIT<\/span>\n<span style=\"color: #F6AD55;\">pragma<\/span> solidity ^<span style=\"color: #F6AD55;\">0.8.20<\/span>;\n\n<span style=\"color: #F6AD55;\">import<\/span> <span style=\"color: #68D391;\">\"@openzeppelin\/contracts\/access\/Ownable.sol\"<\/span>;\n\n<span style=\"color: #F6AD55;\">contract<\/span> PTVSClaimInjector <span style=\"color: #F6AD55;\">is<\/span> Ownable {\n    \n    <span style=\"color: #F6AD55;\">struct<\/span> VerifiableClaim {\n        <span style=\"color: #F6AD55;\">bytes32<\/span> assetId;\n        <span style=\"color: #F6AD55;\">uint8<\/span> ptvsScore;\n        <span style=\"color: #F6AD55;\">bytes32<\/span> forensicHash;\n        <span style=\"color: #F6AD55;\">uint256<\/span> inspectionTimestamp;\n        <span style=\"color: #F6AD55;\">address<\/span> ptceAddress;\n        ClaimStatus status;\n    }\n    \n    <span style=\"color: #F6AD55;\">enum<\/span> ClaimStatus { VERIFIED, CONDITIONAL, EXPIRED, REVOKED }\n    \n    <span style=\"color: #F6AD55;\">mapping<\/span>(<span style=\"color: #F6AD55;\">bytes32<\/span> =&gt; VerifiableClaim) <span style=\"color: #F6AD55;\">public<\/span> claims;\n    <span style=\"color: #F6AD55;\">mapping<\/span>(<span style=\"color: #F6AD55;\">address<\/span> =&gt; <span style=\"color: #F6AD55;\">bool<\/span>) <span style=\"color: #F6AD55;\">public<\/span> authorizedPTCEs;\n    \n    <span style=\"color: #F6AD55;\">event<\/span> ClaimInjected(\n        <span style=\"color: #F6AD55;\">bytes32<\/span> <span style=\"color: #F6AD55;\">indexed<\/span> assetId,\n        <span style=\"color: #F6AD55;\">uint8<\/span> ptvsScore,\n        <span style=\"color: #F6AD55;\">bytes32<\/span> forensicHash,\n        <span style=\"color: #F6AD55;\">address<\/span> <span style=\"color: #F6AD55;\">indexed<\/span> ptceAddress,\n        <span style=\"color: #F6AD55;\">uint256<\/span> timestamp\n    );\n    \n    <span style=\"color: #F6AD55;\">modifier<\/span> onlyAuthorizedPTCE() {\n        <span style=\"color: #F6AD55;\">require<\/span>(authorizedPTCEs[msg.sender], <span style=\"color: #68D391;\">\"Not authorized\"<\/span>);\n        _;\n    }\n    \n    <span style=\"color: #F6AD55;\">function<\/span> injectClaim(\n        <span style=\"color: #F6AD55;\">bytes32<\/span> assetId,\n        <span style=\"color: #F6AD55;\">uint8<\/span> ptvsScore,\n        <span style=\"color: #F6AD55;\">bytes32<\/span> forensicHash,\n        <span style=\"color: #F6AD55;\">uint256<\/span> inspectionTimestamp,\n        <span style=\"color: #F6AD55;\">bytes<\/span> <span style=\"color: #F6AD55;\">memory<\/span> ptceSignature\n    ) <span style=\"color: #F6AD55;\">external<\/span> onlyAuthorizedPTCE {\n        ClaimStatus status = ptvsScore &gt;= <span style=\"color: #F6AD55;\">70<\/span> \n            ? ClaimStatus.VERIFIED \n            : ClaimStatus.REVOKED;\n            \n        claims[assetId] = VerifiableClaim({\n            assetId: assetId,\n            ptvsScore: ptvsScore,\n            forensicHash: forensicHash,\n            inspectionTimestamp: inspectionTimestamp,\n            ptceAddress: msg.sender,\n            status: status\n        });\n        \n        <span style=\"color: #F6AD55;\">emit<\/span> ClaimInjected(\n            assetId, \n            ptvsScore, \n            forensicHash, \n            msg.sender, \n            block.timestamp\n        );\n    }\n    \n    <span style=\"color: #F6AD55;\">function<\/span> getClaim(<span style=\"color: #F6AD55;\">bytes32<\/span> assetId) \n        <span style=\"color: #F6AD55;\">external<\/span> <span style=\"color: #F6AD55;\">view<\/span> \n        <span style=\"color: #F6AD55;\">returns<\/span> (VerifiableClaim <span style=\"color: #F6AD55;\">memory<\/span>) \n    {\n        <span style=\"color: #F6AD55;\">return<\/span> claims[assetId];\n    }\n}<\/pre>\n<\/div>\n<\/div>\n<\/section>\n\n<!-- SECTION 3: NEXT STEPS -->\n<section class=\"section\">\n<span class=\"section-num\">Section III<\/span>\n<h2>Next Steps<\/h2>\n\n<div class=\"next-steps\">\n<h3>Ready to Integrate PTVS in Production?<\/h3>\n<p>Move from sandbox to production with our comprehensive resources:<\/p>\n\n<div class=\"next-steps-grid\">\n<div class=\"next-step-card\">\n<h4>&#128218; Documentation<\/h4>\n<p>Complete technical specification of PTVS v1.0 with 23 sections covering architecture, smart contracts, and regulatory alignment.<\/p>\n<a href=\"\/standard\/\">Read Documentation &rarr;<\/a>\n<\/div>\n<div class=\"next-step-card\">\n<h4>&#128104;&zwj;&#128188; Become a PTCE<\/h4>\n<p>Join the Prop Trust Certified Expert network. 40-hour certification program. 85% revenue share on inspections.<\/p>\n<a href=\"\/vendor-register\/\">Apply Now &rarr;<\/a>\n<\/div>\n<div class=\"next-step-card\">\n<h4>&#127970; Enterprise Integration<\/h4>\n<p>Custom integration support for banks, insurers, and RWA platforms. Dedicated technical account manager.<\/p>\n<a href=\"mailto:enterprise@proptrustverified.com\">Contact Sales &rarr;<\/a>\n<\/div>\n<div class=\"next-step-card\">\n<h4>&#128300; Research Grants<\/h4>\n<p>&euro;50,000 annual grants for academic research on PFOI. Open to European universities. Deadline: October 31, 2026.<\/p>\n<a href=\"https:\/\/forensics-oracle.org\/research-grants\/\" target=\"_blank\">Apply for Grant &rarr;<\/a>\n<\/div>\n<\/div>\n<\/div>\n<\/section>\n\n<\/main>\n\n<!-- ECOSYSTEM FOOTER -->\n<footer class=\"ecosystem-footer\">\n<div class=\"ecosystem-container\">\n<div class=\"ecosystem-label\">\n<span class=\"ecosystem-motto\">VERITAS IN RE &middot; CERTITUDO IN CODE<\/span>\n<span class=\"ecosystem-title\">The PFOI Ecosystem<\/span>\n<\/div>\n<div class=\"ecosystem-grid\">\n<a href=\"https:\/\/www.aureliotamaritblay.es\" class=\"eco-link\" target=\"_blank\" rel=\"noopener\">\n<span class=\"eco-role\">Founder &middot; Authority<\/span>\n<strong>Aurelio Tamarit Blay<\/strong>\n<span class=\"eco-desc\">Lead Researcher &middot; Judicial Expert Exp. 0161<\/span>\n<\/a>\n<a href=\"https:\/\/forensics-oracle.org\" class=\"eco-link\" target=\"_blank\" rel=\"noopener\">\n<span class=\"eco-role\">Standard &middot; Governance<\/span>\n<strong>Forensics Oracle Initiative<\/strong>\n<span class=\"eco-desc\">PTVS v1.0 &middot; Technical Board &middot; Research<\/span>\n<\/a>\n<a href=\"https:\/\/proptrustverified.com\" class=\"eco-link\">\n<span class=\"eco-role\">Certification &middot; Network<\/span>\n<strong>Prop Trust Verified<\/strong>\n<span class=\"eco-desc\">PTCE Network &middot; Verified by PTVS seal<\/span>\n<\/a>\n<a href=\"https:\/\/aurema-group.com\" class=\"eco-link\" target=\"_blank\" rel=\"noopener\">\n<span class=\"eco-role\">Holding &middot; IP &middot; Governance<\/span>\n<strong>Aurema Group L.L.C.<\/strong>\n<span class=\"eco-desc\">Delaware, USA &middot; Parent Entity<\/span>\n<\/a>\n<\/div>\n<div class=\"ecosystem-footnote\">\n&copy; 2026 Aurema Group L.L.C. &middot; Prop Trust Verified&trade;, PFOI&trade;, PTCE&trade; and Forensics Oracle&trade; are registered trademarks.<br>\nPTVS v1.0 Reference Architecture DOI: <a href=\"https:\/\/doi.org\/10.5281\/zenodo.21719175\" target=\"_blank\" rel=\"noopener\">10.5281\/zenodo.21719175<\/a> &middot; Contact: <a href=\"mailto:enterprise@proptrustverified.com\">enterprise@proptrustverified.com<\/a>\n<\/div>\n<\/div>\n<\/footer>\n\n<script>\n\/\/ &#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552; SANDBOX LOGIC &#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;&#9552;\n\nlet currentStep = 1;\nlet generatedHash = '';\n\n\/\/ Step navigation\nfunction nextStep(step) {\n  document.getElementById(`step${currentStep}`).style.display = 'none';\n  document.getElementById(`step${step}`).style.display = 'block';\n  \n  \/\/ Update step indicators\n  document.querySelectorAll('.step-dot').forEach((dot, idx) => {\n    dot.classList.remove('active', 'completed');\n    if (idx + 1 < step) dot.classList.add('completed');\n    if (idx + 1 === step) dot.classList.add('active');\n  });\n  \n  currentStep = step;\n  \n  \/\/ Execute step-specific logic\n  if (step === 3) calculateScore();\n  if (step === 4) generateCanonicalJson();\n  if (step === 5) injectClaim();\n  if (step === 6) verifyClaim();\n  \n  window.scrollTo({ top: 0, behavior: 'smooth' });\n}\n\nfunction prevStep(step) {\n  nextStep(step);\n}\n\nfunction resetSandbox() {\n  currentStep = 1;\n  document.querySelectorAll('.form-section').forEach(s => s.style.display = 'none');\n  document.getElementById('step1').style.display = 'block';\n  document.querySelectorAll('.step-dot').forEach((dot, idx) => {\n    dot.classList.remove('active', 'completed');\n    if (idx === 0) dot.classList.add('active');\n  });\n  window.scrollTo({ top: 0, behavior: 'smooth' });\n}\n\n\/\/ Update score display in real-time\nfunction updateScoreDisplay() {\n  document.getElementById('structuralValue').textContent = document.getElementById('structuralScore').value;\n  document.getElementById('legalValue').textContent = document.getElementById('legalScore').value;\n  document.getElementById('environmentalValue').textContent = document.getElementById('environmentalScore').value;\n  document.getElementById('documentationValue').textContent = document.getElementById('documentationScore').value;\n  document.getElementById('insuranceValue').textContent = document.getElementById('insuranceScore').value;\n}\n\n\/\/ Calculate PTVS Score\nfunction calculateScore() {\n  const structural = parseInt(document.getElementById('structuralScore').value);\n  const legal = parseInt(document.getElementById('legalScore').value);\n  const environmental = parseInt(document.getElementById('environmentalScore').value);\n  const documentation = parseInt(document.getElementById('documentationScore').value);\n  const insurance = parseInt(document.getElementById('insuranceScore').value);\n  \n  const ptvsScore = Math.round(\n    (structural * 0.40) +\n    (legal * 0.25) +\n    (environmental * 0.20) +\n    (documentation * 0.10) +\n    (insurance * 0.05)\n  );\n  \n  document.getElementById('ptvsScoreDisplay').textContent = ptvsScore;\n  document.getElementById('breakdownStructural').textContent = structural;\n  document.getElementById('breakdownLegal').textContent = legal;\n  document.getElementById('breakdownEnvironmental').textContent = environmental;\n  document.getElementById('breakdownDocumentation').textContent = documentation;\n  document.getElementById('breakdownInsurance').textContent = insurance;\n  \n  const statusEl = document.getElementById('scoreStatus');\n  if (ptvsScore >= 70) {\n    statusEl.textContent = 'VERIFIED';\n    statusEl.className = 'score-status verified';\n  } else if (ptvsScore >= 50) {\n    statusEl.textContent = 'CONDITIONAL';\n    statusEl.className = 'score-status conditional';\n  } else {\n    statusEl.textContent = 'REVOKED';\n    statusEl.className = 'score-status revoked';\n  }\n}\n\n\/\/ Generate canonical JSON and compute hash\nasync function generateCanonicalJson() {\n  const inspectionData = {\n    assetId: document.getElementById('assetId').value,\n    assetName: document.getElementById('assetName').value,\n    assetType: document.getElementById('assetType').value,\n    environmental: {\n      contamination: 0,\n      hazards: 0,\n      score: parseInt(document.getElementById('environmentalScore').value)\n    },\n    inspectionDate: new Date().toISOString(),\n    insurance: {\n      active: true,\n      score: parseInt(document.getElementById('insuranceScore').value)\n    },\n    jurisdiction: document.getElementById('jurisdiction').value,\n    legal: {\n      encumbrances: 0,\n      score: parseInt(document.getElementById('legalScore').value),\n      titleClear: true\n    },\n    notes: document.getElementById('inspectorNotes').value,\n    ptceId: 'PTCE-0161',\n    ptvsScore: parseInt(document.getElementById('ptvsScoreDisplay').textContent),\n    structural: {\n      corrosion: 1,\n      cracks: 0,\n      degradation: 0,\n      score: parseInt(document.getElementById('structuralScore').value)\n    }\n  };\n  \n  \/\/ Canonical JSON (sorted keys, no whitespace)\n  const canonicalJson = JSON.stringify(inspectionData, Object.keys(inspectionData).sort());\n  \n  document.getElementById('canonicalJsonOutput').textContent = JSON.stringify(inspectionData, null, 2);\n  \n  \/\/ Compute SHA-256 hash using Web Crypto API\n  const encoder = new TextEncoder();\n  const data = encoder.encode(canonicalJson);\n  const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n  const hashArray = Array.from(new Uint8Array(hashBuffer));\n  generatedHash = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');\n  \n  document.getElementById('hashValue').textContent = '0x' + generatedHash;\n}\n\n\/\/ Inject claim (simulated)\nfunction injectClaim() {\n  const assetId = document.getElementById('assetId').value;\n  const ptvsScore = document.getElementById('ptvsScoreDisplay').textContent;\n  const timestamp = new Date().toISOString();\n  \n  document.getElementById('claimAssetId').textContent = assetId;\n  document.getElementById('claimScore').textContent = ptvsScore + ' \/ 100';\n  document.getElementById('claimHash').textContent = '0x' + generatedHash;\n  document.getElementById('claimTimestamp').textContent = timestamp;\n  \n  const status = parseInt(ptvsScore) >= 70 ? 'VERIFIED' : 'REVOKED';\n  document.getElementById('claimStatus').textContent = status;\n  \n  \/\/ Generate Solidity event output\n  const eventOutput = `event ClaimInjected(\n    bytes32 indexed assetId: ${assetId},\n    uint8 ptvsScore: ${ptvsScore},\n    bytes32 forensicHash: 0x${generatedHash},\n    address indexed ptceAddress: 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb,\n    uint256 timestamp: ${Math.floor(Date.now() \/ 1000)}\n);\n\n\/\/ Transaction Hash (simulated): 0x${Math.random().toString(16).substring(2, 66)}\n\/\/ Block Number: ${Math.floor(Math.random() * 1000000) + 18000000}\n\/\/ Gas Used: 125,432`;\n  \n  document.getElementById('solidityEventOutput').textContent = eventOutput;\n}\n\n\/\/ Verify claim\nfunction verifyClaim() {\n  document.getElementById('verifyHash1').textContent = '0x' + generatedHash;\n  document.getElementById('verifyHash2').textContent = '0x' + generatedHash;\n}\n\n\/\/ Tab switching for code examples\nfunction switchTab(lang) {\n  document.querySelectorAll('.code-tab').forEach(tab => tab.classList.remove('active'));\n  document.querySelectorAll('.code-panel').forEach(panel => panel.classList.remove('active'));\n  \n  event.target.classList.add('active');\n  document.getElementById(`panel-${lang}`).classList.add('active');\n}\n\n\/\/ Initialize\nupdateScoreDisplay();\n<\/script>\n\n<\/body>\n<\/html><div style=\"margin: 20px 0;\"><div class=\"qrcswholewtapper\" style=\"text-align:left;\"><div class=\"qrcprowrapper\"  id=\"qrcwraa2leds\"><div class=\"qrc_canvass\" id=\"qrc_cuttenpages_2\" style=\"display:inline-block\" data-text=\"https:\/\/proptrustverified.com\/en\/PTVS-SandBox\/\"><\/div><div><a download=\"PTVS SandBox.png\" class=\"qrcdownloads\" id=\"worign\">\r\n           <button type=\"button\" style=\"min-width:200px;background:#dddddd;color:#000;font-weight: 600;border: 1px solid #dddddd;border-radius:4px;font-size:12px;padding: 6px 0;\" class=\"uqr_code_btn\">Download QR<\/button>\r\n           <\/a><\/div><\/div><\/div><\/div>","protected":false},"excerpt":{"rendered":"<p>PTVS Sandbox &mdash; Try Prop Trust Verified Standard in 5 Minutes Prop Trust VerifiedCertification &middot; PTCE Network Home PTVS Standard PTCE Registry Sandbox Register Interactive Playground &middot; No Backend Required PTVS Sandbox Experience the Prop Trust Verified Standard in your browser. Create a mock asset, generate forensic evidence, compute cryptographic hashes, and simulate on-chain Verifiable [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-2196","page","type-page","status-publish","hentry"],"_hostinger_reach_plugin_has_subscription_block":false,"_hostinger_reach_plugin_is_elementor":false,"_links":{"self":[{"href":"https:\/\/proptrustverified.com\/en\/wp-json\/wp\/v2\/pages\/2196","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/proptrustverified.com\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/proptrustverified.com\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/proptrustverified.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/proptrustverified.com\/en\/wp-json\/wp\/v2\/comments?post=2196"}],"version-history":[{"count":2,"href":"https:\/\/proptrustverified.com\/en\/wp-json\/wp\/v2\/pages\/2196\/revisions"}],"predecessor-version":[{"id":2200,"href":"https:\/\/proptrustverified.com\/en\/wp-json\/wp\/v2\/pages\/2196\/revisions\/2200"}],"wp:attachment":[{"href":"https:\/\/proptrustverified.com\/en\/wp-json\/wp\/v2\/media?parent=2196"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}