Модераторы: Sardar, Aliance

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сортировка объекта по полю в Java Script, помогите отсортировать объекта по полю 
V
    Опции темы
patap
Дата 7.5.2005, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 893
Регистрация: 7.5.2005
Где: Украина, Зп

Репутация: нет
Всего: 40



Здорово, народ.
У меня такая проблемка.
Я создал объект и заполнил его, в общем вот фрагмент проги:

Код

function comand(name,games,wins,lose,proc) {
    this.name=name
    this.games=games
    this.wins=wins
    this.lose=lose
    this.proc=proc
}

function comand_athlantic() {
var bost_m=new Array(4)
bost_m[0]='Бостон'
bost_m[1]=73
bost_m[2]=39
bost_m[3]=34
bost_m[4]=procent(bost_m[1],bost_m[2])
    athlantic[0]=new comand(bost_m[0],bost_m[1],bost_m[2],bost_m[3],bost_m[4])
..........................................................
var newy_m=new Array(4)
newy_m[0]='Нью-Йорк'
newy_m[1]=72
newy_m[2]=37
newy_m[3]=43
newy_m[4]=procent(newy_m[1],newy_m[2])
    athlantic[4]=new comand(newy_m[0],newy_m[1],newy_m[2],newy_m[3],newy_m[4])
}


теперь подскажите:
Как упорядочнить объект athlantic[] по убыванию, по полю wins?

Я делал вот так:
Код

function sort_by_wins(com) {
var a1
var mas_wins=new Array(4)
for (i=0;i<5;i++) {
mas_wins[i]=com[i].wins
document.write(mas_wins[i]+' ')
}
for (i=0;i<5;i++) {
for (j=0;j<5;j++) {
     if (mas_wins[j]<mas_wins[j+1]) {
    a1=com[j]
    com[j]=com[j+1]
    com[j+1]=a1
     }
}
}
}

в Pascal это работает без проблем, а в JavaScript начинает гнать, в чем проблема?


 ! 
 

Aliance: patap, давай будем выбирать выражения/слова. Разговаривай нормальным языком.


Это сообщение отредактировал(а) Aliance - 7.5.2005, 15:59


--------------------
На боку кобура болталась, сзади шашка отцовская звякала. 
Впереди меня все хохотало, а позади все плакало (с)
PM MAIL ICQ   Вверх
Aliance
Дата 8.5.2005, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



Сортировка в JavaScript происходит так:
Код

elem.sort(sortByID);

function sortByID(a, b) {
// Если данные имеют тип string
// то преобразуем их в одинокавый регистр
   a = a.toLowerCase();
   b = b.toLowerCase();
   return ((a < b) ? -1 : ((a > b) ? 1 : 0));
}


Это лишь пример, нужно знать конкретнее твою задачу...
PM MAIL WWW ICQ Skype   Вверх
patap
Дата 8.5.2005, 12:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 893
Регистрация: 7.5.2005
Где: Украина, Зп

Репутация: нет
Всего: 40



мне нужно взять и сравнить все athlantic[i].wins, и упорядочнить по убыванию athlantic[i] относительно
этого поля(wins).
вот допустим заполним поля:
Код

athlantic[0].name='Бостон'
athlantic[0].games=73
athlantic[0].wins=39
athlantic[0].lose=34

athlantic[1].name='Нью-джерси'
athlantic[1].games=74
athlantic[1].wins=35
athlantic[1].lose=39

athlantic[2].name='Филадельфия'
athlantic[2].games=73
athlantic[2].wins=36
athlantic[2].lose=37

athlantic[1].name='Торонто'
athlantic[1].games=72
athlantic[1].wins=38
athlantic[1].lose=34


теперь если вывести на экран поля athlantic[i].name, будет вот такой результат

1. Бостон
2. Нью-Джерси
3. Филадельфия
4. Торонто

а мне нужно провести сортировку и упорядочнить команды по количеству побед, т.е. по полю wins,
и результат должен быть такой:

1. Бостон(wins=39)
4. Торонто(wins=38)
3. Филадельфия(wins=36)
2. Нью-Джерси(wins=35)

