• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

Programming |OT| C is better than C++! No, C++ is better than C

wolfmat

Confirmed Asshole
Hey guys. I'm writing a forum application in Rails and I'm stuck on limiting nested quotes.

I'm try to use regex and recursion, going down to each matching tag, counting the levels and if the current level is > max, deleting everything inside of it. Problem is that my regex is only matching the first [ quote ] with the first seen [ /quote ], and not the last as intended.

The regex is just a slight tweak of what was given in the docs of the custom bbcode library I'm using (I know very little about regex, I've tried to learn as much as I can in the past couple days but I'm still stuck). I changed it so it'd include [ quote], [ quote=name] and [ quote=name;222]. Could someone examine my code and let me know what the problem could be? I'd appreciate it lots.

Code:
  def remove_nested_quotes(post_string, max_quotes, count)
    result = post_string.match(/\[quote(:.*)?(?:)?(.*?)(?:)?\](.*?)\[\/quote\1?\]/mi)

    if result.nil?
      return false
    elsif  (count = count+1) > max_quotes
      full_str = result[0]
      offset_beg = result.begin(3)
      offset_end = result.end(3)
      excess_quotes = full_str[offset_beg ..offset_end ]
      new_string = full_str.slice(excess_quotes )
      return new_string
    else
      offset_beg = result.begin(3)
      offset_end = result.end(3)
      full_str = result[0]
      inner_string = full_str[offset_beg..offset_end]
      return remove_nested_quotes(inner_string , max, count)
    end
 end

Not gonna comment on your specific issue, but generally, I recommend http://www.regexr.com/ to people who want to get in touch with regular expressions. Direct visual feedback helps a lot.
 

Big Chungus

Member
Try passing the &format=json argument with your API call. I think the API ignores the HTTP Accept header. It'll result in a big JSON result. You can however control which fields you want to have in your response by passing the field_list argument (see here).

Nice, it worked but when i specify which field I want it just gives me a bunch of extra stuff.

I guess I want the stuff in the results field:

{"error":"OK","limit":1,"offset":0,"number_of_page_results":1,"number_of_total_results":1,"status_code":1,"results":{"name":"Metroid Prime 3: Corruption"},"version":"1.0"}
 

Somnid

Member
That's just a breadth first search isn't it?

@Somnid: I think your skeleton still goes down by depth, only you're adding an entire level before moving down the first element of that level.

If it's fully breadth first maybe this?

Code:
function visit(elements, doFunc){
   while(elements.length > 0){
		var element = elements.shift();
		doFunc(element);
		elements = elements.concat(element.children);
   }
}
 
Anyone familiar with Spring and REST?

This should be a fairly simple exercise, but I'm just missing something. The idea is to use a ready made REST interface in this address in order to offer a similar interface to handle information on games and their ratings.

The relevant classes are:

The controller.
Code:
@RestController
@RequestMapping("games")
public class GameController {
    
    @Autowired
    private GameRestClient gameRestClient;
    
    // posts a new game (doesn't work)
    @RequestMapping(method=RequestMethod.POST)
    public Game postGame(@RequestBody Game game) {  
        return gameRestClient.create(game);
    }
    
    // gets all the games (works)
    @RequestMapping(method=RequestMethod.GET)
    public Collection<Game> listGames() {
        return gameRestClient.findAll();
    }
    
    // gets a game by name (doesn't work)
    @RequestMapping(value="/{name}", method=RequestMethod.GET)
    public Game showGameByName(@PathVariable("name") String name) {       
        return gameRestClient.findByName(name);
    }
    
    // deletes a game (untested)
    @RequestMapping(value="/{name}", method=RequestMethod.DELETE)
    public Game deleteGame(@PathVariable("name") String name) {
        Game game = gameRestClient.findByName(name);
        gameRestClient.deleteByName(name);
        return game;
    }
    
    // I'm not sure quite if this is the correct way to set the URI but it seems to work at least
    @PostConstruct
    public void giveUri() {
        gameRestClient.setUri("http://wepa-scoreservice-heroku.herokuapp.com/games"); 
    }

}

A service using the REST interface of the above mentioned address (using the class RestTemplate for it):
Code:
@Service
public class GameRestClient implements GameService {

