import java.awt.Color ;
import java.util.* ;
import java.awt.* ;
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author misiek
*/
public class Nieregularne
extends javax.
swing .
JFrame {
/**
* Creates new form Nieregularne
*/
public Nieregularne( ) {
initComponents( ) ;
//new SerializacjaCzasownik();
dzialaj = new Dzialaj( "czasowniki.ser" ) ;
jSlider1.setMaximum ( dzialaj.size ( ) ) ;
jSlider1.setValue ( 20 ) ;
this .aktywuj ( false ) ;
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings( "unchecked" )
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents( ) {
jButton1
= new javax.
swing .
JButton ( ) ; jLabel1
= new javax.
swing .
JLabel ( ) ; jButton2
= new javax.
swing .
JButton ( ) ; jLabel2
= new javax.
swing .
JLabel ( ) ; jLabel3
= new javax.
swing .
JLabel ( ) ; jLabel4
= new javax.
swing .
JLabel ( ) ; jSlider1
= new javax.
swing .
JSlider ( ) ; jMenu1
= new javax.
swing .
JMenu ( ) ;
setTitle( "Czasowniki nieregularne" ) ;
jButton1.
setFont ( new java.
awt .
Font ( "Calibri" ,
0 ,
24 ) ) ; // NOI18N jButton1.setText ( "Losuj" ) ;
jButton1.
setMaximumSize ( new java.
awt .
Dimension ( 120 ,
39 ) ) ; jButton1.
setMinimumSize ( new java.
awt .
Dimension ( 120 ,
39 ) ) ; jButton1.
setPreferredSize ( new java.
awt .
Dimension ( 120 ,
39 ) ) ; jButton1.
addMouseListener ( new java.
awt .
event .
MouseAdapter ( ) { public void mouseClicked
( java.
awt .
event .
MouseEvent evt
) { jButton1MouseClicked( evt) ;
}
} ) ;
jLabel1.
setFont ( new java.
awt .
Font ( "Calibri" ,
1 ,
36 ) ) ; // NOI18N jLabel1.setText ( "Czasowniki nieregularne!" ) ;
jLabel1.
setCursor ( new java.
awt .
Cursor ( java.
awt .
Cursor .
DEFAULT_CURSOR ) ) ;
jTextField1.
setBackground ( new java.
awt .
Color ( 204 ,
204 ,
204 ) ) ; jTextField1.
setFont ( new java.
awt .
Font ( "Calibri" ,
0 ,
20 ) ) ; // NOI18N public void mouseDragged
( java.
awt .
event .
MouseEvent evt
) { jTextField1MouseDragged( evt) ;
}
public void mouseMoved
( java.
awt .
event .
MouseEvent evt
) { jTextField1MouseMoved( evt) ;
}
} ) ;
jTextField2.
setBackground ( new java.
awt .
Color ( 204 ,
204 ,
204 ) ) ; jTextField2.
setFont ( new java.
awt .
Font ( "Calibri" ,
0 ,
20 ) ) ; // NOI18N
jTextField3.
setBackground ( new java.
awt .
Color ( 204 ,
204 ,
204 ) ) ; jTextField3.
setFont ( new java.
awt .
Font ( "Calibri" ,
0 ,
20 ) ) ; // NOI18N
jButton2.
setFont ( new java.
awt .
Font ( "Calibri" ,
0 ,
24 ) ) ; // NOI18N jButton2.setText ( "Sprawdź" ) ;
jButton2.setEnabled ( false ) ;
jButton2.
setMaximumSize ( new java.
awt .
Dimension ( 120 ,
39 ) ) ; jButton2.
setMinimumSize ( new java.
awt .
Dimension ( 120 ,
39 ) ) ; jButton2.setName ( "" ) ; // NOI18N
jButton2.
setPreferredSize ( new java.
awt .
Dimension ( 120 ,
39 ) ) ; jButton2.
addMouseListener ( new java.
awt .
event .
MouseAdapter ( ) { public void mouseClicked
( java.
awt .
event .
MouseEvent evt
) { jButton2MouseClicked( evt) ;
}
} ) ;
public void actionPerformed
( java.
awt .
event .
ActionEvent evt
) { jButton2ActionPerformed( evt) ;
}
} ) ;
jButton2.
addKeyListener ( new java.
awt .
event .
KeyAdapter ( ) { public void keyReleased
( java.
awt .
event .
KeyEvent evt
) { jButton2KeyReleased( evt) ;
}
} ) ;
jLabel2.setText ( "jLabel2" ) ;
jLabel3.setText ( "jLabel2" ) ;
jLabel4.setText ( "jLabel2" ) ;
jSlider1.setMinimum ( 1 ) ;
jSlider1.setValue ( 20 ) ;
public void stateChanged
( javax.
swing .
event .
ChangeEvent evt
) { jSlider1StateChanged( evt) ;
}
} ) ;
jSlider1.
addMouseListener ( new java.
awt .
event .
MouseAdapter ( ) { public void mouseClicked
( java.
awt .
event .
MouseEvent evt
) { jSlider1MouseClicked( evt) ;
}
} ) ;
jTextField4.
setBackground ( new java.
awt .
Color ( 240 ,
240 ,
240 ) ) ; jTextField4.
setHorizontalAlignment ( javax.
swing .
JTextField .
CENTER ) ; jTextField4.setText ( "20" ) ;
jTextField4.
addCaretListener ( new javax.
swing .
event .
CaretListener ( ) { public void caretUpdate
( javax.
swing .
event .
CaretEvent evt
) { jTextField4CaretUpdate( evt) ;
}
} ) ;
public void actionPerformed
( java.
awt .
event .
ActionEvent evt
) { jTextField4ActionPerformed( evt) ;
}
} ) ;
jMenu1.setText ( "Plik" ) ;
jMenuItem1.setText ( "Resetuj statystyki" ) ;
public void actionPerformed
( java.
awt .
event .
ActionEvent evt
) { jMenuItem1ActionPerformed( evt) ;
}
} ) ;
jMenu1.add ( jMenuItem1) ;
jMenuBar1.add ( jMenu1) ;
setJMenuBar( jMenuBar1) ;
javax.swing .GroupLayout layout = new javax.swing .GroupLayout ( getContentPane( ) ) ;
getContentPane( ) .setLayout ( layout) ;
layout.setHorizontalGroup (
layout.createParallelGroup ( javax.swing .GroupLayout .Alignment .LEADING )
.addGroup ( layout.createSequentialGroup ( )
.addContainerGap ( )
.addGroup ( layout.createParallelGroup ( javax.swing .GroupLayout .Alignment .LEADING )
.addGroup ( layout.createSequentialGroup ( )
.addComponent ( jLabel1, javax.swing .GroupLayout .PREFERRED_SIZE , 487 , javax.swing .GroupLayout .PREFERRED_SIZE )
.
addGap ( 0 ,
0 ,
Short .
MAX_VALUE ) ) .addGroup ( layout.createSequentialGroup ( )
.
addGap ( 0 ,
0 ,
Short .
MAX_VALUE ) .addComponent ( jTextField4, javax.swing .GroupLayout .PREFERRED_SIZE , 33 , javax.swing .GroupLayout .PREFERRED_SIZE )
.addPreferredGap ( javax.swing .LayoutStyle .ComponentPlacement .RELATED )
.addComponent ( jSlider1, javax.swing .GroupLayout .PREFERRED_SIZE , 69 , javax.swing .GroupLayout .PREFERRED_SIZE ) )
.addGroup ( layout.createSequentialGroup ( )
.addGroup ( layout.createParallelGroup ( javax.swing .GroupLayout .Alignment .TRAILING , false )
.
addComponent ( jLabel2, javax.
swing .
GroupLayout .
DEFAULT_SIZE , javax.
swing .
GroupLayout .
DEFAULT_SIZE ,
Short .
MAX_VALUE ) .
addComponent ( jTextField1, javax.
swing .
GroupLayout .
DEFAULT_SIZE ,
150 ,
Short .
MAX_VALUE ) ) .addGap ( 18 , 18 , 18 )
.addGroup ( layout.createParallelGroup ( javax.swing .GroupLayout .Alignment .LEADING )
.
addComponent ( jLabel3, javax.
swing .
GroupLayout .
Alignment .
TRAILING , javax.
swing .
GroupLayout .
DEFAULT_SIZE , javax.
swing .
GroupLayout .
DEFAULT_SIZE ,
Short .
MAX_VALUE ) .addComponent ( jTextField2, javax.swing .GroupLayout .Alignment .TRAILING , javax.swing .GroupLayout .PREFERRED_SIZE , 150 , javax.swing .GroupLayout .PREFERRED_SIZE ) )
.addGap ( 18 , 18 , 18 )
.addGroup ( layout.createParallelGroup ( javax.swing .GroupLayout .Alignment .LEADING , false )
.
addComponent ( jTextField3, javax.
swing .
GroupLayout .
DEFAULT_SIZE ,
150 ,
Short .
MAX_VALUE ) .
addComponent ( jLabel4, javax.
swing .
GroupLayout .
DEFAULT_SIZE , javax.
swing .
GroupLayout .
DEFAULT_SIZE ,
Short .
MAX_VALUE ) ) ) ) .addContainerGap ( ) )
.addGroup ( layout.createSequentialGroup ( )
.addGap ( 95 , 95 , 95 )
.addComponent ( jButton2, javax.swing .GroupLayout .PREFERRED_SIZE , 150 , javax.swing .GroupLayout .PREFERRED_SIZE )
.addGap ( 18 , 18 , 18 )
.addComponent ( jButton1, javax.swing .GroupLayout .PREFERRED_SIZE , 150 , javax.swing .GroupLayout .PREFERRED_SIZE )
.
addContainerGap ( javax.
swing .
GroupLayout .
DEFAULT_SIZE ,
Short .
MAX_VALUE ) ) ) ;
layout.setVerticalGroup (
layout.createParallelGroup ( javax.swing .GroupLayout .Alignment .LEADING )
.addGroup ( javax.swing .GroupLayout .Alignment .TRAILING , layout.createSequentialGroup ( )
.addGroup ( layout.createParallelGroup ( javax.swing .GroupLayout .Alignment .LEADING )
.addComponent ( jTextField4, javax.swing .GroupLayout .PREFERRED_SIZE , 23 , javax.swing .GroupLayout .PREFERRED_SIZE )
.addComponent ( jSlider1, javax.swing .GroupLayout .PREFERRED_SIZE , javax.swing .GroupLayout .DEFAULT_SIZE , javax.swing .GroupLayout .PREFERRED_SIZE ) )
.addPreferredGap ( javax.swing .LayoutStyle .ComponentPlacement .RELATED )
.addComponent ( jLabel1, javax.swing .GroupLayout .PREFERRED_SIZE , 48 , javax.swing .GroupLayout .PREFERRED_SIZE )
.addGap ( 2 , 2 , 2 )
.addGroup ( layout.createParallelGroup ( javax.swing .GroupLayout .Alignment .BASELINE )
.addComponent ( jLabel2)
.addComponent ( jLabel3)
.addComponent ( jLabel4) )
.addGap ( 2 , 2 , 2 )
.addGroup ( layout.createParallelGroup ( javax.swing .GroupLayout .Alignment .BASELINE )
.addComponent ( jTextField1, javax.swing .GroupLayout .PREFERRED_SIZE , 30 , javax.swing .GroupLayout .PREFERRED_SIZE )
.addComponent ( jTextField2, javax.swing .GroupLayout .PREFERRED_SIZE , 30 , javax.swing .GroupLayout .PREFERRED_SIZE )
.addComponent ( jTextField3, javax.swing .GroupLayout .PREFERRED_SIZE , 30 , javax.swing .GroupLayout .PREFERRED_SIZE ) )
.addGap ( 18 , 18 , 18 )
.addGroup ( layout.createParallelGroup ( javax.swing .GroupLayout .Alignment .BASELINE )
.addComponent ( jButton2, javax.swing .GroupLayout .PREFERRED_SIZE , 44 , javax.swing .GroupLayout .PREFERRED_SIZE )
.addComponent ( jButton1, javax.swing .GroupLayout .PREFERRED_SIZE , 44 , javax.swing .GroupLayout .PREFERRED_SIZE ) )
.
addContainerGap ( javax.
swing .
GroupLayout .
DEFAULT_SIZE ,
Short .
MAX_VALUE ) ) ) ;
pack( ) ;
} // </editor-fold>
private void jButton1MouseClicked
( java.
awt .
event .
MouseEvent evt
) { // TODO add your handling code here:
if ( test == false ) {
test = this .nastepny ( ) ;
} else {
test = this .losujIndeksy ( jSlider1.getValue ( ) ) ;
jSlider1.setEnabled ( false ) ;
jTextField4.setEnabled ( false ) ;
jButton1.setText ( "Następny" ) ;
test = this .nastepny ( ) ;
this .aktywuj ( true ) ;
}
}
private void jButton2MouseClicked
( java.
awt .
event .
MouseEvent evt
) { // TODO add your handling code here:
if ( jButton2.isEnabled ( ) ) {
this .sprawdz ( ) ;
}
}
private void jMenuItem1ActionPerformed
( java.
awt .
event .
ActionEvent evt
) { // TODO add your handling code here:
dzialaj = new Dzialaj( "czasowniki2.ser" ) ;
}
private void jButton2KeyReleased
( java.
awt .
event .
KeyEvent evt
) { // TODO add your handling code here:
if ( jButton2.isEnabled ( ) ) {
this .sprawdz ( ) ;
}
}
private void jTextField4ActionPerformed
( java.
awt .
event .
ActionEvent evt
) { // TODO add your handling code here:
jSlider1.
setValue ( Integer .
parseInt ( jTextField4.
getText ( ) ) ) ; }
private void jSlider1StateChanged
( javax.
swing .
event .
ChangeEvent evt
) { // TODO add your handling code here:
jTextField4.
setText ( Integer .
toString ( jSlider1.
getValue ( ) ) ) ; losujIndeksy( jSlider1.getValue ( ) ) ;
}
/**
* @param args the command line arguments
*/
public static void main
( String args
[ ] ) { /* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://d...content-available-to-author-only...e.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
if ( "Nimbus" .equals ( info.getName ( ) ) ) {
javax.
swing .
UIManager .
setLookAndFeel ( info.
getClassName ( ) ) ; break ;
}
}
java.util .logging .Logger .getLogger ( Nieregularne.class .getName ( ) ) .log ( java.util .logging .Level .SEVERE , null , ex) ;
java.util .logging .Logger .getLogger ( Nieregularne.class .getName ( ) ) .log ( java.util .logging .Level .SEVERE , null , ex) ;
java.util .logging .Logger .getLogger ( Nieregularne.class .getName ( ) ) .log ( java.util .logging .Level .SEVERE , null , ex) ;
java.util .logging .Logger .getLogger ( Nieregularne.class .getName ( ) ) .log ( java.util .logging .Level .SEVERE , null , ex) ;
}
//</editor-fold>
/* Create and display the form */
public void run( ) {
new Nieregularne( ) .setVisible ( true ) ;
}
} ) ;
}
public void aktywuj( boolean b) {
jTextField1.setEnabled ( b) ;
jTextField2.setEnabled ( b) ;
jTextField3.setEnabled ( b) ;
jButton2.setEnabled ( b) ;
}
public boolean losujIndeksy( int i) {
indeksy = dzialaj.losujListe ( i) ;
return false ;
}
public void reset( ) {
jTextField1.
setForeground ( Color .
BLACK ) ; jTextField2.
setForeground ( Color .
BLACK ) ; jTextField3.
setForeground ( Color .
BLACK ) ; jTextField1.setText ( "" ) ;
jTextField2.setText ( "" ) ;
jTextField3.setText ( "" ) ;
}
/*public class Watek implements Runnable{
public void run(){
sprawdz();
}
}*/
public boolean nastepny( ) {
if ( jButton2.isEnabled ( ) ) {
/*Runnable w2 = new Watek();
Thread watek2 = new Thread(w2);
watek2.start();*/
sprawdz( ) ;
czekaj( ) ;
}
index++;
if ( indeksy.isEmpty ( ) ) {
jLabel1.setText ( "Koniec" ) ;
jButton1.setText ( "Losuj" ) ;
jSlider1.setEnabled ( true ) ;
jTextField4.setEnabled ( true ) ;
this .aktywuj ( false ) ;
dzialaj.serializuj ( ) ;
this .reset ( ) ;
return true ;
}
if ( index == indeksy.size ( ) ) {
index = 0 ;
}
jLabel1.setText ( dzialaj.getConcret ( indeksy.get ( index) ) .getEng1 ( ) ) ;
jLabel2.setText ( dzialaj.getConcret ( indeksy.get ( index) ) .getEng2 ( ) ) ;
jLabel3.setText ( dzialaj.getConcret ( indeksy.get ( index) ) .getEng3 ( ) ) ;
jLabel4.setText ( dzialaj.getConcret ( indeksy.get ( index) ) .getPol ( ) ) ;
this .reset ( ) ;
jButton2.setEnabled ( true ) ;
return false ;
}
public void czekaj( ) {
try {
System .
out .
println ( "Nie mozna zatrzymać programu" ) ; }
}
public void sprawdz( ) {
/**
* Sprawdzamy pokolei czy wprowadzono poprawną wartość. Jeśli tak,
* ustawiamy zielone tło Jeśli nie, ustawiamy czerwone tło
*/
boolean wynik1 = dzialaj.sprawdzCzasownik ( dzialaj.getConcret ( indeksy.get ( index) ) .getEng2 ( ) , jTextField1.getText ( ) ) ;
if ( wynik1 == true ) {
jTextField1.setForeground ( ZIELONY) ;
} else {
jTextField1.
setForeground ( Color .
RED ) ; jTextField1.setText ( dzialaj.getConcret ( indeksy.get ( index) ) .getEng2 ( ) ) ;
//jTextField1.setBackground(Color.RED);
}
boolean wynik2 = dzialaj.sprawdzCzasownik ( dzialaj.getConcret ( indeksy.get ( index) ) .getEng3 ( ) , jTextField2.getText ( ) ) ;
if ( wynik2 == true ) {
jTextField2.setForeground ( ZIELONY) ;
} else {
jTextField2.
setForeground ( Color .
RED ) ; jTextField2.setText ( dzialaj.getConcret ( indeksy.get ( index) ) .getEng3 ( ) ) ;
}
boolean wynik3 = dzialaj.sprawdzCzasownik ( dzialaj.getConcret ( indeksy.get ( index) ) .getPol ( ) , jTextField3.getText ( ) ) ;
if ( wynik3 == true ) {
jTextField3.setForeground ( ZIELONY) ;
} else {
jTextField3.
setForeground ( Color .
RED ) ; jTextField3.setText ( dzialaj.getConcret ( indeksy.get ( index) ) .getPol ( ) ) ;
}
/**
* Sprawdzamy czy wszystkie pola zostały poprawnie uzupełnione. Jeśli
* nie, ustawiamy błędną odpowiedź Jeśli tak, ustawiamy poprawną
* odpoweidź, usuwamy to słowo z aktualnej listy, obniżamy index.
*
*/
if ( wynik1 != true || wynik2 != true || wynik3 != true ) {
dzialaj.getConcret ( indeksy.get ( index) ) .setWynik ( false ) ;
System .
out .
println ( dzialaj.
getConcret ( indeksy.
get ( index
) ) ) ; } else {
dzialaj.getConcret ( indeksy.get ( index) ) .setWynik ( true ) ;
System .
out .
println ( dzialaj.
getConcret ( indeksy.
get ( index
) ) ) ; indeksy.remove ( index) ;
index--;
}
jButton2.setEnabled ( false ) ;
}
Dzialaj dzialaj;
ArrayList< Integer> indeksy;
private int index = - 1 ;
boolean test = true ;
// Variables declaration - do not modify
private javax.
swing .
JButton jButton1
; private javax.
swing .
JButton jButton2
; private javax.
swing .
JLabel jLabel1
; private javax.
swing .
JLabel jLabel2
; private javax.
swing .
JLabel jLabel3
; private javax.
swing .
JLabel jLabel4
; private javax.
swing .
JMenu jMenu1
; private javax.
swing .
JSlider jSlider1
; // End of variables declaration
}
aW1wb3J0IGphdmEuYXd0LkNvbG9yOwppbXBvcnQgamF2YS51dGlsLio7CmltcG9ydCBqYXZhLmF3dC4qOwoKLyoKICogVG8gY2hhbmdlIHRoaXMgbGljZW5zZSBoZWFkZXIsIGNob29zZSBMaWNlbnNlIEhlYWRlcnMgaW4gUHJvamVjdCBQcm9wZXJ0aWVzLgogKiBUbyBjaGFuZ2UgdGhpcyB0ZW1wbGF0ZSBmaWxlLCBjaG9vc2UgVG9vbHMgfCBUZW1wbGF0ZXMKICogYW5kIG9wZW4gdGhlIHRlbXBsYXRlIGluIHRoZSBlZGl0b3IuCiAqLwovKioKICoKICogQGF1dGhvciBtaXNpZWsKICovCnB1YmxpYyBjbGFzcyBOaWVyZWd1bGFybmUgZXh0ZW5kcyBqYXZheC5zd2luZy5KRnJhbWUgewoKICAgIC8qKgogICAgICogQ3JlYXRlcyBuZXcgZm9ybSBOaWVyZWd1bGFybmUKICAgICAqLwogICAgcHVibGljIE5pZXJlZ3VsYXJuZSgpIHsKICAgICAgICBpbml0Q29tcG9uZW50cygpOwogICAgICAgIC8vbmV3IFNlcmlhbGl6YWNqYUN6YXNvd25paygpOwogICAgICAgIGR6aWFsYWogPSBuZXcgRHppYWxhaigiY3phc293bmlraS5zZXIiKTsKICAgICAgICBqU2xpZGVyMS5zZXRNYXhpbXVtKGR6aWFsYWouc2l6ZSgpKTsKICAgICAgICBqU2xpZGVyMS5zZXRWYWx1ZSgyMCk7CiAgICAgICAgdGhpcy5ha3R5d3VqKGZhbHNlKTsKICAgIH0KCiAgICAvKioKICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBmcm9tIHdpdGhpbiB0aGUgY29uc3RydWN0b3IgdG8gaW5pdGlhbGl6ZSB0aGUgZm9ybS4KICAgICAqIFdBUk5JTkc6IERvIE5PVCBtb2RpZnkgdGhpcyBjb2RlLiBUaGUgY29udGVudCBvZiB0aGlzIG1ldGhvZCBpcyBhbHdheXMKICAgICAqIHJlZ2VuZXJhdGVkIGJ5IHRoZSBGb3JtIEVkaXRvci4KICAgICAqLwogICAgQFN1cHByZXNzV2FybmluZ3MoInVuY2hlY2tlZCIpCiAgICAvLyA8ZWRpdG9yLWZvbGQgZGVmYXVsdHN0YXRlPSJjb2xsYXBzZWQiIGRlc2M9IkdlbmVyYXRlZCBDb2RlIj4gICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgcHJpdmF0ZSB2b2lkIGluaXRDb21wb25lbnRzKCkgewoKICAgICAgICBqQnV0dG9uMSA9IG5ldyBqYXZheC5zd2luZy5KQnV0dG9uKCk7CiAgICAgICAgakxhYmVsMSA9IG5ldyBqYXZheC5zd2luZy5KTGFiZWwoKTsKICAgICAgICBqVGV4dEZpZWxkMSA9IG5ldyBqYXZheC5zd2luZy5KVGV4dEZpZWxkKCk7CiAgICAgICAgalRleHRGaWVsZDIgPSBuZXcgamF2YXguc3dpbmcuSlRleHRGaWVsZCgpOwogICAgICAgIGpUZXh0RmllbGQzID0gbmV3IGphdmF4LnN3aW5nLkpUZXh0RmllbGQoKTsKICAgICAgICBqQnV0dG9uMiA9IG5ldyBqYXZheC5zd2luZy5KQnV0dG9uKCk7CiAgICAgICAgakxhYmVsMiA9IG5ldyBqYXZheC5zd2luZy5KTGFiZWwoKTsKICAgICAgICBqTGFiZWwzID0gbmV3IGphdmF4LnN3aW5nLkpMYWJlbCgpOwogICAgICAgIGpMYWJlbDQgPSBuZXcgamF2YXguc3dpbmcuSkxhYmVsKCk7CiAgICAgICAgalNsaWRlcjEgPSBuZXcgamF2YXguc3dpbmcuSlNsaWRlcigpOwogICAgICAgIGpUZXh0RmllbGQ0ID0gbmV3IGphdmF4LnN3aW5nLkpUZXh0RmllbGQoKTsKICAgICAgICBqTWVudUJhcjEgPSBuZXcgamF2YXguc3dpbmcuSk1lbnVCYXIoKTsKICAgICAgICBqTWVudTEgPSBuZXcgamF2YXguc3dpbmcuSk1lbnUoKTsKICAgICAgICBqTWVudUl0ZW0xID0gbmV3IGphdmF4LnN3aW5nLkpNZW51SXRlbSgpOwoKICAgICAgICBzZXREZWZhdWx0Q2xvc2VPcGVyYXRpb24oamF2YXguc3dpbmcuV2luZG93Q29uc3RhbnRzLkVYSVRfT05fQ0xPU0UpOwogICAgICAgIHNldFRpdGxlKCJDemFzb3duaWtpIG5pZXJlZ3VsYXJuZSIpOwoKICAgICAgICBqQnV0dG9uMS5zZXRGb250KG5ldyBqYXZhLmF3dC5Gb250KCJDYWxpYnJpIiwgMCwgMjQpKTsgLy8gTk9JMThOCiAgICAgICAgakJ1dHRvbjEuc2V0VGV4dCgiTG9zdWoiKTsKICAgICAgICBqQnV0dG9uMS5zZXRNYXhpbXVtU2l6ZShuZXcgamF2YS5hd3QuRGltZW5zaW9uKDEyMCwgMzkpKTsKICAgICAgICBqQnV0dG9uMS5zZXRNaW5pbXVtU2l6ZShuZXcgamF2YS5hd3QuRGltZW5zaW9uKDEyMCwgMzkpKTsKICAgICAgICBqQnV0dG9uMS5zZXRQcmVmZXJyZWRTaXplKG5ldyBqYXZhLmF3dC5EaW1lbnNpb24oMTIwLCAzOSkpOwogICAgICAgIGpCdXR0b24xLmFkZE1vdXNlTGlzdGVuZXIobmV3IGphdmEuYXd0LmV2ZW50Lk1vdXNlQWRhcHRlcigpIHsKICAgICAgICAgICAgcHVibGljIHZvaWQgbW91c2VDbGlja2VkKGphdmEuYXd0LmV2ZW50Lk1vdXNlRXZlbnQgZXZ0KSB7CiAgICAgICAgICAgICAgICBqQnV0dG9uMU1vdXNlQ2xpY2tlZChldnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIGpMYWJlbDEuc2V0Rm9udChuZXcgamF2YS5hd3QuRm9udCgiQ2FsaWJyaSIsIDEsIDM2KSk7IC8vIE5PSTE4TgogICAgICAgIGpMYWJlbDEuc2V0SG9yaXpvbnRhbEFsaWdubWVudChqYXZheC5zd2luZy5Td2luZ0NvbnN0YW50cy5DRU5URVIpOwogICAgICAgIGpMYWJlbDEuc2V0VGV4dCgiQ3phc293bmlraSBuaWVyZWd1bGFybmUhIik7CiAgICAgICAgakxhYmVsMS5zZXRDdXJzb3IobmV3IGphdmEuYXd0LkN1cnNvcihqYXZhLmF3dC5DdXJzb3IuREVGQVVMVF9DVVJTT1IpKTsKCiAgICAgICAgalRleHRGaWVsZDEuc2V0QmFja2dyb3VuZChuZXcgamF2YS5hd3QuQ29sb3IoMjA0LCAyMDQsIDIwNCkpOwogICAgICAgIGpUZXh0RmllbGQxLnNldEZvbnQobmV3IGphdmEuYXd0LkZvbnQoIkNhbGlicmkiLCAwLCAyMCkpOyAvLyBOT0kxOE4KICAgICAgICBqVGV4dEZpZWxkMS5hZGRNb3VzZU1vdGlvbkxpc3RlbmVyKG5ldyBqYXZhLmF3dC5ldmVudC5Nb3VzZU1vdGlvbkFkYXB0ZXIoKSB7CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIG1vdXNlRHJhZ2dlZChqYXZhLmF3dC5ldmVudC5Nb3VzZUV2ZW50IGV2dCkgewogICAgICAgICAgICAgICAgalRleHRGaWVsZDFNb3VzZURyYWdnZWQoZXZ0KTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwdWJsaWMgdm9pZCBtb3VzZU1vdmVkKGphdmEuYXd0LmV2ZW50Lk1vdXNlRXZlbnQgZXZ0KSB7CiAgICAgICAgICAgICAgICBqVGV4dEZpZWxkMU1vdXNlTW92ZWQoZXZ0KTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwoKICAgICAgICBqVGV4dEZpZWxkMi5zZXRCYWNrZ3JvdW5kKG5ldyBqYXZhLmF3dC5Db2xvcigyMDQsIDIwNCwgMjA0KSk7CiAgICAgICAgalRleHRGaWVsZDIuc2V0Rm9udChuZXcgamF2YS5hd3QuRm9udCgiQ2FsaWJyaSIsIDAsIDIwKSk7IC8vIE5PSTE4TgoKICAgICAgICBqVGV4dEZpZWxkMy5zZXRCYWNrZ3JvdW5kKG5ldyBqYXZhLmF3dC5Db2xvcigyMDQsIDIwNCwgMjA0KSk7CiAgICAgICAgalRleHRGaWVsZDMuc2V0Rm9udChuZXcgamF2YS5hd3QuRm9udCgiQ2FsaWJyaSIsIDAsIDIwKSk7IC8vIE5PSTE4TgoKICAgICAgICBqQnV0dG9uMi5zZXRGb250KG5ldyBqYXZhLmF3dC5Gb250KCJDYWxpYnJpIiwgMCwgMjQpKTsgLy8gTk9JMThOCiAgICAgICAgakJ1dHRvbjIuc2V0VGV4dCgiU3ByYXdkxboiKTsKICAgICAgICBqQnV0dG9uMi5zZXRFbmFibGVkKGZhbHNlKTsKICAgICAgICBqQnV0dG9uMi5zZXRNYXhpbXVtU2l6ZShuZXcgamF2YS5hd3QuRGltZW5zaW9uKDEyMCwgMzkpKTsKICAgICAgICBqQnV0dG9uMi5zZXRNaW5pbXVtU2l6ZShuZXcgamF2YS5hd3QuRGltZW5zaW9uKDEyMCwgMzkpKTsKICAgICAgICBqQnV0dG9uMi5zZXROYW1lKCIiKTsgLy8gTk9JMThOCiAgICAgICAgakJ1dHRvbjIuc2V0UHJlZmVycmVkU2l6ZShuZXcgamF2YS5hd3QuRGltZW5zaW9uKDEyMCwgMzkpKTsKICAgICAgICBqQnV0dG9uMi5hZGRNb3VzZUxpc3RlbmVyKG5ldyBqYXZhLmF3dC5ldmVudC5Nb3VzZUFkYXB0ZXIoKSB7CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIG1vdXNlQ2xpY2tlZChqYXZhLmF3dC5ldmVudC5Nb3VzZUV2ZW50IGV2dCkgewogICAgICAgICAgICAgICAgakJ1dHRvbjJNb3VzZUNsaWNrZWQoZXZ0KTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIGpCdXR0b24yLmFkZEFjdGlvbkxpc3RlbmVyKG5ldyBqYXZhLmF3dC5ldmVudC5BY3Rpb25MaXN0ZW5lcigpIHsKICAgICAgICAgICAgcHVibGljIHZvaWQgYWN0aW9uUGVyZm9ybWVkKGphdmEuYXd0LmV2ZW50LkFjdGlvbkV2ZW50IGV2dCkgewogICAgICAgICAgICAgICAgakJ1dHRvbjJBY3Rpb25QZXJmb3JtZWQoZXZ0KTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIGpCdXR0b24yLmFkZEtleUxpc3RlbmVyKG5ldyBqYXZhLmF3dC5ldmVudC5LZXlBZGFwdGVyKCkgewogICAgICAgICAgICBwdWJsaWMgdm9pZCBrZXlSZWxlYXNlZChqYXZhLmF3dC5ldmVudC5LZXlFdmVudCBldnQpIHsKICAgICAgICAgICAgICAgIGpCdXR0b24yS2V5UmVsZWFzZWQoZXZ0KTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwoKICAgICAgICBqTGFiZWwyLnNldEhvcml6b250YWxBbGlnbm1lbnQoamF2YXguc3dpbmcuU3dpbmdDb25zdGFudHMuQ0VOVEVSKTsKICAgICAgICBqTGFiZWwyLnNldFRleHQoImpMYWJlbDIiKTsKCiAgICAgICAgakxhYmVsMy5zZXRIb3Jpem9udGFsQWxpZ25tZW50KGphdmF4LnN3aW5nLlN3aW5nQ29uc3RhbnRzLkNFTlRFUik7CiAgICAgICAgakxhYmVsMy5zZXRUZXh0KCJqTGFiZWwyIik7CgogICAgICAgIGpMYWJlbDQuc2V0SG9yaXpvbnRhbEFsaWdubWVudChqYXZheC5zd2luZy5Td2luZ0NvbnN0YW50cy5DRU5URVIpOwogICAgICAgIGpMYWJlbDQuc2V0VGV4dCgiakxhYmVsMiIpOwoKICAgICAgICBqU2xpZGVyMS5zZXRNaW5pbXVtKDEpOwogICAgICAgIGpTbGlkZXIxLnNldFZhbHVlKDIwKTsKICAgICAgICBqU2xpZGVyMS5hZGRDaGFuZ2VMaXN0ZW5lcihuZXcgamF2YXguc3dpbmcuZXZlbnQuQ2hhbmdlTGlzdGVuZXIoKSB7CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHN0YXRlQ2hhbmdlZChqYXZheC5zd2luZy5ldmVudC5DaGFuZ2VFdmVudCBldnQpIHsKICAgICAgICAgICAgICAgIGpTbGlkZXIxU3RhdGVDaGFuZ2VkKGV2dCk7CiAgICAgICAgICAgIH0KICAgICAgICB9KTsKICAgICAgICBqU2xpZGVyMS5hZGRNb3VzZUxpc3RlbmVyKG5ldyBqYXZhLmF3dC5ldmVudC5Nb3VzZUFkYXB0ZXIoKSB7CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIG1vdXNlQ2xpY2tlZChqYXZhLmF3dC5ldmVudC5Nb3VzZUV2ZW50IGV2dCkgewogICAgICAgICAgICAgICAgalNsaWRlcjFNb3VzZUNsaWNrZWQoZXZ0KTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwoKICAgICAgICBqVGV4dEZpZWxkNC5zZXRCYWNrZ3JvdW5kKG5ldyBqYXZhLmF3dC5Db2xvcigyNDAsIDI0MCwgMjQwKSk7CiAgICAgICAgalRleHRGaWVsZDQuc2V0SG9yaXpvbnRhbEFsaWdubWVudChqYXZheC5zd2luZy5KVGV4dEZpZWxkLkNFTlRFUik7CiAgICAgICAgalRleHRGaWVsZDQuc2V0VGV4dCgiMjAiKTsKICAgICAgICBqVGV4dEZpZWxkNC5hZGRDYXJldExpc3RlbmVyKG5ldyBqYXZheC5zd2luZy5ldmVudC5DYXJldExpc3RlbmVyKCkgewogICAgICAgICAgICBwdWJsaWMgdm9pZCBjYXJldFVwZGF0ZShqYXZheC5zd2luZy5ldmVudC5DYXJldEV2ZW50IGV2dCkgewogICAgICAgICAgICAgICAgalRleHRGaWVsZDRDYXJldFVwZGF0ZShldnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICAgICAgalRleHRGaWVsZDQuYWRkQWN0aW9uTGlzdGVuZXIobmV3IGphdmEuYXd0LmV2ZW50LkFjdGlvbkxpc3RlbmVyKCkgewogICAgICAgICAgICBwdWJsaWMgdm9pZCBhY3Rpb25QZXJmb3JtZWQoamF2YS5hd3QuZXZlbnQuQWN0aW9uRXZlbnQgZXZ0KSB7CiAgICAgICAgICAgICAgICBqVGV4dEZpZWxkNEFjdGlvblBlcmZvcm1lZChldnQpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CgogICAgICAgIGpNZW51MS5zZXRUZXh0KCJQbGlrIik7CgogICAgICAgIGpNZW51SXRlbTEuc2V0VGV4dCgiUmVzZXR1aiBzdGF0eXN0eWtpIik7CiAgICAgICAgak1lbnVJdGVtMS5hZGRBY3Rpb25MaXN0ZW5lcihuZXcgamF2YS5hd3QuZXZlbnQuQWN0aW9uTGlzdGVuZXIoKSB7CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIGFjdGlvblBlcmZvcm1lZChqYXZhLmF3dC5ldmVudC5BY3Rpb25FdmVudCBldnQpIHsKICAgICAgICAgICAgICAgIGpNZW51SXRlbTFBY3Rpb25QZXJmb3JtZWQoZXZ0KTsKICAgICAgICAgICAgfQogICAgICAgIH0pOwogICAgICAgIGpNZW51MS5hZGQoak1lbnVJdGVtMSk7CgogICAgICAgIGpNZW51QmFyMS5hZGQoak1lbnUxKTsKCiAgICAgICAgc2V0Sk1lbnVCYXIoak1lbnVCYXIxKTsKCiAgICAgICAgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQgbGF5b3V0ID0gbmV3IGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0KGdldENvbnRlbnRQYW5lKCkpOwogICAgICAgIGdldENvbnRlbnRQYW5lKCkuc2V0TGF5b3V0KGxheW91dCk7CiAgICAgICAgbGF5b3V0LnNldEhvcml6b250YWxHcm91cCgKICAgICAgICAgICAgbGF5b3V0LmNyZWF0ZVBhcmFsbGVsR3JvdXAoamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuQWxpZ25tZW50LkxFQURJTkcpCiAgICAgICAgICAgIC5hZGRHcm91cChsYXlvdXQuY3JlYXRlU2VxdWVudGlhbEdyb3VwKCkKICAgICAgICAgICAgICAgIC5hZGRDb250YWluZXJHYXAoKQogICAgICAgICAgICAgICAgLmFkZEdyb3VwKGxheW91dC5jcmVhdGVQYXJhbGxlbEdyb3VwKGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LkFsaWdubWVudC5MRUFESU5HKQogICAgICAgICAgICAgICAgICAgIC5hZGRHcm91cChsYXlvdXQuY3JlYXRlU2VxdWVudGlhbEdyb3VwKCkKICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENvbXBvbmVudChqTGFiZWwxLCBqYXZheC5zd2luZy5Hcm91cExheW91dC5QUkVGRVJSRURfU0laRSwgNDg3LCBqYXZheC5zd2luZy5Hcm91cExheW91dC5QUkVGRVJSRURfU0laRSkKICAgICAgICAgICAgICAgICAgICAgICAgLmFkZEdhcCgwLCAwLCBTaG9ydC5NQVhfVkFMVUUpKQogICAgICAgICAgICAgICAgICAgIC5hZGRHcm91cChsYXlvdXQuY3JlYXRlU2VxdWVudGlhbEdyb3VwKCkKICAgICAgICAgICAgICAgICAgICAgICAgLmFkZEdhcCgwLCAwLCBTaG9ydC5NQVhfVkFMVUUpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDb21wb25lbnQoalRleHRGaWVsZDQsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LlBSRUZFUlJFRF9TSVpFLCAzMywgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuUFJFRkVSUkVEX1NJWkUpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRQcmVmZXJyZWRHYXAoamF2YXguc3dpbmcuTGF5b3V0U3R5bGUuQ29tcG9uZW50UGxhY2VtZW50LlJFTEFURUQpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDb21wb25lbnQoalNsaWRlcjEsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LlBSRUZFUlJFRF9TSVpFLCA2OSwgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuUFJFRkVSUkVEX1NJWkUpKQogICAgICAgICAgICAgICAgICAgIC5hZGRHcm91cChsYXlvdXQuY3JlYXRlU2VxdWVudGlhbEdyb3VwKCkKICAgICAgICAgICAgICAgICAgICAgICAgLmFkZEdyb3VwKGxheW91dC5jcmVhdGVQYXJhbGxlbEdyb3VwKGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LkFsaWdubWVudC5UUkFJTElORywgZmFsc2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ29tcG9uZW50KGpMYWJlbDIsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LkRFRkFVTFRfU0laRSwgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuREVGQVVMVF9TSVpFLCBTaG9ydC5NQVhfVkFMVUUpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ29tcG9uZW50KGpUZXh0RmllbGQxLCBqYXZheC5zd2luZy5Hcm91cExheW91dC5ERUZBVUxUX1NJWkUsIDE1MCwgU2hvcnQuTUFYX1ZBTFVFKSkKICAgICAgICAgICAgICAgICAgICAgICAgLmFkZEdhcCgxOCwgMTgsIDE4KQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkR3JvdXAobGF5b3V0LmNyZWF0ZVBhcmFsbGVsR3JvdXAoamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuQWxpZ25tZW50LkxFQURJTkcpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ29tcG9uZW50KGpMYWJlbDMsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LkFsaWdubWVudC5UUkFJTElORywgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuREVGQVVMVF9TSVpFLCBqYXZheC5zd2luZy5Hcm91cExheW91dC5ERUZBVUxUX1NJWkUsIFNob3J0Lk1BWF9WQUxVRSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDb21wb25lbnQoalRleHRGaWVsZDIsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LkFsaWdubWVudC5UUkFJTElORywgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuUFJFRkVSUkVEX1NJWkUsIDE1MCwgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuUFJFRkVSUkVEX1NJWkUpKQogICAgICAgICAgICAgICAgICAgICAgICAuYWRkR2FwKDE4LCAxOCwgMTgpCiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRHcm91cChsYXlvdXQuY3JlYXRlUGFyYWxsZWxHcm91cChqYXZheC5zd2luZy5Hcm91cExheW91dC5BbGlnbm1lbnQuTEVBRElORywgZmFsc2UpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ29tcG9uZW50KGpUZXh0RmllbGQzLCBqYXZheC5zd2luZy5Hcm91cExheW91dC5ERUZBVUxUX1NJWkUsIDE1MCwgU2hvcnQuTUFYX1ZBTFVFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENvbXBvbmVudChqTGFiZWw0LCBqYXZheC5zd2luZy5Hcm91cExheW91dC5ERUZBVUxUX1NJWkUsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LkRFRkFVTFRfU0laRSwgU2hvcnQuTUFYX1ZBTFVFKSkpKQogICAgICAgICAgICAgICAgLmFkZENvbnRhaW5lckdhcCgpKQogICAgICAgICAgICAuYWRkR3JvdXAobGF5b3V0LmNyZWF0ZVNlcXVlbnRpYWxHcm91cCgpCiAgICAgICAgICAgICAgICAuYWRkR2FwKDk1LCA5NSwgOTUpCiAgICAgICAgICAgICAgICAuYWRkQ29tcG9uZW50KGpCdXR0b24yLCBqYXZheC5zd2luZy5Hcm91cExheW91dC5QUkVGRVJSRURfU0laRSwgMTUwLCBqYXZheC5zd2luZy5Hcm91cExheW91dC5QUkVGRVJSRURfU0laRSkKICAgICAgICAgICAgICAgIC5hZGRHYXAoMTgsIDE4LCAxOCkKICAgICAgICAgICAgICAgIC5hZGRDb21wb25lbnQoakJ1dHRvbjEsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LlBSRUZFUlJFRF9TSVpFLCAxNTAsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LlBSRUZFUlJFRF9TSVpFKQogICAgICAgICAgICAgICAgLmFkZENvbnRhaW5lckdhcChqYXZheC5zd2luZy5Hcm91cExheW91dC5ERUZBVUxUX1NJWkUsIFNob3J0Lk1BWF9WQUxVRSkpCiAgICAgICAgKTsKICAgICAgICBsYXlvdXQuc2V0VmVydGljYWxHcm91cCgKICAgICAgICAgICAgbGF5b3V0LmNyZWF0ZVBhcmFsbGVsR3JvdXAoamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuQWxpZ25tZW50LkxFQURJTkcpCiAgICAgICAgICAgIC5hZGRHcm91cChqYXZheC5zd2luZy5Hcm91cExheW91dC5BbGlnbm1lbnQuVFJBSUxJTkcsIGxheW91dC5jcmVhdGVTZXF1ZW50aWFsR3JvdXAoKQogICAgICAgICAgICAgICAgLmFkZEdyb3VwKGxheW91dC5jcmVhdGVQYXJhbGxlbEdyb3VwKGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LkFsaWdubWVudC5MRUFESU5HKQogICAgICAgICAgICAgICAgICAgIC5hZGRDb21wb25lbnQoalRleHRGaWVsZDQsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LlBSRUZFUlJFRF9TSVpFLCAyMywgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuUFJFRkVSUkVEX1NJWkUpCiAgICAgICAgICAgICAgICAgICAgLmFkZENvbXBvbmVudChqU2xpZGVyMSwgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuUFJFRkVSUkVEX1NJWkUsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LkRFRkFVTFRfU0laRSwgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuUFJFRkVSUkVEX1NJWkUpKQogICAgICAgICAgICAgICAgLmFkZFByZWZlcnJlZEdhcChqYXZheC5zd2luZy5MYXlvdXRTdHlsZS5Db21wb25lbnRQbGFjZW1lbnQuUkVMQVRFRCkKICAgICAgICAgICAgICAgIC5hZGRDb21wb25lbnQoakxhYmVsMSwgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuUFJFRkVSUkVEX1NJWkUsIDQ4LCBqYXZheC5zd2luZy5Hcm91cExheW91dC5QUkVGRVJSRURfU0laRSkKICAgICAgICAgICAgICAgIC5hZGRHYXAoMiwgMiwgMikKICAgICAgICAgICAgICAgIC5hZGRHcm91cChsYXlvdXQuY3JlYXRlUGFyYWxsZWxHcm91cChqYXZheC5zd2luZy5Hcm91cExheW91dC5BbGlnbm1lbnQuQkFTRUxJTkUpCiAgICAgICAgICAgICAgICAgICAgLmFkZENvbXBvbmVudChqTGFiZWwyKQogICAgICAgICAgICAgICAgICAgIC5hZGRDb21wb25lbnQoakxhYmVsMykKICAgICAgICAgICAgICAgICAgICAuYWRkQ29tcG9uZW50KGpMYWJlbDQpKQogICAgICAgICAgICAgICAgLmFkZEdhcCgyLCAyLCAyKQogICAgICAgICAgICAgICAgLmFkZEdyb3VwKGxheW91dC5jcmVhdGVQYXJhbGxlbEdyb3VwKGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LkFsaWdubWVudC5CQVNFTElORSkKICAgICAgICAgICAgICAgICAgICAuYWRkQ29tcG9uZW50KGpUZXh0RmllbGQxLCBqYXZheC5zd2luZy5Hcm91cExheW91dC5QUkVGRVJSRURfU0laRSwgMzAsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LlBSRUZFUlJFRF9TSVpFKQogICAgICAgICAgICAgICAgICAgIC5hZGRDb21wb25lbnQoalRleHRGaWVsZDIsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LlBSRUZFUlJFRF9TSVpFLCAzMCwgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuUFJFRkVSUkVEX1NJWkUpCiAgICAgICAgICAgICAgICAgICAgLmFkZENvbXBvbmVudChqVGV4dEZpZWxkMywgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuUFJFRkVSUkVEX1NJWkUsIDMwLCBqYXZheC5zd2luZy5Hcm91cExheW91dC5QUkVGRVJSRURfU0laRSkpCiAgICAgICAgICAgICAgICAuYWRkR2FwKDE4LCAxOCwgMTgpCiAgICAgICAgICAgICAgICAuYWRkR3JvdXAobGF5b3V0LmNyZWF0ZVBhcmFsbGVsR3JvdXAoamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuQWxpZ25tZW50LkJBU0VMSU5FKQogICAgICAgICAgICAgICAgICAgIC5hZGRDb21wb25lbnQoakJ1dHRvbjIsIGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LlBSRUZFUlJFRF9TSVpFLCA0NCwgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuUFJFRkVSUkVEX1NJWkUpCiAgICAgICAgICAgICAgICAgICAgLmFkZENvbXBvbmVudChqQnV0dG9uMSwgamF2YXguc3dpbmcuR3JvdXBMYXlvdXQuUFJFRkVSUkVEX1NJWkUsIDQ0LCBqYXZheC5zd2luZy5Hcm91cExheW91dC5QUkVGRVJSRURfU0laRSkpCiAgICAgICAgICAgICAgICAuYWRkQ29udGFpbmVyR2FwKGphdmF4LnN3aW5nLkdyb3VwTGF5b3V0LkRFRkFVTFRfU0laRSwgU2hvcnQuTUFYX1ZBTFVFKSkKICAgICAgICApOwoKICAgICAgICBwYWNrKCk7CiAgICB9Ly8gPC9lZGl0b3ItZm9sZD4gICAgICAgICAgICAgICAgICAgICAgICAKCiAgICBwcml2YXRlIHZvaWQgakJ1dHRvbjFNb3VzZUNsaWNrZWQoamF2YS5hd3QuZXZlbnQuTW91c2VFdmVudCBldnQpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgIC8vIFRPRE8gYWRkIHlvdXIgaGFuZGxpbmcgY29kZSBoZXJlOgogICAgICAgIGlmICh0ZXN0ID09IGZhbHNlKSB7CiAgICAgICAgICAgIHRlc3QgPSB0aGlzLm5hc3RlcG55KCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGVzdCA9IHRoaXMubG9zdWpJbmRla3N5KGpTbGlkZXIxLmdldFZhbHVlKCkpOwogICAgICAgICAgICBqU2xpZGVyMS5zZXRFbmFibGVkKGZhbHNlKTsKICAgICAgICAgICAgalRleHRGaWVsZDQuc2V0RW5hYmxlZChmYWxzZSk7CiAgICAgICAgICAgIGpCdXR0b24xLnNldFRleHQoIk5hc3TEmXBueSIpOwogICAgICAgICAgICB0ZXN0ID0gdGhpcy5uYXN0ZXBueSgpOwogICAgICAgICAgICB0aGlzLmFrdHl3dWoodHJ1ZSk7CiAgICAgICAgfQogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCiAgICBwcml2YXRlIHZvaWQgakJ1dHRvbjJNb3VzZUNsaWNrZWQoamF2YS5hd3QuZXZlbnQuTW91c2VFdmVudCBldnQpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgIC8vIFRPRE8gYWRkIHlvdXIgaGFuZGxpbmcgY29kZSBoZXJlOgogICAgICAgIGlmKGpCdXR0b24yLmlzRW5hYmxlZCgpKXsKICAgICAgICAgICAgdGhpcy5zcHJhd2R6KCk7CiAgICAgICAgfQogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgogICAgcHJpdmF0ZSB2b2lkIGpNZW51SXRlbTFBY3Rpb25QZXJmb3JtZWQoamF2YS5hd3QuZXZlbnQuQWN0aW9uRXZlbnQgZXZ0KSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgIC8vIFRPRE8gYWRkIHlvdXIgaGFuZGxpbmcgY29kZSBoZXJlOgogICAgICAgIGR6aWFsYWogPSBuZXcgRHppYWxhaigiY3phc293bmlraTIuc2VyIik7CiAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgogICAgcHJpdmF0ZSB2b2lkIGpCdXR0b24yS2V5UmVsZWFzZWQoamF2YS5hd3QuZXZlbnQuS2V5RXZlbnQgZXZ0KSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgIC8vIFRPRE8gYWRkIHlvdXIgaGFuZGxpbmcgY29kZSBoZXJlOgogICAgICAgIGlmKGpCdXR0b24yLmlzRW5hYmxlZCgpKXsKICAgICAgICAgICAgdGhpcy5zcHJhd2R6KCk7CiAgICAgICAgfQogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAoKICAgIHByaXZhdGUgdm9pZCBqVGV4dEZpZWxkNEFjdGlvblBlcmZvcm1lZChqYXZhLmF3dC5ldmVudC5BY3Rpb25FdmVudCBldnQpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgIC8vIFRPRE8gYWRkIHlvdXIgaGFuZGxpbmcgY29kZSBoZXJlOgogICAgICAgIGpTbGlkZXIxLnNldFZhbHVlKEludGVnZXIucGFyc2VJbnQoalRleHRGaWVsZDQuZ2V0VGV4dCgpKSk7CiAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKCiAgICBwcml2YXRlIHZvaWQgalNsaWRlcjFTdGF0ZUNoYW5nZWQoamF2YXguc3dpbmcuZXZlbnQuQ2hhbmdlRXZlbnQgZXZ0KSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAvLyBUT0RPIGFkZCB5b3VyIGhhbmRsaW5nIGNvZGUgaGVyZToKICAgICAgICBqVGV4dEZpZWxkNC5zZXRUZXh0KEludGVnZXIudG9TdHJpbmcoalNsaWRlcjEuZ2V0VmFsdWUoKSkpOwogICAgICAgIGxvc3VqSW5kZWtzeShqU2xpZGVyMS5nZXRWYWx1ZSgpKTsKICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCgogICAgLyoqCiAgICAgKiBAcGFyYW0gYXJncyB0aGUgY29tbWFuZCBsaW5lIGFyZ3VtZW50cwogICAgICovCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJnc1tdKSB7CiAgICAgICAgLyogU2V0IHRoZSBOaW1idXMgbG9vayBhbmQgZmVlbCAqLwogICAgICAgIC8vPGVkaXRvci1mb2xkIGRlZmF1bHRzdGF0ZT0iY29sbGFwc2VkIiBkZXNjPSIgTG9vayBhbmQgZmVlbCBzZXR0aW5nIGNvZGUgKG9wdGlvbmFsKSAiPgogICAgICAgIC8qIElmIE5pbWJ1cyAoaW50cm9kdWNlZCBpbiBKYXZhIFNFIDYpIGlzIG5vdCBhdmFpbGFibGUsIHN0YXkgd2l0aCB0aGUgZGVmYXVsdCBsb29rIGFuZCBmZWVsLgogICAgICAgICAqIEZvciBkZXRhaWxzIHNlZSBodHRwOi8vZC4uLmNvbnRlbnQtYXZhaWxhYmxlLXRvLWF1dGhvci1vbmx5Li4uZS5jb20vamF2YXNlL3R1dG9yaWFsL3Vpc3dpbmcvbG9va2FuZGZlZWwvcGxhZi5odG1sIAogICAgICAgICAqLwogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGZvciAoamF2YXguc3dpbmcuVUlNYW5hZ2VyLkxvb2tBbmRGZWVsSW5mbyBpbmZvIDogamF2YXguc3dpbmcuVUlNYW5hZ2VyLmdldEluc3RhbGxlZExvb2tBbmRGZWVscygpKSB7CiAgICAgICAgICAgICAgICBpZiAoIk5pbWJ1cyIuZXF1YWxzKGluZm8uZ2V0TmFtZSgpKSkgewogICAgICAgICAgICAgICAgICAgIGphdmF4LnN3aW5nLlVJTWFuYWdlci5zZXRMb29rQW5kRmVlbChpbmZvLmdldENsYXNzTmFtZSgpKTsKICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0gY2F0Y2ggKENsYXNzTm90Rm91bmRFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyLmdldExvZ2dlcihOaWVyZWd1bGFybmUuY2xhc3MuZ2V0TmFtZSgpKS5sb2coamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWwuU0VWRVJFLCBudWxsLCBleCk7CiAgICAgICAgfSBjYXRjaCAoSW5zdGFudGlhdGlvbkV4Y2VwdGlvbiBleCkgewogICAgICAgICAgICBqYXZhLnV0aWwubG9nZ2luZy5Mb2dnZXIuZ2V0TG9nZ2VyKE5pZXJlZ3VsYXJuZS5jbGFzcy5nZXROYW1lKCkpLmxvZyhqYXZhLnV0aWwubG9nZ2luZy5MZXZlbC5TRVZFUkUsIG51bGwsIGV4KTsKICAgICAgICB9IGNhdGNoIChJbGxlZ2FsQWNjZXNzRXhjZXB0aW9uIGV4KSB7CiAgICAgICAgICAgIGphdmEudXRpbC5sb2dnaW5nLkxvZ2dlci5nZXRMb2dnZXIoTmllcmVndWxhcm5lLmNsYXNzLmdldE5hbWUoKSkubG9nKGphdmEudXRpbC5sb2dnaW5nLkxldmVsLlNFVkVSRSwgbnVsbCwgZXgpOwogICAgICAgIH0gY2F0Y2ggKGphdmF4LnN3aW5nLlVuc3VwcG9ydGVkTG9va0FuZEZlZWxFeGNlcHRpb24gZXgpIHsKICAgICAgICAgICAgamF2YS51dGlsLmxvZ2dpbmcuTG9nZ2VyLmdldExvZ2dlcihOaWVyZWd1bGFybmUuY2xhc3MuZ2V0TmFtZSgpKS5sb2coamF2YS51dGlsLmxvZ2dpbmcuTGV2ZWwuU0VWRVJFLCBudWxsLCBleCk7CiAgICAgICAgfQogICAgICAgIC8vPC9lZGl0b3ItZm9sZD4KCiAgICAgICAgLyogQ3JlYXRlIGFuZCBkaXNwbGF5IHRoZSBmb3JtICovCiAgICAgICAgamF2YS5hd3QuRXZlbnRRdWV1ZS5pbnZva2VMYXRlcihuZXcgUnVubmFibGUoKSB7CiAgICAgICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpIHsKICAgICAgICAgICAgICAgIG5ldyBOaWVyZWd1bGFybmUoKS5zZXRWaXNpYmxlKHRydWUpOwogICAgICAgICAgICB9CiAgICAgICAgfSk7CiAgICB9CiAgICAKICAgIHB1YmxpYyB2b2lkIGFrdHl3dWooYm9vbGVhbiBiKXsKICAgICAgICBqVGV4dEZpZWxkMS5zZXRFbmFibGVkKGIpOwogICAgICAgIGpUZXh0RmllbGQyLnNldEVuYWJsZWQoYik7CiAgICAgICAgalRleHRGaWVsZDMuc2V0RW5hYmxlZChiKTsKICAgICAgICBqQnV0dG9uMi5zZXRFbmFibGVkKGIpOwogICAgfQoKICAgIHB1YmxpYyBib29sZWFuIGxvc3VqSW5kZWtzeShpbnQgaSkgewogICAgICAgIGluZGVrc3kgPSBkemlhbGFqLmxvc3VqTGlzdGUoaSk7CiAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgfQoKICAgIHB1YmxpYyB2b2lkIHJlc2V0KCl7CiAgICAgICAgalRleHRGaWVsZDEuc2V0Rm9yZWdyb3VuZChDb2xvci5CTEFDSyk7CiAgICAgICAgalRleHRGaWVsZDIuc2V0Rm9yZWdyb3VuZChDb2xvci5CTEFDSyk7CiAgICAgICAgalRleHRGaWVsZDMuc2V0Rm9yZWdyb3VuZChDb2xvci5CTEFDSyk7CiAgICAgICAgalRleHRGaWVsZDEuc2V0VGV4dCgiIik7CiAgICAgICAgalRleHRGaWVsZDIuc2V0VGV4dCgiIik7CiAgICAgICAgalRleHRGaWVsZDMuc2V0VGV4dCgiIik7CiAgICB9CiAgICAvKnB1YmxpYyBjbGFzcyBXYXRlayBpbXBsZW1lbnRzIFJ1bm5hYmxlewogICAgICAgIHB1YmxpYyB2b2lkIHJ1bigpewogICAgICAgICAgICBzcHJhd2R6KCk7CiAgICAgICAgfQogICAgfSovCiAgICBwdWJsaWMgYm9vbGVhbiBuYXN0ZXBueSgpIHsKICAgICAgICBpZihqQnV0dG9uMi5pc0VuYWJsZWQoKSl7CiAgICAgICAgICAgIC8qUnVubmFibGUgdzIgPSBuZXcgV2F0ZWsoKTsKICAgICAgICAgICAgVGhyZWFkIHdhdGVrMiA9IG5ldyBUaHJlYWQodzIpOwogICAgICAgICAgICB3YXRlazIuc3RhcnQoKTsqLwogICAgICAgICAgICBzcHJhd2R6KCk7CiAgICAgICAgICAgIGN6ZWthaigpOwogICAgICAgIH0KICAgICAgICBpbmRleCsrOwogICAgICAgIGlmIChpbmRla3N5LmlzRW1wdHkoKSkgewogICAgICAgICAgICBqTGFiZWwxLnNldFRleHQoIktvbmllYyIpOwogICAgICAgICAgICBqQnV0dG9uMS5zZXRUZXh0KCJMb3N1aiIpOwogICAgICAgICAgICBqU2xpZGVyMS5zZXRFbmFibGVkKHRydWUpOwogICAgICAgICAgICBqVGV4dEZpZWxkNC5zZXRFbmFibGVkKHRydWUpOwogICAgICAgICAgICB0aGlzLmFrdHl3dWooZmFsc2UpOwogICAgICAgICAgICBkemlhbGFqLnNlcmlhbGl6dWooKTsKICAgICAgICAgICAgdGhpcy5yZXNldCgpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgaWYgKGluZGV4ID09IGluZGVrc3kuc2l6ZSgpKSB7CiAgICAgICAgICAgIGluZGV4ID0gMDsKICAgICAgICB9CiAgICAgICAgakxhYmVsMS5zZXRUZXh0KGR6aWFsYWouZ2V0Q29uY3JldChpbmRla3N5LmdldChpbmRleCkpLmdldEVuZzEoKSk7CiAgICAgICAgakxhYmVsMi5zZXRUZXh0KGR6aWFsYWouZ2V0Q29uY3JldChpbmRla3N5LmdldChpbmRleCkpLmdldEVuZzIoKSk7CiAgICAgICAgakxhYmVsMy5zZXRUZXh0KGR6aWFsYWouZ2V0Q29uY3JldChpbmRla3N5LmdldChpbmRleCkpLmdldEVuZzMoKSk7CiAgICAgICAgakxhYmVsNC5zZXRUZXh0KGR6aWFsYWouZ2V0Q29uY3JldChpbmRla3N5LmdldChpbmRleCkpLmdldFBvbCgpKTsKICAgICAgICB0aGlzLnJlc2V0KCk7CiAgICAgICAgakJ1dHRvbjIuc2V0RW5hYmxlZCh0cnVlKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBwdWJsaWMgdm9pZCBjemVrYWooKXsKICAgICAgICB0cnl7CiAgICAgICAgICAgIFRocmVhZC5zbGVlcCg1MDAwKTsKICAgICAgICB9Y2F0Y2goSW50ZXJydXB0ZWRFeGNlcHRpb24gZXgpewogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIk5pZSBtb3puYSB6YXRyenltYcSHIHByb2dyYW11Iik7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyB2b2lkIHNwcmF3ZHooKSB7CiAgICAgICAgLyoqCiAgICAgICAgICogU3ByYXdkemFteSBwb2tvbGVpIGN6eSB3cHJvd2Fkem9ubyBwb3ByYXduxIUgd2FydG/Fm8SHLiBKZcWbbGkgdGFrLAogICAgICAgICAqIHVzdGF3aWFteSB6aWVsb25lIHTFgm8gSmXFm2xpIG5pZSwgdXN0YXdpYW15IGN6ZXJ3b25lIHTFgm8KICAgICAgICAgKi8KICAgICAgICBmaW5hbCBDb2xvciBaSUVMT05ZID0gbmV3IENvbG9yKDAsMTUzLDApOwogICAgICAgIGJvb2xlYW4gd3luaWsxID0gZHppYWxhai5zcHJhd2R6Q3phc293bmlrKGR6aWFsYWouZ2V0Q29uY3JldChpbmRla3N5LmdldChpbmRleCkpLmdldEVuZzIoKSwgalRleHRGaWVsZDEuZ2V0VGV4dCgpKTsKICAgICAgICBpZiAod3luaWsxID09IHRydWUpIHsKICAgICAgICAgICAgalRleHRGaWVsZDEuc2V0Rm9yZWdyb3VuZChaSUVMT05ZKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBqVGV4dEZpZWxkMS5zZXRGb3JlZ3JvdW5kKENvbG9yLlJFRCk7CiAgICAgICAgICAgIGpUZXh0RmllbGQxLnNldFRleHQoZHppYWxhai5nZXRDb25jcmV0KGluZGVrc3kuZ2V0KGluZGV4KSkuZ2V0RW5nMigpKTsKICAgICAgICAgICAgLy9qVGV4dEZpZWxkMS5zZXRCYWNrZ3JvdW5kKENvbG9yLlJFRCk7CiAgICAgICAgfQogICAgICAgIGJvb2xlYW4gd3luaWsyID0gZHppYWxhai5zcHJhd2R6Q3phc293bmlrKGR6aWFsYWouZ2V0Q29uY3JldChpbmRla3N5LmdldChpbmRleCkpLmdldEVuZzMoKSwgalRleHRGaWVsZDIuZ2V0VGV4dCgpKTsKICAgICAgICBpZiAod3luaWsyID09IHRydWUpIHsKICAgICAgICAgICAgalRleHRGaWVsZDIuc2V0Rm9yZWdyb3VuZChaSUVMT05ZKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBqVGV4dEZpZWxkMi5zZXRGb3JlZ3JvdW5kKENvbG9yLlJFRCk7CiAgICAgICAgICAgIGpUZXh0RmllbGQyLnNldFRleHQoZHppYWxhai5nZXRDb25jcmV0KGluZGVrc3kuZ2V0KGluZGV4KSkuZ2V0RW5nMygpKTsKICAgICAgICB9CiAgICAgICAgYm9vbGVhbiB3eW5pazMgPSBkemlhbGFqLnNwcmF3ZHpDemFzb3duaWsoZHppYWxhai5nZXRDb25jcmV0KGluZGVrc3kuZ2V0KGluZGV4KSkuZ2V0UG9sKCksIGpUZXh0RmllbGQzLmdldFRleHQoKSk7CiAgICAgICAgaWYgKHd5bmlrMyA9PSB0cnVlKSB7CiAgICAgICAgICAgIGpUZXh0RmllbGQzLnNldEZvcmVncm91bmQoWklFTE9OWSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgalRleHRGaWVsZDMuc2V0Rm9yZWdyb3VuZChDb2xvci5SRUQpOwogICAgICAgICAgICBqVGV4dEZpZWxkMy5zZXRUZXh0KGR6aWFsYWouZ2V0Q29uY3JldChpbmRla3N5LmdldChpbmRleCkpLmdldFBvbCgpKTsKICAgICAgICB9CiAgICAgICAgLyoqCiAgICAgICAgICogU3ByYXdkemFteSBjenkgd3N6eXN0a2llIHBvbGEgem9zdGHFgnkgcG9wcmF3bmllIHV6dXBlxYJuaW9uZS4gSmXFm2xpCiAgICAgICAgICogbmllLCB1c3Rhd2lhbXkgYsWCxJlkbsSFIG9kcG93aWVkxbogSmXFm2xpIHRhaywgdXN0YXdpYW15IHBvcHJhd27EhQogICAgICAgICAqIG9kcG93ZWlkxbosIHVzdXdhbXkgdG8gc8WCb3dvIHogYWt0dWFsbmVqIGxpc3R5LCBvYm5pxbxhbXkgaW5kZXguCioKICAgICAgICAgKi8KICAgICAgICBpZiAod3luaWsxICE9IHRydWUgfHwgd3luaWsyICE9IHRydWUgfHwgd3luaWszICE9IHRydWUpIHsKICAgICAgICAgICAgZHppYWxhai5nZXRDb25jcmV0KGluZGVrc3kuZ2V0KGluZGV4KSkuc2V0V3luaWsoZmFsc2UpOwogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZHppYWxhai5nZXRDb25jcmV0KGluZGVrc3kuZ2V0KGluZGV4KSkpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGR6aWFsYWouZ2V0Q29uY3JldChpbmRla3N5LmdldChpbmRleCkpLnNldFd5bmlrKHRydWUpOwogICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZHppYWxhai5nZXRDb25jcmV0KGluZGVrc3kuZ2V0KGluZGV4KSkpOwogICAgICAgICAgICBpbmRla3N5LnJlbW92ZShpbmRleCk7CiAgICAgICAgICAgIGluZGV4LS07CiAgICAgICAgfQogICAgICAgIGpCdXR0b24yLnNldEVuYWJsZWQoZmFsc2UpOwogICAgfQoKICAgIER6aWFsYWogZHppYWxhajsKICAgIEFycmF5TGlzdDxJbnRlZ2VyPiBpbmRla3N5OwogICAgcHJpdmF0ZSBpbnQgaW5kZXggPSAtMTsKICAgIGJvb2xlYW4gdGVzdCA9IHRydWU7CiAgICAvLyBWYXJpYWJsZXMgZGVjbGFyYXRpb24gLSBkbyBub3QgbW9kaWZ5ICAgICAgICAgICAgICAgICAgICAgCiAgICBwcml2YXRlIGphdmF4LnN3aW5nLkpCdXR0b24gakJ1dHRvbjE7CiAgICBwcml2YXRlIGphdmF4LnN3aW5nLkpCdXR0b24gakJ1dHRvbjI7CiAgICBwcml2YXRlIGphdmF4LnN3aW5nLkpMYWJlbCBqTGFiZWwxOwogICAgcHJpdmF0ZSBqYXZheC5zd2luZy5KTGFiZWwgakxhYmVsMjsKICAgIHByaXZhdGUgamF2YXguc3dpbmcuSkxhYmVsIGpMYWJlbDM7CiAgICBwcml2YXRlIGphdmF4LnN3aW5nLkpMYWJlbCBqTGFiZWw0OwogICAgcHJpdmF0ZSBqYXZheC5zd2luZy5KTWVudSBqTWVudTE7CiAgICBwcml2YXRlIGphdmF4LnN3aW5nLkpNZW51QmFyIGpNZW51QmFyMTsKICAgIHByaXZhdGUgamF2YXguc3dpbmcuSk1lbnVJdGVtIGpNZW51SXRlbTE7CiAgICBwcml2YXRlIGphdmF4LnN3aW5nLkpTbGlkZXIgalNsaWRlcjE7CiAgICBwcml2YXRlIGphdmF4LnN3aW5nLkpUZXh0RmllbGQgalRleHRGaWVsZDE7CiAgICBwcml2YXRlIGphdmF4LnN3aW5nLkpUZXh0RmllbGQgalRleHRGaWVsZDI7CiAgICBwcml2YXRlIGphdmF4LnN3aW5nLkpUZXh0RmllbGQgalRleHRGaWVsZDM7CiAgICBwcml2YXRlIGphdmF4LnN3aW5nLkpUZXh0RmllbGQgalRleHRGaWVsZDQ7CiAgICAvLyBFbmQgb2YgdmFyaWFibGVzIGRlY2xhcmF0aW9uICAgICAgICAgICAgICAgICAgIAp9Cg==