/** * rData — rich landing page body. * Returned by landingPage() in the module export; * the shell wraps it with header, CSS, and analytics. */ export function renderLanding(): string { return `
rData

(You)rData, your signal.

Privacy-First Analytics

See how your community engages without tracking individuals. No cookies, no consent banners, no third-party data — just clean, real-time metrics from your own server.

View Dashboard Create a Space

What rData Handles

📊

Privacy-First Dashboard

Active visitors, page views, bounce rate, and session duration — all without tracking individuals.

🔒

No Cookies

Umami uses a privacy-friendly fingerprinting method. Zero cookies, zero local storage, zero consent banners.

GDPR Compliant

No personal data collected. No consent banner needed. Compliant out of the box.

🏠

Self-Hosted Metrics

Your visitor metrics never leave your server. No ad networks, no data brokers, no surprises.

How It Works

1

Add a Tracking Snippet

Every rSpace module is automatically tracked — no code changes, no tag managers required.

2

Collect Anonymized Pageviews

A sub-2 KB script collects anonymized pageviews with no impact on page load performance.

3

Analyze in a Clean Dashboard

Open rData to see page views, active visitors, referrers, and top content in real time.

Why Self-Hosted Analytics?

Compare rData with third-party analytics platforms.

🚫

No Third-Party Data

Your visitor metrics never leave your server. No ad networks, no data brokers, no surprises.

🚫

No Cookie Banners

Because no cookies are set, you skip the annoying consent popups entirely.

🦿

Sub-2 KB Script

Google Analytics loads 45 KB+. The Umami tracker is under 2 KB — 20x lighter.

Built on Open Source

The libraries and tools that power rData.

📈

Umami

Open-source, privacy-first analytics platform — the ethical alternative to Google Analytics.

🗃

PostgreSQL

Reliable relational storage for all analytics data, event logs, and aggregation queries.

Hono

Ultrafast web framework powering the API proxy layer between your modules and the analytics backend.

Interactive Demo

Your Data, Your Membranes

Every piece of knowledge lives inside a permissioned boundary. Your personal data sits in encrypted local storage, shared data flows through permissioned spaces, and public data is open to all. Drag any object between zones to see how rData manages permission transitions.

Your Data, Protected

How rData keeps your information safe.

🔒

End-to-End Encryption

Coming Soon

All content encrypted before it leaves your device. Not even the server can read it.

🕵

Zero-Knowledge Architecture

Coming Soon

The server processes your requests without ever seeing your data in the clear.

🏠

Self-Hosted

Run on your own infrastructure. Your server, your rules, your data.

(You)rData, your signal.

Try the demo or create a space to get started.

← Back to rSpace
`; } function getMembraneScript(): string { return ` (function(){ 'use strict'; var mob=function(){return window.innerWidth<600;}; var ZONES=[ {id:'public',label:'Public',sublabel:'Open to everyone',color:'#34d399',colorFaded:'rgba(52,211,153,0.08)',borderStyle:'solid',icon:'\\u{1F310}'}, {id:'permissioned',label:'Permissioned Space',sublabel:'Shared with members',color:'#fbbf24',colorFaded:'rgba(251,191,36,0.08)',borderStyle:'solid',icon:'\\u{1F511}'}, {id:'personal',label:'Personal Storage',sublabel:'Encrypted \\u00b7 Local only',color:'#f87171',colorFaded:'rgba(248,113,113,0.10)',borderStyle:'dotted',icon:'\\u{1F512}'} ]; var DEMO_OBJECTS=[ {id:'obj1',label:'Product Roadmap',icon:'\\u{1F4DD}',zone:'personal',tags:['planning']}, {id:'obj2',label:'Meeting Notes',icon:'\\u{1F4D3}',zone:'personal',tags:['meetings']}, {id:'obj3',label:'Private Journal',icon:'\\u{1F510}',zone:'personal',tags:['personal']}, {id:'obj4',label:'Team Calendar',icon:'\\u{1F4C5}',zone:'permissioned',tags:['team']}, {id:'obj5',label:'Budget Q2',icon:'\\u{1F4B0}',zone:'permissioned',tags:['finance']}, {id:'obj6',label:'Design System',icon:'\\u{1F3A8}',zone:'permissioned',tags:['dev']}, {id:'obj7',label:'API Docs',icon:'\\u{1F4C4}',zone:'public',tags:['dev']}, {id:'obj8',label:'Community Wiki',icon:'\\u{1F4DA}',zone:'public',tags:['community']}, {id:'obj9',label:'Open Proposals',icon:'\\u{1F5F3}',zone:'public',tags:['governance']} ]; var objects=JSON.parse(JSON.stringify(DEMO_OBJECTS)); var dragState=null,popup=null,hoveredZone=null,containerEl=null,canvasEl=null,tooltipObj=null,selectedObj=null; function nodeR(){return mob()?22:28;} function getZoneGeometry(W,H){var cx=W/2,cy=H/2,maxR=Math.min(cx,cy)-(mob()?8:16),zones=[]; for(var i=0;izg.innerR;} function findZoneAtPoint(x,y,zgs){for(var i=zgs.length-1;i>=0;i--){if(pointInZone(x,y,zgs[i]))return zgs[i];}return null;} function computeObjectPositions(zgs){var positions={},byZone={},nr=nodeR(); objects.forEach(function(o){if(!byZone[o.zone])byZone[o.zone]=[];byZone[o.zone].push(o);}); zgs.forEach(function(zg){var items=byZone[zg.id]||[];var midR=(zg.outerR+zg.innerR)/2;var count=items.length; for(var i=0;i1){r=midR+(i%2===0?-nr*0.6:nr*0.6);} positions[items[i].id]={x:zg.cx+r*Math.cos(angle),y:zg.cy+r*Math.sin(angle)};}});return positions;} function escSvg(s){return s.replace(/&/g,'&').replace(//g,'>');} function escHtml(s){return s.replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"');} function truncate(s,max){return s.length>max?s.slice(0,max-1)+'\\u2026':s;} function render(){if(!containerEl)return;var rect=containerEl.getBoundingClientRect();var W=rect.width;var m=mob(); var H=m?Math.max(360,Math.min(W*0.95,480)):Math.max(480,Math.min(600,W*0.65));containerEl.style.height=H+'px'; var zgs=getZoneGeometry(W,H);var positions=computeObjectPositions(zgs);var nr=nodeR();var svg=''; svg+=''; var zls=m?10:13,zsls=m?8:10; zgs.forEach(function(zg){var da=zg.borderStyle==='dotted'?'8,6':'none'; svg+=''; svg+=''; var ly=zg.cy-zg.outerR+(m?16:24);var lbl=m&&zg.id==='permissioned'?'Permissioned':zg.label; svg+=''+zg.icon+' '+escSvg(lbl)+''; svg+=''+escSvg(zg.sublabel)+'';}); var ifs=m?14:18,lfs=m?7.5:9; objects.forEach(function(obj){var pos=positions[obj.id];if(!pos)return;var ox=pos.x,oy=pos.y; if(dragState&&dragState.objId===obj.id){ox=dragState.currentX;oy=dragState.currentY;} var isDragging=dragState&&dragState.objId===obj.id;var isSel=selectedObj===obj.id;var zc=ZONES.find(function(z){return z.id===obj.zone;});var nc=zc?zc.color:'#94a3b8'; svg+=''; var hitR=m?nr+4:nr;svg+=''; svg+=''; if(isSel&&m){svg+='';} svg+=''+obj.icon+''; var tly=m?nr-6:18;svg+=''+escSvg(truncate(obj.label,m?12:14))+''; svg+='';}); if(dragState&&hoveredZone){var tzg=zgs.find(function(z){return z.id===hoveredZone;});if(tzg){var dObj=objects.find(function(o){return o.id===dragState.objId;}); if(dObj&&dObj.zone!==hoveredZone){svg+='';}}} if(m&&!dragState&&!popup&&!selectedObj){svg+='Tap an object, then drag to move between zones';} canvasEl.setAttribute('viewBox','0 0 '+W+' '+H);canvasEl.style.width=W+'px';canvasEl.style.height=H+'px';canvasEl.innerHTML=svg;renderPopup();} function renderPopup(){var ep=containerEl.querySelector('.membrane-popup-overlay');if(!popup){if(ep)ep.remove();return;} if(!ep){ep=document.createElement('div');ep.className='membrane-popup-overlay';containerEl.appendChild(ep);} var obj=objects.find(function(o){return o.id===popup.objId;});var fz=ZONES.find(function(z){return z.id===popup.fromZone;});var tz=ZONES.find(function(z){return z.id===popup.toZone;}); if(!obj||!fz||!tz)return;var zo={personal:0,permissioned:1,public:2};var isExp=zo[popup.toZone]>zo[popup.fromZone];var isRes=zo[popup.toZone] from '+fz.icon+' '+fz.label+' to '+tz.icon+' '+tz.label+' will make this data accessible to more people.'; if(popup.toZone==='public'){wm+='

This will make the data publicly visible. Anyone will be able to view it.';cl='Make Public';cc='#34d399';} else{wm+='

Members of this permissioned space will be able to view and potentially edit this data.';cl='Share with Space';cc='#fbbf24';}} else if(isRes){wi='\\u{1F512}';wt='Restricting Access';wm='Moving '+escHtml(obj.label)+' from '+fz.icon+' '+fz.label+' to '+tz.icon+' '+tz.label+' will reduce who can access this data.'; if(popup.toZone==='personal'){wm+='

This data will be encrypted and stored locally in your browser only. No one else will have access.';cl='Make Private';cc='#f87171';} else{wm+='

Only members of this permissioned space will retain access.';cl='Restrict Access';cc='#fbbf24';}} ep.innerHTML='
'+wi+'

'+wt+'

'+wm+'

'+fz.icon+' '+fz.label+'
'+(isExp?'\\u2192':'\\u2190')+'
'+tz.icon+' '+tz.label+'
'; ep.querySelector('.membrane-popup-cancel').onclick=function(){popup=null;selectedObj=null;render();}; ep.querySelector('.membrane-popup-confirm').onclick=function(){var o=objects.find(function(x){return x.id===popup.objId;});if(o)o.zone=popup.toZone;popup=null;selectedObj=null;render();}; ep.onclick=function(e){if(e.target===ep){popup=null;selectedObj=null;render();}};} function getPointerPos(e){var evt=e.touches?e.touches[0]:e;var rect=canvasEl.getBoundingClientRect();var sx=canvasEl.viewBox.baseVal.width/rect.width;var sy=canvasEl.viewBox.baseVal.height/rect.height;return{x:(evt.clientX-rect.left)*sx,y:(evt.clientY-rect.top)*sy};} function onPointerDown(e){if(popup)return;var t=e.target.closest('.membrane-obj'); if(!t){if(mob()&&selectedObj){selectedObj=null;render();}return;} var objId=t.getAttribute('data-obj-id'); if(mob()&&e.touches&&selectedObj!==objId){e.preventDefault();selectedObj=objId;render();return;} e.preventDefault();var pos=getPointerPos(e); var rect=containerEl.getBoundingClientRect();var W=rect.width;var H=parseInt(containerEl.style.height)||480;var zgs=getZoneGeometry(W,H);var positions=computeObjectPositions(zgs);var op=positions[objId]; dragState={objId:objId,startX:pos.x,startY:pos.y,currentX:op?op.x:pos.x,currentY:op?op.y:pos.y,offsetX:op?pos.x-op.x:0,offsetY:op?pos.y-op.y:0}; selectedObj=objId;canvasEl.style.cursor='grabbing'; if(e.touches){document.body.style.overflow='hidden';document.body.style.touchAction='none';}} function onPointerMove(e){if(!dragState)return;e.preventDefault();var pos=getPointerPos(e);dragState.currentX=pos.x-dragState.offsetX;dragState.currentY=pos.y-dragState.offsetY; var rect=containerEl.getBoundingClientRect();var W=rect.width;var H=parseInt(containerEl.style.height)||480;var zgs=getZoneGeometry(W,H);var zone=findZoneAtPoint(dragState.currentX,dragState.currentY,zgs);hoveredZone=zone?zone.id:null;render();} function onPointerUp(){if(!dragState)return;document.body.style.overflow='';document.body.style.touchAction=''; var obj=objects.find(function(o){return o.id===dragState.objId;}); if(obj&&hoveredZone&&hoveredZone!==obj.zone){popup={objId:obj.id,fromZone:obj.zone,toZone:hoveredZone};} dragState=null;hoveredZone=null;canvasEl.style.cursor='';render();} function initDrag(){canvasEl.addEventListener('mousedown',onPointerDown);canvasEl.addEventListener('touchstart',onPointerDown,{passive:false}); document.addEventListener('mousemove',onPointerMove);document.addEventListener('touchmove',onPointerMove,{passive:false});document.addEventListener('mouseup',onPointerUp);document.addEventListener('touchend',onPointerUp);} function initTooltip(){if('ontouchstart' in window)return; canvasEl.addEventListener('mouseover',function(e){var t=e.target.closest('.membrane-obj');if(t){var id=t.getAttribute('data-obj-id');tooltipObj=objects.find(function(o){return o.id===id;})||null;}else{tooltipObj=null;}renderTooltip(e);}); canvasEl.addEventListener('mouseout',function(e){if(!e.target.closest('.membrane-obj')){tooltipObj=null;renderTooltip(e);}});} function renderTooltip(e){var tip=containerEl.querySelector('.membrane-tooltip');if(!tooltipObj){if(tip)tip.style.display='none';return;} if(!tip){tip=document.createElement('div');tip.className='membrane-tooltip';containerEl.appendChild(tip);} var zone=ZONES.find(function(z){return z.id===tooltipObj.zone;}); tip.innerHTML=''+tooltipObj.icon+' '+escHtml(tooltipObj.label)+'
'+zone.icon+' '+zone.label+''+(tooltipObj.tags.length?'
'+tooltipObj.tags.map(function(t){return'#'+t;}).join(' ')+'':'')+'
Drag to change permissions'; tip.style.display='block';var rect=containerEl.getBoundingClientRect();tip.style.left=Math.min(e.clientX-rect.left+12,rect.width-180)+'px';tip.style.top=(e.clientY-rect.top-70)+'px';} function injectStyles(){if(document.getElementById('membrane-styles'))return;var s=document.createElement('style');s.id='membrane-styles'; s.textContent='.membrane-container{position:relative;width:100%;overflow:hidden;border-radius:16px;background:rgba(10,14,26,0.6);border:1px solid rgba(255,255,255,0.06);-webkit-touch-callout:none;-webkit-user-select:none;user-select:none;touch-action:none}.membrane-container svg{display:block}.membrane-tooltip{position:absolute;display:none;background:rgba(15,23,42,0.95);border:1px solid rgba(255,255,255,0.15);border-radius:8px;padding:8px 12px;font-size:0.8rem;color:#e2e8f0;pointer-events:none;z-index:20;line-height:1.5;max-width:200px;backdrop-filter:blur(8px)}.membrane-legend{display:flex;justify-content:center;gap:1.5rem;padding:0.75rem 1rem;flex-wrap:wrap}.membrane-legend-item{display:flex;align-items:center;gap:0.5rem;font-size:0.8rem;color:#94a3b8}.membrane-legend-swatch{display:inline-block;width:16px;height:16px;border-radius:50%;flex-shrink:0}.membrane-reset-btn{position:absolute;top:12px;right:12px;padding:4px 12px;border-radius:6px;border:1px solid rgba(255,255,255,0.12);background:rgba(15,23,42,0.8);color:#94a3b8;font-size:0.75rem;cursor:pointer;z-index:10;transition:border-color 0.2s,color 0.2s}.membrane-reset-btn:hover{border-color:rgba(255,255,255,0.3);color:#e2e8f0}.membrane-popup-overlay{position:absolute;inset:0;background:rgba(0,0,0,0.6);backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;z-index:50;border-radius:16px}.membrane-popup{background:#1e293b;border:1px solid rgba(255,255,255,0.12);border-radius:16px;padding:2rem;max-width:420px;width:90%;text-align:center;box-shadow:0 25px 50px -12px rgba(0,0,0,0.5)}.membrane-popup-icon{font-size:2.5rem;margin-bottom:0.75rem}.membrane-popup-title{font-size:1.2rem;color:#f1f5f9;margin-bottom:0.75rem;font-weight:700}.membrane-popup-msg{font-size:0.9rem;color:#94a3b8;line-height:1.6;margin-bottom:1.25rem}.membrane-popup-visual{display:flex;align-items:center;justify-content:center;gap:1rem;margin-bottom:1.5rem}.membrane-popup-zone{padding:0.5rem 1rem;border:2px solid;border-radius:10px;font-size:0.8rem;font-weight:600;background:rgba(255,255,255,0.03)}.membrane-popup-arrow{font-size:1.5rem;color:#64748b}.membrane-popup-actions{display:flex;gap:0.75rem;justify-content:center}.membrane-popup-btn{padding:0.6rem 1.5rem;border-radius:8px;font-size:0.9rem;font-weight:600;cursor:pointer;border:none;transition:transform 0.15s,opacity 0.15s}.membrane-popup-btn:hover{transform:translateY(-1px)}.membrane-popup-cancel{background:rgba(255,255,255,0.06);color:#cbd5e1;border:1px solid rgba(255,255,255,0.12)}.membrane-popup-cancel:hover{border-color:rgba(255,255,255,0.25)}@media(max-width:600px){.membrane-container{border-radius:12px}.membrane-legend{gap:0.6rem;padding:0.5rem}.membrane-legend-item{font-size:0.7rem;gap:0.35rem}.membrane-legend-swatch{width:12px;height:12px}.membrane-reset-btn{top:8px;right:8px;padding:3px 8px;font-size:0.65rem}.membrane-popup{padding:1.25rem 1rem;border-radius:12px;width:94%}.membrane-popup-icon{font-size:2rem;margin-bottom:0.5rem}.membrane-popup-title{font-size:1rem}.membrane-popup-msg{font-size:0.8rem;margin-bottom:1rem}.membrane-popup-visual{flex-direction:column;gap:0.5rem}.membrane-popup-arrow{transform:rotate(90deg)}.membrane-popup-zone{padding:0.4rem 0.75rem;font-size:0.75rem}.membrane-popup-btn{padding:0.5rem 1.25rem;font-size:0.85rem}}'; document.head.appendChild(s);} function addResetButton(){var btn=document.createElement('button');btn.className='membrane-reset-btn';btn.textContent='Reset Demo';btn.title='Reset all objects to their default zones'; btn.onclick=function(){objects=JSON.parse(JSON.stringify(DEMO_OBJECTS));popup=null;dragState=null;hoveredZone=null;selectedObj=null;render();};containerEl.appendChild(btn);} function addLegend(){var legend=document.createElement('div');legend.className='membrane-legend'; legend.innerHTML=ZONES.slice().reverse().map(function(z){return'
'+z.icon+' '+z.label+'
';}).join(''); containerEl.appendChild(legend);} function init(sel){injectStyles();var wrapper=document.querySelector(sel);if(!wrapper)return; containerEl=document.createElement('div');containerEl.className='membrane-container'; canvasEl=document.createElementNS('http://www.w3.org/2000/svg','svg');canvasEl.setAttribute('xmlns','http://www.w3.org/2000/svg'); containerEl.appendChild(canvasEl);wrapper.appendChild(containerEl);addResetButton();addLegend();initDrag();initTooltip();render(); var rt;window.addEventListener('resize',function(){clearTimeout(rt);rt=setTimeout(render,100);});} window.DataMembrane={init:init}; })();`; }