 Who I am, I'm Alexandre. I've worked at Sao Paulo next. It's a good place to be. Awesome team. Now I'm up at 10 scores with a couple of guys here. And we're doing some nice quality score optimization platform. And if you need to add words, you should check. So what's the purpose of that talk? We wanted to reinvent Google Analytics. Well, actually we're not using what I'm going to show yet somehow. But we need insight on user behavior. So that's your case, whatever. So we'll cover very briefly. And actually, I'm probably not going to take 45 minutes because I don't have enough material. We'll see. So we'll see what's J-Event very quickly, J-Event Sakuraiyo, and how we do integration in Pyramid. We're going to use AngularJS. By the way, raise your hand if you're interested into the JavaScript stuff. Raise your hand if you're not. OK. Because this is a real time web, so there's JavaScript involved. Maybe a little bit too much. So if you're annoyed, scream. If you want to see more, you can also ask. I'm going to have a slight bottle integration. And so the slides are up there live. I mean it. That means go to that URL. You can find some interesting stuff happening now if you want. OK. So quick presentation, J-Event. It's a cooperative concurrency model implemented on top of Python. So you import J-Event, and it creates micro threads. So that's the basis for J-Event Sakuraiyo. It allows it to be very fast at handling multiple threads. So handling a large number of concurrent connections. There's no system context switching because it's all in one process and one system thread. And so these things, you can spawn many, many jobs with spawn. They return a little object that you can rejoin later on. You can kill them. And they're very lightweight. They call them greenlets. OK, so that's the basis for J-Event Sakuraiyo. It sits on top. You can't run J-Event Sakuraiyo without sitting on top of J-Event. And it monkey patches the socket and all sorts of different Python libraries. So that it actually taps into the J-Event loop when waiting on I-O, OK? So a little history there. So Jeffrey Gillan started J-Event Sakuraiyo. We took over at PyCon this year, John Anderson and myself. And we revamped it. So if you recall, I wrote and I presented also Py-Event Sakuraiyo, which was a little tack on to the original. Well, that's dead. And all the good stuff that was in Py-Event Sakuraiyo is now inside J-Event Sakuraiyo and across framework. So it works in Django, Bottle, Flask, name it. It's just standard WSGI stuff with some hacks in there. But anyway, OK. Yeah, I want me to respirate. So the talk here is going to be a demo, right? I'm not going to show slides that much. We're going to type things. And I'm going to build the app. So I'm going to build Google Analytics. So you might see that there's a couple of parts that are missing, right? I didn't have time to build a full thing. And actually, it's pretty much a fake. It was just to get you guys here. Anyway, OK. So I'm going to do that in a virtual lab. I have the environment installed already, so it doesn't take time. It requires libj-event, lib-event, j-event requires that. I'm going to install the Sakuraiyo library. And there's a patch sub-process so that it hooks into the j-event loop. OK, we're going to kickstart a Pyramid application for starter. Who's happy now? Yeah, right. OK, so shoot, man. So where do we start? Why did I write that? Pardon? Oh, it's called a squeeze. Peekrate starter. The application is going to be called Moo. OK, so that's my shortcut for activate. OK, sorry, I didn't write that little part there. So Moo, shoot, man. This is not going to be as fast as it used to be. Now it's set up. OK, and we're going to serve that app. OK, this gives us a simple app. Sorry, I'm going to take that one out here. OK, so that's the standard Pyramid app. And then we're going to tack on to this HTML5 boilerplate. So we're going to take out all the nasty original things in there. OK, we're going to take out those files. And we're going to copy from, I have HTML boilerplate here. So gs and mg things. So our into Moo static. OK, so it copies the normalization of the standard main.css and a couple of scripts. So we'll start with some fresh base. OK, is that good? Template, I'm going to use Emacs. Yeah. Yeah. Wow. And this one is going to be, yeah. OK, so we're going to use that fat Emacs. Can you read that? There's a quick thing. We replace all the JavaScript calls. And all the, I know this is boilerplate. OK, poof. So we should be all set. Now we should have, OK, yes. We're going to tweak a little bit of the development to add Mac code to your directories. OK, and then we're going to go in the views to change the file here. That's going to be index. Oh, and a little last hack. I promise I won't do that for too long. That's going to be, oops, add renderer. Sorry. What was funny? OK, so should this work? It died. Factories. OK, so we have HTML5 boilerplate. I'm going to put for the rest of the, OK, I'm going to put a couple of CSS there so that it's used later on. So I wish I had a simple body and then a wrapper there. NGClock, I'm going to show that a bit later on. And the rest is for the graphs, OK? You don't need to bother with those. They're just set there, OK? OK, so we're all set. Oh, I forgot a little thing. OK, so that's going to be our main content here. Addive, I need to wrap. OK, there we go. And now we're ready to go. OK, first thing we're going to do, we're going to integrate AngularJS. Who knows about AngularJS? OK, AngularJS is an awesome framework. Shoot. And we're going to copy the, I have a copy of the file here. We're going to put the Angular, we're going to put that in move static JS vendor, OK? And down here, just after plugins, so vendor, what is it, Angular? Min, is that it? Is it load? OK, so I'm going to show you a little bit of how it works. It's awesome because we're going to, otherwise you're going to ask question what's happening. Angular, just most of the job for the rendering here, OK? So Angular, yeah, it's loaded, OK? And then we're going to mark the app as being handled by Angular. That's where the magic starts. The app is move. We'll do some handlers for the old beasts, OK? And then on the body tag, we're going to mark this is a controller, OK? That will mean there's going to be a function that deals with the full body and does some rendering and templating stuff. So we'll go to static, your static main here. As you see, it's empty, right? So that's going to be our JavaScript side of thing. So you need to understand a little bit of it. You didn't scream once, so you understand everything. It's interesting. But I'm going to change regulator, OK? So move is going to be the, sorry, and no dependencies. And then controller, move, controller function, take scope, OK? So the scope is actually kind of a pipe. Yes, that's a very good idea. So he asked, what is scope? And scope is an object, which is just a simple object with the key values. It's attached to the NG controllers. It's got wired to the DOM. So the controller attached to some DOM elements, some data structure, right? So it's just a simple key value thing, which is awesome and great because it's not, it doesn't require all the entourloupette, like knockout.js uses like set so that it detects things that have been changed. This is a data binding frame, but I don't want to take too much time for those who are not interested into, you know, OK? So that should work somehow. See, we have, we're here. It's bound to the fact that we have the NG app and the controller, it runs the code attached to the DOM. And we're going to show a little bit of the data binding. He says, Angular wires things up. Yes, it does. Yeah, because I loaded it. So module blah, oh yeah, it's bootstrapped. It's great. OK, so see we have like inline templates here and that since it's inside the NG controller, this is going to call attached to the scope. So it's going to have nested scopes and everything. Yes, of course, nested scopes in the DOM. So let's say you have that part of the page as a menu, that part is the, I don't know what, you have nested scopes and you'll see. I am so sorry. OK, so did you see that? So at first it loads and when it's ready to deal with the DOM, it does the replacement. OK, and that's bound. Yes. Yeah, exactly. Oh, you didn't look. Why don't you look? So I set here scope dot who and that's just a variable in the scope and it's automatically like interpreted. It does the data binding and more than that. So if we look at, let's say we have so input an NG model and that is who. So if we do that, the actual thing here is going to be automatically mapped in blah, blah. Each time it changes, it changes all the model and everything is a, it's not me, shut up. No, we know it's not who is playing. Yeah, Angular is developed by Google guys. So we're not yet into JVN thing. I'm just laying out the grounds because JVN thing is going to push things in there and you're going to see change, things are going to change, but you won't know why. So I just want to lay the ground here. I'm not going to do the jQuery boilerplate thing. You know, on event change and then insert on the DOM, it's done here. Yeah, I understand. But you're in a web, you know, web framework thing. So, no, that's just a far. Yeah, okay. Anyway, it's a real-time web, right? So there's unfortunately some JavaScript. It's cool JavaScript for those who like though. Okay, so great. So that's the two-way data binding, the NG model attached to the input and knows when it changes and writes to the scope and then runs the digest, which is going to go through and reapply whatever has changed. So you can do very complex things with few lines. It has the, yeah, okay. And you can have many, many of those. Like they say limit to 2,000 per page. So performance can be good. You rarely have 2,000, like changing things in your face otherwise you can optimize or, you know, things you can do. Yeah, okay. So now we're going to wire NG event socket IO. Yes, yes. Actually, it's not going to be so exciting because it's going to be quite short. Yeah, really, I'm at page four. I have 10. Do we have to say that? Okay, so I'm going to go into development. So we would need to install G event. What was it? So those dependencies here, socket IO, it loads G event, web socket that the other guy wrote. And G event, okay? Those things are all installed already. And we're going to change the server here. What is it? So yeah, a couple of, yes. So yeah, maybe just to be clear, socket IO is a wrapper around all the different polling mechanism and push methods that were kind of developed last year. So like Facebook, they have many other sites they do. They poll with XML HTTP requests. They wait for 60 seconds. So if the server has something to say, it's going to put it into the pipe, come back, and then the client is going to send another request. So that's the polling mechanism. So socket IO abstracts you from those things. It's going to use web socket, polling mechanism, HTML file, multipart polling, like seven different methods. And it could go through flash also. So that abstracts you and gives you some bi-directional communication for your web client, which is pretty cool. So there's two things. And they're in the process of splitting things. There's the abstraction of the communication layer. And also socket IO gives you nice semantics, like namespaces and event, named events, and JSON encoding. So it gives a little bit more. And they're splitting that in socket IO for the naming thing and engine IO. They're working on that right now. There are no JS guys that do that. OK, so over here, we can add some. Does that answer the question? You didn't tell me to repeat the question. Yep, exactly. Yeah, and the next version is always going to try the one that we know works, like the JSON P polling. Yeah, yeah, you can have way back. Not five, you bastard. You funny guy. I mean, it falls back through very far. Yeah. Are you six at least? So we can specify the transport. Yes. Which question? Yeah, sorry. Yeah, that's true shit. So transport will give which ones you want to have the server supported. You want to answer to which one. It's going to send that to the client, so he knows which one to use. Sometimes going through proxies or weird things, you can't have live web sockets going through. So for a certain application, you'll say, well, start by multipart or never use web socket. For that one, I just want to take out the flash socket thing because it waits until it finds out that the connection is not blah, blah, blah. Yeah, who cares about it? OK, so I mean, that's basically it. When that's done, you reload the thing and you're now backed by a G event. You don't see a thing. It changes the web server underneath. It monkey patches. And then you're ready to have that high throughput multi-connections. And then it's pretty cool. Well, you don't know it yet. Yeah, yeah, poor you. OK, so are there any questions up to there? What? Right, we're getting into it. OK, now we're getting into some. So we're going to integrate the socket IO lib into the client side so that it starts communicating with the server side, right? That's where we lay out the ground. So I understand that might be too long for you, right? We might shorten that part for the next talk. OK, so we'll go in the index. I also have imagine. I also have socket IO here. I can copy directly to my vendors, right? And so socket IO, that should be loaded. Oh, so you might find that annoying. You see the who thing before it loads? We call that flash of unstyled content, or fuk, flash of unstyled contents. You can add ng-cloak. That will hide it. We have CSS thing that hides things until they're ready to be interpreted by it. So it's better, OK? So I have socket IO in there. And then I'm going to wire in socket IO here. And I'm not going to type the full thing. I have a snippet for that. But basically, it's the standard integration for socket IO inside Angular. It kind of wraps. So yeah, it's a nice snippet, huh? And so basically, you have two methods. You can listen to an incoming event with on. We'll do that. And you can send an event, which is going to be a named event. And that just tacks into the Angular loop. When you have something coming in, it's going to rerun that binding thing so that it updates all the UI. And same thing on the other side, OK? If you emit stuff, you can have a callback. The server sets is going to callback. So you have both sides. No, so you have the root scope, which is the top top. Oh, so he's asking, is the root scope the same as the scope? The root scope is the same thing. It's just an object, but it's attached to the ng-app. So to the furthest thing, and you can always know it's going to be there, and you can put some state in there or some data that you can use throughout your app. It's an app. Yeah, it's a simple object. It has some methods that start with $. You're curious about JavaScript, right? You should go to JavaScript Montreal. OK, so you might have noticed I changed slash that. That's the namespace. I highly suggest you guys use namespace, because if you don't put a namespace, it kind of falls back on an old method of using JVN psychology for backwards compatibility reason. Just use a namespace there. Documentations will, thank you, documentation will sometimes, you can just connect. Don't do that with the Python version. And it's better to have a name anyway, isn't it? It's always better to have a name, huh? Yeah, OK, and then we're going to go into a knit here. We're going to add a route so that we can forward all the traffic, whoops, remaining to a controller piece of code. So what happens if that's pyramid stuff, it's going to look at anything under Sakurayo. That's the, you can change that, but it's the resource in Sakurayo. And it's going to use those things underneath, like to say, WebSocket with a session ID. So anyone sending connections is going to be associated through a virtual socket, you know. So it uses, Sakurayo uses all those stuff underneath Sakurayo. OK, yes. So remaining, he's asking, what remaining matter? Remain. It doesn't mind, the thing is just the star. Yeah, I understand. The important thing is just the star. When you have a star, it matches anything afterwards, sets that into a variable called remaining or whatever. It could be some other thing, OK? So, yes. So, OK. Yeah, so he's wondering if we add a root for slash stat. Those are two different things. Here we're talking HTTP requests. The moment we're talking Sakurayo namespaces, we're removed from the HTTP. We're in another world, and that's bizarre a little bit. It goes over HTTP sometimes when it's not using WebSocket, it's getting posts. But then you have named events inside that are packets that hold their own namespaces. That's where stat comes in. So it's not related. And you're not going to get an HTTP call for each packet coming in or going out. It's removed, and it's going to be stateful. It's going to spawn a long lifetime. It's not just like a request when you have on the web. It stays and runs on the server associated to the client there, the browser, and stays in memory and can have processes running and doing some job while the browser is waiting. If the browser closes, it's going to shut down all the processes that are running on the server. There's always a corresponding process. Yes. Yes, exactly. Actually, no. When you connect, he's asking each time you go through the Sakurayo, it's going to go through that route. Only when you connect does it go through that and establish a tunnel that's going to exist independently of those things. And you'll see there's a function in view. The rest is just standard pyramid or a bottle or whatever. Exactly. You got it. OK. It goes through an API that. So OK, you'll see that. Well, calm down, boys. You'll see that. I'm going to show the back and forth thing and the values going through. You'll see the protocol. It's not fast enough? Yeah, it's not fast enough. OK, where am I? OK. So how we handle that is we have a view config that we're going to bind to that route we just set, right? And we're going to get a request. That's pyramid stuff. So it maps to this one here, socket IO. The route is going to go to that piece of code. And then import. Man, we're going to import that socket IO manage command, pass it an environ so that we can use that with any frameworks, not dependent on pyramid. And we'll pass it a dictionary, OK? So with the namespace. So we can have one server, all sorts of different pages, but that server could handle different namespaces. So it's kind of a re-implementation of the namespacing that we have in URLs, but in the socket IO world. OK? So that's that namespace doesn't exist. We're going to from socket IO, namespace import, base name, space, what was that? Yeah, here, it's just not finished, boy. OK. So we're going to create that one. Name, space, base, OK? And this one is going to, for example, initialize. This is called, at the moment, socket IO tries to access or whatever that context, OK? That namespace is going to run. So we're going to print, and we're going to be so happy if it works. And let's try, we can emit, what are we going to emit? Let's say assign, and that's going to be our first trick, OK? We're going to send out a sine wave through, yeah, it's going to be so exciting. Shoot, I thought I didn't have that much time, yeah, not that much. OK, so when we're ready here, oh, just a fun thing, Angular has dependency injection. So if I specify, $suckatio there, it's going to instantiate that piece of thing once for throughout the application, and I can use that in any controller, I'll have that instance there. That's pretty cool. And you can declare all those factories or directives or controllers in all sorts of different files. It's all run at the end and injected when the controller is needed. It's pretty cool. So it's very easy for testing. They well made that for a test. You can mock socket IO very easily, and it enters up. OK, so we'll do here on sine, and we'll have a function data. OK, and so sine data. You want to try that? OK, I'm not sure. Are you sure? Is that going to work? Oh, I got a sine object. OK, so I have that one. Hey, you're supposed to scream. He's screaming. Come on, five lines. Come on. OK, how many? What? Five lines in 15 minutes? Yeah, it's good. Yeah, OK, thank you very much. Thank you. Yeah, OK. So what we can do, actually go here, and we're going to define the sine value to be waiting. And from in there, sine equals data value. So we'll have a default value. The moment we have an input, we're going to write it there. And let's say we have p sine, sine, right? So see, you have waiting, and then you have the value coming in. It updates. So the Angular wrapper does that. OK, great. OK, OK. Well, that's this part. OK, we can run of applause now. No? And we're just going to show a little bit of the. So there are several commands, just so that you know. I'm not going to write them all. You have on event name, that, on args. That's positional arguments. Any event name that's going to be emit is going to be mapped to on something. And you'll have a couple events like RECV, like RECV connect. There's a special packet in Socket.io that's sent when you connect to a namespace, or receive disconnect. You can send a disconnect packet. So these are a different level of things. And you can also have, we'll show that a little bit later, mix-ins so that you add tag-in functionality to your namespace. We'll do that with the broadcasts. And if you want a broadcast between all the users in chat room or whatever, we could add that as a subclass. So now what we want to do is actually graph the sine wave. So I'm going to run a little server-side process. That's going to take, for example, the time, running time, and plot sine wave elements. It's going to send it through the server, the client. And the client is going to graph that on the little thing. Would that be good? And we'll see the server-side process running, even though the client is not sending requests. So first of all, I'm going to go and copy another vendor thing. And we're going to use D3, which is a very cool and nice. And I didn't sleep many nights just because I was doing those things. It was useless for the presentation, but I hope it's nice. And we're going to tack this in over here. D3, V2, I think that's going to work. Is it going to work? OK, we have it. And obviously, I'm not going to show any D3 stuff, so I have a little snippet that's just going to throw things. Yeah, you know. And that snippet is my live graph. So this is all the little D3 thing. It's going to take data. If it's live updated, there's a little watch here, and it's going to update the graph the moment we push something in the array. And the way we're going to use that is this way, because Angular adds to the HTML language somehow, and it maps to that code. So I'm going to go in there, and we're going to add the sign graph. So my live graph and the data is going to be the live sign array, and the max delta, because the code supports that. Sorry, that's the window of time it's going to throw. You'll see. And with 700, that's going to make a great graph. What do you think? OK, so when I have that, I mean, things should display. Of course, of course it crashed, because I'm passing this data here. It does not exist on the scope. So we'll add the array on the scope so that it reads something, right? Because right now, obviously, don't you find that? I'm going to go back here. So live sign equals stuff. And actually, we're going to add the values, live sign, push. That'd be great, right? The moment we have the data coming in, we're going to add it. And that's all. You believe me? You believe me? OK, so the graph is there. Now I have an object. So let's put the server side part that's going to push the values. Will that be cool? OK, cool. So over here, we're going to define a job. It's just my convention. I prepend job, because it's a long running process. I'm going to span it with a green light. OK, so that's going to be send sign. It's always, see? And over here, we're going to span it, sell job, job, bang. By doing that, the moment we initialize, it runs that in a separate threadlet, if you would say. And it's still associated with the socket through self. We can emit and go through and, yeah, per connection, per user, exactly. And JVN allows you to have like 100,000 connections on one machine and one server. Because it doesn't do context switching of the system. It does some polling and select things. Yeah, we'll do that. Whoa, come down, boy. He was asking for broadcasts. Yeah, he's following at least. OK, so we're going to increment CNT. And actually, we're going to import a couple of things. Import time here. Whoa, shoot. Import JVN, because we're going to need the sleep function to yield the control to the hub, because there's an event loop going on and math. OK? And so this is going to be the current time. And we're going to emit a new value. So we're going to take this one out, because we're going to change the syntax of the event. And that's good. Oh, sorry, we're not. Whatever. That's going to be, so the time, because it's in microseconds, whatever. It just graphs better. And the sign. OK, what about that? And then sleep for a second. What about that? Is that going to work? You see underneath here? Oh, shoot. But now it's fun to have a server-side process running, but we want to interact with it, right? And tweak it a little bit. So we're going to add a speed controller, right? And the speed controller, shoot, times goes by. Sorry, it's just because of the frequency there. We'll improve that. Let's see. It was not interesting. You stop asking questions. I don't have so much time, OK? OK, so we're going to add a speed controller. OK? And the speed controller is going to be just here. And select the speed. Select. We're going to map that to the speed. And OK, we'll shoot. And the option, and we can have like 0.5. And we can have like 0.2, 0.5, 1, 2, right? Good values. And obviously, ngModel is just going to change the value inside the scope. So let's have here scope speed default to 1. And if we load that, you'll see that we have the speed. We can change it. For now, nothing happens. OK? We want to have a little check. So we're going to run a watch. If speed changes, we're going to send a signal to the server to change the speed. Huh, cool, OK? And that's going to be through Sakurayo, emit, for example, new speed, and parse float, because it's coming from a box, new val. Great. And on the view side, what we're going to do, we're going to parse on new speed. Speed, so arguments are passed like linearly, just the same thing as Python. And we're going to do something here. We're going to set a default value on the session, OK? And over here, it's going to be equal to speed. Whoops. You with me? Equals 1. Change the speed, OK? And over here, we'll say self-session speed. So that's attached server side. It's not the beaker session or Django session. There's a little difficulty with that. We'll explain another time, OK? Because it stays open, so you don't flush it back the moment the request is done, right? So you have to do some special things to either use it only when you want it. OK, so what? Oh, never mind. It's unrelated. OK, so can we change the speed now? 0.2. Whoa, now we have something better, like 0.5. And now things arrive at a pretty good rate, right? For the server pushing things to the client, that's pretty good. 0.5, so it sleeps a little bit. You have the time running, OK? OK, OK, so that was speed. Yes, of course. D3 is awesome, because it's SVG. He said, can we change the color? That's SVG. We just changed a CSS class, and this changes color. Those are all native objects in the DOM, because it's SVG. It's really great. D3 is awesome. You should have a look at that. And it's the same data binding. You put some data, and it scaffold some great SVG. Like that, because it iterates automatically and creates objects. It's awesome, OK. OK, so that's running. Let's calm down a little bit. And then the next thing we're going to do, we're going to play a game, OK? You guys are good hackers. You know all the tech jokes, right? So I wrote a little application that you got. I'll take out your internet-connected device. So you're going to connect, and you're going to influence what's on a graph, because that's Google Analytics, right? It analyzes real-time traffic. So you're going to create the real-time traffic. So I'm going to show you a little program I wrote. It's called Clickable. It's not very useful elsewhere, but OK. So it opens a file. It's a little bottle program. It's unrelated to Socket.io. It's just to collect your state of loser or winner, OK? When we receive an event log event, I'm going to write that as JSON to a file, OK? That's it. And if we look at its JavaScript side, so it's going to, if we click on a button, send an event. To see that, you'll go to Moo. Yes, you understood, OK? Go to that place. Moo.aborge.net, and you'll see a couple of questions. That's kind of a quiz for all your geeky funniness. Moo.aborge.net. You want to take a picture? I never use QR code. They suck, but. Someone is going to use that. OK, so I have to run it. Obviously, this is going to connect to my machine here. OK, so Clickable. Bang. So now you should be able to connect. And we'll see the request coming in. OK, that's good. Those questions are going to write things to the log. Next thing we want to do is we actually want to take those lines that are coming down. Yes. No. You're slowing down. Stop the timer. He's the guy with the timer. That's why I say he wants to use the QR code. Stop the timer. What are you doing? No, you didn't. I know it's hot. I know it's hot. You can blow in your face. Yeah, but we're going to see if you're good or bad, because we're going to graph the winners and losers and the page views, OK? So are you done? Sorry? Somehow. So he's asked, is that anonymous? We don't need to repeat those questions. OK, we're going to add another little handler that's going to grab that file, that's going to tail it. And the moment there's new data, it's going to push it back to the UI. And the UI is going to graph that, like Google Analytics does, but better, because that's going to be real time and pretty fast. Google Analytics doesn't do real time. Well, they added that later, but then it's, yeah? OK, anyway, I'm not pretending this is better than Google Analytics, but anyway. OK, so we're going to add another little job. And that job, that's going to be grab click data. This one is going to get, I install that. OK, that's the G event support, so that it yields control to the when it's blocking on read line or stuff like that. It's going to yield control back to the loop, so it's not blocking, it's never blocking. Because there's only one thread. If you block something with G event, it blocks everything. Yeah, exactly. You're kind of biswacked. OK, so we're going to run popen tail. And I have that in move clickable clickable.log. And let's start with 100 lines. Go through the shell and the standard out. It's going to go through the pipe, OK? And we're going to read line, because that's how you do. You can't just do read lines. If you do that, it's going to wait until you're dead. OK, we're going to show that. And then just emit, whoops, click. And we're going to load the line, send the object. It's going to be a re-serialized on the way out. OK, is that clear? Thank you. So, spam, we're going to launch that job when the guy grab click data. Is that going to work? Now we should see, well, let me add a handler in the JavaScript, right? If we get scope, no, suck it IO, on, we get a click, function data, I know, I know, OK? We're going to console log click data. OK, want to try that? Go ahead and click on things. We should see things. No, it doesn't work. What happens? Serve, oh, JSON to define. Who wrote JSON? Who did that? OK, it's going to restart. OK, so it starts, so it sends a bunch of clicks, we see them arriving. Who's that one? Loser, who's that one? OK, and now we're going to graph. So I have another D3 thing I'm just going to tack in, and it's going to spread that into bins, a histogram thing. OK, so main, where is that? That's going to be my bar graph. OK, does the same thing, pretty nice stuff. It's not so long, puts that into bins, draws an SVG. And now, we'll want to have those things here. That's going to be a page views, OK? And that's going to be my bar graph. And this one is going to use data from click data. And the type is going to be page view. Let's try that one. OK, so we have something. Now, what do we miss? Take the data, put it into the array. You think it's going to work? It's going to work. Everything worked, so why don't not? So on click, we'll have that. Scopes, what is it? Click data, an empty list. Click data, push data there. Oh, phew. OK, now refresh your browser. You should see those things. So those are bins of 10 seconds that are going to accumulate. So if you refresh, OK, those graphs are synchronized through three, so that's why the scale changes. So you see the page views. An awesome thing we have with Angular, you can reuse your components very easily. So we're going to just copy that. And this one is going to be the losers, winners. And we're going to change a couple of attributes. Type is answer. That's the format of the data coming in. You guys answer a lot of things. Whoa, never had such traffic. So type, whatever. OK, you see it, answer. You see the winner, OK? And which question they answer. So we're going to do the same things. Type answer, field winner, loser, OK? And then we have three graphs, hopefully, with all the losers. Oh, we have a lot of losers. Whoa, that's great. More losers than winners. So you don't know your tech jokes. Or you're just clicking like crazy, right? That's all right. Oh, I have a comment. Your battery. I have two batteries. Whoa. I have a bay battery. I like it. OK, so, sorry? 30 seconds. OK, so I have other things to show. But if you want to answer a question and close it, I know it's late. Yes, time. Actually, I don't know if someone was going to ask. This is the time. It supports the time very well, like you see in the sign thing. But I just split the full thing with whatever data is coming in. I just split equal width. So it's not represented. It doesn't represent time. Those bars are not correctly aligned to the bar underneath. It's true. That's a failure. But I'm going to improve that for some other times. So in case you might have noticed, have you guys loaded that page on your machine? So there's a little, you know, this. I also wired in Sakurayo into a little bottle app. And those slides push to you guys the moment I change the slide, right? So if you guys open that, you'll see it changes with me. And you guys can't change it because it's tight. That's a social component, yeah. Sorry? How do you monetize? Well, we can see it this way, right? We can see it this way. And I'm the presenter, so I can switch here. And things go out together. And it does that on your machine, too. OK, OK, come on, come on. So that's the slides thing. And it looks like this. There's a broadcast mixing. And the broadcast adds a couple of functions to the object, like broadcast event, not me. And then it's going to send to everyone connected, except myself, that event. And then, obviously, it's easy on the client side, just take that event and switch page. So there's a couple of lines. That's the bottle example. I'll have that up on the web also. It's one file, Sakurayo server there. You have the namespace, present to IP. Are there any questions?