Hi, I'm Zor. Welcome to Unisor Education. So we continue with dynamics. This is a part of the physics for teens course, which is presented on Unisor.com. That's the website. I suggest you to watch this lecture and all others on this website, because it contains very detailed notes for each lecture. It has certain educational functionality for people who want to study under supervision. Of a parent or teacher or whoever. So, and by the way, the site is completely free and no advertising. So I do suggest you to go to Unisor.com. Oh, by the way, it also contains a prerequisite course for this, which is the math for teens. So math for teens. It's prerequisite for physics for teens. Now, we're talking about momentum of motion. This is a completely new concept. Well, you remember we had the concept of space, time, speed, acceleration, velocity, mass. So this is yet another physical concept. Now, in this case, it's not a primary concept. It's derived. So we will define it basically. And it's a very, very convenient characteristic of the motion. And it will be obvious why at the end of this lecture. Okay. So first of all, I would like to consider a relatively simple motion, not the simplest. The simplest motion is when there are no forces and the object just moves along its straight line trajectory with a constant velocity. So this is the most simple. The second simplest way of motion is motion with constant acceleration. Now, since there is a constant acceleration, there is a force, obviously. So we are assuming that we are talking about a case when there is a straight line. This is the trajectory of the movement. The force is exactly along this line. So this is our object. And it has certain mass. And it has certain acceleration, which is directed along the same line of straight line of motion. So this is the very, very simple case. And since it's a one-dimensional case, I don't really have to use the vector. So A is basically a scalar. And let this be the positive direction of the x-axis. So A is positive and f is also positive. And we all know the second law, Newton's second law, which states this. So f is a constant force acting along the straight line trajectory of the object. A is acceleration, m is a mass. Okay, so let's now consider two moments in time. First is when the object was here. This is t0, or just t, that would be even better. And another moment in time, then the object move to this position. This is t plus delta t. So this interval is delta t. Now speed was v. And speed of t plus delta t was obviously v plus delta v. Speed is increasing from the value of v. This object had at this particular moment in time. And by the time t plus delta t, speed has increased, obviously. By how much? Well, we do know the acceleration, right? Now the average increase of the speed per unit of time would be v of t plus delta t minus v of t divided by t plus delta t minus t, right? We have the difference between speeds, difference between times. And this is obviously delta v divided by delta t. And this is the average acceleration. But since acceleration is constant, that's exactly equal to a. The same a. It's a constant acceleration, very simple, right? So what do we have from here if we will use this? Well, this will be m delta v divided by delta t. Or f times delta t is equal to m times delta v. Same thing. So increment of speed times mass is increment of time times force. This is a very interesting equation. It has far-reaching consequences. Now, since this is true, let's just make our delta t smaller and smaller. Obviously, we all know from calculus that whenever it happens, this delta v divided by delta t would be basically a derivative, right? So that goes to m dv by dt or mv prime. So this is a derivative of the speed. Okay, so what we can say is that force is equal to m times dv by dt. Now, what's interesting about this equation, since delta t can be infinitesimally small, we don't really have to depend on constant force and constant velocity or constant acceleration, et cetera. Because all we need is the constant value of these within this delta t. Within the next delta t, it can be different. That's okay. No problems, right? But within the delta t, we assume that if these functions are smooth enough, then basically, whenever we are making this interval smaller and smaller, this is the final value. So f can be actually function of t and m can be function of t. No, not m. m is constant right now. For now, I assume it's constant. But velocity is the function of t. So this is already a little bit more general formula because it does not require the values of force and acceleration to be constants. Okay, that's good. Now, what can we say then next? Well, next is we can obviously extend this formula for f being a vector in three-dimensional space. So not just we have this particular straight line as a trajectory. f can be anything. It's a vector which can be dependent on time, obviously. So it's changing. So a trajectory also can change any way we want. And the formula will still be the same because obviously for each coordinate, the x-coordinate, the y-coordinate, and z-coordinate, the formula is exactly the same. So it can be combined into the vector formula. And so I can actually do this. Vector, vector. So this is the vector of velocity, general vector of velocity of the point, which has a mass m. And the force is f. It's any vector which depends on the time. And obviously that equation would be true. All right, it is important. And again, it can be actually rewritten in differential form equals m dv of t. That's the same thing, but this is the derivative form and this is the differential form. Now, what's also interesting is that since m is a constant, I can multiply m under the derivative, right? Because the factor multiplied by a function can be taken outside of the derivative. So it can be d dt.  That's the same thing. And here also the same thing. Differential of m times v of t. Now, one of the things which can be derived from here, by the way, is that if there is no function at all, so the object is completely by itself. So f of t is equal to zero. Then this is a constant. So if f of t is zero, what follows is that m times v of t is constant. What's also interesting is that in this particular notation, I do not really require m to be a constant. So we obviously derived it in case m is a constant. But again, if my time limit from t to t plus delta t is very small, even if mass is changing, smoothly changing, you will still have exactly the same type of a formula. So m also can be a function of t. There is nothing wrong with that. So in any case, this particular quantity is called momentum of motion. And we see that the momentum of motion is not changing if there are no external forces. That's very, very important. Now, what I will do next is I will exemplify this with a very important example, which will show actually how important this particular quantity is. Here is the problem. Here is this example.  But this example will show you how deeply this momentum of motion is actually embedded in our world. Let's consider a two-stage rocket. So this is the rocket and it has two stages. Now, it's flying freely. So all the engines have already finished. Everything is okay, no problem. The first stage probably burned. It's filled whatever it is. It ended the job and the rocket is actually flying freely in the space. And let's assume there are no close by planets. So it's just free space, no gravitational fields, etc. So it's basically flying along a straight trajectory according to whatever system of references it is in. And then we have to really get rid of this first stage, which has already, you know, burned. It did its function. Now we have to get rid of it. Let's consider a very ideal kind of a scenario when what happens is there are some mechanisms inside this rocket which basically force this first stage to go back along the same line for simplicity. So let's just assume there is certain internal force F. Just for simplicity, you might consider, okay, this is a spring which is actually tied together and then at a certain moment we release the spring. So it springs and pushes this one down and obviously this one up with the same speed because there is a third law of Newton, right? So there is a certain force which acts during the time t and this force actually allows our first stage to go back and the first stage and second stage continues to go along the same trajectory. Now during this particular time period this force obviously accelerates and then it finishes. That's it. Like spring has already done its job, it's finished and then the first stage goes by its own inertia and the second stage continues going by its own inertia. All right, so let's just consider the following thing. Let's say the first and the second has certain masses and the whole rocket has a speed b in the very beginning. Now what happens when I act with this force during this time with the first stage? Well, it has initial speed v as the whole thing and then I am acting on this particular first stage with this force with this time which means the acceleration is this, right? Acceleration is equal to, in this case, mass is m1. This is acceleration. This is force. So acceleration is this. Now during the time t, if I have acceleration, my speed would increase or decrease depending on the sign of the acceleration by a times t, right? Now in this case since the rocket moves this direction and we are pushing the first stage backwards, so it's minus. So it's minus f divided by m1t and this is my speed at the end of this process. This is the speed of this first stage after we have finished pushing it out. Now if we have pushed really hard, it may go completely in the opposite direction along the same trajectory. If we pushed it slightly, it will just separate from the second stage and it will just move slower. That's it and it will be farther and farther but it will still continue moving this direction but slower than the second stage. Now as far as the second stage is concerned, initially it has also speed v. Now the acceleration it will have is the same force because the same force which goes towards the first stage, it will push the second stage forward along its trajectory but the acceleration would be the same force divided by different mass and the same time t. That's what we know, right? Now what happens next is very simple. I would like to actually convert it into momentum of both stages, both parts of the rocket. So the final momentum is, I will multiply this by m1, so the final momentum is this, final momentum of the second stages. Now this is the first, this is the second, second is equal to m2v plus ft. Right? mv minus mv plus. Okay now let's add it together. What do I have? I will have m1v1 plus m2v2 equals 2. Well this will cancel out obviously and this has the same v so it would be m1 plus m2v. Now m1 plus m2 is the mass of the entire rocket. Now this is a very important equation. What is mv? mv is momentum of motion of an entire rocket before we separated the stages. What is this? This is a sum of momentum of two parts of the rockets into which we are, which we have separated this rocket. So the sum of momentum after the action and this is the total momentum before action. So if the whole rocket with two stages is a system, let's call it a system, right? Then this is the total momentum of the system after this separation happened and this is the total momentum before this separation. So our total momentum is constant. You know? Same thing. We go back to whatever I was talking before about constant momentum if there are no forces. And now there is a force here but it's internal force. It's internal for the system. So if we have a system of objects and there are no external forces upon them like gravitational field or something like that, which definitely distorts the whole picture. So if there are no external forces, if all forces are internal, then obviously different parts of our system will start moving differently but the total momentum will be preserved. So it's conservation of the momentum and we will talk about this later on. I just wanted you to understand how important this momentum actually is. Momentum of motion in case the system is enclosed without any kind of external influence is preserved. That's why it's very, very important. All right. Now, I do suggest you to read the notes for this lecture again. It's on Unisor.com. You go to the website and there is a Physics 14 course on the left in the menu. And then you choose Mechanics. You choose Dynamics. And in the Dynamics you have momentum as a particular topic. And that's where it is. This is the first lecture of this. The whole topic is actually called I think momentum and impulse. All right. Okay. So that's it for today. Thank you very much and good luck.


