This is a class for making simple sprites within WinForms. This article explains how to use the class, as well as how the class works if you want to make something like it.
Windows Forms have been around for quite some time, but it is still not very easy to make graphical games in WinForms. There are many complex libraries, and other systems for making games in, and using those extensive systems is how they recommend most people do their games. This is a simple sprite engine for use within Windows Forms, with the intent of keeping things simple. While you can make a complete game with this library, it is not a very polished system in and of itself. It is mainly to get people started in graphical programming. Probably the first comment I will get from this is, "why not use a real gaming library?" The point of this library is for simple games, for an entry into graphical programming. After someone uses this, then they will probably have the desire to work with DirectX, OpenGL, Unity, UnrealEngine, etc.
This SpriteController class allows you to take a PictureBox and turn it into a gaming field. You give it a background to draw on, and then plunk your sprites on it. All the work of animating and moving the sprites is taken care of. It also contains a simple system for determining if keys have been pressed (since that is one of the big things that stymies fledgling programmers). You can use this as an example for how to make your own sprite-controller, or use this one.
C# Winforms are not built to do complex graphics easily, but it does not take much to spark the interest of a fledgling programmer. And using a class like this is a fairly simple way to get started. First, I will explain how to use the code for those who are interested in simply using this library. And then, I will explain a bit about how the library works.
I recently had the opportunity to start to teach a nephew some programming. His mindset was the same as my mindset eons ago, when I started thinking about programming. "How can I make a game?" I like C# and Visual Studio. It is very easy for someone who does not know much about programming, yet wants to make something that works. It has excellent built-in documentation, and can be as complex, or as simple, as you need it to be. But it does not do graphics easily, unless you are very simplistic (one image in a box), or go to OpenGL, DirectX, Unity, or one of those fairly complex systems. Granted, there is a lot of documentation and tutorials to make those "simple." But, using this class is even simpler. This is my attempt for putting graphical game creation into the hands of fledgling C# programmers.
2D programming is a whole lot easier to make images for. With the right languages, it may not be a lot more complex to program for 3D, but so much of programming is in building the graphics. It is still a bit of a chore to build an animation for a 2D world, but it is doable without a lot of rendering knowledge.
After you download the source code for the library, you need to open the project and "build" it. Down at the bottom of Visual Studio, it should tell you that it has been built. The library cannot be executed on its own; you need to make a project (or download and run the demo) to see it in action. The resulting DLL file should be in the projects SpriteLibrary/SpriteLibrary/Bin/Release directory.
In your project (make a new project if you do not have one already), right-click your project name in the "Solution Explorer" and "Add" and "Reference." Go down to "Browse" and find the SpriteLibrary DLL. If you have built it (see above), it should be in your projects/SpriteLibrary/SpriteLibrary/Bin/Release directory. If you develop a game and use the built-in ClickOnce installer, this DLL will be automatically installed, along with your package, now that you have added it as a reference. So you should only need to do this once.
To install the msha file and configure Visual Studio for accessing the online help, open Visual Studio and go to "Help" -> "View Help." The Microsoft Help Viewer should come up, usually with the "Manage content" tab selected. If it is not selected, open the "manage content" tab.
Then, select "Disk" and browse to your SpriteLibrary project, finding the Documentation.msha file under the Doc\Help directory. Once you have found that, click the "Add" button next to the new documentation file.
Once that has been added, you still need to press "Update" in the bottom right corner of the window. At the time of this writing, SpriteLibrary has not been digitally signed, and a notification of that will pop up during the install.
You may notice that we do not yet instantiate it. We need to have a PictureBox associated with the SpriteController when we make it. So, after the form is loaded and the InitializeComponents(); has been run, then we can instantiate the SpriteController. In this example, we have a PictureBox named MainDrawingArea. You can have multiple sprite controllers per game, but you only want to have one per PictureBox. So you will want to store the variable, and pass it to the appropriate places that your program needs.
We set the background layout to stretch. This is important for being able to resize the window and for a number of other things.
First, you must have a sprite to add. Sprites are basically a series of frames on one image. Each frame is one picture, and is the same size (for example, 100x100). And there may be many frames in the image. The resulting image might be 400 x 100, or 200 x 200. The sprite will display each frame, one at a time. So you might have an image of your main character standing there. The next frame will be with his leg slightly extended. The next has his leg out. When we see it animate, the leg moves out as if your adventurer is walking. This sprite controller assumes the image will already have the transparency set so you can see the background behind the sprite, which basically means you are using png files with transparency.
In this example, we are making a sprite named JellyMonster by pulling the animation out of the second row of the image. (0,0 is the first row, 0,100 is the second row.) We pass it the sprite controller, and then the image file. We specify that the image we are pulling out is of the size 100 x 100. We use an animation speed of 200ms per frame, and we pull 4 frames out of the image. When we print the sprite, we can grow, or shrink the sprite on the PictureBox. It does not need to remain at 100x100. That is just the size of the individual frame in the sprite sheet image.
The last step we do in the above code is to name the sprite. We name our master sprites, and then clone them when we want to have a bunch of them. We usually will not have the named sprites display on the screen without cloning (though you can). The main reason we do this is so that we can destroy sprites at our leisure, and make as many of them again whenever we want. When you destroy a clone, it is easy to make more from the master. But destroying the master means you need to start from scratch. It is very efficient to clone sprites, but it takes a lot more effort to generate new ones from scratch.
Now that we have a sprite, we can put it somewhere. Once it is placed on the background, it will automatically start displaying the first animation (animation 0). You can have multiple animations for each sprite (walk left, walk right, fall left, fall right, die, etc.) You can tell a sprite to change animations, or to animate once (leaving the sprite displaying the final frame of the animation). Here is some code for how the Sprite is configured in the ShootingDemo.
We tell the Sprite that it will automatically move. We tell it that it cannot go outside the bounds of the picturebox. And then we tell it where it starts, and which direction it moves. The += line is an event. SpriteBounces is a function that gets executed when the Sprite hits the picturebox. (See "Sprite Events" below).
You can add events to sprites. For example, you can add some code that is run when one sprite hits another sprite. In the ShootingDemo, we add that event to the monster sprites. Many times a second, the sprites check to see if they have hit another sprite, and if they do, they execute the code in that event. There are events for when sprites hit the edge of the picturebox, or if they have exited the picturebox. There is even an event that fires off before a sprite moves to a new location. You can use that one to adjust, or cancel the movement location.
You need to create an event, and add that event to the sprite. Events are cloned with the sprites, so you can add events to the parent Sprite, and those events will work for all the cloned sprites.
You then make a new payload, set the data, and store it in the Sprite.payload.
The ShootingDemo, which is a downloadable example, is a very simple "Space Invaders" style game. You are a spaceship at the bottom of the screen, and sprites are bouncing across the top. You shoot them. When the monsters are hit by the shot, they explode.
When the game instantiates, the "InitializeComponents" function fires off, and makes the picturebox. After that, we set the background image of the picturebox, and set the backgroundlayout = stretch. This is important for the sprites to function well. We do it in this order because the PictureBox needs to exist and be configured before we create our SpriteController, which uses that PictureBox.
After the PictureBox is defined and configured, the SpriteController is create and given the PictureBox it is supposed to draw the sprites on.
The last main item in the setup process is that an event is added to the SpriteController "Tick." The Tick happens multiple times a second, and we add a function that reacts to keypresses.
Now that the sprite controller has been created, we want to load the various sprites. The demo shows a number of different types of sprites. The sprite demos have multiple sprites on one image, have one image that contains one sprite, and has an image that contains multiple animations for the one sprite. Some of the sprites have events added to them (more on that below).
After the sprites are loaded, we add a number of them to the game, and the game begins.
When the game begins, this particular game works off a Timer. The sprites are set to move left or right, and they move until they hit an edge. At that time, an event fires off to tell the sprite to move the opposite direction.
Meanwhile, the "CheckForKeypress" function fires off many times a second to see what the user is up to. If the user is using a left or right key, we tell the sprite to move to the left or right. If the space is pressed, we generate a "shot" and send it moving in a straight line up.
If a monster gets hit by the shot, the monster gets destroyed. An "explosion" sprite is generated, which is the same size as the monster that got hit. The explosion is told to animate once, and when the animation is complete, for it to run one last "event." The explosion done event destroys the explosion, which removes it from the game. Whenever an explosion finishes, we count the monster sprites. If they are all gone, the game is over.
This is a very simplistic "game." It is meant as a demo, not an actual game you would play over and over. But it shows off most of the functionality of the SpriteController.
The SpriteController works in a time-based system. It has a Timer (This is the name of the C# class) that fires off many times a second. Because of how C# handles time, we cannot guarantee precisely how often that timer goes off. So everything keeps track of the last time it did anything. For example, a Sprite will keep track of the last time it moved. It knows how many pixels a millisecond it traverses, and so it can compute how far it should move when the tick goes and it finds out that 15.3 milliseconds have transpired since the last time it moved. It does the same thing with animations; it computes the time since the last time it changed frames. If it needed to change a frame 10 milliseconds ago, but 15 milliseconds have passed, it will change the frame, but pretend that the last time it changed the animation was 5 milliseconds ago. That way, the next animation is still set to happen at the right time, even though there was a tiny stutter in the timing. By tracking time in this way, everything appears to move smoothly even though some events take longer than others to happen.
Note: The SpriteController does not yet have something to adjust the time if things begin taking too long on a regular basis. Most games will recognize that things are updating slowly and will adjust the effective time passage accordingly. This is not too difficult to do, but I have not yet done it.
What makes the SpriteController able to function is how it handles drawing sprites. The SpriteController has a copy of the original background image without any sprites on it. This is used to grab pieces to erase our sprites with. To do that, it simply grabs the original background that comes from the entire rectangle that the sprite is in, and it draws that on the background (that usually has the sprites on it). We also have another image, which is the one that is displayed on the PictureBox. This is the one that has the sprites drawn all over it. When we re-draw the sprites, we draw them on the image of the PictureBox (the same one we "erased"). There are some issues that we can have with this, particularly if two sprites are overlapping. In that case, we tell each sprite that might have had part of it erased to re-draw itself. This is rather inefficient, but it works very well for a simple sprite controller.
The SpriteController is relatively simple in design. Each Sprite has one or more "frames." Each frame is an image, and has a "duration." Every tick, each sprite checks itself to see if it needs to be refreshed. If it needs to be redrawn, it erases itself (copying the portion of the background image behind itself and drawing that little back on the master image). It then moves or changes its animation, and then draws itself again in the new location or with the new image. For both of these, it invalidates the picturebox, but only the portion of the picturebox that covers that particular sprite. The system figures out when to actually redraw the image, but it usually works pretty smoothly.
So the simplistic description is that we have one larger image, which is displayed inside the PictureBox. That larger image is re-drawn by erasing or drawing the sprite images onto the image. And the PictureBox is "invalidated" with only the portions that have changed. So the program only needs to redraw a small portion of the screen each time. By redrawing just the little portion, it can be done fairly quickly, which makes it look smooth.
The smoothest method for telling a sprite how to move is by giving it a speed and direction. The direction can be specified as an angle in degrees, an angle in radians, or a vector. Most people will use degrees, as that seems to be how us simple game writing people think. Vectors work quite nicely if you are doing three-dimensional games. But this Sprite Controller does not handle 3D easily.
You can tell a sprite to rotate, and the sprite will change the angle in which it is drawn. So you can have one car sprite, and have it rotate around to look like it is driving in a bunch of different directions. There is a small issue with the way we do rotation; we rotate the image, and then draw the rotated image back inside the original shape rectangle. This causes a little bit of shrinkage when we are at non-right angles. But it looks pretty good.
Remember to turn off mirroring when you want it to flip back.
When the sprite reaches each of the waypoints (the points along the way, except the last point are all waypoints) the event, SpriteArrivedAtWaypoint fires off. And, when the final point is reached, the event SpriteArrivedAtEndPoint gets fired off.
Where the black lines are the main pieces of code that get fired off every so often. The blue and green are things that Windows puts in when it needs to do so. For example, the blue is re-drawing the screen, and the green is "Garbage Collection" (cleaning up un-used memory).
The important thing about this is to realize that there are a number of things you can do that will keep the thread from moving on. You can use a "Thread.Sleep(100)" command, but that will halt everything in the "thread." The result is that sprites do not move or animate while the thread is sleeping. They are all part of the same thread.
The SpriteLibrary assumes that you will have triggered events, and that the events will return control to the SpriteController when they are done.
You want to have one central function, usually tied in with the SpriteController "Tick." The first thing you want this function to do is to determine what the status is of your code. Are you waiting for something? Should you be checking to see if something has completed? And, finally, check to see if you should be getting input and changing your status based on the current input.
The ShootingDemo only has one check. It makes sure we have not won already. If we have not won, then check to see if we should move anywhere or do anything.
So, let me give you a more complex example. Let's say we have a function called myDoTick that is added to the SpriteController DoTick event. We have three states, moving (the sprite is using a MoveTo function to travel to a specific point on the screen), waiting for keypress, and "the game has ended."
The next time it goes to the myDoTick function, it takes us to the "case end_game", which checks to see if five seconds have passed. If so, then we close the window.
The CheckForKeypress function would check to see if any keys had been pressed, and, if so, tell the player's sprite what it should be doing.
There are many events that sprites go through. They collide with the edges of the picture-box, they run into other sprites, and they move to new locations. Life can be made a lot simpler if you can use those events to trigger different things in your game. For example, in the ShootingDemo, each of the monsters check to see what they got hit by. Often they are hit by other monsters, but, they can also get hit by the "shot." When they do, they explode. This is the joy of object oriented programming. You tell the object that, when it is hit by a shot, it explodes. And, then it just seems to happen when the game goes on. If you can famialiarize yourself with the events that a sprite can have, you will soon become an expert in programming with the SpriteLibrary.
This SpriteLibrary works nicely for simple games, but it will bog down if you make something that is too complex. If there are too many sprites running around, or if you need a lot more features that is programmed into it, you will end up needing a more complex gaming system. But this should work nicely for your first few games, at least.
But the two main weaknesses are that the SpriteLibrary has limited scope, mainly to try to keep it simple, and it has limitations due to how it deals with time.
It does not have scrolling backgrounds, it has limited collision detection, and it really only works well with a limited number of sprites. As you program, you will run into these limitations. You will want to find some way to do something, and not see it there.
I talked a bit about the limitations previously. Here, I want to discuss how to notice that you are running into time based issues.
If you have too many sprites, or if you are doing too many things in one function, you will begin to notice strange behavior. You will notice that sprites are moving in a fairly jerky manner. They will disappear and re-appear in a different location, etc. And you will also see issues with collision detection. Sprites will pass through other sprites without it being triggered. So, you will shoot something and the shot will pass through it harmlessly.
In such cases, think about what you are doing and how to make it run faster or run more concisely. You want to give the SpriteController enough time for it to be able to handle everything it needs to.
I really enjoyed your project and was wondering if I could get permission to create a wpf version of it and submit it to github.
No, I do not mind. I am sure you will make a number of improvements and changes. If you see any glaring bugs that I should fix in my version, please let me know (if you think of it.) I do occasionally add more functionality. I assume your WPF version would be more of a fork than a clone; that way you can add / change functionality that we do not need to keep in sync.
If you do get one up and running, let me know and I will post a link to it somewhere.
Nice intro to sprites. Even an ancient, grizzled coding veteran gets excited by visual "eye-candy"
Add a sprite-eating snake and using only the arrows and kids will love this.
are you going to do a follow-up article on making sprites and/or what tools you use ?
Thanks. I have not read up much on how other people make sprites, but I have seen a number of articles out there on the subject. I will make a note to see if I can find an article or two for tools or something that work with this library.
So far I have been using the Gimp to make my sprites. But I have not made too many of them. The extent of my sprite building has been to make a gimp layer that was a "grid." Then I draw my images, one after the other in the grid. At the end, I set the grid properties to be invisible. It is a tedious process. And I never really know what the sprite will look like until I animate the thing.
And you are right. If I am building this thing to help get my younger family members interested in programming, I ought to put some effort into making the sprite building easier.
Most sprite sheets are built on the same principles. So most tools that build them should work with this library. I open to suggestions, and, if I find a few of them I will happily add a section on building sprites.
Yesterday I looked around a bit at what tools exist out there. This one seems to make great sprites that would work with the SpriteLibrary.
If you download it, go straight to their help. For me, the thing I needed to understand in how to use it was to click on the properties of the first frame and set the transparency. After that, the onion-skin worked. The "onion-skin" allows you to see the frames before / after the one you are looking at, which helps considerably when doing an animation.
Nice work - got my 5!
I suggest to replace DateTime.Now with DateTime.UtcNow because it is much faster and it doesn't have the summer-/winter time problem.
Thank you. This seems a very nice sprite animation library for WinForms and C#. I especially appreciate the effort that you obviously put into commenting your code (e.g., producing the nice SpriteLibrary.XML file). We have a bunch of simple games for very young children with disabilities, originally written for the Apple IIe using Manx Aztec C; then using C and C++, then using MacroMedia (now Adobe) Director and Lingo. Finally maybe getting around to updating those. Whenever we've needed animation in C# lately, we just wrote a fixed solution that "worked" (sometimes not too well). I think it might be fun (and fast) to try porting that code using your DLL.
Thanks for the encouragement. I hope it works for you. It is meant to be simple to program with. I do not know how well it would work for anything complex; I have not done any real optimization on it. But the small projects I have done with it have worked quite nicely. If you do use it and could use some added features to the sprite library, let me know. I am not sure if I would have the time to add them, but I might. And if you find something that would make your life easier, probably someone else will find that useful at some time also. Thanks.
Thanks. I will accept the compliment as a compliment. I do hope it turns out to be easy to use. That was the intent. My main audience are some young family or friends who are starting to get into programming. Though only one of them are getting into it at the moment. So if things are hard to use for you, it will probably be hard to use for them.
Hi, I am happy to report that I've had substantial success porting an old game using SpriteController. But it has not been too easy, even with excellent in-line documentation. A reason, I think, is that the available functions appear to be ones that were needed to make a particular kind of game .. like the demo Space Invaders one. I'm pretty sure your stated audience of young family and friends will not have too much trouble ... because for each new thing they will want to do, you will be handy to help and explain. Pretty soon they will thoroughly understand each example and go on themselves.
For example, one thing I have not figured out but need and could use some suggestions regarding is how to animate a sprite for a certain number of animations. (AnimateOnce(0) seems to be all there is of that and it seems to have side-effects). I want a sprite to move in some direction 4 animation steps involving 2 frames per step, for instance. Or a sprite to move from where it is now to some other basepoint on the Gameboard .. and stop.
For instance, if it were a "Mother, may I" game, then "Sprite, take 3 steps to the left, then 1 step up" or "Sprite, run over to the fence", etc.
Honestly, you have made a very good C# library. But I were to use it, I wonder whether anyone (me included) later would be able to understand the code without a long process of rediscovery. I am thinking for these particular (very simple) games (which have already gone through about 5 graphics development platforms) I might simply be better off to write my own animation functions controlled by timers and draw these on the GameBoard picturebox. Then everything about the game code would be obvious and self-contained and could more easily be modified, adapted, and ported (say, to iOS, etc.) in the future.
Perhaps .. but right now I am having fun with SpriteController!
Hi there, I was pretty sure that you would be the one to give me the most feedback overall. I suspect there are a number of good pieces that would come out of this.
There are a few "easy" things that can be done to help out. I could add a SpriteChangesAnimationFrames event that fires off every time an animation frame changes. That might help a little bit. I have not yet uploaded the few changes I made with the payload, but that might also help a little bit. That way you can give each sprite some sprite-specific counters (so you can keep track of how many "steps" it has taken, etc). Let me add that event. I was hoping to do a little more modification to that and update things over the long weekend coming up.
Trying to tell a sprite to go to a specific point and then to jump over something is a little more interesting. I use the Sprite.CheckBeforeMove event to handle things like telling a sprite to stop. That event fires off just before a Sprite moves to a new location. You can use it to adjust the final point and to modify the sprite itself.
In the long haul, I do not think this class will easily port to other devices. Most of those devices to have graphics libraries, and there are graphic libraries which are specifically designed for portability. I do not know much about those, I am afraid.
A very functional class - nice.
making the Sprite class a generic, with the type of the Payload the generic parameter.
Thanks for the suggestion. You are right about type safety issues. I am a self-learned (hobby only) c# guy, and so excuse my ignorance. If I were to implement the generic class thing, then most every time someone wants to create a sprite, they will need to define the type of payload? If you have no payload Sprite<null>, or do not specify a type, can that work?
I suspect that everyone will have one type of payload instead of having lots of different payloads. But most of the small things I have written with this had no payload at all. So it can be annoying to need to specify a type for the payload if one is not going to use it.
For type safety purposes, I could make a generic SpritePayload class, which could be overridden.
A big part of this is that I am hoping to make something that is relatively simple for novice programmers to use.
Thanks for pointing out the messiness of the generic payload, and for the suggestion for how to fix it.
So - if most instances of Sprite don't actually need a payload, then having to specify one every time is certainly going to become a pain.
I hadn't appreciated that this is a feature not used by the demo code. YAGNI would say don't put the property in until you have a use-case for it.
Then (and only then) will you know what you want from it.
We can make the Sprite class generic, cascade the generic type through the SpriteEventArgs class and all of the event handlers.
Which works wonderfully if we have one type of Sprite payload in use consistently.
If you want a heterogeneous collection of Sprite payloads, then things get complicated and messy and out of control very quickly.
Which comes back to the question of why you want the payload property.
was used in Windows Forms coding, where all of the events were typically hooked up from within the Form.
If this is simply about handling events in an object-appropriate manner, then this possibly suggests a lack of encapsulation.
class that handles the events. E.g.
// We have direct access to Monster from this handler - we don't need to pull it from the event args or the Sprite itself.
Yes, this looks like it is easy enough to do, and straight-forward enough to use. I will remove the payload and update the documentation accordingly. I probably ought to make a simple demo showing how to use it effectively. Thanks!


text:
@interface CDTBlobCustomEncryptedData : CDTBlobEncryptedData

@property (strong, nonatomic) NSData *iv;

- (instancetype)initWithPath:(NSString *)path
               encryptionKey:(CDTEncryptionKey *)encryptionKey
                          iv:(NSData *)iv NS_DESIGNATED_INITIALIZER;

@end

@interface CDTBlobEncryptedDataTests : XCTestCase

@property (strong, nonatomic) NSData *ivData;
@property (strong, nonatomic) NSData *otherIVData;

@property (strong, nonatomic) CDTEncryptionKey *encryptionKey;

@property (strong, nonatomic) NSData *plainData;
@property (strong, nonatomic) NSData *encryptedData;
@property (strong, nonatomic) NSData *otherPlainData;
@property (strong, nonatomic) NSData *otherEncryptedData;
@property (strong, nonatomic) NSData *headerData;
@property (strong, nonatomic) NSMutableData *headerPlusEncryptedData;

@property (strong, nonatomic) NSString *pathToNotEmptyFile;
@property (strong, nonatomic) CDTBlobCustomEncryptedData *blobForNotEmptyFile;

@property (strong, nonatomic) NSString *pathToNonExistingFile;
@property (strong, nonatomic) CDTBlobCustomEncryptedData *blobForNotPrexistingFile;

@end

@implementation CDTBlobEncryptedDataTests

- (void)setUp
{
    [super setUp];

    // Put setup code here. This method is called before the invocation of each test method in the
    // class.
    NSString *keyStr = @"3271b0b2ae09cf10128893abba0871b64ea933253378d0c65bcbe05befe636c3";
    NSData *keyData = dataFromHexadecimalString(keyStr);

    NSString *ivStr = @"10327cc29f13539f8ce5378318f46137";
    self.ivData = dataFromHexadecimalString(ivStr);

    ivStr = @"00000cc00f00000f0ce0000000f00000";
    self.otherIVData = dataFromHexadecimalString(ivStr);

    CDTHelperFixedKeyProvider *provider = [CDTHelperFixedKeyProvider providerWithKey:keyData];
    self.encryptionKey = [provider encryptionKey];

    self.plainData = [@"摇;摃:xx👹⌚👽" dataUsingEncoding:NSUnicodeStringEncoding];
    self.encryptedData = [TDBase64 decode:@"H6nWVwfuGB8hDv/dFVUXbU2yb07NzE2vf3HttPF/qps="];

    self.otherPlainData = [@"摇;摃:§婘栰" dataUsingEncoding:NSUnicodeStringEncoding];
    self.otherEncryptedData = [TDBase64 decode:@"+B/AXr0PQrxQSAdMnE8BKKUymEak2akCuGGHIY99lNU="];

    char buffer[sizeof(CDTBLOBENCRYPTEDDATA_VERSION_TYPE) + self.ivData.length];
    memset(buffer + CDTBLOBENCRYPTEDDATA_VERSION_LOCATION, CDTBLOBENCRYPTEDDATA_VERSION_VALUE,
           sizeof(CDTBLOBENCRYPTEDDATA_VERSION_TYPE));
    memcpy(buffer + CDTBLOBENCRYPTEDDATA_IV_LOCATION, self.ivData.bytes, self.ivData.length);
    self.headerData = [NSData dataWithBytes:buffer length:sizeof(buffer)];

    self.headerPlusEncryptedData = [NSMutableData dataWithData:self.headerData];
    [self.headerPlusEncryptedData appendData:self.encryptedData];

    self.pathToNotEmptyFile = [NSTemporaryDirectory()
        stringByAppendingPathComponent:@"CDTBlobEncryptedDataTests_notEmpty.txt"];
    [self.headerPlusEncryptedData writeToFile:self.pathToNotEmptyFile atomically:YES];

    self.blobForNotEmptyFile =
        [[CDTBlobCustomEncryptedData alloc] initWithPath:self.pathToNotEmptyFile
                                           encryptionKey:self.encryptionKey
                                                      iv:self.ivData];

    self.pathToNonExistingFile = [NSTemporaryDirectory()
        stringByAppendingPathComponent:@"CDTBlobEncryptedDataTests_noExists.txt"];

    self.blobForNotPrexistingFile =
        [[CDTBlobCustomEncryptedData alloc] initWithPath:self.pathToNonExistingFile
                                           encryptionKey:self.encryptionKey
                                                      iv:self.ivData];
}

- (void)tearDown
{
    // Put teardown code here. This method is called after the invocation of each test method in the
    // class.
    self.blobForNotPrexistingFile = nil;

    [[NSFileManager defaultManager] removeItemAtPath:self.pathToNonExistingFile error:nil];
    self.pathToNonExistingFile = nil;

    self.blobForNotEmptyFile = nil;

    [[NSFileManager defaultManager] removeItemAtPath:self.pathToNotEmptyFile error:nil];
    self.pathToNotEmptyFile = nil;

    self.headerPlusEncryptedData = nil;
    self.headerData = nil;
    self.otherEncryptedData = nil;
    self.otherPlainData = nil;
    self.encryptedData = nil;
    self.plainData = nil;

    self.encryptionKey = nil;

    self.otherIVData = nil;
    self.ivData = nil;

    [super tearDown];
}

- (void)testInitWithPathEqualToNilFails
{
    XCTAssertNil([[CDTBlobEncryptedData alloc] initWithPath:nil encryptionKey:self.encryptionKey],
                 @"A path is mandatory");
}

- (void)testInitWithEmptyPathFails
{
    XCTAssertNil([[CDTBlobEncryptedData alloc] initWithPath:@"" encryptionKey:self.encryptionKey],
                 @"A path is mandatory");
}

- (void)testInitWithNotValidPathSucceeds
{
    XCTAssertNotNil([[CDTBlobEncryptedData alloc] initWithPath:@"///This is not a path"
                                                 encryptionKey:self.encryptionKey],
                    @"Any string is valid as long as it is not empty");
}

- (void)testInitWithEncryptionKeyEqualToNilFails
{
    XCTAssertNil(
        [[CDTBlobEncryptedData alloc] initWithPath:self.pathToNonExistingFile encryptionKey:nil],
        @"An encryption key is mandatory");
}

- (void)testDataWithErrorFailsIfBlobIsOpen
{
    [self.blobForNotEmptyFile openForWriting];

    NSError *error = nil;
    NSData *data = [self.blobForNotEmptyFile dataWithError:&error];

    XCTAssertNil(data, @"Blob can not be read if it is open");
    XCTAssertNotNil(error, @"An error is expected in this case");
}

- (void)testDataWithErrorFailsIfFileDoesNotExist
{
    NSError *error = nil;
    NSData *data = [self.blobForNotPrexistingFile dataWithError:&error];

    XCTAssertNil(data, @"No data to read if file does not exist");
    XCTAssertNotNil(error, @"An error must be informed");
}

- (void)testDataWithErrorFailsIfFileDoesNotHaveTheMinimumSize
{
    NSData *fileData =
        [self.headerData subdataWithRange:NSMakeRange(0, self.headerData.length - 1)];
    [fileData writeToFile:self.pathToNotEmptyFile atomically:YES];

    NSError *error = nil;
    NSData *data = [self.blobForNotEmptyFile dataWithError:&error];

    XCTAssertNil(data, @"Data is not encrypted or is corrupted");
    XCTAssertTrue(error && [error.domain isEqualToString:CDTBlobEncryptedDataErrorDomain] &&
                      (error.code == CDTBlobEncryptedDataErrorFileTooSmall),
                  @"In this situation the expected error is: (%@, %li)",
                  CDTBlobEncryptedDataErrorDomain, (long)CDTBlobEncryptedDataErrorFileTooSmall);
}

- (void)testDataWithErrorFailsIfFileStartsWithVersion0
{
    NSMutableData *fileData = [NSMutableData dataWithData:self.headerData];

    CDTBLOBENCRYPTEDDATA_VERSION_TYPE wrongVersion = 0;
    [fileData replaceBytesInRange:NSMakeRange(CDTBLOBENCRYPTEDDATA_VERSION_LOCATION,
                                              sizeof(CDTBLOBENCRYPTEDDATA_VERSION_TYPE))
                        withBytes:&wrongVersion];

    [fileData writeToFile:self.pathToNotEmptyFile atomically:YES];

    NSError *error = nil;
    NSData *data = [self.blobForNotEmptyFile dataWithError:&error];

    XCTAssertNil(data, @"Data is not encrypted, is corrupted or the version is wrong");
    XCTAssertTrue(error && [error.domain isEqualToString:CDTBlobEncryptedDataErrorDomain] &&
                      (error.code == CDTBlobEncryptedDataErrorWrongVersion),
                  @"In this situation the expected error is: (%@, %li)",
                  CDTBlobEncryptedDataErrorDomain, (long)CDTBlobEncryptedDataErrorWrongVersion);
}

- (void)testDataWithErrorFailsIfFileDoesNotStartWithCorrectVersion
{
    NSMutableData *fileData = [NSMutableData dataWithData:self.headerData];

    CDTBLOBENCRYPTEDDATA_VERSION_TYPE wrongVersion = (CDTBLOBENCRYPTEDDATA_VERSION_VALUE + 1);
    [fileData replaceBytesInRange:NSMakeRange(CDTBLOBENCRYPTEDDATA_VERSION_LOCATION,
                                              sizeof(CDTBLOBENCRYPTEDDATA_VERSION_TYPE))
                        withBytes:&wrongVersion];

    [fileData writeToFile:self.pathToNotEmptyFile atomically:YES];

    NSError *error = nil;
    NSData *data = [self.blobForNotEmptyFile dataWithError:&error];

    XCTAssertNil(data, @"Data is not encrypted, is corrupted or the version is wrong");
    XCTAssertTrue(error && [error.domain isEqualToString:CDTBlobEncryptedDataErrorDomain] &&
                      (error.code == CDTBlobEncryptedDataErrorWrongVersion),
                  @"In this situation the expected error is: (%@, %li)",
                  CDTBlobEncryptedDataErrorDomain, (long)CDTBlobEncryptedDataErrorWrongVersion);
}

- (void)testDataWithErrorReturnsEmptyIfThereIsNotEncryptedData
{
    [self.headerData writeToFile:self.pathToNotEmptyFile atomically:YES];

    NSError *error = nil;
    NSData *data = [self.blobForNotEmptyFile dataWithError:&error];

    XCTAssertTrue(data && (data.length == 0),
                  @"It is OK is there is not encrypted data but it has to return an empty buffer");
    XCTAssertNil(error, @"No error to report");
}

- (void)testDataWithErrorReturnsExpectedData
{
    NSError *error = nil;
    NSData *data = [self.blobForNotEmptyFile dataWithError:&error];

    XCTAssertEqualObjects(data, self.plainData, @"Unexpected result");
    XCTAssertNil(error, @"No error to report");
}

- (void)testInputStreamWithOutputLengthFailsIfBlobIsOpen
{
    [self.blobForNotEmptyFile openForWriting];

    UInt64 length = 0;
    XCTAssertNil([self.blobForNotEmptyFile inputStreamWithOutputLength:&length],
                 @"Close the blob in order to create an input stream bound to the same file");
}

- (void)testInputStreamWithOutputLengthFailsIfFileDoesNotExist
{
    UInt64 length = 0;
    XCTAssertNil([self.blobForNotPrexistingFile inputStreamWithOutputLength:&length],
                 @"File must exist in order to create an input stream");
}

- (void)testInputStreamWithOutputLengthFailsIfFileDoesNotExistEvenIfIDoNotGetTheLength
{
    XCTAssertNil([self.blobForNotPrexistingFile inputStreamWithOutputLength:nil],
                 @"File must exist in order to create an input stream");
}

- (void)testWriteEntireBlobWithDataFailsIfBlobIsOpen
{
    [self.blobForNotEmptyFile openForWriting];

    NSError *error = nil;
    BOOL success =
        [self.blobForNotEmptyFile writeEntireBlobWithData:self.otherPlainData error:&error];

    XCTAssertFalse(success, @"Close the blob in order to overwrite it");
    XCTAssertNotNil(error, @"An error is expected in this situation");
}

- (void)testWriteEntireBlobWithDataSucceedsIfFileExists
{
    NSError *error = nil;
    BOOL success =
        [self.blobForNotEmptyFile writeEntireBlobWithData:self.otherPlainData error:&error];

    XCTAssertTrue(success, @"The previous data will be overwritten with the next one");
    XCTAssertNil(error, @"No error to report");
}

- (void)testWriteEntireBlobWithDataSucceedsIfFileDoesNotExist
{
    NSError *error = nil;
    BOOL success =
        [self.blobForNotPrexistingFile writeEntireBlobWithData:self.plainData error:&error];

    XCTAssertTrue(success, @"A new file will be created");
    XCTAssertNil(error, @"No error to report");
}

- (void)testWriteEntireBlobWithDataFailsIfDataIsNil
{
    NSError *error = nil;
    BOOL success = [self.blobForNotEmptyFile writeEntireBlobWithData:nil error:&error];

    XCTAssertFalse(success, @"Provide some data to create the blob");
    XCTAssertTrue(error && [error.domain isEqualToString:CDTBlobEncryptedDataErrorDomain] &&
                      error.code == CDTBlobEncryptedDataErrorNoDataProvided,
                  @"In this situation the expected error is: (%@, %li)",
                  CDTBlobEncryptedDataErrorDomain, (long)CDTBlobEncryptedDataErrorNoDataProvided);
}

- (void)testWriteEntireBlobWithDataSucceedsIfDataIsEmpty
{
    NSError *error = nil;
    BOOL success =
        [self.blobForNotPrexistingFile writeEntireBlobWithData:[NSData data] error:&error];

    XCTAssertTrue(success, @"A new file will be created");
    XCTAssertNil(error, @"No error to report");
}

- (void)testWriteEntireBlobWithDataCreatesFileWithExpectedData
{
    [self.blobForNotPrexistingFile writeEntireBlobWithData:self.plainData error:nil];

    NSData *fileData = [NSData dataWithContentsOfFile:self.pathToNonExistingFile];

    XCTAssertEqualObjects(fileData, self.headerPlusEncryptedData, @"Unexpected result");
}

- (void)testwriteEntireBlobWithEmptyDataCreatesFileWithExpectedData
{
    [self.blobForNotPrexistingFile writeEntireBlobWithData:[NSData data] error:nil];

    NSData *fileData = [NSData dataWithContentsOfFile:self.pathToNonExistingFile];

    XCTAssertEqualObjects(fileData, self.headerData, @"Unexpected result");
}

- (void)testWriteEntireBlobWithDataOverwritesThePreviousContent
{
    [self.blobForNotEmptyFile writeEntireBlobWithData:self.otherPlainData error:nil];

    NSData *fileData = [NSData dataWithContentsOfFile:self.pathToNotEmptyFile];

    NSMutableData *expectedData = [NSMutableData dataWithData:self.headerData];
    [expectedData appendData:self.otherEncryptedData];

    XCTAssertEqualObjects(fileData, expectedData, @"Unexpected result");
}

- (void)testWriteEntireBlobWithDataGeneratesDifferentFileDatas
{
    [self.blobForNotPrexistingFile writeEntireBlobWithData:self.plainData error:nil];
    NSData *fileData = [NSData dataWithContentsOfFile:self.pathToNonExistingFile];

    self.blobForNotPrexistingFile.iv = self.otherIVData;

    [self.blobForNotPrexistingFile writeEntireBlobWithData:self.plainData error:nil];
    NSData *otherFileData = [NSData dataWithContentsOfFile:self.pathToNonExistingFile];

    XCTAssertNotEqualObjects(fileData, otherFileData,
                             @"Different IVs should generate different encrypted data");
}

- (void)testOpenForWritingSucceedsIfFileDoesNotExist
{
    XCTAssertTrue(
        [self.blobForNotPrexistingFile openForWriting],
        @"It does not matter if the file does not exist, it will be created before opening it");
}

- (void)testOpenForWritingSucceedsIfFileExists
{
    XCTAssertTrue([self.blobForNotEmptyFile openForWriting],
                  @"If the file exists, we should be able to open it");
}

- (void)testOpenForWritingFailsIfPathIsNotValid
{
    CDTBlobEncryptedData *blob = [[CDTBlobEncryptedData alloc] initWithPath:@"///This is not a path"
                                                              encryptionKey:self.encryptionKey];

    XCTAssertFalse([blob openForWriting], @"It should fail if the path is not valid");
}

- (void)testOpenForWritingCreatesFileOnlyWithHeader
{
    [self.blobForNotPrexistingFile openForWriting];

    BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:self.pathToNonExistingFile];
    NSData *fileData = [NSData dataWithContentsOfFile:self.pathToNonExistingFile];

    XCTAssertTrue(fileExists, @"A file is created after opening the blob");
    XCTAssertEqualObjects(fileData, self.headerData,
                          @"The only content in the file should be the header");
}

