#include <includes.h>
//AARRGGBB
struct button_color
{
DWORD button;
DWORD border;
DWORD text;
button_color(){}
~button_color(){}
button_color(DWORD color_button,DWORD color_border,DWORD color_text)
: button(color_button),border(color_border),text(color_text)
{}
};
class button
{
public:
std::string text_;
button_color appearance_;
button_color highlighted_;
button_color mousedown_;
bool clickable_;
bool highlight_;
unsigned short vkkey_;
int fontid_;
button(){}
~button(){}
button(std::string button_text,button_color &appearance, button_color &highlighted, button_color &mousedown, bool clickable, bool highlight, int fontid = 1, unsigned short vkkey = VK_LBUTTON)
: text_(button_text), appearance_(appearance), highlighted_(highlighted), clickable_(clickable), highlight_(highlight), mousedown_(mousedown), vkkey_(vkkey), fontid_(fontid)
{}
std::function<void(void)> callback;
template<class Functor> button(Functor&& f) : callback(std::forward<Functor>(f))
{
}
template<class Functor> void SetFunction(Functor&& f)
{
callback = std::forward<Functor>(f);
}
void SetInfo(std::string button_text,button_color &appearance, button_color &highlighted, button_color &mousedown, bool clickable, bool highlight, int fontid = 1, unsigned short vkkey = VK_LBUTTON)
{
text_.assign(button_text);
appearance_ = appearance;
highlighted_ = highlighted;
clickable_ = clickable;
highlight_ = highlight;
mousedown_ = mousedown;
vkkey_ = vkkey;
fontid_ = fontid;
}
float GetLenght()
{
return DirectXFont::Access(fontid_)->DrawLength(text_.c_str());
}
float GetHeight()
{
return DirectXFont::Access(fontid_)->DrawHeight();
}
bool IsCursorOnThis(float btn_x, float btn_y, float btn_w, float btn_h)
{
return IsPointInArea(cursorPos.x,cursorPos.y,btn_x,btn_y,btn_w,btn_h);
}
void Display(float btn_x, float btn_y, float btn_w, float btn_h)
{
if(!IsPointInArea(cursorPos.x,cursorPos.y,btn_x,btn_y,btn_w,btn_h))
{
render->D3DBoxBorder(btn_x,btn_y,btn_w,btn_h,appearance_.border,appearance_.button);
DirectXFont::Access(fontid_)->Print(btn_x+((btn_w-GetLenght())/2.0f),btn_y+((btn_h-GetHeight())/2.0f),appearance_.text,text_.c_str(),true);
return;
}
if(!clickable_)
{
render->D3DBoxBorder(btn_x,btn_y,btn_w,btn_h,(highlight_)? highlighted_.border : appearance_.border,(highlight_)? highlighted_.button : appearance_.button);
DirectXFont::Access(fontid_)->Print(btn_x+((btn_w-GetLenght())/2.0f),btn_y+((btn_h-GetHeight())/2.0f),(highlight_)? highlighted_.text : appearance_.text,text_.c_str(),true);
return;
}
if(!OldKeys(vkkey_).Down)
{
render->D3DBoxBorder(btn_x,btn_y,btn_w,btn_h,(highlight_)? highlighted_.border : appearance_.border,(highlight_)? highlighted_.button : appearance_.button);
DirectXFont::Access(fontid_)->Print(btn_x+((btn_w-GetLenght())/2.0f),btn_y+((btn_h-GetHeight())/2.0f),(highlight_)? highlighted_.text : appearance_.text,text_.c_str(),true);
return;
}
if(!Keys(vkkey_).Released)
{
render->D3DBoxBorder(btn_x,btn_y,btn_w,btn_h, mousedown_.border,mousedown_.button);
DirectXFont::Access(fontid_)->Print(btn_x+((btn_w-GetLenght())/2.0f),btn_y+((btn_h-GetHeight())/2.0f), mousedown_.text,text_.c_str(),true);
return;
}
callback();
return;
}
void DisplayEx(float btn_x, float btn_y, float btn_w, float btn_h)
{
Display(btn_x, btn_y,GetLenght()+btn_w, GetHeight()+btn_h);
}
};
class Menu
{
public:
std::vector<std::shared_ptr<button>> Buttons_;
float pos_top_;
float pos_left_;
float spacing_;
float width_;
float height_;
DWORD BoxColor;
DWORD BorderColor;
std::string name_;
Menu()
{
pos_top_ = 0.0f;
pos_left_ = 0.0f;
spacing_ = 5.0f;
width_ = 0.0f;
height_ = 0.0f;
BoxColor = 0xFF330088;
BorderColor = 0xFF338800;
}
~Menu(){}
void SetupWidth()
{
width_ = 0.0f;
height_ = 0.0f;
for(unsigned int i = 0; i < Buttons_.size(); ++i)
{
if(width_ < Buttons_[i]->GetLenght())
{
width_ = Buttons_[i]->GetLenght();
}
if(height_ < Buttons_[i]->GetHeight())
{
height_ = Buttons_[i]->GetHeight();
}
}
}
void AddButton(std::shared_ptr<button> button)
{
Buttons_.push_back(button);
SetupWidth();
}
void RemoveButton(std::shared_ptr<button> button)
{
for(unsigned int i = 0; i < Buttons_.size(); ++i)
{
if(Buttons_[i] == button)
{
Buttons_.erase(Buttons_.begin()+i);
}
}
SetupWidth();
}
float GetWidth(bool horizontal = false)
{
if(!horizontal)
return (width_ + (spacing_ * 4.0f));
if(Buttons_.empty())
return spacing_;
return spacing_ + ((width_ + (3.0f * spacing_)) * ((float)Buttons_.size()));
}
float GetHeight(bool horizontal = false)
{
if(horizontal)
return (3.0f * spacing_) + height_;
if(Buttons_.empty())
return spacing_;
return spacing_ + (((float)Buttons_.size())*spacing_)+((spacing_ + height_)*((float)Buttons_.size()));
}
void Process(bool horizontal = false, bool central = true)
{
if(Buttons_.empty())
return;
if(central)
{
Pos((((float)ScreenX)/2.0f)-(GetWidth(horizontal)/2.0f),(((float)ScreenY)/2.0f)-(GetHeight(horizontal)/2.0f));
}
if(!horizontal)
{
render->D3DBoxBorder(pos_left_,pos_top_,(width_ + (spacing_ * 4.0f)),spacing_ + (((float)Buttons_.size())*spacing_)+((spacing_ + height_)*((float)Buttons_.size())), BorderColor,BoxColor);
for(unsigned int i = 0; i < Buttons_.size(); ++i)
{
Buttons_[i]->Display(pos_left_ + spacing_,pos_top_ + spacing_ + spacing_*((float)i) + ((spacing_ + height_)*(float)i),(width_ + (2.0f * spacing_)),height_+spacing_);
}
}
else
{
render->D3DBoxBorder(pos_left_,pos_top_,spacing_ + ((width_ + (3.0f * spacing_)) * ((float)Buttons_.size())),(3.0f * spacing_) + height_, BorderColor,BoxColor);
for(unsigned int i = 0; i < Buttons_.size(); ++i)
{
Buttons_[i]->Display(pos_left_ + spacing_ + ((width_ + (3.0f * spacing_)) * ((float)i)),pos_top_ + spacing_ ,(width_ + (2.0f * spacing_)),height_+spacing_);
}
}
}
void Pos(float x, float y)
{
pos_left_ = x;
pos_top_ = y;
}
void Colors(DWORD border,DWORD background)
{
BorderColor = border;
BoxColor = background;
}
};
I2luY2x1ZGUgPGluY2x1ZGVzLmg+CgovL0FBUlJHR0JCCnN0cnVjdCBidXR0b25fY29sb3IKewogICAgRFdPUkQgYnV0dG9uOwoJRFdPUkQgYm9yZGVyOwoJRFdPUkQgdGV4dDsKCWJ1dHRvbl9jb2xvcigpe30KCX5idXR0b25fY29sb3IoKXt9CglidXR0b25fY29sb3IoRFdPUkQgY29sb3JfYnV0dG9uLERXT1JEIGNvbG9yX2JvcmRlcixEV09SRCBjb2xvcl90ZXh0KQoJCTogYnV0dG9uKGNvbG9yX2J1dHRvbiksYm9yZGVyKGNvbG9yX2JvcmRlciksdGV4dChjb2xvcl90ZXh0KQoJe30KfTsKCmNsYXNzIGJ1dHRvbgp7CnB1YmxpYzoKCXN0ZDo6c3RyaW5nIHRleHRfOwoJYnV0dG9uX2NvbG9yIGFwcGVhcmFuY2VfOwoJYnV0dG9uX2NvbG9yIGhpZ2hsaWdodGVkXzsKCWJ1dHRvbl9jb2xvciBtb3VzZWRvd25fOwoJYm9vbCBjbGlja2FibGVfOwoJYm9vbCBoaWdobGlnaHRfOwoJdW5zaWduZWQgc2hvcnQgdmtrZXlfOwoJaW50IGZvbnRpZF87CgoJYnV0dG9uKCl7fQoJfmJ1dHRvbigpe30KCWJ1dHRvbihzdGQ6OnN0cmluZyBidXR0b25fdGV4dCxidXR0b25fY29sb3IgJmFwcGVhcmFuY2UsIGJ1dHRvbl9jb2xvciAmaGlnaGxpZ2h0ZWQsIGJ1dHRvbl9jb2xvciAmbW91c2Vkb3duLCBib29sIGNsaWNrYWJsZSwgYm9vbCBoaWdobGlnaHQsIGludCBmb250aWQgPSAxLCB1bnNpZ25lZCBzaG9ydCB2a2tleSA9IFZLX0xCVVRUT04pCgkJOiB0ZXh0XyhidXR0b25fdGV4dCksIGFwcGVhcmFuY2VfKGFwcGVhcmFuY2UpLCBoaWdobGlnaHRlZF8oaGlnaGxpZ2h0ZWQpLCBjbGlja2FibGVfKGNsaWNrYWJsZSksIGhpZ2hsaWdodF8oaGlnaGxpZ2h0KSwgbW91c2Vkb3duXyhtb3VzZWRvd24pLCB2a2tleV8odmtrZXkpLCBmb250aWRfKGZvbnRpZCkKCXt9CgkKCXN0ZDo6ZnVuY3Rpb248dm9pZCh2b2lkKT4gY2FsbGJhY2s7IAoJdGVtcGxhdGU8Y2xhc3MgRnVuY3Rvcj4gYnV0dG9uKEZ1bmN0b3ImJiBmKSA6IGNhbGxiYWNrKHN0ZDo6Zm9yd2FyZDxGdW5jdG9yPihmKSkgCgl7IAoJCgl9Cgl0ZW1wbGF0ZTxjbGFzcyBGdW5jdG9yPiB2b2lkIFNldEZ1bmN0aW9uKEZ1bmN0b3ImJiBmKQoJewoJCWNhbGxiYWNrID0gc3RkOjpmb3J3YXJkPEZ1bmN0b3I+KGYpOwoJfQoJdm9pZCBTZXRJbmZvKHN0ZDo6c3RyaW5nIGJ1dHRvbl90ZXh0LGJ1dHRvbl9jb2xvciAmYXBwZWFyYW5jZSwgYnV0dG9uX2NvbG9yICZoaWdobGlnaHRlZCwgYnV0dG9uX2NvbG9yICZtb3VzZWRvd24sIGJvb2wgY2xpY2thYmxlLCBib29sIGhpZ2hsaWdodCwgaW50IGZvbnRpZCA9IDEsIHVuc2lnbmVkIHNob3J0IHZra2V5ID0gVktfTEJVVFRPTikKCXsKCQl0ZXh0Xy5hc3NpZ24oYnV0dG9uX3RleHQpOwoJCWFwcGVhcmFuY2VfID0gYXBwZWFyYW5jZTsKCQloaWdobGlnaHRlZF8gPSBoaWdobGlnaHRlZDsKCQljbGlja2FibGVfID0gY2xpY2thYmxlOwoJCWhpZ2hsaWdodF8gPSBoaWdobGlnaHQ7CgkJbW91c2Vkb3duXyA9IG1vdXNlZG93bjsKCQl2a2tleV8gPSB2a2tleTsKCQlmb250aWRfID0gZm9udGlkOwoJfQoJZmxvYXQgR2V0TGVuZ2h0KCkKCXsKCQlyZXR1cm4gRGlyZWN0WEZvbnQ6OkFjY2Vzcyhmb250aWRfKS0+RHJhd0xlbmd0aCh0ZXh0Xy5jX3N0cigpKTsKCX0KCWZsb2F0IEdldEhlaWdodCgpCgl7CgkJcmV0dXJuIERpcmVjdFhGb250OjpBY2Nlc3MoZm9udGlkXyktPkRyYXdIZWlnaHQoKTsKCX0KCWJvb2wgSXNDdXJzb3JPblRoaXMoZmxvYXQgYnRuX3gsIGZsb2F0IGJ0bl95LCBmbG9hdCBidG5fdywgZmxvYXQgYnRuX2gpCgl7CgkJcmV0dXJuIElzUG9pbnRJbkFyZWEoY3Vyc29yUG9zLngsY3Vyc29yUG9zLnksYnRuX3gsYnRuX3ksYnRuX3csYnRuX2gpOwoJfQoJdm9pZCBEaXNwbGF5KGZsb2F0IGJ0bl94LCBmbG9hdCBidG5feSwgZmxvYXQgYnRuX3csIGZsb2F0IGJ0bl9oKQoJewoJCWlmKCFJc1BvaW50SW5BcmVhKGN1cnNvclBvcy54LGN1cnNvclBvcy55LGJ0bl94LGJ0bl95LGJ0bl93LGJ0bl9oKSkKCQl7CgkJCXJlbmRlci0+RDNEQm94Qm9yZGVyKGJ0bl94LGJ0bl95LGJ0bl93LGJ0bl9oLGFwcGVhcmFuY2VfLmJvcmRlcixhcHBlYXJhbmNlXy5idXR0b24pOwoJCQlEaXJlY3RYRm9udDo6QWNjZXNzKGZvbnRpZF8pLT5QcmludChidG5feCsoKGJ0bl93LUdldExlbmdodCgpKS8yLjBmKSxidG5feSsoKGJ0bl9oLUdldEhlaWdodCgpKS8yLjBmKSxhcHBlYXJhbmNlXy50ZXh0LHRleHRfLmNfc3RyKCksdHJ1ZSk7CgkJCXJldHVybjsKCQl9CgkJaWYoIWNsaWNrYWJsZV8pCgkJewoJCQlyZW5kZXItPkQzREJveEJvcmRlcihidG5feCxidG5feSxidG5fdyxidG5faCwoaGlnaGxpZ2h0Xyk/IGhpZ2hsaWdodGVkXy5ib3JkZXIgOiBhcHBlYXJhbmNlXy5ib3JkZXIsKGhpZ2hsaWdodF8pPyBoaWdobGlnaHRlZF8uYnV0dG9uIDogYXBwZWFyYW5jZV8uYnV0dG9uKTsKCQkJRGlyZWN0WEZvbnQ6OkFjY2Vzcyhmb250aWRfKS0+UHJpbnQoYnRuX3grKChidG5fdy1HZXRMZW5naHQoKSkvMi4wZiksYnRuX3krKChidG5faC1HZXRIZWlnaHQoKSkvMi4wZiksKGhpZ2hsaWdodF8pPyBoaWdobGlnaHRlZF8udGV4dCA6IGFwcGVhcmFuY2VfLnRleHQsdGV4dF8uY19zdHIoKSx0cnVlKTsKCQkJcmV0dXJuOwoJCX0KCQlpZighT2xkS2V5cyh2a2tleV8pLkRvd24pCgkJewoJCQlyZW5kZXItPkQzREJveEJvcmRlcihidG5feCxidG5feSxidG5fdyxidG5faCwoaGlnaGxpZ2h0Xyk/IGhpZ2hsaWdodGVkXy5ib3JkZXIgOiBhcHBlYXJhbmNlXy5ib3JkZXIsKGhpZ2hsaWdodF8pPyBoaWdobGlnaHRlZF8uYnV0dG9uIDogYXBwZWFyYW5jZV8uYnV0dG9uKTsKCQkJRGlyZWN0WEZvbnQ6OkFjY2Vzcyhmb250aWRfKS0+UHJpbnQoYnRuX3grKChidG5fdy1HZXRMZW5naHQoKSkvMi4wZiksYnRuX3krKChidG5faC1HZXRIZWlnaHQoKSkvMi4wZiksKGhpZ2hsaWdodF8pPyBoaWdobGlnaHRlZF8udGV4dCA6IGFwcGVhcmFuY2VfLnRleHQsdGV4dF8uY19zdHIoKSx0cnVlKTsJCgkJCXJldHVybjsKCQl9CgkJaWYoIUtleXModmtrZXlfKS5SZWxlYXNlZCkKCQl7CgkJCXJlbmRlci0+RDNEQm94Qm9yZGVyKGJ0bl94LGJ0bl95LGJ0bl93LGJ0bl9oLCBtb3VzZWRvd25fLmJvcmRlcixtb3VzZWRvd25fLmJ1dHRvbik7CgkJCURpcmVjdFhGb250OjpBY2Nlc3MoZm9udGlkXyktPlByaW50KGJ0bl94KygoYnRuX3ctR2V0TGVuZ2h0KCkpLzIuMGYpLGJ0bl95KygoYnRuX2gtR2V0SGVpZ2h0KCkpLzIuMGYpLCBtb3VzZWRvd25fLnRleHQsdGV4dF8uY19zdHIoKSx0cnVlKTsKCQkJcmV0dXJuOwoJCX0KCQljYWxsYmFjaygpOwoJCXJldHVybjsKCX0KCXZvaWQgRGlzcGxheUV4KGZsb2F0IGJ0bl94LCBmbG9hdCBidG5feSwgZmxvYXQgYnRuX3csIGZsb2F0IGJ0bl9oKQoJewoJCURpc3BsYXkoYnRuX3gsIGJ0bl95LEdldExlbmdodCgpK2J0bl93LCBHZXRIZWlnaHQoKStidG5faCk7Cgl9Cn07CgpjbGFzcyBNZW51CnsKcHVibGljOgoJc3RkOjp2ZWN0b3I8c3RkOjpzaGFyZWRfcHRyPGJ1dHRvbj4+IEJ1dHRvbnNfOwoJZmxvYXQgcG9zX3RvcF87CglmbG9hdCBwb3NfbGVmdF87CglmbG9hdCBzcGFjaW5nXzsKCWZsb2F0IHdpZHRoXzsKCWZsb2F0IGhlaWdodF87CglEV09SRCBCb3hDb2xvcjsKCURXT1JEIEJvcmRlckNvbG9yOwoKCXN0ZDo6c3RyaW5nIG5hbWVfOwoJTWVudSgpCgl7CgkJcG9zX3RvcF8gPSAwLjBmOwoJCXBvc19sZWZ0XyA9IDAuMGY7CgkJc3BhY2luZ18gPSA1LjBmOwoJCXdpZHRoXyA9IDAuMGY7CgkJaGVpZ2h0XyA9IDAuMGY7CgkJQm94Q29sb3IgPSAweEZGMzMwMDg4OwoJCUJvcmRlckNvbG9yID0gMHhGRjMzODgwMDsKCX0KCX5NZW51KCl7fQoJdm9pZCBTZXR1cFdpZHRoKCkKCXsKCQl3aWR0aF8gPSAwLjBmOwoJCWhlaWdodF8gPSAwLjBmOwoJCWZvcih1bnNpZ25lZCBpbnQgaSA9IDA7IGkgPCBCdXR0b25zXy5zaXplKCk7ICsraSkKCQl7CgkJCWlmKHdpZHRoXyA8IEJ1dHRvbnNfW2ldLT5HZXRMZW5naHQoKSkKCQkJewoJCQkJd2lkdGhfID0gQnV0dG9uc19baV0tPkdldExlbmdodCgpOwoJCQl9CgkJCWlmKGhlaWdodF8gPCBCdXR0b25zX1tpXS0+R2V0SGVpZ2h0KCkpCgkJCXsKCQkJCWhlaWdodF8gPSBCdXR0b25zX1tpXS0+R2V0SGVpZ2h0KCk7CgkJCX0KCQl9Cgl9Cgl2b2lkIEFkZEJ1dHRvbihzdGQ6OnNoYXJlZF9wdHI8YnV0dG9uPiBidXR0b24pCgl7CgkJQnV0dG9uc18ucHVzaF9iYWNrKGJ1dHRvbik7CgkJU2V0dXBXaWR0aCgpOwoJfQoJdm9pZCBSZW1vdmVCdXR0b24oc3RkOjpzaGFyZWRfcHRyPGJ1dHRvbj4gYnV0dG9uKQoJewoJCWZvcih1bnNpZ25lZCBpbnQgaSA9IDA7IGkgPCBCdXR0b25zXy5zaXplKCk7ICsraSkKCQl7CgkJCWlmKEJ1dHRvbnNfW2ldID09IGJ1dHRvbikKCQkJewoJCQkJQnV0dG9uc18uZXJhc2UoQnV0dG9uc18uYmVnaW4oKStpKTsKCQkJfQoJCX0KCQlTZXR1cFdpZHRoKCk7Cgl9CglmbG9hdCBHZXRXaWR0aChib29sIGhvcml6b250YWwgPSBmYWxzZSkKCXsKCQlpZighaG9yaXpvbnRhbCkKCQkJcmV0dXJuICh3aWR0aF8gKyAoc3BhY2luZ18gKiA0LjBmKSk7CgkJaWYoQnV0dG9uc18uZW1wdHkoKSkKCQkJcmV0dXJuIHNwYWNpbmdfOwoJCXJldHVybiBzcGFjaW5nXyArICgod2lkdGhfICsgKDMuMGYgKiBzcGFjaW5nXykpICogKChmbG9hdClCdXR0b25zXy5zaXplKCkpKTsKCX0KCWZsb2F0IEdldEhlaWdodChib29sIGhvcml6b250YWwgPSBmYWxzZSkKCXsKCQlpZihob3Jpem9udGFsKQoJCQlyZXR1cm4gKDMuMGYgKiBzcGFjaW5nXykgKyBoZWlnaHRfOwoJCWlmKEJ1dHRvbnNfLmVtcHR5KCkpCgkJCXJldHVybiBzcGFjaW5nXzsKCQlyZXR1cm4gc3BhY2luZ18gKyAoKChmbG9hdClCdXR0b25zXy5zaXplKCkpKnNwYWNpbmdfKSsoKHNwYWNpbmdfICsgaGVpZ2h0XykqKChmbG9hdClCdXR0b25zXy5zaXplKCkpKTsKCX0KCXZvaWQgUHJvY2Vzcyhib29sIGhvcml6b250YWwgPSBmYWxzZSwgYm9vbCBjZW50cmFsID0gdHJ1ZSkKCXsKCQlpZihCdXR0b25zXy5lbXB0eSgpKQoJCQlyZXR1cm47CgkJaWYoY2VudHJhbCkKCQl7CgkJCVBvcygoKChmbG9hdClTY3JlZW5YKS8yLjBmKS0oR2V0V2lkdGgoaG9yaXpvbnRhbCkvMi4wZiksKCgoZmxvYXQpU2NyZWVuWSkvMi4wZiktKEdldEhlaWdodChob3Jpem9udGFsKS8yLjBmKSk7CgkJfQoJCWlmKCFob3Jpem9udGFsKQoJCXsKCQkJcmVuZGVyLT5EM0RCb3hCb3JkZXIocG9zX2xlZnRfLHBvc190b3BfLCh3aWR0aF8gKyAoc3BhY2luZ18gKiA0LjBmKSksc3BhY2luZ18gKyAoKChmbG9hdClCdXR0b25zXy5zaXplKCkpKnNwYWNpbmdfKSsoKHNwYWNpbmdfICsgaGVpZ2h0XykqKChmbG9hdClCdXR0b25zXy5zaXplKCkpKSwgQm9yZGVyQ29sb3IsQm94Q29sb3IpOwoJCQlmb3IodW5zaWduZWQgaW50IGkgPSAwOyBpIDwgQnV0dG9uc18uc2l6ZSgpOyArK2kpCgkJCXsJCgkJCQlCdXR0b25zX1tpXS0+RGlzcGxheShwb3NfbGVmdF8gKyBzcGFjaW5nXyxwb3NfdG9wXyArIHNwYWNpbmdfICsgc3BhY2luZ18qKChmbG9hdClpKSArICgoc3BhY2luZ18gKyBoZWlnaHRfKSooZmxvYXQpaSksKHdpZHRoXyArICgyLjBmICogc3BhY2luZ18pKSxoZWlnaHRfK3NwYWNpbmdfKTsKCQkJfQoJCX0KCQllbHNlCgkJewoJCQlyZW5kZXItPkQzREJveEJvcmRlcihwb3NfbGVmdF8scG9zX3RvcF8sc3BhY2luZ18gKyAoKHdpZHRoXyArICgzLjBmICogc3BhY2luZ18pKSAqICgoZmxvYXQpQnV0dG9uc18uc2l6ZSgpKSksKDMuMGYgKiBzcGFjaW5nXykgKyBoZWlnaHRfLCBCb3JkZXJDb2xvcixCb3hDb2xvcik7CgkJCWZvcih1bnNpZ25lZCBpbnQgaSA9IDA7IGkgPCBCdXR0b25zXy5zaXplKCk7ICsraSkKCQkJewkKCQkJCUJ1dHRvbnNfW2ldLT5EaXNwbGF5KHBvc19sZWZ0XyArIHNwYWNpbmdfICsgKCh3aWR0aF8gKyAoMy4wZiAqIHNwYWNpbmdfKSkgKiAoKGZsb2F0KWkpKSxwb3NfdG9wXyArIHNwYWNpbmdfICwod2lkdGhfICsgKDIuMGYgKiBzcGFjaW5nXykpLGhlaWdodF8rc3BhY2luZ18pOwoJCQl9CgkJfQoJfQoJdm9pZCBQb3MoZmxvYXQgeCwgZmxvYXQgeSkKCXsKCQlwb3NfbGVmdF8gPSB4OwoJCXBvc190b3BfID0geTsKCX0KCXZvaWQgQ29sb3JzKERXT1JEIGJvcmRlcixEV09SRCBiYWNrZ3JvdW5kKQoJewoJCUJvcmRlckNvbG9yID0gYm9yZGVyOwoJCUJveENvbG9yID0gYmFja2dyb3VuZDsKCX0KfTs=