diff --git a/Assets/stylesheet.css b/Assets/stylesheet.css index ad50d6b4..e7a2c21c 100644 --- a/Assets/stylesheet.css +++ b/Assets/stylesheet.css @@ -1,6 +1,19 @@ * { + alignment: none; + autoresizing-mask: none; background-color: transparent; + background-gradient-angle: 0; + background-gradient-color: transparent; + border-color: transparent; + border-radius: 0; border-width: 0; + clips-subviews: false; + corner-cut: 0; + max-size: 0 0; + min-size: 0 0; + padding: 0; + pointer-events: auto; + visibility: unspecified; } Box { @@ -12,9 +25,10 @@ Box { } Box > Label { + alignment: internal; background-color: #888888; - padding: 0 8 0 8; left: 20; + padding: 0 8 0 8; } Box > Label > Text { @@ -49,41 +63,58 @@ Checkbox { } Checkbox ImageView { - hidden: true; - width: 12; + autoresizing-mask: fill; height: 12; + visibility: hidden; + width: 12; } Checkbox:selected ImageView { - hidden: false; + visibility: visible; } +/* The box holds a 12 check in 4 of padding, so 20 is the size it takes once one is in it */ + Checkbox > Control { + alignment: middle-center; autoresizing-mask: contain; background-color: #22222266; bevel: inset; - min-width: 18; - min-height: 18; + min-height: 20; + min-width: 20; padding: 4 4 4 4; } CollectionItemView { background-color: #22222266; border-color: #999999aa; + clips-subviews: true; +} + +CollectionItemView > ImageView { + autoresizing-mask: fill; +} + +CollectionItemView > Text { + alignment: middle-center; } CollectionItemView > .selectionOverlay { + autoresizing-mask: fill; background-color: #ffffff22; - hidden: true; + visibility: hidden; } CollectionItemView:selected > .selectionOverlay { - hidden: false; + visibility: visible; } CollectionView { + axis: vertical; background-color: #22222266; + item-size: 0 0; item-size: 64 64; + item-spacing: 0 0; item-spacing: 10 10; } @@ -93,8 +124,12 @@ CollectionView .contentView { } Control { + bevel-dark-color: black; + bevel-light-color: silver; + bevel: none; border-radius: 4; min-height: 32; + selection: none; selection: single; } @@ -138,6 +173,16 @@ Option > Text { alignment: middle-left; } +/* + * A ViewController's own root View fills its parent, which is what a controller pushed onto a + * window or added to another wants. A rule rather than the element style, so that a controller + * whose view is a panel of its own, or a page measured by its content, can say so. + */ + +.viewController { + autoresizing-mask: fill; +} + PageView { autoresizing-mask: contain; border-color: #888888; @@ -149,7 +194,9 @@ Panel { background-color: #444444dd; border-color: #dedede; border-width: 1; + draggable: true; padding: 12 12 12 12; + resizable: true; } Panel > StackView { @@ -163,7 +210,17 @@ Panel .accessoryView { spacing: 16; } +/* + * A Panel shows its own accessory view only once something is put in it. The class name is a + * layout a consumer may wear anywhere, so this addresses the Panel's own by where it sits. + */ + +Panel > StackView > .accessoryView { + visibility: hidden; +} + Panel > .resizeHandle { + alignment: internal; border-radius: 4; } @@ -186,8 +243,9 @@ ProgressBar > Text { } ScrollBar { - width: 12; background-color: #222222c0; + clips-subviews: true; + width: 12; } ScrollBar > .handle { @@ -198,6 +256,12 @@ ScrollBar > .handle { ScrollView { autoresizing-mask: fill; clips-subviews: true; + scrollbar: auto; +} + +ScrollView > .scrollBar { + alignment: right; + autoresizing-mask: height; } ScrollView > .contentView { @@ -209,6 +273,7 @@ Select { background-color: #dedede10; bevel: outset; padding: 4 4 4 4; + selection: single; } Select > StackView { @@ -218,7 +283,7 @@ Select > StackView { Slider { autoresizing-mask: contain; - width: 140; + min-width: 140; } Slider > .bar { @@ -250,6 +315,14 @@ SlideShowView > ImageView { autoresizing-mask: fill; } +StackView { + autoresizing-mask: contain; + axis: vertical; + distribution: default; + reversed: false; + spacing: 0; +} + StackView.container { spacing: 12; } @@ -324,8 +397,10 @@ TextView { autoresizing-mask: contain; background-color: #22222266; bevel: inset; + clips-subviews: true; + editable: true; + min-width: 160; padding: 4 4 4 4; - width: 160; } TextView > Text { @@ -351,7 +426,7 @@ Text { .options > Option { border-radius: 2; - padding: 0 4 0 4; + padding: 2 4 2 4; } .options > Option:hover { diff --git a/Assets/stylesheet.css.h b/Assets/stylesheet.css.h index c1d67112..b9de1c9f 100644 --- a/Assets/stylesheet.css.h +++ b/Assets/stylesheet.css.h @@ -1,271 +1,406 @@ unsigned char stylesheet_css[] = { - 0x2a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, - 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x2a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x0a, 0x20, + 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, + 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, + 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x74, 0x72, + 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3b, 0x0a, 0x20, + 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x67, 0x72, 0x61, 0x64, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x61, 0x6e, 0x67, + 0x6c, 0x65, 0x3a, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x67, 0x72, 0x61, 0x64, + 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x3b, - 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x77, 0x69, - 0x64, 0x74, 0x68, 0x3a, 0x20, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x42, - 0x6f, 0x78, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, - 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, - 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x20, - 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, - 0x72, 0x3a, 0x20, 0x23, 0x64, 0x65, 0x64, 0x65, 0x64, 0x65, 0x61, 0x61, - 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, - 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20, - 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, - 0x3a, 0x20, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, - 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x30, 0x20, 0x31, 0x30, 0x20, 0x31, 0x30, - 0x20, 0x31, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x42, 0x6f, 0x78, 0x20, - 0x3e, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, - 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x38, 0x38, 0x38, 0x38, 0x38, - 0x38, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, - 0x3a, 0x20, 0x30, 0x20, 0x38, 0x20, 0x30, 0x20, 0x38, 0x3b, 0x0a, 0x20, - 0x20, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x32, 0x30, 0x3b, 0x0a, 0x7d, - 0x0a, 0x0a, 0x42, 0x6f, 0x78, 0x20, 0x3e, 0x20, 0x4c, 0x61, 0x62, 0x65, - 0x6c, 0x20, 0x3e, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, - 0x20, 0x66, 0x6f, 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, - 0x31, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x42, 0x6f, 0x78, 0x20, 0x3e, - 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x56, 0x69, 0x65, - 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, - 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, - 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x77, - 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, - 0x69, 0x6e, 0x67, 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x34, 0x3b, 0x0a, - 0x20, 0x20, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x34, - 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, - 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, - 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, - 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x32, - 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, - 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x67, 0x68, 0x6f, 0x73, 0x74, - 0x77, 0x68, 0x69, 0x74, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x65, 0x76, - 0x65, 0x6c, 0x3a, 0x20, 0x6f, 0x75, 0x74, 0x73, 0x65, 0x74, 0x3b, 0x0a, - 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, - 0x20, 0x31, 0x30, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, - 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x38, 0x20, 0x38, 0x20, 0x38, 0x20, 0x38, - 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x3a, - 0x68, 0x69, 0x67, 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x20, 0x69, - 0x6e, 0x73, 0x65, 0x74, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x42, 0x75, 0x74, - 0x74, 0x6f, 0x6e, 0x20, 0x3e, 0x20, 0x2a, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, - 0x69, 0x64, 0x64, 0x6c, 0x65, 0x2d, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, - 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, - 0x78, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, - 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, - 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x7d, 0x0a, - 0x0a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x20, 0x49, 0x6d, - 0x61, 0x67, 0x65, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, - 0x3b, 0x0a, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, - 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, - 0x20, 0x31, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x68, 0x65, 0x63, - 0x6b, 0x62, 0x6f, 0x78, 0x3a, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, - 0x64, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x56, 0x69, 0x65, 0x77, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3a, 0x20, - 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x68, - 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x20, 0x3e, 0x20, 0x43, 0x6f, 0x6e, - 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, + 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x70, 0x61, + 0x72, 0x65, 0x6e, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, + 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x30, + 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x63, + 0x6c, 0x69, 0x70, 0x73, 0x2d, 0x73, 0x75, 0x62, 0x76, 0x69, 0x65, 0x77, + 0x73, 0x3a, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x0a, 0x20, 0x20, + 0x63, 0x6f, 0x72, 0x6e, 0x65, 0x72, 0x2d, 0x63, 0x75, 0x74, 0x3a, 0x20, + 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x61, 0x78, 0x2d, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x20, 0x30, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x69, + 0x6e, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x30, 0x20, 0x30, 0x3b, + 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, + 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x2d, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x3a, 0x20, 0x61, 0x75, 0x74, + 0x6f, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x3a, 0x20, 0x75, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x69, + 0x66, 0x69, 0x65, 0x64, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x42, 0x6f, 0x78, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, + 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x64, 0x65, 0x64, 0x65, 0x64, 0x65, 0x61, 0x61, 0x3b, 0x0a, + 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, + 0x69, 0x75, 0x73, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, + 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x3a, 0x20, 0x31, 0x30, 0x20, 0x31, 0x30, 0x20, 0x31, 0x30, 0x20, 0x31, + 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x42, 0x6f, 0x78, 0x20, 0x3e, 0x20, + 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x69, 0x6e, 0x74, + 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, + 0x72, 0x3a, 0x20, 0x23, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x3b, 0x0a, + 0x20, 0x20, 0x6c, 0x65, 0x66, 0x74, 0x3a, 0x20, 0x32, 0x30, 0x3b, 0x0a, + 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x30, + 0x20, 0x38, 0x20, 0x30, 0x20, 0x38, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x42, + 0x6f, 0x78, 0x20, 0x3e, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x3e, + 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x66, 0x6f, + 0x6e, 0x74, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x31, 0x32, 0x3b, + 0x0a, 0x7d, 0x0a, 0x0a, 0x42, 0x6f, 0x78, 0x20, 0x3e, 0x20, 0x2e, 0x63, + 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, + 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x2d, 0x74, 0x6f, 0x70, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x73, + 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, + 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, + 0x20, 0x23, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x32, 0x32, 0x3b, 0x0a, + 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x67, 0x68, 0x6f, 0x73, 0x74, 0x77, 0x68, 0x69, + 0x74, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x65, 0x76, 0x65, 0x6c, 0x3a, + 0x20, 0x6f, 0x75, 0x74, 0x73, 0x65, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x6d, + 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, + 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x3a, 0x20, 0x38, 0x20, 0x38, 0x20, 0x38, 0x20, 0x38, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, 0x3a, 0x68, 0x69, 0x67, + 0x68, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x65, 0x64, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x62, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x20, 0x69, 0x6e, 0x73, 0x65, + 0x74, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x42, 0x75, 0x74, 0x74, 0x6f, 0x6e, + 0x20, 0x3e, 0x20, 0x2a, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, 0x69, 0x64, 0x64, + 0x6c, 0x65, 0x2d, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, + 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x68, + 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, - 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, - 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, - 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, 0x32, - 0x32, 0x32, 0x32, 0x32, 0x36, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x65, - 0x76, 0x65, 0x6c, 0x3a, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x74, 0x3b, 0x0a, - 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, - 0x20, 0x31, 0x38, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x2d, 0x68, - 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x31, 0x38, 0x3b, 0x0a, 0x20, - 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x34, 0x20, - 0x34, 0x20, 0x34, 0x20, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x6f, + 0x73, 0x6b, 0x3a, 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x3b, 0x0a, 0x20, 0x20, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x31, 0x32, 0x3b, 0x0a, + 0x20, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x3a, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x0a, 0x20, 0x20, + 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x32, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x3a, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x49, 0x6d, 0x61, 0x67, + 0x65, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x6c, 0x65, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2f, 0x2a, + 0x20, 0x54, 0x68, 0x65, 0x20, 0x62, 0x6f, 0x78, 0x20, 0x68, 0x6f, 0x6c, + 0x64, 0x73, 0x20, 0x61, 0x20, 0x31, 0x32, 0x20, 0x63, 0x68, 0x65, 0x63, + 0x6b, 0x20, 0x69, 0x6e, 0x20, 0x34, 0x20, 0x6f, 0x66, 0x20, 0x70, 0x61, + 0x64, 0x64, 0x69, 0x6e, 0x67, 0x2c, 0x20, 0x73, 0x6f, 0x20, 0x32, 0x30, + 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x69, 0x7a, 0x65, + 0x20, 0x69, 0x74, 0x20, 0x74, 0x61, 0x6b, 0x65, 0x73, 0x20, 0x6f, 0x6e, + 0x63, 0x65, 0x20, 0x6f, 0x6e, 0x65, 0x20, 0x69, 0x73, 0x20, 0x69, 0x6e, + 0x20, 0x69, 0x74, 0x20, 0x2a, 0x2f, 0x0a, 0x0a, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x62, 0x6f, 0x78, 0x20, 0x3e, 0x20, 0x43, 0x6f, 0x6e, 0x74, 0x72, + 0x6f, 0x6c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, + 0x2d, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x61, + 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, + 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, + 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x36, 0x36, 0x3b, 0x0a, 0x20, 0x20, + 0x62, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x74, + 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x2d, 0x68, 0x65, 0x69, 0x67, + 0x68, 0x74, 0x3a, 0x20, 0x32, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x69, + 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x32, 0x30, 0x3b, + 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, + 0x34, 0x20, 0x34, 0x20, 0x34, 0x20, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, + 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, + 0x65, 0x6d, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, + 0x36, 0x36, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x39, 0x39, 0x39, + 0x39, 0x39, 0x39, 0x61, 0x61, 0x3b, 0x0a, 0x20, 0x20, 0x63, 0x6c, 0x69, + 0x70, 0x73, 0x2d, 0x73, 0x75, 0x62, 0x76, 0x69, 0x65, 0x77, 0x73, 0x3a, + 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, - 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, + 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, 0x49, 0x6d, 0x61, 0x67, 0x65, + 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, + 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, + 0x73, 0x6b, 0x3a, 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x3b, 0x0a, 0x7d, 0x0a, + 0x0a, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, + 0x74, 0x65, 0x6d, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, 0x54, 0x65, + 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, + 0x2d, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, + 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, + 0x65, 0x6d, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x76, 0x65, 0x72, 0x6c, + 0x61, 0x79, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, + 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, + 0x3a, 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x32, + 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, + 0x69, 0x74, 0x79, 0x3a, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, + 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x56, 0x69, 0x65, 0x77, 0x3a, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x3e, 0x20, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x76, 0x65, 0x72, + 0x6c, 0x61, 0x79, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x76, 0x69, 0x73, 0x69, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x76, 0x69, 0x73, 0x69, + 0x62, 0x6c, 0x65, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x61, 0x78, 0x69, 0x73, 0x3a, 0x20, 0x76, 0x65, 0x72, + 0x74, 0x69, 0x63, 0x61, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x36, 0x36, - 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, - 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x39, 0x39, 0x39, 0x39, 0x39, - 0x39, 0x61, 0x61, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x6c, - 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x56, 0x69, - 0x65, 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x4f, 0x76, 0x65, 0x72, 0x6c, 0x61, 0x79, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, - 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, - 0x66, 0x66, 0x66, 0x66, 0x32, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x69, - 0x64, 0x64, 0x65, 0x6e, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x0a, + 0x3b, 0x0a, 0x20, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x2d, 0x73, 0x69, 0x7a, + 0x65, 0x3a, 0x20, 0x30, 0x20, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x69, 0x74, + 0x65, 0x6d, 0x2d, 0x73, 0x69, 0x7a, 0x65, 0x3a, 0x20, 0x36, 0x34, 0x20, + 0x36, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x2d, 0x73, + 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x30, 0x20, 0x30, 0x3b, + 0x0a, 0x20, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x2d, 0x73, 0x70, 0x61, 0x63, + 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x30, 0x20, 0x31, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x49, 0x74, 0x65, 0x6d, 0x56, 0x69, 0x65, 0x77, 0x3a, 0x73, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x3e, 0x20, 0x2e, 0x73, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4f, 0x76, 0x65, 0x72, 0x6c, - 0x61, 0x79, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x68, 0x69, 0x64, 0x64, 0x65, - 0x6e, 0x3a, 0x20, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x3b, 0x0a, 0x7d, 0x0a, - 0x0a, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, - 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, - 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, - 0x3a, 0x20, 0x23, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x36, 0x36, 0x3b, - 0x0a, 0x20, 0x20, 0x69, 0x74, 0x65, 0x6d, 0x2d, 0x73, 0x69, 0x7a, 0x65, - 0x3a, 0x20, 0x36, 0x34, 0x20, 0x36, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x69, - 0x74, 0x65, 0x6d, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3a, - 0x20, 0x31, 0x30, 0x20, 0x31, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, - 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, 0x65, - 0x77, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x56, 0x69, - 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, - 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, - 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, - 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, - 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x30, 0x20, 0x31, 0x30, 0x20, - 0x31, 0x30, 0x20, 0x31, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x6f, - 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, - 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x2d, 0x68, 0x65, - 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x33, 0x32, 0x3b, 0x0a, 0x20, 0x20, - 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x73, - 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x6f, - 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x3a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x67, 0x72, 0x65, 0x79, 0x3b, - 0x0a, 0x7d, 0x0a, 0x0a, 0x48, 0x53, 0x56, 0x43, 0x6f, 0x6c, 0x6f, 0x72, - 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x2c, 0x0a, 0x48, 0x75, 0x65, 0x43, - 0x6f, 0x6c, 0x6f, 0x72, 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x2c, 0x0a, - 0x52, 0x47, 0x42, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x50, 0x69, 0x63, 0x6b, - 0x65, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, - 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, - 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x7d, + 0x6e, 0x56, 0x69, 0x65, 0x77, 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, + 0x6e, 0x74, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, + 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, + 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x20, 0x7c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x20, + 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x30, + 0x20, 0x31, 0x30, 0x20, 0x31, 0x30, 0x20, 0x31, 0x30, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x62, 0x65, 0x76, 0x65, 0x6c, 0x2d, 0x64, 0x61, 0x72, 0x6b, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x62, 0x6c, 0x61, 0x63, + 0x6b, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x65, 0x76, 0x65, 0x6c, 0x2d, 0x6c, + 0x69, 0x67, 0x68, 0x74, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x73, 0x69, 0x6c, 0x76, 0x65, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x65, + 0x76, 0x65, 0x6c, 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x0a, 0x20, + 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, + 0x75, 0x73, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x69, 0x6e, + 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x33, 0x32, 0x3b, + 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x3a, 0x20, 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x73, 0x65, + 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x73, 0x69, 0x6e, + 0x67, 0x6c, 0x65, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x6f, 0x6c, 0x3a, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x67, 0x72, 0x65, 0x79, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x48, 0x53, 0x56, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x50, 0x69, - 0x63, 0x6b, 0x65, 0x72, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x56, - 0x69, 0x65, 0x77, 0x2c, 0x0a, 0x48, 0x75, 0x65, 0x43, 0x6f, 0x6c, 0x6f, - 0x72, 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x20, 0x2e, 0x63, 0x6f, 0x6c, - 0x6f, 0x72, 0x56, 0x69, 0x65, 0x77, 0x2c, 0x0a, 0x52, 0x47, 0x42, 0x43, - 0x6f, 0x6c, 0x6f, 0x72, 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x20, 0x2e, - 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, - 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x77, 0x69, 0x64, - 0x74, 0x68, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, - 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, - 0x6e, 0x6f, 0x6e, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, - 0x68, 0x74, 0x3a, 0x20, 0x38, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x49, 0x6e, - 0x70, 0x75, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, - 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, - 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, - 0x7d, 0x0a, 0x0a, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x7b, 0x0a, 0x20, - 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, - 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x4c, 0x61, 0x62, 0x65, - 0x6c, 0x20, 0x3e, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, - 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, - 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3b, - 0x0a, 0x7d, 0x0a, 0x0a, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7b, - 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, - 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x77, 0x69, 0x64, 0x74, - 0x68, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, - 0x74, 0x68, 0x3a, 0x20, 0x31, 0x30, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x70, - 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x32, 0x20, 0x32, 0x20, - 0x32, 0x20, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x20, 0x3e, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, - 0x20, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x2d, 0x6c, 0x65, 0x66, 0x74, - 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x61, 0x67, 0x65, 0x56, 0x69, 0x65, - 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, - 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, - 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x20, 0x20, - 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, - 0x3a, 0x20, 0x23, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x3b, 0x0a, 0x20, - 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x32, - 0x20, 0x31, 0x32, 0x20, 0x31, 0x32, 0x20, 0x31, 0x32, 0x3b, 0x0a, 0x7d, - 0x0a, 0x0a, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x63, 0x6b, 0x65, 0x72, 0x2c, 0x0a, 0x48, 0x75, 0x65, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x2c, 0x0a, 0x52, 0x47, + 0x42, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, + 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, + 0x48, 0x53, 0x56, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x50, 0x69, 0x63, 0x6b, + 0x65, 0x72, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x56, 0x69, 0x65, + 0x77, 0x2c, 0x0a, 0x48, 0x75, 0x65, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x50, + 0x69, 0x63, 0x6b, 0x65, 0x72, 0x20, 0x2e, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x56, 0x69, 0x65, 0x77, 0x2c, 0x0a, 0x52, 0x47, 0x42, 0x43, 0x6f, 0x6c, + 0x6f, 0x72, 0x50, 0x69, 0x63, 0x6b, 0x65, 0x72, 0x20, 0x2e, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, - 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, - 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, - 0x23, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x64, 0x64, 0x3b, 0x0a, 0x20, - 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, - 0x72, 0x3a, 0x20, 0x23, 0x64, 0x65, 0x64, 0x65, 0x64, 0x65, 0x3b, 0x0a, - 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x77, 0x69, 0x64, - 0x74, 0x68, 0x3a, 0x20, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, - 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x32, 0x20, 0x31, 0x32, 0x20, - 0x31, 0x32, 0x20, 0x31, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x61, - 0x6e, 0x65, 0x6c, 0x20, 0x3e, 0x20, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x56, - 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x73, 0x70, 0x61, 0x63, - 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, - 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x6f, 0x72, 0x79, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, - 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, - 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, - 0x3b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, - 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x61, 0x78, - 0x69, 0x73, 0x3a, 0x20, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, - 0x61, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, - 0x67, 0x3a, 0x20, 0x31, 0x36, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x61, - 0x6e, 0x65, 0x6c, 0x20, 0x3e, 0x20, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, - 0x65, 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, - 0x73, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x72, 0x6f, - 0x67, 0x72, 0x65, 0x73, 0x73, 0x42, 0x61, 0x72, 0x20, 0x7b, 0x0a, 0x20, + 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x6e, 0x6f, + 0x6e, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, + 0x3a, 0x20, 0x38, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x49, 0x6e, 0x70, 0x75, + 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, + 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x7d, 0x0a, + 0x0a, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, + 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, + 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x20, + 0x3e, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, 0x69, + 0x64, 0x64, 0x6c, 0x65, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, + 0x0a, 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, + 0x3a, 0x20, 0x31, 0x30, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x32, 0x20, 0x32, 0x20, 0x32, 0x20, + 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x20, 0x3e, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, + 0x69, 0x64, 0x64, 0x6c, 0x65, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x0a, + 0x7d, 0x0a, 0x0a, 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x41, 0x20, 0x56, + 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x27, 0x73, 0x20, 0x6f, 0x77, 0x6e, 0x20, 0x72, 0x6f, 0x6f, 0x74, + 0x20, 0x56, 0x69, 0x65, 0x77, 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x73, 0x20, + 0x69, 0x74, 0x73, 0x20, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x2c, 0x20, + 0x77, 0x68, 0x69, 0x63, 0x68, 0x20, 0x69, 0x73, 0x20, 0x77, 0x68, 0x61, + 0x74, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, + 0x65, 0x72, 0x20, 0x70, 0x75, 0x73, 0x68, 0x65, 0x64, 0x20, 0x6f, 0x6e, + 0x74, 0x6f, 0x20, 0x61, 0x0a, 0x20, 0x2a, 0x20, 0x77, 0x69, 0x6e, 0x64, + 0x6f, 0x77, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, + 0x74, 0x6f, 0x20, 0x61, 0x6e, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x20, 0x77, + 0x61, 0x6e, 0x74, 0x73, 0x2e, 0x20, 0x41, 0x20, 0x72, 0x75, 0x6c, 0x65, + 0x20, 0x72, 0x61, 0x74, 0x68, 0x65, 0x72, 0x20, 0x74, 0x68, 0x61, 0x6e, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x20, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x2c, 0x20, 0x73, 0x6f, 0x20, 0x74, + 0x68, 0x61, 0x74, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x6f, + 0x6c, 0x6c, 0x65, 0x72, 0x0a, 0x20, 0x2a, 0x20, 0x77, 0x68, 0x6f, 0x73, + 0x65, 0x20, 0x76, 0x69, 0x65, 0x77, 0x20, 0x69, 0x73, 0x20, 0x61, 0x20, + 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x6f, 0x66, 0x20, 0x69, 0x74, 0x73, + 0x20, 0x6f, 0x77, 0x6e, 0x2c, 0x20, 0x6f, 0x72, 0x20, 0x61, 0x20, 0x70, + 0x61, 0x67, 0x65, 0x20, 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x64, + 0x20, 0x62, 0x79, 0x20, 0x69, 0x74, 0x73, 0x20, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x2c, 0x20, 0x63, 0x61, 0x6e, 0x20, 0x73, 0x61, 0x79, + 0x20, 0x73, 0x6f, 0x2e, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x0a, 0x2e, 0x76, + 0x69, 0x65, 0x77, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x6f, 0x6c, 0x6c, 0x65, + 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, + 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, + 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x61, + 0x67, 0x65, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, + 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, + 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x38, 0x38, 0x38, 0x38, + 0x38, 0x38, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x3a, 0x20, 0x31, 0x32, 0x20, 0x31, 0x32, 0x20, 0x31, 0x32, 0x20, + 0x31, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, + 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, + 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, + 0x64, 0x64, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, + 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x64, 0x65, 0x64, + 0x65, 0x64, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x3b, 0x0a, + 0x20, 0x20, 0x64, 0x72, 0x61, 0x67, 0x67, 0x61, 0x62, 0x6c, 0x65, 0x3a, + 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x32, 0x20, 0x31, 0x32, 0x20, + 0x31, 0x32, 0x20, 0x31, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x72, 0x65, 0x73, + 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, + 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x3e, + 0x20, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3a, 0x20, + 0x31, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, 0x79, 0x56, + 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, + 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, 0x69, 0x64, 0x64, 0x6c, + 0x65, 0x2d, 0x72, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x61, + 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, + 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x61, 0x78, 0x69, 0x73, 0x3a, 0x20, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x20, + 0x20, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x36, + 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2f, 0x2a, 0x0a, 0x20, 0x2a, 0x20, 0x41, + 0x20, 0x50, 0x61, 0x6e, 0x65, 0x6c, 0x20, 0x73, 0x68, 0x6f, 0x77, 0x73, + 0x20, 0x69, 0x74, 0x73, 0x20, 0x6f, 0x77, 0x6e, 0x20, 0x61, 0x63, 0x63, + 0x65, 0x73, 0x73, 0x6f, 0x72, 0x79, 0x20, 0x76, 0x69, 0x65, 0x77, 0x20, + 0x6f, 0x6e, 0x6c, 0x79, 0x20, 0x6f, 0x6e, 0x63, 0x65, 0x20, 0x73, 0x6f, + 0x6d, 0x65, 0x74, 0x68, 0x69, 0x6e, 0x67, 0x20, 0x69, 0x73, 0x20, 0x70, + 0x75, 0x74, 0x20, 0x69, 0x6e, 0x20, 0x69, 0x74, 0x2e, 0x20, 0x54, 0x68, + 0x65, 0x20, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x20, 0x6e, 0x61, 0x6d, 0x65, + 0x20, 0x69, 0x73, 0x20, 0x61, 0x0a, 0x20, 0x2a, 0x20, 0x6c, 0x61, 0x79, + 0x6f, 0x75, 0x74, 0x20, 0x61, 0x20, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, + 0x65, 0x72, 0x20, 0x6d, 0x61, 0x79, 0x20, 0x77, 0x65, 0x61, 0x72, 0x20, + 0x61, 0x6e, 0x79, 0x77, 0x68, 0x65, 0x72, 0x65, 0x2c, 0x20, 0x73, 0x6f, + 0x20, 0x74, 0x68, 0x69, 0x73, 0x20, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x65, 0x73, 0x20, 0x74, 0x68, 0x65, 0x20, 0x50, 0x61, 0x6e, 0x65, + 0x6c, 0x27, 0x73, 0x20, 0x6f, 0x77, 0x6e, 0x20, 0x62, 0x79, 0x20, 0x77, + 0x68, 0x65, 0x72, 0x65, 0x20, 0x69, 0x74, 0x20, 0x73, 0x69, 0x74, 0x73, + 0x2e, 0x0a, 0x20, 0x2a, 0x2f, 0x0a, 0x0a, 0x50, 0x61, 0x6e, 0x65, 0x6c, + 0x20, 0x3e, 0x20, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x56, 0x69, 0x65, 0x77, + 0x20, 0x3e, 0x20, 0x2e, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x6f, 0x72, + 0x79, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x76, 0x69, + 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x3a, 0x20, 0x68, 0x69, + 0x64, 0x64, 0x65, 0x6e, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x61, 0x6e, + 0x65, 0x6c, 0x20, 0x3e, 0x20, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, + 0x48, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x69, 0x6e, + 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, + 0x20, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x67, 0x72, + 0x65, 0x73, 0x73, 0x42, 0x61, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, + 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, + 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x20, 0x7c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x42, 0x61, + 0x72, 0x20, 0x3e, 0x20, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, + 0x75, 0x6e, 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, + 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, + 0x6b, 0x3a, 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x62, + 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x73, 0x69, 0x6c, 0x76, 0x65, 0x72, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, - 0x42, 0x61, 0x72, 0x20, 0x3e, 0x20, 0x2e, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x42, 0x61, 0x72, 0x20, 0x3e, 0x20, 0x2e, 0x66, 0x6f, 0x72, 0x65, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, - 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x3b, 0x0a, 0x20, - 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, - 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x73, 0x69, 0x6c, 0x76, 0x65, - 0x72, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, - 0x73, 0x73, 0x42, 0x61, 0x72, 0x20, 0x3e, 0x20, 0x2e, 0x66, 0x6f, 0x72, - 0x65, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, - 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, - 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, - 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x64, - 0x61, 0x72, 0x6b, 0x67, 0x72, 0x61, 0x79, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, - 0x50, 0x72, 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x42, 0x61, 0x72, 0x20, - 0x3e, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, - 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, 0x69, - 0x64, 0x64, 0x6c, 0x65, 0x2d, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, - 0x0a, 0x7d, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x42, 0x61, - 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, - 0x20, 0x31, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, - 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, - 0x20, 0x23, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x63, 0x30, 0x3b, 0x0a, - 0x7d, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x42, 0x61, 0x72, - 0x20, 0x3e, 0x20, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x7b, + 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, - 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x38, 0x38, - 0x38, 0x38, 0x38, 0x38, 0x63, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x69, - 0x6e, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x31, 0x36, - 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x56, - 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, - 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, - 0x6b, 0x3a, 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x63, + 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x64, 0x61, 0x72, + 0x6b, 0x67, 0x72, 0x61, 0x79, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x50, 0x72, + 0x6f, 0x67, 0x72, 0x65, 0x73, 0x73, 0x42, 0x61, 0x72, 0x20, 0x3e, 0x20, + 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, 0x69, 0x64, 0x64, + 0x6c, 0x65, 0x2d, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x42, 0x61, 0x72, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x32, + 0x32, 0x32, 0x32, 0x32, 0x32, 0x63, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x63, 0x6c, 0x69, 0x70, 0x73, 0x2d, 0x73, 0x75, 0x62, 0x76, 0x69, 0x65, 0x77, - 0x73, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, - 0x53, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, - 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x56, 0x69, 0x65, + 0x73, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, + 0x0a, 0x53, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x42, 0x61, 0x72, 0x20, 0x3e, + 0x20, 0x2e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x20, 0x7b, 0x0a, 0x20, + 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x38, 0x38, 0x38, 0x38, + 0x38, 0x38, 0x63, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x2d, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3a, 0x20, 0x31, 0x36, 0x3b, 0x0a, + 0x7d, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, - 0x20, 0x66, 0x69, 0x74, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x53, 0x65, 0x6c, - 0x65, 0x63, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, - 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, - 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, - 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, - 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x64, 0x65, 0x64, - 0x65, 0x64, 0x65, 0x31, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x65, 0x76, - 0x65, 0x6c, 0x3a, 0x20, 0x6f, 0x75, 0x74, 0x73, 0x65, 0x74, 0x3b, 0x0a, - 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x34, - 0x20, 0x34, 0x20, 0x34, 0x20, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x53, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x20, 0x3e, 0x20, 0x53, 0x74, 0x61, 0x63, - 0x6b, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, - 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, - 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x3b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, - 0x74, 0x3a, 0x20, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x2d, 0x6c, 0x65, - 0x66, 0x74, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x53, 0x6c, 0x69, 0x64, 0x65, - 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, + 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x63, 0x6c, 0x69, + 0x70, 0x73, 0x2d, 0x73, 0x75, 0x62, 0x76, 0x69, 0x65, 0x77, 0x73, 0x3a, + 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x73, 0x63, 0x72, + 0x6f, 0x6c, 0x6c, 0x62, 0x61, 0x72, 0x3a, 0x20, 0x61, 0x75, 0x74, 0x6f, + 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x56, + 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x73, 0x63, 0x72, 0x6f, 0x6c, + 0x6c, 0x42, 0x61, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, + 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x72, 0x69, 0x67, 0x68, + 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, + 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, + 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x53, + 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, + 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x56, 0x69, 0x65, 0x77, + 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, + 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, + 0x66, 0x69, 0x74, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x53, 0x65, 0x6c, 0x65, + 0x63, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, + 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, + 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x20, + 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, + 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x64, 0x65, 0x64, 0x65, + 0x64, 0x65, 0x31, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x65, 0x76, 0x65, + 0x6c, 0x3a, 0x20, 0x6f, 0x75, 0x74, 0x73, 0x65, 0x74, 0x3b, 0x0a, 0x20, + 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x34, 0x20, + 0x34, 0x20, 0x34, 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x73, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x73, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x53, 0x65, 0x6c, 0x65, 0x63, + 0x74, 0x20, 0x3e, 0x20, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x56, 0x69, 0x65, + 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x20, 0x20, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, + 0x69, 0x64, 0x64, 0x6c, 0x65, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x0a, + 0x7d, 0x0a, 0x0a, 0x53, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, + 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x34, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x53, 0x6c, 0x69, 0x64, 0x65, 0x72, 0x20, 0x3e, 0x20, 0x2e, 0x62, 0x61, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, @@ -305,146 +440,159 @@ unsigned char stylesheet_css[] = { 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x53, 0x74, 0x61, - 0x63, 0x6b, 0x56, 0x69, 0x65, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x73, 0x70, 0x61, - 0x63, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, - 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x56, 0x69, - 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, - 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, - 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, 0x20, - 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x30, 0x20, - 0x32, 0x20, 0x30, 0x20, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x69, 0x6e, - 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x38, 0x30, 0x3b, 0x0a, - 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, - 0x3a, 0x20, 0x32, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, - 0x6c, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, - 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, - 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, 0x69, 0x64, - 0x64, 0x6c, 0x65, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x0a, 0x7d, 0x0a, - 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, - 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, - 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, - 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x32, 0x32, - 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x6f, - 0x77, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, - 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, - 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, - 0x20, 0x7c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x20, 0x20, - 0x61, 0x78, 0x69, 0x73, 0x3a, 0x20, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x6f, - 0x6e, 0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x64, 0x69, 0x73, 0x74, - 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, 0x69, - 0x6c, 0x6c, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, - 0x52, 0x6f, 0x77, 0x56, 0x69, 0x65, 0x77, 0x3a, 0x6e, 0x74, 0x68, 0x2d, - 0x63, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x29, 0x20, - 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x56, 0x69, 0x65, - 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, - 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, - 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x31, 0x31, 0x3b, 0x0a, 0x7d, - 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x56, 0x69, - 0x65, 0x77, 0x3a, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, - 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, - 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x64, 0x61, - 0x72, 0x6b, 0x67, 0x72, 0x61, 0x79, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, - 0x61, 0x62, 0x6c, 0x65, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, 0x53, - 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, - 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x56, 0x69, 0x65, 0x77, - 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, - 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, - 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x77, 0x69, - 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x56, - 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x73, 0x70, 0x61, 0x63, - 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, - 0x61, 0x62, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x74, 0x61, - 0x62, 0x50, 0x61, 0x67, 0x65, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, - 0x6f, 0x72, 0x3a, 0x20, 0x73, 0x69, 0x6c, 0x76, 0x65, 0x72, 0x3b, 0x0a, - 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, - 0x69, 0x75, 0x73, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, - 0x72, 0x64, 0x65, 0x72, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, - 0x31, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x56, 0x69, 0x65, - 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x53, 0x65, 0x6c, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, - 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, - 0x3b, 0x0a, 0x20, 0x20, 0x61, 0x78, 0x69, 0x73, 0x3a, 0x20, 0x68, 0x6f, - 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x20, 0x20, - 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x3a, 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x2d, 0x65, 0x71, 0x75, 0x61, 0x6c, - 0x6c, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x73, 0x70, 0x61, 0x63, 0x69, 0x6e, - 0x67, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, - 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x53, - 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, 0x65, 0x77, - 0x20, 0x3e, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x7b, 0x0a, 0x20, - 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x32, 0x20, - 0x32, 0x20, 0x32, 0x20, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, - 0x62, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x74, 0x61, 0x62, - 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, 0x65, - 0x77, 0x20, 0x3e, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x73, 0x65, - 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, - 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, - 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x64, 0x61, 0x72, 0x6b, 0x67, 0x72, 0x61, - 0x79, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x56, 0x69, 0x65, - 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x53, 0x65, 0x6c, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, - 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x64, 0x20, 0x3e, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, - 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x67, 0x72, 0x65, - 0x79, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x56, 0x69, 0x65, - 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x53, 0x65, 0x6c, 0x65, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, - 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x3e, 0x20, 0x54, 0x65, 0x78, 0x74, - 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x3a, 0x20, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x2d, 0x63, - 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x65, - 0x78, 0x74, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, + 0x63, 0x6b, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, - 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x23, - 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x36, 0x36, 0x3b, 0x0a, 0x20, 0x20, - 0x62, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x20, 0x69, 0x6e, 0x73, 0x65, 0x74, - 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, - 0x20, 0x34, 0x20, 0x34, 0x20, 0x34, 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20, - 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x36, 0x30, 0x3b, 0x0a, - 0x7d, 0x0a, 0x0a, 0x54, 0x65, 0x78, 0x74, 0x56, 0x69, 0x65, 0x77, 0x20, + 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x61, 0x78, 0x69, 0x73, 0x3a, 0x20, 0x76, + 0x65, 0x72, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x64, + 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3a, + 0x20, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x3b, 0x0a, 0x20, 0x20, + 0x72, 0x65, 0x76, 0x65, 0x72, 0x73, 0x65, 0x64, 0x3a, 0x20, 0x66, 0x61, + 0x6c, 0x73, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x73, 0x70, 0x61, 0x63, 0x69, + 0x6e, 0x67, 0x3a, 0x20, 0x30, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x53, 0x74, + 0x61, 0x63, 0x6b, 0x56, 0x69, 0x65, 0x77, 0x2e, 0x63, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x73, 0x70, + 0x61, 0x63, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x31, 0x32, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x56, + 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, + 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, + 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x3b, 0x0a, + 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x30, + 0x20, 0x32, 0x20, 0x30, 0x20, 0x32, 0x3b, 0x0a, 0x20, 0x20, 0x6d, 0x69, + 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x38, 0x30, 0x3b, + 0x0a, 0x20, 0x20, 0x6d, 0x69, 0x6e, 0x2d, 0x68, 0x65, 0x69, 0x67, 0x68, + 0x74, 0x3a, 0x20, 0x32, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, + 0x62, 0x6c, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x0a, 0x7d, - 0x0a, 0x0a, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x63, - 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x67, 0x68, 0x6f, 0x73, 0x74, 0x77, - 0x68, 0x69, 0x74, 0x65, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, - 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, - 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x6f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, - 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, - 0x6e, 0x61, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, + 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, + 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, + 0x6f, 0x72, 0x3a, 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x32, + 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, + 0x6f, 0x77, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, + 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, + 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x20, 0x7c, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x20, + 0x20, 0x61, 0x78, 0x69, 0x73, 0x3a, 0x20, 0x68, 0x6f, 0x72, 0x69, 0x7a, + 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x64, 0x69, 0x73, + 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x66, + 0x69, 0x6c, 0x6c, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, + 0x65, 0x52, 0x6f, 0x77, 0x56, 0x69, 0x65, 0x77, 0x3a, 0x6e, 0x74, 0x68, + 0x2d, 0x63, 0x68, 0x69, 0x6c, 0x64, 0x28, 0x65, 0x76, 0x65, 0x6e, 0x29, + 0x20, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x65, 0x6c, 0x6c, 0x56, 0x69, + 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, - 0x20, 0x63, 0x68, 0x61, 0x72, 0x63, 0x6f, 0x61, 0x6c, 0x3b, 0x0a, 0x20, - 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, - 0x72, 0x3a, 0x20, 0x23, 0x64, 0x65, 0x64, 0x65, 0x64, 0x65, 0x61, 0x61, - 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, - 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20, - 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, - 0x3a, 0x20, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, - 0x6e, 0x67, 0x3a, 0x20, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x6f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3e, 0x20, 0x4f, 0x70, 0x74, - 0x69, 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, - 0x65, 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x32, - 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, - 0x20, 0x30, 0x20, 0x34, 0x20, 0x30, 0x20, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, - 0x0a, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3e, 0x20, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, + 0x20, 0x23, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x31, 0x31, 0x3b, 0x0a, + 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x6f, 0x77, 0x56, + 0x69, 0x65, 0x77, 0x3a, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x64, 0x61, 0x72, 0x6b, 0x67, 0x72, 0x61, 0x79, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, + 0x54, 0x61, 0x62, 0x6c, 0x65, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, + 0x53, 0x63, 0x72, 0x6f, 0x6c, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, + 0x20, 0x2e, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x56, 0x69, 0x65, + 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, + 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, + 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x77, + 0x69, 0x64, 0x74, 0x68, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, + 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x73, 0x70, 0x61, + 0x63, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, + 0x54, 0x61, 0x62, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x74, + 0x61, 0x62, 0x50, 0x61, 0x67, 0x65, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x73, 0x69, 0x6c, 0x76, 0x65, 0x72, 0x3b, + 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, + 0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x20, 0x31, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x56, 0x69, + 0x65, 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, + 0x69, 0x6e, 0x67, 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, + 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x20, 0x7c, 0x20, 0x77, 0x69, 0x64, 0x74, + 0x68, 0x3b, 0x0a, 0x20, 0x20, 0x61, 0x78, 0x69, 0x73, 0x3a, 0x20, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x6f, 0x6e, 0x74, 0x61, 0x6c, 0x3b, 0x0a, 0x20, + 0x20, 0x64, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x69, 0x6f, + 0x6e, 0x3a, 0x20, 0x66, 0x69, 0x6c, 0x6c, 0x2d, 0x65, 0x71, 0x75, 0x61, + 0x6c, 0x6c, 0x79, 0x3b, 0x0a, 0x20, 0x20, 0x73, 0x70, 0x61, 0x63, 0x69, + 0x6e, 0x67, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, + 0x62, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x74, 0x61, 0x62, + 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, 0x65, + 0x77, 0x20, 0x3e, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x7b, 0x0a, + 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x32, + 0x20, 0x32, 0x20, 0x32, 0x20, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, + 0x61, 0x62, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x74, 0x61, + 0x62, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, + 0x65, 0x77, 0x20, 0x3e, 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x73, + 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, + 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x64, 0x61, 0x72, 0x6b, 0x67, 0x72, + 0x61, 0x79, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x56, 0x69, + 0x65, 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, + 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x2e, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x20, 0x3e, 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, + 0x0a, 0x20, 0x20, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x67, 0x72, + 0x65, 0x79, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, 0x61, 0x62, 0x56, 0x69, + 0x65, 0x77, 0x20, 0x3e, 0x20, 0x2e, 0x74, 0x61, 0x62, 0x53, 0x65, 0x6c, + 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, + 0x20, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x20, 0x3e, 0x20, 0x54, 0x65, 0x78, + 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, 0x69, 0x64, 0x64, 0x6c, 0x65, 0x2d, + 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x54, + 0x65, 0x78, 0x74, 0x56, 0x69, 0x65, 0x77, 0x20, 0x7b, 0x0a, 0x20, 0x20, + 0x61, 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, + 0x2d, 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, + 0x69, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x23, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x36, 0x36, 0x3b, 0x0a, 0x20, + 0x20, 0x62, 0x65, 0x76, 0x65, 0x6c, 0x3a, 0x20, 0x69, 0x6e, 0x73, 0x65, + 0x74, 0x3b, 0x0a, 0x20, 0x20, 0x63, 0x6c, 0x69, 0x70, 0x73, 0x2d, 0x73, + 0x75, 0x62, 0x76, 0x69, 0x65, 0x77, 0x73, 0x3a, 0x20, 0x74, 0x72, 0x75, + 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x65, 0x64, 0x69, 0x74, 0x61, 0x62, 0x6c, + 0x65, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x3b, 0x0a, 0x20, 0x20, 0x6d, + 0x69, 0x6e, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, 0x20, 0x31, 0x36, + 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, + 0x3a, 0x20, 0x34, 0x20, 0x34, 0x20, 0x34, 0x20, 0x34, 0x3b, 0x0a, 0x7d, + 0x0a, 0x0a, 0x54, 0x65, 0x78, 0x74, 0x56, 0x69, 0x65, 0x77, 0x20, 0x3e, + 0x20, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, + 0x69, 0x67, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x6d, 0x69, 0x64, + 0x64, 0x6c, 0x65, 0x2d, 0x6c, 0x65, 0x66, 0x74, 0x3b, 0x0a, 0x7d, 0x0a, + 0x0a, 0x54, 0x65, 0x78, 0x74, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x63, 0x6f, + 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x67, 0x68, 0x6f, 0x73, 0x74, 0x77, 0x68, + 0x69, 0x74, 0x65, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x63, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, + 0x75, 0x74, 0x6f, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x69, 0x6e, 0x67, 0x2d, + 0x6d, 0x61, 0x73, 0x6b, 0x3a, 0x20, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x61, 0x6c, 0x69, 0x67, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, + 0x61, 0x6c, 0x3b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x63, 0x68, 0x61, 0x72, 0x63, 0x6f, 0x61, 0x6c, 0x3b, 0x0a, 0x20, 0x20, + 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, + 0x3a, 0x20, 0x23, 0x64, 0x65, 0x64, 0x65, 0x64, 0x65, 0x61, 0x61, 0x3b, + 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x72, 0x61, + 0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x34, 0x3b, 0x0a, 0x20, 0x20, 0x62, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x2d, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3a, + 0x20, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, + 0x67, 0x3a, 0x20, 0x32, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x6f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3e, 0x20, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x6f, 0x72, 0x64, 0x65, + 0x72, 0x2d, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, 0x3a, 0x20, 0x32, 0x3b, + 0x0a, 0x20, 0x20, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x3a, 0x20, + 0x32, 0x20, 0x34, 0x20, 0x32, 0x20, 0x34, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3e, 0x20, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, - 0x65, 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, - 0x72, 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, - 0x20, 0x64, 0x69, 0x6d, 0x67, 0x72, 0x61, 0x79, 0x3b, 0x0a, 0x7d, 0x0a, - 0x00 + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x68, 0x6f, 0x76, 0x65, 0x72, 0x20, + 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, 0x6f, 0x75, + 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, 0x64, 0x61, + 0x72, 0x6b, 0x67, 0x72, 0x61, 0x79, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x2e, + 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x20, 0x3e, 0x20, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x20, 0x7b, 0x0a, 0x20, 0x20, 0x62, 0x61, 0x63, 0x6b, 0x67, 0x72, + 0x6f, 0x75, 0x6e, 0x64, 0x2d, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3a, 0x20, + 0x64, 0x69, 0x6d, 0x67, 0x72, 0x61, 0x79, 0x3b, 0x0a, 0x7d, 0x0a, 0x00 }; -unsigned int stylesheet_css_len = 5352; +unsigned int stylesheet_css_len = 7139; diff --git a/Doxyfile b/Doxyfile index 3eec3b8d..ed3c33b1 100644 --- a/Doxyfile +++ b/Doxyfile @@ -228,7 +228,7 @@ TAB_SIZE = 4 # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. -ALIASES = +ALIASES = "styled=@remarks **Styled.** Set from a Style, and overwritten by the next one applied. Assign View::style, or a stylesheet rule, rather than this field." # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" diff --git a/Examples/HUD.c b/Examples/HUD.c index 879d4859..e859b124 100644 --- a/Examples/HUD.c +++ b/Examples/HUD.c @@ -76,7 +76,7 @@ static AppState application; static Label *label(View *superview, const char *text, ViewAlignment alignment) { Label *label = $(alloc(Label), initWithText, text, NULL); - label->view.alignment = alignment; + $(label->view.style, addEnumAttribute, "alignment", ViewAlignmentNames, alignment); $(superview, addSubview, (View *) label); release(label); @@ -90,9 +90,10 @@ static Label *label(View *superview, const char *text, ViewAlignment alignment) static StackView *stackView(View *superview, ViewAlignment alignment) { StackView *stack = $(alloc(StackView), initWithFrame, NULL); - stack->view.alignment = alignment; - stack->view.autoresizingMask = ViewAutoresizingContain; - stack->spacing = 4; + $(stack->view.style, addEnumAttribute, "alignment", ViewAlignmentNames, alignment); + $(stack->view.style, addEnumAttribute, "autoresizing-mask", ViewAutoresizingNames, + ViewAutoresizingContain); + $(stack->view.style, addIntegerAttribute, "spacing", 4); $(superview, addSubview, (View *) stack); release(stack); @@ -139,7 +140,7 @@ static void buildHUD(AppState *app, View *root) { // Ten solid segments sharing the Renderer's white texture: with a shared scissor these // collapse into one draw call, so their count is the direct check that merging works. StackView *segments = stackView(root, ViewAlignmentBottomCenter); - segments->axis = StackViewAxisHorizontal; + $(segments->view.style, addEnumAttribute, "axis", StackViewAxisNames, StackViewAxisHorizontal); for (int i = 0; i < 10; i++) { View *segment = $(alloc(View), initWithFrame, &MakeRect(0, 0, 24, 8)); @@ -150,7 +151,7 @@ static void buildHUD(AppState *app, View *root) { // Eight icons of varied sizes packed into one atlas: one draw call for the whole row StackView *icons = stackView(root, ViewAlignmentTopRight); - icons->axis = StackViewAxisHorizontal; + $(icons->view.style, addEnumAttribute, "axis", StackViewAxisNames, StackViewAxisHorizontal); Theme *theme = app->windowController->theme; @@ -181,15 +182,17 @@ static void buildHUD(AppState *app, View *root) { app->chat = stackView(root, ViewAlignmentTopLeft); Panel *scoreboard = $(alloc(Panel), initWithFrame, NULL); - scoreboard->control.view.alignment = ViewAlignmentMiddleCenter; + $(scoreboard->control.view.style, addEnumAttribute, "alignment", ViewAlignmentNames, + ViewAlignmentMiddleCenter); const int rows = 8; for (int i = 0; i < rows; i++) { StackView *row = $(alloc(StackView), initWithFrame, NULL); - row->axis = StackViewAxisHorizontal; - row->spacing = 32; - row->view.autoresizingMask = ViewAutoresizingContain; + $(row->view.style, addEnumAttribute, "axis", StackViewAxisNames, StackViewAxisHorizontal); + $(row->view.style, addIntegerAttribute, "spacing", 32); + $(row->view.style, addEnumAttribute, "autoresizing-mask", ViewAutoresizingNames, + ViewAutoresizingContain); Label *name = $(alloc(Label), initWithText, "Player", NULL); $(name->text, setTextWithFormat, "Player %d", i + 1); @@ -205,7 +208,7 @@ static void buildHUD(AppState *app, View *root) { release(row); } - $((View *) scoreboard, setHidden, true); + $((View *) scoreboard, setVisibility, ViewVisibilityHidden); $(root, addSubview, (View *) scoreboard); release(scoreboard); @@ -260,7 +263,9 @@ static void updateHUD(AppState *app, Uint64 ticks) { if (ticks >= app->scoreboardDue) { app->scoreboardDue = ticks + 5000; - $((View *) app->scoreboard, setHidden, !app->scoreboard->control.view.hidden); + $((View *) app->scoreboard, setVisibility, + app->scoreboard->control.view.visibility == ViewVisibilityHidden + ? ViewVisibilityVisible : ViewVisibilityHidden); } } diff --git a/Sources/ObjectivelyMVC/Box.c b/Sources/ObjectivelyMVC/Box.c index af159cfd..aa12fe46 100644 --- a/Sources/ObjectivelyMVC/Box.c +++ b/Sources/ObjectivelyMVC/Box.c @@ -76,7 +76,7 @@ static void layoutSubviews(View *self) { super(View, self, layoutSubviews); View *label = (View *) ((Box *) self)->label; - if (label->hidden == false) { + if (label->visibility != ViewVisibilityHidden) { const SDL_Size size = $(label, sizeThatContains); label->frame.y = -size.h * 0.5; @@ -105,10 +105,6 @@ static Box *initWithFrame(Box *self, const SDL_Rect *frame) { self->label = $(alloc(Label), initWithText, NULL, NULL); assert(self->label); - View *label = (View *) self->label; - - label->alignment = ViewAlignmentInternal; - $((View *) self, addSubview, (View *) self->label); } diff --git a/Sources/ObjectivelyMVC/Checkbox.c b/Sources/ObjectivelyMVC/Checkbox.c index fb9c34f2..7dc1ba6f 100644 --- a/Sources/ObjectivelyMVC/Checkbox.c +++ b/Sources/ObjectivelyMVC/Checkbox.c @@ -137,13 +137,9 @@ static Checkbox *initWithFrame(Checkbox *self, const SDL_Rect *frame) { self->box = $(alloc(Control), initWithFrame, frame); assert(self->box); - self->box->view.alignment = ViewAlignmentMiddleCenter; - self->check = $(alloc(ImageView), initWithImage, _check); assert(self->check); - self->check->view.autoresizingMask = ViewAutoresizingFill; - $((View *) self->box, addSubview, (View *) self->check); $((View *) self, addSubview, (View *) self->box); } diff --git a/Sources/ObjectivelyMVC/CollectionItemView.c b/Sources/ObjectivelyMVC/CollectionItemView.c index 0f4122ad..3e5c282e 100644 --- a/Sources/ObjectivelyMVC/CollectionItemView.c +++ b/Sources/ObjectivelyMVC/CollectionItemView.c @@ -81,15 +81,11 @@ static CollectionItemView *initWithFrame(CollectionItemView *self, const SDL_Rec self->imageView = $(alloc(ImageView), initWithFrame, frame); assert(self->imageView); - self->imageView->view.autoresizingMask = ViewAutoresizingFill; - $((View *) self, addSubview, (View *) self->imageView); self->text = $(alloc(Text), initWithText, NULL, NULL); assert(self->text); - self->text->view.alignment = ViewAlignmentMiddleCenter; - $((View *) self, addSubview, (View *) self->text); self->selectionOverlay = $(alloc(View), initWithFrame, NULL); @@ -97,11 +93,8 @@ static CollectionItemView *initWithFrame(CollectionItemView *self, const SDL_Rec $(self->selectionOverlay, addClassName, "selectionOverlay"); - self->selectionOverlay->autoresizingMask = ViewAutoresizingFill; - $((View *) self, addSubview, self->selectionOverlay); - self->view.clipsSubviews = true; } return self; diff --git a/Sources/ObjectivelyMVC/CollectionView.h b/Sources/ObjectivelyMVC/CollectionView.h index c8c5e7c7..a5555a2d 100644 --- a/Sources/ObjectivelyMVC/CollectionView.h +++ b/Sources/ObjectivelyMVC/CollectionView.h @@ -130,6 +130,7 @@ struct CollectionView { /** * @brief The layout axis. + * @styled */ CollectionViewAxis axis; @@ -155,11 +156,13 @@ struct CollectionView { /** * @brief The item size. + * @styled */ SDL_Size itemSize; /** * @brief The item spacing. + * @styled */ SDL_Size itemSpacing; diff --git a/Sources/ObjectivelyMVC/Control.h b/Sources/ObjectivelyMVC/Control.h index 10daf62d..af5d0b6b 100644 --- a/Sources/ObjectivelyMVC/Control.h +++ b/Sources/ObjectivelyMVC/Control.h @@ -95,16 +95,19 @@ struct Control { /** * @brief The ControlBevel. + * @styled */ ControlBevel bevel; /** * @brief The bevel color for the shadowed edges. + * @styled */ SDL_Color bevelDarkColor; /** * @brief The bevel color for the lit edges. + * @styled */ SDL_Color bevelLightColor; @@ -115,6 +118,7 @@ struct Control { /** * @brief The ControlSelection. + * @styled */ ControlSelection selection; }; diff --git a/Sources/ObjectivelyMVC/HSVColorPicker.c b/Sources/ObjectivelyMVC/HSVColorPicker.c index f882677f..c303e49f 100644 --- a/Sources/ObjectivelyMVC/HSVColorPicker.c +++ b/Sources/ObjectivelyMVC/HSVColorPicker.c @@ -124,7 +124,9 @@ static void updateBindings(View *self, ident data) { $(this->saturationSlider, setValue, this->saturation); $(this->valueSlider, setValue, this->value); - this->colorView->backgroundColor = $(this, rgbColor); + const SDL_Color color = $(this, rgbColor); + $(this->colorView->style, addColorAttribute, "background-color", &color); + $(this->colorView, invalidateStyle); } #pragma mark - HSVColorPicker diff --git a/Sources/ObjectivelyMVC/HueColorPicker.c b/Sources/ObjectivelyMVC/HueColorPicker.c index 9b0a146f..c2f99896 100644 --- a/Sources/ObjectivelyMVC/HueColorPicker.c +++ b/Sources/ObjectivelyMVC/HueColorPicker.c @@ -105,7 +105,9 @@ static void updateBindings(View *self, ident data) { $(this->hueSlider, setValue, this->hue); - this->colorView->backgroundColor = $(this, rgbColor); + const SDL_Color color = $(this, rgbColor); + $(this->colorView->style, addColorAttribute, "background-color", &color); + $(this->colorView, invalidateStyle); } #pragma mark - HueColorPicker diff --git a/Sources/ObjectivelyMVC/Input.c b/Sources/ObjectivelyMVC/Input.c index c7d9606c..4b72adee 100644 --- a/Sources/ObjectivelyMVC/Input.c +++ b/Sources/ObjectivelyMVC/Input.c @@ -148,43 +148,49 @@ static void setOrientation(Input *self, InputOrientation orientation) { self->orientation = orientation; - $((View *) self->control, removeFromSuperview); - $((View *) self->label, removeFromSuperview); + View *this = (View *) self, *label = (View *) self->label, *control = (View *) self->control; + + $(control, removeFromSuperview); + $(label, removeFromSuperview); switch (self->orientation) { case InputOrientationLeft: case InputOrientationAbove: - $((View *) self, addSubview, (View *) self->label); - $((View *) self, addSubview, (View *) self->control); + $(this, addSubview, label); + $(this, addSubview, control); break; case InputOrientationRight: case InputOrientationBelow: - $((View *) self, addSubview, (View *) self->control); - $((View *) self, addSubview, (View *) self->label); + $(this, addSubview, control); + $(this, addSubview, label); break; } switch (self->orientation) { case InputOrientationLeft: - self->stackView.axis = StackViewAxisHorizontal; - self->label->view.alignment = ViewAlignmentMiddleLeft; - self->control->view.alignment = ViewAlignmentMiddleRight; + $(this->style, addEnumAttribute, "axis", StackViewAxisNames, StackViewAxisHorizontal); + $(label->style, addEnumAttribute, "alignment", ViewAlignmentNames, ViewAlignmentMiddleLeft); + $(control->style, addEnumAttribute, "alignment", ViewAlignmentNames, ViewAlignmentMiddleRight); break; case InputOrientationRight: - self->stackView.axis = StackViewAxisHorizontal; - self->label->view.alignment = ViewAlignmentMiddleRight; - self->control->view.alignment = ViewAlignmentMiddleLeft; + $(this->style, addEnumAttribute, "axis", StackViewAxisNames, StackViewAxisHorizontal); + $(label->style, addEnumAttribute, "alignment", ViewAlignmentNames, ViewAlignmentMiddleRight); + $(control->style, addEnumAttribute, "alignment", ViewAlignmentNames, ViewAlignmentMiddleLeft); break; case InputOrientationAbove: case InputOrientationBelow: - self->stackView.axis = StackViewAxisVertical; - self->label->view.alignment = ViewAlignmentMiddleCenter; - self->control->view.alignment = ViewAlignmentMiddleCenter; + $(this->style, addEnumAttribute, "axis", StackViewAxisNames, StackViewAxisVertical); + $(label->style, addEnumAttribute, "alignment", ViewAlignmentNames, ViewAlignmentMiddleCenter); + $(control->style, addEnumAttribute, "alignment", ViewAlignmentNames, ViewAlignmentMiddleCenter); break; } + + $(this, invalidateStyle); + $(label, invalidateStyle); + $(control, invalidateStyle); } #pragma mark - Class lifecycle diff --git a/Sources/ObjectivelyMVC/PageView.c b/Sources/ObjectivelyMVC/PageView.c index be74f1ac..be53aca7 100644 --- a/Sources/ObjectivelyMVC/PageView.c +++ b/Sources/ObjectivelyMVC/PageView.c @@ -52,7 +52,7 @@ static void addSubview(View *self, View *subview) { PageView *this = (PageView *) self; - $(subview, setHidden, true); + $(subview, setVisibility, ViewVisibilityHidden); if (this->currentPage == NULL) { $(this, setCurrentPage, subview); @@ -77,7 +77,7 @@ static void removeSubview(View *self, View *subview) { super(View, self, removeSubview, subview); - $(subview, setHidden, false); + $(subview, setVisibility, ViewVisibilityVisible); if (subview == this->currentPage) { $(this, setCurrentPage, NULL); @@ -117,9 +117,9 @@ static void setCurrentPage_enumerate(const Array *array, ident obj, ident data) View *subview = obj; if (subview == ((PageView *) data)->currentPage) { - $(subview, setHidden, false); + $(subview, setVisibility, ViewVisibilityVisible); } else { - $(subview, setHidden, true); + $(subview, setVisibility, ViewVisibilityHidden); } } diff --git a/Sources/ObjectivelyMVC/Panel.c b/Sources/ObjectivelyMVC/Panel.c index 9c038b74..436b7e17 100644 --- a/Sources/ObjectivelyMVC/Panel.c +++ b/Sources/ObjectivelyMVC/Panel.c @@ -119,7 +119,8 @@ static void layoutSubviews(View *self) { resizeHandle->frame.x = self->frame.w - resizeHandle->frame.w; resizeHandle->frame.y = self->frame.h - resizeHandle->frame.h; - $(resizeHandle, setHidden, !this->isResizable); + $(resizeHandle, setVisibility, + this->isResizable ? ViewVisibilityVisible : ViewVisibilityHidden); } #pragma mark - Control @@ -204,7 +205,7 @@ static SDL_Size contentSize(const Panel *self) { SDL_Size size = $(contentView, sizeThatContains); - if (accessoryView->hidden == false) { + if (accessoryView->visibility != ViewVisibilityHidden) { const SDL_Size accessorySize = $(accessoryView, sizeThatContains); size.h -= accessorySize.h + self->stackView->spacing; } @@ -246,7 +247,6 @@ static Panel *initWithFrame(Panel *self, const SDL_Rect *frame) { $((View *) self->accessoryView, addClassName, "accessoryView"); $((View *) self->accessoryView, addClassName, "container"); - self->accessoryView->view.hidden = true; $((View *) self->stackView, addSubview, (View *) self->accessoryView); @@ -255,8 +255,6 @@ static Panel *initWithFrame(Panel *self, const SDL_Rect *frame) { $((View *) self->resizeHandle, addClassName, "resizeHandle"); - self->resizeHandle->view.alignment = ViewAlignmentInternal; - self->resizeHandle->view.frame.w = DEFAULT_PANEL_RESIZE_HANDLE_SIZE; self->resizeHandle->view.frame.h = DEFAULT_PANEL_RESIZE_HANDLE_SIZE; diff --git a/Sources/ObjectivelyMVC/Panel.h b/Sources/ObjectivelyMVC/Panel.h index a5b5ade3..3d45cb76 100644 --- a/Sources/ObjectivelyMVC/Panel.h +++ b/Sources/ObjectivelyMVC/Panel.h @@ -70,6 +70,7 @@ struct Panel { /** * @brief If true, this Panel may be repositioned by the user. + * @styled */ bool isDraggable; @@ -80,6 +81,7 @@ struct Panel { /** * @brief If true, this Panel may be resized by the user. + * @styled */ bool isResizable; diff --git a/Sources/ObjectivelyMVC/RGBColorPicker.c b/Sources/ObjectivelyMVC/RGBColorPicker.c index f82582b5..72b13588 100644 --- a/Sources/ObjectivelyMVC/RGBColorPicker.c +++ b/Sources/ObjectivelyMVC/RGBColorPicker.c @@ -132,7 +132,9 @@ static void updateBindings(View *self, ident data) { $(this->blueSlider, setValue, this->color.b); $(this->alphaSlider, setValue, this->color.a); - this->colorView->backgroundColor = this->color; + const SDL_Color color = this->color; + $(this->colorView->style, addColorAttribute, "background-color", &color); + $(this->colorView, invalidateStyle); } #pragma mark - RGBColorPicker diff --git a/Sources/ObjectivelyMVC/Renderer.c b/Sources/ObjectivelyMVC/Renderer.c index be0b108f..65b84f47 100644 --- a/Sources/ObjectivelyMVC/Renderer.c +++ b/Sources/ObjectivelyMVC/Renderer.c @@ -161,7 +161,7 @@ static SDL_FRect textureRegion(const Texture *texture, const SDL_Rect *src) { /** * @brief The color at `x, y` for a gradient of `angle` degrees across `bounds`. - * @details `angle` is measured clockwise from north, so `0` fills upwards and `90` to the + * @details `angle` is measured clockwise from south, so `0` fills downwards and `90` to the * right. The interpolant is the point's projection onto the gradient axis, normalized by the * extent of `bounds` along that axis, which makes the color an affine function of position: * barycentric interpolation across the triangle then reproduces the gradient exactly, at any @@ -171,7 +171,7 @@ static SDL_Color gradientColor(float x, float y, const SDL_FRect *bounds, int an const SDL_Color *from, const SDL_Color *to) { const float radians = float_radians((float) angle); - const float dx = sinf(radians), dy = -cosf(radians); + const float dx = sinf(radians), dy = cosf(radians); const float cx = bounds->x + bounds->w * 0.5f; const float cy = bounds->y + bounds->h * 0.5f; diff --git a/Sources/ObjectivelyMVC/Renderer.h b/Sources/ObjectivelyMVC/Renderer.h index 0dcb4d65..57d2b0e0 100644 --- a/Sources/ObjectivelyMVC/Renderer.h +++ b/Sources/ObjectivelyMVC/Renderer.h @@ -255,7 +255,7 @@ struct RendererInterface { * @param self The Renderer. * @param points The points, in order. * @param count The number of points; fewer than three draws nothing. - * @param angle The gradient angle in degrees, clockwise from north. Ignored when `to` is + * @param angle The gradient angle in degrees, clockwise from south. Ignored when `to` is * `NULL`. * @param from The fill color, and the near color of the gradient. * @param to The far color of the gradient, or `NULL` to fill flat with `from`. @@ -313,8 +313,8 @@ struct RendererInterface { * @param self The Renderer. * @param rect The rectangle. * @param radius The corner radius. - * @param angle The gradient angle in degrees, clockwise from north: `0` fills upwards, - * `90` to the right, `180` downwards. + * @param angle The gradient angle in degrees, clockwise from south: `0` fills downwards, + * `90` to the right, `180` upwards. * @param from The near color of the gradient. * @param to The far color of the gradient. * @memberof Renderer diff --git a/Sources/ObjectivelyMVC/ScrollBar.c b/Sources/ObjectivelyMVC/ScrollBar.c index 7730c82d..f577ee07 100644 --- a/Sources/ObjectivelyMVC/ScrollBar.c +++ b/Sources/ObjectivelyMVC/ScrollBar.c @@ -176,7 +176,6 @@ static ScrollBar *initWithScrollView(ScrollBar *self, ScrollView *scrollView) { if (self) { $((View *) self, addClassName, "scrollBar"); - ((View *) self)->clipsSubviews = true; self->handle = $(alloc(ScrollHandle), initWithFrame, NULL); assert(self->handle); diff --git a/Sources/ObjectivelyMVC/ScrollView.c b/Sources/ObjectivelyMVC/ScrollView.c index d866ed62..b5e7b770 100644 --- a/Sources/ObjectivelyMVC/ScrollView.c +++ b/Sources/ObjectivelyMVC/ScrollView.c @@ -106,7 +106,8 @@ static void layoutSubviews(View *self) { } } - $((View *) this->scrollBar, setHidden, scrollBarHidden); + $((View *) this->scrollBar, setVisibility, + scrollBarHidden ? ViewVisibilityHidden : ViewVisibilityVisible); super(View, self, layoutSubviews); @@ -165,15 +166,12 @@ static ScrollView *initWithFrame(ScrollView *self, const SDL_Rect *frame) { self = (ScrollView *) super(Control, self, initWithFrame, frame); if (self) { self->step = 12.f; - self->scrollBarVisibility = ScrollBarAuto; self->scrollBar = $(alloc(ScrollBar), initWithScrollView, self); assert(self->scrollBar); View *scrollBar = (View *) self->scrollBar; - scrollBar->alignment = ViewAlignmentRight; - scrollBar->autoresizingMask = ViewAutoresizingHeight; - scrollBar->hidden = true; + $(scrollBar, setVisibility, ViewVisibilityHidden); $((View *) self, addSubview, scrollBar); } @@ -243,8 +241,11 @@ static void setContentView(ScrollView *self, View *contentView) { */ static void setScrollBarVisibility(ScrollView *self, ScrollBarVisibility visibility) { - self->scrollBarVisibility = visibility; - $((View *) self, setNeedsLayout); + View *this = (View *) self; + + $(this->style, addEnumAttribute, "scrollbar", ScrollBarVisibilityNames, visibility); + + $(this, invalidateStyle); } #pragma mark - Class lifecycle diff --git a/Sources/ObjectivelyMVC/ScrollView.h b/Sources/ObjectivelyMVC/ScrollView.h index f9a37302..b92e2d57 100644 --- a/Sources/ObjectivelyMVC/ScrollView.h +++ b/Sources/ObjectivelyMVC/ScrollView.h @@ -96,6 +96,7 @@ struct ScrollView { * @brief Governs whether the scrollbar is shown. Attribute `scrollbar`. * @details `ScrollBarAuto` (the default) shows it only when the content * View's height exceeds this ScrollView's own. + * @styled */ ScrollBarVisibility scrollBarVisibility; }; diff --git a/Sources/ObjectivelyMVC/Select.c b/Sources/ObjectivelyMVC/Select.c index 4ac0bddb..14d9fc1f 100644 --- a/Sources/ObjectivelyMVC/Select.c +++ b/Sources/ObjectivelyMVC/Select.c @@ -71,11 +71,11 @@ static void layoutSubviews(View *self) { Option *option = $(options, objectAtIndex, i); if (option->isSelected) { - $((View *) option, setHidden, false); + $((View *) option, setVisibility, ViewVisibilityVisible); } else if ($(control, isHighlighted)) { - $((View *) option, setHidden, false); + $((View *) option, setVisibility, ViewVisibilityVisible); } else { - $((View *) option, setHidden, true); + $((View *) option, setVisibility, ViewVisibilityHidden); } } diff --git a/Sources/ObjectivelyMVC/Slider.c b/Sources/ObjectivelyMVC/Slider.c index decd2919..1a7b4001 100644 --- a/Sources/ObjectivelyMVC/Slider.c +++ b/Sources/ObjectivelyMVC/Slider.c @@ -101,7 +101,7 @@ static void layoutSubviews(View *self) { if (this->max > this->min) { - if (((View *) this->label)->hidden == false) { + if (((View *) this->label)->visibility != ViewVisibilityHidden) { int minWidth, maxWidth; char text[64]; diff --git a/Sources/ObjectivelyMVC/StackView.c b/Sources/ObjectivelyMVC/StackView.c index 3922d59e..19beb92d 100644 --- a/Sources/ObjectivelyMVC/StackView.c +++ b/Sources/ObjectivelyMVC/StackView.c @@ -277,8 +277,8 @@ static SDL_Size sizeThatFits(const View *self) { release(subviews); - size.w = clamp(size.w, self->minSize.w, self->maxSize.w); - size.h = clamp(size.h, self->minSize.h, self->maxSize.h); + size.w = ClampSize(size.w, self->minSize.w, self->maxSize.w); + size.h = ClampSize(size.h, self->minSize.h, self->maxSize.h); return size; } @@ -293,7 +293,6 @@ static StackView *initWithFrame(StackView *self, const SDL_Rect *frame) { self = (StackView *) super(View, self, initWithFrame, frame); if (self) { - self->view.autoresizingMask = ViewAutoresizingContain; } return self; diff --git a/Sources/ObjectivelyMVC/StackView.h b/Sources/ObjectivelyMVC/StackView.h index 59807fe3..a2264fef 100644 --- a/Sources/ObjectivelyMVC/StackView.h +++ b/Sources/ObjectivelyMVC/StackView.h @@ -80,11 +80,13 @@ struct StackView { /** * @brief The axis. + * @styled */ StackViewAxis axis; /** * @brief The distribution. + * @styled */ StackViewDistribution distribution; @@ -92,11 +94,13 @@ struct StackView { * @brief If true, subviews are laid out in reverse order along View::axis. * @remarks The order of View::subviews, and so of hit testing and drawing, is unchanged; * only the positions along the axis are mirrored. + * @styled */ bool reversed; /** * @brief The subview spacing. + * @styled */ int spacing; }; diff --git a/Sources/ObjectivelyMVC/Style.c b/Sources/ObjectivelyMVC/Style.c index cd1e4a16..41a3f8e2 100644 --- a/Sources/ObjectivelyMVC/Style.c +++ b/Sources/ObjectivelyMVC/Style.c @@ -95,6 +95,100 @@ static bool isEqual(const Object *self, const Object *other) { #pragma mark - Style +/** + * @brief A shorthand attribute, and the longhands it stands for. + * @details Attributes are stored as longhands only, because a View binds each of them to a + * separate Inlet over the same bytes: `padding` and `padding-left` write the same field, and + * the Inlet declared later wins regardless of which Selector the cascade preferred. Expanding + * on the way in means the cascade resolves each longhand on its own, as CSS does. + */ +typedef struct { + const char *shorthand; + const char *longhands[4]; +} StyleShorthand; + +/** + * @remarks The longhands are in the order the shorthand's values are written, which is the + * order of the struct each one binds: `padding` is top right bottom left, `frame` is x y w h. + */ +static const StyleShorthand styleShorthands[] = { + { "corner-cut", { "corner-cut-top-left", "corner-cut-top-right", + "corner-cut-bottom-right", "corner-cut-bottom-left" } }, + { "max-size", { "max-width", "max-height" } }, + { "min-size", { "min-width", "min-height" } }, + { "padding", { "padding-top", "padding-right", "padding-bottom", "padding-left" } }, +}; + +/** + * @return The number of longhands `shorthand` stands for. + */ +static size_t styleShorthandCount(const StyleShorthand *shorthand) { + + size_t count = 0; + while (count < lengthof(shorthand->longhands) && shorthand->longhands[count]) { + count++; + } + + return count; +} + +/** + * @return The StyleShorthand `key` names, or `NULL` if it is already a longhand. + */ +static const StyleShorthand *styleShorthandForKey(const char *key) { + + for (size_t i = 0; i < lengthof(styleShorthands); i++) { + if (strcmp(styleShorthands[i].shorthand, key) == 0) { + return &styleShorthands[i]; + } + } + + return NULL; +} + +/** + * @brief Stores `value` as the longhands of `shorthand`, if it can be split into them. + * @return True if the value was expanded and stored. + * @remarks A single Number splats to every longhand, as View+JSON's rectangle binding does, + * so `padding: 2` still means all four sides. A value of any other shape is left to the Inlet + * binding to reject, rather than being silently dropped here. + */ +static bool addShorthandAttribute(Style *self, const StyleShorthand *shorthand, ident value) { + + const size_t count = styleShorthandCount(shorthand); + + if ($((Object *) value, isKindOfClass, _Number())) { + for (size_t i = 0; i < count; i++) { + $((Dictionary *) self->attributes, setObjectForKeyPath, value, shorthand->longhands[i]); + } + return true; + } + + if ($((Object *) value, isKindOfClass, _Array())) { + const Array *array = value; + if (array->count == count) { + for (size_t i = 0; i < count; i++) { + ident number = $(array, objectAtIndex, i); + $((Dictionary *) self->attributes, setObjectForKeyPath, number, shorthand->longhands[i]); + } + return true; + } + } + + return false; +} + +/** + * @brief Stores `value` under `key`, expanding it into longhands if `key` is a shorthand. + */ +static void setAttribute(Style *self, const char *key, ident value) { + + const StyleShorthand *shorthand = styleShorthandForKey(key); + if (shorthand == NULL || !addShorthandAttribute(self, shorthand, value)) { + $((Dictionary *) self->attributes, setObjectForKeyPath, value, key); + } +} + /** * @fn void Style::addAttribute(Style *self, const char *attr, ident value) * @memberof Style @@ -107,11 +201,19 @@ static void addAttribute(Style *self, const char *attr, ident value) { char *key = strtrim(attr); assert(key); - $((Dictionary *) self->attributes, setObjectForKeyPath, value, key); + setAttribute(self, key, value); free(key); } +/** + * @brief DictionaryEnumerator for addAttributes. + */ +static void addAttributes_enumerate(const Dictionary *dictionary, ident obj, ident key, ident data) { + + setAttribute((Style *) data, ((String *) key)->chars, obj); +} + /** * @fn void Style::addAttributes(Style *self, const Dictionary *attributes) * @memberof Style @@ -120,7 +222,7 @@ static void addAttributes(Style *self, const Dictionary *attributes) { assert(attributes); - $((Dictionary *) self->attributes, addEntriesFromDictionary, attributes); + $(attributes, enumerateObjectsAndKeys, addAttributes_enumerate, self); } /** diff --git a/Sources/ObjectivelyMVC/TabViewController.c b/Sources/ObjectivelyMVC/TabViewController.c index 227f60e0..5c9280cf 100644 --- a/Sources/ObjectivelyMVC/TabViewController.c +++ b/Sources/ObjectivelyMVC/TabViewController.c @@ -50,7 +50,8 @@ static void loadView(ViewController *self) { super(ViewController, self, loadView); - self->view->autoresizingMask = ViewAutoresizingContain; + $(self->view->style, addEnumAttribute, "autoresizing-mask", ViewAutoresizingNames, + ViewAutoresizingContain); TabViewController *this = (TabViewController *) self; diff --git a/Sources/ObjectivelyMVC/TableView.c b/Sources/ObjectivelyMVC/TableView.c index b0c6195f..bbad6efd 100644 --- a/Sources/ObjectivelyMVC/TableView.c +++ b/Sources/ObjectivelyMVC/TableView.c @@ -102,7 +102,7 @@ static void layoutSubviews(View *self) { SDL_Rect frame = $(self, bounds); - if (headerView->hidden == false) { + if (headerView->visibility != ViewVisibilityHidden) { const SDL_Size size = $(headerView, sizeThatFits); diff --git a/Sources/ObjectivelyMVC/Text.h b/Sources/ObjectivelyMVC/Text.h index 280db155..b54a481f 100644 --- a/Sources/ObjectivelyMVC/Text.h +++ b/Sources/ObjectivelyMVC/Text.h @@ -143,6 +143,7 @@ struct Text { /** * @brief The text color. + * @styled */ SDL_Color color; diff --git a/Sources/ObjectivelyMVC/TextView.c b/Sources/ObjectivelyMVC/TextView.c index 1c7742ce..df1ea0ec 100644 --- a/Sources/ObjectivelyMVC/TextView.c +++ b/Sources/ObjectivelyMVC/TextView.c @@ -436,7 +436,6 @@ static TextView *initWithFrame(TextView *self, const SDL_Rect *frame) { $((View *) self, addSubview, (View *) self->text); - self->control.view.clipsSubviews = true; } return self; diff --git a/Sources/ObjectivelyMVC/TextView.h b/Sources/ObjectivelyMVC/TextView.h index 3bb23f23..29c7c0cf 100644 --- a/Sources/ObjectivelyMVC/TextView.h +++ b/Sources/ObjectivelyMVC/TextView.h @@ -106,6 +106,7 @@ struct TextView { /** * @brief True if this TextView supports editing, false otherwise. + * @styled */ bool isEditable; diff --git a/Sources/ObjectivelyMVC/View.c b/Sources/ObjectivelyMVC/View.c index a561a7ff..1bcca931 100644 --- a/Sources/ObjectivelyMVC/View.c +++ b/Sources/ObjectivelyMVC/View.c @@ -49,6 +49,17 @@ void MVC_InvalidateRenderFrames(void) { } } +const EnumName ViewPointerEventsNames[] = MakeEnumNames( + MakeEnumAlias(ViewPointerEventsAuto, auto), + MakeEnumAlias(ViewPointerEventsNone, none) +); + +const EnumName ViewVisibilityNames[] = MakeEnumNames( + MakeEnumAlias(ViewVisibilityUnspecified, unspecified), + MakeEnumAlias(ViewVisibilityVisible, visible), + MakeEnumAlias(ViewVisibilityHidden, hidden) +); + const EnumName ViewAlignmentNames[] = MakeEnumNames( MakeEnumAlias(ViewAlignmentNone, none), MakeEnumAlias(ViewAlignmentTop, top), @@ -277,8 +288,6 @@ static void applyStyle(View *self, const Style *style) { MakeInlet("corner-cut-top-right", InletTypeInteger, &self->cornerCut.topRight, NULL), MakeInlet("corner-cut-bottom-right", InletTypeInteger, &self->cornerCut.bottomRight, NULL), MakeInlet("corner-cut-bottom-left", InletTypeInteger, &self->cornerCut.bottomLeft, NULL), - MakeInlet("frame", InletTypeRectangle, &self->frame, NULL), - MakeInlet("hidden", InletTypeBool, &self->hidden, NULL), MakeInlet("height", InletTypeInteger, &self->frame.h, NULL), MakeInlet("left", InletTypeInteger, &self->frame.x, NULL), MakeInlet("max-height", InletTypeInteger, &self->maxSize.h, NULL), @@ -292,20 +301,22 @@ static void applyStyle(View *self, const Style *style) { MakeInlet("padding-right", InletTypeInteger, &self->padding.right, NULL), MakeInlet("padding-bottom", InletTypeInteger, &self->padding.bottom, NULL), MakeInlet("padding-left", InletTypeInteger, &self->padding.left, NULL), - MakeInlet("pointer-events", InletTypeBool, &self->pointerEvents, NULL), + MakeInlet("pointer-events", InletTypeEnum, &self->pointerEvents, (ident) ViewPointerEventsNames), MakeInlet("top", InletTypeInteger, &self->frame.y, NULL), + MakeInlet("visibility", InletTypeEnum, &self->visibility, (ident) ViewVisibilityNames), MakeInlet("width", InletTypeInteger, &self->frame.w, NULL) ); $(self, bind, inlets, style->attributes); - // Capture the authored width/height, if either was actually present in this Style -- distinct - // from self->frame.w/h, which layout goes on to freely resize. - if ($(style->attributes, objectForKeyPath, "width")) { - self->styledSize.w = self->frame.w; + if ((self->alignment & ViewAlignmentMaskHorizontal) && + $(style->attributes, objectForKeyPath, "left")) { + $(self, warn, WarningTypeStyle, "`left` is overruled by the horizontal `alignment`"); } - if ($(style->attributes, objectForKeyPath, "height")) { - self->styledSize.h = self->frame.h; + + if ((self->alignment & ViewAlignmentMaskVertical) && + $(style->attributes, objectForKeyPath, "top")) { + $(self, warn, WarningTypeStyle, "`top` is overruled by the vertical `alignment`"); } } @@ -320,13 +331,15 @@ static void applyTheme(View *self, const Theme *theme) { Style *computedStyle = $(theme, computeStyle, self); assert(computedStyle); - if (!$(self->computedStyle, isComputedEqual, computedStyle)) { + if (self->needsApplyStyle || !$(self->computedStyle, isComputedEqual, computedStyle)) { release(self->computedStyle); self->computedStyle = retain(computedStyle); $(self->computedStyle, addAttributes, self->style->attributes); $(self, applyStyle, self->computedStyle); + + self->needsApplyStyle = false; } release(computedStyle); @@ -758,7 +771,7 @@ static void draw(View *self, Renderer *renderer) { assert(self->window); - if (self->hidden == false) { + if (self->visibility != ViewVisibilityHidden) { $(renderer, drawView, self); @@ -955,7 +968,7 @@ static void hasOverflow_enumerate(View *view, ident data) { Overflow *overflow = data; - if (!view->hidden) { + if (view->visibility != ViewVisibilityHidden) { const SDL_Rect bounds = $(view, bounds); @@ -990,7 +1003,7 @@ static bool hasOverflow(const View *self) { */ static View *hitTest(const View *self, const SDL_Point *point) { - if (self->hidden == false) { + if (self->visibility != ViewVisibilityHidden) { if ($(self, containsPoint, point)) { @@ -1004,7 +1017,7 @@ static View *hitTest(const View *self, const SDL_Point *point) { } } - return self->pointerEvents ? (View *) self : NULL; + return self->pointerEvents == ViewPointerEventsAuto ? (View *) self : NULL; } } @@ -1047,10 +1060,6 @@ static View *initWithFrame(View *self, const SDL_Rect *frame) { self->warnings = $$(Array, arrayWithCapacity, 0); assert(self->warnings); - self->backgroundGradientAngle = 180; - self->maxSize = MakeSize(INT32_MAX, INT32_MAX); - self->pointerEvents = true; - self->needsApplyTheme = true; self->needsLayout = true; } @@ -1062,6 +1071,9 @@ static View *initWithFrame(View *self, const SDL_Rect *frame) { * @brief ViewEnumerator for invalidateStyle. */ static void invalidateStyle_enumerate(View *view, ident data) { + + view->needsApplyStyle = true; + $(view, setNeedsApplyTheme); } @@ -1132,7 +1144,7 @@ static bool isTouchResponder(const View *self) { static bool isVisible(const View *self) { for (const View *view = self; view; view = view->superview) { - if (view->hidden) { + if (view->visibility == ViewVisibilityHidden) { return false; } } @@ -1675,8 +1687,8 @@ static void resignTouchResponder(View *self) { */ static void resize(View *self, const SDL_Size *size) { - const int w = clamp(size->w, self->minSize.w, self->maxSize.w); - const int h = clamp(size->h, self->minSize.h, self->maxSize.h); + const int w = ClampSize(size->w, self->minSize.w, self->maxSize.w); + const int h = ClampSize(size->h, self->minSize.h, self->maxSize.h); if (self->frame.w != w || self->frame.h != h) { @@ -1796,14 +1808,16 @@ static View *selectFirst(View *self, const char *rule) { } /** - * @fn void View::setHidden(View *self, bool hidden) + * @fn void View::setVisibility(View *self, ViewVisibility visibility) * @memberof View */ -static void setHidden(View *self, bool hidden) { +static void setVisibility(View *self, ViewVisibility visibility) { + + if (self->visibility != visibility) { - if (self->hidden != hidden) { + self->visibility = visibility; - self->hidden = hidden; + $(self->style, addEnumAttribute, "visibility", ViewVisibilityNames, visibility); if (self->superview && $(self->superview, isContainer)) { $(self->superview, setNeedsLayout); @@ -1910,15 +1924,10 @@ static SDL_Size sizeThatFits(const View *self) { release(subviews); - // A styled width/height is authored intent for this View's own frame; floor the - // children-derived sum against it so it survives summing subviews with no size of their - // own to contribute (e.g. Slider, whose bar and handle have none independently). - size.w = max(size.w, self->styledSize.w); - size.h = max(size.h, self->styledSize.h); } - size.w = clamp(size.w, self->minSize.w, self->maxSize.w); - size.h = clamp(size.h, self->minSize.h, self->maxSize.h); + size.w = ClampSize(size.w, self->minSize.w, self->maxSize.w); + size.h = ClampSize(size.h, self->minSize.h, self->maxSize.h); return size; } @@ -1954,8 +1963,8 @@ static SDL_Size sizeThatSatisfies(View *self, ViewConstraint width, ViewConstrai size.w = resolveViewConstraint(self->autoresizingMask & ViewAutoresizingWidth, width, size.w); size.h = resolveViewConstraint(self->autoresizingMask & ViewAutoresizingHeight, height, size.h); - size.w = clamp(size.w, self->minSize.w, self->maxSize.w); - size.h = clamp(size.h, self->minSize.h, self->maxSize.h); + size.w = ClampSize(size.w, self->minSize.w, self->maxSize.w); + size.h = ClampSize(size.h, self->minSize.h, self->maxSize.h); return size; } @@ -2139,7 +2148,7 @@ static bool visibleSubviews_filter(ident obj, ident data) { const View *view = (View *) obj; - return view->hidden == false && view->alignment != ViewAlignmentInternal; + return view->visibility != ViewVisibilityHidden && view->alignment != ViewAlignmentInternal; } /** @@ -2269,7 +2278,7 @@ static void initialize(Class *clazz) { ((ViewInterface *) clazz->interface)->respondToEvent = respondToEvent; ((ViewInterface *) clazz->interface)->select = _select; ((ViewInterface *) clazz->interface)->selectFirst = selectFirst; - ((ViewInterface *) clazz->interface)->setHidden = setHidden; + ((ViewInterface *) clazz->interface)->setVisibility = setVisibility; ((ViewInterface *) clazz->interface)->setNeedsApplyTheme = setNeedsApplyTheme; ((ViewInterface *) clazz->interface)->setNeedsLayout = setNeedsLayout; ((ViewInterface *) clazz->interface)->size = size; diff --git a/Sources/ObjectivelyMVC/View.h b/Sources/ObjectivelyMVC/View.h index d553f454..1f8c4118 100644 --- a/Sources/ObjectivelyMVC/View.h +++ b/Sources/ObjectivelyMVC/View.h @@ -97,6 +97,34 @@ typedef enum { OBJECTIVELYMVC_EXPORT const EnumName ViewAutoresizingNames[]; +/** + * @brief Clamps `size` to `min` and `max`, where a `max` of zero is unbounded. + */ +#define ClampSize(size, min, max) \ + clamp((size), (min), (max) ? (max) : INT32_MAX) + +/** + * @brief Whether a View is the result of a hit test. + */ +typedef enum { + ViewPointerEventsAuto, + ViewPointerEventsNone +} ViewPointerEvents; + +OBJECTIVELYMVC_EXPORT const EnumName ViewPointerEventsNames[]; + +/** + * @brief Visibility constants. + */ +typedef enum { + ViewVisibilityUnspecified, + ViewVisibilityVisible, + ViewVisibilityHidden +} ViewVisibility; + + +OBJECTIVELYMVC_EXPORT const EnumName ViewVisibilityNames[]; + /** * @brief A constraint offered by an ancestor View to a descendant during View::sizeThatSatisfies. */ @@ -209,22 +237,26 @@ struct View { /** * @brief The alignment. + * @styled */ ViewAlignment alignment; /** * @brief The ViewAutoresizing bitmask. + * @styled */ int autoresizingMask; /** * @brief The background color. + * @styled */ SDL_Color backgroundColor; /** - * @brief The angle of the background gradient, in degrees, clockwise from north: `0` fills - * upwards, `90` to the right, `180` (the default) downwards. + * @brief The angle of the background gradient, in degrees, clockwise from south: `0` (the + * default) fills downwards, `90` to the right, `180` upwards. + * @styled */ int backgroundGradientAngle; @@ -232,21 +264,25 @@ struct View { * @brief The far color of the background gradient, which runs from View::backgroundColor. * @remarks The gradient is drawn only when this color has a non-zero alpha; otherwise the * background is a flat View::backgroundColor. + * @styled */ SDL_Color backgroundGradientColor; /** * @brief The border color. + * @styled */ SDL_Color borderColor; /** * @brief The corner radius applied to the background, border and bevel. + * @styled */ int borderRadius; /** * @brief The border width. + * @styled */ int borderWidth; @@ -268,6 +304,7 @@ struct View { /** * @brief If true, subviews will be clipped to this View's frame. + * @styled */ bool clipsSubviews; @@ -280,6 +317,7 @@ struct View { * @brief The horizontal inset of each corner of the background and border. * @remarks A View with any corner inset is drawn as a polygon rather than through the * rounded rectangle shader, so View::borderRadius does not apply to it. + * @styled */ ViewCornerCut cornerCut; @@ -288,12 +326,6 @@ struct View { */ SDL_Rect frame; - /** - * @brief If `true`, this View is not drawn. - * @see View::setHidden(View *, bool) - */ - bool hidden; - /** * @brief An optional identifier. * @remarks Identifiers are commonly used to resolve Outlets when loading Views via JSON. @@ -302,11 +334,13 @@ struct View { /** * @brief The maximum size this View may be resized to during layout. + * @styled */ SDL_Size maxSize; /** * @brief The minimum size this View may be resized to during layout. + * @styled */ SDL_Size minSize; @@ -318,6 +352,15 @@ struct View { */ bool needsApplyTheme; + /** + * @brief If true, this View's Style must be applied even if the same Selectors still match. + * @remarks Set by View::invalidateStyle, which is how a change to View::style asks to be + * seen: the Selectors that matched are unchanged, so View::applyTheme's comparison cannot + * tell that anything happened. + * @private + */ + bool needsApplyStyle; + /** * @brief If true, a descendant of this View has `needsApplyTheme` set. * @remarks Maintained by View::setNeedsApplyTheme; View::applyThemeIfNeeded only descends @@ -350,18 +393,19 @@ struct View { /** * @brief The padding. + * @styled */ ViewPadding padding; /** - * @brief If `false`, this View is never the result of a hit test; its subviews still are. - * @remarks Defaults to `true`. Overlays that are drawn but never interacted with, such as a - * full-window HUD or console layer stacked above interactive content, SHOULD set this to - * `false` so that clicks pass through them to whatever lies beneath. Styled as - * `pointer-events: false`. + * @brief Whether this View is the result of a hit test; its subviews always are. + * @remarks An overlay that is drawn but never interacted with, such as a full-window HUD or + * console layer stacked above interactive content, SHOULD be `none` so that clicks pass + * through it to whatever lies beneath. Styled as `pointer-events`. * @see View::hitTest(const View *, const SDL_Point *) + * @styled */ - bool pointerEvents; + ViewPointerEvents pointerEvents; /** * @brief The cached View::renderFrame, valid while `generation` matches the current @@ -380,17 +424,6 @@ struct View { */ Style *style; - /** - * @brief The `width`/`height` this View was most recently given via styling, per axis. - * @remarks Written only when a `width` or `height` Style attribute is actually present -- not - * on every View::applyStyle call -- so it reflects the last authored value for an axis, or - * `0` if that axis has never been styled. View::sizeThatFits's container branch floors its - * children-derived sum against this, so an authored size survives being a Contain view with no - * content of its own to size from (e.g. Slider, whose `bar` and `handle` have none - * independently). - */ - SDL_Size styledSize; - /** * @brief An optional Stylesheet. * @remarks If set, this Stylesheet is added to or removed from the current Theme when this @@ -415,6 +448,14 @@ struct View { */ ViewController *viewController; + /** + * @brief Whether this View is drawn, and contributes to its superview's size. + * @remarks `unspecified` is visible. + * @see View::setVisibility(View *, ViewVisibility) + * @styled + */ + ViewVisibility visibility; + /** * @brief The Warnings this View generated. * @remarks These are optionally displayed by the DebugViewController. @@ -934,10 +975,6 @@ struct ViewInterface { * This method is called by View::layoutIfNeeded only after a View::sizeThatSatisfies pass has * already resolved `self->frame`; it must not perform any sizing of its own, only positioning * and committing of subview frames. - * @remarks The default implementation resolves each subview's size via View::layoutWithConstraint, - * offering `ViewConstraintEqual` for a `ViewAutoresizingWidth`/`Height` subview (since this - * View's bounds are already final) or `ViewConstraintUnspecified` otherwise (so the subview - * sizes itself from its own content). * @memberof View */ void (*layoutSubviews)(View *self); @@ -1149,16 +1186,16 @@ struct ViewInterface { View *(*selectFirst)(View *self, const char *rule); /** - * @fn void View::setHidden(View *self, bool hidden) - * @brief Sets this View's hidden state. + * @fn void View::setVisibility(View *self, ViewVisibility visibility) + * @brief Sets this View's visibility. * @param self The View. - * @param hidden The hidden state. - * @remarks Hiding or unhiding a View changes its superview's View::visibleSubviews, so this - * marks the superview `needsLayout` if it is a container; writing `self->hidden` directly does - * not. + * @param visibility The visibility. + * @remarks Callers MUST use this method rather than assigning View::visibility directly: it + * marks the superview `needsLayout` if it is a container, and writes View::style so that the + * choice outlives the next Style applied. * @memberof View */ - void (*setHidden)(View *self, bool hidden); + void (*setVisibility)(View *self, ViewVisibility visibility); /** * @fn void View::setNeedsApplyTheme(View *self) diff --git a/Sources/ObjectivelyMVC/ViewController.c b/Sources/ObjectivelyMVC/ViewController.c index 0eec28c4..660af250 100644 --- a/Sources/ObjectivelyMVC/ViewController.c +++ b/Sources/ObjectivelyMVC/ViewController.c @@ -100,7 +100,7 @@ static void loadView(ViewController *self) { View *view = $(alloc(View), initWithFrame, NULL); assert(view); - view->autoresizingMask = ViewAutoresizingFill; + $(view, addClassName, "viewController"); $(self, setView, view); release(view); diff --git a/Tests/ObjectivelyMVC/View.c b/Tests/ObjectivelyMVC/View.c index 6d8ce3e3..14720592 100644 --- a/Tests/ObjectivelyMVC/View.c +++ b/Tests/ObjectivelyMVC/View.c @@ -234,18 +234,17 @@ START_TEST(fillOnlyChildFillsContainBounds) { } END_TEST -START_TEST(styledSizeFloorsContainBoundsWithNoMinSize) { +START_TEST(minSizeFloorsContainBounds) { - // Mirrors Slider itself: a styled `width` is the only thing giving a Contain view with no - // sized content of its own (a bare `fill` leaf, contributing nothing) a real width -- with no - // minSize set at all, unlike fillOnlyChildFillsContainBounds above. + // Mirrors Slider itself: a styled `min-width` is the only thing giving a Contain view with no + // sized content of its own (a bare `fill` leaf, contributing nothing) a real width. View *outer = $(alloc(View), initWithFrame, NULL); outer->autoresizingMask = ViewAutoresizingContain; Style *style = $(alloc(Style), initWithAttributes, NULL); - $(style, addIntegerAttribute, "width", 140); - $(style, addIntegerAttribute, "height", 24); + $(style, addIntegerAttribute, "min-width", 140); + $(style, addIntegerAttribute, "min-height", 24); $(outer, applyStyle, style); release(style); @@ -266,9 +265,10 @@ START_TEST(styledSizeFloorsContainBoundsWithNoMinSize) { } END_TEST -START_TEST(setHiddenMarksSuperviewNeedsLayout) { +START_TEST(setVisibilityMarksSuperviewNeedsLayout) { StackView *stackView = $(alloc(StackView), initWithFrame, NULL); + stackView->view.autoresizingMask = ViewAutoresizingContain; View *a = fixedView(40, 20); View *b = fixedView(60, 30); @@ -278,7 +278,7 @@ START_TEST(setHiddenMarksSuperviewNeedsLayout) { $((View *) stackView, layoutIfNeeded); - $(a, setHidden, true); + $(a, setVisibility, ViewVisibilityHidden); $((View *) stackView, layoutIfNeeded); ck_assert_int_eq(60, stackView->view.frame.w); @@ -336,13 +336,13 @@ START_TEST(pointerEventsPassThroughToSubviewsAndSiblings) { ck_assert_ptr_eq(button, $(root, hitTest, &MakePoint(10, 10))); ck_assert_ptr_eq(overlay, $(root, hitTest, &MakePoint(300, 100))); - overlay->pointerEvents = false; + overlay->pointerEvents = ViewPointerEventsNone; ck_assert_ptr_eq(button, $(root, hitTest, &MakePoint(10, 10))); ck_assert_ptr_eq(beneath, $(root, hitTest, &MakePoint(300, 100))); Style *style = $(alloc(Style), initWithRules, "View"); - $(style, addBoolAttribute, "pointer-events", true); + $(style, addEnumAttribute, "pointer-events", ViewPointerEventsNames, ViewPointerEventsAuto); $(overlay, applyStyle, style); release(style); @@ -365,8 +365,8 @@ int main(int argc, char **argv) { tcase_add_test(tcase, stackViewMeasuresFreshNotStale); tcase_add_test(tcase, standaloneRelayoutDoesNotShrinkFillChild); tcase_add_test(tcase, fillOnlyChildFillsContainBounds); - tcase_add_test(tcase, styledSizeFloorsContainBoundsWithNoMinSize); - tcase_add_test(tcase, setHiddenMarksSuperviewNeedsLayout); + tcase_add_test(tcase, minSizeFloorsContainBounds); + tcase_add_test(tcase, setVisibilityMarksSuperviewNeedsLayout); tcase_add_test(tcase, alignedContainChildRecentersOnGrowth); tcase_add_test(tcase, pointerEventsPassThroughToSubviewsAndSiblings); diff --git a/configure.ac b/configure.ac index 6532c7eb..ecbcc83c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ(2.69) -AC_INIT([ObjectivelyMVC], [2.4.7], [jay@jaydolan.com]) +AC_INIT([ObjectivelyMVC], [2.5.0], [jay@jaydolan.com]) AC_SUBST([RELEASE_VERSION], [m4_bpatsubst(AC_PACKAGE_VERSION, [\.[0-9]*$], [])]) AC_CONFIG_HEADERS([Sources/ObjectivelyMVC/Config.h])