- (void)testOpenForWritingSucceedsIfAlreadyOpen
{
    [self.blobForNotEmptyFile openForWriting];

    XCTAssertTrue(
        [self.blobForNotEmptyFile openForWriting],
        @"If the blob is already opened, open it again let the file open, thefore it succeeds");
}

- (void)testOpenForWritingClearTheContentOfTheFile
{
    [self.blobForNotEmptyFile openForWriting];

    NSData *fileData = [NSData dataWithContentsOfFile:self.pathToNotEmptyFile];

    XCTAssertEqualObjects(fileData, self.headerData,
                          @"The only content in the file should be the header");
}

- (void)testOpenForWritingDoesNotClearTheContentOfTheFileIfItIsAlreadyOpen
{
    [self.blobForNotPrexistingFile openForWriting];
    [self.blobForNotPrexistingFile appendData:self.plainData];

    [self.blobForNotPrexistingFile openForWriting];

    [self.blobForNotPrexistingFile close];

    NSData *fileData = [NSData dataWithContentsOfFile:self.pathToNonExistingFile];

    XCTAssertEqualObjects(fileData, self.headerPlusEncryptedData,
                          @"If it is already open, do not clear it");
}

- (void)testOpenForWritingSucceedsAfterClosingBlob
{
    [self.blobForNotEmptyFile openForWriting];
    [self.blobForNotEmptyFile close];

    XCTAssertTrue([self.blobForNotEmptyFile openForWriting],
                  @"As long as the file still exists, we should be able to open it again");
}

