/*!
// Contents
// ------------------------------------------------

 1. Mixins
 2. Helper classes & resets
 3. Loader
 4. Colours
 5. Typography
 6. Spacing
 7. Buttons
 8. Navigation
 9. Slider, Dividers
 10. Speakers & Topics
 11. Schedule
 12. Galleries
 13. Pricing & FAQ
 14. Subscribe
 15. Contact
 16. Forms
 17. Footers

// --------------------------------------------------*/

@import "variables.less";
@import "mixins.less";

/*!
// 1. Useful Mixins
// --------------------------------------------------*/

.vertical-align {
  position: relative;
  top: 50%;
  -webkit-transform: translateY(-50%);
  -ms-transform: translateY(-50%);
  transform: translateY(-50%);
}

.vertical-align-cancel{
	top: 0px;
	-webkit-transform: translateY(0px);
	-ms-transform: translateY(0px);
	transform: translateY(0px);
}

.preserve-3d {
  -webkit-transform-style: preserve-3d;
  -moz-transform-style: preserve-3d;
  transform-style: preserve-3d;
}

.transition-100{
	transition: all .1s ease-out;
	-webkit-transition: all .1s ease-out;
	-moz-transition: all .1s ease-out;
}

.transition-300{
	transition: all .3s ease-out;
	-webkit-transition: all .3s ease-out;
	-moz-transition: all .3s ease-out;
}

.transition-700{
	transition: all .7s ease-out;
	-webkit-transition: all .7s ease-out;
	-moz-transition: all .7s ease-out;
}

.translate3d(@x,@y,@z){
	transform: translate3d(@x,@y,@z);
	-webkit-transform: translate3d(@x,@y,@z);
	-moz-transform: translate3d(@x,@y,@z);
}

.scale2d(@x,@y){
	transform: scale(@x,@y);
	-webkit-transform: scale(@x,@y);
	-moz-transform: scale(@x,@y);
}

.overlay-params(@strength, @bg-color){
	background-color: @bg-color;
	opacity: @strength;
	position: absolute;
	content: '';
	width: 100%;
	height: 100%;
	z-index: 1;
	top: 0px;
}

.overlay:before{ .overlay-params(@strength: 0.5, @bg-color: @color-heading); }
.overlay .container{ position: relative; z-index: 2; }

/*!
// 2. Helper Classes & Resets
// --------------------------------------------------*/

.go-right{ right: 0px; }
.go-left{ left: 0px; }

img{ max-width: 100%; }

.main-container{ .transition-300; }

/*!
// 3. Loader
// --------------------------------------------------*/