в общем мне нужна функция сортировки, чтобы ей передавался объект athlantic, она его переробатывала
и выдавала результат.
во, вроде все ясно, но если чего спрашивай.




--------------------
На боку кобура болталась, сзади шашка отцовская звякала. 
Впереди меня все хохотало, а позади все плакало (с)
PM MAIL ICQ   Вверх
Aliance
Дата 8.5.2005, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



Код

athlantic.sort(sortByWin);

function sortByWin(a, b) {
   return a.wins - b.wins;
}

PM MAIL WWW ICQ Skype   Вверх
Sardar
Дата 8.5.2005, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



patap это еще что за паскале-дельфийский код! Так извратно на JS не пишут smile
С сортировки пузырьком вообще упал smile

Пишем правильно:
Код
//описание сущности, в которой храним инфу
function Comand(name,games,wins,lose,proc) {
    this.name=name
    this.games=games
    this.wins=wins
    this.lose=lose
    this.proc=proc
}
//контейнер, который будет умно селектировать инфу
function CommandContainer() {
  this.container=[];
}
//ну и пара функций для манипуляций, придумай ещё slice, splice, push, pop...
CommandContainer.prototype.setContainer=function(cont){
  this.container=cont;
}
//собстна выборка из контейнера, возвращаем новый контейнер с упорядоченной инфой
CommandContainer.prototype.select=function(field, comparator) {
   if(this.container.length<1) return [];
   var cont=this.container.slice(0); //копия массива
   if(typeof(comparator)!="function") comp=function(a,b) { //дефолтовый компаратор
          if(typeof(a)=="string") a=a.toLowerCase();  //на случай если значения строки
       if(typeof(b)=="string") b=b.toLowerCase(); //не учитываем регистр
       return (a<b? -1: (a>b? 1: 0));   
     }
   else comp=comparator; //либо заданный компаратор
   cont.sort(function(a, b) { //сортируем
      return comp(a[field], b[field]);
   });
   var con=new CommandContainer(); //новый контейнер
   con.setContainer(cont); //в принципе можно отдать и старый, если боишся за память :)
   return con;
}

//здесь забиваем инфу
function comand_athlantic() {
 function procent(f, p) { return (p*100)/f; }

 //смотрим на синтаксис литерального массива
 data=[
   new Comand('Бостон',73,39,34,procent(73,39)), 
   //..........................................................
   new Comand('Нью-Йорк',72,37,43,procent(72,37))
  ];
  var athlantic=new CommandContainer();
  athlantic.setContainer(data);
  return athlantic;
}

//тестируем всё
var athlantic=comand_athlantic();

var resContainer=athlantic.select('lose');  //выбираем по полю lose, дефолтовый компаратор
var res=resContainer.container;

//смотрим что вышло
for(var i=0; i<res.length; i++) {
  document.write("<div style='border: 1px solid black'>");
  for(j in res[i]) {
    document.write("res["+i+"]."+j+"=<b>"+res[i][j]+"</b><br />");
  }
  document.write("</div>");
}


Собстна надеюсь что ты врубишся в приём и перестанешь думать в убогом паскалевском стиле(да не в обиду всем фанатам, просто моё ИМХО) smile


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
patap
Дата 9.5.2005, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 893
Регистрация: 7.5.2005
Где: Украина, Зп

Репутация: нет
Всего: 40



Sardar
ну, дружище, спасибо! угодил так угодил!
именно то, что надо, есть конечно непонятные моменты, ну я еще <вырезано модератором>, а если что, то спрашу. ок?
а на счет паскаля ты прав. я просто только его более менее и знаю. а java script вот только начал осваивать,
тут по-ходу свой подход нужен, но со временем вкурю что к чему, язык не из сложных.
в общем спасибо тебе. удачи!


 ! 
 

Последний раз предупреждаю: используй нормальную лексику!


Это сообщение отредактировал(а) Aliance - 10.5.2005, 00:26


--------------------
На боку кобура болталась, сзади шашка отцовская звякала. 
Впереди меня все хохотало, а позади все плакало (с)
PM MAIL ICQ   Вверх
patap
Дата 10.5.2005, 00:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 893
Регистрация: 7.5.2005
Где: Украина, Зп