- (void)testBlobIsNotOpenAfterCreatingIt
{
    XCTAssertFalse([self.blobForNotEmptyFile isBlobOpenForWriting],
                   @"After init, blob is not open");
}

- (void)testBlobIsOpenAfterOpeningIt
{
    [self.blobForNotEmptyFile openForWriting];

    XCTAssertTrue([self.blobForNotEmptyFile isBlobOpenForWriting], @"Obviously, it is open");
}

- (void)testBlobIsNotOpenAfterClosingIt
{
    [self.blobForNotEmptyFile openForWriting];
    [self.blobForNotEmptyFile close];

    XCTAssertFalse([self.blobForNotEmptyFile isBlobOpenForWriting], @"Obviously, it is closed");
}

- (void)testAppendDataFailsIfBlobIsNotOpen
{
    XCTAssertFalse([self.blobForNotEmptyFile appendData:self.plainData],
                   @"Open blob before adding data");
}

- (void)testAppendDataFailsIfDataIsNil
{
    [self.blobForNotEmptyFile openForWriting];

    XCTAssertFalse([self.blobForNotEmptyFile appendData:nil],
                   @"It should fail if there is no data to add");
}

- (void)testAppendDataDoesNotIncreasesTheSizeOfTheFile
{
    [self.blobForNotEmptyFile openForWriting];

    NSData *fileData = [NSData dataWithContentsOfFile:self.pathToNotEmptyFile];
    NSUInteger previousFileDataLength = fileData.length;

    [self.blobForNotEmptyFile appendData:self.otherPlainData];

    fileData = [NSData dataWithContentsOfFile:self.pathToNotEmptyFile];

    XCTAssertEqual(fileData.length, previousFileDataLength,
                   @"'addData:' does not update the file, 'closeBlob' does it");
}

