import java.awt.* ;
import java.applet.* ;
import java.awt.event.* ;
class Dot
{
int left, top;
Dot
( int l,
int t,
Color c
) {
left = l;
top = t;
color = c;
}
public void setWidth( int w) { }
public int widthOf( )
{
return 0 ;
}
public void setHeight( int h) { }
public int heightOf( )
{
return 0 ;
}
public void setLeft( int l)
{
left = l;
}
public int leftOf( )
{
return left;
}
public void setTop( int t)
{
top = t;
}
public int topOf( )
{
return top;
}
public void setColor
( Color c
) {
color = c;
}
{
return color;
}
public boolean find ( int x, int y)
{
return false ;
}
}
class RectDot extends Dot
{
int width, height;
RectDot
( int l,
int t,
int w,
int h,
Color c
) {
super ( l,t,c) ;
width = w;
height = h;
}
public void setWidth( int w)
{
width = w;
}
public int widthOf( )
{
return width;
}
public void setHeight( int h)
{
height = h;
}
public int heightOf( )
{
return height;
}
public boolean find( int x, int y)
{
if ( super .leftOf ( ) < x && x < super .leftOf ( ) + width && super .topOf ( ) < y && y < super .topOf ( ) + height)
return true ;
return false ;
}
{
g.setColor ( colorOf( ) ) ;
g.fillRect ( leftOf( ) , topOf( ) , width, height) ;
}
}
class CircDot extends Dot
{
int diam;
CircDot
( int l,
int t,
int d,
Color c
) {
super ( l,t,c) ;
diam = d;
}
public void setWidth( int w)
{
diam = w;
}
public int widthOf( )
{
return diam;
}
public void setHeight( int h)
{
diam = h;
}
public int heightOf( )
{
return diam;
}
public void setDiam( int d)
{
diam = d;
}
public int diameterOf( )
{
return diam;
}
public boolean find ( int x, int y)
{
if ( super .leftOf ( ) < x && x < super .leftOf ( ) + diam && super .topOf ( ) < y && y < super .topOf ( ) + diam)
return true ;
return false ;
}
{
g.setColor ( colorOf( ) ) ;
g.fillOval ( leftOf( ) , topOf( ) , diam, diam) ;
g.
setColor ( new Color ( 0 ,
0 ,
0 ) ) ; }
}
{
//runtime variables
boolean running = false ;
boolean currentlyCircle = true ;
boolean showtails = false ;
//buttons
//text
//panels
//scrollbars
private final int barHeight = 20 ;
private final int SLIDER_WIDTH = 10 ;
private final int MAXSPEED = 110 ;
private final int MINSPEED = 0 ;
private final int MAX_SIZE = 110 ;
private final int MIN_SIZE = 10 ;
/* These are the default values, and do not need to be implemented.
* If I wanted to use something other then default, these constants
* would be used.
private final int UNIT_INC = 1;
private final int BLOC_INC = 10;
*/
//drawn objs
Dot dot;
//initialize the applet and draw everything
public void init( )
{
double colWeight[ ] = { 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 } ; //15 cols
double rowWeight[ ] = { 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 } ; //10 rows
int colWidth[ ] = { 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 } ; //15 cols
int rowHeight[ ] = { 1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 } ; //10 rows
gbl.rowHeights = rowHeight;
gbl.rowWeights = rowWeight;
gbl.columnWeights = colWeight;
gbl.columnWidths = colWidth;
//setBounds(0,0,480,640);
p.setLayout ( gbl) ;
//speed scrollbar
c.weightx = 1 ;
c.weighty = 1 ;
c.gridwidth = 3 ;
c.gridheight = 1 ;
c.gridx = 1 ;
c.gridy = 7 ;
gbl.setConstraints ( this .speedbar ,c) ;
//run button
c.weightx = 1 ;
c.weighty = 1 ;
c.gridwidth = 2 ;
c.gridheight = 1 ;
c.gridx = 5 ;
c.gridy = 7 ;
gbl.setConstraints ( this .runbutton ,c) ;
//tail button
c.weightx = 1 ;
c.weighty = 1 ;
c.gridwidth = 2 ;
c.gridheight = 1 ;
c.gridx = 8 ;
c.gridy = 7 ;
gbl.setConstraints ( this .tailbutton ,c) ;
//size scrollbar
c.weightx = 1 ;
c.weighty = 1 ;
c.gridwidth = 3 ;
c.gridheight = 1 ;
c.gridx = 11 ;
c.gridy = 7 ;
gbl.setConstraints ( this .sizebar ,c) ;
//speed text label
c.weightx = 1 ;
c.weighty = 1 ;
c.gridwidth = 3 ;
c.gridheight = 1 ;
c.gridx = 1 ;
c.gridy = 8 ;
gbl.setConstraints ( this .speedlabel ,c) ;
//shape button
c.weightx = 1 ;
c.weighty = 1 ;
c.gridwidth = 2 ;
c.gridheight = 1 ;
c.gridx = 5 ;
c.gridy = 8 ;
gbl.setConstraints ( this .shapebutton ,c) ;
//clear button
c.weightx = 1 ;
c.weighty = 1 ;
c.gridwidth = 2 ;
c.gridheight = 1 ;
c.gridx = 8 ;
c.gridy = 8 ;
gbl.setConstraints ( this .clearbutton ,c) ;
//size text label
c.weightx = 1 ;
c.weighty = 1 ;
c.gridwidth = 3 ;
c.gridheight = 1 ;
c.gridx = 11 ;
c.gridy = 8 ;
gbl.setConstraints ( this .sizelabel ,c) ;
//quit button
c.weightx = 1 ;
c.weighty = 1 ;
c.gridwidth = 3 ;
c.gridheight = 1 ;
c.gridx = 6 ;
c.gridy = 9 ;
gbl.setConstraints ( this .quitbutton ,c) ;
//add to the screen
p.add ( this .speedbar ) ;
p.add ( this .runbutton ) ;
p.add ( this .tailbutton ) ;
p.add ( this .sizebar ) ;
p.add ( this .speedlabel ) ;
p.add ( this .shapebutton ) ;
p.add ( this .clearbutton ) ;
p.add ( this .sizelabel ) ;
p.add ( this .quitbutton ) ;
//add listners
this .speedbar .addAdjustmentListener ( this ) ;
this .runbutton .addActionListener ( this ) ;
this .tailbutton .addActionListener ( this ) ;
this .sizebar .addAdjustmentListener ( this ) ;
this .shapebutton .addActionListener ( this ) ;
this .clearbutton .addActionListener ( this ) ;
this .quitbutton .addActionListener ( this ) ;
//drawing paramaters
page = getGraphics( ) ;
//boundaries
int bound_x
= Integer .
parseInt ( getParameter
( "WIDTH" ) ) ; int bound_y
= Integer .
parseInt ( getParameter
( "HEIGHT" ) ) ; //directions
int dx = 5 ;
int dy = 5 ;
//add the panels
add( "South" , p) ;
add( "Center" , drawingpanel) ;
}
public void run( )
{
//while (running)
//{
if ( ! showtails)
{
dot.setColor ( drawingpanel.getBackground ( ) ) ;
}
update( ) ; //check if speed, size, or shape changed
draw( ) ; //draw next dot based on move(), or initial condition
pause( ) ;
move( ) ; //calculate and prepare the coordinates for the next iteration to be drawn
//}
}
public void update( )
{
previouslocation = currentlocation;
currentlocation
= new Point ( dot.
leftOf ( ) , dot.
topOf ( ) ) ; }
public void draw( )
{
}
{
if ( currentlyCircle)
{
page.drawOval ( dot.leftOf ( ) , dot.topOf ( ) , dot.widthOf ( ) , dot.heightOf ( ) ) ;
page.fillOval ( dot.leftOf ( ) , dot.topOf ( ) , dot.widthOf ( ) , dot.heightOf ( ) ) ;
}
else
{
page.drawRect ( dot.leftOf ( ) , dot.topOf ( ) , dot.widthOf ( ) , dot.heightOf ( ) ) ;
page.fillRect ( dot.leftOf ( ) , dot.topOf ( ) , dot.widthOf ( ) , dot.heightOf ( ) ) ;
}
}
public void pause( )
{
//for (long i = 100000000; i <= i; i++){}
}
public void move( )
{
}
{
Object source
= e.
getSource ( ) ;
if ( source == this .runbutton )
{
if ( ! running) //prevents drawing a new dot when there is already one on the screen
{
running = true ;
dot
= new CircDot
( 100 ,
100 , sizebar.
getValue ( ) ,
Color .
RED ) ; currentlyCircle = true ;
}
run( ) ;
}
else if ( source == this .shapebutton )
{
if ( running) //no need to evaluate if the run button hasn't been pressed (ie no dot to switch)
{
if ( currentlyCircle) //if circle, draw it as a rectangle
{
dot = new RectDot( dot.leftOf ( ) , dot.topOf ( ) , dot.widthOf ( ) , dot.heightOf ( ) , dot.colorOf ( ) ) ;
this .shapebutton .setLabel ( "Square" ) ;
currentlyCircle = false ;
}
else //if rectangle, draw it as a circle
{
dot = new CircDot( dot.leftOf ( ) , dot.topOf ( ) , 2 * dot.widthOf ( ) , dot.colorOf ( ) ) ;
this .shapebutton .setLabel ( "Circle" ) ;
currentlyCircle = true ;
}
}
}
else if ( source == this .clearbutton )
{
/* Erase the dot by setting its color to the background.
* Running is also set to false. This means the run button
* can be pressed again and another dot will be drawn.
*/
running = false ;
dot.setColor ( getBackground( ) ) ;
}
else if ( source == this .tailbutton )
{
//toggle showing tails. This is used in run
showtails = true ;
}
else if ( source == quitbutton)
{
//remove listeners
stop( ) ;
}
update( drawingpanel.getGraphics ( ) ) ;
}
{
Object source
= e.
getSource ( ) ;
//set the new size. If the size is too big its adjusted in draw
if ( source == sizebar)
{
dot.setWidth ( sizebar.getValue ( ) ) ;
dot.setHeight ( sizebar.getValue ( ) ) ;
}
if ( source == speedbar)
{
}
}
public void stop( )
{
this .speedbar .removeAdjustmentListener ( this ) ;
this .runbutton .removeActionListener ( this ) ;
this .tailbutton .removeActionListener ( this ) ;
this .sizebar .removeAdjustmentListener ( this ) ;
this .shapebutton .removeActionListener ( this ) ;
this .clearbutton .removeActionListener ( this ) ;
this .quitbutton .removeActionListener ( this ) ;
}
}
aW1wb3J0IGphdmEuYXd0Lio7CmltcG9ydCBqYXZhLmFwcGxldC4qOwppbXBvcnQgamF2YS5hd3QuZXZlbnQuKjsKCmNsYXNzIERvdAp7CglpbnQgbGVmdCwgdG9wOwoJQ29sb3IgY29sb3IgPSBDb2xvci5SRUQ7CgkKCURvdChpbnQgbCwgaW50IHQsIENvbG9yIGMpCgl7CgkJbGVmdCAgID0gbDsKCQl0b3AgICAgPSB0OwoJCWNvbG9yICA9IGM7Cgl9CgkKCXB1YmxpYyB2b2lkIHNldFdpZHRoKGludCB3KSB7fSAgICAgICAgCglwdWJsaWMgaW50IHdpZHRoT2YoKSAgCgl7IAoJCXJldHVybiAwOyAKCX0gICAgICAgCgkKCXB1YmxpYyB2b2lkIHNldEhlaWdodChpbnQgaCkge30gICAgICAgICAgICAgCglwdWJsaWMgaW50IGhlaWdodE9mKCkgCgl7IAoJCXJldHVybiAwOwoJfSAgICAgICAgCgkKCXB1YmxpYyB2b2lkIHNldExlZnQoaW50IGwpICAgICAKCXsgCgkJbGVmdCA9IGw7IAoJfQoJcHVibGljIGludCBsZWZ0T2YoKSAgCgl7IAoJCXJldHVybiBsZWZ0OyAKCX0KCQoJcHVibGljIHZvaWQgc2V0VG9wKGludCB0KSAgICAgIAoJeyAKCQl0b3AgPSB0OyAKCX0KCXB1YmxpYyBpbnQgdG9wT2YoKSAgIAoJeyAKCQlyZXR1cm4gdG9wOyAKCX0KCQoJcHVibGljIHZvaWQgc2V0Q29sb3IoQ29sb3IgYykgCgl7IAoJCWNvbG9yID0gYzsgCgl9CglwdWJsaWMgQ29sb3IgY29sb3JPZigpIAoJeyAKCQlyZXR1cm4gY29sb3I7IAoJfQoJCglwdWJsaWMgdm9pZCBkcmF3IChHcmFwaGljcyBnKSB7fQoJCglwdWJsaWMgYm9vbGVhbiBmaW5kIChpbnQgeCwgaW50IHkpIAoJeyAKCQlyZXR1cm4gZmFsc2U7IAoJfQp9CgpjbGFzcyBSZWN0RG90IGV4dGVuZHMgRG90CnsKCWludCB3aWR0aCwgaGVpZ2h0OwoJCglSZWN0RG90IChpbnQgbCwgaW50IHQsIGludCB3LCBpbnQgaCwgQ29sb3IgYykKCXsKCQlzdXBlcihsLHQsYyk7CgkJd2lkdGggPSB3OwoJCWhlaWdodCA9IGg7Cgl9CgkKCXB1YmxpYyB2b2lkIHNldFdpZHRoKGludCB3KSAgIAoJeyAKCQl3aWR0aCA9IHc7IAoJfQoJcHVibGljIGludCAgd2lkdGhPZigpICAKCXsgCgkJcmV0dXJuIHdpZHRoOyAKCX0KCQoJcHVibGljIHZvaWQgc2V0SGVpZ2h0KGludCBoKSAKCXsgCgkJaGVpZ2h0ID0gaDsgCgl9CglwdWJsaWMgaW50ICBoZWlnaHRPZigpIAoJeyAKCQlyZXR1cm4gaGVpZ2h0OwoJfQoJCglwdWJsaWMgYm9vbGVhbiBmaW5kKGludCB4LCBpbnQgeSkKCXsKCQlpZiAoc3VwZXIubGVmdE9mKCkgPCB4ICYmIHggPCBzdXBlci5sZWZ0T2YoKSt3aWR0aCAmJiBzdXBlci50b3BPZigpICA8IHkgJiYgeSA8IHN1cGVyLnRvcE9mKCkraGVpZ2h0KQoJCXJldHVybiB0cnVlOwoJCXJldHVybiBmYWxzZTsKCX0KCQoJcHVibGljIHZvaWQgZHJhdyhHcmFwaGljcyBnKQoJewoJCWcuc2V0Q29sb3IoY29sb3JPZigpKTsKCQlnLmZpbGxSZWN0KGxlZnRPZigpLCB0b3BPZigpLCB3aWR0aCwgaGVpZ2h0KTsKCQlnLnNldENvbG9yKENvbG9yLmJsYWNrKTsKCX0KfQoKY2xhc3MgQ2lyY0RvdCBleHRlbmRzIERvdAp7CglpbnQgZGlhbTsKCQoJQ2lyY0RvdCAoaW50IGwsIGludCB0LCBpbnQgZCwgQ29sb3IgYykKCXsKCQlzdXBlcihsLHQsYyk7CgkJZGlhbSA9IGQ7Cgl9CgkKCXB1YmxpYyB2b2lkIHNldFdpZHRoKGludCB3KSAgCgl7IAoJCWRpYW0gPSB3OyAKCX0KCXB1YmxpYyBpbnQgICB3aWR0aE9mKCkgICAgIAoJeyAKCQlyZXR1cm4gZGlhbTsgCgl9CgkKCXB1YmxpYyB2b2lkIHNldEhlaWdodChpbnQgaCkgCgl7IAoJCWRpYW0gPSBoOyAKCX0KCXB1YmxpYyBpbnQgICBoZWlnaHRPZigpICAgIAoJeyAKCQlyZXR1cm4gZGlhbTsKCX0KCQoJcHVibGljIHZvaWQgc2V0RGlhbShpbnQgZCkgICAKCXsgCgkJZGlhbSA9IGQ7IAoJfQoJcHVibGljIGludCBkaWFtZXRlck9mKCkgCgl7IAoJCXJldHVybiBkaWFtOyAKCX0KCQoJcHVibGljIGJvb2xlYW4gZmluZCAoaW50IHgsIGludCB5KQoJewoJCWlmIChzdXBlci5sZWZ0T2YoKSA8IHggJiYgeCA8IHN1cGVyLmxlZnRPZigpK2RpYW0gJiYgc3VwZXIudG9wT2YoKSAgPCB5ICYmIHkgPCBzdXBlci50b3BPZigpK2RpYW0pCgkJcmV0dXJuIHRydWU7CgkJcmV0dXJuIGZhbHNlOwoJfQoJCglwdWJsaWMgdm9pZCBkcmF3KEdyYXBoaWNzIGcpCgl7CgkJZy5zZXRDb2xvcihjb2xvck9mKCkpOwoJCWcuZmlsbE92YWwobGVmdE9mKCksIHRvcE9mKCksIGRpYW0sIGRpYW0pOwoJCWcuc2V0Q29sb3IobmV3IENvbG9yKDAsMCwwKSk7Cgl9Cn0KCnB1YmxpYyBjbGFzcyBCb3VuY2UgZXh0ZW5kcyBBcHBsZXQgaW1wbGVtZW50cyBBY3Rpb25MaXN0ZW5lciwgQWRqdXN0bWVudExpc3RlbmVyCnsKCS8vcnVudGltZSB2YXJpYWJsZXMKCWJvb2xlYW4gcnVubmluZyA9IGZhbHNlOwoJYm9vbGVhbiBjdXJyZW50bHlDaXJjbGUgPSB0cnVlOwoJYm9vbGVhbiBzaG93dGFpbHMgPSBmYWxzZTsKCQoJLy9idXR0b25zCglCdXR0b24gcnVuYnV0dG9uID0gbmV3IEJ1dHRvbigiUnVuIik7CglCdXR0b24gdGFpbGJ1dHRvbiA9IG5ldyBCdXR0b24oIlRhaWwiKTsKCUJ1dHRvbiBzaGFwZWJ1dHRvbiA9IG5ldyBCdXR0b24oIlNxdWFyZSIpOwoJQnV0dG9uIGNsZWFyYnV0dG9uID0gbmV3IEJ1dHRvbigiQ2xlYXIiKTsKCUJ1dHRvbiBxdWl0YnV0dG9uID0gbmV3IEJ1dHRvbigiUXVpdCIpOwoJCgkvL3RleHQKCUxhYmVsIHNwZWVkbGFiZWwgPSBuZXcgTGFiZWwoIlNwZWVkIik7CglMYWJlbCBzaXplbGFiZWwgPSBuZXcgTGFiZWwoIlNpemUiKTsKCQoJLy9wYW5lbHMKCVBhbmVsIGRyYXdpbmdwYW5lbCA9IG5ldyBQYW5lbCgpOwoJCgkvL3Njcm9sbGJhcnMKCXByaXZhdGUgZmluYWwgaW50IGJhckhlaWdodCA9IDIwOwoJcHJpdmF0ZSBmaW5hbCBpbnQgU0xJREVSX1dJRFRIID0gMTA7Cglwcml2YXRlIGZpbmFsIGludCBNQVhTUEVFRCA9IDExMDsKCXByaXZhdGUgZmluYWwgaW50IE1JTlNQRUVEID0gMDsKCXByaXZhdGUgZmluYWwgaW50IE1BWF9TSVpFID0gMTEwOwoJcHJpdmF0ZSBmaW5hbCBpbnQgTUlOX1NJWkUgPSAxMDsKCS8qIFRoZXNlIGFyZSB0aGUgZGVmYXVsdCB2YWx1ZXMsIGFuZCBkbyBub3QgbmVlZCB0byBiZSBpbXBsZW1lbnRlZC4KCSAqIElmIEkgd2FudGVkIHRvIHVzZSBzb21ldGhpbmcgb3RoZXIgdGhlbiBkZWZhdWx0LCB0aGVzZSBjb25zdGFudHMKCSAqIHdvdWxkIGJlIHVzZWQuCglwcml2YXRlIGZpbmFsIGludCBVTklUX0lOQyA9IDE7Cglwcml2YXRlIGZpbmFsIGludCBCTE9DX0lOQyA9IDEwOwoJKi8KCVNjcm9sbGJhciBzcGVlZGJhciA9IG5ldyBTY3JvbGxiYXIoU2Nyb2xsYmFyLkhPUklaT05UQUwsIE1BWFNQRUVELzIsIFNMSURFUl9XSURUSCwgTUlOU1BFRUQsIE1BWFNQRUVEKTsKCVNjcm9sbGJhciBzaXplYmFyID0gbmV3IFNjcm9sbGJhcihTY3JvbGxiYXIuSE9SSVpPTlRBTCwgTUFYX1NJWkUvMiwgU0xJREVSX1dJRFRILCBNSU5fU0laRSwgTUFYX1NJWkUpOwoJCgkvL2RyYXduIG9ianMKCURvdCBkb3Q7Cglwcml2YXRlIEdyYXBoaWNzIHBhZ2U7CglQb2ludCBjdXJyZW50bG9jYXRpb247CglQb2ludCBwcmV2aW91c2xvY2F0aW9uOwoKCS8vaW5pdGlhbGl6ZSB0aGUgYXBwbGV0IGFuZCBkcmF3IGV2ZXJ5dGhpbmcKCXB1YmxpYyB2b2lkIGluaXQoKQoJewoJCWRvdWJsZSBjb2xXZWlnaHRbXSA9IHsxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMX07Ly8xNSBjb2xzCgkJZG91YmxlIHJvd1dlaWdodFtdID0gezEsMSwxLDEsMSwxLDEsMSwxLDF9OyAvLzEwIHJvd3MKCQlpbnQgY29sV2lkdGhbXSA9IHsxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMSwxLDEsMX07Ly8xNSBjb2xzCgkJaW50IHJvd0hlaWdodFtdID0gezEsMSwxLDEsMSwxLDEsMSwxLDF9OyAvLzEwIHJvd3MKCQlHcmlkQmFnQ29uc3RyYWludHMgYyA9IG5ldyBHcmlkQmFnQ29uc3RyYWludHMoKTsKCQlHcmlkQmFnTGF5b3V0IGdibCA9IG5ldyBHcmlkQmFnTGF5b3V0KCk7CgkJZ2JsLnJvd0hlaWdodHMgPSByb3dIZWlnaHQ7CgkJZ2JsLnJvd1dlaWdodHMgPSByb3dXZWlnaHQ7CgkJZ2JsLmNvbHVtbldlaWdodHMgPSBjb2xXZWlnaHQ7CgkJZ2JsLmNvbHVtbldpZHRocyA9IGNvbFdpZHRoOwoJCWMuYW5jaG9yID0gR3JpZEJhZ0NvbnN0cmFpbnRzLkNFTlRFUjsKCQkKCQkvL3NldEJvdW5kcygwLDAsNDgwLDY0MCk7CgkJc2V0TGF5b3V0KG5ldyBCb3JkZXJMYXlvdXQoKSk7CgkJUGFuZWwgcCA9IG5ldyBQYW5lbCgpOwoJCXAuc2V0TGF5b3V0KGdibCk7CgkJCgkJLy9zcGVlZCBzY3JvbGxiYXIKCQljLndlaWdodHggPSAxOwoJCWMud2VpZ2h0eSA9IDE7CgkJYy5ncmlkd2lkdGggPSAzOwoJCWMuZ3JpZGhlaWdodCA9IDE7CgkJYy5ncmlkeCA9IDE7CgkJYy5ncmlkeSA9IDc7CgkJYy5maWxsPSBHcmlkQmFnQ29uc3RyYWludHMuSE9SSVpPTlRBTDsKCQlnYmwuc2V0Q29uc3RyYWludHModGhpcy5zcGVlZGJhcixjKTsKCQkKCQkvL3J1biBidXR0b24KCQljLndlaWdodHggPSAxOwoJCWMud2VpZ2h0eSA9IDE7CgkJYy5ncmlkd2lkdGggPSAyOwoJCWMuZ3JpZGhlaWdodCA9IDE7CgkJYy5ncmlkeCA9IDU7CgkJYy5ncmlkeSA9IDc7CgkJYy5maWxsPSBHcmlkQmFnQ29uc3RyYWludHMuSE9SSVpPTlRBTDsKCQlnYmwuc2V0Q29uc3RyYWludHModGhpcy5ydW5idXR0b24sYyk7CgkJCgkJLy90YWlsIGJ1dHRvbgoJCWMud2VpZ2h0eCA9IDE7CgkJYy53ZWlnaHR5ID0gMTsKCQljLmdyaWR3aWR0aCA9IDI7CgkJYy5ncmlkaGVpZ2h0ID0gMTsKCQljLmdyaWR4ID0gODsKCQljLmdyaWR5ID0gNzsKCQljLmZpbGw9IEdyaWRCYWdDb25zdHJhaW50cy5IT1JJWk9OVEFMOwoJCWdibC5zZXRDb25zdHJhaW50cyh0aGlzLnRhaWxidXR0b24sYyk7CgkJCgkJLy9zaXplIHNjcm9sbGJhcgoJCWMud2VpZ2h0eCA9IDE7CgkJYy53ZWlnaHR5ID0gMTsKCQljLmdyaWR3aWR0aCA9IDM7CgkJYy5ncmlkaGVpZ2h0ID0gMTsKCQljLmdyaWR4ID0gMTE7CgkJYy5ncmlkeSA9IDc7CgkJYy5maWxsPSBHcmlkQmFnQ29uc3RyYWludHMuSE9SSVpPTlRBTDsKCQlnYmwuc2V0Q29uc3RyYWludHModGhpcy5zaXplYmFyLGMpOwoJCQoJCS8vc3BlZWQgdGV4dCBsYWJlbAoJCWMud2VpZ2h0eCA9IDE7CgkJYy53ZWlnaHR5ID0gMTsKCQljLmdyaWR3aWR0aCA9IDM7CgkJYy5ncmlkaGVpZ2h0ID0gMTsKCQljLmdyaWR4ID0gMTsKCQljLmdyaWR5ID0gODsKCQljLmZpbGw9IEdyaWRCYWdDb25zdHJhaW50cy5IT1JJWk9OVEFMOwoJCWdibC5zZXRDb25zdHJhaW50cyh0aGlzLnNwZWVkbGFiZWwsYyk7CgkJCgkJLy9zaGFwZSBidXR0b24KCQljLndlaWdodHggPSAxOwoJCWMud2VpZ2h0eSA9IDE7CgkJYy5ncmlkd2lkdGggPSAyOwoJCWMuZ3JpZGhlaWdodCA9IDE7CgkJYy5ncmlkeCA9IDU7CgkJYy5ncmlkeSA9IDg7CgkJYy5maWxsPSBHcmlkQmFnQ29uc3RyYWludHMuSE9SSVpPTlRBTDsKCQlnYmwuc2V0Q29uc3RyYWludHModGhpcy5zaGFwZWJ1dHRvbixjKTsKCQkKCQkvL2NsZWFyIGJ1dHRvbgoJCWMud2VpZ2h0eCA9IDE7CgkJYy53ZWlnaHR5ID0gMTsKCQljLmdyaWR3aWR0aCA9IDI7CgkJYy5ncmlkaGVpZ2h0ID0gMTsKCQljLmdyaWR4ID0gODsKCQljLmdyaWR5ID0gODsKCQljLmZpbGw9IEdyaWRCYWdDb25zdHJhaW50cy5IT1JJWk9OVEFMOwoJCWdibC5zZXRDb25zdHJhaW50cyh0aGlzLmNsZWFyYnV0dG9uLGMpOwoJCQoJCS8vc2l6ZSB0ZXh0IGxhYmVsCgkJYy53ZWlnaHR4ID0gMTsKCQljLndlaWdodHkgPSAxOwoJCWMuZ3JpZHdpZHRoID0gMzsKCQljLmdyaWRoZWlnaHQgPSAxOwoJCWMuZ3JpZHggPSAxMTsKCQljLmdyaWR5ID0gODsKCQljLmZpbGw9IEdyaWRCYWdDb25zdHJhaW50cy5IT1JJWk9OVEFMOwoJCWdibC5zZXRDb25zdHJhaW50cyh0aGlzLnNpemVsYWJlbCxjKTsKCQkKCQkvL3F1aXQgYnV0dG9uCgkJYy53ZWlnaHR4ID0gMTsKCQljLndlaWdodHkgPSAxOwoJCWMuZ3JpZHdpZHRoID0gMzsKCQljLmdyaWRoZWlnaHQgPSAxOwoJCWMuZ3JpZHggPSA2OwoJCWMuZ3JpZHkgPSA5OwoJCWMuZmlsbD0gR3JpZEJhZ0NvbnN0cmFpbnRzLkhPUklaT05UQUw7CgkJZ2JsLnNldENvbnN0cmFpbnRzKHRoaXMucXVpdGJ1dHRvbixjKTsKCQkKCQkvL2FkZCB0byB0aGUgc2NyZWVuCgkJcC5hZGQodGhpcy5zcGVlZGJhcik7CgkJcC5hZGQodGhpcy5ydW5idXR0b24pOwoJCXAuYWRkKHRoaXMudGFpbGJ1dHRvbik7CgkJcC5hZGQodGhpcy5zaXplYmFyKTsKCQlwLmFkZCh0aGlzLnNwZWVkbGFiZWwpOwoJCXAuYWRkKHRoaXMuc2hhcGVidXR0b24pOwoJCXAuYWRkKHRoaXMuY2xlYXJidXR0b24pOwoJCXAuYWRkKHRoaXMuc2l6ZWxhYmVsKTsKCQlwLmFkZCh0aGlzLnF1aXRidXR0b24pOwoJCQoJCS8vYWRkIGxpc3RuZXJzCgkJdGhpcy5zcGVlZGJhci5hZGRBZGp1c3RtZW50TGlzdGVuZXIodGhpcyk7CgkJdGhpcy5ydW5idXR0b24uYWRkQWN0aW9uTGlzdGVuZXIodGhpcyk7CgkJdGhpcy50YWlsYnV0dG9uLmFkZEFjdGlvbkxpc3RlbmVyKHRoaXMpOwoJCXRoaXMuc2l6ZWJhci5hZGRBZGp1c3RtZW50TGlzdGVuZXIodGhpcyk7CgkJdGhpcy5zaGFwZWJ1dHRvbi5hZGRBY3Rpb25MaXN0ZW5lcih0aGlzKTsKCQl0aGlzLmNsZWFyYnV0dG9uLmFkZEFjdGlvbkxpc3RlbmVyKHRoaXMpOwoJCXRoaXMucXVpdGJ1dHRvbi5hZGRBY3Rpb25MaXN0ZW5lcih0aGlzKTsKCgkJLy9kcmF3aW5nIHBhcmFtYXRlcnMKCQlwYWdlID0gZ2V0R3JhcGhpY3MoKTsKCQkvL2JvdW5kYXJpZXMKCQlpbnQgYm91bmRfeCA9IEludGVnZXIucGFyc2VJbnQoZ2V0UGFyYW1ldGVyKCJXSURUSCIpKTsKCQlpbnQgYm91bmRfeSA9IEludGVnZXIucGFyc2VJbnQoZ2V0UGFyYW1ldGVyKCJIRUlHSFQiKSk7CgkJLy9kaXJlY3Rpb25zCgkJaW50IGR4ID0gNTsKCQlpbnQgZHkgPSA1OwkKCgkJLy9hZGQgdGhlIHBhbmVscwoJCWFkZCgiU291dGgiLCBwKTsKCQlhZGQoIkNlbnRlciIsIGRyYXdpbmdwYW5lbCk7Cgl9CgoJcHVibGljIHZvaWQgcnVuKCkKCXsKCgkJLy93aGlsZSAocnVubmluZykKCQkvL3sKCQkJaWYgKCFzaG93dGFpbHMpCgkJCXsKCQkJCWRvdC5zZXRDb2xvcihkcmF3aW5ncGFuZWwuZ2V0QmFja2dyb3VuZCgpKTsKCQkJfQoJCQl1cGRhdGUoKTsvL2NoZWNrIGlmIHNwZWVkLCBzaXplLCBvciBzaGFwZSBjaGFuZ2VkCgkJCWRyYXcoKTsvL2RyYXcgbmV4dCBkb3QgYmFzZWQgb24gbW92ZSgpLCBvciBpbml0aWFsIGNvbmRpdGlvbgoJCQlwYXVzZSgpOwoJCQltb3ZlKCk7Ly9jYWxjdWxhdGUgYW5kIHByZXBhcmUgdGhlIGNvb3JkaW5hdGVzIGZvciB0aGUgbmV4dCBpdGVyYXRpb24gdG8gYmUgZHJhd24KCQkvL30KCX0KCglwdWJsaWMgdm9pZCB1cGRhdGUoKQoJewoJCXByZXZpb3VzbG9jYXRpb24gPSBjdXJyZW50bG9jYXRpb247CgkJY3VycmVudGxvY2F0aW9uID0gbmV3IFBvaW50KGRvdC5sZWZ0T2YoKSwgZG90LnRvcE9mKCkpOwoJfQoJCglwdWJsaWMgdm9pZCBkcmF3KCkKCXsKCQkKCX0KCQoJcHVibGljIHZvaWQgcGFpbnQoR3JhcGhpY3MgcGFnZSkKCXsKCQlpZihjdXJyZW50bHlDaXJjbGUpCgkJewoJCQlTeXN0ZW0uZXJyLnByaW50bG4oImhlcmUiKTsKCQkJcGFnZS5kcmF3T3ZhbChkb3QubGVmdE9mKCksIGRvdC50b3BPZigpLCBkb3Qud2lkdGhPZigpLCBkb3QuaGVpZ2h0T2YoKSk7CgkJCXBhZ2UuZmlsbE92YWwoZG90LmxlZnRPZigpLCBkb3QudG9wT2YoKSwgZG90LndpZHRoT2YoKSwgZG90LmhlaWdodE9mKCkpOwoJCX0KCQllbHNlCgkJewoJCQlwYWdlLmRyYXdSZWN0KGRvdC5sZWZ0T2YoKSwgZG90LnRvcE9mKCksIGRvdC53aWR0aE9mKCksIGRvdC5oZWlnaHRPZigpKTsKCQkJcGFnZS5maWxsUmVjdChkb3QubGVmdE9mKCksIGRvdC50b3BPZigpLCBkb3Qud2lkdGhPZigpLCBkb3QuaGVpZ2h0T2YoKSk7CgkJfQoJfQoJCglwdWJsaWMgdm9pZCBwYXVzZSgpCgl7CgkJLy9mb3IgKGxvbmcgaSA9IDEwMDAwMDAwMDsgaSA8PSBpOyBpKyspe30KCX0KCQoJcHVibGljIHZvaWQgbW92ZSgpCgl7CgkKCX0KICAgCiAgIAlwdWJsaWMgdm9pZCBhY3Rpb25QZXJmb3JtZWQoQWN0aW9uRXZlbnQgZSkKCXsKCQlPYmplY3Qgc291cmNlID0gZS5nZXRTb3VyY2UoKTsKCQkKCQlpZiAoc291cmNlID09IHRoaXMucnVuYnV0dG9uKQoJCXsKCQkJaWYgKCFydW5uaW5nKSAvL3ByZXZlbnRzIGRyYXdpbmcgYSBuZXcgZG90IHdoZW4gdGhlcmUgaXMgYWxyZWFkeSBvbmUgb24gdGhlIHNjcmVlbgoJCQl7CgkJCQlydW5uaW5nID0gdHJ1ZTsKCQkJCWRvdCA9IG5ldyBDaXJjRG90KDEwMCwgMTAwLCBzaXplYmFyLmdldFZhbHVlKCksIENvbG9yLlJFRCk7CgkJCQljdXJyZW50bHlDaXJjbGUgPSB0cnVlOwoJCQl9CgkJCXJ1bigpOwoJCX0KCQllbHNlIGlmIChzb3VyY2UgPT0gdGhpcy5zaGFwZWJ1dHRvbikKCQl7CgkJCWlmKHJ1bm5pbmcpLy9ubyBuZWVkIHRvIGV2YWx1YXRlIGlmIHRoZSBydW4gYnV0dG9uIGhhc24ndCBiZWVuIHByZXNzZWQgKGllIG5vIGRvdCB0byBzd2l0Y2gpCgkJCXsKCQkJCWlmIChjdXJyZW50bHlDaXJjbGUpIC8vaWYgY2lyY2xlLCBkcmF3IGl0IGFzIGEgcmVjdGFuZ2xlCgkJCQl7CgkJCQkJZG90ID0gbmV3IFJlY3REb3QoZG90LmxlZnRPZigpLCBkb3QudG9wT2YoKSwgZG90LndpZHRoT2YoKSwgZG90LmhlaWdodE9mKCksIGRvdC5jb2xvck9mKCkpOwoJCQkJCXRoaXMuc2hhcGVidXR0b24uc2V0TGFiZWwoIlNxdWFyZSIpOwoJCQkJCWN1cnJlbnRseUNpcmNsZSA9IGZhbHNlOwoJCQkJfQoJCQkJZWxzZSAvL2lmIHJlY3RhbmdsZSwgZHJhdyBpdCBhcyBhIGNpcmNsZQoJCQkJewoJCQkJCWRvdCA9IG5ldyBDaXJjRG90KGRvdC5sZWZ0T2YoKSwgZG90LnRvcE9mKCksIDIqZG90LndpZHRoT2YoKSwgZG90LmNvbG9yT2YoKSk7CgkJCQkJdGhpcy5zaGFwZWJ1dHRvbi5zZXRMYWJlbCgiQ2lyY2xlIik7CgkJCQkJY3VycmVudGx5Q2lyY2xlID0gdHJ1ZTsKCQkJCX0KCQkJfQoJCX0KCQllbHNlIGlmIChzb3VyY2UgPT0gdGhpcy5jbGVhcmJ1dHRvbikKCQl7CgkJCS8qIEVyYXNlIHRoZSBkb3QgYnkgc2V0dGluZyBpdHMgY29sb3IgdG8gdGhlIGJhY2tncm91bmQuIAoJCQkgKiBSdW5uaW5nIGlzIGFsc28gc2V0IHRvIGZhbHNlLiBUaGlzIG1lYW5zIHRoZSBydW4gYnV0dG9uCgkJCSAqIGNhbiBiZSBwcmVzc2VkIGFnYWluIGFuZCBhbm90aGVyIGRvdCB3aWxsIGJlIGRyYXduLgoJCQkgKi8KCQkJcnVubmluZyA9IGZhbHNlOwoJCQlkb3Quc2V0Q29sb3IoZ2V0QmFja2dyb3VuZCgpKTsKCQl9CgkJZWxzZSBpZiAoc291cmNlID09IHRoaXMudGFpbGJ1dHRvbikKCQl7CgkJCS8vdG9nZ2xlIHNob3dpbmcgdGFpbHMuIFRoaXMgaXMgdXNlZCBpbiBydW4KCQkJc2hvd3RhaWxzID0gdHJ1ZTsKCQl9CgkJZWxzZSBpZiAoc291cmNlID09IHF1aXRidXR0b24pCgkJewoJCQkvL3JlbW92ZSBsaXN0ZW5lcnMKCQkJc3RvcCgpOwoJCX0KCQkKCQl1cGRhdGUoZHJhd2luZ3BhbmVsLmdldEdyYXBoaWNzKCkpOwoJfQoJCglwdWJsaWMgdm9pZCBhZGp1c3RtZW50VmFsdWVDaGFuZ2VkKEFkanVzdG1lbnRFdmVudCBlKQoJewoJCU9iamVjdCBzb3VyY2UgPSBlLmdldFNvdXJjZSgpOwoJCQoJCS8vc2V0IHRoZSBuZXcgc2l6ZS4gSWYgdGhlIHNpemUgaXMgdG9vIGJpZyBpdHMgYWRqdXN0ZWQgaW4gZHJhdwoJCWlmIChzb3VyY2UgPT0gc2l6ZWJhcikKCQl7CgkJCWRvdC5zZXRXaWR0aChzaXplYmFyLmdldFZhbHVlKCkpOwoJCQlkb3Quc2V0SGVpZ2h0KHNpemViYXIuZ2V0VmFsdWUoKSk7CgkJfQoJCWlmIChzb3VyY2UgPT0gc3BlZWRiYXIpCgkJewoJCQkKCQl9Cgl9CgkKCXB1YmxpYyB2b2lkIHN0b3AoKQoJewoJCXRoaXMuc3BlZWRiYXIucmVtb3ZlQWRqdXN0bWVudExpc3RlbmVyKHRoaXMpOwoJCXRoaXMucnVuYnV0dG9uLnJlbW92ZUFjdGlvbkxpc3RlbmVyKHRoaXMpOwoJCXRoaXMudGFpbGJ1dHRvbi5yZW1vdmVBY3Rpb25MaXN0ZW5lcih0aGlzKTsKCQl0aGlzLnNpemViYXIucmVtb3ZlQWRqdXN0bWVudExpc3RlbmVyKHRoaXMpOwoJCXRoaXMuc2hhcGVidXR0b24ucmVtb3ZlQWN0aW9uTGlzdGVuZXIodGhpcyk7CgkJdGhpcy5jbGVhcmJ1dHRvbi5yZW1vdmVBY3Rpb25MaXN0ZW5lcih0aGlzKTsKCQl0aGlzLnF1aXRidXR0b24ucmVtb3ZlQWN0aW9uTGlzdGVuZXIodGhpcyk7Cgl9Cn0=