    private RestTemplate restTemplate;
    private String uri; 

    public GameRestClient() {
        this.restTemplate = new RestTemplate();
    }

    @Override
    public void setUri(String uri) {
        this.uri = uri;
    }

    @Override
    public Game create(Game game) {
        return restTemplate.postForObject(uri, game, Game.class);
    }

    @Override
    public Game findByName(String name) {      
        return restTemplate.getForObject(uri, Game.class, name);
    }

    @Override
    public void deleteByName(String name) {
        restTemplate.delete(uri, name); // not quite sure if this is right or if I should find the corresponding game first, but that's a smaller problem)
    }

    // this works, the others don't (apart from the setUri method)
    @Override
    public Collection<Game> findAll() {
        return restTemplate.getForObject(uri, List.class);
    }

}

The GET method listGames() in the controller (and thus the findAll() method in the service) seemingly works just fine when I try it on localhost:8080/games. But if I pick any random game and try to see its info (on localhost:8080/games/game'sNameHere), I get a whitelabel error page:
There was an unexpected error (type=Bad Request, status=400).
Could not read JSON: Can not deserialize instance of wad.domain.Game out of START_ARRAY token at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@597b4b9b; line: 1, column: 1]; nested exception is com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of wad.domain.Game out of START_ARRAY token at [Source: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@597b4b9b; line: 1, column: 1]

The tests in the exercise also get error immediately when it tests the POST type method ( postGame(@RequestBody Game game) ). The error is as follows:
NestedServletException: Request processing failed; nested exception is org.springframework.web.client.HttpServerErrorException: 500 Internal Server Error

I really don't have any clue why those errors come. Or yeah, I think I get that the first error comes as it can't parse the JSON, but I really don't understand why it can't be parsed.
Anyone who could help please?

If needed, I can post the stacktrace and the code of the REST interface in the given address.

Sorry if anything's unclear. I'm not sure if I fully understand the assignment myself and it feels like I'm still slightly clueless about web stuff in general.
 

_Isaac

Member
Anyone familiar with Spring and REST?

This should be a fairly simple exercise, but I'm just missing something. The idea is to use a ready made REST interface in this address in order to offer a similar interface to handle information on games and their ratings.

The relevant classes are:

The controller.
Code:
@RestController
@RequestMapping("games")
public class GameController {
    
    @Autowired
    private GameRestClient gameRestClient;
    
    // posts a new game (doesn't work)
    @RequestMapping(method=RequestMethod.POST)
    public Game postGame(@RequestBody Game game) {  
        return gameRestClient.create(game);
    }
    
    // gets all the games (works)
    @RequestMapping(method=RequestMethod.GET)
    public Collection<Game> listGames() {
        return gameRestClient.findAll();
    }
    
    // gets a game by name (doesn't work)
    @RequestMapping(value="/{name}", method=RequestMethod.GET)
    public Game showGameByName(@PathVariable("name") String name) {       
        return gameRestClient.findByName(name);
    }
    
    // deletes a game (untested)
    @RequestMapping(value="/{name}", method=RequestMethod.DELETE)
    public Game deleteGame(@PathVariable("name") String name) {
        Game game = gameRestClient.findByName(name);
        gameRestClient.deleteByName(name);
        return game;
    }
    
    // I'm not sure quite if this is the correct way to set the URI but it seems to work at least
    @PostConstruct
    public void giveUri() {
        gameRestClient.setUri("http://wepa-scoreservice-heroku.herokuapp.com/games"); 
    }

}

A service using the REST interface of the above mentioned address (using the class RestTemplate for it):
Code:
@Service
public class GameRestClient implements GameService {

    private RestTemplate restTemplate;
    private String uri; 

    public GameRestClient() {
        this.restTemplate = new RestTemplate();
    }

    @Override
    public void setUri(String uri) {
        this.uri = uri;
    }

    @Override
    public Game create(Game game) {
        return restTemplate.postForObject(uri, game, Game.class);
    }

    @Override
    public Game findByName(String name) {      
        return restTemplate.getForObject(uri, Game.class, name);
    }