- (void)testCloseBlobWithoutAddingDataGeneratesOnlyAHeader
{
    [self.blobForNotEmptyFile openForWriting];
    [self.blobForNotEmptyFile close];

    NSData *fileData = [NSData dataWithContentsOfFile:self.pathToNotEmptyFile];

    XCTAssertEqualObjects(fileData, self.headerData, @"Unexpected result");
}

- (void)testAppendDataOverwritesThePreviousContent
{
    [self.blobForNotEmptyFile openForWriting];
    [self.blobForNotEmptyFile appendData:self.otherPlainData];
    [self.blobForNotEmptyFile close];

    NSMutableData *expectedData = [NSMutableData dataWithData:self.headerData];
    [expectedData appendData:self.otherEncryptedData];

    NSData *fileData = [NSData dataWithContentsOfFile:self.pathToNotEmptyFile];

    XCTAssertEqualObjects(fileData, expectedData, @"Only the added data should be in the file");
}

- (void)testCloseBlobGeneratesDifferentFileDatas
{
    [self.blobForNotPrexistingFile openForWriting];
    [self.blobForNotPrexistingFile appendData:self.plainData];
    [self.blobForNotPrexistingFile close];
    NSData *fileData = [NSData dataWithContentsOfFile:self.pathToNonExistingFile];

    self.blobForNotPrexistingFile.iv = self.otherIVData;

    [self.blobForNotPrexistingFile openForWriting];
    [self.blobForNotPrexistingFile appendData:self.plainData];
    [self.blobForNotPrexistingFile close];
    NSData *otherFileData = [NSData dataWithContentsOfFile:self.pathToNonExistingFile];

    XCTAssertNotEqualObjects(fileData, otherFileData,
                             @"Different IVs should generate different encrypted data");
}

