345449.vhj5l3oj7.asia Condition.java 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">//: c04:statemachine2:Condition.java // Condition function object for state machine package c04.statemachine2; public interface Condition { boolean condition(Input i); } ///:~ </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z Input.java 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">//: c04:statemachine2:Input.java // Inputs to a state machine package c04.statemachine2; public interface Input {} ///:~ </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z MouseAction.java 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">//: c04:mouse:MouseAction.java // This state machine takes an Iterator of Inputs // to move from State to State using a template // method. package c04.mouse; import c04.statemachine.*; public class MouseAction implements Input { private String action; public MouseAction(String a) { action = a; } public String toString() { return action; } public int hashCode() { return action.hashCode(); } public boolean equals(Object o) { return (o instanceof MouseAction) &amp;&amp; action.equals(((MouseAction)o).action); } public static MouseAction appears = new MouseAction(&quot;mouse appears&quot;), runsAway = new MouseAction(&quot;mouse runs away&quot;), enters = new MouseAction(&quot;mouse enters trap&quot;), escapes = new MouseAction(&quot;mouse escapes&quot;), trapped = new MouseAction(&quot;mouse trapped&quot;), removed = new MouseAction(&quot;mouse removed&quot;); } ///:~ </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z MouseAction.py 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="py" rows="16" cols="100">#: c04:mouse:MouseAction.py class MouseAction: def __init__(self, action): self.action = action def __str__(self): return self.action def __cmp__(self, other): return cmp(self.action, other.action) # Necessary when __cmp__ or __eq__ is defined # in order to make this class usable as a # dictionary key: def __hash__(self): return hash(self.action) # Static fields; an enumeration of instances: MouseAction.appears = MouseAction(&quot;mouse appears&quot;) MouseAction.runsAway = MouseAction(&quot;mouse runs away&quot;) MouseAction.enters = MouseAction(&quot;mouse enters trap&quot;) MouseAction.escapes = MouseAction(&quot;mouse escapes&quot;) MouseAction.trapped = MouseAction(&quot;mouse trapped&quot;) MouseAction.removed = MouseAction(&quot;mouse removed&quot;) #:~</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z MouseMoveList.java 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">//: c04:mouse:MouseMoveList.java // A transformer to produce a // List of MouseAction objects. package c04.mouse; import java.util.*; import com.bruceeckel.util.*; public class MouseMoveList extends ArrayList { public MouseMoveList(Iterator sit) { while(sit.hasNext()) add(new MouseAction((String)sit.next())); } } ///:~ </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z MouseMoves.txt 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/>mouse appears<br/>mouse runs away<br/>mouse appears<br/>mouse enters trap<br/>mouse escapes<br/>mouse appears<br/>mouse enters trap<br/>mouse trapped<br/>mouse removed<br/>mouse appears<br/>mouse runs away<br/>mouse appears<br/>mouse enters trap<br/>mouse trapped<br/>mouse removed<br/><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z MouseTrap2Test.java 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">//: c04:mousetrap2:MouseTrap2Test.java // A better mousetrap using tables package c04.mousetrap2; import c04.mouse.*; import c04.statemachine.*; import java.util.*; import java.io.*; import com.bruceeckel.util.*; import com.bruceeckel.test.*; abstract class StateT implements State { protected Map transitions = null; protected void init(Object[][] states) { transitions = new HashMap(); for(int i = 0; i &lt; states.length; i++) transitions.put(states[i][0], states[i][1]); } public abstract void run(); public State next(Input i) { if(transitions.containsKey(i)) return (State)transitions.get(i); else throw new RuntimeException( &quot;Input not supported for current state&quot;); } } class MouseTrap extends StateMachine { public static State waiting = new Waiting(), luring = new Luring(), trapping = new Trapping(), holding = new Holding(); public MouseTrap() { super(waiting); // Initial state } } class Waiting extends StateT { public void run() { System.out.println( &quot;Waiting: Broadcasting cheese smell&quot;); } public State next(Input i) { // Delayed initialization: if(transitions == null) init(new Object[][] { { MouseAction.appears, MouseTrap.luring }, }); return super.next(i); } } class Luring extends StateT { public void run() { System.out.println( &quot;Luring: Presenting Cheese, door open&quot;); } public State next(Input i) { if(transitions == null) init(new Object[][] { { MouseAction.enters, MouseTrap.trapping }, { MouseAction.runsAway, MouseTrap.waiting }, }); return super.next(i); } } class Trapping extends StateT { public void run() { System.out.println(&quot;Trapping: Closing door&quot;); } public State next(Input i) { if(transitions == null) init(new Object[][] { { MouseAction.escapes, MouseTrap.waiting }, { MouseAction.trapped, MouseTrap.holding }, }); return super.next(i); } } class Holding extends StateT { public void run() { System.out.println(&quot;Holding: Mouse caught&quot;); } public State next(Input i) { if(transitions == null) init(new Object[][] { { MouseAction.removed, MouseTrap.waiting }, }); return super.next(i); } } public class MouseTrap2Test extends UnitTest { MouseTrap trap = new MouseTrap(); MouseMoveList moves = new MouseMoveList( new StringList(&quot;../mouse/MouseMoves.txt&quot;) .iterator()); public void test() { trap.runAll(moves.iterator()); } public static void main(String args[]) { new MouseTrap2Test().test(); } } ///:~ </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z MouseTrapTest.java 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">//: c04:mousetrap1:MouseTrapTest.java // State Machine pattern using 'if' statements // to determine the next state. package c04.mousetrap1; import c04.mouse.*; import c04.statemachine.*; import com.bruceeckel.util.*; import java.util.*; import java.io.*; import com.bruceeckel.test.*; // A different subclass for each state: class Waiting implements State { public void run() { System.out.println( &quot;Waiting: Broadcasting cheese smell&quot;); } public State next(Input i) { MouseAction ma = (MouseAction)i; if(ma.equals(MouseAction.appears)) return MouseTrap.luring; return MouseTrap.waiting; } } class Luring implements State { public void run() { System.out.println( &quot;Luring: Presenting Cheese, door open&quot;); } public State next(Input i) { MouseAction ma = (MouseAction)i; if(ma.equals(MouseAction.runsAway)) return MouseTrap.waiting; if(ma.equals(MouseAction.enters)) return MouseTrap.trapping; return MouseTrap.luring; } } class Trapping implements State { public void run() { System.out.println(&quot;Trapping: Closing door&quot;); } public State next(Input i) { MouseAction ma = (MouseAction)i; if(ma.equals(MouseAction.escapes)) return MouseTrap.waiting; if(ma.equals(MouseAction.trapped)) return MouseTrap.holding; return MouseTrap.trapping; } } class Holding implements State { public void run() { System.out.println(&quot;Holding: Mouse caught&quot;); } public State next(Input i) { MouseAction ma = (MouseAction)i; if(ma.equals(MouseAction.removed)) return MouseTrap.waiting; return MouseTrap.holding; } } class MouseTrap extends StateMachine { public static State waiting = new Waiting(), luring = new Luring(), trapping = new Trapping(), holding = new Holding(); public MouseTrap() { super(waiting); // Initial state } } public class MouseTrapTest extends UnitTest { MouseTrap trap = new MouseTrap(); MouseMoveList moves = new MouseMoveList( new StringList(&quot;../mouse/MouseMoves.txt&quot;) .iterator()); public void test() { trap.runAll(moves.iterator()); } public static void main(String args[]) { new MouseTrapTest().test(); } } ///:~ </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z State.java 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">//: c04:statemachine2:State.java package c04.statemachine2; public class State { private String name; public State(String nm) { name = nm; } public String toString() { return name; } } ///:~ </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z State.py 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="py" rows="16" cols="100">#: c04:statemachine:State.py # A State has an operation, and can be moved # into the next State given an Input: class State: def run(self): assert 1, &quot;run not implemented&quot; def next(self, input): assert 1, &quot;next not implemented&quot; #:~</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z StateMachine.java 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">//: c04:statemachine2:StateMachine.java // A table-driven state machine package c04.statemachine2; import java.util.*; public class StateMachine { private State state; private Map map = new HashMap(); public StateMachine(State initial) { state = initial; } public void buildTable(Object[][][] table) { for(int i = 0; i &lt; table.length; i++) { Object[][] row = table[i]; Object currentState = row[0][0]; List transitions = new ArrayList(); for(int j = 1; j &lt; row.length; j++) transitions.add(row[j]); map.put(currentState, transitions); } } public void nextState(Input input) { Iterator it=((List)map.get(state)).iterator(); while(it.hasNext()) { Object[] tran = (Object[])it.next(); if(input == tran[0] || input.getClass() == tran[0]) { if(tran[1] != null) { Condition c = (Condition)tran[1]; if(!c.condition(input)) continue; // Failed test } if(tran[2] != null) ((Transition)tran[2]).transition(input); state = (State)tran[3]; return; } } throw new RuntimeException( &quot;Input not supported for current state&quot;); } } ///:~ </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z StateMachine.py 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="py" rows="16" cols="100">#: c04:statemachine:StateMachine.py # Takes a list of Inputs to move from State to # State using a template method. class StateMachine: def __init__(self, initialState): self.currentState = initialState self.currentState.run() # Template method: def runAll(self, inputs): for i in inputs: print i self.currentState = self.currentState.next(i) self.currentState.run() #:~</TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z Transition.java 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">//: c04:statemachine2:Transition.java // Transition function object for state machine package c04.statemachine2; public interface Transition { void transition(Input i); } ///:~ </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z VendingMachine.java 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">//: c04:vendingmachine:VendingMachine.java // Demonstrates use of StateMachine.java package c04.vendingmachine; import c04.statemachine2.*; final class VM extends State { private VM(String nm) { super(nm); } public final static VM quiescent = new VM(&quot;Quiesecent&quot;), collecting = new VM(&quot;Collecting&quot;), selecting = new VM(&quot;Selecting&quot;), unavailable = new VM(&quot;Unavailable&quot;), wantMore = new VM(&quot;Want More?&quot;), noChange = new VM(&quot;Use Exact Change Only&quot;), makesChange = new VM(&quot;Machine makes change&quot;); } final class HasChange implements Input { private String name; private HasChange(String nm) { name = nm; } public String toString() { return name; } public final static HasChange yes = new HasChange(&quot;Has change&quot;), no = new HasChange(&quot;Cannot make change&quot;); } class ChangeAvailable extends StateMachine { public ChangeAvailable() { super(VM.makesChange); buildTable(new Object[][][]{ { {VM.makesChange}, // Current state // Input, test, transition, next state: {HasChange.no, null, null, VM.noChange}}, { {VM.noChange}, // Current state // Input, test, transition, next state: {HasChange.yes, null, null, VM.makesChange}}, }); } } final class Money implements Input { private String name; private int value; private Money(String nm, int val) { name = nm; value = val; } public String toString() { return name; } public int getValue() { return value; } public final static Money quarter = new Money(&quot;Quarter&quot;, 25), dollar = new Money(&quot;Dollar&quot;, 100); } final class Quit implements Input { private Quit() {} public String toString() { return &quot;Quit&quot;; } public final static Quit quit = new Quit(); } final class FirstDigit implements Input { private String name; private int value; private FirstDigit(String nm, int val) { name = nm; value = val; } public String toString() { return name; } public int getValue() { return value; } public final static FirstDigit A = new FirstDigit(&quot;A&quot;, 0), B = new FirstDigit(&quot;B&quot;, 1), C = new FirstDigit(&quot;C&quot;, 2), D = new FirstDigit(&quot;D&quot;, 3); } final class SecondDigit implements Input { private String name; private int value; private SecondDigit(String nm, int val) { name = nm; value = val; } public String toString() { return name; } public int getValue() { return value; } public final static SecondDigit one = new SecondDigit(&quot;one&quot;, 0), two = new SecondDigit(&quot;two&quot;, 1), three = new SecondDigit(&quot;three&quot;, 2), four = new SecondDigit(&quot;four&quot;, 3); } class ItemSlot { int price; int quantity; static int counter = 0; String id = Integer.toString(counter++); public ItemSlot(int prc, int quant) { price = prc; quantity = quant; } public String toString() { return id; } public int getPrice() { return price; } public int getQuantity() { return quantity; } public void decrQuantity() { quantity--; } } public class VendingMachine extends StateMachine{ StateMachine changeAvailable = new ChangeAvailable(); int amount = 0; FirstDigit first = null; ItemSlot[][] items = new ItemSlot[4][4]; Condition notEnough = new Condition() { public boolean condition(Input input) { int i1 = first.getValue(); int i2 = ((SecondDigit)input).getValue(); return items[i1][i2].getPrice() &gt; amount; } }; Condition itemAvailable = new Condition() { public boolean condition(Input input) { int i1 = first.getValue(); int i2 = ((SecondDigit)input).getValue(); return items[i1][i2].getQuantity() &gt; 0; } }; Condition itemNotAvailable = new Condition() { public boolean condition(Input input) { return !itemAvailable.condition(input); //int i1 = first.getValue(); //int i2 = ((SecondDigit)input).getValue(); //return items[i1][i2].getQuantity() == 0; } }; Transition clearSelection = new Transition() { public void transition(Input input) { int i1 = first.getValue(); int i2 = ((SecondDigit)input).getValue(); ItemSlot is = items[i1][i2]; System.out.println( &quot;Clearing selection: item &quot; + is + &quot; costs &quot; + is.getPrice() + &quot; and has quantity &quot; + is.getQuantity()); first = null; } }; Transition dispense = new Transition() { public void transition(Input input) { int i1 = first.getValue(); int i2 = ((SecondDigit)input).getValue(); ItemSlot is = items[i1][i2]; System.out.println(&quot;Dispensing item &quot; + is + &quot; costs &quot; + is.getPrice() + &quot; and has quantity &quot; + is.getQuantity()); items[i1][i2].decrQuantity(); System.out.println(&quot;New Quantity &quot; + is.getQuantity()); amount -= is.getPrice(); System.out.println(&quot;Amount remaining &quot; + amount); } }; Transition showTotal = new Transition() { public void transition(Input input) { amount += ((Money)input).getValue(); System.out.println(&quot;Total amount = &quot; + amount); } }; Transition returnChange = new Transition() { public void transition(Input input) { System.out.println(&quot;Returning &quot; + amount); amount = 0; } }; Transition showDigit = new Transition() { public void transition(Input input) { first = (FirstDigit)input; System.out.println(&quot;First Digit= &quot;+ first); } }; public VendingMachine() { super(VM.quiescent); // Initial state for(int i = 0; i &lt; items.length; i++) for(int j = 0; j &lt; items[i].length; j++) items[i][j] = new ItemSlot((j+1)*25, 5); items[3][0] = new ItemSlot(25, 0); buildTable(new Object[][][]{ { {VM.quiescent}, // Current state // Input, test, transition, next state: {Money.class, null, showTotal, VM.collecting}}, { {VM.collecting}, // Current state // Input, test, transition, next state: {Quit.quit, null, returnChange, VM.quiescent}, {Money.class, null, showTotal, VM.collecting}, {FirstDigit.class, null, showDigit, VM.selecting}}, { {VM.selecting}, // Current state // Input, test, transition, next state: {Quit.quit, null, returnChange, VM.quiescent}, {SecondDigit.class, notEnough, clearSelection, VM.collecting}, {SecondDigit.class, itemNotAvailable, clearSelection, VM.unavailable}, {SecondDigit.class, itemAvailable, dispense, VM.wantMore}}, { {VM.unavailable}, // Current state // Input, test, transition, next state: {Quit.quit, null, returnChange, VM.quiescent}, {FirstDigit.class, null, showDigit, VM.selecting}}, { {VM.wantMore}, // Current state // Input, test, transition, next state: {Quit.quit, null, returnChange, VM.quiescent}, {FirstDigit.class, null, showDigit, VM.selecting}}, }); } } ///:~ </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z VendingMachineTest.java 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="java" rows="16" cols="100">//: c04:vendingmachine:VendingMachineTest.java // Demonstrates use of StateMachine.java package c04.vendingmachine; import c04.statemachine2.*; import com.bruceeckel.test.*; public class VendingMachineTest extends UnitTest{ VendingMachine vm = new VendingMachine(); Input[] inputs = { Money.quarter, Money.quarter, Money.dollar, FirstDigit.A, SecondDigit.two, FirstDigit.A, SecondDigit.two, FirstDigit.C, SecondDigit.three, FirstDigit.D, SecondDigit.one, Quit.quit, }; public void test() { for(int i = 0; i &lt; inputs.length; i++) vm.nextState(inputs[i]); } public static void main(String[] args) { new VendingMachineTest().test(); } } ///:~ </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z makefile 2001-12-26T16:00:00Z 2001-12-26T16:00:00Z <br/><TEXTAREA name="code" class="" rows="16" cols="100"># From Thinking in Patterns (with Java) by Bruce Eckel # At http://www.BruceEckel.com # (c)2001 Bruce Eckel # Copyright notice in Copyright.txt # Automatically-generated MAKEFILE # For examples in directory .\c04\vendingmachine # using the JDK 1.3 compiler # Invoke with: make HOME := ../../ ifndef MAKECMDGOALS MAKECMDGOALS := javac endif # Command.com is too weak to build this under Windows NT/2000: ifeq ($(OS),Windows_NT) COMSPEC=$(SYSTEMROOT)\system32\cmd.exe endif ifneq ($(MAKECMDGOALS),clean) include $(HOME)/$(MAKECMDGOALS).mac endif .SUFFIXES : .class .java .java.class : $(JVC) $(JVCFLAGS) $&lt; javac: \ VendingMachine.class \ VendingMachineTest.class jikes: \ VendingMachine.class \ VendingMachineTest.class clean: ifeq ($(notdir $(SHELL)),COMMAND.COM) del *.class else rm -f *.class endif VendingMachine.class: VendingMachine.java VendingMachineTest.class: VendingMachineTest.java $(JVC) $(JVCFLAGS) $&lt; java com.bruceeckel.test.RunUnitTests c04.vendingmachine.VendingMachineTest </TEXTAREA><br><br/><script type="text/javascript"><!--google_ad_client = "pub-9426659565807829";google_ad_slot = "9359905831";google_ad_width = 728;google_ad_height = 15;//--></script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script> 2001-12-26T16:00:00Z