    @Override
    public void deleteByName(String name) {
        restTemplate.delete(uri, name); // not quite sure if this is right or if I should find the corresponding game first, but that's a smaller problem)
    }

    // this works, the others don't (apart from the setUri method)
    @Override
    public Collection<Game> findAll() {
        return restTemplate.getForObject(uri, List.class);
    }

}

The GET method listGames() in the controller (and thus the findAll() method in the service) seemingly works just fine when I try it on localhost:8080/games. But if I pick any random game and try to see its info (on localhost:8080/games/game'sNameHere), I get a whitelabel error page:


The tests in the exercise also get error immediately when it tests the POST type method ( postGame(@RequestBody Game game) ). The error is as follows:


I really don't have any clue why those errors come. Or yeah, I think I get that the first error comes as it can't parse the JSON, but I really don't understand why it can't be parsed.
Anyone who could help please?

If needed, I can post the stacktrace and the code of the REST interface in the given address.

Sorry if anything's unclear. I'm not sure if I fully understand the assignment myself and it feels like I'm still slightly clueless about web stuff in general.

It's working for me.
http://wepa-scoreservice-heroku.herokuapp.com/games/game:046df0a0-ee6b-4d4a-8b93-ee4d5bba5e0d
 
Right, the site works just fine, but that's not my assignment. My assignment just uses it. Basically the assignment is very similar to outside except that the database isn't in my assignment but it's in the software that's accessible from that website. The RestTemplate is supposed to help with that.
 
For the first error with the GET method, it looks like the Deserializer receives an unexpected START_ARRAY token. In this case you could work around it by deserializing as Game[].class in the findByName() method.

The second error points to - as the name implies - to an internal server error. My first best guess is that your server is not configured. It either doesn't know where to store the data from the POST request or you maybe don't have write access to that particular store. But it's a wild guess.

EDIT:
I am not sure if this is related, but the site you posted expects an URI of the form {root}/games/game:{name} to ask for a specific game instance, while you are building the uri without "game:".
 
I have completed my initial studies of C# in 2 months, spending 2 hours a day on weekdays and 2-3 on weekends. Rarely missed a day, went from knowing absolutely nothing about code to gaining decent knowledge and finding something I actually enjoy doing.

I learned the following:

- How to use Visual Studio IDE
- Variables / Data Types
- Statements (If, Else if, Switch, Compound)
- Loops
- Reading / Writing IO
- Arrays (Strings, Values)
- Classes & Methods
- Error Handling

and a bunch of other stuff in those categories...

My question is can someone tell me the logical next steps? I can only create console applications with no GUI. I need a suggestion on how/where I can move to doing something more practical so I can put this to use.
 
I have completed my initial studies of C# in 2 months, spending 2 hours a day on weekdays and 2-3 on weekends. Rarely missed a day, went from knowing absolutely nothing about code to gaining decent knowledge and finding something I actually enjoy doing.

I learned the following:

- How to use Visual Studio IDE
- Variables / Data Types
- Statements (If, Else if, Switch, Compound)
- Loops
- Reading / Writing IO
- Arrays (Strings, Values)
- Classes & Methods
- Error Handling

and a bunch of other stuff in those categories...

My question is can someone tell me the logical next steps? I can only create console applications with no GUI. I need a suggestion on how/where I can move to doing something more practical so I can put this to use.

Practice. Rosetta Code and Project Euler are good sources of practice problems, but there are plenty of other practice problem databases on the web too.
 
Practice. Rosetta Code and Project Euler are good sources of practice problems, but there are plenty of other practice problem databases on the web too.

Hmm, that doesn't sound fun.

I would like to move into being able to visually display things instead of making fake bank accounts or calculating student grades.
 

Haly

One day I realized that sadness is just another word for not enough coffee.
Seems about right if they're serious about getting you started.

1 hour for lectures, 2 for homework, 5 times per week isn't out of the ordinary.

Although usually it's more like 2 hours for lectures 3 times per week and then many more hours on homework.
 

survivor

Banned
Man, working with threads such a pain in the ass, so many race conditions start popping up and all what I was trying to do is use a simple Timer class in C#.
 
Man, working with threads such a pain in the ass, so many race conditions start popping up and all what I was trying to do is use a simple Timer class in C#.

If you're using threads in C#, there's a pretty good chance you're doing it wrong. You probably haven't learned about asynchronous programming in C# yet.
 

survivor

Banned
If you're using threads in C#, there's a pretty good chance you're doing it wrong. You probably haven't learned about asynchronous programming in C# yet.

Can't do much about it, the existing codebase is filled with threads for background tasks so I gotta deal with that pain.
 
Hmm, that doesn't sound fun.

I would like to move into being able to visually display things instead of making fake bank accounts or calculating student grades.

Create an application to schedule tasks, track your finances, or if you want something really simple, just create a todo list with no worry about when it should be done. Once you get it working for a single user, make it multi-user with information being tied to a user and refactor the code where necessary.
 

KageZero

Member
Hello i have a question regarding the google in app purchases.
I want to create an in app for my application(as a managed product on store) so i was wondering if the title of the purchase must match the title of the item in the application itself.
I know that the id is important but i'm not sure about the title so if anyone can tell me i would be grateful.
 

Exuro

Member
noob java question. Was looking at some basic fractals and wanted to try out some examples so I found this java code. I've barely ever used java. How exactly is the pain method being called? It's not in main and it's not being called in the constructor so I don't see how its running. I debugged with eclipse and the method runs after main is finished so I'm a little lost.

Code:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
 
public class FractalTree extends JFrame {
 
    public FractalTree() {
        super("Fractal Tree");
        setBounds(100, 100, 800, 600);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
 
    private void drawTree(Graphics g, int x1, int y1, double angle, int depth) {
        if (depth == 0) return;
        int x2 = x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * 10.0);
        int y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * 10.0);
        g.drawLine(x1, y1, x2, y2);
        drawTree(g, x2, y2, angle - 20, depth - 1);
        drawTree(g, x2, y2, angle + 20, depth - 1);
    }
 
    @Override
    public void paint(Graphics g) {
        g.setColor(Color.BLACK);
        drawTree(g, 400, 500, -90, 9);
    }
 
    public static void main(String[] args) {
        new FractalTree().setVisible(true);
    }
}
 