Репутация: нет
Всего: 40



Sardar
обоснуй пожалуйста:
1. что значит [] в этой функции

Код

function CommandContainer() {
  this.container=[];
}
или в этой строке
   if(this.container.length<1) return [];


или я так думаю что это пустой объект?

2. объясни как действует data в этой функции?
Код

function comand_athlantic() {
 function procent(f, p) { return (p*100)/f; }
 //смотрим на синтаксис литерального массива
 data=[
   new Comand('Бостон',73,39,34,procent(73,39)), 
.........................................................................................
   new Comand('Нью-Йорк',72,37,36,procent(72,37))
  ];
  var athlantic=new CommandContainer();
  athlantic.setContainer(data);
  return athlantic;
}


и еще такоя просьба: на простом примерчике объясни как действует this. а то я вроде понимаю,
но не совсем.

буду очень благодарен.

Aliance
прости дружище, я с непривычки.
буду стараться. smile

М
 

Пользуйся кнопкой Code!


Это сообщение отредактировал(а) Aliance - 10.5.2005, 01:02


--------------------
На боку кобура болталась, сзади шашка отцовская звякала. 
Впереди меня все хохотало, а позади все плакало (с)
PM MAIL ICQ   Вверх
Aliance
Дата 10.5.2005, 01:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I ♥ <script>
****


Профиль
Группа: Модератор
Сообщений: 6418
Регистрация: 2.8.2004
Где: spb

Репутация: 55
Всего: 137



Цитата(patap @ 10.5.2005, 01:58)
на простом примерчике объясни как действует this

интересно, ты сам писал скрипт, который ты выложил выше... ведь там она использована.
Вообще, глобальная ссылка this указывает на объект (в широком смысле этого слова), от которого производится обращение.
Вот, полезно, прочти.

Цитата(patap @ 10.5.2005, 01:58)
объясни как действует data в этой функции?

это массив. что непонятно?

Цитата(patap @ 10.5.2005, 01:58)
1. что значит [] в этой функции

я так понимаю, по умолчанию это объект, а мы его делаем массивом...
PM MAIL WWW ICQ Skype   Вверх
Sardar
Дата 10.5.2005, 03:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(patap @ 9.5.2005, 23:58)
1. что значит [] в этой функции

Литеральный пустой массив. Синтаксис: ['test', 'test2', 'test3'] - массив из трёх элементов.

Цитата(patap @ 9.5.2005, 23:58)
объясни как действует data в этой функции?

Это просто массив с инфой, которую ты сам забиваешь.


Цитата(patap @ 9.5.2005, 23:58)
и еще такоя просьба: на простом примерчике объясни как действует this. а то я вроде понимаю,
но не совсем.

Как в любом ООП языке this это сылка на текущий обьект, в контексте которого исполняется функция(метод). Если функцию вызываем просто как функцию, то она исполняется в контексте window.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
patap
Дата 10.5.2005, 22:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 893
Регистрация: 7.5.2005
Где: Украина, Зп

Репутация: нет
Всего: 40



привет еще раз.
я в общем посидел подумал, поразбирал код и появились еще вопросы
я прокоментировал строки так как я это понял, если что не правильно, прошу исправить и там где заданы вопросы - дайте ответы.
если не сложно изложите в такой же форме как и я.
заранее спасибо мужики.

Код

function Comand(name,games,wins,lose,proc) {
    this.name=name
    this.games=games
    this.wins=wins
    this.lose=lose
    this.proc=proc
}

function CommandContainer() {    //создаем контейнер, который заполним данными      
  this.container=[];             //это будет поле в котором будет храниться наш массив(data)
}

CommandContainer.prototype.setContainer=function(cont){ //создаем свойство, для того, чтобы загрузить данные в контейнер
  this.container=cont;
}