.loader{ position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; z-index: 99; background: #fff; .preserve-3d; .transition-300; opacity: 1; }
.strip-holder{ .vertical-align; left: 50%; margin-left: -50px; position: relative; }
.strip-1, .strip-2, .strip-3{ width: 20px; height: 20px; background: @color-primary; position: relative; -webkit-animation: stripMove 2s ease infinite alternate; animation: stripMove 2s ease infinite alternate; -moz-animation: stripMove 2s ease infinite alternate; }
.strip-2{ -webkit-animation-duration: 2.1s; animation-duration: 2.1s; background-color: lighten(@color-primary, 20%); }
.strip-3{ -webkit-animation-duration: 2.2s; animation-duration: 2.2s; background-color: lighten(@color-primary, 40%); }

@-webkit-keyframes stripMove{
	0% { .translate3d(@x: 0px, @y: 0px, @z: 0px); }
	50% { .translate3d(@x: 0px, @y: 0px, @z: 0px); .scale2d(@x: 4, @y: 1); }
	100% { .translate3d(@x: -50px, @y: 0px, @z: 0px); }
}

@-moz-keyframes stripMove{
	0% { .translate3d(@x: -50px, @y: 0px, @z: 0px); }
	50% { .translate3d(@x: 0px, @y: 0px, @z: 0px); .scale2d(@x: 4, @y: 1); }
	100% { .translate3d(@x: 50px, @y: 0px, @z: 0px); }
}

@keyframes stripMove{
	0% { .translate3d(@x: -50px, @y: 0px, @z: 0px); }
	50% { .translate3d(@x: 0px, @y: 0px, @z: 0px); .scale2d(@x: 4, @y: 1); }
	100% { .translate3d(@x: 50px, @y: 0px, @z: 0px); }
}

.main-container{ .transition-300; opacity: 0; }
nav{ .transition-300; opacity: 0; }
.show-content{ opacity: 1 !important; }
.hide-loader{ opacity: 0 !important; }

/*!
// 4. Colours
// --------------------------------------------------*/

@color-primary: #FFA900;
@color-heading: #333;
@color-body: #777;
@color-muted: #f5f5f5 !important;

.background-dark{ background-color: @color-heading !important; }
.color-heading{ color: @color-heading; }

/*!
// 5. Typography
// --------------------------------------------------*/

@custom-heading-font: 'Open Sans';
@custom-body-font: 'Open Sans';

.text-white{ color: #fff; }

body{ font-family: @custom-body-font,"Helvetica Neue", Helvetica, Arial, sans-serif; font-smoothing: antialiased; -webkit-font-smoothing: antialiased; color: @color-body; font-size: 14px; line-height: 24px; background: #fff; }
h1,h2,h3,h4,h5,h6{ font-family: @custom-heading-font,"Helvetica Neue", Helvetica, Arial, sans-serif; font-weight: 300; margin: 0px; color: @color-heading; }

h1{ font-size: 30px; line-height: 36px; margin-bottom: 42px; }
h3{ font-size: 20px; line-height: 28px; }

.large-h1{ font-size: 42px; line-height: 48px; font-weight: 300;  }

p{ font-size: 14px; line-height: 24px; }
p:last-child{ margin-bottom: 0px; }
p.lead{ font-size: 16px; line-height: 30px; font-weight: 400; }
span.lead{ font-weight: 400; }
.uppercase{ text-transform: uppercase; letter-spacing: 1px; display: inline-block; margin-right: -1px; }

strong{ font-weight: 600; }

ul{ list-style: none; margin: 0px; padding: 0px; }

@media all and(max-width: 767px){
	h1{ font-size: 24px; line-height: 28px; margin-bottom: 36px; }
	h2{ font-size: 20px; line-height: 26px; }

	.large-h1{ font-size: 24px; line-height: 28px; }

	p{ font-size: 13px; line-height: 22px; }
	p.lead{ font-size: 15px; line-height: 26px; }
}

/*!
// Spacing Standards
// --------------------------------------------------*/

@standard-space: 72px;

section{ padding: @standard-space 0px; background: #fff; }

.duplicatable-content{ padding-bottom: @standard-space/2; }

/*!
// 6. Buttons
// --------------------------------------------------*/

a:hover{ text-decoration: none; }
h1 a, span a,p a,.text-link a{ font-weight: 600; color: #fff; display: inline-block; border-bottom: 4px solid #fff; padding-bottom: 6px; .transition-300; }
span a, p a,.text-link a{ padding-bottom: 4px; border-bottom: 3px solid #fff; }
span a:hover{ color: #fff; }
p a, .text-link a{ color: @color-primary !important; border-color: @color-primary; padding-bottom: 2px; }
p a, .text-link a:hover{ color: @color-heading; }

.btn{ min-width: 180px; border-radius: 25px; background: @color-primary; text-align: center; padding: 13px 0px 14px 0px; color: #fff; font-size: 15px; .transition-300; font-weight: 600; line-height: 1;  }
.btn:hover{ color: #fff; background: darken(@color-primary, 5%); }
.btn-hollow{ background: none; border: 2px solid @color-primary; color: @color-primary; }
.btn-hollow:hover{ background: @color-primary; }

.btn-white{ background: #fff; color: @color-primary; }
.btn-white:hover{ background: #fff; color: darken(@color-primary,10%); }

.btn-hollow.btn-white{ background: none; border-color: #fff; color: #fff; }
.btn-hollow.btn-white:hover{ background: #fff; color: @color-primary; }

.btn-lg{ padding: 20px 0px 21px 0px; text-transform: uppercase; min-width: 230px; border-radius: 35px; }

/*!
// Backgrounds & Parallax
// --------------------------------------------------*/

.background-image-holder{ position: absolute; width: 100%; height: 130%; top: -10%; background-size: cover !important; background-position: 50% 50% !important; }
.image-holder{ position: relative; overflow: hidden; }

/*!
// 7. Navigation
// --------------------------------------------------*/

nav .logo{ max-height: 45px; max-width: 110px; position: absolute; top: -6px; opacity: 1; }
nav .text-right{ position: relative; }
nav .container{ .transition-300; }

.overlay-nav{ position:fixed; top: 0px; z-index: 10; width: 100%; padding-top: @standard-space/3; line-height: 1; background: none; .transition-300; }
.overlay-nav .logo-dark{ opacity: 0; }
.overlay-nav.sticky-nav .logo-light{ opacity: 0; }
.overlay-nav.sticky-nav .logo-dark{ opacity: 1; }

.bottom-border{ position: absolute; bottom: 2px; width: 100%; height: 2px; background: rgba(255,255,255,0.3); }
.sidebar-menu .bottom-border{ position: relative; bottom: 0px; background: rgba(255,255,255,0.2); display: block !important; }

.menu{ display: inline-block; text-align: left; line-height: 1; }
.menu li{ float: left; margin-right: 32px; font-size: 11px; text-transform: uppercase; letter-spacing: 1px; font-weight: 600; position: relative; top: 4px; }
.menu li:last-child{ margin-right: 0px; }
.menu li:nth-las-child(2){ margin-right: 12px; }
.menu li a{ color: #fff; display: inline-block; padding-bottom: @standard-space/3; border-bottom: 2px solid rgba(0,0,0,0); .transition-300; }
.menu li a:hover{ border-bottom: 2px solid #fff; }

.nav-dropdown{ position: absolute; z-index: -1; max-height: 0px; background: rgba(255,255,255,0.9); min-width: 200px; .transition-300; }
.nav-dropdown li:first-child{ margin-top: 12px; }
.nav-dropdown li{ opacity: 0; .transition-300; margin-right: 0px; float: none; margin-bottom: 18px; }
.nav-dropdown li a{ padding-bottom: 0px; padding-left: 24px; color: @color-heading; }
.nav-dropdown li a:hover{ border-color: rgba(0,0,0,0); }

.has-dropdown:hover .nav-dropdown{ z-index: 10; max-height: 300px; }
.has-dropdown:hover .nav-dropdown li{ opacity: 1; }

.has-dropdown a{ padding-left: 18px; }
.has-dropdown:before{ display: inline-block; font-family: 'Pe-icon-7-stroke'; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; content: "\e688"; color: #fff; font-size: 24px; position: absolute; top: -6px; }

.menu .social-link{ font-size: 14px; top: 0px !important; margin-right: 18px !important; }
.menu .social-link:nth-last-child(2){ margin-right: 18px; }

.sticky-nav{ background: rgba(255,255,255,0.9); }
.sticky-nav .menu li a{ color: @color-heading; }
.sticky-nav .bottom-border{ display: none; }
.sticky-nav .menu li a:hover{ border-color: rgba(0,0,0,0); }
.sticky-nav .sidebar-menu-toggle, .sticky-nav .mobile-menu-toggle{ color: @color-heading; }
.sticky-nav .nav-dropdown{ background: rgba(255,255,255,0.9); }
.sticky-nav .has-dropdown:before{ color: @color-heading; }

.sidebar-menu-toggle, .mobile-menu-toggle{ position: absolute; color: #fff; font-size: 32px; right: 0px; top: -7px; cursor: pointer; .transition-300; }

.mobile-menu-toggle{ display: none; }

.sidebar-menu, .instagram-sidebar{ position: fixed; right: 0px; top: 0px; width: 300px; height: 100%; background: @color-heading; .translate3d(@x: 300px, @y: 0px, @z: 0px); .transition-300; }
.show-sidebar{ .translate3d(@x: 0px, @y: 0px, @z: 0px); }
.reveal-sidebar{ .translate3d(@x: -300px, @y: 0px, @z: 0px); }

.sidebar-content{ padding: 0px 24px; margin-top: 24px; }
.widget{ margin-bottom: 24px; }
.widget .title{ font-size: 16px; font-weight: 600; display: inline-block; margin-bottom: 12px; }
.widget .menu li{ float: none; margin-bottom: 12px; }
.widget .menu li a{ padding-bottom: 0px; color: #fff !important; font-size: 12px; }
.widget .menu li a:hover{ border-color: rgba(0,0,0,0); }
.widget .menu .social-link{ display: none; }
.widget .social-profiles li{ margin-right: 24px; }
.widget .social-profiles li a{ color: #fff; }

.instagram-toggle{ cursor: pointer; }
.instagram-toggle-init{ pointer-events: none; }
.instagram-sidebar li{ width: 100%; height: 250px; }
.instagram-sidebar{ overflow-y: auto; }

.sidebar-content .copy-text{ position: absolute; bottom: 32px; color: rgba(255,255,255,0.5); font-size: 12px; }
.text-panel{ background: lighten(@color-heading, 8%); padding: 18px; }

.relative-nav{ position: relative; padding-top: 28px; background: #fff; }
.relative-nav .menu li a{ color: @color-heading; }
.relative-nav .has-dropdown:before{ color: @color-heading; }
.relative-nav .nav-dropdown{ background: rgba(53,53,53,0.8); }
.relative-nav .has-dropdown li a{ color: #fff; }
.relative-nav .sidebar-menu-toggle{ color: @color-heading; }
.relative-nav .logo-light{ opacity: 0 !important; }
.relative-nav .logo-dark{ opacity: 1 !important; }
.relative-nav .logo{ top: -4px !important; }

.sidebar-menu .logo{ max-width: 110px; position: relative; top: 21px !important; margin-bottom: 32px; left: 24px; }

@media all and(max-width: 768px){
	nav{ max-height: 67px; overflow: hidden; background: rgba(255,255,255,0.9) !important; }
	nav .menu li{ float: none; margin-bottom: 24px; }
	nav .menu li a{ color: @color-heading !important; padding-bottom: 0px; }
	nav .logo{ max-width: 90px; top: -2px; }
	nav .logo-dark{ opacity: 1 !important; }
	nav .logo-light{ opacity: 0 !important; }
	nav .menu{ width: 100%; display: block; margin-top: 67px; margin-right: 0px; }
	nav .social-link{ float: left !important; }
	.sidebar-menu-toggle{ display: none; }
	.mobile-menu-toggle{ display: block; position: fixed; top: 17px; right: 24px; color: @color-heading !important; }
	.open-menu{ max-height: 800px !important; }
	.nav-dropdown{ position: relative; display: none; }
	.has-dropdown:hover .nav-dropdown{ display: block; }
	.has-dropdown:before{ color: @color-heading; }
}

/*!
// 8. Sliders & Dividers & Headers
// --------------------------------------------------*/

.hero-slider{ padding: 0px; position: relative; overflow: hidden; }
.hero-slider .slides li{ height: 780px; position: relative; overflow: hidden; .preserve-3d; }
.hero-slider .slides li:before{ .overlay-params(@strength: 0.4, @bg-color: @color-heading); }

.hero-slider .container{ .vertical-align; z-index: 2;  }
.hero-slider h1{ margin-bottom: 42px; }

.hero-slider .btn-hollow{ color: #fff; border-color: #fff; margin-left: 16px; }
.hero-slider .btn-hollow:hover{ background: #fff; color: @color-primary; }

@media all and(max-width: 767px){
	.hero-slider .btn-hollow{ display: none; }
}

.register-header form.register{ padding-top: 0px; background: rgba(0,0,0,0.4); padding: 24px; }
.register-header form input{ width: 100% !important; }
.register-header form.register span{ color: #fff; }
.register-header .logo, .hero-slide .logo{ max-width: 150px; display: block; margin-bottom: 12px; }

.register-header h1{ margin-bottom: 24px !important; }

@media all and(max-width: 768px){
	.register-header form.register .form-name, .register-header form.register .form-email{ max-width: 100%; width: 100%; }
}

@media all and(min-width: 321px) and(max-width: 767px) and(orientation: landscape){
	.register-header form.register .form-name, .register-header form.register .form-email{ width: 50%; }
}

@media all and(max-width: 767px){
	.hero-slide .logo{ max-width: 100px; }
	.register-header .logo{ display: none; }
	.register-header h1{ display: none; }
	.register-header form h1{ display: block; }
	.register-header span.lead{ display: none; }
	.register-header input, .register-header .select-holder{ max-width: 100% !important; }
	.hero-slider h1{ margin-bottom: 18px; }
}

.testimonials-slider{ position: relative; margin-bottom: 48px; }
.testimonials-slider .flex-control-nav a{ background:rgba(0,0,0,0.3); }
.testimonials-slider .flex-control-nav a.flex-active{ background:rgba(0,0,0,0.8); }
.testimonials-slider .flex-control-nav a:hover{ background: rgba(0,0,0,0.8); }
.testimonials-slider .flex-control-nav{ bottom: -48px; text-align: left; }

.primary-overlay:before{ .overlay-params(@strength: 0.8, @bg-color: @color-primary); background-color: @color-primary !important; }

.strip-divider{ padding: @standard-space*3 0px; position: relative; overflow: hidden; }
.strip-divider .container{ z-index: 2; position: relative; }
.strip-divider h1{ margin: 0px; font-size: 36px; line-height: 48px; }
.strip-divider a:hover{ color: #fff !important; }

@media all and(max-width: 767px){
	.strip-divider{ padding: @standard-space 0px; }
}

.countdown-divider{ padding: @standard-space*2 0px; }
.countdown-divider img, .countdown-header img, .video-header img{ max-width: 300px; display: inline-block; margin-bottom: 12px; }

.countdown-header h1{ margin-bottom: 0px; }
.countdown-header:before{ opacity: 0.8 !important; }

.video-header:before{ opacity: 0.5 !important; background: #000 !important; }
.video-header .uppercase, .countdown-header .uppercase{ display: block; font-weight: 600; margin-bottom: 24px; }

@media all and(max-width: 768px){
	.countdown-header img, .countdown-divider img, .video-header img{ max-width: 150px; }
}

.countdown{ text-align: center; margin-top: @standard-space; }
.countdown-row{ color: #fff; font-size: 80px; font-weight: 300; }
.countdown-section{ width: 20%; display: inline-block; }
.countdown-amount{ display: inline-block; margin-bottom: 48px; }
.countdown-period{ display: block; font-size: 24px; }

.section-header{ position: relative; overflow: hidden; height: 450px; }
.section-header h1{ font-size: 32px; }
.section-header.overlay:before{ opacity: 0.2; }
.section-header i{ font-size: 40px; color: #fff; margin: 0px 24px 12px 0px; }
.section-header i:last-of-type{ margin-right: 0px; }

@media all and(max-width: 767px){
	.countdown{ margin-top: 48px; }
	.countdown-row{ font-size: 36px; }
	.countdown-period{ font-size: 16px; }
}

.video-wrapper{ position: absolute; width: 100%; height: 100%; top: 0px; left: 0px; z-index: 0; }
.video-wrapper video{ width: 100%; }

@media all and(max-width: 1390px){
	.video-wrapper video{ width: 110%; }
}

@media all and(max-width: 1260px){
	.video-wrapper video{ width: 120%; }
}

@media all and(max-width: 1160px){
	.video-wrapper video{ width: 130%; }
}

@media all and(max-width: 1024px){
	.video-wrapper{ display: none; }
}

.call-to-action{ padding: 144px 0px; }
.call-to-action .uppercase{ display: block; width: 100%; text-align: center; margin-bottom: 32px; }
.call-to-action h1{ margin-bottom: 32px; }
.call-to-action .btn{ margin-bottom: 40px; }
.call-to-action a i{ display: inline-block; width: 60px; height: 60px; border-radius: 50%; color: #fff; margin-right: 12px; font-size: 24px; line-height: 60px; }
.call-to-action .social_facebook{ background-color: #3b5998; }
.call-to-action .social_twitter{ background-color: #00aced; }
.call-to-action a:last-of-type i{ margin-right: 0px; }

@media all and(max-width: 768px){
	.call-to-action{ padding: @standard-space 0px; }
}

/*!
// 9. Image with text
// --------------------------------------------------*/

.image-with-text{ overflow: hidden; position: relative; height: 600px; }
.image-with-text h1{ margin-bottom: 24px; }

.side-image{ padding: 0px; position: absolute; top: 0px; height: 100%; }

@media all and(max-width: 767px){
	.image-with-text{ height: auto; padding: @standard-space 0px; }
	.image-with-text .vertical-align{ .vertical-align-cancel }
}

/*!
// Promo Blocks
// --------------------------------------------------*/

.color-blocks{ position: relative; overflow: hidden; color: #fff; }
.color-block{ position: absolute; top: 0px; height: 100%; padding: 0px; color: #fff; .transition-300;  }
.color-blocks h1, .color-blocks h2, .color-blocks h3, .color-blocks h4, .color-blocks h5, .color-blocks h6{ color: #fff; }
.color-blocks h1{ margin-bottom: 12px; }
.color-blocks a{ color: #fff; pointer-events: auto; }
.color-blocks a:hover i{ transform: rotateZ(-10deg); }
.color-blocks i, .contained-promo i{ color: @color-primary; font-size: 70px; display: inline-block; border: 2px solid #fff; border-radius: 50%; width: 120px; height: 120px; line-height: 117px; background: #fff; text-align: center; .transition-100; }
.block-left{ background-color: @color-primary; }
.block-right{ background-color: darken(@color-primary, 8%); right: 0px; }

@media all and(max-width: 768px){
	.block-content{ margin-bottom: @standard-space*2; overflow: hidden; display: block; }
	.block-content:last-of-type{ margin-bottom: 0px; }
	.color-block{ height: 50%; width: 100%; }
	.block-right{ top: 50%; }
}

@media all and(max-width: 767px){
	.block-content i{ margin-bottom: 30px; }
}

/*!
// 10. Speakers & Topics
// --------------------------------------------------*/

.speakers-row{ padding: 0px 15px; }
.speaker-column{ padding: 0px; }

.speaker{ position: relative; overflow: hidden; }
.speaker,.topic{ margin-bottom: @standard-space/2; }
.speaker .hover-state{ position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2; opacity: 0; background: rgba(0,0,0,0.5); .transition-300; }
.speaker .image-holder{ margin-bottom: 12px; }
.speaker span{ display: block; font-size: 16px; }
.speaker-name{ color: @color-heading; }
.speaker .social-links{ width: 100%; .transition-300; .translate3d(@x: 0px, @y: -200px, @z: 0px); }
.speaker .social-links a{ color: #fff; font-size: 24px; display: inline-block; margin-left: 6px; }
.speaker .social-links a:last-child{ margin-right: 0px; }
.speaker .image-holder:hover .hover-state{ opacity: 1; }
.speaker .image-holder:hover .hover-state .social-links{ .translate3d(@x: 0px, @y: 0px, @z: 0px); }

.speaker-with-bio{ overflow: hidden; margin-bottom: @standard-space/2; }
.speaker-with-bio .speaker{ width: 50%; float: left; margin-bottom: 0px; }
.speaker-with-bio .speaker-description{ width: 50%; float: left; padding-left: 30px; }
.speaker-description span{ display: inline-block; margin-bottom: 18px; font-weight: 600; }

@media all and(max-width: 767px){
	.speaker-with-bio .speaker{ width: 100%; }
	.speaker-with-bio .speaker-description{ width: 100%; padding-left: 0px; }
}

.topics{ position: relative; overflow: hidden; }
.topics .container{ position: relative; z-index: 2; }
.topics.overlay .ruled-list li{ border-color: rgba(255,255,255,0.5); }
.topics.overlay .topic i{ color: #fff; }

.topic h3{ margin-bottom: 18px; }
.topic p.lead{ margin-bottom: 32px; }
.topic i{ font-size: 60px; color: @color-primary; display: inline-block; margin-bottom: 32px; }

@media all and(max-width: 767px){
	.topic h3{ display: inline-block; position: relative; bottom: 18px; left: 12px; }
	.topic i{ margin-bottom: 12px; }
}

.ruled-list li{ border-top: 1px dotted rgba(0,0,0,0.3); padding: 12px 0px; font-size: 16px; }

@media all and(min-width: 321px) and(max-width: 767px) and(orientation: landscape){
	.speakers-row .col-sm-6{ width: 50%; float: left !important; }
}

/*!
// 11. Schedule
// --------------------------------------------------*/

.inline-video{ background: @color-muted; }
.inline-video iframe{ width: 100%; height: 300px; border: none; }
.inline-video .btn{ min-width: 150px; margin-top: 32px; margin-right: 16px; }

@media all and(max-width: 768px){
	.inline-video iframe{ height: 350px; margin-top: 42px; }
}

@media all and(max-width: 767px){
	.inline-video iframe{ height: 200px; margin-top: 30px; }
	.inline-video .btn{ margin-top: 18px; }
}

@media all and(min-width: 321px) and(max-width: 767px) and(orientation: landscape){
	.inline-video iframe{ height: 250px; }
}

.embedded-video-holder p{ display: none; }

.schedule-overview{ border: 2px solid rgba(0,0,0,0.2); margin-bottom: @standard-space/2; }
.schedule-overview li{ padding: 24px; position: relative; cursor: pointer; .transition-300; }
.schedule-overview li:first-child .top{ display: none; }
.schedule-overview li:last-child .bottom{ display: none; }

.schedule-title span{ display: block; font-size: 16px; }
.schedule-title .title{ color: @color-heading; }

.schedule-text{ max-height: 0px; .transition-300; opacity: 0; }

.schedule-overview li:hover{ background-color: @color-muted; }
.schedule-overview li:hover .schedule-text{ max-height: 300px; opacity: 1; padding-top: 18px; }
.schedule-overview li:hover .top,.schedule-overview li:hover .bottom,.schedule-overview li:hover .middle{ border-color: rgba(0,0,0,0.4); }
.schedule-overview li:hover .middle{ background: @color-heading; }

.schedule-with-text .btn, .contained-gallery .btn{ margin-top: 24px; margin-right: 12px; }
.schedule-with-text .schedule-overview li{ padding-right: 48px; }

@media all and(max-width: 1024px){
	.schedule-overview li{ padding-right: 48px; }
}

@media all and(max-width: 767px){
	.schedule-with-text .btn, .contained-gallery .btn{ margin-bottom: 32px; }
}

.marker-pin{ position: absolute; right: 32px; top: 0px; height: 100%; }
.marker-pin .top, .marker-pin .bottom{ height: 50%; width: 2px; border-left: 2px solid rgba(0,0,0,0.2); position: absolute; z-index: 1; .transition-300;  }
.marker-pin .top{ top: 0px; }
.marker-pin .bottom{ bottom: 0px; }
.marker-pin .middle{ width: 18px; height: 18px; border: 2px solid rgba(0,0,0,0.2); background: #fff; border-radius: 50%; position: absolute; right: -10px; top: 50%; margin-top: -9px; z-index: 2; .transition-300; }

/*!
// 12. Galleries
// --------------------------------------------------*/

.instagram, .lightbox-gallery{ position: relative; padding: @standard-space*3 0px; }
.gallery-header{  }
.gallery-header .logo{ max-width: 400px; display: block; margin: 0px auto; margin-bottom: 12px;  }

@media screen and(max-width: 768px){
	.gallery-header .logo{ max-width: 200px; }
	.gallery-header h1{ font-size: 24px !important; line-height: 32px !important; }
}

.instagram, .lightbox-gallery{ overflow: hidden; background: #000 !important; }
.instagram ul, .lightbox-gallery ul{ overflow: hidden; position: absolute; width: 100%; height: 100%; top: 0px; }
.instagram li, .lightbox-gallery li{ float: left; width: 20%; height: 50%; position: relative; cursor: pointer; .transition-300; overflow: hidden; background-size: cover !important; opacity: 0.5; }
.instagram li:hover, .lightbox-gallery li:hover{ opacity: 1 !important; }

.instagram .container, .lightbox-gallery .container{ position: relative; z-index: 3; }
.instagram i, .lightbox-gallery i{ font-size: 48px; display: inline-block; margin-bottom: 16px; }
.instagram h1, .lightbox-gallery h1{ .large-h1; margin-bottom: 16px; }

@media all and(max-width: 1200px){
	.instagram li:nth-child(n+9), .lightbox-gallery li:nth-child(n+9){ display: none; }
	.instagram li, .lightbox-gallery li{ width: 25%; }
}

@media all and(max-width: 900px){
	.instagram li:nth-child(n+7), .lightbox-gallery li:nth-child(n+7){ display: none; }
	.instagram li, .lightbox-gallery li{ width: 33.333333%; }
}

@media all and(max-width: 767px){
	.instagram, .lightbox-gallery{ padding: @standard-space*2 0px; }
	.instagram li:nth-child(n+5), .lightbox-gallery li:nth-child(n+5){ display: none; }
	.instagram li, .lightbox-gallery li{ width: 50%; }
}

.testimonials{ background: @color-muted; }

.contained-gallery .instagram, .contained-gallery .lightbox-gallery{ padding: 185px 0px; }
.contained-gallery .instagram li:nth-child(n+9),.contained-gallery .lightbox-gallery li:nth-child(n+9){ display: none; }
.contained-gallery .instagram li, .contained-gallery .lightbox-gallery li{ width: 25%; opacity: 0.7; }

@media all and(max-width: 1024px){
	.contained-gallery .instagram li:nth-child(n+7){ display: none; }
	.contained-gallery .lightbox-gallery li:nth-child(n+7){ display: none; }
	.contained-gallery .instagram li, .contained-gallery .lightbox-gallery li{ width: 33.33333%; }
	.contained-gallery .instagram, .contained-gallery .lightbox-gallery{ padding: 200px 0px; }
}

@media all and(max-width: 768px){
	.contained-gallery .instagram, .contained-gallery .lightbox-gallery{ margin-bottom: 32px; }
	.contained-gallery .btn{ margin-bottom: 0px; }
	.contained-gallery .instagram li:nth-child(n+5), .contained-gallery .lightbox-gallery li:nth-child(n+5){ display: block !important; }
	.contained-gallery .instagram li:nth-child(n+7), .contained-gallery .lightbox-gallery li:nth-child(n+7){ display: none !important; }
	.contained-gallery .instagram li, .contained-gallery .lightbox-gallery li{ width: 33.33333% !important; }
}

/*!
// 13. Pricing
// --------------------------------------------------*/

.pricing-option{ overflow: hidden; background: @color-muted; .preserve-3d; position: relative; padding: @standard-space 0px; margin-bottom: 30px; .transition-300; }
.pricing-option .dot{ position: absolute; top: 24px; right: 24px; width: 24px; height: 24px; border-radius: 50%; background: #fff; }
.pricing-option:hover{ background: darken(@color-muted, 3%); }

@media all and(min-width: 321px) and(max-width: 767px) and(orientation: landscape){
	.pricing-options .col-sm-6{ width: 50%; float: left; }
}

.dollar, .price, .type{ font-weight: 600; color: @color-heading; font-size: 72px; }
.dollar{ font-size: 36px; position: relative; bottom: 22px; }
.price{ line-height: 1; }
.type{ display: block; font-size: 14px; text-transform: uppercase; letter-spacing: 1px; margin-top: 12px; }

.plan-title{ display: block; font-weight: 600; margin-bottom: 12px; font-size: 18px; color: @color-heading; }

.pricing-option ul li{ color: @color-body; }

.pricing-option.emphasis{ background: @color-primary; color: #fff; }
.pricing-option.emphasis .type, .pricing-option.emphasis .dollar, .pricing-option.emphasis .price, .pricing-option.emphasis .plan-title, .pricing-option.emphasis ul li{ color: #fff !important; }

@media all and(max-width: 991px){
	.type{ margin-bottom: 12px; }
	.pricing-option{ text-align: center !important; }
}

/*!
// Frequently Asked Questions
// --------------------------------------------------*/

.faq-item{ margin-bottom: @standard-space/2; }

p.question{ font-weight: 600; color: @color-heading; font-size: 16px; }

/*!
// Visitor Info
// --------------------------------------------------*/

.info-box{ margin-bottom: @standard-space/2; position: relative; overflow: hidden; }
.info-box img{ display: block; margin-bottom: 12px; }
.info-box h3{ margin-bottom: 12px; }
.info-box .text-link{ position: absolute; bottom: 12px; right: 0px; }
.text-link a{ display: inline-block; margin-left: 12px; }

@media all and(min-width: 321px) and(max-width: 767px) and(orientation: landscape){
	.visitor-info .col-sm-4{ width: 50%; float: left; }
}

/*!
// 14. Subscribe
// --------------------------------------------------*/

.subscribe-1{ position: relative; overflow: hidden; padding-top: @standard-space*2; padding-bottom: @standard-space/2; }
.subscribe-1:before{ .overlay-params(@strength: 0.4, @bg-color: @color-heading); }
.subscribe-1 .container{ position: relative; z-index: 2; }
.subscribe-1 .email-subscribe{ margin-bottom: @standard-space*3; }
.subscribe-1 footer{ border-top: 2px solid rgba(255,255,255,0.3); padding-top: @standard-space/2; }
.subscribe-1 .twitter-feed{ margin-bottom: @standard-space; }
.subscribe-1 h1{ margin-bottom: 30px; }

.email-subscribe span{ display: block; margin-top: 12px; }

.twitter-feed i{ font-size: 48px; display: inline-block; margin-bottom: 32px; }
.twitter-feed span a{ border-bottom: none; }

.tweets-feed .user{ display: none; }
.tweets-feed .interact{ display: none; }
.tweets-feed .tweet{ color: #fff; font-size: 30px; line-height: 36px; font-family: @custom-heading-font,"Helvetica Neue", Helvetica, Arial, sans-serif; font-weight: 300;  }
.tweets-feed .tweet a{ color: #fff !important; border-color: #fff !important; }
.tweets-feed .timePosted{ display: none; }

@media all and(max-width: 767px){
	.tweets-feed .tweet{ font-size: 20px; line-height: 26px; }
	.subscribe-2 .form-email{ margin-bottom: 24px; }
}

/*!
// 15. Contact
// --------------------------------------------------*/

.contact-tweets{ background: @color-primary; color: #fff; position: relative; overflow: hidden; height: 600px; .preserve-3d; }
.contact-tweets .social_twitter{ font-size: 42px; margin-bottom: 32px; display: inline-block; }
.contact-tweets .map-holder{ position: absolute; height: 100%; padding: 0px; top: 0px; right: 0px; }
.contact-tweets .timePosted{ display: block !important; }
.map-holder:before{ content: ''; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 2; opacity: 0; }
.map-holder iframe{ border: 0px; position: absolute; width: 100%; height: 100%; }
.contact-tweets span a{ border-bottom: 2px solid #fff; padding-bottom: 1px; }

.contact-tweets form{ padding-top: 0px !important; }
.contact-tweets form .btn{ background: #fff; color: @color-primary; }
.contact-tweets form ::-webkit-input-placeholder { color: rgba(255,255,255,0.9); }
.contact-tweets form :-moz-placeholder { color: rgba(255,255,255,0.9); }
.contact-tweets form ::-moz-placeholder { color: rgba(255,255,255,0.9); }
.contact-tweets form :-ms-input-placeholder  { color: rgba(255,255,255,0.9); }
.contact-tweets .icon{ font-size: 60px; margin-bottom: 12px;  }
.contact-tweets .form-message{ max-width: 95.5%; width: 95.5%; }

.fullwidth-map{ padding: 0px; position: relative; overflow: hidden; }
.fullwidth-map .map-holder{ width: 100%; height: 400px; overflow: hidden; }
.fullwidth-map.screen:before{ content: ''; position: absolute; width: 100%; height: 100%; z-index: 2; }

/*!
// Sponsors
// --------------------------------------------------*/

.sponsors{ background: @color-muted; }
.sponsor{ margin-bottom: @standard-space/2; height: 80px; line-height: 80px; }
.sponsor img{ max-width: 150px; .transition-300; max-height: 80px; }

.sponsors span{ display: inline-block; margin-top: 24px; }
.sponsors span a{ color: @color-primary; border-color: @color-primary; }

@media all and(min-width: 321px) and(max-width: 767px) and(orientation: landscape){
	.sponsors .col-sm-6{ width: 50%; float: left; }
}

/*!
// 16. Forms
// --------------------------------------------------*/

form.register{ overflow: hidden; padding-top: 24px; display: block; }
form.register div{ padding: 0px; }
input[type="text"], form.register .select-holder{ margin-bottom: 32px; padding: 12px; border: none; background: rgba(255,255,255,0.1); border-radius: 25px; font-size: 14px; max-width: 90%; color: #fff; padding-left: 24px; .transition-300; }
input[type="text"]:focus, form.register .select-holder:focus,input[type="text"]:hover, form.register .select-holder:hover{ outline: none; background: rgba(255,255,255,0.2); }

form.register select{ width: 90%; margin: 0px; background: none; border: none; cursor: pointer; }
form.register select:focus{ outline: none; }

form.register input[type="submit"]{ padding-bottom: 12px; width: 90%; margin-bottom: 12px; }

input[type="submit"]{ font-weight: normal; }

.email-subscribe{ overflow: hidden; }
.email-subscribe input{ margin: 0px auto; min-width: 100%; max-width: 100%; }
.email-subscribe input[type="text"]{ background: rgba(255,255,255,0.3); }
.email-subscribe input[type="text"]:hover, .email-subscribe input[type="text"]:focus{ background: rgba(255,255,255,0.4); }
.email-subscribe ::-webkit-input-placeholder { color: rgba(255,255,255,0.9); }
.email-subscribe :-moz-placeholder { color: rgba(255,255,255,0.9); }
.email-subscribe ::-moz-placeholder { color: rgba(255,255,255,0.9); }
.email-subscribe :-ms-input-placeholder  { color: rgba(255,255,255,0.9); }
.email-subscribe input[type="submit"]{ min-height: 48px; }

.subscribe-2 .email-subscribe input[type="text"]{ background: rgba(0,0,0,0.2); }
.subscribe-2 i{ color: @color-primary; font-size: 70px; display: inline-block; margin-right: 24px; margin-bottom: 18px; }
.subscribe-2 i:last-of-type{ margin-right: 0px; }

input.error{ color: #ff4532; }

.mail-list-form{ width: 0px; height: 0px; opacity: 0; overflow: hidden; }

.form-success, .form-error{ display: none; width: 100%; padding: 6px 18px 8px 18px !important; margin-top: 12px; color: #fff; background-color: #55c950; border-radius: 20px;  }
.form-error{ background-color: #D74B4B; }
form .field-error{ background: #D74B4B !important;  }

@media all and(max-width: 768px){

}

@media all and(max-width: 767px){
	form.register input, form.register .select-holder{ width: 100% !important; max-width: 100%; }
	.subscribe-1 .email-subscribe input[type="text"]{ margin-bottom: 24px; }
}

@media all and(min-width: 321px) and(max-width: 767px) and(orientation: landscape){
	form.register .col-sm-6{ width: 50%; float: left; }
	form.register input, form.register .select-holder{ max-width: 95% !important; }
	form.register input[type="submit"]{ max-width: 100% !important; }
}

/*!
// Utility Pages
// --------------------------------------------------*/

.error-page{ background: @color-primary; padding: 0px; }
.error-page h1{ font-size: 84px; line-height: 96px; margin-bottom: 0px; margin-bottom: 12px; }
.error-page p{ font-size: 24px; line-height: 32px; }
.error-page i{ color: #fff; font-size: 84px; display: inline-block; margin-right: 24px; }
.error-page i:last-of-type{ margin-right: 0px; }
.error-page .btn{ margin-right: 24px; margin-top: 12px; }

@media all and(max-width: 767px){
	.error-page i{ display: none; }
}

/*!
// 17. Footers
// --------------------------------------------------*/

.footer .top-border{ height: 2px; width: 100%; background: rgba(255,255,255,0.3); margin-bottom: 32px; }
.footer .menu{ overflow: visible; }
.footer .menu li{ top: 0px; }
.footer .menu li a{ padding-bottom: 0px; }
.footer .menu li .btn{ min-width: 0px; padding: 10px 18px; font-size: 14px; }
.footer .menu li a{ diplay: inline-block; position: relative; border: none; }
.footer .menu li a:hover{ border: none; }
.footer .back-to-top{ padding-right: 42px; }
.footer .menu li a i{ font-size: 36px; position: absolute; right: 0px; top: -12px; }

@media all and(max-width: 767px){
	.footer .text-right{ text-align: left !important; }
	.footer .menu{ margin-top: 24px; }
	.footer .menu li{ float: none; margin-bottom: 12px; }
}

footer.classic{ padding: @standard-space 0px @standard-space/2 0px; background: @color-muted; }
footer.classic .menu li{ float: none; margin-bottom: 12px; }
footer.classic .menu li a{ color: @color-heading; padding-bottom: 0px; font-weight: 600; }
footer.classic span.lead{ display: inline-block; margin-bottom: 12px; }

footer.short{ background: @color-heading; color: #fff; padding: @standard-space 0px; }
footer.short .top-border{ height: 1px !important; }

@media all and(max-width: 767px){
	footer.classic div{ margin-bottom: 18px; }
}

.contact-methods li{ margin-bottom: 12px; }
.contact-methods li:last-child{ margin-bottom: 0px; }
.contact-methods i{ font-size: 36px; color: @color-heading; }
.contact-methods span{ display: inline-block; position: relative; bottom: 10px; left:8px; font-size: 16px; }

footer.classic .social-profiles{ margin-top: 36px; }

.social-profiles{ display: inline-block; overflow: hidden; }
.social-profiles li{ float: left; margin-right: 36px; }
.social-profiles li:last-child{ margin-right: 0px; }
.social-profiles li a{ color: @color-heading; font-size: 20px; }


// *** WARNING: this file was generated by the Pulumi Terraform Bridge (tfgen) Tool. ***
// *** Do not edit by hand unless you're certain you know what you are doing! ***

using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Threading.Tasks;
using Pulumi.Serialization;

namespace Pulumi.Aws.WafV2.Inputs
{

    public sealed class WebAclRuleStatementAndStatementStatementAndStatementStatementGeoMatchStatementForwardedIpConfigGetArgs : Pulumi.ResourceArgs
    {
        /// <summary>
        /// - The match status to assign to the web request if the request doesn't have a valid IP address in the specified position. Valid values include: `MATCH` or `NO_MATCH`.
        /// </summary>
        [Input("fallbackBehavior", required: true)]
        public Input<string> FallbackBehavior { get; set; } = null!;

        /// <summary>
        /// - The name of the HTTP header to use for the IP address.
        /// </summary>
        [Input("headerName", required: true)]
        public Input<string> HeaderName { get; set; } = null!;

        public WebAclRuleStatementAndStatementStatementAndStatementStatementGeoMatchStatementForwardedIpConfigGetArgs()
        {
        }
    }
}


接口格式
========

```js
// 所有接口返回的数据请遵守下面的格式！
var resData = {
    iserro: 0,
    msg: '',
    data: ''
}
```


<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
  <!ENTITY version SYSTEM "version.xml">
]>
<sect1 id="glyph-information">
  <title>Glyph information</title>
  <sect2 id="names-and-numbers">
    <title>Names and numbers</title>
    <para>
    </para>
  </sect2>
</sect1>


/* Test of u16_v[a]s[n]printf() function.
   Copyright (C) 2007, 2009-2020 Free Software Foundation, Inc.

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */

/* Written by Bruno Haible <bruno@clisp.org>, 2007.  */

static void
test_xfunction (uint16_t * (*my_xasprintf) (const char *, ...))
{
  /* Test support of size specifiers as in C99.  */

  {
    uint16_t *result =
      my_xasprintf ("%ju %d", (uintmax_t) 12345671, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '3', '4', '5', '6', '7', '1', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  {
    uint16_t *result =
      my_xasprintf ("%zu %d", (size_t) 12345672, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '3', '4', '5', '6', '7', '2', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  {
    uint16_t *result =
      my_xasprintf ("%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '3', '4', '5', '6', '7', '3', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  {
    uint16_t *result =
      my_xasprintf ("%Lg %d", (long double) 1.5, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '.', '5', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  /* Test the support of the 'U' conversion specifier for Unicode strings.  */

  {
    static const uint8_t unicode_string[] = "Hello";
    {
      uint16_t *result =
        my_xasprintf ("%U %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* Width.  */
      uint16_t *result =
        my_xasprintf ("%10U %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { ' ', ' ', ' ', ' ', ' ', 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* FLAG_LEFT.  */
      uint16_t *result =
        my_xasprintf ("%-10U %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { 'H', 'e', 'l', 'l', 'o', ' ', ' ', ' ', ' ', ' ', ' ', '3', '3', 0 };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* FLAG_ZERO: no effect.  */
      uint16_t *result =
        my_xasprintf ("%010U %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { ' ', ' ', ' ', ' ', ' ', 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
  }

  {
    static const uint16_t unicode_string[] = { 'H', 'e', 'l', 'l', 'o', 0 };
    {
      uint16_t *result =
        my_xasprintf ("%lU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* Width.  */
      uint16_t *result =
        my_xasprintf ("%10lU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { ' ', ' ', ' ', ' ', ' ', 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* FLAG_LEFT.  */
      uint16_t *result =
        my_xasprintf ("%-10lU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { 'H', 'e', 'l', 'l', 'o', ' ', ' ', ' ', ' ', ' ', ' ', '3', '3', 0 };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* FLAG_ZERO: no effect.  */
      uint16_t *result =
        my_xasprintf ("%010lU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { ' ', ' ', ' ', ' ', ' ', 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
  }

  {
    static const uint32_t unicode_string[] = { 'H', 'e', 'l', 'l', 'o', 0 };
    {
      uint16_t *result =
        my_xasprintf ("%llU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* Width.  */
      uint16_t *result =
        my_xasprintf ("%10llU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { ' ', ' ', ' ', ' ', ' ', 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* FLAG_LEFT.  */
      uint16_t *result =
        my_xasprintf ("%-10llU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { 'H', 'e', 'l', 'l', 'o', ' ', ' ', ' ', ' ', ' ', ' ', '3', '3', 0 };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* FLAG_ZERO: no effect.  */
      uint16_t *result =
        my_xasprintf ("%010llU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { ' ', ' ', ' ', ' ', ' ', 'H', 'e', 'l', 'l', 'o', ' ', '3', '3', 0 };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
  }

  /* Test the support of the 's' conversion specifier for strings.  */

  {
    uint16_t *result =
      my_xasprintf ("Mr. %s %d", "Ronald Reagan", 33, 44, 55);
    static const uint16_t expected[] =
      { 'M', 'r', '.', ' ', 'R', 'o', 'n', 'a', 'l', 'd',
        ' ', 'R', 'e', 'a', 'g', 'a', 'n', ' ', '3', '3',
        0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Width.  */
    uint16_t *result =
      my_xasprintf ("Mr. %20s %d", "Ronald Reagan", 33, 44, 55);
    static const uint16_t expected[] =
      { 'M', 'r', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
        ' ', 'R', 'o', 'n', 'a', 'l', 'd', ' ', 'R', 'e',
        'a', 'g', 'a', 'n', ' ', '3', '3', 0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* FLAG_LEFT.  */
    uint16_t *result =
      my_xasprintf ("Mr. %-20s %d", "Ronald Reagan", 33, 44, 55);
    static const uint16_t expected[] =
      { 'M', 'r', '.', ' ', 'R', 'o', 'n', 'a', 'l', 'd',
        ' ', 'R', 'e', 'a', 'g', 'a', 'n', ' ', ' ', ' ',
        ' ', ' ', ' ', ' ', ' ', '3', '3', 0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* FLAG_ZERO: no effect.  */
    uint16_t *result =
      my_xasprintf ("Mr. %020s %d", "Ronald Reagan", 33, 44, 55);
    static const uint16_t expected[] =
      { 'M', 'r', '.', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
        ' ', 'R', 'o', 'n', 'a', 'l', 'd', ' ', 'R', 'e',
        'a', 'g', 'a', 'n', ' ', '3', '3', 0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
     output of floating-point numbers.  */

  { /* A positive number.  */
    uint16_t *result =
      my_xasprintf ("%a %d", 3.1416015625, 33, 44, 55);
    static const uint16_t expected1[] =
      { '0', 'x', '1', '.', '9', '2', '2', 'p', '+', '1', ' ', '3', '3', 0 };
    static const uint16_t expected2[] =
      { '0', 'x', '3', '.', '2', '4', '4', 'p', '+', '0', ' ', '3', '3', 0 };
    static const uint16_t expected3[] =
      { '0', 'x', '6', '.', '4', '8', '8', 'p', '-', '1', ' ', '3', '3', 0 };
    static const uint16_t expected4[] =
      { '0', 'x', 'c', '.', '9', '1', 'p', '-', '2', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected1) == 0
            || u16_strcmp (result, expected2) == 0
            || u16_strcmp (result, expected3) == 0
            || u16_strcmp (result, expected4) == 0);
    free (result);
  }

  { /* Width.  */
    uint16_t *result =
      my_xasprintf ("%10a %d", 1.75, 33, 44, 55);
    static const uint16_t expected1[] =
      { ' ', ' ', '0', 'x', '1', '.', 'c', 'p', '+', '0', ' ', '3', '3', 0 };
    static const uint16_t expected2[] =
      { ' ', ' ', '0', 'x', '3', '.', '8', 'p', '-', '1', ' ', '3', '3', 0 };
    static const uint16_t expected3[] =
      { ' ', ' ', ' ', ' ', '0', 'x', '7', 'p', '-', '2', ' ', '3', '3', 0 };
    static const uint16_t expected4[] =
      { ' ', ' ', ' ', ' ', '0', 'x', 'e', 'p', '-', '3', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected1) == 0
            || u16_strcmp (result, expected2) == 0
            || u16_strcmp (result, expected3) == 0
            || u16_strcmp (result, expected4) == 0);
    free (result);
  }

  { /* Small precision.  */
    uint16_t *result =
      my_xasprintf ("%.10a %d", 1.75, 33, 44, 55);
    static const uint16_t expected1[] =
      { '0', 'x', '1', '.', 'c', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '+', '0', ' ', '3', '3',
        0
      };
    static const uint16_t expected2[] =
      { '0', 'x', '3', '.', '8', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '-', '1', ' ', '3', '3',
        0
      };
    static const uint16_t expected3[] =
      { '0', 'x', '7', '.', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '-', '2', ' ', '3', '3',
        0
      };
    static const uint16_t expected4[] =
      { '0', 'x', 'e', '.', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '-', '3', ' ', '3', '3',
        0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected1) == 0
            || u16_strcmp (result, expected2) == 0
            || u16_strcmp (result, expected3) == 0
            || u16_strcmp (result, expected4) == 0);
    free (result);
  }

  { /* Large precision.  */
    uint16_t *result =
      my_xasprintf ("%.50a %d", 1.75, 33, 44, 55);
    static const uint16_t expected1[] =
      { '0', 'x', '1', '.', 'c', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '+', '0', ' ', '3', '3',
        0
      };
    static const uint16_t expected2[] =
      { '0', 'x', '3', '.', '8', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '-', '1', ' ', '3', '3',
        0
      };
    static const uint16_t expected3[] =
      { '0', 'x', '7', '.', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '-', '2', ' ', '3', '3',
        0
      };
    static const uint16_t expected4[] =
      { '0', 'x', 'e', '.', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '-', '3', ' ', '3', '3',
        0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected1) == 0
            || u16_strcmp (result, expected2) == 0
            || u16_strcmp (result, expected3) == 0
            || u16_strcmp (result, expected4) == 0);
    free (result);
  }

  { /* A positive number.  */
    uint16_t *result =
      my_xasprintf ("%La %d", 3.1416015625L, 33, 44, 55);
    static const uint16_t expected1[] =
      { '0', 'x', '1', '.', '9', '2', '2', 'p', '+', '1',
        ' ', '3', '3', 0
      };
    static const uint16_t expected2[] =
      { '0', 'x', '3', '.', '2', '4', '4', 'p', '+', '0',
        ' ', '3', '3', 0
      };
    static const uint16_t expected3[] =
      { '0', 'x', '6', '.', '4', '8', '8', 'p', '-', '1',
        ' ', '3', '3', 0
      };
    static const uint16_t expected4[] =
      { '0', 'x', 'c', '.', '9', '1', 'p', '-', '2', ' ',
        '3', '3', 0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected1) == 0
            || u16_strcmp (result, expected2) == 0
            || u16_strcmp (result, expected3) == 0
            || u16_strcmp (result, expected4) == 0);
    free (result);
  }

  { /* Width.  */
    uint16_t *result =
      my_xasprintf ("%10La %d", 1.75L, 33, 44, 55);
    static const uint16_t expected1[] =
      { ' ', ' ', '0', 'x', '1', '.', 'c', 'p', '+', '0', ' ', '3', '3', 0 };
    static const uint16_t expected2[] =
      { ' ', ' ', '0', 'x', '3', '.', '8', 'p', '-', '1', ' ', '3', '3', 0 };
    static const uint16_t expected3[] =
      { ' ', ' ', ' ', ' ', '0', 'x', '7', 'p', '-', '2', ' ', '3', '3', 0 };
    static const uint16_t expected4[] =
      { ' ', ' ', ' ', ' ', '0', 'x', 'e', 'p', '-', '3', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected1) == 0
            || u16_strcmp (result, expected2) == 0
            || u16_strcmp (result, expected3) == 0
            || u16_strcmp (result, expected4) == 0);
    free (result);
  }

  { /* Small precision.  */
    uint16_t *result =
      my_xasprintf ("%.10La %d", 1.75L, 33, 44, 55);
    static const uint16_t expected1[] =
      { '0', 'x', '1', '.', 'c', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '+', '0', ' ', '3', '3',
        0
      };
    static const uint16_t expected2[] =
      { '0', 'x', '3', '.', '8', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '-', '1', ' ', '3', '3',
        0
      };
    static const uint16_t expected3[] =
      { '0', 'x', '7', '.', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '-', '2', ' ', '3', '3',
        0
      };
    static const uint16_t expected4[] =
      { '0', 'x', 'e', '.', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '-', '3', ' ', '3', '3',
        0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected1) == 0
            || u16_strcmp (result, expected2) == 0
            || u16_strcmp (result, expected3) == 0
            || u16_strcmp (result, expected4) == 0);
    free (result);
  }

  { /* Large precision.  */
    uint16_t *result =
      my_xasprintf ("%.50La %d", 1.75L, 33, 44, 55);
    static const uint16_t expected1[] =
      { '0', 'x', '1', '.', 'c', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '+', '0', ' ', '3', '3',
        0
      };
    static const uint16_t expected2[] =
      { '0', 'x', '3', '.', '8', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '-', '1', ' ', '3', '3',
        0
      };
    static const uint16_t expected3[] =
      { '0', 'x', '7', '.', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '-', '2', ' ', '3', '3',
        0
      };
    static const uint16_t expected4[] =
      { '0', 'x', 'e', '.', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
        '0', '0', '0', '0', 'p', '-', '3', ' ', '3', '3',
        0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected1) == 0
            || u16_strcmp (result, expected2) == 0
            || u16_strcmp (result, expected3) == 0
            || u16_strcmp (result, expected4) == 0);
    free (result);
  }

  /* Test the support of the %f format directive.  */

  { /* A positive number.  */
    uint16_t *result =
      my_xasprintf ("%f %d", 12.75, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '.', '7', '5', '0', '0', '0', '0', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Width.  */
    uint16_t *result =
      my_xasprintf ("%10f %d", 1.75, 33, 44, 55);
    static const uint16_t expected[] =
      { ' ', ' ', '1', '.', '7', '5', '0', '0', '0', '0', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Precision.  */
    uint16_t *result =
      my_xasprintf ("%.f %d", 1234.0, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '3', '4', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* A positive number.  */
    uint16_t *result =
      my_xasprintf ("%Lf %d", 12.75L, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '.', '7', '5', '0', '0', '0', '0', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Width.  */
    uint16_t *result =
      my_xasprintf ("%10Lf %d", 1.75L, 33, 44, 55);
    static const uint16_t expected[] =
      { ' ', ' ', '1', '.', '7', '5', '0', '0', '0', '0', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Precision.  */
    uint16_t *result =
      my_xasprintf ("%.Lf %d", 1234.0L, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '3', '4', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  /* Test the support of the %F format directive.  */

  { /* A positive number.  */
    uint16_t *result =
      my_xasprintf ("%F %d", 12.75, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '.', '7', '5', '0', '0', '0', '0', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Precision.  */
    uint16_t *result =
      my_xasprintf ("%.F %d", 1234.0, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '3', '4', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* A positive number.  */
    uint16_t *result =
      my_xasprintf ("%LF %d", 12.75L, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '.', '7', '5', '0', '0', '0', '0', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Precision.  */
    uint16_t *result =
      my_xasprintf ("%.LF %d", 1234.0L, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '3', '4', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  /* Test the support of the %e format directive.  */

  { /* A positive number.  */
    uint16_t *result =
      my_xasprintf ("%e %d", 12.75, 33, 44, 55);
    static const uint16_t expected1[] =
      { '1', '.', '2', '7', '5', '0', '0', '0', 'e', '+',
        '0', '1', ' ', '3', '3', 0
      };
    static const uint16_t expected2[] =
      { '1', '.', '2', '7', '5', '0', '0', '0', 'e', '+',
        '0', '0', '1', ' ', '3', '3', 0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected1) == 0
            || u16_strcmp (result, expected2) == 0);
    free (result);
  }

  { /* Width.  */
    uint16_t *result =
      my_xasprintf ("%15e %d", 1.75, 33, 44, 55);
    static const uint16_t expected1[] =
      { ' ', ' ', ' ', '1', '.', '7', '5', '0', '0', '0',
        '0', 'e', '+', '0', '0', ' ', '3', '3', 0
      };
    static const uint16_t expected2[] =
      { ' ', ' ', '1', '.', '7', '5', '0', '0', '0', '0',
        'e', '+', '0', '0', '0', ' ', '3', '3', 0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected1) == 0
            || u16_strcmp (result, expected2) == 0);
    free (result);
  }

  { /* Precision.  */
    uint16_t *result =
      my_xasprintf ("%.e %d", 1234.0, 33, 44, 55);
    static const uint16_t expected1[] =
      { '1', 'e', '+', '0', '3', ' ', '3', '3', 0 };
    static const uint16_t expected2[] =
      { '1', 'e', '+', '0', '0', '3', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected1) == 0
            || u16_strcmp (result, expected2) == 0);
    free (result);
  }

  { /* A positive number.  */
    uint16_t *result =
      my_xasprintf ("%Le %d", 12.75L, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '.', '2', '7', '5', '0', '0', '0', 'e', '+',
        '0', '1', ' ', '3', '3', 0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Width.  */
    uint16_t *result =
      my_xasprintf ("%15Le %d", 1.75L, 33, 44, 55);
    static const uint16_t expected[] =
      { ' ', ' ', ' ', '1', '.', '7', '5', '0', '0', '0',
        '0', 'e', '+', '0', '0', ' ', '3', '3', 0
      };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Precision.  */
    uint16_t *result =
      my_xasprintf ("%.Le %d", 1234.0L, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', 'e', '+', '0', '3', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  /* Test the support of the %g format directive.  */

  { /* A positive number.  */
    uint16_t *result =
      my_xasprintf ("%g %d", 12.75, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '.', '7', '5', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Width.  */
    uint16_t *result =
      my_xasprintf ("%10g %d", 1.75, 33, 44, 55);
    static const uint16_t expected[] =
      { ' ', ' ', ' ', ' ', ' ', ' ', '1', '.', '7', '5', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Precision.  */
    uint16_t *result =
      my_xasprintf ("%.g %d", 1234.0, 33, 44, 55);
    static const uint16_t expected1[] =
      { '1', 'e', '+', '0', '3', ' ', '3', '3', 0 };
    static const uint16_t expected2[] =
      { '1', 'e', '+', '0', '0', '3', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected1) == 0
            || u16_strcmp (result, expected2) == 0);
    free (result);
  }

  { /* A positive number.  */
    uint16_t *result =
      my_xasprintf ("%Lg %d", 12.75L, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '.', '7', '5', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Width.  */
    uint16_t *result =
      my_xasprintf ("%10Lg %d", 1.75L, 33, 44, 55);
    static const uint16_t expected[] =
      { ' ', ' ', ' ', ' ', ' ', ' ', '1', '.', '7', '5', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  { /* Precision.  */
    uint16_t *result =
      my_xasprintf ("%.Lg %d", 1234.0L, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', 'e', '+', '0', '3', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  /* Test the support of the %n format directive.  */

  {
    int count = -1;
    uint16_t *result =
      my_xasprintf ("%d %n", 123, &count, 33, 44, 55);
    static const uint16_t expected[] =
      { '1', '2', '3', ' ', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    ASSERT (count == 4);
    free (result);
  }

  /* Test the support of the POSIX/XSI format strings with positions.  */

  {
    uint16_t *result =
      my_xasprintf ("%2$d %1$d", 33, 55);
    static const uint16_t expected[] =
      { '5', '5', ' ', '3', '3', 0 };
    ASSERT (result != NULL);
    ASSERT (u16_strcmp (result, expected) == 0);
    free (result);
  }

  /* Test the support of the grouping flag.  */

  {
    uint16_t *result =
      my_xasprintf ("%'d %d", 1234567, 99);
    ASSERT (result != NULL);
    ASSERT (result[u16_strlen (result) - 1] == '9');
    free (result);
  }

  /* Test the support of the 'U' conversion specifier for Unicode strings.  */

  {
    static const uint8_t unicode_string[] = "Rafa\305\202 Maszkowski"; /* Rafał Maszkowski */
    {
      uint16_t *result =
        my_xasprintf ("%U %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { 'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z',
          'k', 'o', 'w', 's', 'k', 'i', ' ', '3', '3', 0
        };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* Width.  */
      uint16_t *result =
        my_xasprintf ("%20U %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { ' ', ' ', ' ', ' ', 'R', 'a', 'f', 'a', 0x0142, ' ',
          'M', 'a', 's', 'z', 'k', 'o', 'w', 's', 'k', 'i',
          ' ', '3', '3', 0
        };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* FLAG_LEFT.  */
      uint16_t *result =
        my_xasprintf ("%-20U %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { 'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z',
          'k', 'o', 'w', 's', 'k', 'i', ' ', ' ', ' ', ' ',
          ' ', '3', '3', 0
        };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* FLAG_ZERO: no effect.  */
      uint16_t *result =
        my_xasprintf ("%020U %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { ' ', ' ', ' ', ' ', 'R', 'a', 'f', 'a', 0x0142, ' ',
          'M', 'a', 's', 'z', 'k', 'o', 'w', 's', 'k', 'i',
          ' ', '3', '3', 0
        };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
  }

  {
    static const uint16_t unicode_string[] = /* Rafał Maszkowski */
      {
        'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z', 'k', 'o', 'w',
        's', 'k', 'i', 0
      };
    {
      uint16_t *result =
        my_xasprintf ("%lU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { 'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z',
          'k', 'o', 'w', 's', 'k', 'i', ' ', '3', '3', 0
        };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* Width.  */
      uint16_t *result =
        my_xasprintf ("%20lU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { ' ', ' ', ' ', ' ', 'R', 'a', 'f', 'a', 0x0142, ' ',
          'M', 'a', 's', 'z', 'k', 'o', 'w', 's', 'k', 'i',
          ' ', '3', '3', 0
        };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* FLAG_LEFT.  */
      uint16_t *result =
        my_xasprintf ("%-20lU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { 'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z',
          'k', 'o', 'w', 's', 'k', 'i', ' ', ' ', ' ', ' ',
          ' ', '3', '3', 0
        };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* FLAG_ZERO: no effect.  */
      uint16_t *result =
        my_xasprintf ("%020lU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { ' ', ' ', ' ', ' ', 'R', 'a', 'f', 'a', 0x0142, ' ',
          'M', 'a', 's', 'z', 'k', 'o', 'w', 's', 'k', 'i',
          ' ', '3', '3', 0
        };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
  }

  {
    static const uint32_t unicode_string[] = /* Rafał Maszkowski */
      {
        'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z', 'k', 'o', 'w',
        's', 'k', 'i', 0
      };
    {
      uint16_t *result =
        my_xasprintf ("%llU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { 'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z',
          'k', 'o', 'w', 's', 'k', 'i', ' ', '3', '3', 0
        };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* Width.  */
      uint16_t *result =
        my_xasprintf ("%20llU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { ' ', ' ', ' ', ' ', 'R', 'a', 'f', 'a', 0x0142, ' ',
          'M', 'a', 's', 'z', 'k', 'o', 'w', 's', 'k', 'i',
          ' ', '3', '3', 0
        };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* FLAG_LEFT.  */
      uint16_t *result =
        my_xasprintf ("%-20llU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { 'R', 'a', 'f', 'a', 0x0142, ' ', 'M', 'a', 's', 'z',
          'k', 'o', 'w', 's', 'k', 'i', ' ', ' ', ' ', ' ',
          ' ', '3', '3', 0
        };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
    { /* FLAG_ZERO: no effect.  */
      uint16_t *result =
        my_xasprintf ("%020llU %d", unicode_string, 33, 44, 55);
      static const uint16_t expected[] =
        { ' ', ' ', ' ', ' ', 'R', 'a', 'f', 'a', 0x0142, ' ',
          'M', 'a', 's', 'z', 'k', 'o', 'w', 's', 'k', 'i',
          ' ', '3', '3', 0
        };
      ASSERT (result != NULL);
      ASSERT (u16_strcmp (result, expected) == 0);
      free (result);
    }
  }

  /* Test non-ASCII characters in the format string.  */

  {
    uint16_t *result =
      my_xasprintf ("\304rger", 33, 44, 55);
    ASSERT (result == NULL && errno == EINVAL);
  }
}


/*
 * u_audio.c -- interface to USB gadget "ALSA sound card" utilities
 *
 * Copyright (C) 2016
 * Author: Ruslan Bilovol <ruslan.bilovol@gmail.com>
 *
 * Sound card implementation was cut-and-pasted with changes
 * from f_uac2.c and has:
 *    Copyright (C) 2011
 *    Yadwinder Singh (yadi.brar01@gmail.com)
 *    Jaswinder Singh (jaswinder.singh@linaro.org)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/module.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>

#include "u_audio.h"

#define BUFF_SIZE_MAX	(PAGE_SIZE * 16)
#define PRD_SIZE_MAX	PAGE_SIZE
#define MIN_PERIODS	4

struct uac_req {
	struct uac_rtd_params *pp; /* parent param */
	struct usb_request *req;
};

/* Runtime data params for one stream */
struct uac_rtd_params {
	struct snd_uac_chip *uac; /* parent chip */
	bool ep_enabled; /* if the ep is enabled */
	/* Size of the ring buffer */
	size_t dma_bytes;
	unsigned char *dma_area;

	struct snd_pcm_substream *ss;

	/* Ring buffer */
	ssize_t hw_ptr;

	void *rbuf;

	size_t period_size;

	unsigned max_psize;	/* MaxPacketSize of endpoint */
	struct uac_req *ureq;

	spinlock_t lock;
};

struct snd_uac_chip {
	struct g_audio *audio_dev;

	struct uac_rtd_params p_prm;
	struct uac_rtd_params c_prm;

	struct snd_card *card;
	struct snd_pcm *pcm;

	/* timekeeping for the playback endpoint */
	unsigned int p_interval;
	unsigned int p_residue;

	/* pre-calculated values for playback iso completion */
	unsigned int p_pktsize;
	unsigned int p_pktsize_residue;
	unsigned int p_framesize;
};

static const struct snd_pcm_hardware uac_pcm_hardware = {
	.info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER
		 | SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID
		 | SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME,
	.rates = SNDRV_PCM_RATE_CONTINUOUS,
	.periods_max = BUFF_SIZE_MAX / PRD_SIZE_MAX,
	.buffer_bytes_max = BUFF_SIZE_MAX,
	.period_bytes_max = PRD_SIZE_MAX,
	.periods_min = MIN_PERIODS,
};

static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
{
	unsigned pending;
	unsigned long flags;
	unsigned int hw_ptr;
	bool update_alsa = false;
	int status = req->status;
	struct uac_req *ur = req->context;
	struct snd_pcm_substream *substream;
	struct uac_rtd_params *prm = ur->pp;
	struct snd_uac_chip *uac = prm->uac;

	/* i/f shutting down */
	if (!prm->ep_enabled || req->status == -ESHUTDOWN)
		return;

	/*
	 * We can't really do much about bad xfers.
	 * Afterall, the ISOCH xfers could fail legitimately.
	 */
	if (status)
		pr_debug("%s: iso_complete status(%d) %d/%d\n",
			__func__, status, req->actual, req->length);

	substream = prm->ss;

	/* Do nothing if ALSA isn't active */
	if (!substream)
		goto exit;

	spin_lock_irqsave(&prm->lock, flags);

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		/*
		 * For each IN packet, take the quotient of the current data
		 * rate and the endpoint's interval as the base packet size.
		 * If there is a residue from this division, add it to the
		 * residue accumulator.
		 */
		req->length = uac->p_pktsize;
		uac->p_residue += uac->p_pktsize_residue;

		/*
		 * Whenever there are more bytes in the accumulator than we
		 * need to add one more sample frame, increase this packet's
		 * size and decrease the accumulator.
		 */
		if (uac->p_residue / uac->p_interval >= uac->p_framesize) {
			req->length += uac->p_framesize;
			uac->p_residue -= uac->p_framesize *
					   uac->p_interval;
		}

		req->actual = req->length;
	}

	pending = prm->hw_ptr % prm->period_size;
	pending += req->actual;
	if (pending >= prm->period_size)
		update_alsa = true;

	hw_ptr = prm->hw_ptr;
	prm->hw_ptr = (prm->hw_ptr + req->actual) % prm->dma_bytes;

	spin_unlock_irqrestore(&prm->lock, flags);

	/* Pack USB load in ALSA ring buffer */
	pending = prm->dma_bytes - hw_ptr;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		if (unlikely(pending < req->actual)) {
			memcpy(req->buf, prm->dma_area + hw_ptr, pending);
			memcpy(req->buf + pending, prm->dma_area,
			       req->actual - pending);
		} else {
			memcpy(req->buf, prm->dma_area + hw_ptr, req->actual);
		}
	} else {
		if (unlikely(pending < req->actual)) {
			memcpy(prm->dma_area + hw_ptr, req->buf, pending);
			memcpy(prm->dma_area, req->buf + pending,
			       req->actual - pending);
		} else {
			memcpy(prm->dma_area + hw_ptr, req->buf, req->actual);
		}
	}

exit:
	if (usb_ep_queue(ep, req, GFP_ATOMIC))
		dev_err(uac->card->dev, "%d Error!\n", __LINE__);

	if (update_alsa)
		snd_pcm_period_elapsed(substream);
}

static int uac_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{
	struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
	struct uac_rtd_params *prm;
	struct g_audio *audio_dev;
	struct uac_params *params;
	unsigned long flags;
	int err = 0;

	audio_dev = uac->audio_dev;
	params = &audio_dev->params;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		prm = &uac->p_prm;
	else
		prm = &uac->c_prm;

	spin_lock_irqsave(&prm->lock, flags);

	/* Reset */
	prm->hw_ptr = 0;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
	case SNDRV_PCM_TRIGGER_RESUME:
		prm->ss = substream;
		break;
	case SNDRV_PCM_TRIGGER_STOP:
	case SNDRV_PCM_TRIGGER_SUSPEND:
		prm->ss = NULL;
		break;
	default:
		err = -EINVAL;
	}

	spin_unlock_irqrestore(&prm->lock, flags);

	/* Clear buffer after Play stops */
	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && !prm->ss)
		memset(prm->rbuf, 0, prm->max_psize * params->req_number);

	return err;
}

static snd_pcm_uframes_t uac_pcm_pointer(struct snd_pcm_substream *substream)
{
	struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
	struct uac_rtd_params *prm;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		prm = &uac->p_prm;
	else
		prm = &uac->c_prm;

	return bytes_to_frames(substream->runtime, prm->hw_ptr);
}

static int uac_pcm_hw_params(struct snd_pcm_substream *substream,
			       struct snd_pcm_hw_params *hw_params)
{
	struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
	struct uac_rtd_params *prm;
	int err;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		prm = &uac->p_prm;
	else
		prm = &uac->c_prm;

	err = snd_pcm_lib_malloc_pages(substream,
					params_buffer_bytes(hw_params));
	if (err >= 0) {
		prm->dma_bytes = substream->runtime->dma_bytes;
		prm->dma_area = substream->runtime->dma_area;
		prm->period_size = params_period_bytes(hw_params);
	}

	return err;
}

static int uac_pcm_hw_free(struct snd_pcm_substream *substream)
{
	struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
	struct uac_rtd_params *prm;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
		prm = &uac->p_prm;
	else
		prm = &uac->c_prm;

	prm->dma_area = NULL;
	prm->dma_bytes = 0;
	prm->period_size = 0;

	return snd_pcm_lib_free_pages(substream);
}

static int uac_pcm_open(struct snd_pcm_substream *substream)
{
	struct snd_uac_chip *uac = snd_pcm_substream_chip(substream);
	struct snd_pcm_runtime *runtime = substream->runtime;
	struct g_audio *audio_dev;
	struct uac_params *params;
	int p_ssize, c_ssize;
	int p_srate, c_srate;
	int p_chmask, c_chmask;

	audio_dev = uac->audio_dev;
	params = &audio_dev->params;
	p_ssize = params->p_ssize;
	c_ssize = params->c_ssize;
	p_srate = params->p_srate;
	c_srate = params->c_srate;
	p_chmask = params->p_chmask;
	c_chmask = params->c_chmask;
	uac->p_residue = 0;

	runtime->hw = uac_pcm_hardware;

	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		spin_lock_init(&uac->p_prm.lock);
		runtime->hw.rate_min = p_srate;
		switch (p_ssize) {
		case 3:
			runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE;
			break;
		case 4:
			runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE;
			break;
		default:
			runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
			break;
		}
		runtime->hw.channels_min = num_channels(p_chmask);
		runtime->hw.period_bytes_min = 2 * uac->p_prm.max_psize
						/ runtime->hw.periods_min;
	} else {
		spin_lock_init(&uac->c_prm.lock);
		runtime->hw.rate_min = c_srate;
		switch (c_ssize) {
		case 3:
			runtime->hw.formats = SNDRV_PCM_FMTBIT_S24_3LE;
			break;
		case 4:
			runtime->hw.formats = SNDRV_PCM_FMTBIT_S32_LE;
			break;
		default:
			runtime->hw.formats = SNDRV_PCM_FMTBIT_S16_LE;
			break;
		}
		runtime->hw.channels_min = num_channels(c_chmask);
		runtime->hw.period_bytes_min = 2 * uac->c_prm.max_psize
						/ runtime->hw.periods_min;
	}

	runtime->hw.rate_max = runtime->hw.rate_min;
	runtime->hw.channels_max = runtime->hw.channels_min;

	snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);

	return 0;
}

/* ALSA cries without these function pointers */
static int uac_pcm_null(struct snd_pcm_substream *substream)
{
	return 0;
}

static const struct snd_pcm_ops uac_pcm_ops = {
	.open = uac_pcm_open,
	.close = uac_pcm_null,
	.ioctl = snd_pcm_lib_ioctl,
	.hw_params = uac_pcm_hw_params,
	.hw_free = uac_pcm_hw_free,
	.trigger = uac_pcm_trigger,
	.pointer = uac_pcm_pointer,
	.prepare = uac_pcm_null,
};

static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep)
{
	struct snd_uac_chip *uac = prm->uac;
	struct g_audio *audio_dev;
	struct uac_params *params;
	int i;

	if (!prm->ep_enabled)
		return;

	prm->ep_enabled = false;

	audio_dev = uac->audio_dev;
	params = &audio_dev->params;

	for (i = 0; i < params->req_number; i++) {
		if (prm->ureq[i].req) {
			usb_ep_dequeue(ep, prm->ureq[i].req);
			usb_ep_free_request(ep, prm->ureq[i].req);
			prm->ureq[i].req = NULL;
		}
	}

	if (usb_ep_disable(ep))
		dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__);
}

int u_audio_start_capture(struct g_audio *audio_dev)
{
	struct snd_uac_chip *uac = audio_dev->uac;
	struct usb_gadget *gadget = audio_dev->gadget;
	struct device *dev = &gadget->dev;
	struct usb_request *req;
	struct usb_ep *ep;
	struct uac_rtd_params *prm;
	struct uac_params *params = &audio_dev->params;
	int req_len, i;

	ep = audio_dev->out_ep;
	prm = &uac->c_prm;
	config_ep_by_speed(gadget, &audio_dev->func, ep);
	req_len = prm->max_psize;

	prm->ep_enabled = true;
	usb_ep_enable(ep);

	for (i = 0; i < params->req_number; i++) {
		if (!prm->ureq[i].req) {
			req = usb_ep_alloc_request(ep, GFP_ATOMIC);
			if (req == NULL)
				return -ENOMEM;

			prm->ureq[i].req = req;
			prm->ureq[i].pp = prm;

			req->zero = 0;
			req->context = &prm->ureq[i];
			req->length = req_len;
			req->complete = u_audio_iso_complete;
			req->buf = prm->rbuf + i * prm->max_psize;
		}

		if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC))
			dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
	}

	return 0;
}
EXPORT_SYMBOL_GPL(u_audio_start_capture);

void u_audio_stop_capture(struct g_audio *audio_dev)
{
	struct snd_uac_chip *uac = audio_dev->uac;

	free_ep(&uac->c_prm, audio_dev->out_ep);
}
EXPORT_SYMBOL_GPL(u_audio_stop_capture);

int u_audio_start_playback(struct g_audio *audio_dev)
{
	struct snd_uac_chip *uac = audio_dev->uac;
	struct usb_gadget *gadget = audio_dev->gadget;
	struct device *dev = &gadget->dev;
	struct usb_request *req;
	struct usb_ep *ep;
	struct uac_rtd_params *prm;
	struct uac_params *params = &audio_dev->params;
	unsigned int factor, rate;
	const struct usb_endpoint_descriptor *ep_desc;
	int req_len, i;

	ep = audio_dev->in_ep;
	prm = &uac->p_prm;
	config_ep_by_speed(gadget, &audio_dev->func, ep);

	ep_desc = ep->desc;

	/* pre-calculate the playback endpoint's interval */
	if (gadget->speed == USB_SPEED_FULL)
		factor = 1000;
	else
		factor = 8000;

	/* pre-compute some values for iso_complete() */
	uac->p_framesize = params->p_ssize *
			    num_channels(params->p_chmask);
	rate = params->p_srate * uac->p_framesize;
	uac->p_interval = factor / (1 << (ep_desc->bInterval - 1));
	uac->p_pktsize = min_t(unsigned int, rate / uac->p_interval,
				prm->max_psize);

	if (uac->p_pktsize < prm->max_psize)
		uac->p_pktsize_residue = rate % uac->p_interval;
	else
		uac->p_pktsize_residue = 0;

	req_len = uac->p_pktsize;
	uac->p_residue = 0;

	prm->ep_enabled = true;
	usb_ep_enable(ep);

	for (i = 0; i < params->req_number; i++) {
		if (!prm->ureq[i].req) {
			req = usb_ep_alloc_request(ep, GFP_ATOMIC);
			if (req == NULL)
				return -ENOMEM;

			prm->ureq[i].req = req;
			prm->ureq[i].pp = prm;

			req->zero = 0;
			req->context = &prm->ureq[i];
			req->length = req_len;
			req->complete = u_audio_iso_complete;
			req->buf = prm->rbuf + i * prm->max_psize;
		}

		if (usb_ep_queue(ep, prm->ureq[i].req, GFP_ATOMIC))
			dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
	}

	return 0;
}
EXPORT_SYMBOL_GPL(u_audio_start_playback);

void u_audio_stop_playback(struct g_audio *audio_dev)
{
	struct snd_uac_chip *uac = audio_dev->uac;

	free_ep(&uac->p_prm, audio_dev->in_ep);
}
EXPORT_SYMBOL_GPL(u_audio_stop_playback);

int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
					const char *card_name)
{
	struct snd_uac_chip *uac;
	struct snd_card *card;
	struct snd_pcm *pcm;
	struct uac_params *params;
	int p_chmask, c_chmask;
	int err;

	if (!g_audio)
		return -EINVAL;

	uac = kzalloc(sizeof(*uac), GFP_KERNEL);
	if (!uac)
		return -ENOMEM;
	g_audio->uac = uac;
	uac->audio_dev = g_audio;

	params = &g_audio->params;
	p_chmask = params->p_chmask;
	c_chmask = params->c_chmask;

	if (c_chmask) {
		struct uac_rtd_params *prm = &uac->c_prm;

		uac->c_prm.uac = uac;
		prm->max_psize = g_audio->out_ep_maxpsize;

		prm->ureq = kcalloc(params->req_number, sizeof(struct uac_req),
				GFP_KERNEL);
		if (!prm->ureq) {
			err = -ENOMEM;
			goto fail;
		}

		prm->rbuf = kcalloc(params->req_number, prm->max_psize,
				GFP_KERNEL);
		if (!prm->rbuf) {
			prm->max_psize = 0;
			err = -ENOMEM;
			goto fail;
		}
	}

	if (p_chmask) {
		struct uac_rtd_params *prm = &uac->p_prm;

		uac->p_prm.uac = uac;
		prm->max_psize = g_audio->in_ep_maxpsize;

		prm->ureq = kcalloc(params->req_number, sizeof(struct uac_req),
				GFP_KERNEL);
		if (!prm->ureq) {
			err = -ENOMEM;
			goto fail;
		}

		prm->rbuf = kcalloc(params->req_number, prm->max_psize,
				GFP_KERNEL);
		if (!prm->rbuf) {
			prm->max_psize = 0;
			err = -ENOMEM;
			goto fail;
		}
	}

	/* Choose any slot, with no id */
	err = snd_card_new(&g_audio->gadget->dev,
			-1, NULL, THIS_MODULE, 0, &card);
	if (err < 0)
		goto fail;

	uac->card = card;

	/*
	 * Create first PCM device
	 * Create a substream only for non-zero channel streams
	 */
	err = snd_pcm_new(uac->card, pcm_name, 0,
			       p_chmask ? 1 : 0, c_chmask ? 1 : 0, &pcm);
	if (err < 0)
		goto snd_fail;

	strcpy(pcm->name, pcm_name);
	pcm->private_data = uac;
	uac->pcm = pcm;

	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &uac_pcm_ops);
	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &uac_pcm_ops);

	strcpy(card->driver, card_name);
	strcpy(card->shortname, card_name);
	sprintf(card->longname, "%s %i", card_name, card->dev->id);

	snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
		snd_dma_continuous_data(GFP_KERNEL), 0, BUFF_SIZE_MAX);

	err = snd_card_register(card);

	if (!err)
		return 0;

snd_fail:
	snd_card_free(card);
fail:
	kfree(uac->p_prm.ureq);
	kfree(uac->c_prm.ureq);
	kfree(uac->p_prm.rbuf);
	kfree(uac->c_prm.rbuf);
	kfree(uac);

	return err;
}
EXPORT_SYMBOL_GPL(g_audio_setup);

void g_audio_cleanup(struct g_audio *g_audio)
{
	struct snd_uac_chip *uac;
	struct snd_card *card;

	if (!g_audio || !g_audio->uac)
		return;

	uac = g_audio->uac;
	card = uac->card;
	if (card)
		snd_card_free(card);

	kfree(uac->p_prm.ureq);
	kfree(uac->c_prm.ureq);
	kfree(uac->p_prm.rbuf);
	kfree(uac->c_prm.rbuf);
	kfree(uac);
}
EXPORT_SYMBOL_GPL(g_audio_cleanup);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("USB gadget \"ALSA sound card\" utilities");
MODULE_AUTHOR("Ruslan Bilovol");


320,105,592,105,592,269,320,269,0.9998086
784,583,911,583,911,598,784,598,0.99980634
0,582,224,582,224,598,0,598,0.999803
160,327,752,327,752,496,160,496,0.9998011
384,272,496,272,496,345,384,345,0.9997842


ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"], function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

var DocCommentHighlightRules = function() {
    this.$rules = {
        "start" : [ {
            token : "comment.doc.tag",
            regex : "@[\\w\\d_]+" // TODO: fix email addresses
        },
        DocCommentHighlightRules.getTagRule(),
        {
            defaultToken : "comment.doc",
            caseInsensitive: true
        }]
    };
};

oop.inherits(DocCommentHighlightRules, TextHighlightRules);

DocCommentHighlightRules.getTagRule = function(start) {
    return {
        token : "comment.doc.tag.storage.type",
        regex : "\\b(?:TODO|FIXME|XXX|HACK)\\b"
    };
}

DocCommentHighlightRules.getStartRule = function(start) {
    return {
        token : "comment.doc", // doc comment
        regex : "\\/\\*(?=\\*)",
        next  : start
    };
};

DocCommentHighlightRules.getEndRule = function (start) {
    return {
        token : "comment.doc", // closing comment
        regex : "\\*\\/",
        next  : start
    };
};

exports.DocCommentHighlightRules = DocCommentHighlightRules;

});

ace.define("ace/mode/lean_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/doc_comment_highlight_rules","ace/mode/text_highlight_rules"], function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var DocCommentHighlightRules = require("./doc_comment_highlight_rules").DocCommentHighlightRules;
var TextHighlightRules = require("./text_highlight_rules").TextHighlightRules;

var leanHighlightRules = function() {

    var keywordControls = (
        [ "add_rewrite", "alias", "as", "assume", "attribute",
          "begin", "by", "calc", "calc_refl", "calc_subst", "calc_trans", "check",
          "classes", "coercions", "conjecture", "constants", "context",
          "corollary", "else", "end", "environment", "eval", "example",
          "exists", "exit", "export", "exposing", "extends", "fields", "find_decl",
          "forall", "from", "fun", "have", "help", "hiding", "if",
          "import", "in", "infix", "infixl", "infixr", "instances",
          "let", "local", "match", "namespace", "notation", "obtain", "obtains",
          "omit", "opaque", "open", "options", "parameter", "parameters", "postfix",
          "precedence", "prefix", "premise", "premises", "print", "private", "proof",
          "protected", "qed", "raw", "renaming", "section", "set_option",
          "show", "tactic_hint", "take", "then", "universe",
          "universes", "using", "variable", "variables", "with"].join("|")
    );

    var nameProviders = (
        ["inductive", "structure", "record", "theorem", "axiom",
         "axioms", "lemma", "hypothesis", "definition", "constant"].join("|")
    );

    var storageType = (
        ["Prop", "Type", "Type'", "Type₊", "Type₁", "Type₂", "Type₃"].join("|")
    );

    var storageModifiers = (
        "\\[(" +
            ["abbreviations", "all-transparent", "begin-end-hints", "class", "classes", "coercion",
             "coercions", "declarations", "decls", "instance", "irreducible",
             "multiple-instances", "notation", "notations", "parsing-only", "persistent",
             "reduce-hints", "reducible", "tactic-hints", "visible", "wf", "whnf"
            ].join("|") +
            ")\\]"
    );

    var keywordOperators = (
        [].join("|")
    );

    var keywordMapper = this.$keywords = this.createKeywordMapper({
        "keyword.control" : keywordControls,
        "storage.type" : storageType,
        "keyword.operator" : keywordOperators,
        "variable.language": "sorry"
    }, "identifier");

    var identifierRe = "[A-Za-z_\u03b1-\u03ba\u03bc-\u03fb\u1f00-\u1ffe\u2100-\u214f][A-Za-z0-9_'\u03b1-\u03ba\u03bc-\u03fb\u1f00-\u1ffe\u2070-\u2079\u207f-\u2089\u2090-\u209c\u2100-\u214f]*";
    var operatorRe = new RegExp(["#", "@", "->", "∼", "↔", "/", "==", "=", ":=", "<->",
                                 "/\\", "\\/", "∧", "∨", "≠", "<", ">", "≤", "≥", "¬",
                                 "<=", ">=", "⁻¹", "⬝", "▸", "\\+", "\\*", "-", "/",
                                 "λ", "→", "∃", "∀", ":="].join("|"));

    this.$rules = {
        "start" : [
            {
                token : "comment", // single line comment "--"
                regex : "--.*$"
            },
            DocCommentHighlightRules.getStartRule("doc-start"),
            {
                token : "comment", // multi line comment "/-"
                regex : "\\/-",
                next : "comment"
            }, {
                stateName: "qqstring",
                token : "string.start", regex : '"', next : [
                    {token : "string.end", regex : '"', next : "start"},
                    {token : "constant.language.escape", regex : /\\[n"\\]/},
                    {defaultToken: "string"}
                ]
            }, {
                token : "keyword.control", regex : nameProviders, next : [
                    {token : "variable.language", regex : identifierRe, next : "start"} ]
            }, {
                token : "constant.numeric", // hex
                regex : "0[xX][0-9a-fA-F]+(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"
            }, {
                token : "constant.numeric", // float
                regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b"
            }, {
                token : "storage.modifier",
                regex : storageModifiers
            }, {
                token : keywordMapper,
                regex : identifierRe
            }, {
                token : "operator",
                regex : operatorRe
            }, {
              token : "punctuation.operator",
              regex : "\\?|\\:|\\,|\\;|\\."
            }, {
                token : "paren.lparen",
                regex : "[[({]"
            }, {
                token : "paren.rparen",
                regex : "[\\])}]"
            }, {
                token : "text",
                regex : "\\s+"
            }
        ],
        "comment" : [ {token: "comment", regex: "-/", next: "start"},
                      {defaultToken: "comment"} ]
    };

    this.embedRules(DocCommentHighlightRules, "doc-",
        [ DocCommentHighlightRules.getEndRule("start") ]);
    this.normalizeRules();
};

oop.inherits(leanHighlightRules, TextHighlightRules);

exports.leanHighlightRules = leanHighlightRules;
});

ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"], function(require, exports, module) {
"use strict";

var Range = require("../range").Range;

var MatchingBraceOutdent = function() {};

(function() {

    this.checkOutdent = function(line, input) {
        if (! /^\s+$/.test(line))
            return false;

        return /^\s*\}/.test(input);
    };

    this.autoOutdent = function(doc, row) {
        var line = doc.getLine(row);
        var match = line.match(/^(\s*\})/);

        if (!match) return 0;

        var column = match[1].length;
        var openBracePos = doc.findMatchingBracket({row: row, column: column});

        if (!openBracePos || openBracePos.row == row) return 0;

        var indent = this.$getIndent(doc.getLine(openBracePos.row));
        doc.replace(new Range(row, 0, row, column-1), indent);
    };

    this.$getIndent = function(line) {
        return line.match(/^\s*/)[0];
    };

}).call(MatchingBraceOutdent.prototype);

exports.MatchingBraceOutdent = MatchingBraceOutdent;
});

ace.define("ace/mode/lean",["require","exports","module","ace/lib/oop","ace/mode/text","ace/mode/lean_highlight_rules","ace/mode/matching_brace_outdent","ace/range"], function(require, exports, module) {
"use strict";

var oop = require("../lib/oop");
var TextMode = require("./text").Mode;
var leanHighlightRules = require("./lean_highlight_rules").leanHighlightRules;
var MatchingBraceOutdent = require("./matching_brace_outdent").MatchingBraceOutdent;
var Range = require("../range").Range;

var Mode = function() {
    this.HighlightRules = leanHighlightRules;

    this.$outdent = new MatchingBraceOutdent();
};
oop.inherits(Mode, TextMode);

(function() {

    this.lineCommentStart = "--";
    this.blockComment = {start: "/-", end: "-/"};

    this.getNextLineIndent = function(state, line, tab) {
        var indent = this.$getIndent(line);

        var tokenizedLine = this.getTokenizer().getLineTokens(line, state);
        var tokens = tokenizedLine.tokens;
        var endState = tokenizedLine.state;

        if (tokens.length && tokens[tokens.length-1].type == "comment") {
            return indent;
        }

        if (state == "start") {
            var match = line.match(/^.*[\{\(\[]\s*$/);
            if (match) {
                indent += tab;
            }
        } else if (state == "doc-start") {
            if (endState == "start") {
                return "";
            }
            var match = line.match(/^\s*(\/?)\*/);
            if (match) {
                if (match[1]) {
                    indent += " ";
                }
                indent += "- ";
            }
        }

        return indent;
    };

    this.checkOutdent = function(state, line, input) {
        return this.$outdent.checkOutdent(line, input);
    };

    this.autoOutdent = function(state, doc, row) {
        this.$outdent.autoOutdent(doc, row);
    };

    this.$id = "ace/mode/lean";
}).call(Mode.prototype);

exports.Mode = Mode;
});


using System;
using System.Collections.Generic;
using System.Linq;

namespace Octgn.Site.Api.Models
{
    public class WebhookQueueMessage
    {
        public WebhookEndpoint Endpoint { get; set; }
        public string Body { get; set; }
        public Dictionary<string, List<string>> Headers { get; set; }

        public WebhookQueueMessage()
        {

        }

        public WebhookQueueMessage(WebhookEndpoint end, string body, IEnumerable<KeyValuePair<string, IEnumerable<string>>> headers )
        {
            Endpoint = end;
            if(String.IsNullOrWhiteSpace(body))
                throw new ArgumentNullException("body");
            Body = body;
            Headers = headers.ToDictionary(x=>x.Key, x=>x.Value.ToList());
        }
    }

    public enum WebhookEndpoint
    {
        Octgn,OctgnDev,OctgnLobby
    }
}