- (void)testOpenBlobTwiceDoesNotChangeTheIV
{
    [self.blobForNotPrexistingFile openForWriting];

    self.blobForNotPrexistingFile.iv = self.otherIVData;
    [self.blobForNotPrexistingFile openForWriting];

    [self.blobForNotPrexistingFile appendData:self.plainData];
    [self.blobForNotPrexistingFile close];

    NSData *fileData = [NSData dataWithContentsOfFile:self.pathToNonExistingFile];

    XCTAssertEqualObjects(
        fileData, self.headerPlusEncryptedData,
        @"Once the blob is open, the IV does not change until it is closed and open again ");
}

- (void)testFileCreatedAfterOpeningABlobIsNotDeletedAfterClosingEvenIfNoDataIsAdded
{
    [self.blobForNotPrexistingFile openForWriting];
    [self.blobForNotPrexistingFile close];

    XCTAssertTrue([[NSFileManager defaultManager] fileExistsAtPath:self.pathToNonExistingFile],
                  @"The blob creates a file, it is user responsability to delete it");
}

@end

@implementation CDTBlobCustomEncryptedData

#pragma mark - Init object
- (instancetype)initWithPath:(NSString *)path encryptionKey:(CDTEncryptionKey *)encryptionKey
{
    return [self initWithPath:path encryptionKey:encryptionKey iv:nil];
}

- (instancetype)initWithPath:(NSString *)path
               encryptionKey:(CDTEncryptionKey *)encryptionKey
                          iv:(NSData *)iv
{
    self = [super initWithPath:path encryptionKey:encryptionKey];
    if (self) {
        _iv = iv;
    }

    return self;
}

#pragma mark - CDTBlobEncryptedData+Internal methods
- (NSData *)generateAESIv { return (self.iv ? self.iv : [super generateAESIv]); }
@end

redpajama_set_name: RedPajamaGithub


text:
Dilek Serbest is a Turkish actress and model. She is best known for portraying the role of "İzadora" in the historical drama series Diriliş: Ertuğrul. She also portrayed the role of "Era" in the historical film Fetih 1453. She has also appeared in various movies and TV shows including Yarım Elma, G.O.R.A, Yarım Elma and Kaybolan Yıllar.

Biography
Dilek Serbest started as a model and represented various brands such as Roman, Derishow, Arzu Kaprol and Loft. She also appeared in music videos for Teoman, Ege and Levent Yüksel.  Serbest made her film debut in the science fiction comedy G.O.R.A in 2003 and acted in the horror film Büyü and Tramvay. In 2012, she played Era in the epic film Fetih 1453.

Filmography
Yarım Elma (2002)
G.O.R.A (2003)
Büyü (2004)
Kaybolan Yıllar (2006)
Tramvay (2006)
Gurbet Yolcuları (2007)
Dedektif Biraderler (2008)
Şüphe (2010)
''gümüş
Fetih 1453 (2012)
Kara Para Aşk (2014)
Diriliş: Ertuğrul (2014) (season 1)
Erkenci Kuş (2019)

References

External links

1981 births
Living people
Actresses from İzmir
Turkish film actresses
Turkish television actresses
Turkish female models

redpajama_set_name: RedPajamaWikipedia


Sometimes Life Succs, But It's a Good Thing!
I had a long, quiet trip to a commercial cactus and succulent grower recently. Succulents are one of my favorite things in life! I can't explain it, but sometimes they are so beautiful I tear up.
Having a large family, growing business, farm, and home schooling, rarely do I get that much quiet contemplation time, so along the way I started thinking, "If I could turn back time, what would I change? How far would I go back? What would be the consequences?"
I guess I was thinking of this because I am at an age now where you really begin to see the fruits of your labor, the rewards for your sacrifices, and the difference between the way things turned out and the way you thought they would turn out.
Sometimes there are no fruits to your labor, no rewards for your sacrifices, and a very different world to the one you had in your head.
What would have happened if I had stayed on my career path in technology and sales? I know I wouldn't be worried about my Kitchen Aid mixer breaking or if I could build a commercial kitchen here on the farm. In the early 90s, I was bringing in almost $4k a month plus bonuses. But I became pregnant with my first child and I couldn't bear to leave her in a daycare, so I became a stay-at-home-mom.
We were broke. We were very, very, very broke. My husband at that time spent all our money on food and alcohol, going out with his friends, and his hobbies. I would go on to give him 2 more children and 10 years of my life before he left and never came back. He left me with a newborn, no electric, no phone, no car, and no money. He also took the two older girls, thinking he would be awarded alimony and child support but quickly brought them back when the court ordered the children be given full custody to me.
Those were heartbreaking times. The girls and I struggled with sadness, grief, rejection, and poverty. But out of that poverty came a rising phoenix, a whoopie pie, strawberry shortcake, brownie, and cookie phoenix! I baked our way out of starvation, and it has been something I could fall back on throughout the years.
Meeting my "new" husband was sheer luck. I had made enough money to start a marketing company and shared an office with a friend. We had trouble with some teenagers breaking into cars and called the police. Officer Intense (his nickname) showed up and told me I could do whatever I wanted and he wouldn't arrest me. A man with a promise of freedom AND protection is a man you don't let get away! He has protected us ever since.
So at would point would I go back and what would I change? I sure would like a lot less heartache with the first husband. But I got myself three beautiful and smart daughters from the deal. I could've just stayed single and eventually built up my business and bought a farm myself, but I wouldn't have gotten my two boys and protective hubby. I definitely would've done more on the farm while I was younger. The aches and pains of getting older really catch up with you before ya know it!
What would you change? Would you have stayed single longer, saved more money, taken better care of your health, had more or less children? We can all learn from one another, so feel free to let it flow!
Unfortunately I think many of us get stuck in certain places in our life, and some of us are lucky enough to work ourselves into a better situation.
Congratulations to you for having the grit and determination to overcome.
I have certainly been more lucky than good in more situations than I can count , but as a good friend says, you make your own luck most of the time. But you can never underestimate the importance of a helping hand.
Thank you for your story, look forward to seeing your posts.
ReSteeming and Following you now.
I love that point about making your own luck! They say that success is when preparation and oppurtunity meet, so I'd say making your own luck is right!
Your article is, at the same time, inspiring and beautiful. I'm in a somewhat similar situation, where everything seems to be on me. But I have a beautiful family that is with me and for which I would do anything. There are times when I thought that maybe I should have left my country at a more favorable time, when I was younger. But when I see the beauty of what surrounds me, so hidden by, so unnoticed, it gives me hope to continue. As gives me it your article, so aesthetically provocative. Thanks for sharing.
Stay strong friend. Sometimes there is strength in looking back and seeing that whatever choice we made, theres always a way to make things better, even as we grow older. Friends and family are important. I truly believe that simple pleasures are life's greatest treasures!
Thanks for reading and great comment!
None of us can do anything differently, except with hindsight. Wisdom and skill are the positive benefits of sticking with our choices, whether they were good or bad ones. It's good to see someone work hard to overcome adversity and succeed. Love your plants, you have great taste.
Wisdom is definitely earned! And thanks, I love those little guys and cant wait to see how many i can propogate from them.