CommandContainer.prototype.select=function(field, comparator) {  //field-атрибут который задает название поля, comparator-определяет тип этого поля, правильно?
   if(this.container.length<1) return [];   //для чего эта строка?
   var cont=this.container.slice(0);   //cont приймет все элементы массива
   if(typeof(comparator)!="function") comp=function(a,b) {  //проверка на то, что поле не является функцией, для чего?
          if(typeof(a)=="string") a=a.toLowerCase();  
       if(typeof(b)=="string") b=b.toLowerCase(); 
       return (a<b? -1: (a>b? 1: 0));   
     }
   else comp=comparator;  //этот момент не понятен 
   cont.sort(function(a, b) {  //что за атрибуты передаем этой функции?
      return comp(a[field], b[field]);   //что значит a[field], b[field]?
   });
   var con=new CommandContainer();   //сохраняем результат
   con.setContainer(cont); 
   return con;
}

function comand_athlantic() {        //здесь все понятно
 function procent(f, p) { return (p*100)/f; }

 data=[
   new Comand('Бостон',73,39,34,procent(73,39)), 
   new Comand('Филадельфия',73,36,37,procent(73,36)), 
   new Comand('Торонто',73,30,43,procent(73,30)), 
   new Comand('Нью-Джерси',74,35,39,procent(74,35)), 
   new Comand('Нью-Йорк',72,37,36,procent(72,37))
  ];
  var athlantic=new CommandContainer();  //создаем объект, по функции CommandContainer(), которая как бы задает структуру объекта
  athlantic.setContainer(data);          //заполняем athlantic инфой
  return athlantic;
}

var athlantic=comand_athlantic();       //athlantic будет объектом хранящим инфу

var resContainer=athlantic.select('lose');  //передаем свойству select название поля (почему lose, а не wins?), и почему при создании свойства select функция получает 2 аргумента 
var res=resContainer.container;  //и это непонятно

for(var i=0; i<res.length; i++) {
  document.write("<div style='border: 1px solid black'>");
  for(j in res[i]) {
    document.write("res["+i+"]."+j+"=<b>"+res[i][j]+"</b><br />");
  }
  document.write("</div>");
}




--------------------
На боку кобура болталась, сзади шашка отцовская звякала. 
Впереди меня все хохотало, а позади все плакало (с)
PM MAIL ICQ   Вверх
Sardar
Дата 11.5.2005, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата(patap @ 10.5.2005, 21:05)
field-атрибут который задает название поля, comparator-определяет тип этого поля, правильно?

Не совсем, field это имя селектируемого(выбираемого) поля по которому сортируем. Comparator(compare - сравнивать) - это функция, задающая порядок сортировки по полю обьекта. Стандартный компаратор опеделён там же в функции, сортирует по возрастанию, работает со всеми типами.

Цитата(patap @ 10.5.2005, 21:05)
if(this.container.length<1) return [];   //для чего эта строка

Если контейнер пуст, то нафиг чего либо возвращать smile Собстна я ошибся вернув пустой массив, лучше:
Код
//field - ИМЯ поля по которому выбираем
//comparator - функция, задающая направление сортировки
CommandContainer.prototype.select=function(field, comparator) {
   if(this.container.length>0) {//если нам есть чего выбирать, т.е. массив не пустой
      var cont=this.container.slice(0);   //доздаём ДУБЛИКАТ массива, дабы ты в дальнейшем не убил данные, когда вернёшь их как сслку.
      //проверяем пришёл ли компаратор
      if(typeof(comparator)!="function") comp=function(a,b) { //если ты нифига не дал(второй аргумент) - то берём дефолтовый, который здесь же и написан
          if(typeof(a)=="string") a=a.toLowerCase();  //компаратор пишем по уму
          if(typeof(b)=="string") b=b.toLowerCase();  //дабы со строками без учёта регистра работал
          return (a<b? -1: (a>b? 1: 0));   
       } else comp=comparator;  //иначе берём твой компаратор, переданный вторым аргументом
      //сортируем, в параметрах передаём новую функцию, которая заюзает компаратор на конкретном поле обьекта
      cont.sort(function(a, b) {
          return comp(a[field], b[field]);   //имя поля обьекта лежит в первом аргументе(field)
      });
   } else cont=[]; //иначе возвратим пустой контейнер
   var con=new CommandContainer();   //сохраняем результат
   con.setContainer(cont); 
   return con;
}



Цитата(patap @ 10.5.2005, 21:05)
создаем объект, по функции CommandContainer(), которая как бы задает структуру объекта