Haly

One day I realized that sadness is just another word for not enough coffee.
It's likely called automatically via JFrame's interface since it's overriding JFrame's paint() method. Just from some light googling, JFrame has an update() method that simply calls paint(), and calling a JFrame's setVisible() method will begin its own thread.
 
noob java question. Was looking at some basic fractals and wanted to try out some examples so I found this java code. I've barely ever used java. How exactly is the pain method being called? It's not in main and it's not being called in the constructor so I don't see how its running. I debugged with eclipse and the method runs after main is finished so I'm a little lost.

Code:
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
 
public class FractalTree extends JFrame {
 
    public FractalTree() {
        super("Fractal Tree");
        setBounds(100, 100, 800, 600);
        setResizable(false);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
 
    private void drawTree(Graphics g, int x1, int y1, double angle, int depth) {
        if (depth == 0) return;
        int x2 = x1 + (int) (Math.cos(Math.toRadians(angle)) * depth * 10.0);
        int y2 = y1 + (int) (Math.sin(Math.toRadians(angle)) * depth * 10.0);
        g.drawLine(x1, y1, x2, y2);
        drawTree(g, x2, y2, angle - 20, depth - 1);
        drawTree(g, x2, y2, angle + 20, depth - 1);
    }
 
    @Override
    public void paint(Graphics g) {
        g.setColor(Color.BLACK);
        drawTree(g, 400, 500, -90, 9);
    }
 
    public static void main(String[] args) {
        new FractalTree().setVisible(true);
    }
}

When a JFrame or really any UI control is displayed, resized, or a myriad of other interactions occur, an event gets dispatched which triggers a refresh to the control. When this control refreshes, it calls its paint method.
 

Exuro

Member
Thanks. Figured it out. Another question. With that above code, I threw in a wait statement to see it animate to get a better understanding of the fractal. For some reason it's drawing it 3 times. It draws it once, then clears the screen and draws it twice. Any particular reason for this?
 
I think I'd rather see that expansion from Github.

Well, documentation of most projects on GitHub is already on GitHub. They also offer the platform to host them, gh-pages. SO aims to solve the other problems, mostly people not writing the documentation or providing the clear examples or documentation being closed source altogether.. Not sure if they are going succeed on that. I visit and answer questions on SO everyday and the documentation part could have the exact same problems that the other aspects have. Or it could just make people write even less documentation.
 

Ape

Banned
Guys I really need help on access, very soon too please.

I'm trying to open the preexisting forms by number, I have the sub created using docmd openform, but when I double click it sometimes only opens a blank form Sometimes it works, and sometimes not for the same number

Ask me any questions you have pls
 

Nesotenso

Member
speaking of git and github, I have a question about forks and pulling from the upstream remote. Suppose I fork someone's repo. I then add the second remote as the upstream one to pull updates made to the original repo. If I branch my local repo, merge it to the gh-pages and then pull from the upstream, do I lose my changes?

Or should I only merge branches after my pull from the upstream is the latest one? That way my pull request includes my changes?
 

Slavik81

Member
speaking of git and github, I have a question about forks and pulling from the upstream remote. Suppose I fork someone's repo. I then add the second remote as the upstream one to pull updates made to the original repo. If I branch my local repo, merge it to the gh-pages and then pull from the upstream, do I lose my changes?

Or should I only merge branches after my pull from the upstream is the latest one? That way my pull request includes my changes?
I'm afraid I don't understand the question. It's a little unclear exactly what you're doing.

I think it might be easier to explain what you ultimately want to do, rather than trying to explain the details of everything. Though, if you'd prefer to stick with details, it would be easier to understand if you just showed the commands you'd use to do this.
 
speaking of git and github, I have a question about forks and pulling from the upstream remote. Suppose I fork someone's repo. I then add the second remote as the upstream one to pull updates made to the original repo. If I branch my local repo, merge it to the gh-pages and then pull from the upstream, do I lose my changes?

Or should I only merge branches after my pull from the upstream is the latest one? That way my pull request includes my changes?

You won't lose any changes, but you might run into merge conflicts or a messy commit history. Solution for this is rebasing (which isn't that simple as it sounds, check the git manual and maybe some tutorials and remember that git-reset is your friend :p)
 