Beautiful retail space ranging from 300 sqft to 2,400 sqft located on Main Street in downtown Springfield. Benefit from heavy foot traffic and house your business in the center of town!
Extremely visible and well located Central Business District office opportunities available on the entire Main Street block from Harrison Place to Court Street.
Retail and office space available in Johnson's Bookstore building, built in 1861. MGM casino scheduled to open in 2018, space is going fast - Lease now!
The region's retail center, businesses are booming in North Brownsville where Sunrise Plaza is located. Call now regarding space available for lease in this beautiful shopping center.
Office/Retail Complex with relaxing courtyard setting. Rent is based on USABLE square footage which saves 15%-20% over what the competition charges.
Located in the heart of Harrisonville, MO, Cass County Seat. Four retail spaces available! This is the perfect location for your small business. Call us now for more information.
FANTASTIC opportunity in downtown Greenville. Entire second floor of the historic Henson building on the corner of Wesley and Lee.
Town & Country Shopping Center has space available for lease. Restaurant, end cap & more! This is one of the busiest centers in Lincolnton!


text:
Save listing in PDF
Moab, Utah
www.nps.gov/cany
www.nps.gov/cany, 435-719-2100
Visit their website for current entrance fees.
The Colorado River and the Green River flow together in the heart of Canyonlands, creating a rippled landscape with deep red-walled canyons, arches, buttes, spires and innumerable other spectacular rock formations. Canyonlands is so large and so diverse that it is carved naturally into three distinctive districts: Island in the Sky, The Maze and The Needles. While they adjoin each other, each area must be reached from different entry points. The travel time between each of the three districts is several hours.
Canyonlands is open year-round, 24 hours a day. Visitor center seasons and hours may vary. Check the park's official website for the most current information. All visitor centers are closed Thanksgiving Day, Christmas Day and New Year's Day. Travel to Canyonlands usually requires a car. Once in the park, each district requires some boating, hiking or four-wheel driving to see the area's attractions. Food, gas, lodging and similar services are not available. To truly appreciate this geologic fantasyland, allow four or five days to explore all three districts. Leave Moab with a full tank of gas, food, lots of water, a spare tire and sun protection. There are no restaurants or hotel accommodations in the park. Canyon country is not a friend to cell phones. Do not rely on GPS units to guide you in the park. Once you enter Canyonlands, cellular service diminishes greatly, especially in the canyons (and away from the pavement). Pets are not allowed on any trails. Leashed and restrained pets may accompany visitors in the campground, at overlooks and at pullouts along the paved scenic drives.
Island in the Sky
A wide, high plateau with commanding views across many miles of deep red-rock canyons in all directions. North on US Hwy 191, ten miles to Utah Hwy 313 then southwest 22 miles to the visitor center. Island in the Sky has about 20 miles of paved highway and some gravel roads with several viewpoints. It is the most accessible district and the easiest to visit in a short period of time. There are many hiking trails, including a path to Upheaval Dome, a weird moonlike crater with peaks springing from its center. Firewood and water are not available at campsites.
The Maze, west of the rivers, is the wildest and most remote section of the national park. This most inaccessible district of Canyonlands requires a four-wheel-drive vehicle, time and self-sufficiency. The Hans Flat Ranger Station in The Maze is a three-hour drive west from Moab via Interstate 70. From Interstate 70 take Utah Hwy 24 south along unpaved roads, starting between Hanksville and Green River, across relatively flat and completely uninhabited terrain to Hans Flat Ranger Station. Remember, the roads are passable only in a four-wheel-drive vehicle. No paved roads. There are no amenities, food or gas.
The Needles
The Needles, in the southeast region of the park, is the heart of rock country and offers many opportunities for exploring. 76 miles from Moab, south on US Hwy 191, 40 miles to Utah Hwy 211, then 35 miles west to the park entrance and visitor center. Utah Hwy 211 ends in The Needles District and is the only paved road leading in and out of it. The Needles District has only eight miles of roads accessible by foot, four-wheel-drive vehicles or mountain bikes. Note the petroglyphs on the rock face at Newspaper Rock on the road into The Needles District.
Backcountry Permits
Activities requiring a backcountry permit include backpacking, four-wheel-drive and mountain-bike camping, horseback riding, river trips and four-wheel-drive day use. Permits (other than river) are issued seven days a week at district visitor centers. Permits can be reserved in advance online at www.canypermits.nps.gov. Reservations must be made no more than four months and no fewer than two days prior to the permit start date. Walk-in permits are only available the day before or the day of a trip. Permits are issued up to one hour before the close of business each day.
Camping Fees
Sites at Willow Flat Campground at Island in the Sky are $15/night. Sites at Squaw Flat Campground in The Needles are $20/night. All sites are first-come, first-served.
The National Park Service measured the interior of Canyonlands National Park and found it to be one of the quietest places in the United States.
An authentically dark night The International Dark-Sky Association has granted Gold-Tier International Dark Sky Park status to Canyonlands National Park, an honor reserved for the darkest of dark skies and the most stunning of starscapes.
Commercial Tours NAVTEC Expeditions offers front and backcountry tours for all three districts of Canyonlands.
435-259-7983, www.navtec.com.
GyPSy Guide, Canyonlands National Park's driving tour app, might just be your perfect companion as you explore. It plays commentary automatically as you drive so you won't miss a thing.
www.gypsyguide.com.

redpajama_set_name: RedPajamaCommonCrawl


text:
Q: Pyomo energy storage system dispatch optimization I'm trying to create a model optimization for a energy storage system using pyomo. Using the demand in kWh from an household and the electricity prices, I would like to minimize the cost charging and discharging the battery at the right time. I already have a working model for 1 year of data and the model is able to find an optimal solution (see code below). However, when I try find a model for only three months (let's say from October to December), pyomo returns with a termination condition "unbound" but I can't figure out why.
Model for 1 year of data:
#Battery parameters
battery_capacity = 252
total_energy = 13.1
usable_energy = 12.4
nominal_voltage = 51.8
ratio = total_energy/usable_energy
power = usable_energy / ratio
nominal_current = usable_energy / nominal_voltage * 1000
recharging_hours = battery_capacity/nominal_current
battery_level_threshold = 0

model = pyo.ConcreteModel()
#Set time period
model.T = pyo.Set(initialize=pyo.RangeSet(len(df_2021)),ordered=True)

#PARAMETERS:
model.b_efficiency  = pyo.Param(initialize=0.9)
model.b_min_cap = pyo.Param(initialize=0)
model.b_max_cap = pyo.Param(initialize=12.4)
model.b_charge_power = pyo.Param(initialize=power)
model.b_discharge_power = pyo.Param(initialize=power)

model.spot_prices = pyo.Param(model.T,initialize=dict(enumerate(df_2021["Price/kWh"],1)),within=pyo.Any)
model.demand = pyo.Param(model.T, initialize=dict(enumerate(df_2021["Demand"],1)),within=pyo.Any)
#Variables : also the variable has to  be indexed with the time T
model.b_soc = pyo.Var(model.T, domain = pyo.NonNegativeReals, bounds = (model.b_min_cap, model.b_max_cap))
model.b_discharge = pyo.Var(model.T, domain = pyo.NonNegativeReals)
model.b_charge = pyo.Var(model.T, domain = pyo.NonNegativeReals)
model.elect_purchased = pyo.Var(model.T, domain = pyo.NonNegativeReals)

#CONSTRAINTS
#Purchase constraint
def purchase_constraint(model,t):
    return model.elect_purchased[t] >= model.demand[t] - model.b_discharge[t] + model.b_charge[t]

#State of charge constraint
def soc_constraint(model,t):
    if t == model.T.first():
        return model.b_soc[t] == model.b_max_cap / 2 #- model.b_discharge[t] + model.b_charge[t]
    else:
        return model.b_soc[t] == model.b_soc[t-1] - model.b_discharge[t-1] + model.b_charge[t-1]
#Discharge and charge constraints
def discharge_constraint_1(model,t):
    """ Maximum discharge rate within a single hour """
    return model.b_discharge[t] <= model.b_discharge_power
def discharge_constraint_2(model,t):

    """ Sets the maximum energy available to be discharged as the SOC - minimum SOC """
    return model.b_discharge[t] <= model.b_soc[t] - model.b_min_cap

def charge_constraint_1(model,t):
    """ Maximum charge rate within a single hour """
    return model.b_charge[t] <= model.b_charge_power

def charge_constraint_2(model,t):

    """ Sets the maximum energy available to be cahrge as the SOC max """
    return model.b_charge[t]  <= model.b_max_cap - model.b_soc[t]

model.purchase_c = pyo.Constraint(model.T, rule = purchase_constraint)
model.soc_c = pyo.Constraint(model.T, rule = soc_constraint)

model.discharge_c1 = pyo.Constraint(model.T,rule = discharge_constraint_1)
model.discharge_c2 = pyo.Constraint(model.T,rule = discharge_constraint_2)
model.charge_c1 = pyo.Constraint(model.T,rule = charge_constraint_1)
model.charge_c2 = pyo.Constraint(model.T,rule = charge_constraint_2)

#OBJECTIVE
expr = sum(model.elect_purchased[t] * model.spot_prices[t] for t in model.T)
model.objective = pyo.Objective(rule = expr, sense = pyo.minimize)
opt = pyo.SolverFactory('cbc',executable='/usr/bin/cbc')
results = opt.solve(model)
results.write()

Result 1 year data
The optimal solution is found
However, when I change the dataset, using the SAME model structure and constraints, pyomo doesn't find a solution.
Model for 3 months:
#Battery parameters
battery_capacity = 252
total_energy = 13.1
usable_energy = 12.4
nominal_voltage = 51.8
ratio = total_energy/usable_energy
power = usable_energy / ratio
nominal_current = usable_energy / nominal_voltage * 1000
recharging_hours = battery_capacity/nominal_current
battery_level_threshold = 0

model = pyo.ConcreteModel()
#Set time period
model.T = pyo.Set(initialize=pyo.RangeSet(len(df_2021)),ordered=True)