Ну почти, создаём обьект юзая конструктор CommandContainer, это не просто вызов функции smile

Цитата(patap @ 10.5.2005, 21:05)
//передаем свойству select название поля (почему lose, а не wins?), и почему при создании свойства select функция получает 2 аргумента

Собстна метод select контейнера создан для выборок по заданному полю, результат отсортирован в заданном направлении. То есть пишем: container.select("wins") - выбрали и осортировали обьекты по полю wins с дефолтовым компаратором.

Цитата(patap @ 10.5.2005, 21:05)
var res=resContainer.container;  //и это непонятно

Массив с данными лежит в поле container контейнера обьектов, мы его достали.


patap вообще JS это не такой простой язык как ты думаешь, он прост для тех кто понимает что такое функциональные языки(хотя JS не функциональный язык). Если ты писал на Python, то JS тебе покажеться очень простым и удобным. Если на Java, то наделаешь много лажи, пытаясь создать иерархии "классов", хотя понятия типа/класса в JS нет. Ну а если ты кроме паскаля/C ничего не знаешь, то придётся расслабиться и выкинуть из головы все приёмы и ограничения, что ты имел раньше. В JS, можно всё, можно даже писать код, который будет изменять сам себя по требованию задачи(лямбда программирование).


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Иль
Дата 8.6.2005, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 544
Регистрация: 3.3.2005
Где: Москва

Репутация: 2
Всего: 14



О! Ничего не понимаю smile, а надо! Придется опять велосипед изобретать smile
Добавлено @ 16:03
Sardar, если получится, то можно на словах - чего тут делается, принцип.


--------------------
Ты виндусятник?... А я да. smile
PM MAIL ICQ Skype GTalk   Вверх
Иль
Дата 8.6.2005, 16:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 544
Регистрация: 3.3.2005
Где: Москва

Репутация: 2
Всего: 14



Sardar, вот как я понял твою идею:

В Array накидываем объектов которые хотим отсортировать в нем же, но сравнивать и сортировать сами элементы сего массива нам не интересно (да и чего мы там насравниваем smile). А когда мы начинаем сортировать массив, то в функции сравнения, применяемой в .sort(функция_сравнения) сравниваем не объектные элементы массива, а именно нужные нам значения свойств этих самых объектов-элементов и чтоб получить такое задаем нужную нам функцию сравнения через анонимную функцию .sort(function(a,b){return функция_сравнения(a[нужное_свойство],b[нужное_свойство])}), причем опрашиваемое свойство получаем из контекста метода, в котором вызываем .sort(...)

Ну скажите, что это так и мне будет полная нирвана!!!
А то я тут уже до чертиков дошол (какой-то eval() мне привиделся smile)

Это сообщение отредактировал(а) Иль - 8.6.2005, 17:44


--------------------
Ты виндусятник?... А я да. smile
PM MAIL ICQ Skype GTalk   Вверх
Иль
Дата 8.6.2005, 18:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 544
Регистрация: 3.3.2005
Где: Москва

Репутация: 2
Всего: 14



Цитата(Sardar @ 8.5.2005, 15:43)
if(typeof(a)=="string") a=a.toLowerCase();  //на случай если значения строки
       if(typeof(b)=="string") b=b.toLowerCase(); //не учитываем регистр

Sardar, почему на "string" проверяются и "a", и "b". Как повлияет на сравнения если проверять только "a" и .toLowerCase() применять сразу к обоим?

Это сообщение отредактировал(а) Иль - 8.6.2005, 18:55


--------------------
Ты виндусятник?... А я да. smile
PM MAIL ICQ Skype GTalk   Вверх
Sardar
Дата 9.6.2005, 01:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: 78
Всего: 317



Цитата
Ну скажите, что это так и мне будет полная нирвана!!!

Да, это так smile
Цитата
почему на "string" проверяются и "a", и "b

Потому что в поле обьекта може лежать что угодно. Если это строка, то обычно не нужно учитывать регистр, для этого и приводим к нижнему регистру, а затем сравниваем. Если регистр важен, то эти две строчки убираем.


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.2478 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.