I got injured. The track we were riding on hit a 500-pound bomb that was rigged as a landline and got burned over 41% of my body. Lost my right hand at the wrist and I left my arm at the shoulder and a lot of this figuring scars from the burns. I didn't see a future worth living at that point. Hi, I'm Bobby Berreira. I'm a Vietnam veteran. The changing point in my life was in 1974 where I met Madisela, my wife, and she is a lady who molded me into who I am, into who I became after Vietnam. My biggest passion in life has to be service. I was on the receiving end when I came back, when I had to make the adjustment to living life as a double entity. Someone was there to serve me, someone was there to say, hey, you can do it. So it's a cycle. Now it's my turn to give back to them. I think the advice that I would give, the returning veterans, they need to navigate the system with the support of an organization like DAV. DAV does all kinds of wonderful things to help them finding out the disability, the compensation, educational benefits, the housing allowances. I never knew that I could get my automobile modified, those are the kinds of things that DAV does for the veteran. I really don't think that I could function without Madisela in my life. She's always there. The more important to me is the emotional support, the caring that she extends to me has made the difference. I'm a veteran and my victory is my marriage.


So, hello everyone, my name is Lubomir, I work for Red Hat, mostly on maintaining tools for creating composers and I want to tell you something about how it's done and what problems there are that we face with them and how we are trying to address those problems and where to move from them. So first, let's actually take a step back and give a very brief overview of what the composer actually is. In this case, composing means taking some content for Fedora that's RPM packages from the Koji build system and create something usable from them. Because if you get 100,000 RPMs, it's not fun, you can't really do anything. So we need to create ISOs so that you can actually do stuff, create container images or simply an RPM repo with some structure. And that you can then consume with YAM or DNF. In Fedora, the tool that is used to create these composers is called Panji and I happen to be one of the people trying to maintain it. And to give you some extra perspective, composers in Fedora are really almost everywhere. It's not just the Rohite Compose, which is kind of hard to notice because it regularly spams the devil list with reports. There are also other composers, so behind each update push, there is Panji running and processing packages and creating the repose with updates. So what are the actual problems that we are facing with that? And this is specifically for Rohite and new branch releases. Well, they are slow and that's not particularly great. Like historically, the timings have been different. Like right now, Rohite takes just under five hours to finish. It used to be something like eight or nine hours, only a few weeks back. But there have been situations where the Compose took 15, 16 hours. And that's not really good. There are multiple issues caused by that, but the main problem is that if the Compose takes too long, you can't really iterate on development. So once a new Fedora is coming to be finished, if you need to wait eight hours just to be able to test or fix, that's just not great because that basically gives you one fix a day. Like you come to work in the morning and you see, okay, the Compose failed yesterday. You debug the issue, you write a patch, you build a new updated package and then you wait until the next day because that's how long it takes to get an updated package. So let's be honest here. One of the big issues is just slow things are not fun in computing.  So just so that we have some idea on what's taking so long, let's take an overview of what the Compose actually consists of. It is one big monolithic process, but it's split into different chunks and smaller pieces. So this is an overview of everything that goes into raw height and how Pange is split to create that. It goes from left to right and when there are multiple things on top of each other, that's where there's some parallelism. So it starts with a phase code in it that basically just takes some data and prepares the general structure. So this involves cloning the repository with Compose files. The module defaults files are processed here. And this is generally very fast under a minute. And then comes the first bottleneck and that's the phase code packet set. This is where we talk to Koji and ask, okay, give me a list of all the latest packages and then we go and check headers on every single one of those RPMs because we need to know what is that RPM actually, like where can we put it? The output of this phase is a RPM repository with the packages, one for every single architecture that we are composing for, and also lists of packages like what's actually in the repo. When we want to find some package, we don't want to open the metadata in the repo and search it there. And for raw height, this takes something like 30 minutes, at least in the Compose that I checked this for, which was, I think, Monday Compose. Then multiple things start working at the same time. Like on one hand, the first line, build install phase, that creates the installer image. The way it works is that Panji kicks off a task in Koji and says, okay, let's run Lorax to generate all the necessary files. And then it sits back and waits for the task to finish. Nothing very much in Panji to optimize in that. The OS3 path is very similar. It's just that it kicks off Lorax with different arguments to create and OS3 installer that bundles the OS3 commit in there. The middle line here, gathering and creating repos, that's where some work actually happens. And this is where Panji figures out what goes where. So there's everything, which sounds like it should be everything, but that's actually kind of a lie. Because depending on how you look at it, it's everything plus something extra, or it's just shy of everything. There's all x8664 packages, for example, but there's also something multilip. And not all 32-bit packages are there. So it's not just a matter of taking everything and shipping it somewhere. There's some extra logic. And everything is not everything that's in the compose. There are other parts. There's workstation, there's server, at least for now. And those are subsets of the packages. So in this case, we know a list of packages that we want there to be. Like if it's workstation, then we probably want some stuff. But we need to check the dependencies and make sure that it can actually be installed. Like we don't want to create a repo that contains bash, but not glipc, because then what do you do with that? And this is actually kind of slow. Like in the compose that I checked, the gather phase took all together about one hour and 10 minutes to go through all of the combinations of variant and architecture and figure out what packages should be there. And once we have the list of what to put in there, we also need to make sure that the packages are actually in the compose structure, because it's a bunch of files on the file system. We need to get them there. So we create hard links to the Koji volume, and every single package is hard linked into the Koji volume and to the compose. Interestingly enough, this takes also about 10 minutes. So there's like 10 minute phase where Bungie sits and does nothing but hammer the NFS with requests. It works, maybe not great, but it works. Once we know what we actually want to put in there, we can run create repo on every single combination of variant and architecture and create the repo with the packages that we just hard linked. This interestingly enough also takes about 10 minutes for all of them together. So again, not much to optimize you, although there are some possibilities. And once we have all of this, we can start building the extra artifacts that go into the compose. That's live media, container images, and what have you. The reason why we need to wait with this is that in order to create a bootable live media, we need the installer to finish. If Lorax fails to create a boot ISO, there's no way we can make bootable live media for any spin, any variant, anything. So that's why it has to wait. Again, in all of these phases, they're very similar. Bungie just kicks off tasks in Koji and waits. And this can take from a couple minutes to an hour. Turns out if you optimize the builders correctly, it can be much shorter. Like when I spoke at the beginning about the robot composites going for eight hours to under five, that optimization was done by changing the S390 builders and PowerPC builders and making sure they are faster. And that saved a huge amount of time. That actually makes me feel kind of bad because like no matter what I do in Bungie, like I will never see such speed ups. So that brings us to the end of the compose process. In the image checksum phase, we look at all the generated files and create checksums. Those are kind of useful for people who want to download it and check that they have the correct stuff. And it's actually separated in a separate place because we don't want to duplicate the logic for every single task that is doing something. Just computing the checksums on all of the images takes about 10 minutes, which kind of gives you an idea of how much stuff Fedora is producing. And the last part is the test phase and that's kind of simple. We just run repo closure on the generated repose and some quick sanity checks on the images that we created. Like for example, if we create bootable image, like we actually do and check the file that it can be booted, like it has all the headers because there have historically been bugs where we created stuff that we claimed, okay, this is a bootable image and it turned out you can't actually boot from that because we forgot to run some commands. So that's not going to happen again. So what am I working on right now to fix? And that is in this phase, I'm focusing from the start. So I'm now working on the package set phase. As I said at the beginning, what it does is take all the packages from Koji, mesh that all into one big pile and use that as input for the following phases. This builds on an assumption that historically has been true, that there is one Koji tag with all the packages and we can do this and it works nicely. But unfortunately in the modern, in the brave new world, this is not true because every single module that goes into a compose has a different tag in Koji with the actual packages. So essentially what is happening in the current implementation is that we look at all those different Koji tags, pull the packages into one big pile and then have to do some extra bookkeeping to make sure that the modular packages don't go where they are not supposed to go. This is suboptimal, let's say. So the current work that is in progress is to split this and make Panji aware of multiple tags. Oh, sorry. And have different package set for different tag. In that case, we don't need to do the bookkeeping. We just say, okay, don't want modules. Don't use these generated repos. This by itself is probably not going to speed it up too much but it will lay the groundwork so that we can actually do something more fun. Like one option is to reuse more stuff from previous composes. Like if we have one big pile with everything, in order to reuse something from the previous composes, we have to make sure that we only use the stuff that didn't change and it's difficult. If we have stuff nicely compartmental in nice smaller chunks, then, for example, for modules, we don't really need to rerun that because once the module finishes, if we are using the same module built in the compose, we know what the packages were. We don't need to check them again because given how Code.js is working now, once the module finishes, it doesn't change. So we could just reuse the stuff and not look at all the details in the RPMs. Another thing that we could possibly do with this change is to write a separate service that would listen on the message bus. When it would see a package was built, it would just update the repo and the list of packages so that this would be continuously updated and almost up to date. And at that state, basically the whole phase in Pange is just asking this thing, tell me where the repo is and what's the list of packages and I will use that and the compose will not have to wait for anything. Also, if this actually existed, we could split some other tasks from the compose into separate runnable things. For example, a lot of testing before release waits for installer to be created. But in order to create the installer, you need to have repo with the packages. So if that repo was always there, always up to date, you would just kick off the task to generate the installer and you would wait the 20 minutes it takes to create it. And that would be a fairly nice improvement in terms of waiting for testing of Pedge. But there are also other things that we could look into optimizing. And some of them I have actually started but I don't have specific benchmarks so I will not tell you too many details. Like for example, one thing we could do is try and make faster create repo. Like you may think that create repo C is already faster than the old Python create repo, but we could make more assumptions. Like for example, we know that builds in Koji have NVRs. And if those two NVRs are the same, we know the RPM is going to be the same if we get it with the same signature. So we could use this logic and not look into every single RPM. Like if we know what the RPMs were in the old compose, if the NVR didn't change on them, we can just reuse the data. So there might be some possibility for optimization here. It would not be a general tool because in the wild internet, you can find RPMs that don't hold where this assumption doesn't hold. It probably doesn't always hold even in Fedora. Like there might be cases where this is broken, but it's something to look into. And other things that I plan to do is to look at the code paths that were historically not really used that much. Because for example, I found that this out actually when I was preparing this talk, I looked at the timing of the compose and it turned out that figuring out what goes into the modular variant takes longer than figuring out what goes into everything, which is much, much bigger. And this is just because the code that is used to create modular variant is a different code path. It's working slightly differently to everything. And this was not optimized because it wasn't historically used that much. And this is a place where someone with just knowledge of Python could go and check all the loops and make sure that they are correct. The stuff is done in correct order. This could bring us some speed up as well. So that's basically the current status and where I plan to move from that. So expect some results in the next 10 to 15 years. And if you have any questions, I would be happy to try and answer that. Yes, that's a very good point. As Mohan pointed out, if we know that nothing changed in a particular image, we could completely skip creating it and just use the previous image. And again, this is something that could be helped if we correctly track all the steps in before that particular image in the compose. Right now, we can't really say what changed because all we have is like, we can say like, okay, the configuration for the compose didn't change. But generally in Rohite, some package is changed in the day-to-day business. We have no way of tracking what image is in what package is in what image. So we can't really make this optimization right now. But it's something that is possible and nice and would be useful. Yeah, that's a good point. It's only a couple minutes. Generally, yes, it would probably be an improvement because right now the test phase is done in serialized. So we check one image after each other and we run create repo for one repo for another, another, another. The actual creation of the repos is using a thread pool. So we are using like four create repo C processes at the same time working on the images. So yeah, this would also probably be a possibility to change that and test this as soon as it finishes. The other possibility is to just not care and turn these tests off. Yes? It's all done. Yes. So Panjie is consuming a bunch of packages from Kojie and it's doing that by directly accessing the Kojie volume. So the same volume is mounted in Kojie and Panjie. That's a good question, but I don't have an answer for you. Sorry. It's NFS 3.4 and these kinds of weird problems. So yeah, that's kind of just one thing. NFS 3.3 is a little more challenging. Yeah, yeah. To summarize for the recording, the NFS is not particularly great here. We tried doing something newer and cooler, but it didn't work. Yes? So I had a few quick things. At the end of the images phase, the live images image build back phase. I think, I have to check this again, but I think it waits for all this tests to complete and then, you know, figures out what failed and what didn't fail. But if one of those fails and it's a required image, then it fails to compose, but it waits for all of the rest of them to fail. So one possible optimization here is it could look and if an image fails and it's a required image, it could just say cancel all the other builds, fail now and fail worship. Yeah, so this is basically an implementation detail of how this works. Essentially, Punches spawns a threat for each of the phases and they go and do their own work, but the main threat that is monitoring is like waiting on every single one of those in some order. So if one finishes sooner, it waits until it's turned to wait for it. So this might be possible to fix in some way. For example, I would really like to replace the threats in this case with Python 3.0 async because it's not really doing anything, it's just waiting. Right, but I've seen cases where, you know, it doesn't fail really quickly. Yes, that's very much possible. Like the first task you spawn will fail immediately, but you still have to wait for everything else to finish. This is probably fixable in the code. We probably could do this. So the request is, can we make this more visible? So for starters, like whenever the phase starts or ends, we send a message. So if you're actually interested from that, you can listen to them and do stuff with them, but it's also possible to generate some summary. It goes with a caveat that as I said with the images, like for example, the timing on the phase is not really representative of how long the individual task took. Because for some, if there's like one really long phase, but it happens to be the first one to be waited on, then every other one will be artificially inflated. But having more visibility into what takes how long is something that would be nice. But it's not just a simple diff between timestamps in the log because of things like waiting for some other stuff. Yes? Okay, so the question is what is, what time we want to reach and what good will it bring? So we don't have a set time, like as fast as possible, sounds good. But the main issue we have with the long composite right now is, it takes too long from writing a building a fixed package to seeing some artifact that you can test it with. I didn't fix it, so you need to do another fix to that and it's blocking all the QAA. Yes? Just, I guess I'll point you there's a continual push I think in all parts of trying to get resources that are beyond just our infrastructure to do things how to do a very small subset of speculative composes outside our infrastructure that people can access to find out if those changes work before we engage in a whole composite. Not necessarily making the composes block on that, like being able to spin many of those over the course of the day in addition to our normal composes. Of course that brings up problems of how do you have the storage synchronized so that you're doing something in a public cloud? How is it getting access to the same packages? How do we keep those in sync so that we're not trying to deal, we're not having to do a harder job of tracking where changes went in or didn't go in? But those are problems that we're going to have to solve because we, over time, the pressure is gonna be aligned. I think that there are a, to kind of reduce the amount of part of where the loop. Another way to look at this problem is it would be great if we enabled Fedora contributors to run composes on their own. Right now, if you don't have access to infrastructure, you're out of luck, basically. I think our test that catches the vibe before it gets into the component is in the savings cycle. Right, exactly. Yeah, that for me is like, that's why those two, it's not interesting to me to talk about like doing that and not improving funging. I think like the bone of the rest of the ship. There is one doubt on my list of where to create the minimum composes. But it's still in the kernel interface, but very minimal to that all the time for the different main packages. When it takes a build, it will run the human component probably to make a decision on how to do it. You said for users to be able to run the composes. For any cases, I would like to ask the rest of us to eventually be possible. When we updated Python to 3.7 a couple of releases ago, we do it in a large site tag. And we have everything somehow works. And then we say, yeah, it looks good. And we come to the draw height. And then the composes start to fail for some unrelated reason. And I ask, could that have been somehow prevented that I have tested it? And the answer was not yet. But so is there any plan to support running composes against site tags? So, Pange itself supports that. The problem is that you probably won't have access to the volume with packages. So, if we solve that somehow, you would be able to just take the config from production and say like, okay, instead of F-30 Compose tag, I want to also use my F-30 Python tag. And it will figure, Pange will figure out like, what are the latest packages? So that would work. The only problem is the infrastructure side. We need to make sure that the packages can be consumed somehow differently than direct NFS access. If you convince people from the infrastructure to give you permissions, then you can. This is what you want to do, huh? Well, I mean, yes, that will work, but will that be performant enough to use that? This is why it probably comes, it really comes down to how are we gonna get to a model where our package data is not restricted to the NFS, or whether it goes somewhere that our contributors can like, you know, spin up a cloud machine and access it and do what they can do, and we can control access in a way that, you know, makes that data secure, but gives them all the power to do other things, you know. So that's a key problem to solve, I think. That's not necessarily for you. Sure. Okay, so I think we are out of time, so thank you very much for coming and enjoy lunch.