#PARAMETERS:
model.b_efficiency  = pyo.Param(initialize=0.9)
model.b_min_cap = pyo.Param(initialize=0)
model.b_max_cap = pyo.Param(initialize=12.4)
model.b_charge_power = pyo.Param(initialize=power)
model.b_discharge_power = pyo.Param(initialize=power)

model.spot_prices = pyo.Param(model.T,initialize=dict(enumerate(df_2021["Price/kWh"],1)),within=pyo.Any)
model.demand = pyo.Param(model.T, initialize=dict(enumerate(df_2021["Demand"],1)),within=pyo.Any)
#Variables : also the variable has to  be indexed with the time T
model.b_soc = pyo.Var(model.T, domain = pyo.NonNegativeReals, bounds = (model.b_min_cap, model.b_max_cap))
model.b_discharge = pyo.Var(model.T, domain = pyo.NonNegativeReals)
model.b_charge = pyo.Var(model.T, domain = pyo.NonNegativeReals)
model.elect_purchased = pyo.Var(model.T, domain = pyo.NonNegativeReals)

#CONSTRAINTS
#Purchase constraint
def purchase_constraint(model,t):
    return model.elect_purchased[t] >= model.demand[t] - model.b_discharge[t] + model.b_charge[t]

#State of charge constraint
def soc_constraint(model,t):
    if t == model.T.first():
        return model.b_soc[t] == model.b_max_cap / 2 #- model.b_discharge[t] + model.b_charge[t]
    else:
        return model.b_soc[t] == model.b_soc[t-1] - model.b_discharge[t-1] + model.b_charge[t-1]
#Discharge and charge constraints
def discharge_constraint_1(model,t):
    """ Maximum discharge rate within a single hour """
    return model.b_discharge[t] <= model.b_discharge_power
def discharge_constraint_2(model,t):

    """ Sets the maximum energy available to be discharged as the SOC - minimum SOC """
    return model.b_discharge[t] <= model.b_soc[t] - model.b_min_cap

def charge_constraint_1(model,t):
    """ Maximum charge rate within a single hour """
    return model.b_charge[t] <= model.b_charge_power

def charge_constraint_2(model,t):

    """ Sets the maximum energy available to be cahrge as the SOC max """
    return model.b_charge[t]  <= model.b_max_cap - model.b_soc[t]

model.purchase_c = pyo.Constraint(model.T, rule = purchase_constraint)
model.soc_c = pyo.Constraint(model.T, rule = soc_constraint)

model.discharge_c1 = pyo.Constraint(model.T,rule = discharge_constraint_1)
model.discharge_c2 = pyo.Constraint(model.T,rule = discharge_constraint_2)
model.charge_c1 = pyo.Constraint(model.T,rule = charge_constraint_1)
model.charge_c2 = pyo.Constraint(model.T,rule = charge_constraint_2)

#OBJECTIVE
expr = sum(model.elect_purchased[t] * model.spot_prices[t] for t in model.T)
model.objective = pyo.Objective(rule = expr, sense = pyo.minimize)
opt = pyo.SolverFactory('cbc',executable='/usr/bin/cbc')
results = opt.solv

Pyomo returns:
WARNING: Loading a SolverResults object with a warning status into
    model.name="unknown";
      - termination condition: unbounded
      - message from solver: <undefined>
# ==========================================================
# = Solver Results                                         =
# ==========================================================
# ----------------------------------------------------------
#   Problem Information
# ----------------------------------------------------------
Problem:
- Name: unknown
  Lower bound: None
  Upper bound: inf
  Number of objectives: 1
  Number of constraints: 16993
  Number of variables: 11329
  Number of nonzeros: 2832
  Sense: minimize
# ----------------------------------------------------------
#   Solver Information
# ----------------------------------------------------------
Solver:
- Status: warning
  User time: -1.0
  System time: 0.45
  Wallclock time: 0.58
  Termination condition: unbounded
  Termination message: Model was proven to be unbounded.
  Statistics:
    Branch and bound:
      Number of bounded subproblems: 0
      Number of created subproblems: 0
    Black box:
      Number of iterations: 0
  Error rc: 0
  Time: 0.6151924133300781

Since the only change between the two runs is the length of the dataframe, I don't really know where to look for the error.