Nesotenso

Member
You won't lose any changes, but you might run into merge conflicts or a messy commit history. Solution for this is rebasing (which isn't that simple as it sounds, check the git manual and maybe some tutorials and remember that git-reset is your friend :p)

ok thanks for the reply

I'm afraid I don't understand the question. It's a little unclear exactly what you're doing.

I think it might be easier to explain what you ultimately want to do, rather than trying to explain the details of everything. Though, if you'd prefer to stick with details, it would be easier to understand if you just showed the commands you'd use to do this.

ok i hope I do a better job of explaining it this time.

1) I fork a repo from Github.
2) I clone my fork to my local git directory. I think this would automatically add it as a remote.
3) I add a second remote ( tutorials seems to say that conventionally it is called upstream) to the original repo from github so that I can pull changes to my local one.
4)I branch my local one, make changes and then merge it back to the main branch of the local.
5) I then pull from the upstream repo because of some updates made by the authors.Do I lose the changes I made with the branch and merge before I pulled from upstream ?
 
ok i hope I do a better job of explaining it this time.

1) I fork a repo from Github.
2) I clone my fork to my local git directory. I think this would automatically add it as a remote.
3) I add a second remote ( tutorials seems to say that conventionally it is called upstream) to the original repo from github so that I can pull changes to my local one.
4)I branch my local one, make changes and then merge it back to the main branch of the local.
5) I then pull from the upstream repo because of some updates made by the authors.Do I lose the changes I made with the branch and merge before I pulled from upstream ?

The procedure to get your feature branch up-to-date with the author's master branch is the following (I only learned that a couple of days ago when I made a tiny contribution to Servo):
Code:
git checkout your_feature_branch
git fetch upstream
git rebase -i upstream/master
git push -f origin your_feature_branch
That assumes that upstream refers to the remote repository of the author. Important in this case is to use 'fetch upstream', not pull, because pull will try to merge things into your branch if I'm not mistaken.
 
