 Hey, so my name is Rakesh and this is, you know, like 10 times the audience I expected for this talk, but that's a good thing. I work on this little app, you know, so I put my job like a couple of months ago and I've been trying to build something for the JavaScript community and obviously trying to make it work on the side when I'm doing that. So one of the apps that I built while doing this was this app for... Alright, so I put my job a couple of months ago to start working on printing tools for JavaScript and stuff around that. One of the tools that I've been working on over the last couple of months is this tool called Errorception. It's a tool that lets people record errors in their pages as they happen in end-user browsers, right? It's generally later than it's lost because it gets printed in the user's console, which is a student-based printer because you never get access to it. This one has been using it so I don't know if he has any feedback about it. But that said, it's an interesting tool. So I don't want to make this a product pitch. The idea is that occasionally there are services that help speakers to use, so I interfere with them. So the main works is that I give you a little snippet of code to insert into your pages and then this starts recording errors. Let's talk in the details about how that works. The interesting bit over here is that I give you a snippet of code to insert. This is very similar to how, say, Google Analytics works or how, you know, even Discuss or other forms of plugins, that's the reality of what works now. This talk is meant to give you an idea of the knowledge that I got when building a snippet like this because it turns out that it's a wild world out there where you can never trust what kind of page in your time environment you're running it. So this talk is about the lessons that I learned in the process of building. So it's basically about the lessons learned when I was creating Air Reception itself. I spoke already briefly about Air Reception. So these are examples that I studied in the process of trying to create this snippet that I was talking about. Let's Google Analytics, Dismetics, Discuss, Facebook, Twitter, you know, there's a whole thousand of examples of Javascript. So I get a series of blog posts about this that recently happened to get a lot of Javascript press, so to say, if people are subscribing to magazines like Javascript Weekly and stuff, this was published over there, Smashing magazine, you know, a bunch of places that we got. So it was broken down into three posts, so I'm sort of stuck to that format over here. So this is the first post where I call it the first rule of writing third party Javascript. So three parts, we go over the first one really quickly because I guess most of us will be familiar with the first post, so to say. The second and the third we'll live in when someone will be there. So how many are here familiar with the movie Fight Club, right? The first rule of Fight Club is? Don't talk about Fight Club. So the first rule of third party Javascript though is that you do not own the page, or this doesn't sound as interesting as that I've done in the beginning, but you do not own the page, right? That's the first rule of third party Javascript. This has got a lot of implications. So the first one is that when you insert your code, when you ask somebody to insert your code into the page, the impact of that should be minimal. There should be very little impact of that, and we'll discuss what that means. And secondly, that you cannot make any assumptions about the page. You cannot make any assumptions about the environment that your code is running into. And we'll discuss what that means as well. So one way of ensuring that you have minimal impact, there are at least two or three of them, but one of them is that you should not have any globals at all, right? So there is this idea of immediately invoked anonymous functions. I'm sure most of you know about this. There you have a function block that you invoke immediately. This essentially creates a scope trap, so to say, for your variables. And since your variables are inside this scope trap, you are not leaking into the global scope, right? So a simple example of how not to create globals. A slight improvement over this is where you take in window and document as parameters, you take them back into the function. The benefit of doing this is that when you run this through a minifier in the future, right, your variables become something really small like A and B, right? So even though you're thinking that you're accessing global variables, you're actually accessing local variables now. So basically your code can shrink slightly when you run through a minifier. So window or whatever will become A or whatever and so on, right? So slight improvement on your code. You know this already, this can be applied to general JavaScript as well, so it's a benefit that you get anyway. Now I say no globals, of course. It's useless if you have code that does not expose a variable at all. You know, what is your namespace variable, right? How do you work with this code? So you have to have one global, let's be fair, right? So if you look at what other guys are doing, Google Analytics has got underscore GAQ as their variable, I'm sure. If you've worked on the front end, everybody's worked with Google Analytics. You know what I'm talking about. GAQ is that Facebook uses FB, Twitter has got TWPGR. Error step shifting, you see what I did here? Error step shifting has got underscore ERRS, right, which is their global variable. Another sort of fallout of not having any global impact whatsoever is that it should not mess with shared objects. Shared objects like strings, numbers, arrays, objects, don't mess with these, don't add to string.project, right? Left pad or whatever. Don't do that kind of stuff, right? That's not a good idea. So never mess with shared objects. Do not do DOM modifications. People don't like it if there are DOM changes. There are two exceptions, of course. The first is when you are expected to do a DOM modification, of course. Like, for example, when you're adding a Facebook widget, right, you're expected to do a DOM modification. In that case, it's fine. But I would say that the way you do that is by taking in the DOM node that you want to operate on. So you're setting an expectation that the developer is passing you a DOM node within which you're supposed to play. So, you know, the developer knows that I'm not going to own that anymore. That's yours, you know, you play with that. So that's one case where it's okay to play with the DOM. And the second case where it's okay to play with the DOM is this hacky, is when you want to do cross-domain communication back to your own server. Now, ideally, you should not use the DOM for this. You should use the core spec, the cross-origin resource sharing spec. But, you know, reality is that it's not supported in most, in older browsers at least. So the way you deal with it is by, you know, doing stupid hacks, like creating an image which has got a query string that is talking to your server or, you know, passing data over to your server. Or, you know, using JSONP or something that is, you know, creating a script back locally. Or even dirtier is using iframes or things like that so that you can, you know, plump data into your page like me. So there are the only cases where you can... There's no way out other than using the DOM to communicate across domains in this case. So that's the only case where, you know, you can still use the DOM. Well, meanwhile, let's keep this interactive if you have any questions and all that, feel free to fire me. So that was about not messing with the page at all. This one's about not making assumptions at all about the page. For example, you know, does document.head exist? So a lot of times what people do is that they append stuff to the document, to the page when they want to write. So if you want to add a script back to the page, you append it to document.head. Can you trust that document.head always exists? Turns out you can't. You know, you think that when you have... So there's an assumption that when you have... that when the page is parsed and it's ready and the DOM is created, that there will be a head and a body to it, irrespective of whether the markup had a head and body in it or not. Right? Turns out that assumption cannot be made. There are older browsers... I think there's opera, an older version of opera did not support document.head if your DOM did not have document... if your HTML did not have document.head in it, right? So you cannot even trust simple things like this. And the example is if you use the base tag, what is your path relative to? That becomes a complicated question to answer. So you know, these are kind of things that people generally take for granted when we are writing code in our own pages. But you cannot make these assumptions when you're writing code for the while. Quickly moving on. So that's basically the basics of what needs to be taken care of. Don't mess with the page. Don't give surprises to anyone. And don't make any assumptions about what's going on. We move on very quickly. The third part is even more interesting. It's about how to load your code. There are considerations that you need to keep... take care of is eliminate any network performance effect, which is to say that just by virtue of adding your code, the page should not slow down, right? That's something you should take care of. And the second is that what happens in case your servers go down? So, you know, let's say that... the decision is using error-ception and error-ception servers go down. Now, does that mean that his site is going to be impacted by this? You know, it's not something... I don't want to take on the responsibility of having damaged his site just because my servers went down. So I have to take care of that in my code. I don't want to sign a license agreement with him that will sort of keep me safe from this. I want to take care of this and impose that in code, right? So how do I take care of that? So number one is do not use a script tag. We all know this team server that has been standing on rooftops and shouting. Do not use a script tag. It blocks your page rendering. It blocks your network request that go out. We know about this. There's no need helping on... But Twitter does this. I don't know why Twitter does this. This is the stupidest thing. But Twitter does this for there, at anywhere, SDK, right? So what I'm talking about though is not about just eliminating... I'm not talking about reducing the performance. Everyone knows how to reduce performance, right? You use a cache. You do proper caching. You use a CDN. We know about all of that. That's not a problem. I'm talking about eliminating the performance. The effect of adding your code should be literally zero. It should not be reduced to as close to zero as possible. It should be literally zero. So we'll talk about how we do that. Anyone familiar with the async attribute in HTML5? Yeah? Right. So you would think that the async attribute... And the async attribute is cool. For those who don't know, what it means is that when you create a script tag and you add async to it, it means that your browser is now instructed that the browser should not block on loading that code. And instead, the browser will continue passing the rest of the HTML as well. And this is good for two reasons because, number one, you have not blocked the page, the network requests. And two, because you have not blocked page rendering. So you'll get two benefits with using async. That's two birds with one stone. That's awesome. The problem is that async is not supported in older browsers, including browsers up to IE9. IE10, the pitas that are out are showing support for async. But up to IE9, there is no support for async at all. And then there are older browsers as well. Of course, async is rather new. So there are older browsers as well that don't support async, including Firefox 2. I think Firefox 3 doesn't support async as well. So, you know, something to watch out for. As a third-party developer, I cannot cast async to work. I will have to find another mechanism because I cannot make assumptions about where end users are going to come from, which browser they're going to come from. I need a better mechanism than async. So one of the mechanisms, Street Souders, found this and I think it was Nicholas Zuckers who basically created the script snippet here. He calls it the dynamic script tag creation technique, where what you do is that you create a script tag. Is this visible behind? Is it okay? So you create a script tag dynamically and then you append that to the body and turns out this has the same effect as creating an async attribute. So at this point, your browser is now not going to block on either network loading or on rendering and your code is loaded, you know, parallelly. So this has the same effect as doing async loading. So you can now load your code using this mechanism rather than asking people to add a script tag that is going to load your file from some external server. It's better that you give them a script tag that looks like this and your external server's path is over here and you're basically creating the script tag using JavaScript itself. There is very similar to... Facebook, in fact, does exactly this. So Facebook's SDK, when you're loading it up, that's exactly what they do. They create a JavaScript file and then they append that to the head. So that's exactly what Facebook does. Except we just discussed that you cannot trust that the head exists. I don't know why Facebook still does this. It's common knowledge now. Google Analytics has done a minor improvement where document not body or document not head does not trust it. And so they append. This is an interesting approach. So if you don't have head or if you don't have body, where do you append to? It turns out that one thing you can't trust is that this script tag exists on the page. You can trust that because that's how your code is running. So you can trust that your script tag is there on the page. So you get a handle to a script tag, some script tag. It doesn't matter which script tag that exists. But you know that for sure there's at least one script tag on the page. So you get a handle to some script tag which is what they are doing here. So they're getting all the script tags, taking the first script tag, whichever that might be. It doesn't matter. And then to the parent node of that, they are appending this. Forget about the detail about excerpt before. It doesn't matter. Yeah, go on. So the question is that even if the DOM is reformed, doesn't the browser handle that? Yes, they do in modern browsers. Turns out there are older browsers where, so for example, if you don't have a head tag in your HTML, the corresponding DOM that is created might not have the head element inside the DOM. This is the case in Opera and some other older browsers. So you have to account for that. So it's just better that you can trust yourself. So the script tag that you have created definitely exists. So you try to work around that to make sure that you can add your code. Why would this be asynchronous? I still could not get that. It's a browser work. The way the browsers work is that if you are creating JavaScript with JavaScript, if you are adding JavaScript with JavaScript, the browser treats it as a risky. It's just the way the browsers are working. You know, it's a hack that was discovered last year. It just works. Is it respective of the async attribute in the GAR or for that script tag being set to 2? Yes, it is irrespective. So this is actually unnecessary in all. So on my blog post, I had said that I don't know why people do this. Turns out Steve Souders came to my blog to correct me and explain why this works. And the reason it works is because in older browsers, I think Firefox 3 and older, the async equal to 2 is actually needed to ensure that it is async. So you know, all newer browsers since then and all the IEs and all the other browsers, I think it's specific to Firefox 3 that you need to have async equal to 2 to ensure that it is properly async. So my next question was and displays into the idea about if my servers go down, does that affect the site? For whatever reason, my code takes 10 seconds to load. Is the onload of the end-users page going to be blocked? Because if it is, then that's horrible. Just because my script is taking long, I don't want that guy's code to be affected. So I had to run quick tests to find out whether it's actually the way it works. Turns out we can't be sure like everything in client-side development, we never know. So in some older browsers, it is blocked. Newer versions of browsers, the async is actually async and has nothing to do with the onload. In fact, it even varies with browser versions. So if you look at older versions of Chrome, at 12 or 13, I think, they used to block onload even if you gave async. Whereas newer versions of Chrome do not block onload when you gave async. So there's a difference in behavior across browsers and browser versions as well. So this is something that I did not want to trust. So basically if my code goes slower, depending on which browser the end-user is using, the site might have a bad experience. I didn't want it to depend on that. So I found a solution here, slightly more convoluted code. But what I'm doing is, this is a loader function right here that I created. That does what we have been discussing so far, where it creates the script tag and affects that to the page. Except I'm calling this loader function only after page load is actually completed. So what is happening now is that I'm explicitly waiting for the page load to complete and only then am I adding my script tag. The benefit is, so this gives me two benefits, right? I did not even consider this when I was waiting it, but it turned out that these are solid benefits. Number one, if my server is down, it does not affect the site at all because his regular page load cycle is already complete on the page before my code is even involved in the process. Number two, and this was quite a pleasant surprise, is that the entire bandwidth that the end-user has is available to finish loading up his resources first. And only after his resources are complete does my code start jumping into the picture. Now, this might look like a small, minor thing, and it is actually on computers that I've got FAT pipes connecting them. But on computers that I've got, you know, like you're making mobile phones, right? Where you have got bandwidth-related problems. If I can load my code as late as possible, that gives immense benefit as opposed to loading my code parallely along with the other code, right? Where I'm consuming bandwidth simultaneously with others. So that's one benefit. Admittedly, this is not for everyone because obviously, for example, if you have Facebook, or if you're using Facebook on your page, you want the SDK to be loaded as quickly as possible so that you can start playing with it. In my case, that is not the case because you're not going to play with the error-ception object. Ideally, error-ception should not even be in the picture because ideally, your sites don't have errors in them, right? So error-ception is sort of basically stepping out of the process completely and letting you do what you want, letting you do what your site is supposed to do so that you know how to interact with your object. I can add this code to Google Analytics too so that my code loads first when I use Google Analytics, I can use it. Sure, sure, sure. So if you're courageous enough to play with the Google Analytics loader code itself, you can try this for sure. In fact, I'll put up these presentations, these slides for you so if you want to give it a shot. But the only real difference you will get is that Google Analytics loads parallely. Error-ception, in this case, loads later. So it's that minor difference that you get. So, yeah, I already spoke about this. The first benefit is that I'm stepping out of the page load process completely, letting the site load as usual. And secondly, that I'm allowing the full bandwidth of the user to load up the page and I'm not consuming any of that bandwidth while the page is loading. So essentially, I have prioritized the page resources over my own code which is good, which means that and this philosophically works fine with me because I don't want a philosophical standard I was taking when building Error-ception is that I'm not going to affect your page load in any way whatsoever. Me being a JavaScript programmer, I know that that is important to me when I'm building JavaScript tabs. And just because I've included some third-party, something that I'm not in control of, I don't want that to start playing with my page load process. I don't want that to start affecting my page performance. So this was a philosophical standard I took and it plays in very well with that. Also, in case my code does not load, for whatever reason, it has absolutely no effect whatsoever. So that's great because that second descriptor that is to be appended will not work and that's fine. There's no effect whatsoever. So that wraps up part two. Part three, this is very interesting, is planning for an API. This was a revelation for me because it made things very mind-blowing facts over time. So the biggest challenge here is how do you announce that you are ready? If you're planning for an API, you want to make an object available to people and people are going to play with that object. Now, how do you make that object available to people? How do you announce that an object is ready to play with? Now, if you take the case of Twitter, it's rather simple because they've got a script that you include the script. It's a blocking call, so as soon as the script is done, you have the better object to play with. Simple. Except we have discussed that this is a horrible, horrible idea because you're blocking. We are talking about asynchronous loading instead. So there are several mechanisms. One is that we can use script.onload. Script tags, since we are creating them dynamically, have got an onload event on them. So you can have a listener assigned to onload that will be fired when the script tag is loaded. But that has got edge cases now. What if your script tag is 404s? How will onload fire? Will that fire by saying that, yes, onload is done, but I have got an unpossible page? You know, you have to handle that now. Secondly, honestly, from experience, you do not want to have too much code inside that snippet that you are passing on to the person. For two reasons. One is that it's a lot of code. You don't want that there to be copy pasting a lot of code into a script. Secondly, you want to have a lot of control over that code yourself because if there are bugs, the more code you have, the more bugs there are. You want to keep that code size to a minimum. And if there are going to be bugs, you would rather have them at a place where you can control the deployments later. Now if I have asked somebody to copy paste the snippet onto that site, I have no control over that once it's been copy pasted. So if I have to do maintenance on that, it's going to be very difficult. So I'd rather keep that chunk as low as possible and try to keep as much code at my end as possible. So I didn't want to have script.org and all of that logic sitting over there. So what are the options that are available to make this even smoother? What Facebook does is interesting, and this was the first cue for me, is that they ask you to define this function called fb async in a horrible name, but forget about that. So the point is that you define this function and Facebook tells you that whenever we are ready, we'll call this function. And so inside this function now, you will have a global fb object that we guarantee will be ready for you to play with. And then they go ahead and they load their code asynchronously as they used to anyway. The benefit over here now is that... So the way this works is that when the code loads, it will have defined an fb object and all the paraphernalia that goes on with that. And then they will say that if you have got fb async in it defined in the page, that's what the code does, right? I've shown you that snippet, but I don't have that over here. But they will say if window.fb async in it and if the type of that is a function, then invoke the function. That's it, right? So they'll guarantee now that the fb will be ready. Another benefit of this is that in case the Facebook script does not load, fb async in it will never be called. And that's great. That means that your code will not be initialized. The user does not see anything. The user will instinctively hit refresh and it will just work. By experience, but at least things don't get... There are no errors that happen simply because of timing issues, right? Now, this is brilliant. It's awesome. I'll just outline the process for this in case you're interested. Step one is ask the developer of the page to define a global function, call it whatever you want. Facebook calls it fb async in it. Second is that you start loading your code, which is the rest of the snippet that I had shown over there. And then finally call the function that you had asked the developer to define before, right? From inside your code. This is one way of doing it. Now, there are write-only APIs. This is a special case and this is the interesting part. There are most of the... Most of third-party snippets that people use are actually invisible snippets that are writing to their services, right? These are trackers, these are loggers, these are apps like that. Erreception is one of them. So, there are write-only APIs. Write-only APIs have this interesting nature where generally you are not using the object yourself, or if you are, you're basically just asking it what to write. Like, for example, in Google Analytics, you're telling it track this event or, you know, do whatever, you know, things like that. You're basically writing to it. You're not expecting data back. Now, if you're not going to expect data back, turns out you don't even have to have a Google object to play with, right? And I'll show you how this works. And this is very, very interesting. So, look at this. This is like how there is the FB object. This is similar to that. The underscore GAQ object, which is the Google Analytics queue. I think that's what GAQ stands for. They have never spoken about this anywhere. That's what GAQ stands for. Google Analytics queue is basically an array. It's not even an object, right? It's just an array. Now, to this array, you are keeping on pushing what looks like commands, right? So, you're saying set account and you're passing it your account at it. You're saying track page view. You're saying, you know, track event and so on. You're basically just pushing commands into a queue, right? And at any point, you can continue doing this at any point of time in your code. You can continue adding stuff into this queue and it doesn't matter. At some point in the future, whenever the Google code is loaded, they will start processing this queue, right? As far as you as a developer is concerned, you continue to write to this queue whenever you have anything to write and Google will keep reading from that queue and keep sending instructions to their server, right? The benefit of this is that there is no question about now waiting for when it will be loaded. Is there a global function that has to be defined? I would call none of that business, right? You're just writing to a queue and then later that queue is flushed, right? So, this is very similar to what error section does as well. Error section is also defined in the queue because we are writing to API as well. You know, there's nothing to read from the service. Basically, every time there's an error, go write that error to the server, right? That's all that we're doing. So, what we're doing is that there's a queue and then we're keeping on pushing errors to that queue and we start loading our JavaScript. At some point in the future, the JavaScript will load and, you know, whenever it loads, that's fine and, you know, it will start processing that queue and that's how error section works, right? Now, there are tricks to this. What I do, for example, is after the code has loaded, I change this array into an object that has got only one method on it called dot push, right? And the reason why I do that is because now I don't have to pull the queue to know if there were any changes. The moment there is something pushed to the queue, I can instantly find out that there was a push that was done and then I can, you know, buffer that up and send it up, right? So, there are tricks that you can do. Google Analytics does this as well. If you look at the minified code, which requires a lot of, you know, it peels your eyes to look at that code because it's so minified, but if you ever have the, if you ever end up having the patience to do that, they do the same thing in the GAQ case as well, is they convert the array into an object with one method or dot push on it, right? So, obviously, this whole thing was driving up to a pitch so I'll, you know, I'll make the pitch really quick on one slide. Is that error section is high performance by design because of the reasons we discussed. And it is highly reliable by design because even if ours... So, reliable is a funky word because what I mean is that in case our servers go down and does not affect you, that's what I mean by reliable, right? So, it's highly reliable by design. And that's error section for you. It catches errors for you. You have got over 5 billion errors so far in major internet brands already. And I urge you to give it a look. That's it. Give it a spin. ErrorSuction.com. My Twitter handle is at ErrorSuction. If you ever want to give it a shot. Thanks a lot. Thank you. I must say this audience is far larger than I expected. I don't expect anything this big. Go ahead. Yes. I'm sorry, I can barely hear you. Right. Race condition of WhatsApp? You will not have that race condition because JavaScript is a single thread. There's only one thread. So, at any point you are either writing to the queue... Sorry, I'll repeat the question for the sake of the camera. Is that will there be a race condition in between when the code has loaded and when there are items being pushed into the queue? No, there will not be because JavaScript is a single thread. So, there is either writing going on or there is processing going on. You cannot have both happening manually. So, there is no question of a race condition as far as that queue is concerned. Any other questions? Does that answer the question? No. Go ahead. Is this the one you were talking about? Yes. Or the loading? I had two slides on people. The age limit is... The loading. This one. All right. So, this is basically where there is... The developer is asked to create a global function called FBA Syncnet. FBA Syncnet. And this is just a global function that's available on the page. Later, when the code loads, inside of the Facebook's SDK code, which is FB.js or whatever, inside of that code, they are checking if there is this global function called FBA Syncnet defined. And if it is, they just invoke it. The point is that at this point, FB.js or whatever is their code has definitely created the FB object. We are sure that the FB object exists. So, when this function is called, FB is definitely ready for use. Before this function is called, it is not, because the code has not loaded yet. But once this function has been called, we are sure. So, this is basically... It's like an on ready for the FBA sync, for the Facebook code, right? So, that's how it works. What is the set object? Sorry, why should we not modify it? Set object, like string or typo. That's standard JavaScript practice, right? You're living in a runtime that is shared across a lot of people. What if I have defined a function, or what if you have defined a function that's called pad-left, but it has got a different signature from my pad-left function, right? You should never... I should not have to change code that is inside your environment. Because I don't know what you are expecting to do with it. You know what I mean? Nothing, not clear. Actually, but sometimes we need to reveal the method in prototypes, like... In general, suppose I am making some regular reference, that should be available to all strings. Right. Then I should... I must try to write that regular expression in string dot some expression from there. Right, right. So, there is a lot of debate about whether there should be modifying prototypes at all or not. I guess there are valid cases. So, let us say that you decide to change string dot prototype to have some validation method on it, right? For example, is email, right? You have the string dot is email. It's debatable whether that's a good idea or not, but let's say you decide to do that. Now, if you are doing that, and if I start to define an is email on the same string method, which one is correct? It might be different from your implementation. Do I even have the right to do that to your code, right? It's your runtime. Do I even have the right to add an is email to your string interpretation, right? I should not be doing that. So, that's why there's no modifications allowed to shared objects. Are they just smiling there? Any more questions? All right. Either everybody or nobody else. There is one good news for you is that it has changed the way they indicate the button now. You just switched to the ursync mode just a few days ago. You know, like... Is it? Yeah. So, now they normally use that one night and this must be true for the button. For the button, yeah. Even as of yesterday, I was looking at the at anywhere SDK, which is the entire API set. Right, right. And that is still forcing us to do it. But you might be right about the button, the tweet button you're talking about, right? Yeah, that may be as interesting. But was there really a reason for them to keep it that way? You know, because they claim that it has something to do with OAuth authentication and the experience associated with that. I don't buy it. It doesn't make sense. There's not just that. You know, they add this button, they also don't use ursync. They just give you a skip tag, you know. Yeah. I would like to imagine it just kills strange performance. It's not something that I would do at all. I don't like third parties doing that in my code. There's no way I would do that. Because I believe in something to do with the way they modified the DOM, yeah, because there's no reason I add this and do it off button. Both just keep us with tag here. Because back then, when I built, you know, I was building a similar button, right? So I inspected both these codes, yeah. Right. And I had the local option, but you know, I was in India and got a little scared and just took the straight approach and gave it to all my clients, yeah. So I also want to know why am I still doing this, you know. Is there? Yeah, no. There should not be any good reason to lock one's code. Like, I mean, if you're still doing that, I'll ask teams to understand it. You know, you change your mind. But there's no reason for you to still do that. You should move away from that. People will love you more if you do that. Is that it? So I guess, either everybody understood or nobody understood. But, you know, catch me if you have any questions. Thanks a lot. Thank you very much. It's a deal. I'll send you a Twitter. Yeah. Oh, that's... So at Eroception, my personal Twitter is rubbish314. My last name is Pius, I think 0.14. Okay. You know, so... Thanks.