mergeconflict346 === [00:00:00] James: Frank. Frank, Frank. Frank. Frank. Frank. Frank, Frank. Frank, I wanna talk to you about a serious topic that not a lot of people are talking about, but is sort of, maybe because it's a deeper, lower level talk, but I feel like it's a topic that Frank Kruer would be into cause our good friend Eric, There we go. Perfect. Eric Sync the, you know, without Eric Sync in general, SQLite doesn't exist in the world of.net at all. Uh, what about a very fascinating blog post, and this is in a part of, uh, a series of blog posts on something called Native a o t for.net. Do you know what this is about? Do you know we're about to go with this? Only because I sent you the blog post earlier in. [00:00:53] Frank: Oh, I've been doing my research. When you give me homework, James, I do my research and yeah, this is totally a topic I'm into and I, we should do more episodes about Eric Sink's work. I'm a big fan. Uh, he and I seem to collide on topics all the time, so yeah, we both got into sequel light around the same time. Uh, my library takes a dependency on his, and we both get into Native Coda a lot because we are weird. People, and we love thinking about machine cycles and assembly language and things like that, and object file formats. I don't know why I'm into this stuff. It's weird. It's a weird hobby. Anyway, , uh, native a O two. You know, it's, it's funny because coming from the mono za iOS world, we've been doing native. A o t lowercase letters for a very long time. Uh, but Microsoft has, um, a new technology native, a o t capitalized, capitalized native where, um, done net six, I think had a done. Net seven definitely has it where it compiles your. Managed app, your C Sharp app into purely native code. And I think the thing I kind of knew that was a feature because I'd heard Scott Hanselman bragging about it a lot, where you can just publish your website down to native code. Hmm. Uh, the part that I didn't know, uh, and Eric Sync is talking about is, There's support for libraries too. So you can take your C Sharp library and turn that into a native library, not just a native app. And that's kind of cool. And he has gone absolutely insane. playing off of that idea, seeing how far he can push it in, what things he can do with it. And so I think this is gonna be fun. Let's talk about native a o t Libraries. [00:02:45] James: Yeah, because I think native, native, a o t, you're right. I think even when I talked about, in one of my videos, I talked about how you can take your like, you know, um, council app or whatever, and a o t if I it, and just, it's an XE that runs everywhere and it's super fast a startup and you know, that was the, the major thing that folks talk about. And now you're right. Like what? He did in this blog post and video that I'm gonna put in the show notes and definitely recommend everyone take a glance at is use native a o t to take a library specifically Quest PDF is, which is a really, really cool PDF library for.net developers for like generating PDFs and reading PDFs on this stuff. Took it and got it. Inside of a rust application, . Now how he got there is very fascinating as what we're gonna talk about. But before we even get into that, I think he makes a good point, um, in this blog post, which is, this isn't like a, a new concept of running.net in another, um, like operating system. Not operating system, but other, another language and another framework, right? Mm-hmm. . Has been done for a while. Like if you think of, um, um, I dunno, you know, you gimme an example cuz you've done it. [00:04:06] Frank: Oh yeah. , I mean, we'll go all the way back to the early days of Monto and Zamarin. Uh, Zamarin always supported what they called zamarin embedding. So you could take an objective C app that you're writing an X code and. Put a Zamarin app inside of it. So your main app, your main compilation can be um, you know, native code, but then you can take advantage of managed code by taking a library dependency. They called that embedding. But embedding was just a fancy term for, we packaged up , the.net runtime and all your code into native compatible layers. Um, that native code could talk to. So when we say native code, um, it's funny because e Eric is loving his rest , he's way into the rust world. . I'm not a rust person myself. Um, but what's enabling all this tech is we call it the C A B I or the a b i, the application binary interface. And it's just an agreed upon way to shuffle around data in order to call functions. and if you can make, uh, a library that obeys the abi, the standard ABI for the platform, it's different for every processor. It's different for every platform. If you can, I'll put that kind of stuff. Then pretty much any programming language can talk to it because, Any language worth any of its salt. can talk to a C library. That's just how the world is. We have to be able to talk to the operating system that's done through the C A B I. You need to be able to talk to old timey libraries. That's through the C A B I. And so of course, REST can talk to the C A P I, uh, see sharp can talk to the, um, see a b I through P invoke. That's what P in Vogue is. That's just, uh, making all that work. Uh, so this is, as he said, it's, it's not a new concept. It's just kind of neat how easy they made it to take a c sharp library and expose functions. You're not gonna expose your classes and all that kind of stuff. What you're gonna have to do is create some new global functions, basically some static functions that. Take data in and pass data out that obey that a b i. And once you do that, pretty much anyone can talk to it. Python can talk to it. Russ can talk to it. Go can talk to it. Ruby can talk to it. C Sharp can talk to it. , [00:06:39] James: I think we, we, we take our.net, uh, libraries. We run them through, uh, native a o t and then we get a C library. And then we create P Invoke wrappers around that and then call it again from C Sharp. I think that'll be the most performant way of doing [00:06:55] Frank: it, correct. Yes, exactly. I think Eric even has, uh, so you, you mentioned Eric Si bed on a blog series talking about all this stuff, and I think even in one of his blog posts, he did exactly that experiment, took some C sharp code, compiled it down. The native wrote other C sharp code that talked through the native layer to that C sharp code and had it all working. Hilarious. That's not what it's for everyone. That's not what it's for. ? No. What it's for is, um, deploying libraries to other operating systems in case you don't like, there's always libraries that you pick up. Like I always pick up lib jpeg, you know, you want to compile some Linux software, something you need lib jpeg. And so this would enable you to create, uh, lib James with all, with all your good code in it and have that available to cn Russ programmers the problem. is, as we all know, pian Vogue. No one likes calling Pian Vogue. It's annoying. Um, no. , you don't want to call native C code from Python because it's not Python. It you have to go through a bunch of wrappers and marshaling data and converting string types and all that kind of stuff. It's really ugly. And so Eric did the, uh, especially fun thing of, he's like, well, if, if we're gonna make these things cullable, he also, uh, Made rapper libraries to make it easier to call. We should get into all of that and how, how crazy it is to be doing rappers from that direction, because we've been doing rappers for Jain forever. But it's, it's all just weird. It's, it's weird how it's a big cycle that can just keep looping [00:08:32] James: around. Yeah. And then the important parts to mention here is with the native a o T aspect, like you said, this is compiled down to that sea library and it follows, as long as those exported functions follow the sea rules, things will be gravy. And again, the biggest advantage of this, I'm just gonna reiterate a few things that you said, but you, you talked through a lot of things. I wanna reiterate a you part that there's no C l R involved at this point. [00:08:58] Frank: They just put it all in. Yep. That's huge advantage there. Sorry, I should say it's there. They're just packaging it [00:09:05] James: up. Yeah, so, but you don't have to host the c r I should say. And now that was one of the things with the ator was that, uh, you needed to host the C L R, but then if you had multiple Cs and there were some conflicting stuff, it was kind of a pain in the butt. . I think this is like one of the big advantages. So the biggest advantage, like you said, is, oh, okay. Like any new programming language comes out, if it can speak to a C thing, it could take advantage of these things. Or if you're like, Hey, I have tons of Donnell libraries, but these folks over here that Eric's leading this team on wants to do everything in rust, we're gonna have to throw away or rewrite all of our work. We can leverage that. Or this fancy thing that's available in.net, which. Super duper crazy impressive at the end of the day because again, it's just, see, but I agree with you, the biggest thing that I always struggled with, because there is some tooling in Visual Studio, and I remember, uh, working with like the c plus plus team in Visual Studio way back in the day where they made it really easy to like drop in a. C Sharp Library into an Android app, and it would automatically create the bindings for you and like you could like expose a few things and access it. It was really, really neat, uh, because it was just like automated in that regard and not having to do anything manually. But I think even now in our documentation, it's like, oh, like drop in these, you know, Your files and then just call B Invoke and you, you'll figure it out and just get every single parameter correct under the sun. Yeah, . That's not, not super fun. [00:10:42] Frank: Yeah. So, okay, at one level this is all super easy. If we just take a step back and rewind. Um, I had to follow along in Eric's blog cuz I had never created one of these native libraries. So it's neat. You just create a class library and then you add a property to your project file called publish a o t. and you said it to true . Done and now done. And that's it, . And now when you, um, you have to say.net publish, it doesn't happen during.net build. So net build, blah blah blah.net publish is when it does all the crazy work of, um, It's kind of funny. Um, it, it, it was going slow at first. It wasn't giving me any console feedback. I was like, what's going on? And so I brought up my network monitor. I saw I was downloading many new versions of.net because it has a special, uh, packaged version at.net. It does anyway, uh, so it, it downloads all that, links it all together and outputs the native library. So at at one level it's it's trivial Bra, Bravo team. You did it. Great job. At a second level, it's a little bit complicated because, um, as I said, your managed objects aren't gonna be exposed. right away. This is you. You are gonna have to think through what is the native interface to your library going to be. Mm-hmm. . And you're gonna want to create very specific functions for all of those. And that's nothing new. Um, I remember, okay, so sorry everyone, this is gonna get complicated cuz it's a big giant circle. In Theam days we wanted to bind to c plus plus libraries, C plus plus libraries technically. Abide by the C A B I. It's just they're weird. C plus plus has its rules. It's not, it's not so easy to just bind to a c plus plus library. So in the end, all c plus plus libraries would have another funny version of them that presented a much cleaner, simpler c. Interface. Just functions, just data structures, just pointers. That's, that's the happy world of the Unix world that we all live in right now. That's, that's all Any binary wants to be, just functions and data structures, and so you would have these. anytime you wanted to bind a c plus plus library, first thing you would do is write a C interface to that c plus plus library. And then in whatever language you were trying to consume that from, you would write a wrapper around that C , uh, interface. So this is all kind of gross and weird. Um, It, but it's been a common problem. It it, it's something you always have to do when you have a rich programming language and you wanna present a simple interface. It's usually best to just declare and write that simple interface directly. and uh, you can do that pretty darn to easily. Also, you just create some static classes, put some static methods on it. Put this funny attribute on it. What's the attribute called? It's something like, um hmm. Unmanaged Callers Only. Ooh, I love that name. So , only unmanaged people, native people are allowed to call that code and you create your nice clean sea interface to your library. [00:14:06] James: Yeah, it's beautiful. In fact, I remember having to do this when I was demoing Ator that it was, the reverse was true is because I wanted to take my C sharp stuff and expose something to objective C through the same exact system, but I didn't. I wanted to make sure that I wasn't. Like using gen, like creating things with generics and like invoking, you know, this and the returning types that, like the other thing wouldn't, you know, would be compliant right at that point. So you do have to sort of, um, yeah, interestingly enough, spice it up a little bit to make it, uh, make [00:14:42] Frank: it work for you. Yeah. Uh, and, and so, The C A B I is wonderful, but it's annoying because it, it is so simple. It's functions and data. That's all it is. And so I think the, the beauty of the work, what, what's really coming out of, um, this.net version is.net is a very rich programming system. I wanna say C sharp is, but really it's, it's all in.net. It's in the il, it's in those managed libraries. It's in the assemblies. Mm-hmm. , it has rich type information and all of that. . And so what I think is so cool about Eric Sink's work is he's like, you know what? Writing that sea interface and then running the rust rappers over that sea interface, that's a lot of work. And Eric Sink is like me. We're lazy. . We, we we're willing to spend three months. Writing a new tool to generate the rappers rather than spend a day to write the rappers yourself. And so he did the super cool step of for Rust, and you could do this for any other language of not only, um, exposing that C A B I. To the native world, but also generates the wrappers for the rust so that you can write rust code that, I mean, I don't like rust . I think it's a bit of an ugly programming language, but at least the rust equivalent code for using the library looks like the C sharp code. You know, it's nice and clean. You're not calling funny function names, you're not marshaling data, you're not doing any of that nasty stuff. Uh, he's generating very nice rappers in addition to. [00:16:21] James: Yeah, that, that's really, really neat. I mean, I think that's, that's the hardest part, right? When we were talking about bringing in any C library, is you're not calling those things from C, right? You're, if you were using them in a C program, which I know many of our listeners are definitely writing c just normal C program, you know what I mean, all the time, , uh, then it, it wouldn't be such a big problem, right? But to your point, it's, I want to use this thing in. Language that I, that I want to use. And Donnet developers have that same thing when they want to use a C program. Um, they want bring it in. I guess the question is, he mentioned in the blog post Swig, which I am very, very aware of because it's a simplified wrapper and interface generator, uh, that supports C Sharp. And the whole idea is to run your cc plus plus libraries through swig and it will pump out a, um, The binding thing for you. Uh, but I don't think that that supports rust. It seems like it supports Go and Java and r and a few other ones, but basically he wrote Swig for Rust. Is that [00:17:32] Frank: correct? Yeah, exactly. Uh, taking advantage of some things. So swig, I actually had to look up. I don't have much experience with it, but it solves, like you said, it solves that problem of the wrapper generation for the different programming languages. Um, the problem is, it, it's coming at it a little bit. Um, it doesn't have all the information that's actually available to.net at the time that you could write these wrappers because it is generic. Mm-hmm. , um, it. You know, it has access to the native code and things it can figure out from there. But I think the neat thing that Eric Stern is because this is coming from managed code, which is type rich and information rich, he can generate better, uh, wrappers than I think sway can. I, I don't wanna take anything away from Sway cuz it's super cool what it's capable of doing. It's create all these binding libraries for all these different languages. Um, but. Uh, specific built tool's always gonna be better than a general purpose tool. So I think super cool, uh, what he's doing, it got me to think. I'm like, okay, he likes rust. I'm not a rust person, but you know, I do c plus plus. It'd be fun to have the c plus plus header file generator and all that, that actually reflects like your class hierarchy generated for all the code. , obviously I'm old. No one wants to write c plus plus anymore, but that's where my mind went when, when he did this rust demo, I'm like, oh wow. You could actually generate some decent, uh, c plus plus classes also from it. Yeah. Fun Programming languages are fun, aren't they? They are [00:19:15] James: fun. Yes. It's a blast. Well, you know, and the one thing that I wanted to kind of talk about here is, you know, The, this is a really neat project. I recommend people now reading the blog, but also taking a look at his video too, because he demos all of it. Now it's like six minutes or so walking through the entire process. Uh, near the end of the blog, he links to the, the video. I'll put it in the show notes. But what I think is cool is there's nothing, there's nothing like, obviously the rust stuff and the bridge stuff that he is running is there, but there's nothing really, like you said. That's like wild, right? Because you just calling.net published commands. There's like a few package references and then that's sort of it, right? And just like then puts it in rust and does the rust stuff. So it is kind of just normal, just development, yeah. At that point. And you have an API. [00:20:11] Frank: I mean, that's so fun. Like Yeah, it's a, they made it trivial to generate a native library, so that's cool. And then that means the only hard part left is generating the wrappers. And once you have a tool to automate that for you, um, Yeah, life should be good. He did joke, uh, in his blog that the tool's not the easiest thing to use. the rapper generator, they never are, uh, if anyone's ever done. The rappers I have the most experience with are the objective C wrappers for NC Sharp. So you're making one object-oriented programming language. Talk to another object-oriented programming language. Something that's even worse than the C A B I. It's the objective C a B I . Hmm. And so I remember when it started out, we were, we, we thought it would be so easy, you know, it just objective CS seem so simple. You just have a few different. Types, pass them around. You call objective C, message send. Life will be easy and good. And now when you look at modern bindings used in, uh, net seven for like iOS or for Xin, for iOS, there's like a thousand attributes on every method. On every parameter being very specific about exactly how it should be marshaled. So it's, it's funny, there's a slippery slope when making one programming. Talk to another. You can get 80% of it to work very quickly, but then that last 20% is very difficult. And that's all I was thinking about when he was joking about, uh, complicated command line arguments. I'm like, oh yeah, been there, . I know what you're talking about. [00:21:52] James: So really what ends up this being is, you know, when we look at the use cases for this, this sort of shows you the power and flexibility of of.net as as, as it continues on its adventure, right? It's not only being able to build anything with.net, but also bring.net anywhere easier than ever. And again, I said it's not like a new concept, but it's a newer Hmm. Enhancements to the process. You know, when I think of the adoption of.net, I really hope that, you know, it's looked at and it's sort of these different ways of using.net are kind of celebrated in a way, cuz some people could look at it and say, oh, well isn't this just like a way for people to get away from.net? I'm like, well, no. I think this is a way for people to use.net in a different way where maybe. You know, maybe even.net doesn't run everywhere, right? Like if I think of, yeah, couldn't you just take some cool library and then run it on like a tiny, like, you know, I don't know what, like what's a little, uh, SB board or e s P 32 board? Couldn't you just run, it's a C. It's C, right? Could you not do that? Couldn't you be generating PDFs on an SB. 32 right now using this thing. Frank, technically , [00:23:04] Frank: uh, no, sadly. Oh, but close. Close, um, . So when you do native, it's native, which very specifically means your processor type and the operating system that it's gonna be running under those ESP sps that I absolutely love, they're their own processor type. They're not even. Uh, yeah, they're, they're, they're just their own. Uh, PRI is the company. It's, it's, it's their own processor architecture. It's its own assembly language. the.net team is never gonna support that , but the.net team does support ARM 64 and maybe arm seven. I forget. I think arm 64. Yeah, it says Arm 64. So if you had, um, a little embedded processor that ran arm 64, you'd be all set. You could do it. You if with the, it runs on Linux , so you would have to get a little mm-hmm. on there also. , but technically it would output all the things. That's a funny scenario. I was thinking of a simpler scenarios. Uh, plugins are a big one, so if you wanna write like a Photoshop plugin or a blender plugin mm-hmm. those are almost always native code, um, like a. Dynamic library that you put into a folder and then the app creepily picks up your dynamic library when it's, uh, loading up. So I was thinking about, uh, the Blender sdk, which is just a c plus plus s d k. You could write a.net app that does. , all your magical 3D stuff that you wanna do, but you gotta package that up into native code and you would be able to use native a o t here to do that and expose the interfaces you need to become a plugin. Photoshop the same. These are the old ways plugins used to work. [00:24:53] James: That makes a lot of sense. Yeah, I was thinking about how when I worked at Canon, there was a lot of similarities. We had like a plug-in format and things like that. Yeah. That, that's kind of cool. And think about that. [00:25:03] Frank: Yeah, I, I think that's a big use for it. Um, another one is, you know, just efficiency. , you know, if, if you don't wanna bring up the whole c l r, you can, uh, package it all up. Honestly, native a o t makes most sense for apps. I, I should be shipping Kka as a native a o t app for Windows, because it would be like a five megabytes self-contained exc, you know, no dependencies, nothing like that. Super cool. Uh, so it has those benefits, but for libraries, oh, there's, oh yes, there's still places where you need native libraries. But can I complain now? Real. Yeah, go [00:25:40] James: ahead. I was, I was waiting. I was waiting. , [00:25:43] Frank: I was effusive here. I I was very kind to it because it is wonderful technology, but the big butt is no Mac support James. Mm. Where, where's the Mac support? It's, it's kind of funny. If you get.net seven, I was playing with this on my computer and you tell it to build for a West 10 X 64, it's still called a West 10 in the.net world. , it'll build it. It'll actually create a dynamic library. It just doesn't work. . It's just, and it's not supported. Um, so the supported platforms are Linux and Windows, Intel 64 bit and Arm, 64 bit. Those are the four platforms you can run it on, which makes sense. Windows, obviously it's Microsoft Linux makes a lot of sense because everyone's doing dockers and server deployments and all that kind. So if you're running your apps and Docker and everything, you absolutely should be doing this and integrating with other kind of native apps. But no Mac James. [00:26:45] James: No Mac. Well, I guess the question is, and I'll put it out to you, I'm assuming this is a no, but is there any way to just say if you had a library, not an app, right? You just have a Donna library and you're like, oh, I have a, I dunno, A Swift or a Kotlin app could, I mean, cuz Android's just Linux, right? at the end of the day. Mm-hmm. , I mean, obviously Wow. iOS is something. [00:27:14] Frank: It's something. It sure is. It, it, it's funny. I mean, it it, they're not queer, it's not supportive. The documentation says not supported, but the tool doesn't fail necessarily. Like mm-hmm. . Uh, so when you create native code on Windows, it's gonna be a dot d lll, uh, for a dynamic library, if you create a static library, it's gonna be a dot lib. On, uh, Linux, you would get a, so for a shared object shared library, , you would get a a for an archive for static code on Mac, you should get a um, a dial lib. Um, that's our dynamic libraries. And it's funny, when you run the tool and tell it what's runtime to output, it will output a dial li and that code is executable. It just doesn't initialize correctly. It doesn't link correctly. I think there's actually something missing from the object file format. I wasn't able to find it exactly, but. A very simple library outputs a big nine megabytes cuz it's not trimmed, , uh, self-contained version of the c l R and my code. But, uh, I haven't been able to get it to work yet. I don't know. Just have to complain. To who do we have to complain to? Rich Emo. Who do we complain to? , probably Rich. I [00:28:30] James: would say there's probably someone rich. There's someone probably rich first and then follow up in there. Yeah. Cause I'm looking at the samples repo on the on.net/samples and there's a, uh, under core there's a native a o t and there's like, it says the, when you run this above command, It will drop a shared library, windows dl, l o s, xlib Linux. So, and sure enough is there, I guess, yeah, on Android it does the, it does ask for, so files. Mm-hmm. , man, that'd be just interesting. I really want to spec it and like just test it. Just even a, a simple Hello world. Yeah. Can I take that? So file, put it into an Android app and. Open and run and say hello, world. [00:29:09] Frank: Back to you may have to modify some flags inside the object format. This is, now we're going into the really nerdy territory here, . Um, all of these native libraries, they're just files, right man. They're just, they're just files. You can edit them, you can poke around in them, you can change things in them. Uh, there's a sdk, it's called the FBX sdk. It's a native. Library to open FBX files, which are 3D file format files. They contain 3D geometry and animations, all that kind of stuff. Hmm. They've kind of become a standard for transmitting files around, but it's a native library and I wanted to be able to run it in all my apps, my app support, uh, Mac X 64 and iOS arm 64. But I also wanted to support Mac Catalyst X 64 because I'm in the.net seven world man. I, I write Mac Catalyst. Mm-hmm. Apps. Now the thing is, um, even though I have the static library for Mac. Intel 64 bit. The Mac Catalyst linker won't accept it. It's like, no, no, no. You are not a Mac Catalyst library. I shall not link you. I do not like your code, even though you obey the C A B I and the C A B I hasn't changed between the two, but. , you know what you do? You open yourself a hex editor, or in my case, write a whole bunch of C sharp code to automate the process. And you go change a few flags in it and you say, you know what? I'm not a Mac Library. I'm a Mac Catalyst library. Haha, on you Apple. And then all the tools because they're stupid. Link it on in and it works perfectly fine because you're right, James Code is code to a processor. Code is code. So to a processor, yeah. None of this really matters. and to some extent the operating system doesn't matter. That's how I was able to change out the operating system. What does matter is that operating system provides dependencies. That native library, just because it's a native library, doesn't mean it's not looking for some dependencies. It needs to be able to open files and write files, and mostly files. Mostly they have to do that, and that's provided by the operating system. That's why they're specific to the operating system. If you know what you're doing or you get lucky and like in my case, , you can just modify those too and tell it to go use different functions instead of the functions it's using. So all this to say is hacking native code is hilarious and fun. Um, but I'm glad that we mostly don't have to do that and rather get rich to just support it. Straight up and, and Donna. Yeah, [00:31:43] James: that's, I love it. That's cool. It's, I'm, I'm glad that I took you down. Well, Eric Sink took us down this rabbit hole, so all shout out to Eric for this, but I'm glad that you went even deeper and wilder down this journey. This is very exciting. I'm, I'm gonna very much have a clickbait title Yeah. For this episode, [00:32:01] Frank: and, and Fair. You probably don't need to use this , like unless you're running a plugin, like yes, use native a o t for your apps, but for your libraries, uh, the use cases are a lot smaller, but it's super cool and I love how easy it is. So again, bravo to the.net team and thanks Eric for, um, um, making me pay attention because I haven't been paying attention to this. [00:32:26] James: There you go. Well, I'd be super interested in any, the listeners have any interest in something like this. Maybe during your job you are writing plugins into doing something like that, or you've actually experimented with us, let us know. Go merge, conflict out fm, hit that contact button or hit us up in our Discord or on Twitter, wherever we're at on the internet. But, uh, Frank, I think that's gonna do it for this week's, uh, natively compiled podcast. This is gonna be the biggest download file that you'll ever have because I'm gonna export. A O t. I'm gonna a o t, the mp3. How do you feel about that? [00:32:56] Frank: It's gonna run fast. That's all I know. [00:32:59] James: Fast. It's gonna run soup quick. All right. What he is gonna do for this week's podcast. Until next time, I'm James [00:33:05] Frank: Watts Magno. And I'm Frank Krueger. Thanks for listening. Peace.