A: Given that the model works on some data, but not on an alternate data source, we can obviously focus a bit on the data set (which isn't shown).
We have a huge clue in the error report that the problem is unbounded.  This means that there is nothing to prevent the objective function from running away to infinity, or negative infinity in the case of a minimization problem.  So, let's look at your objective function.  You are:
sum(demand[t] * price[t] for t in T)

The domain of your demand variable is set to non-negative real numbers (good) and price[t] is a parameter read in from data, and you are minimizing.  So the only way this could run away to negative infinity is if there are one (or more) negative prices in your data, which the solver would then act on and demand would be unbounded.
So, comb your data set.  if you are using pandas, just use a logical search for rows where price is < 0, you'll likely find at least one.  Then you'll have to decide if that is a typo or if it is realistic to have a negative price (which could happen in some systems), and if it is legit, you will have to impose some other constraint to limit the model in that situation.

redpajama_set_name: RedPajamaStackExchange


More Sunday street closures are planned to get people out in their neighborhoods for walking and biking. Albemarle Road will be closed on Sunday September 19 from 1-4 p.m. Brandeis Road will be closed on Sunday October 3 from 1-4 p.m.
The NewtonStreets program is sponsored by Bike Newton, the Newton Bicycle/Pedestrian Task Force and the Newton Parks and Recreation Department.


Made from juicy mangoes and fresh ginger. Spread it on toast with lots of French butter. It's an inspired addition to Devonshire teas, bread and butter puddings, jam tarts and sponge cakes. Just as delicious on a cheese sandwich as it is with a spicy Indian curry. Bon appetit!
Mango (56%), sugar, ginger (5.7%), lemon juice.


text:
Q: ltrim doesn't return expected result with slashes i've a problem with "/anystring" and ltrim function in php.
here's my code:
$s = "/ciao/come/va";

$s1 = ltrim($s,'/ciao');

echo $s1;

i want $s1 return "/come/va" but the code always returns "me/va"
I've already test other solution but i need to use ltrim.


"Independence of Korea", "Korea and Koreans", "Emperor's escape: Attempted Assassination", "Rising in Korea, The Fight for Freedom", "Japanese in Korea: Policy of Assimilation…Sever rule alleged", "Discontent in Korea: Agitation renewed…Business suspended", "Crushed Korea…Hopes of Freedom", "Japan in Korea…Imperialistic Military Dominance", and "Mixture of Czarist Russia and Germany…The Korean Language a Crime", and so on.
These were the headlines of major newspapers in Australia and New Zealand in 1919 in the wake of the Korean independence movement and the establishment of the Provisional Government of the Republic of Korea.
Even the contribution to an American daily newspaper by Dr Syngman Rhee, the Secretary of State under the Provisional Government of the Republic of Korea later becoming the first President of South Korea to appeal to American people for their support for the Korean independence was reproduced in the Australian Worker in July 1919.
Also the Sydney Morning Herald reported in the year that "Korea's hope of independence is cherished albeit Japanese oppression, referring Kore to 'the Land of Morning Calm'.
Earlier, most of the mainstream papers around the nation including the Sydney Morning Herald, the AGE and the Daily Telegraph covered the Korea's historic event of the breakout of the independence movement, with the slightly different angles on the movement.
Some newspapers described the Korea's nationwide upheaval as 'disturbance, unrest, trouble, agitation, disorder, riot, revolt, rising', meanwhile most used the term of 'Korea's independence movement against Japanese rule.


What is Pu'er? It is made from sun-dried raw materials of broad leaf species from Yunnan, China, that has undergone an exacting production process. Classified into raw (non-fermented) or ripe (fermented) tea, it is power packed with complex flavours. Pu'er has abundant amounts of antioxidants and aids in weight loss. Like that apple a day which keeps the doctor away, a cup of Pu'er tea helps lower the big C - cholesterol while also aiding digestion.
TEASPEC is not a tea merchant. We are avid collectors and advocates of Pu'er tea. Our teas are aged in Malaysia because it is widely acknowledged that Malaysian aged Pu'er is more sought after over Pu'er stored in China, Hong Kong, Taiwan or elsewhere. This tea has matured like a much older vintage because it has been aged in Malaysia under the most ideal natural environment.
© 2019 TEASPEC. All Right Reserved.


text:
Wioślarstwo na Letnich Igrzyskach Olimpijskich 1960 w Rzymie rozgrywane było w dniach 30 sierpnia - 3 września. Zawody odbyły się w Rzymie. W zawodach wioślarskich wzięło udział 410 zawodników z 33 krajów. Startowali tylko mężczyźni. Rozegrano 7 konkurencji. Polska wywalczyła jeden medal - brązowy w konkurencji jedynek.

Konkurencje

Medaliści

Występy Polaków

Kraje uczestniczące
W zawodach wzięło udział 410 wioślarzy z 33 krajów:

Klasyfikacja medalowa

Bibliografia

Dyscypliny rozgrywane podczas Letnich Igrzysk Olimpijskich 1960
1960


text:
Venture Partner, Flywheel Ventures
Mr. Traylor is an accomplished entrepreneur, professional investor, and former competitive athlete. While at PureColor, Inc. Mr. Traylor led a restart as CEO including raising several million in seed capital and building a veteran team, board and culture. Prior to his role with PureColor, Inc. Mr. Traylor managed Business Development and served as Global Director for Commercial and Institutional Markets at MIOX Corporation, a cleantech water purification company. With MIOX, Chris grew new market sales 100% year over year for three straight years.
Prior to MIOX, Mr. Traylor was a founding member of Flywheel Ventures, a leading venture capital firm based in the Rocky Mountain West. Mr. Traylor was involved with portfolio companies Lingotek, Micromanipulator (parent Astria Semiconductor Holdings acq. by NASDAQ: CSCD) and Tuscany Design Automation (acq. by EPA: DSY).
Currently Chris manages the GAP Fund, a portfolio of startups funded by Flywheel Ventures.
Chris had a stint as a professional athlete with the Seattle Mariners organization and previously competed in major collegiate athletics in the Big XII Conference. Mr. Traylor holds a BS/BA in Management with a concentration in Finance from Kansas State University, and an MBA from the University of New Mexico with concentrations in Management of Technology and Investment Finance.
View Next MentorJohn GrayA leading expert in museum and education tech and innovation
View Previous MentorGail BaralEntrepreneur, business development coach


text:
The PS Vita Multiplayer Experience
June 14, 2019 Simon Plumbe Blog, Headlines 0
When you think about handheld consoles, you rarely think about multiplayer gaming. It's certainly the last thing that springs to mind when discussing the PlayStation Vita. However, it's a more than capable system and has delivered a diverse range of multiplayer experiences to cater for even the most demanding of Vita owners. What may surprise many is that the Vita has been able to offer plenty of options for those eager to test their gaming skills against others in far more ways that you would expect from a portable device…
Normally multiplayer gaming is the reserve of PCs and consoles. Couch co-op multiplayer arcade and sports games have delighted gamers for decades. he plethora of first person shooters are prevalent amongst online gamers eager to prove to their peers who is the top dog. And multiplayer battle arena style games like League Of Legends here have captivated the esports community. At times Vita owners have felt left out from all of these but there's no need to, as there are games out there to satisfy virtually all of these genres and much more besides.
Ad-Hoc Multiplayer
Being a handheld console, it can only be used by one person at a time. That hasn't stopped multiplayer gaming from being a success and we were fortunate that Sony Interactive Entertainment carried over a few of the PSP's design elements over into the Vita. One of the most important is its wi-fi capabilities, more specifically the fact that it can connect to a second PS Vita for ad-hoc (or local) network gaming. While only a limited number of games support this, those that do have managed to deliver some fantastic gaming experiences.
While it works superbly as a single player game, the PS Vita port of Housemarque's PS4 launch title Resogun really comes into its own when played over an ad-hoc connection. While it can be played online, the connection isn't always the greatest but ad-hoc allows for super-fast co-op gameplay, making this already remarkable shoot-em-up even better.
For something a little different, one of my personal favourites is Table Top Racing. A modern take on the Codemasters classic MicroMachines, it's one I play regularly against my wife both at home and when we're traveling away from home. The top down racer has enough variety and tracks to keep anyone coming back for more and it's array of weapon pickups adds that extra competitive touch that is always a winner in multiplayer racers that made the Mario Kart series such a huge success.
Nothing to do with King Arthur and his Knights, but the round table approach to multiplayer games goes right back to the early arcade games. When arcade games were inherently single player, a simple way to generate extra income for arcade operators was to add a two player option but getting players to swap over at the end of each life. In reality this served two purposes. Not only did it make players more competitive and more likely to play the game more than once (to beat each others scores), but were also less likely to last as long in their individual games. If you have to step away from a joystick or controls between lives, it breaks the flow of your game and in turn your concentration. It's a psychological trick but the shorter your game lasts, the more money the arcade can earn once again!
When it comes to home games on the Vita, probably the best of these are Zen Pinball 2 and The Pinball Arcade. While there are plenty of other games offering the same type of multiplayer options, for anyone who was a fan of pinball machines in the arcades, this really brings the true arcade experience into the home, especially if you were ever one for challenging friends in the arcades.
Not satisfied with getting together with your friends? Then online gaming with the Vita is for you. While there aren't as many options as there used to be with servers shutting down, we haven't been short of choice here either. We've had player vs player with the likes of King Of Fighters '97 for those of you with a penchant for beat-em-ups, and the seminal Killzone Mercenary for solo and team based first person shooters (and arguably the best multiplayer experience the PS Vita can offer). Then we have arena based battles with the online side of things in Sword Art Online. This was the last aspect of the game that I tried but found that it extended the game's lifespan incredibly.
Enter The PlayStation TV
What had the potential to boost sales of the PS Vita immensely turned out to be one of Sony's biggest disasters. The PlayStation TV microconsole took the PS Vita and turned it into a small form factor console with HDMI output, an ethernet connection, kept compatability with most software that would run on the PS Vita and added support for up to four controllers. On paper it should have been a global success. Instead, by marketing it as an accessory for the PS4, not bundling it with a necessary controller, and limiting its compatability it was dead in the water soon after launch.
It was a shame because it opened up new avenues for multiplayer gaming on the PS Vita. The PSTV breathed new life into games that supported it properly, enhancing them visually with the superb 720p output. Many games took advantage of the extra controls offered by the DualShock3 or DualShock4 controllers such as Killzone Mercenary and Minecraft making for a more engaging and user friendly gaming experience. But where games really came into their own were those that offered the chance to play against your friends… on a single console.
Couch Multiplayer Is Here
The PSTV brought couch multiplayer gaming to the PS Vita in a way none of us saw coming. While only a small number of games supported it, some developers took advantage of the fact that the PSTV could handle multiple controllers and built this into their games. So instead of Vita games being single player, we could suddenly play against our friends on a single Vita. The fencing based game Nidhogg allowed two players at the same time, others allowed two or three but the pinnacle for the system pushed the PSTV to its limits and deserves special mention… Spelunky. While the game had a single player mode, in it's multiplayer game mode you could have up to four people playing at the same time on the humble PlayStation TV. If only more people knew about it, maybe the console could have fared better…
PSOne Classics
I can't finish off without talking about the original PlayStation. We have over 150 original PlayStation games available to download from the PlayStation Store that can run on the PS Vita and – in turn – on the PSTV. Many classic PSOne games supported more than one player, notably the Tekken series, and this functionality has remained in the versions downloadable from the Store. Players who purchased these to run them on the PlayStation 3 were already aware of that but now we have the PSTV we too can enjoy the same multiplayer gaming from the comfort of our sofas!
This is really just the tip of the iceberg. There are countless multiplayer games out there available for the PS Vita. We've covered what we think are some of the highlights but let us know what some of your favourites are in the comments below.
PS Vita To The Nintendo Switch – Moving On Or Gaming Partners?
Why PS Vita Digital Games Failed On The High Street
PlayStation Handhelds And The Different Kinds Of Casino Gambling


text:
Modjo is broadcast on
M odjo is a French house/pop musical duo made up of producer Romain Tranchart and vocalist Yann Destagnol (aka Yann Destal). They met in 1998, immediately deciding to form a partnership.
They became known in 2000 with their first release, "Lady (Hear Me Tonight)", a "french-flavour" house track with heavy pop and disco influences, which featured a sample from Chic's "Soup for One". The track became an instant #1 across Europe, and was followed up by other singles "Chillin'", "What I Mean" and "No More Tears". With this last single, they started calling themselves Modjo Band.
After "No More Tears" they started their respective solo careers, with Romain Tranchart remixing songs from various artist like Res ("Golden Boys"), Shaggy ("Sexy Lady"), Mylène Farmer ("California") and post producing the likes of Everynote's "Once Upon A Time". Yann released a very Queen-esque album, reaching some success in France.
Their offical website: http://www.modjo.com/
User-contributed text is available under the Creative Commons By-SA License and may also be available under the GNU FDL.
Source: lastfm
dance, electronic, house, pop
Benjamin Diamond
The Supermen Lovers


 » SMS / SCCM » You're currently reading "Copy and paste for SCCM console"
Finally there has been a free third party to copy and paste collection queries, advertisement, programs and packages in SCCM. This is long overdue and really should be basic functionality in any Microsoft Management Console snap-in. I've tested it out and it works well.
More details and download from http://blogs.microsoft.co.il/blogs/doli/archive/2011/04/27/sccm-copy-and-paste-context-menu-add-on.aspx.


I've been a queen of cheap living for quite some time, not Always out of requirement or need, but more because I believe in adopting variety that is simple, thrifty, and really experiencing a far more straightforward, uncomplicated life. Learn conserve money on fuel whenever you fill up, regardless of What are how to be more frugal? happens to gasoline prices in the foreseeable future and how to lock in the current minimal fuel costs. I do believe talking about income is beneficial to everyone who would like to find out more about it. It shouldn't get in the means of a beautiful dinner using a spouse or irritate your friends but I think we'd possess a more knowlegeable community, when it were less taboo.
Produce some adjustments that are small to money spending practices and you may find that you will have a many more money every month todo more of the entertaining items you'd like to do. You could perhaps find that you benefit from the frugal lifestyle, when you feel about living on which you will need without most of the surplus, good.
Obviously they wished the top for his or her son, not to mention they needed than they had, me to really have a better lifestyle; as having more money nevertheless, they didn't establish better". Drive by walking or cycle: navigating around on your own bike or on foot are definitely transport's environmentally-friendly and most economical modes. I'll also discuss ideas that WOn't merely help you save money, but earn significantly more money. Bottomline is that individuals that are frugal do reach own notch quality things that are top - but these things are well orchestrated, skillfully researched and usually conserve money over the long term.
This hub results in at the least three other subjects - kindness (what direction to go using the cash to spare thanks to frugal living); receiving debt-free (and therefore attention obligations free), and the way to lead less to global warming and pollution and much more to some healthy atmosphere and ecological economy—like, make and work with a solar range; hold garments to dry on a clothes-line.
Easily did not take an economical approach to life, I wouldnot have the ability to have those things AND cut costs. For me personally, having only a little fun-money will be the only means I could remain on track with my goals. Besides existing green, you placed more and can cut costs. Below you may discover all-the data you may ever must conserve money at the grocery store.
To aid us undertake this concern we lay along with Life-Coach and Government Anna Percy-Davis, who's provided us her top tips for sorting our savings out and using control of our money management. The money goes to the restaurant, whether or not it's a line object around the bill, as well as in if the bill was settled in income, the server must give it. Your connection with money is getting with living in the manner of the relationship. One of many easiest strategies to spend less on groceries is always to increase your personal fruit and veggies.
There are currently many ecologically sound possibilities you can make which the bank breaks, as well as in reality, countless green suggestions that are not only more affordable, but can actually help you save money. Although, if sustainability ie the long term could be the purpose, then there's a terrific potential for ultimately being able to create that lifestyle.
My entire life spouse and that I joke about our stirring stories " i.e., of thrift, how we found out a great frugal compromise to how to live more frugally acquire a better package over a required service or how minor he or I'd to spend over a distinct merchandise. They appreciate it and handle their cash properly. An individual that is cheap will share what they have - however, not a cheapo. Approximately living wiser so that you may live the life span you truly want to call home, on the contrary, cheap living is.