Understory
Feed
Map
Sign in with your Atmosphere Account
WebTiles Showcase
Ted Han @knowtheory.net · Robin Berjon @robin.berjon.com
Room 2301
presentation
32 min
Mar 29, 3:00 PM
WebTiles Showcase
Your browser does not support video playback.
Ted Han
2:47
Thanks.
2:48
Oh, sorry.
Robin Berjon
2:48
No, go ahead.
2:48
Hi, everyone.
2:49
I'd like to introduce the next speaker.
Speaker C
2:52
Hi, everybody.
Robin Berjon
2:53
We're going to be talking about tiles and some Dazzle stuff.
2:58
For the folks listening on the stream, Hayley is unable to present.
3:01
So we're going to do this instead.
Speaker D
3:05
I got—
Ted Han
3:05
I'm mic'd up.
3:08
So hi, everyone.
3:09
Welcome to the impromptu, slightly impromptu tiles talk.
3:14
I see people taking pictures.
3:16
Hi, everyone.
3:17
So, you know, let's jump right in.
3:19
The idea is that I'm going to give like a pretty short intro.
3:23
I see the faces here.
3:25
I think most of you already know what this is, but like, you know, at least I'm going to run through it pretty quickly.
3:29
And then Ted and Nick, or Ted or Nick, or I don't know, are going to show some really cool demos of stuff they've been building with tiles.
3:40
So what are tiles?
3:43
Well, they're really confusing because they're so simple.
3:48
It's what if you could have a mini web app, as so many have tried before, that could be embedded in anything safely?
3:57
Because it can't touch the network.
3:59
That's essentially the whole story.
4:01
And the idea is that you remove a lot of power because you remove network, and that's significant for people who do network things.
4:09
But this reduction in power makes it possible to use this in many more contexts that are potentially security or privacy sensitive, such as social media.
4:22
And so that is pretty cool, especially since the web is pretty powerful.
4:26
So you can build all kinds of stuff with these.
4:28
These are examples of widgets of all kinds that could easily be tiles.
4:34
And the thing is, what's new about this?
4:36
Many people have tried the web app thing before.
4:39
And well, we haven't heard back from them in 20 years.
4:44
I remember, if you're really old like me, you'll remember the XML packaging initiative that was trying to put XHTML and SVG inside some kind of thing that you could run as an app.
4:57
And all that, there have been every 2 to 3 years the W3C has some kind of workshop about web apps, and like, really, maybe guys, we could be solving this at some point perhaps, and there's progress every time, but it's pretty slow, and of course, you could always use iframes if you don't mind exfiltrating a ton of information, so this is something that's been tried many times.
5:23
The thing that hasn't been properly tried is just cutting off the network.
5:30
And that's where things can, I think, get quite interesting.
5:33
And so the anatomy of a tile is basically it's a small, secluded web runtime.
5:40
It can load things that are listed in its manifest.
5:44
One of the values of tiles is that they don't have to be in a zip file.
5:48
A lot of the time, a lot of these things like widgets— I worked on W3C widgets and all that— They had to be in a zip, which means that you can only start showing something after you've loaded the whole zip because you don't know where the index is, you don't know if you have all the resources you need, yada yada.
6:03
If you have a video, your zip might be gigabytes big.
6:06
It's all problematic.
6:09
So some people have tried to do stuff around that, but it's usually not great.
6:11
In this case, you load the manifest over AT, if they are stored on AT, or you could load it over HTTP.
6:19
It's going to be pretty small.
6:22
And then dynamically setting up a Service Worker or something like that, you see what you need to load.
6:27
And if you don't need to load everything, maybe you're not watching the video that's included in that thing, that's perfectly fine.
6:32
You could have an entire archive of many things in a tile without ever having to worry about it.
6:39
If we look at basically— this is a PDSLS of a tile that was published on ATProto.
6:45
Most of the fields are pretty straightforward.
6:47
If you've seen web app manifests, straight out of web app manifests, there's like an icon, there's a name, there's a description.
6:55
And one thing that's specific to tiles and that really helps solve this idea of like content-addressable apps that you can just like move around and publish in different contexts in a way that's completely reusable is that it has this resources thing that maps proper web paths So like slash is mapped to this blob of HTML, and like /image.whatever is mapped to a CID of this.
7:20
And these things get to have proper HTTP headers.
7:26
In a lot of previous iterations of content-addressed web things, the headers were not included.
7:32
So you're getting the content, but without the HTTP headers, you don't have the proper context.
7:37
They might interpret differently in different contexts, and then you're in a crazy world.
7:41
And so like, really, that's about it.
7:44
One of the things that's great is that this example shows them stored on AT, but you could store this anywhere.
7:50
It really doesn't matter because everything is content-addressed throughout the stack.
7:53
So you can put them in a CAR file, you can put them over HTTP, you can load them with Razzle, so you can razzle dazzle.
8:00
All of that is pretty cool.
8:02
And so essentially, you know, that's it.
8:06
You know, it's just like, it's basically this small contained thing And what makes it interesting is when you start integrating it in context and giving it extra power.
8:17
So the idea is that the embedding context can say like, oh, hey, this tile, actually, I know what's safe for it.
8:23
I can give it access to this specific thing that I've controlled.
8:27
And you're going to see a number of demos of precisely that pattern in action.
8:31
But that's it.
8:32
Like, because you've removed the power, then you can decide what you give to it.
8:35
And so I'm just going to go through a list of like— and these are— most of these are fake except for a couple of ones of like how to put them in different contexts.
8:45
Like very simply, you could have a game in your social media stream, just like in your feed, you're scrolling by and they're like, oh yeah, look, Robin posted a game and like, this is me playing like, you know, like Minesweeper in the middle of the thing.
8:58
It can be embedded.
8:59
It's completely safe.
9:00
And now, you know, like I hit the bookmark button and I've got a game installed because I can just like go find it.
9:07
And then you could have like some local curation of stuff.
9:11
And of course, because it's loading off a PDS, you can pay wallet.
9:14
So like there's a business model even potentially behind that.
9:18
You can also do long-form content.
9:20
I can give you the slides afterwards.
9:22
Don't have to take pictures.
9:24
You can do long-form.
9:25
So this is one of— this is a blog post I wrote a while ago.
9:29
And so you could imagine that in a in the leaflet kind of interface instead of like, you know, using the leaflet editor.
9:36
You could embed your own long-form source that has your own style and your own, you know, pictures, fonts, etc., just like as part of the normal leaflet publication format.
9:48
And you click that and it opens and you just get the blog post.
9:53
Another thing that's interesting is you can have something called wishes.
9:58
So if any of you are familiar with Android Intents or Web Intents or stuff like that.
10:04
It's sort of a declarative way of saying, hey, I'm a piece of functionality.
10:08
I'm a tile.
10:09
And I need someone to edit an image for me.
10:12
But I don't want to call a specific program.
10:15
And I definitely don't want to do the thing where you have to save the file to a file system, and then the user has to figure out what app they want to use, and then give it back to me, and all that dance that's fucking insane.
10:26
And so what you say is, is you say, hey, I wish to edit— so there's always a verb— this type of data, and here's the data.
10:34
And it will find for you a tile that knows how to carry out that wish.
10:40
And of course, maybe you have it installed, as we said earlier, like bookmarking is installing, so that's sufficient.
10:45
But maybe it's on the network.
10:47
If it was published to AT, you can know that it's able to— you can find things that are able to handle specific requests.
10:53
So you can use the AT data itself.
10:55
And this is just an example of like, you clicked edit here and it loaded the image inside a filter editor.
11:03
Why not?
11:04
And then when you hit save, it sends it back.
11:06
And it's really simple, but you can integrate a lot of things in this way with loose coupling.
11:12
This is an example of a tile in Rumi.
11:18
The idea— and I really love this pattern.
11:21
I would love to like, when you get to that part of like building stuff, I would love to work on that.
11:26
The idea here is that you can give tiles, and DeltaChat does that, you can give them a way to just write to a data channel of the channel.
11:35
And so it shares data, but only with other people who are on the channel.
11:39
So you can install a tile to a chat.
11:44
And what's cool about that?
11:45
Yeah, I know it kind of breaks the brain, but like, if you think, if you think about it, like a chat is a security perimeter, right?
11:52
There are people who are inside the chat and can read stuff and people who are on the outside who can't.
11:57
And there's no reason that a chat would only send text messages.
12:00
Actually, they don't.
12:01
Under the hood, they always send structured something, right?
12:04
And so you send a different structured something that's just data that like— and so, you know, user installs a tile to the chat room.
12:13
Everyone in the chat room gets to see that tile.
12:16
And then the thing is, those things can post messages that are basically CRDT that sync state across every instance.
12:22
Of the tile that people in the room see.
12:25
And so you can do something instead of like having all these fucking doodle things that are always ugly and like you lose the link and you never know which one.
12:32
You just like in your chat, you just like drop a time picker thing where you've like configured some options and anyone in the chat can answer and it syncs the options for everyone.
12:43
And you could do that with a document.
12:44
You could have like a shared Markdown editor, like let's edit a doc together in the chat.
12:50
So that's another thing.
12:52
Blento, you know, this is almost so obvious that— You're killing us, man.
12:58
Oh, man, sorry, sorry.
13:00
The thing is, I don't even know what these guys are going to say.
13:02
So sorry about that.
13:03
Let me go faster.
13:05
That way— this thing, this is like, what if we could render arbitrary content by loading a tile that has a render wish?
13:14
And so imagine that you have like whatever, this is like a karaoke lexicon.
13:21
And inside of it, it has a stratosphere lexicon.
13:23
And you just want to arbitrarily render things.
13:26
You could load a tile that knows how to render this so that you can do nested rendering of arbitrary embedded lexica.
13:35
And this one is actually my favorite.
13:37
It looks like ass, like most of the things I design, but that's fine.
13:41
But the idea here, and actually, I'm going to use the real thing if I can find where the cursor goes.
13:50
Yes.
13:51
So the idea here is that they don't have to be on ATProto, right?
13:54
They can be inside a CAR file.
13:57
So you can have a local file that contains a tile that you can run in something that's like a PDF viewer.
14:02
And so you could kill PDF because we should kill PDF.
14:07
but we don't just kill PDF by reproducing PDF.
14:09
This is basically a presentation that I gave about tiles that was in a tile.
14:16
And so you can do this, of course.
14:19
But the other thing that you can do is that you can have self-editing documents.
14:24
Because you can make it so that the tile can write to a data segment in its own car container.
14:30
And therefore, this is a rich text thing.
14:33
And I can say like, hi folks, whatever.
14:36
And you see the little save things here.
14:38
If I close this and I email it to Ricardo and he opens it in this and he doesn't have a rich text editor, he just has the PDF replacement thing, then he can open it and edit it.
14:50
And you can, you can do this with arbitrary editors.
14:53
So like for instance, here it is, MS Paint, you know, and you do this and whatever.
14:59
And then you have an image editor that I can send it over to Ted, and he can edit the image, and yada, yada, yada.
15:07
And so with that, we have websites.
15:12
We have a fake demo shit browser on it.
15:15
It's a Dazzle spec, because everything's Dazzle these days.
15:17
That's how you dazzle people.
15:19
And there's some code that you can check out on the wonderful npmx.
15:23
And you can come to our meetings.
15:25
We share stuff.
15:26
Fuck yeah, tiles.
15:27
And with this—
Robin Berjon
15:51
Can everybody hear me?
Speaker C
15:54
All right, awesome.
15:55
Nobody can see what is on my screen, so let me just fix that.
15:59
Oh, I'm giving away the thing.
16:01
We're going to go fast.
16:02
This also is extremely unstyled because we've been doing this around organizing a conference.
16:07
So this is more of a tech demo, especially since Robin has given you the dream, in part, and shown a lot of what we thought was really kind of cool about WebTiles.
16:18
So I'm going to run through some of the stuff quickly.
16:20
And just kind of give you a sense of where— once we saw WebTiles, what we immediately thought of.
16:24
Because the entire pitch that Robin's giving is around having these self-contained little tiles that you know that you can kind of pass around safely, which I think is really an exciting idea.
16:35
And the notion of these things as pieces of contextless, content-addressed, signed data is really useful, especially when you start thinking, well, OK.
16:46
What if we reintroduced a little bit of context?
16:48
What context would you want to introduce?
16:50
And so we said, well, why not think about ways in which you could actually gain access to app proto data directly through this?
16:56
So what we've built is a platform for being able to create and host web tiles.
17:05
And these things are as simple as something really goofy like an HTML page and some JavaScript.
17:13
And they can be dragged and dropped.
17:15
And there's a reason why I'm going with this super simple example here first, because I want to be able to show that these are things where if you want to handcraft something and just upload it and make something tiny, quick— let's see, hello world clock— you absolutely can.
17:38
You can self-host, or you can upload these things, host them.
17:42
Share them with other people.
17:45
These are— I'll keep going— embeddable, and our whole goal is to be able to build a runtime that can provide a way to load web tiles and connect with your app proto account simply and easily.
Speaker E
18:02
So I'll—
Speaker C
18:04
whoop—
Speaker E
18:04
switch between desktops here.
Speaker C
18:06
So this includes things like being able to just take an URI from, say, a desktop app, and also just load the tile.
18:14
And we've been talking about all the different places in which we could stick and embed these, whether these are within web apps, as Robin was pointing out, social feeds, embedded inside of leaflet posts or other sorts of data structures where you can both be confident of the safety and security of the app that you're embedding and still give users access to all of their data.
18:37
From there, though, this gets a lot more exciting.
18:40
We can do quite a lot of things with arbitrary access to data, including crazy things like, why don't we build embeddable media players?
18:50
This is data that is up on the protocol.
18:54
And—
Ted Han
18:54
[Speaker:AUDIENCE] So part of the thing that we built is basically a Razzle CDN.
Robin Berjon
19:01
As tiles are created and propagate through the network, we look at the CIDs because CIDs are identifiers for both records and for blobs.
19:13
And we can serve them geographically.
19:15
We know that they are generally safe.
19:17
When you label a CID or an ATURI, you know that it's not gonna change, which means that you have a certain guarantee of trust in the future.
19:26
And we can return that in chunked streaming forms in whatever mechanisms are necessary for streaming audio, video, et cetera.
Speaker E
19:36
And so we can also define the security boundary here pretty easily and simply to align with the affordances of the protocol.
19:44
Right?
19:44
Atproto has a capability model that allows you to define—
Speaker C
19:49
Yeah.
19:49
So for example— What's that?
Ted Han
19:51
And you can.
Robin Berjon
19:52
Yep.
Speaker E
19:53
With you cans and other sorts of things.
Speaker C
19:54
So this allows us to do some fun other things that build on the work that we've been talking about for the past year.
20:02
For example, being able to do gated content.
Speaker E
20:05
You could embed an article in, say, a social post that goes and checks whether or not you have proof of purchase or a subscription or a membership to a particular service.
Speaker C
20:17
And that actually will immediately unlock for you.
20:20
Or if you don't, you have a call to action there directly.
Speaker E
20:25
And in this context, maybe it's a call to action to pay for the article.
20:29
And then you issue, you know, payment requests here, say, yes, I'd like to pay for this.
20:35
And then it actually goes, makes an XRPC call, proves that you've got the signature, and then loads the rest of the content directly for that record.
Robin Berjon
20:42
Over the past several months, we've, you know, I've published quite a bit on how and why ProtoFans works the way it works, attestations, and the whole concept that you can have proof of payment, not web payments, but proof of payment on record.
20:55
In structured, uh, structured ways.
20:59
Which means that, uh, if you are a content provider, like with the BetterStack tile that we produced, uh, your payment, uh, your, your member base of people who have paid for the one-offs or the subscriptions, they follow you if you want to change payment providers or not.
21:15
If you want to change your PDS or they change their PDS or any combinations of identity and data mobility, which is central to the AdProto ethos, like this allows and enables that.
Speaker C
21:25
Yeah.
21:26
And this isn't just about connections with your PDS either.
21:29
You can build and launch other services that can talk through XRPC channels and that can extend everything from like little sessions and being able to do real-time-ish experiences.
21:45
Like, why don't you give me a high five here?
21:47
Yeah, yeah.
Ted Han
21:47
There you go.
Robin Berjon
21:48
High fives.
Speaker C
21:49
Oh, I got to send the permission.
Speaker E
21:52
And so this provides the opportunity to do things like actually doing games directly in feeds and other sorts of mini multiplayer experiences.
Robin Berjon
22:02
What's really important to note that this isn't magical.
22:04
This tile is entirely sandboxed.
22:06
The tile itself is not making external API calls.
22:09
It's not breaking the boundary that we set from our security profile.
22:15
What it's doing is it's communicating with the runtime, whether that runtime is the browser making xRPC requests that are authenticated and have the context of the user, allowing for a stateless tile that is deterministic in nature, thanks to Content Addressable Storage.
22:31
But we have this global context of your PDS and the xRPC calls that you can invoke.
22:36
So we can provide some structure around making queries and procedures and WebSocket connections asynchronously to offer this experience.
22:46
Yep.
Speaker E
22:46
And so we have a bunch of experimental runners, which we have been tinkering with, like for example, this Rust desktop-based one.
22:53
So now we have a—
Speaker C
22:55
whoop.
Speaker E
22:57
OK.
22:57
Don't have the permission for it.
Speaker D
22:58
All right.
22:59
Well, come back.
Robin Berjon
22:59
It's a little strict sometimes.
23:01
There's a query string parameter to allow for create and destruct methods.
Ted Han
23:04
Doop, doop, doop.
Speaker C
23:05
So we'll go back to using the web version of this.
23:08
And let's see.
Robin Berjon
23:12
Hello.
Speaker E
23:21
These are all individual aircraft.
Robin Berjon
23:27
Hangar software is Han Jeroen Kienes.
Speaker E
23:34
And so, right, like, these are little full apps that you can post and do anything you want with.
Speaker C
23:41
So the two things—
Speaker E
23:43
I mean, and Robin's kind of given the game away here.
Speaker C
23:45
But one of the things that we're— no, no, it's perfect.
23:47
Like, that was great.
Speaker E
23:48
Being able to talk about where we want to put all of these tiles and how can we share these.
23:52
My thesis around this is having good structures allow for people to be able to experiment more.
23:57
And so, you know, I started out with, like, a little goofy app that you can, like, hand code if you want.
24:03
But also, like, this is a great place to safely be able to experiment with apps, plug Claude in and say, go for it.
24:11
You can read lexicons out of the Lexicon Garden MCP and give people capabilities to tinker with data, have front-end capabilities on top of the app proto stack, and basically be able to grow the types of things and the access to other communities for building new apps.
Robin Berjon
24:28
To check the little agentic AI checkbox that's now required everywhere, the difference between an MCP application and a web tile is the runtime.
24:37
So we right now, there's this service is actually an MCP.
24:40
So if you authenticate in and say load the Hello World tile or load the Create Post tile, it will use the same structure, the same, the exact same runtime structure to make authenticated XRPC calls from within your agent to do things like create posts, make XRPC calls, et cetera.
24:59
And that means that we have broad, broad distribution.
25:02
Anyone can say, hey, I want to have an allow list of tiles that are going into Rumi.
25:06
Or, hey, I want to have a standalone website that displays some of this content and has a runner that supports this payment method specific to this content provider.
25:17
And that same tile can then work on a mobile device.
25:19
It can work on a desktop app.
25:21
You can have a local CAR file with a dual CAR data payload that you can give to someone else to load that local data.
25:29
It's truly distributed content.
25:31
And we think that's pretty cool.
Speaker E
25:32
Let's bring back mixtapes.
Ted Han
25:34
Yes.
Speaker C
25:37
Okay.
Speaker E
25:37
We've got, like, a minute.
Speaker C
25:39
Any questions?
Speaker F
25:45
Okay.
25:46
This is awesome, you guys.
25:47
Like, I wanted to do this 15 years ago.
25:51
So the— basically what I wanted to do is actually put charts, interactive charts or maps in a feed?
26:01
Okay.
26:02
Okay.
26:02
My question is, with regards to security, so you— I'm guessing you can run a JavaScript here within, right?
26:11
So how does it cross boundaries with, like, if there is Content Security Policy?
26:14
How does that work?
Robin Berjon
26:15
[Speaker:MANOOCHEHRI] So basically, when the tile runner gets a manifest, it takes that content, and because it's a CID that's recognized and listed in the blob, the runtime is ferrying it down, and then it's loaded.
26:31
And that's the same way any assets are referenced as well.
26:34
So like the image gallery one—
Speaker D
26:36
could you pop that up?
Ted Han
26:37
Yep.
Robin Berjon
26:38
Image gallery, whether it's JavaScript images, media, et cetera, the runtime is making these calls to determine what can be fed into the sandbox.
Speaker E
26:49
The other thing about this is each one of these tiles The way that we host them is actually giving them each their own subdomain based on the CID.
26:58
So they're actually sandboxed based on origin.
Ted Han
27:02
Like a synthetic origin?
27:03
Yes.
27:04
Not a DNS origin?
Speaker E
27:04
A random synthetic origin?
Robin Berjon
27:05
Yes, a synthetic origin.
27:08
Non-deterministic to make it more difficult to avoid two people somehow getting the same DNS and having the chance that there's contamination.
Ted Han
27:17
You have a question?
27:20
Are you using wishes in your message channel here or a different type of messaging channel because Tiles Basically, you can use it for—
Robin Berjon
27:26
So wishes— and please do correct me if I'm wrong here— wishes represent the intention of a user to take an action that may involve other tiles.
27:34
This is adjacent to it.
27:37
And it's specifically XRPC calls within the app proto ecosystem.
27:41
So it's not conflicting and could support it.
27:44
We could look at what layering of tiles or navigation or the wishes concepts look like.
27:51
Yeah.
Speaker D
27:53
The wishes are much more for the use case of like arbitrary composition.
27:58
It's— the idea is really task-based computing.
28:00
So you don't— you want your thing needs to carry out a task.
28:03
It doesn't know who else can answer that task.
28:06
And then that means you have like open-ended composition instead of having apps because apps suck.
28:12
Oh, and one small thing I wanted to add.
28:14
I didn't have time to add it to my presentation.
28:16
Some person I'd never met or interacted with the other day on blue sky said, oh, this seems interesting.
28:24
I'll integrate it.
28:25
And then the following day, they shipped a servo-based browser that supports tile.
28:29
So it's coming.
Ted Han
28:31
That's awesome.
28:32
For clarification, I was asking so that people would know you don't have to use wishes.
28:35
You can use all kinds of things.
Speaker G
28:38
Is Hangar open source?
Speaker C
28:41
Parts of it.
28:42
Not yet.
Ted Han
28:43
Yeah.
Speaker E
28:43
We intend on open sourcing parts of it.
28:45
But there's a bunch of different components that we're—
Robin Berjon
28:48
Yeah.
28:49
We think that there's potential value to the community ecosystem to open source both the runtime and the CDN, but then make some of the xRPC services specific to payment processing or other things, the secret sauce of how this thing can sustain itself.
Speaker E
29:08
One last question, and I think we've got to wrap up.
Speaker G
29:11
Yeah.
29:13
Forgive my ignorance.
29:15
This is the first time I've ever heard of WebTiles.
29:16
Is this a W3C thing?
29:18
Is this supported in all browsers?
29:19
Is this a WASM thing?
29:22
What is the runtime, I guess?
Speaker D
29:23
So I mean, this is not a W3C thing.
29:26
But the runtime is like a web runtime.
29:28
So it works in the browser.
29:31
It's not a Dazzle.
29:33
The container itself is not a W3C standard.
29:36
It's a Dazzle standard.
29:38
So I mean, if you want to call Dazzle standards.
29:39
But it's along the same suite of stuff that powers the rest of 80 Pro.
Robin Berjon
29:44
Yeah.
Speaker D
29:45
No, this works in a browser today.
Speaker E
29:47
Yeah.
29:47
And the key things here are web tiles are standard.
29:51
The runtime that we're talking about is the thing that loads web tiles and has the message channel for being able to connect to your app.proto account.
Robin Berjon
29:59
I think there's a lot of room to standardize and create more formality around what runtimes do and don't support.
30:05
And the MASL document is actually— it's simple and plain complementary.
30:12
It does exactly what you'd expect by defining what resources we're using CIDs, Content Addressable Storage references or links, to tell you what it needs to load and how.
30:23
And then it's up to the runtime to implement it.
30:25
So think of it as like the PDS is a collection of XRPC services.
30:29
It's not really a formal spec.
30:31
But you do have a general shape of what it looks like.
30:34
It's very similar.
Speaker D
30:35
And also, generally, I mean, the way we do specs in Dazzle, we do small specs that do one thing, do it well, and that way you implement what you need to implement for that.
30:44
So the tile spec is tiny and it's just tiles, but the wishes spec is going to be separate from that and it's only wishes.
30:52
You could do task-based computing in other contexts, but also various environments.
31:01
So for instance, I demoed— I showed Roomie integration.
31:05
You could have a chat context integration.
31:09
And like if Rumi integrates it and say, I'm making this up, Matrix integrates it, you could use the same tiles in both.
Ted Han
31:15
Yeah.
Speaker D
31:17
So we're like 10 minutes into the 1 minute.
Speaker E
31:19
Yeah, we're now in the bonus round.
31:22
This is the coffee break.
31:22
So please be free should you want to be.
31:25
Otherwise, if you would like to talk about tiles more, let's go.