The procedure to get your feature branch up-to-date with the author's master branch is the following (I only learned that a couple of days ago when I made a tiny contribution to Servo):
Code:
git checkout your_feature_branch
git fetch upstream
git rebase -i upstream/master
git push -f origin your_feature_branch
That assumes that upstream refers to the remote repository of the author. Important in this case is to use 'fetch upstream', not pull, because pull will try to merge things into your branch if I'm not mistaken.

Remember that force pushing (--force or -f) is dangerous* and that could end up with you or someone else losing stuff if you have already shared your repo with someone.
 

Nesotenso

Member
The procedure to get your feature branch up-to-date with the author's master branch is the following (I only learned that a couple of days ago when I made a tiny contribution to Servo):
Code:
git checkout your_feature_branch
git fetch upstream
git rebase -i upstream/master
git push -f origin your_feature_branch
That assumes that upstream refers to the remote repository of the author. Important in this case is to use 'fetch upstream', not pull, because pull will try to merge things into your branch if I'm not mistaken.

thanks for the help and answer. I'll have to look into some of those commands later.
 
that feel when you should've done better during the hashing portion of your data structures class cuz your phone interview had a question about it and reversing a hashed string, which made sense once I stepped through it but boy did I struggle initially and i fear may cost me the chance at another interview.
 

JesseZao

Member
that feel when you should've done better during the hashing portion of your data structures class cuz your phone interview had a question about it and reversing a hashed string, which made sense once I stepped through it but boy did I struggle initially and i fear may cost me the chance at another interview.

I haven't finished data structures yet, but the point of hashing something is so that you can't get the original back from it? Were they just asking how to reverse it if you knew the algorithm or using a rainbow table or something?
 

Two Words

Member
I don't get why my Computer Science 2 class is so easy and reteaching us stuff we've learned. Is the following typical?

First CS class I took was an intro to programming class with C++. Then I took a CS 1 class in C++ where we learned a lot more and did some relatively challenging stuff, all the way up to object oriented programming. Now I'm taking CS 2, which is in Java. Over the past two weeks, we've been learning how primitive data types work and if/else and looks, and Boolean conditional operations, etc, all work. This is diff we learned in the intro course. I'm far more interested into learning how Java differs from C++. Is this typical?
 
I don't get why my Computer Science 2 class is so easy and reteaching us stuff we've learned. Is the following typical?

First CS class I took was an intro to programming class with C++. Then I took a CS 1 class in C++ where we learned a lot more and did some relatively challenging stuff, all the way up to object oriented programming. Now I'm taking CS 2, which is in Java. Over the past two weeks, we've been learning how primitive data types work and if/else and looks, and Boolean conditional operations, etc, all work. This is diff we learned in the intro course. I'm far more interested into learning how Java differs from C++. Is this typical?
It's typical for a course in a new language to get you up to speed with the language. Java was designed to be similar to c++ in syntax and language constructs, so it's no surprise you feel like you're just relearning stuff when in actuality the professor is just making sure no one gets left behind from the language jump. What are the two courses supposed to be about? CS1 is intermediate programming and CS2 is just a straight java class?
 

upandaway

Member
I don't get why my Computer Science 2 class is so easy and reteaching us stuff we've learned. Is the following typical?

First CS class I took was an intro to programming class with C++. Then I took a CS 1 class in C++ where we learned a lot more and did some relatively challenging stuff, all the way up to object oriented programming. Now I'm taking CS 2, which is in Java. Over the past two weeks, we've been learning how primitive data types work and if/else and looks, and Boolean conditional operations, etc, all work. This is diff we learned in the intro course. I'm far more interested into learning how Java differs from C++. Is this typical?
Usually for me a professor would teach the first couple of lessons assuming not everyone are strong on the previous courses' material. Sometimes people take long breaks, or skip courses with a test, or have transferred from somewhere else, so it's just getting everyone to the starting line.

It picks up fast enough that it's a non-issue
 
I haven't finished data structures yet, but the point of hashing something is so that you can't get the original back from it? Were they just asking how to reverse it if you knew the algorithm or using a rainbow table or something?

i was given the simple hashing function (x * # + index) and had to turn it around to convert the number into a string.
 
Top Bottom