text:
layout:     post
title:      "Album Released: Science Series III : Landscape"
subtitle:   ""
date:       2015-08-23 12:00:00
author:     "Phil Chapavich T."
header-img: "public/news/2015-08-23-SSIII/header.jpg"
---

<img src="https://40.media.tumblr.com/7d4f434224836f43262eedbbb88955af/tumblr_nti6jlzGAd1rv4foko1_1280.jpg">

### Science Series III : Landscape

Music by phil_wc

Genre: Ambient, Instrumental, Atmospheric

**Track list**

1. Dust (intro)
2. If We Can Go Back in Time
3. A Picture in Our Eyes
4. Generation
5. Spaceship Launching Broadcast
6. What Do We Have Left
7. Still Hoping
8. Dreams

Download & Streaming Link: [https://phil-wc.bandcamp.com/album/science-series-iii-landscape](https://phil-wc.bandcamp.com/album/science-series-iii-landscape)
Free Streaming site: [http://fungjai.com/artist/Phillwc](http://fungjai.com/artist/Phillwc)

Youtube video teaser: [https://www.youtube.com/watch?v=01dHc5ETpTo](https://www.youtube.com/watch?v=01dHc5ETpTo)

The concept of this album is about a group of humans during the post-apocalypse of planet earth. They are surviving on The earth for long. And they are still hoping that it will be better after sent a spaceship to find a new territory.
This is the another story which is in the same universe of Science Series II : Space Explorer.

If you like it, Please share! Also you can give me a feedback by posting comments here.
This album will be free until 17/9/2015.Then I'll sell for a cheap price

All rights reserved phil_wc

-------

ภาษาไทย

อัลบั้มใหม่มาแล้วครับหลังจากหายไปเกือบสองปี ฟังและคอมเม้นได้เลย

คอนเซปต์อัลบั้มนี้เกี่ยวกับเรื่องราวของคนบนโลกหลังผ่านเหตุการณ์ล่มสลายของโลก พวกเขาต้องอยู่อย่างลำพังกับคนเพียงหยิบมือ แต่ก็ยังจะพอมีความหวังให้อยู่ต่อไป เป็นคอนเซปต์อัลบั้มที่มีเรื่องราวไปตลอดทั้งอัลบั้ม
นี่เป็นอัลบั้มที่มีเนื้อเรื่องอยู่ในจักรวาลเดียวกับ Science Series II : Space Explorer แต่เป็นคนละกลุ่มคน


text:
//
//  ReservarViewController.m
//  HorizonSuites
//
//  Created by Fernando Archila on 10/13/13.
//  Copyright (c) 2013 Fernando Archila. All rights reserved.
//

#import "ReservarViewController.h"

@interface ReservarViewController (){
    int costo;
    int dias;
    int total;

}

@end
/*
extern NSDate *extern_fecha_checkin;
extern NSDate *extern_fecha_checkout;
extern NSInteger extern_room_type;
extern NSInteger indicador_fecha_checkin;
extern NSInteger indicador_fecha_checkout;

 */
@implementation ReservarViewController
NSString *str;

extern NSDate *extern_fecha_checkin;
extern NSDate *extern_fecha_checkout;
extern NSInteger extern_room_type;
extern NSInteger indicador_fecha_checkin;
extern NSInteger indicador_fecha_checkout;
extern  NSInteger costo;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {

        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.textfield_email.delegate=self;
    self.textfield_firstname.delegate=self;
    self.textfield_lastname.delegate=self;
    self.textfield_phone1.delegate=self;
    self.textfield_phone2.delegate=self;
    self.textfield_skype.delegate=self;

    self.label_checkin.text=self.fecha_checkin;
    self.label_checkout.text=self.fecha_checkout;
    self.label_room.text=self.room_type;

    if (indicador_fecha_checkin==1) {
        NSDateFormatter *form = [[NSDateFormatter alloc] init];
        [form setDateFormat:@"MM-dd-YYYY"];
        NSString *str = [form stringFromDate:extern_fecha_checkin];
        self.label_checkin.text=str;
    }
    if (indicador_fecha_checkout==1) {
        NSDateFormatter *form = [[NSDateFormatter alloc] init];
        [form setDateFormat:@"MM-dd-YYYY"];
        NSString *str = [form stringFromDate:extern_fecha_checkout];
        self.label_checkout.text=str;
    }
    if (extern_room_type==1){
        self.label_room.text=@"Simple";
        costo=80;

    } else if (extern_room_type==2){
        self.label_room.text=@"Double";
        costo=95;

    }else if (extern_room_type==1){
        self.label_room.text=@"Suite";
        costo=115;

    }

	// Do any additional setup after loading the view.
}

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    [_textfield_email resignFirstResponder];
    [_textfield_firstname resignFirstResponder];
    [_textfield_lastname resignFirstResponder];
    [_textfield_phone1 resignFirstResponder];
    [_textfield_phone2 resignFirstResponder];
    [_textfield_skype resignFirstResponder];

    }

- (BOOL)  textFieldShouldReturn:(UITextField *)textField {

    if (textField) {
        [textField resignFirstResponder];
    }
    return NO;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)reservar:(id)sender {

    NSTimeInterval secondsBetween = [extern_fecha_checkout timeIntervalSinceDate:extern_fecha_checkin];

    int numberOfDays = secondsBetween / 86400;

    total = costo* numberOfDays;

   // NSLog(@"There are %d days in between the two dates.", numberOfDays);

    NSString *mensaje =[NSString stringWithFormat:@"Su reservacion sera por %i ", total];

    confirmation = [[UIAlertView alloc] initWithTitle:@"Confirmation" message:mensaje delegate:self cancelButtonTitle: @"Cancel" otherButtonTitles:@"Confirm", nil];

    [confirmation show];

}
@end

redpajama_set_name: RedPajamaGithub


text:
"""
This module provide the attack method for Iterator FGSM's implement.
"""
from __future__ import division

import logging
from collections import Iterable

import numpy as np

from .base import Attack

__all__ = [
    'GradientMethodAttack', 'FastGradientSignMethodAttack', 'FGSM',
    'FastGradientSignMethodTargetedAttack', 'FGSMT',
    'BasicIterativeMethodAttack', 'BIM',
    'IterativeLeastLikelyClassMethodAttack', 'ILCM'
]

class GradientMethodAttack(Attack):
    """
    This class implements gradient attack method, and is the base of FGSM, BIM,
    ILCM, etc.
    """

    def __init__(self, model, support_targeted=True):
        """
        :param model(model): The model to be attacked.
        :param support_targeted(bool): Does this attack method support targeted.
        """
        super(GradientMethodAttack, self).__init__(model)
        self.support_targeted = support_targeted

    def _apply(self, adversary, norm_ord=np.inf, epsilons=0.01, steps=100):
        """
        Apply the gradient attack method.
        :param adversary(Adversary):
            The Adversary object.
        :param norm_ord(int):
            Order of the norm, such as np.inf, 1, 2, etc. It can't be 0.
        :param epsilons(list|tuple|int):
            Attack step size (input variation).
        :param steps:
            The number of iterator steps.
        :return:
            adversary(Adversary): The Adversary object.
        """
        if norm_ord == 0:
            raise ValueError("L0 norm is not supported!")

        if not self.support_targeted:
            if adversary.is_targeted_attack:
                raise ValueError(
                    "This attack method doesn't support targeted attack!")

        if not isinstance(epsilons, Iterable):
            epsilons = np.linspace(epsilons, epsilons + 1e-10, num=steps)

        pre_label = adversary.original_label
        min_, max_ = self.model.bounds()

        assert self.model.channel_axis() == adversary.original.ndim
        assert (self.model.channel_axis() == 1 or
                self.model.channel_axis() == adversary.original.shape[0] or
                self.model.channel_axis() == adversary.original.shape[-1])

        step = 1
        adv_img = adversary.original
        for epsilon in epsilons[:steps]:
            if epsilon == 0.0:
                continue
            if adversary.is_targeted_attack:
                gradient = -self.model.gradient(adv_img, adversary.target_label)
            else:
                gradient = self.model.gradient(adv_img,
                                               adversary.original_label)
            if norm_ord == np.inf:
                gradient_norm = np.sign(gradient)
            else:
                gradient_norm = gradient / self._norm(gradient, ord=norm_ord)

            adv_img = adv_img + epsilon * gradient_norm * (max_ - min_)
            adv_img = np.clip(adv_img, min_, max_)
            adv_label = np.argmax(self.model.predict(adv_img))
            logging.info('step={}, epsilon = {:.5f}, pre_label = {}, '
                         'adv_label={}'.format(step, epsilon, pre_label,
                                               adv_label))
            if adversary.try_accept_the_example(adv_img, adv_label):
                return adversary
            step += 1
        return adversary

    @staticmethod
    def _norm(a, ord):
        if a.ndim == 1:
            return np.linalg.norm(a, ord=ord)
        if a.ndim == a.shape[0]:
            norm_shape = (a.ndim, reduce(np.dot, a.shape[1:]))
            norm_axis = 1
        else:
            norm_shape = (reduce(np.dot, a.shape[:-1]), a.ndim)
            norm_axis = 0
        return np.linalg.norm(a.reshape(norm_shape), ord=ord, axis=norm_axis)

class FastGradientSignMethodTargetedAttack(GradientMethodAttack):
    """
    "Fast Gradient Sign Method" is extended to support targeted attack.
    "Fast Gradient Sign Method" was originally implemented by Goodfellow et
    al. (2015) with the infinity norm.

    Paper link: https://arxiv.org/abs/1412.6572
    """

    def _apply(self, adversary, epsilons=0.03):
        return GradientMethodAttack._apply(
            self,
            adversary=adversary,
            norm_ord=np.inf,
            epsilons=epsilons,
            steps=1)

class FastGradientSignMethodAttack(FastGradientSignMethodTargetedAttack):
    """
    This attack was originally implemented by Goodfellow et al. (2015) with the
    infinity norm, and is known as the "Fast Gradient Sign Method".

    Paper link: https://arxiv.org/abs/1412.6572
    """

    def __init__(self, model):
        super(FastGradientSignMethodAttack, self).__init__(model, False)

class IterativeLeastLikelyClassMethodAttack(GradientMethodAttack):
    """
    "Iterative Least-likely Class Method (ILCM)" extends "BIM" to support
    targeted attack.
    "The Basic Iterative Method (BIM)" is to extend "FSGM". "BIM" iteratively
    take multiple small steps while adjusting the direction after each step.

    Paper link: https://arxiv.org/abs/1607.02533
    """

    def _apply(self, adversary, epsilons=0.001, steps=1000):
        return GradientMethodAttack._apply(
            self,
            adversary=adversary,
            norm_ord=np.inf,
            epsilons=epsilons,
            steps=steps)

class BasicIterativeMethodAttack(IterativeLeastLikelyClassMethodAttack):
    """
    FGSM is a one-step method. "The Basic Iterative Method (BIM)" iteratively
    take multiple small steps while adjusting the direction after each step.
    Paper link: https://arxiv.org/abs/1607.02533
    """

    def __init__(self, model):
        super(BasicIterativeMethodAttack, self).__init__(model, False)

FGSM = FastGradientSignMethodAttack
FGSMT = FastGradientSignMethodTargetedAttack
BIM = BasicIterativeMethodAttack
ILCM = IterativeLeastLikelyClassMethodAttack


text:
//main namespace
(function(global){

/* This file includes
 * PointCloud: to render points
 * ParticleEmissor: to render basic particles
 * Billboard: to render screen aligned plane
 * SpritesBatch

*/

/**
* PointCloud renders an array of points
* @class PointCloud
* @constructor
*/
function PointCloud()
{
	this._ctor();

	this.points = [];
	this.max_points = 1000;

	this.draw_range = [0,this.max_points*3];
	this.shader = "pointcloud";
	this.textures = { color: "white" };
	this.blend_mode = RD.BLEND_ALPHA;
	this.flags.depth_write = false;
	this.render_priority = RD.PRIORITY_ALPHA;

	this.num_textures = 1; //atlas number of rows and columns

	this.points_size = 100;

	this._uniforms = {
			u_pointSize: this.points_size,
			u_texture_info: vec2.fromValues(1,1)
		};

	this.primitive = gl.POINTS;
	this._vertices = new Float32Array( this.max_points * 3 );
	this._extra = new Float32Array( this.max_points * 3 );

	this._meshes = {};

	this._accumulated_time = 0;
	this._last_point_id = 0;
}

extendClass( PointCloud, RD.SceneNode );
RD.PointCloud = PointCloud;

PointCloud.prototype.render = function(renderer, camera )
{
	if(this.points.length == 0)
		return;

	this.updateVertices();

	//we can have several meshes if we have more than one context
	var mesh = this._meshes[ renderer.gl.context_id ];

	if(!mesh)
	{
		mesh = new GL.Mesh( undefined,undefined, renderer.gl );
		this._vertices_buffer = mesh.createVertexBuffer("vertices", null, 3, this._vertices, gl.DYNAMIC_DRAW );
		this._extra_buffer = mesh.createVertexBuffer("extra3", null, 3, this._extra, gl.DYNAMIC_DRAW );
	}
	this._mesh = mesh;

	this._vertices_buffer.uploadRange(0, this.points.length * 3 * 4); //4 bytes per float
	this._extra_buffer.uploadRange(0, this.points.length * 3 * 4); //4 bytes per float

	var shader = gl.shaders[ this.shader ];
	if(!shader)
	{
		shader = gl.shaders["pointcloud"];
		if(!shader)
			gl.shaders["pointcloud"] = new GL.Shader( PointCloud._vertex_shader, PointCloud._pixel_shader );
	}

	this.draw_range[1] = this.points.length;
	var viewport = gl.getViewport();
	this._uniforms.u_pointSize = this.points_size / (gl.canvas.width / viewport[2]);
	this._uniforms.u_color = this.color;
	if(this.num_textures > 0)
	{
		this._uniforms.u_texture_info[0] = 1 / this.num_textures;
		this._uniforms.u_texture_info[1] = this.num_textures * this.num_textures;
	}
	else
		this._uniforms.u_texture_info[0] = 0;

	if(this.ignore_transform)
	{
		mat4.identity( renderer._model_matrix );
		renderer._mvp_matrix.set( renderer._viewprojection_matrix );
	}
	renderer.renderNode( this, renderer, camera );
}

PointCloud.prototype.updateVertices = function(mesh)
{
	//update mesh
	var l = this.points.length;
	if(!l)
		return;
	var vertices = this._vertices;
	var extra = this._extra;
	var pos = 0;
	var num_textures2 = this.num_textures * this.num_textures;
	for(var i = 0; i < l; i++)
	{
		var p = this.points[i];
		vertices.set( p.pos ? p.pos : p, pos );
		extra[pos] = 1;
		extra[pos+1] = 1;
		if(num_textures2 > 1)
			extra[pos+2] = p.tex;
		pos+=3;
	}
}

PointCloud._vertex_shader = '\
			precision highp float;\
			attribute vec3 a_vertex;\
			attribute vec3 a_extra3;\
			varying vec2 v_coord;\
			varying vec4 v_color;\
			varying vec3 v_position;\
			uniform vec3 u_camera_position;\
			uniform mat4 u_mvp;\
			uniform mat4 u_model;\
			uniform vec4 u_color;\
			uniform float u_pointSize;\
			uniform vec2 u_texture_info;\
			void main() {\n\
				v_color = u_color;\n\
				v_color.a *= a_extra3.y;\n\
				v_coord.x = (a_extra3.z * u_texture_info.y) * u_texture_info.x;\n\
				v_coord.y = abs(floor(v_coord.x) * u_texture_info.x);\n\
				v_coord.x = fract(v_coord.x);\n\
				gl_Position = u_mvp * vec4(a_vertex,1.0);\n\
				v_position = (u_model * vec4(a_vertex,1.0)).xyz;\n\
				float dist = distance( u_camera_position, v_position );\n\
				gl_PointSize = 10.0 * u_pointSize / dist;\n\
			}\
			';
PointCloud._pixel_shader = '\
			precision highp float;\
			varying vec4 v_color;\
			varying vec2 v_coord;\
			varying vec3 v_position;\
			uniform sampler2D u_color_texture;\
			uniform vec2 u_texture_info;\
			void main() {\
			  vec2 uv = vec2(v_coord.x + gl_PointCoord.x * u_texture_info.x, v_coord.y + (1.0 - gl_PointCoord.y) * u_texture_info.x );\n\
			  vec4 color = texture2D( u_color_texture, uv );\n\
			  color.xyz *= v_color.xyz;\n\
			  #ifdef USE_PROCESS_COLOR\n\
				USE_PROCESS_COLOR\n\
			  #endif\n\
			  gl_FragColor = vec4( color.xyz, color.a * v_color.a );\n\
			}\
		';

/**
* ParticlesEmissor renders points and animate them as particles
* @class ParticlesEmissor
* @constructor
*/
function ParticlesEmissor()
{
	this._ctor();

	this.particles = [];
	this.max_particles = 1000;

	this.draw_range = [0,this.max_particles*3];
	this.shader = "particles";
	this.textures = { color: "white" };
	this.blend_mode = RD.BLEND_ALPHA;
	this.flags.depth_write = false;
	this.render_priority = RD.PRIORITY_ALPHA;

	this.num_textures = 1; //atlas number of rows and columns

	this.particles_size = 100;
	this.particles_per_second = 5;
	this.particles_life = 5;
	this.particles_damping = 0.5;
	this.particles_acceleration = vec3.create(); //use it for gravity and stuff
	this.particles_start_scale = 1;
	this.particles_end_scale = 1;
	this.velocity_variation = 1;
	this.emissor_direction = vec3.fromValues(0,1,0);

	this._uniforms = {
			u_pointSize: this.particle_size,
			u_scaleStartEnd: vec2.fromValues(1,1),
			u_texture_info: vec2.fromValues(1,1)
		};

	this.primitive = gl.POINTS;
	this._vertices = new Float32Array( this.max_particles * 3 );
	this._extra = new Float32Array( this.max_particles * 3 );

	this._meshes = {};

	this._accumulated_time = 0;
	this._last_particle_id = 0;
}

extendClass( ParticlesEmissor, RD.SceneNode );
RD.ParticlesEmissor = ParticlesEmissor;

ParticlesEmissor.prototype.update = function(dt)
{
	var l = this.particles.length;
	var damping = this.particles_damping;
	var acc = this.particles_acceleration;
	var forces = vec3.length(acc);
	if(l)
	{
		//update every particle alive (remove the dead ones)
		var alive = [];
		for(var i = 0; i < l; i++)
		{
			var p = this.particles[i];
			vec3.scaleAndAdd( p.pos, p.pos, p.vel, dt );
			if(forces)
				vec3.scaleAndAdd( p.vel, p.vel, acc, dt );
			if(damping)
				vec3.scaleAndAdd( p.vel, p.vel, p.vel, -dt * damping );
			p.ttl -= dt;
			if(p.ttl > 0)
				alive.push(p);
		}
		this.particles = alive;
	}

	//Create new ones
	var pos = this.getGlobalPosition();
	var vel = this.emissor_direction;
	var life = this.particles_life;
	var num_textures2 = this.num_textures * this.num_textures;
	var velocity_variation = this.velocity_variation;

	if(this.particles_per_second > 0)
	{
		var particles_to_create = this.particles_per_second * (dt + this._accumulated_time);
		this._accumulated_time = (particles_to_create - Math.floor( particles_to_create )) / this.particles_per_second;
		particles_to_create = Math.floor( particles_to_create );
		for(var i = 0; i < particles_to_create; i++)
		{
			if(this.particles.length >= this.max_particles)
				break;
			var vel = vec3.clone(vel);
			vel[0] += Math.random() * 0.5 * velocity_variation;
			vel[2] += Math.random() * 0.5 * velocity_variation;
			this.particles.push({id: this._last_particle_id++, tex: Math.floor(Math.random() * num_textures2) / num_textures2, pos: vec3.clone(pos), vel: vel, ttl: life});
		}
	}
}

ParticlesEmissor.prototype.render = function(renderer, camera )
{
	if(this.particles.length == 0)
		return;

	this.updateVertices();

	//we can have several meshes if we have more than one context
	var mesh = this._meshes[ renderer.gl.context_id ];

	if(!mesh)
	{
		mesh = new GL.Mesh( undefined,undefined, renderer.gl );
		this._vertices_buffer = mesh.createVertexBuffer("vertices", null, 3, this._vertices, gl.DYNAMIC_DRAW );
		this._extra_buffer = mesh.createVertexBuffer("extra3", null, 3, this._extra, gl.DYNAMIC_DRAW );
	}
	this._mesh = mesh;

	this._vertices_buffer.uploadRange(0, this.particles.length * 3 * 4); //4 bytes per float
	this._extra_buffer.uploadRange(0, this.particles.length * 3 * 4); //4 bytes per float

	var shader = gl.shaders[ this.shader ];
	if(!shader)
	{
		shader = gl.shaders["particles"];
		if(!shader)
			gl.shaders["particles"] = new GL.Shader(ParticlesEmissor._vertex_shader, ParticlesEmissor._pixel_shader);
	}

	this.draw_range[1] = this.particles.length;
	var viewport = gl.getViewport();
	this._uniforms.u_pointSize = this.particles_size / (gl.canvas.width / viewport[2]);
	this._uniforms.u_color = this.color;
	this._uniforms.u_texture_info[0] = 1 / this.num_textures;
	this._uniforms.u_texture_info[1] = this.num_textures * this.num_textures;
	this._uniforms.u_scaleStartEnd[0] = this.particles_start_scale;
	this._uniforms.u_scaleStartEnd[1] = this.particles_end_scale;
	mat4.identity( renderer._model_matrix );
	renderer._mvp_matrix.set( renderer._viewprojection_matrix );
	renderer.renderNode( this, renderer, camera );
}

ParticlesEmissor.prototype.updateVertices = function(mesh)
{
	//update mesh
	var l = this.particles.length;
	if(!l)
		return;
	var vertices = this._vertices;
	var extra = this._extra;
	var pos = 0;
	var life = this.particles_life;
	var num_textures2 = this.num_textures * this.num_textures;
	for(var i = 0; i < l; i++)
	{
		var p = this.particles[i];
		vertices.set( p.pos, pos );
		extra[pos] = 1;
		extra[pos+1] = p.ttl / life;
		if(num_textures2 > 1)
			extra[pos+2] = p.tex;
		pos+=3;
	}
}

ParticlesEmissor._vertex_shader = '\
			precision highp float;\
			attribute vec3 a_vertex;\
			attribute vec3 a_extra3;\
			varying vec2 v_coord;\
			varying vec4 v_color;\
			varying vec3 v_position;\
			uniform vec3 u_camera_position;\
			uniform mat4 u_mvp;\
			uniform mat4 u_model;\
			uniform vec4 u_color;\
			uniform float u_pointSize;\
			uniform vec2 u_texture_info;\
			uniform vec2 u_scaleStartEnd;\
			void main() {\n\
				v_color = u_color;\n\
				v_color.a *= a_extra3.y;\n\
				v_coord.x = (a_extra3.z * u_texture_info.y) * u_texture_info.x;\n\
				v_coord.y = floor(v_coord.x) * u_texture_info.x;\n\
				v_coord.x = fract(v_coord.x);\n\
				gl_Position = u_mvp * vec4(a_vertex,1.0);\n\
				v_position = (u_model * vec4(a_vertex,1.0)).xyz;\n\
				float dist = distance( u_camera_position, v_position );\n\
				gl_PointSize = mix(u_scaleStartEnd.y, u_scaleStartEnd.x, a_extra3.y) * 10.0 * u_pointSize / dist;\n\
			}\
			';
ParticlesEmissor._pixel_shader = '\
			precision highp float;\
			varying vec4 v_color;\
			varying vec2 v_coord;\
			varying vec3 v_position;\
			uniform sampler2D u_color_texture;\
			uniform vec2 u_texture_info;\
			void main() {\
			  vec4 color = texture2D( u_color_texture, v_coord + vec2(gl_PointCoord.x,1.0 - gl_PointCoord.y) * u_texture_info.x );\n\
			  color.xyz *= v_color.xyz;\n\
			  #ifdef USE_PROCESS_COLOR\n\
				USE_PROCESS_COLOR\n\
			  #endif\n\
			  gl_FragColor = vec4( color.xyz, color.a * v_color.a );\n\
			}\
		';

/**
* Billboard class to hold an scene item, used for camera aligned objects
* @class Billboard
* @constructor
*/
function Billboard()
{
	this._ctor();
}

extendClass( Billboard, RD.SceneNode );
RD.Billboard = Billboard;

Billboard.SPHERIC = 1;
Billboard.PARALLEL_SPHERIC = 2;
Billboard.CYLINDRIC = 3;
Billboard.PARALLEL_CYLINDRIC = 4;

Billboard.prototype._ctor = function()
{
	this.billboard_mode = Billboard.SPHERIC;
	this.auto_orient = true;
	RD.SceneNode.prototype._ctor.call(this);
}

Billboard.prototype.render = function(renderer, camera )
{
	//avoid orienting if it is not visible
	if(this.flags.visible === false)
		return;
	if(this.auto_orient)
		RD.orientNodeToCamera( this.billboard_mode, this, camera, renderer );
	renderer.renderNode( this, renderer, camera );
}

/**
* To render several sprites from a texture atlas
* It can be used as a scene node or a helper class
* @class SpritesBatch
* @constructor
*/
function SpritesBatch(o)
{
	this._ctor();
	if(o)
		this.configure(o);
}

SpritesBatch.prototype._ctor = function()
{
	RD.SceneNode.prototype._ctor.call(this);

	this.size = 1; //world units
	this._atlas_size = vec2.fromValues(1,1); //num columns and rows in the spritebatch atlas
	this.max_sprites = 1024;
	this.positions = new Float32Array(this.max_sprites*3); //positions
	this.sprite_info = new Float32Array(this.max_sprites*4); //sprite info [ frame, flipx, scale, extra_num ]
	this.index = 0;
	this.shader = null;
	this.use_points = false;
	this.mode = SpritesBatch.CYLINDRICAL;
	this.must_update_buffers = true;
}

RD.SpritesBatch = SpritesBatch;

SpritesBatch.XY = 0;
SpritesBatch.XZ = 1;
SpritesBatch.CYLINDRICAL = 2;
SpritesBatch.SPHERICAL = 3;
SpritesBatch.FLAT = 4;

Object.defineProperty( SpritesBatch.prototype, "atlas_size",{
	get: function(){return this._atlas_size;},
	set: function(v){this._atlas_size.set(v);}
});

SpritesBatch.prototype.clear = function()
{
	this.index = 0;
}

//adds one sprite,
SpritesBatch.prototype.add = function( position, frame, flipx, scale, extra_num )
{
	if( this.max_sprites <= this.index )
	{
		console.warn("too many sprites in batch, increase size");
		return;
	}
	var index = this.index;
	this.index += 1;
	this.positions.set( position, index*3 );
	if( position.length == 2 )
		this.positions[index*3+2] = 0;
	var i = index*4;
	this.sprite_info[i] = frame || 0;
	this.sprite_info[i+1] = flipx ? 1 : 0;
	this.sprite_info[i+2] = scale == null ? 1 : scale;
	this.sprite_info[i+3] = extra_num || 0;
	this.must_update_buffers = true;
}

SpritesBatch.prototype.addData = function( pos, extra )
{
	if( this.max_sprites <= this.index )
	{
		console.warn("too many sprites in batch, increase size");
		return;
	}
	var index = this.index;
	this.index += 1;
	this.positions.set( pos, index*3 );
	this.sprite_info.set( extra, index*4 );
	this.must_update_buffers = true;
}

SpritesBatch.prototype.render = function(renderer, camera)
{
	if(!this.texture)
		return;

	var tex = renderer.textures[ this.texture ];
	if(tex && this.flags.pixelated )
	{
		tex.bind(0);
		gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, this.flags.pixelated ? gl.NEAREST : gl.LINEAR );
		gl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, this.flags.pixelated ? gl.NEAREST_MIPMAP_NEAREST : gl.LINEAR_MIPMAP_LINEAR );
	}

	this.renderSprites( tex, camera, this.size, this.atlas_size, this.color, this.mode );
}

//mode allows to orient them
SpritesBatch.prototype.renderSprites = function( texture, camera, size, atlas_size, color, mode )
{
	if(!this.index) //no sprites
		return;

	var shader = gl.shaders[ this.shader ];

	if(!shader)
		shader = gl.shaders[ this.use_points ? "point_sprites" : "quad_sprites" ];

	if(!shader)
	{
		if(this.use_points)
			shader = gl.shaders[ "point_sprites" ] = new GL.Shader( SpritesBatch.point_sprites_vertex_shader, SpritesBatch.point_sprites_fragment_shader );
		else
			shader = gl.shaders[ "quad_sprites" ] = new GL.Shader( SpritesBatch.quad_sprites_vertex_shader, SpritesBatch.quad_sprites_fragment_shader );
	}

	mode = mode || 0;

	if( this.use_points )
	{
		shader.uniforms( GFX.scene_renderer._uniforms );
		shader.setUniform( "u_pointSize", size );
		shader.setUniform( "u_atlas", atlas_size );
		shader.setUniform( "u_texture", texture.bind(0) );
		RD.renderPoints( this.positions, this.sprite_info, camera, this.index, shader );
		return;
	}

	//using quads
	if(!this.vertex_buffer_data)
	{
		this.vertex_buffer_data = new Float32Array( this.max_sprites * 3 * 4 ); //4 vertex per quad
		this.extra4_buffer_data = new Float32Array( this.max_sprites * 4 * 4 ); //4 vertex per quad
		var extra2_data = new Int8Array( this.max_sprites * 2 * 4 ); //for inflation direction, could be shared among spritesheets
		var quad_data = new Int8Array([-1,1, 1,1, -1,-1, 1,-1]);
		for(var i = 0; i < extra2_data.length; i += 8 )
			extra2_data.set( quad_data, i );
		var indices_data = new Int16Array([0,2,1, 1,2,3]);
		var indices_buffer_data = new Uint16Array( this.max_sprites * 3 * 2); //3 indices, 2 triangles
		for(var i = 0; i < indices_buffer_data.length; ++i )
			indices_buffer_data[i] = indices_data[i%6] + Math.floor(i/6)*4;
		this.vertex_buffer = new GL.Buffer( gl.ARRAY_BUFFER, this.vertex_buffer_data, 3, gl.DYNAMIC_DRAW );
		this.extra4_buffer = new GL.Buffer( gl.ARRAY_BUFFER, this.extra4_buffer_data, 4, gl.DYNAMIC_DRAW );
		this.extra2_buffer = new GL.Buffer( gl.ARRAY_BUFFER, extra2_data, 2, gl.STATIC_DRAW );
		this.indices_buffer = new GL.Buffer( gl.ELEMENT_ARRAY_BUFFER, indices_buffer_data, 1, gl.STATIC_DRAW );
	}

	if( this.must_update_buffers )
	{
		var vertices = this.vertex_buffer_data;
		var extra4 = this.extra4_buffer_data;
		var end = Math.min( this.index, this.positions.length / 3);
		for(var i = 0, l = end; i < l; ++i )
		{
			var index = i*3;
			var pos = this.positions.subarray( index, index + 3 );
			vertices.set( pos, index*4 );
			vertices.set( pos, index*4 + 3 );
			vertices.set( pos, index*4 + 6 );
			vertices.set( pos, index*4 + 9 );
			var index = i*4;
			var info = this.sprite_info.subarray( index, index + 4 );
			extra4.set( info, index*4 );
			extra4.set( info, index*4 + 4 );
			extra4.set( info, index*4 + 8 );
			extra4.set( info, index*4 + 12 );
		}

		//upload subarray
		this.vertex_buffer.uploadRange(0, this.index * 3 * 4 * 4 );
		this.extra4_buffer.uploadRange(0, this.index * 4 * 4 * 4 );
		//this.vertex_buffer.upload();
		//this.extra4_buffer.upload();
		this.must_update_buffers = false;
	}

	var frame_width = (texture.width / atlas_size[0]);
	var frame_height = (texture.height / atlas_size[1]);
	var aspect = frame_width / frame_height;

	var top = RD.UP;
	var right = RD.RIGHT;

	switch( mode )
	{
		case RD.SpritesBatch.SPHERICAL: top = camera.getLocalVector( RD.UP ); //break not missing
		case RD.SpritesBatch.CYLINDRICAL: right = camera.getLocalVector( RD.RIGHT ); break;
		case RD.SpritesBatch.FLAT: top = camera.getLocalVector( RD.FRONT ); right = camera.getLocalVector( RD.RIGHT ); break;
		case RD.SpritesBatch.XZ: top = RD.FRONT; break;
	};

	//render
	shader.bind();
	shader.setUniform("u_model", RD.IDENTITY );
	shader.setUniform("u_viewprojection", camera._viewprojection_matrix );
	shader.setUniform("u_color", color || RD.ONES4 );
	shader.setUniform("u_size", [size, size / aspect] );
	shader.setUniform("u_top", top );
	shader.setUniform("u_right", right );
	shader.setUniform( "u_atlas", atlas_size );
	shader.setUniform( "u_texture", texture.bind(0) );
	shader.setUniform( "u_itexsize", [ 1 / texture.width, 1 / texture.height ] );
	shader.setUniform( "u_viewport", gl.viewport_data );

	var loc1 = shader.attributes["a_vertex"];
	var loc2 = shader.attributes["a_extra4"];
	var loc3 = shader.attributes["a_extra2"];
	this.vertex_buffer.bind( loc1 );
	this.extra4_buffer.bind( loc2 );
	this.extra2_buffer.bind( loc3 );
	gl.bindBuffer( gl.ELEMENT_ARRAY_BUFFER, this.indices_buffer.buffer );
	gl.drawElements( gl.TRIANGLES, this.index * 6, gl.UNSIGNED_SHORT, 0);
	gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null);
	this.vertex_buffer.unbind( loc1 );
	this.extra4_buffer.unbind( loc2 );
	this.extra2_buffer.unbind( loc3 );
}

extendClass( SpritesBatch, RD.SceneNode );

SpritesBatch.quad_sprites_vertex_shader = "\n\
precision highp float;\n\
attribute vec3 a_vertex;\n\
attribute vec4 a_extra4; //frame,flipx,scale,extranum\n\
attribute vec2 a_extra2;//expanse direction\n\
varying vec3 v_pos;\n\
varying vec2 v_uv;\n\
varying vec4 v_color;\n\
uniform mat4 u_model;\n\
uniform mat4 u_viewprojection;\n\
uniform vec4 u_viewport;\n\
uniform vec2 u_size;\n\
uniform vec3 u_top;\n\
uniform vec3 u_right;\n\
uniform vec4 u_color;\n\
uniform vec2 u_atlas;\n\
uniform vec2 u_itexsize;\n\
\n\
void main() {\n\
	vec3 vertex = a_vertex + a_extra4.z * u_size.y * u_top * a_extra2.y + a_extra4.z * u_size.x * u_right * a_extra2.x;\n\
	vec2 uv = a_extra2;\n\
	if( a_extra4.y != 0.0) //flip X\n\
		uv.x *= -1.0;\n\
	uv.x *= 1.0 - u_itexsize.x;\n\
	uv.y *= -1.0;\n\
	uv = uv * 0.5 + vec2(0.5);\n\
	\n\
	vec2 i_atlas = vec2(1.0) / u_atlas; \n\
	float frame = a_extra4.x;\n\
	float frame_x = mod( frame, u_atlas.x );\n\
	float frame_y = floor( frame * i_atlas.x );\n\
	uv.x = (uv.x + frame_x) * i_atlas.x;\n\
	uv.y += frame_y;\n\
	uv.y = 1.0 - uv.y * i_atlas.y;\n\
	v_uv = uv;\n\
	v_pos = (u_model * vec4(vertex,1.0)).xyz;\n\
	gl_Position = u_viewprojection * vec4(v_pos,1.0);\n\
	//gl_Position.x = floor(gl_Position.x * u_viewport.z * 1.0) / (u_viewport.z * 1.0);\n\
	//gl_Position.y = floor(gl_Position.y * u_viewport.w * 1.0) / (u_viewport.w * 1.0);\n\
}\n\
\n\
";

SpritesBatch.quad_sprites_fragment_shader = "\n\
precision highp float;\n\
precision mediump int;\n\
\n\
varying vec3 v_pos;\n\
varying vec2 v_uv;\n\
uniform vec4 u_color;\n\
uniform sampler2D u_texture;\n\
\n\
void main() {\n\
	vec4 color = texture2D( u_texture, v_uv );\n\
	if(color.a < 0.1)\n\
		discard;\n\
	color *= u_color;\n\
	gl_FragColor = color;\n\
}\n\
";

SpritesBatch.point_sprites_vertex_shader = "\n\
precision highp float;\n\
attribute vec3 a_vertex;\n\
attribute vec4 a_extra4;\n\
varying vec3 v_pos;\n\
varying vec3 v_wPos;\n\
varying vec4 v_extra4;\n\
uniform mat4 u_model;\n\
uniform mat4 u_mvp;\n\
uniform vec4 u_viewport;\n\
uniform float u_camera_perspective;\n\
uniform float u_pointSize;\n\
\n\
float computePointSize( float radius, float w )\n\
{\n\
	if(radius < 0.0)\n\
		return -radius;\n\
	return u_viewport.w * u_camera_perspective * radius / w;\n\
}\n\
\n\
void main() {\n\
	vec3 vertex = a_vertex;	\n\
	v_pos = vertex;\n\
	v_wPos = (u_model * vec4(vertex,1.0)).xyz;\n\
	v_extra4 = a_extra4;\n\
	gl_Position = u_mvp * vec4(vertex,1.0);\n\
	gl_Position.x = floor(gl_Position.x * u_viewport.z) / u_viewport.z;\n\
	gl_Position.y = floor(gl_Position.y * u_viewport.w) / u_viewport.w;\n\
	gl_PointSize = computePointSize( u_pointSize * u_extra4.z, gl_Position.w );\n\
}\n\
";

SpritesBatch.point_sprites_fragment_shader = "\n\
precision highp float;\n\
varying vec3 v_pos;\n\
varying vec3 v_wPos;\n\
varying vec4 v_extra4; //id,flip,scale,extra\n\
uniform float u_atlas;\n\
\n\
uniform sampler2D u_texture;\n\
\n\
void main() {\n\
	float i_atlas = 1.0 / u_atlas;\n\
	float frame = v_extra4.x;\n\
	float x = frame * i_atlas;\n\
	float y = floor(x);\n\
	x = (x - y);\n\
	y = y / u_atlas;\n\
	if( v_extra4.y > 0.0 ) //must flip in x\n\
		x -= gl_PointCoord.x * i_atlas - i_atlas;\n\
	else\n\
		x += gl_PointCoord.x * i_atlas;\n\
	\n\
	vec2 uv = vec2( x, 1.0 - (y + gl_PointCoord.y / u_atlas) );\n\
	vec4 color = texture2D( u_texture, uv );\n\
	if(color.a < 0.1)\n\
		discard;\n\
	gl_FragColor = color;\n\
}\n\
";

//footer
})( typeof(window) != "undefined" ? window : (typeof(self) != "undefined" ? self : global ) );


text:
package com.bigbangbutton.editcodeview;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.support.annotation.ColorInt;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.content.ContextCompat;
import android.text.Editable;
import android.text.InputType;
import android.text.Selection;
import android.text.Spanned;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;

public class EditCodeView extends View
        implements View.OnClickListener, View.OnFocusChangeListener {

    private static final int DEFAULT_CODE_LENGTH = 4;
    private static final String DEFAULT_CODE_MASK = "*";
    private static final String DEFAULT_CODE_SYMBOL = "0";
    private static final String DEFAULT_REGEX = "[^0-9]";
    private static final float DEFAULT_REDUCTION_SCALE = 0.5f;

    private final CodeTextWatcher textWatcher = new CodeTextWatcher();
    private InputMethodManager inputmethodmanager;
    private EditCodeInputConnection editCodeInputConnection;
    private EditCodeListener editCodeListener;
    private EditCodeWatcher editCodeWatcher;
    private Editable editable;

    private Paint textPaint;
    private Paint underlinePaint;
    private Paint cursorPaint;

    private float textSize;
    private float textPosY;
    private int textColor;
    private float sectionWidth;
    private int codeLength;
    private float symbolWidth;
    private float symbolMaskedWidth;
    private float underlineHorizontalPadding;
    private float underlineReductionScale;
    private float underlineStrokeWidth;
    private int underlineBaseColor;
    private int underlineSelectedColor;
    private int underlineFilledColor;
    private int underlineCursorColor;
    private float underlinePosY;
    private int fontStyle;
    private boolean cursorEnabled;
    private boolean codeHiddenMode;
    private boolean isSelected;
    private String codeHiddenMask;
    private Rect textBounds = new Rect();

    private Runnable cursorAnimation = new Runnable() {
        public void run() {
            int color = cursorPaint.getColor() == underlineSelectedColor
                    ? underlineCursorColor
                    : underlineSelectedColor;
            cursorPaint.setColor(color);
            invalidate();
            postDelayed(cursorAnimation, 500);
        }
    };

    public EditCodeView(Context context) {
        super(context);
        init(context, null);
    }

    public EditCodeView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public EditCodeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    private void init(Context context, @Nullable AttributeSet attrs) {
        initDefaultAttrs(context);
        initCustomAttrs(context, attrs);
        initPaints();
        initViewsOptions(context);

        if (isInEditMode()) {
            editModePreview();
        }
    }

    private void initDefaultAttrs(Context context) {
        Resources resources = context.getResources();

        underlineReductionScale = DEFAULT_REDUCTION_SCALE;
        underlineStrokeWidth = resources.getDimension(R.dimen.underline_stroke_width);
        underlineBaseColor = ContextCompat.getColor(context, R.color.underline_base_color);
        underlineFilledColor = ContextCompat.getColor(context, R.color.underline_filled_color);
        underlineCursorColor = ContextCompat.getColor(context, R.color.underline_cursor_color);
        underlineSelectedColor = ContextCompat.getColor(context, R.color.underline_selected_color);
        textSize = resources.getDimension(R.dimen.code_text_size);
        textColor = ContextCompat.getColor(context, R.color.text_main_color);
        codeLength = DEFAULT_CODE_LENGTH;
        codeHiddenMask = DEFAULT_CODE_MASK;
    }

    private void initCustomAttrs(Context context, AttributeSet attributeSet) {
        if (attributeSet == null) return;

        TypedArray attributes = context.obtainStyledAttributes(
                attributeSet, R.styleable.EditCodeView);

        underlineStrokeWidth = attributes.getDimension(
                R.styleable.EditCodeView_underlineStroke, underlineStrokeWidth);

        underlineReductionScale = attributes.getFloat(
                R.styleable.EditCodeView_underlineReductionScale, underlineReductionScale);

        underlineBaseColor = attributes.getColor(
                R.styleable.EditCodeView_underlineBaseColor, underlineBaseColor);

        underlineSelectedColor = attributes.getColor(
                R.styleable.EditCodeView_underlineSelectedColor, underlineSelectedColor);

        underlineFilledColor = attributes.getColor(
                R.styleable.EditCodeView_underlineFilledColor, underlineFilledColor);

        underlineCursorColor = attributes.getColor(
                R.styleable.EditCodeView_underlineCursorColor, underlineCursorColor);

        cursorEnabled = attributes.getBoolean(
                R.styleable.EditCodeView_underlineCursorEnabled, cursorEnabled);

        textSize = attributes.getDimension(
                R.styleable.EditCodeView_textSize, textSize);

        textColor = attributes.getColor(
                R.styleable.EditCodeView_textColor, textColor);

        fontStyle = attributes.getInt(
                R.styleable.EditCodeView_font_style, fontStyle);

        codeLength = attributes.getInt(
                R.styleable.EditCodeView_codeLength, DEFAULT_CODE_LENGTH);

        codeHiddenMode = attributes.getBoolean(
                R.styleable.EditCodeView_codeHiddenMode, codeHiddenMode);

        String mask = attributes.getString(R.styleable.EditCodeView_codeHiddenMask);
        if (mask != null && mask.length() > 0) {
            codeHiddenMask = mask.substring(0, 1);
        }

        attributes.recycle();
    }

    private void editModePreview() {
        for (int i = 0; i < codeLength; i++) {
            if (codeHiddenMode) {
                editable.append(codeHiddenMask);
            } else {
                editable.append(DEFAULT_CODE_SYMBOL);
            }
        }
    }

    private void initPaints() {
        textPaint = new Paint();
        textPaint.setColor(textColor);
        textPaint.setTextSize(textSize);
        textPaint.setTypeface(Typeface.create(Typeface.DEFAULT, fontStyle));
        textPaint.setAntiAlias(true);

        underlinePaint = new Paint();
        underlinePaint.setColor(underlineBaseColor);
        underlinePaint.setStrokeWidth(underlineStrokeWidth);

        cursorPaint = new Paint();
        cursorPaint.setColor(underlineBaseColor);
        cursorPaint.setStrokeWidth(underlineStrokeWidth);
    }

    private void initViewsOptions(Context context) {
        setOnClickListener(this);
        setFocusable(true);
        setFocusableInTouchMode(true);
        setOnFocusChangeListener(this);

        inputmethodmanager =
                (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);

        editable = Editable.Factory.getInstance().newEditable("");
        editable.setSpan(textWatcher, 0, editable.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
        Selection.setSelection(editable, 0);

        editCodeInputConnection = new EditCodeInputConnection(this, true, codeLength);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        measureSizes(w, h);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        drawUnderline(canvas);
        drawText(canvas);
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        setSelected(hasFocus);
        if (hasFocus) {
            if (cursorEnabled) {
                post(cursorAnimation);
            }
            showKeyboard();
        } else {
            if (cursorEnabled) {
                removeCallbacks(cursorAnimation);
            }
            hideKeyboard();
        }
    }

    private void drawText(Canvas canvas) {
        if (codeHiddenMode) {
            char[] symbol = {codeHiddenMask.charAt(0)};
            for (int i = 0; i < editable.length(); i++) {
                float textPosX = sectionWidth * i + sectionWidth / 2 - symbolMaskedWidth / 2;
                canvas.drawText(symbol, 0, 1, textPosX, textPosY, textPaint);
            }
        } else {
            for (int i = 0; i < editable.length(); i++) {
                char[] symbol = {editable.charAt(i)};
                float textPosX = sectionWidth * i + sectionWidth / 2 - symbolWidth / 2;
                canvas.drawText(symbol, 0, 1, textPosX, textPosY, textPaint);
            }
        }
    }

    private void drawUnderline(Canvas canvas) {
        for (int i = 0; i < codeLength; i++) {
            float startPosX = sectionWidth * i + underlineHorizontalPadding;
            float endPosX = startPosX + sectionWidth - underlineHorizontalPadding * 2;

            if (cursorEnabled && isSelected && editable.length() == i) {
                canvas.drawLine(startPosX, underlinePosY, endPosX, underlinePosY, cursorPaint);
            } else {
                if (editable.length() <= i && isSelected) {
                    underlinePaint.setColor(underlineSelectedColor);
                } else if (editable.length() <= i && !isSelected) {
                    underlinePaint.setColor(underlineBaseColor);
                } else {
                    underlinePaint.setColor(underlineFilledColor);
                }
                canvas.drawLine(startPosX, underlinePosY, endPosX, underlinePosY, underlinePaint);
            }
        }
    }

    private void measureSizes(int viewWidth, int viewHeight) {
        if (underlineReductionScale > 1) underlineReductionScale = 1;
        if (underlineReductionScale < 0) underlineReductionScale = 0;

        if (codeLength <= 0) {
            throw new IllegalArgumentException("Code length must be over than zero");
        }

        symbolWidth = textPaint.measureText(DEFAULT_CODE_SYMBOL);
        symbolMaskedWidth = textPaint.measureText(codeHiddenMask);
        textPaint.getTextBounds(DEFAULT_CODE_SYMBOL, 0, 1, textBounds);
        sectionWidth = viewWidth / codeLength;
        underlinePosY = viewHeight - getPaddingBottom();
        underlineHorizontalPadding = sectionWidth * underlineReductionScale / 2;
        textPosY = viewHeight / 2 + textBounds.height() / 2;
    }

    private int measureHeight(int measureSpec) {
        int size = (int) (getPaddingBottom()
                + getPaddingTop()
                + textBounds.height()
                + textSize
                + underlineStrokeWidth);
        return resolveSizeAndState(size, measureSpec, 0);
    }

    private int measureWidth(int measureSpec) {
        int size = (int) ((getPaddingLeft() + getPaddingRight() + textSize) * codeLength * 2);
        return resolveSizeAndState(size, measureSpec, 0);
    }

    public void setEditCodeListener(EditCodeListener EditCodeListener) {
        this.editCodeListener = EditCodeListener;
    }

    public void setCode(@NonNull String code) {
        code = code.replaceAll(DEFAULT_REGEX, "");
        editCodeInputConnection.setComposingText(code, 1);
        editCodeInputConnection.finishComposingText();
    }

    public void clearCode() {
        editCodeInputConnection.setComposingRegion(0, codeLength);
        editCodeInputConnection.setComposingText("", 0);
        editCodeInputConnection.finishComposingText();
    }

    public String getCode() {
        return editable.toString();
    }

    public void setReductionScale(float scale) {
        if (scale > 1) scale = 1;
        if (scale < 0) scale = 0;

        underlineReductionScale = scale;
        invalidate();
    }

    public void setCodeHiddenMode(boolean hiddenMode) {
        codeHiddenMode = hiddenMode;
        invalidate();
    }

    public void setUnderlineBaseColor(@ColorInt int colorId) {
        underlineBaseColor = colorId;
        invalidate();
    }

    public void setUnderlineFilledColor(@ColorInt int colorId) {
        underlineFilledColor = colorId;
        invalidate();
    }

    public void setUnderlineSelectedColor(@ColorInt int colorId) {
        underlineSelectedColor = colorId;
        invalidate();
    }

    public void setUnderlineCursorColor(@ColorInt int colorId) {
        underlineCursorColor = colorId;
        invalidate();
    }

    public void setTextColor(@ColorInt int colorId) {
        textColor = colorId;
        invalidate();
    }

    public void setUnderlineStrokeWidth(float underlineStrokeWidth) {
        this.underlineStrokeWidth = underlineStrokeWidth;
        invalidate();
    }

    public void setCodeLength(int length) {
        codeLength = length;
        editCodeInputConnection = new EditCodeInputConnection(this, true, codeLength);
        editable.clear();
        inputmethodmanager.restartInput(this);
        invalidate();
    }

    public void setEditCodeWatcher(EditCodeWatcher editCodeWatcher) {
        this.editCodeWatcher = editCodeWatcher;
    }

    public int getCodeLength() {
        return codeLength;
    }

    public void showKeyboard() {
        inputmethodmanager.showSoftInput(this, 0);
    }

    public void hideKeyboard() {
        inputmethodmanager.hideSoftInputFromWindow(
                getWindowToken(),
                InputMethodManager.RESULT_UNCHANGED_SHOWN);
    }

    @Override
    public void onClick(View v) {
        showKeyboard();
    }

    @Override
    public InputConnection onCreateInputConnection(EditorInfo outAttrs) {

        outAttrs.inputType = InputType.TYPE_CLASS_NUMBER;
        outAttrs.imeOptions = EditorInfo.IME_ACTION_DONE;
        outAttrs.initialSelStart = 0;

        return editCodeInputConnection;
    }

    public void setSelected(boolean selected) {
        isSelected = selected;
        invalidate();
    }

    protected Editable getEditable() {
        return editable;
    }

    @Override
    public boolean onCheckIsTextEditor() {
        return true;
    }

    private class CodeTextWatcher implements TextWatcher {

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {
            invalidate();
            if(editCodeWatcher != null) {
                editCodeWatcher.onCodeChanged(s.toString());
            }
            if (editable.length() == codeLength) {
                if (editCodeListener != null) {
                    editCodeListener.onCodeReady(editable.toString());
                }
            }
        }
    }
}


text:
NS_ASSUME_NONNULL_BEGIN

/// The AffirmBaseModalViewController is a view controller which loads the informational modal for the Affirm promotional messaging (see https://docs.affirm.com/Integrate_Affirm/Promotional_Messaging ). The View Controller handles the closing of the modal window by closing itself.
/// To launch the modal when a button is clicked, create an AffirmConfiguration instance, then create an AffirmSiteModalViewController instance, passing in the modalId (given to you by Affirm) and the configuration. Then present the view controller.
@interface AffirmBaseModalViewController : UIViewController

@end

NS_ASSUME_NONNULL_END


text:
An asynchronous 4-bit counter built with JK Flip-Flops.

Here's a quick video of the circuit in action:

[![AsyncJKCounter](https://img.youtube.com/vi/dyn9gv996iY/0.jpg)](https://www.youtube.com/watch?v=dyn9gv996iY)

## Notes

This circuit uses 4 JK flip-flops set up for the "toggle" mode to implement an asynchronous 4-bit binary counter.

I'm using two 74LS73 chips for the flip-flops (each has two flip-flops).
These also support a "clear" input, but since I'm not using that, all the CLR inputs are pulled high.

The "toggle" mode corresponds to the state where both J and K inputs are high. In this situation, the output
will invert on the clock pulse (falling edge for the 74LS73).

A low-frequency 555 Timer astable oscillator provides a clock pulse of around [1.226 Hz](http://visual555.tardate.com/?mode=astable&r1=10.22&r2=10.22&c=1), and so it is possible to follow the counter with the human eye.

### Performance

Here's a logic trace captured with the clock souped up to [470Hz](http://visual555.tardate.com/?mode=astable&r1=10.22&r2=10.22&c=0.1).

* Logic channel D0 is the clock signal, also traced on CH1
* Logic channels D1, D2, D3, and D4 are the outputs from LSB to MSB

![Scope](./assets/AsyncJKCounter_scope.gif?raw=true)

### How Asynchronous is it?

The "asynchronous" description of the counter reflects the fact that the output transitions are not all synchronised to the same clock signal.

* only the first flip-flop is directly triggered by the input clock signal
* subsequent flip-flops are clocked by the output of the previous stage

For display purposes (like this circuit), this is not an issue.
But if the counter is in turn an input to subsequent digital logic stages, the lack of synchronisation may raise havoc due to the rippling changes.

There is a "synchronous" version of this circuit - see [LEAP#320](../SyncJKCounter) for this circuit.

Here's a trace of 4 digit signals captured in analog with the clock souped up to [470Hz](http://visual555.tardate.com/?mode=astable&r1=10.22&r2=10.22&c=0.1):

* CH1 is digit D3 (per the schematic) (MSB) - used for triggering on the falling edge, so we see all digit transitions together
* CH2 is digit D2 (per the schematic)
* CH2 is digit D1 (per the schematic)
* CH2 is digit D0 (per the schematic) (LSB)

The ripples are clear, taking place over about 42ns:

![Sync](./assets/AsyncJKCounter_sync.gif?raw=true)

## Construction

![Breadboard](./assets/AsyncJKCounter_bb.jpg?raw=true)

![The Schematic](./assets/AsyncJKCounter_schematic.jpg?raw=true)

![The Build](./assets/AsyncJKCounter_build.jpg?raw=true)

## Credits and References

* [74LS73 datasheet](https://www.futurlec.com/74LS/74LS73.shtml) - Dual JK Flip-Flop with Clear
* [CD4096 datasheet](http://www.alldatasheet.com/datasheet-pdf/pdf/66451/INTERSIL/CD4096BMS.html)
* [Sequential Circuits - Asynchronous Counters](http://www.allaboutcircuits.com/textbook/digital/chpt-11/asynchronous-counters/)
* [Basic Flip Flop Applications](https://youtu.be/SvF4etmRMhA) - Columbia Gorge Community College
* [JK Flip Flops](https://youtu.be/vy807m8LX84) - Columbia Gorge Community College
* [JK Flip Flop Examples](https://youtu.be/QTGgTxa2HeM) - Columbia Gorge Community College
* [Binary Counter Using J K Flip Flops](https://youtu.be/kwIHU5pCDtE)
* [Digital Electronics -- Counter Circuits](https://youtu.be/xf0EIWk7U0k)
* [..as mentioned on my blog](https://blog.tardate.com/2016/02/littlearduinoprojects186-asynchronous.html)


text:
using namespace std;

class Solution {
public:
    unordered_map<string, vector<string> > cache;
    vector<string> FindWord(string s, set<string> &wordDict) {
        if (cache.count(s)) {
            return cache[s];
        }
        vector<string> res;
        if (s.size() == 0) {
            res.push_back("");
            return res;
        }
        for (auto word : wordDict) {
            if ( s.length() >= word.length() && s.compare(0, word.length(), word) == 0) {
                vector<string> tail = FindWord(s.substr(word.length()), wordDict);
                for (auto t : tail) {
                    res.push_back(word + (t.empty() ? "" : " ") + t);
                }
            }
        }
        cache[s] = res;
        return res;
    }

    vector<string> wordBreak(string s, vector<string>& wordDict) {
        set<string> ss(wordDict.begin(), wordDict.end());
        return FindWord(s, ss);
    }
};


text:
/* global QUnit */

import { ObjectLoader } from '../../../../src/loaders/ObjectLoader.js';
import { DirectionalLight } from '../../../../src/lights/DirectionalLight.js';
import { DirectionalLightShadow } from '../../../../src/lights/DirectionalLightShadow.js';

export default QUnit.module( 'Lights', () => {

	QUnit.module( 'DirectionalLightShadow', () => {

		// INHERITANCE
		QUnit.todo( 'Extending', ( assert ) => {

			assert.ok( false, 'everything\'s gonna be alright' );

		} );

		// INSTANCING
		QUnit.todo( 'Instancing', ( assert ) => {

			assert.ok( false, 'everything\'s gonna be alright' );

		} );

		// OTHERS
		QUnit.test( 'clone/copy', ( assert ) => {

			var a = new DirectionalLightShadow();
			var b = new DirectionalLightShadow();
			var c;

			assert.notDeepEqual( a, b, 'Newly instanced shadows are not equal' );

			c = a.clone();
			assert.smartEqual( a, c, 'Shadows are identical after clone()' );

			c.mapSize.set( 1024, 1024 );
			assert.notDeepEqual( a, c, 'Shadows are different again after change' );

			b.copy( a );
			assert.smartEqual( a, b, 'Shadows are identical after copy()' );

			b.mapSize.set( 512, 512 );
			assert.notDeepEqual( a, b, 'Shadows are different again after change' );

		} );

		QUnit.test( 'toJSON', ( assert ) => {

			var light = new DirectionalLight();
			var shadow = new DirectionalLightShadow();

			shadow.bias = 10;
			shadow.radius = 5;
			shadow.mapSize.set( 1024, 1024 );
			light.shadow = shadow;

			var json = light.toJSON();
			var newLight = new ObjectLoader().parse( json );

			assert.smartEqual( newLight.shadow, light.shadow, 'Reloaded shadow is identical to the original one' );

		} );

	} );

} );


text:
package org.cordovastudio.dom;

import com.intellij.openapi.util.KeyValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.*;

/**
 * @author yole
 */
public class AttributeDefinition {
    private final String myName;
    private final Set<AttributeFormat> myFormats = EnumSet.noneOf(AttributeFormat.class);
    private final Vector<KeyValue<String, String>> myValues = new Vector<>();
    private final Map<String, String> myStyleable2DocValue = new HashMap<>();
    private String myGlobalDocValue;

    public AttributeDefinition(@NotNull String name) {
        myName = name;
    }

    public AttributeDefinition(@NotNull String name, @NotNull Collection<AttributeFormat> formats) {
        myName = name;
        myFormats.addAll(formats);
    }

    public void addValue(@NotNull String name, @NotNull String displayName) {
        myValues.add(new KeyValue<>(name, displayName));
    }

    @NotNull
    public String getName() {
        return myName;
    }

    @NotNull
    public Set<AttributeFormat> getFormats() {
        return Collections.unmodifiableSet(myFormats);
    }

    public void addFormats(@NotNull Collection<AttributeFormat> format) {
        myFormats.addAll(format);
    }

    @NotNull
    public Vector<KeyValue<String, String>> getValues() {
        return myValues;
    }

    @Nullable
    public String getDocValue(@Nullable String parentStyleable) {
        if (parentStyleable == null || !myStyleable2DocValue.containsKey(parentStyleable)) {
            return myGlobalDocValue;
        }
        return myStyleable2DocValue.get(parentStyleable);
    }

    public void addDocValue(@NotNull String docValue, @Nullable String parentStyleable) {
        if (parentStyleable == null || myGlobalDocValue == null) {
            myGlobalDocValue = docValue;
        }
        if (parentStyleable != null) {
            myStyleable2DocValue.put(parentStyleable, docValue);
        }
    }

    @Override
    public String toString() {
        return myName + " [" + myFormats + ']';
    }
}


text:
package sql.fredy.dbtools;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author sql@hulmen.ch
 */
public class TableLoader {

    private boolean TEST = false;
    private int CHUNKSIZE = 10000;
    //private int CHUNKSIZE = 1;  /// nimm das, wenn du doofe Fehler hast...
    private boolean initial = true;  // actually I can only load initially

    private Connection sourceConnection;
    private Connection destinationConnection;

    DatabaseMetaData sourceDmd;
    DatabaseMetaData destDmd;

    String readQuery;
    String destQuery;

    private String srcDb, destDb;
    private String srcSchema, destSchema;

    private String table;
    private String tableNamePattern;
    private ArrayList<TabellenSpalteInfo> spalten;
    private ArrayList<String> tableNames;
    private Logger logger = Logger.getLogger("loader");

    DatabaseMetaData dmd; // = c.getMetaData();

    public TableLoader(boolean test, String sourceDB, String destDB, String sourceSchema, String destinationSchema, Connection source, Connection dest) {
        setTEST(test);
        setSourceConnection(source);
        setDestinationConnection(dest);
        setSrcDb(sourceDB);
        setDestDb(destDB);
        setSrcSchema(sourceSchema);
        setDestSchema(destinationSchema);
    }

    public void loadIt(ArrayList<String> toLoad) {

        try {
            dmd = destinationConnection.getMetaData();
        } catch (SQLException ex) {
            Logger.getLogger(TableLoader.class.getName()).log(Level.SEVERE, "Error when fetching Destination MetaData", ex);
        }

        for (int i = 0; i < toLoad.size(); i++) {
            String t = toLoad.get(i);
            setTableNamePattern(t);
            createTableInfo();
            runImport();
        }

        close();

    }

    private int importLooper;
    private String aktuelleTabelle;
    /*
     Jede der Tabellen gem. TableNamePattern wird in einem eigenen Thread abgearbeitet
     Am Schluss der Verarbeitung muss gewartet werden, bis alle fertig sind...
     */

    public void runImport() {

        /*
         loope durch die Tabellen und importiere

         */
        for (importLooper = 0; importLooper < tableNames.size(); importLooper++) {
            aktuelleTabelle = tableNames.get(importLooper);

            processData(aktuelleTabelle);
        }

    }

    public static void main(String args[]) {

        String isTest = readFromPrompt("Test y/n", "y");
        boolean test = true;
        if (isTest.equalsIgnoreCase("n")) {
            test = false;
        }

        boolean initial = true;
        /*
         String isInitial = readFromPrompt("Initial Load y/n", "n");
         if (isInitial.equalsIgnoreCase("n")) {
         initial = false;
         }
         */

        String tnp = readFromPrompt("Tablename Pattern: ", "");

        //GenericTableLoader gtl = new TableLoader(test, initial);
        //gtl.loadIt(tnp);
        System.exit(0);
    }

    /* read from commandline
     *
     * 1st parameter as displaytext
     * 2nd parameter as defaultvalue
     */
    public static String readFromPrompt(String text, String defValue) {
        String fromPrompt = null;
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        System.out.print(text + " (Default: " + defValue + ") ");
        try {
            fromPrompt = br.readLine();
            if (fromPrompt.length() < 1) {
                fromPrompt = defValue;
            }
        } catch (IOException ioe) {
            fromPrompt = defValue;
        }
        return fromPrompt;
    }

    private String getInfo() {
        return "Info";
    }

    /*
     private void print() {
     System.out.println("Generic Loader");
     System.out.println("==============");
     System.out.println(getInfo());
     for (int i = 0; i < tableNames.size(); i++) {
     setTable(tableNames.get(i));

     System.out.println("Tabelle: " + tableNames.get(i));
     System.out.println("-------");
     System.out.println("ITSM8-Select-Statement: " + getITSMreadStatement(tableNames.get(i)) + "\r\n");
     System.out.println("Create Table Statement: " + getCreateStatement(tableNames.get(i)) + "\r\n");
     System.out.println("Insert PreparedStatement: " + getInsertPreparedStatement(dwhConnection.getDatabase(), dwhConnection.getSchema(), tableNames.get(i), dwhConnection.getCon()));
     System.out.println("Update PreparedStatement: " + getUpdatePreparedStatement(dwhConnection.getDatabase(), dwhConnection.getSchema(), tableNames.get(i), dwhConnection.getCon()));
     }
     }

     */
    int colType;

    //private void processData(String table, DWHConnection dwhConnection, ITSM8ocrSnapshotConnection itsmConnection) {
    private void processData(String table) {

        System.out.println("Processing " + table);

        String updateOderInsert = "";

        PreparedStatement insert;
        PreparedStatement update;
        PreparedStatement check;
        PreparedStatement work; // dieses wird für den Ablauf benötigt

        int insertCounter = 0;
        int updateCounter = 0;

        // schreiben der Info
        //LoaderInfoWriter loaderInfoWriter = new LoaderInfoWriter(table);
        //LoaderErrorWriter loaderErrorWriter = new LoaderErrorWriter(table, loaderInfoWriter.loaderInfo.getLoadDatum());
        String aktuellerDatensatz = "";

        boolean isUpdate = false;

        // loesche die Tabelle, bei einem Initialen Load
        if (isInitial()) {
            dropTable(table);
        }

        // falls die Tabelle nicht da ist, wird sie nun erstellt
        createTable(table);
        colType = 0;

        try {

            // initalisieren der Prepared Statements Source
            insert = destinationConnection.prepareStatement(getInsertPreparedStatement(getDestDb(), getDestSchema(), table, destinationConnection));
            //update = destinationConnection.prepareStatement(getUpdatePreparedStatement(getDestDb(), getDestSchema(), table, destinationConnection));
            //check = destinationConnection.prepareStatement(getCheckStatement(table));

            work = insert;

            // die Abfrage ans ITSM8
            String sql = getReadStatement(table);
            ResultSet rs = sourceConnection.createStatement().executeQuery(sql);

            // Informationen zur Abfrage im ITSM
            ResultSetMetaData rsmd;
            rsmd = rs.getMetaData();
            int numberOfColumns = rsmd.getColumnCount();

            while (rs.next()) {

                // prüfen, ob der Datensatz bereits existiert
                // wird nicht benötigt, da wir eh einen Initial Load fahren
                /*
                 check.setString(1, rs.getString(1));
                 aktuellerDatensatz = rs.getString(1);

                 ResultSet res = check.executeQuery();
                 res.next();
                 if (res.getInt(1) > 0) {
                 updateOderInsert = "update";
                 isUpdate = true;
                 work = update;

                 if (++updateCounter % getCHUNKSIZE() == 0) {
                 System.out.print(table + ": Update der naechsten " + getCHUNKSIZE() + " Datensaetze ");
                 update.executeBatch();
                 System.out.println(table + ": " + updateCounter + " Datensaetze upgedated\r\n");
                 }

                 } else {
                 updateOderInsert = "insert";
                 isUpdate = false;
                 work = insert;

                 if (++insertCounter % getCHUNKSIZE() == 0) {
                 System.out.println(table + ": Insert der naechsten " + getCHUNKSIZE() + " Datensaetze ");
                 insert.executeBatch();
                 System.out.print(table + " " + insertCounter + " Datensaetze inserted\r\n");
                 }
                 }
                 */
                updateOderInsert = "insert";
                isUpdate = false;
                work = insert;

                if (++insertCounter % getCHUNKSIZE() == 0) {
                    System.out.println(table + ": Insert der naechsten " + getCHUNKSIZE() + " Datensaetze ");
                    insert.executeBatch();
                    System.out.print(table + " " + insertCounter + " Datensaetze inserted\r\n");
                }

                // Verarbeiten des Datensatzes
                int i = 0;
                int j = 0;
                int fieldLength = 0;
                boolean typFound = true;

                try {
                    for (j = 0; j < (numberOfColumns); j++) {
                        i++;

                        typFound = false;

                        // wie lange ist dieses Feld? Muss geprüft werden, damit das mit den Datenlänge passt
                        // welcher DatenTyp ist gefragt?
                        colType = rsmd.getColumnType(i);

                        if (colType == java.sql.Types.CHAR) {
                            work.setString(i, rs.getString(i));
                            typFound = true;
                        }
                        if (colType == java.sql.Types.VARCHAR) {

                            try {
                                work.setString(i, rs.getString(i));
                                typFound = true;
                            } catch (SQLException e) {

                            }
                            typFound = true;
                        }

                        if (colType == java.sql.Types.BINARY) {
                            work.setString(i, rs.getString(i));
                            typFound = true;

                        }
                        if (colType == java.sql.Types.LONGVARBINARY) {
                            work.setString(i, rs.getString(i));
                            typFound = true;
                        }
                        if (colType == java.sql.Types.VARBINARY) {
                            work.setString(i, rs.getString(i));
                            typFound = true;
                        }
                        if (colType == java.sql.Types.TIME) {

                            // die Zeit wird als GMT gespeichert, wie sie aus dem ITSM kommt
                            work.setTimestamp(i, rs.getTimestamp(i));
                            typFound = true;

                            // vielleicht ein NULL Wert?
                            if ((rs.wasNull()) && (rsmd.isNullable(i) == ResultSetMetaData.columnNullable)) {
                                work.setNull(i, colType);
                            }
                        }
                        if (colType == java.sql.Types.DATE) {
                            work.setDate(i, rs.getDate(i));

                            // vielleicht ein NULL Wert?
                            if ((rs.wasNull()) && (rsmd.isNullable(i) == ResultSetMetaData.columnNullable)) {
                                work.setNull(i, colType);
                            }
                            typFound = true;
                        }
                        if (colType == java.sql.Types.TIMESTAMP) {
                            // die Zeit wird als GMT gespeichert, wie sie aus dem ITSM kommt
                            work.setTimestamp(i, rs.getTimestamp(i));
                            // vielleicht ein NULL Wert?
                            if ((rs.wasNull()) && (rsmd.isNullable(i) == ResultSetMetaData.columnNullable)) {
                                work.setNull(i, colType);
                            }

                            typFound = true;
                        }
                        if (colType == java.sql.Types.INTEGER) {
                            work.setInt(i, rs.getInt(i));

                            // vielleicht ein NULL Wert?
                            if ((rs.wasNull()) && (rsmd.isNullable(i) == ResultSetMetaData.columnNullable)) {
                                work.setNull(i, colType);
                            }

                            typFound = true;
                        }
                        if (colType == java.sql.Types.NUMERIC) {
                            work.setFloat(i, rs.getFloat(i));
                            // vielleicht ein NULL Wert?
                            if ((rs.wasNull()) && (rsmd.isNullable(i) == ResultSetMetaData.columnNullable)) {
                                work.setNull(i, colType);
                            }
                            typFound = true;
                        }
                        if (colType == java.sql.Types.DOUBLE) {
                            work.setDouble(i, rs.getDouble(i));
                            // vielleicht ein NULL Wert?
                            if ((rs.wasNull()) && (rsmd.isNullable(i) == ResultSetMetaData.columnNullable)) {
                                work.setNull(i, colType);
                            }
                            typFound = true;
                        }
                        if (colType == java.sql.Types.FLOAT) {
                            work.setFloat(i, rs.getFloat(i));
                            // vielleicht ein NULL Wert?
                            if ((rs.wasNull()) && (rsmd.isNullable(i) == ResultSetMetaData.columnNullable)) {
                                work.setNull(i, colType);
                            }
                            typFound = true;
                        }
                        if (colType == java.sql.Types.BIGINT) {
                            work.setInt(i, rs.getInt(i));
                            typFound = true;

                        }
                        if (colType == java.sql.Types.BIT) {
                            work.setInt(i, rs.getInt(i));
                            // vielleicht ein NULL Wert?
                            if ((rs.wasNull()) && (rsmd.isNullable(i) == ResultSetMetaData.columnNullable)) {
                                work.setNull(i, colType);
                            }
                            typFound = true;

                        }

                        if (colType == java.sql.Types.BLOB) {
                            work.setString(i, rs.getString(i));
                            typFound = true;

                        }
                        if (colType == java.sql.Types.CLOB) {
                            work.setString(i, rs.getString(i));
                            typFound = true;

                        }
                        if (colType == java.sql.Types.DECIMAL) {
                            work.setFloat(i, rs.getFloat(i));
                            // vielleicht ein NULL Wert?
                            if ((rs.wasNull()) && (rsmd.isNullable(i) == ResultSetMetaData.columnNullable)) {
                                work.setNull(i, colType);
                            }
                            typFound = true;

                        }
                        if (colType == java.sql.Types.OTHER) {
                            work.setString(i, rs.getString(i));
                            typFound = true;
                        }

                        if (!typFound) {
                            try {
                                work.setObject(i, rs.getObject(i));
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }

                    }

                    // wir haben alle Felder geschafft und speichern nun den Datensatz
                    if (isUpdate) {
                        work.setString(rsmd.getColumnCount() + 1, rs.getString(1));
                    }
                    work.addBatch();

                } catch (SQLException einSatzAusnahme) {
                    logger.log(Level.INFO, "SQL Type: {0}", colType);
                    logger.log(Level.WARNING, "Error when processing table {0}  on {1} Message {2}", new Object[]{table, updateOderInsert, einSatzAusnahme.getMessage()});
                    logger.log(Level.INFO, " Row has not been processed");
                    //loaderErrorWriter.write(aktuellerDatensatz, einSatzAusnahme.getMessage(), "loader.TableLoader.processData(" + table + ")");
                }

            }

            // alle Datensaetze sind durch, schreiben des restlichen Batchlaufs
            // update.executeBatch();
            // System.out.print(table + ": " + updateCounter + " rows upgedated\r\n");
            insert.executeBatch();
            System.out.print(table + ": " + insertCounter + " rows inserted\r\n");

            //loaderInfoWriter.write(insertCounter, updateCounter);
            //loaderInfoWriter.close();
            insert.close();
            //update.close();

            //itsmConnection.close();
            //dwhConnection.close();
            System.out.println("table: " + table + " finished, DB things closed");

        } catch (SQLException sqlex) {
            logger.log(Level.INFO, "SQL Type: {0}", colType);
            logger.log(Level.WARNING, "Error when processing table {0}  at {1} message {2}", new Object[]{table, updateOderInsert, sqlex.getMessage()});
            sqlex.printStackTrace();
            ///loaderErrorWriter.write(aktuellerDatensatz, sqlex.getMessage(), "loader.TableLoader.processData(" + table + ")");
        }

    }

    protected void finalize() {
        close();
    }

    private void close() {

        try {
            sourceConnection.close();
            destinationConnection.close();
        } catch (SQLException ex) {
            Logger.getLogger(TableLoader.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private ArrayList<TabellenSpalteInfo> getTableInfo() {
        return spalten;
    }

    private void createTable(String table) {
        String sql = getCreateStatement(table);

        try {
            destinationConnection.createStatement().executeUpdate(sql);
            logger.log(Level.INFO, "Table " + table + " created.");
        } catch (SQLException sqlex) {
            logger.log(Level.WARNING, "Error when creating table {0} {1}", new Object[]{table, sqlex.getMessage()});
            logger.log(Level.INFO, sql);
        }

    }

    private void dropTable(String table) {
        String sql = "drop table " + table;

        try {

            //dwhConnection.getStmt().executeUpdate(sql);
            //logger.log(Level.INFO, "Tabelle " + table + " truncated.");
            destinationConnection.createStatement().executeUpdate(sql);
            logger.log(Level.INFO, "Table " + table + " dropped.");

        } catch (SQLException sqlex) {
            logger.log(Level.WARNING, "Error while dropping table {0} {1}", new Object[]{table, sqlex.getMessage()});
            logger.log(Level.INFO, sql);
        }

    }

    /*
     Hier werden die Informationen zu denITSM-Tabellen abgeholt, die in der Variablen tableNamePattern enthalten sind.
     */
    private void createTableInfo() {
        spalten = new ArrayList();
        tableNames = new ArrayList();
        String[] tableTypes = {"TABLE", "VIEW", "ALIAS", "SYNONYM"};
        String tableName = "";
        TabellenSpalteInfo tsi;

        try {

            // welche Tabellen suchen wir?
            sourceDmd = sourceConnection.getMetaData();
            ResultSet rs = sourceDmd.getTables(getSrcDb(), getSrcSchema(), getTableNamePattern(), tableTypes);

            while (rs.next()) {

                tableName = rs.getString(3);
                tableNames.add(tableName);

                // und jetzt die einzelnen Spalten dieser Tabelle
                ResultSet rsTable = sourceDmd.getColumns(getSrcDb(), getSrcSchema(), tableName, "%");
                while (rsTable.next()) {
                    tsi = new TabellenSpalteInfo();

                    tsi.setDatabase(rsTable.getString(1));
                    tsi.setSchema(rsTable.getString(2));
                    tsi.setTabelle(rsTable.getString(3));
                    tsi.setName("\"" + rsTable.getString(4) + "\"");
                    tsi.setDataType(rsTable.getInt(5));
                    tsi.setType(rsTable.getString(6));
                    if (tsi.getType().equalsIgnoreCase("datetime")) {
                        tsi.setType("TIMESTAMP");
                    }
                    if (tsi.getType().equalsIgnoreCase("text")) {
                        tsi.setType("CLOB");
                    }
                    if (tsi.getType().equalsIgnoreCase("nvarchar")) {
                        tsi.setType("varchar");
                    }
                    tsi.setLength(rsTable.getInt(7));
                    tsi.setDecimalDigits(rsTable.getInt(9));

                    if (rsTable.getString(18).equalsIgnoreCase("yes")) {
                        tsi.setNullAllowed(true);
                    } else {
                        tsi.setNullAllowed(false);
                    }

                    try {
                        if (rsTable.getString(23).equalsIgnoreCase("yes")) {
                            tsi.setAutoIncrement(true);
                        } else {
                            tsi.setAutoIncrement(false);
                        }
                    } catch (Exception e) {
                        tsi.setAutoIncrement(false);
                    }

                    tsi.setKey("");  // not used
                    tsi.setExportedKeys("");  // not used

                    spalten.add(tsi);

                }
                rsTable.close();
            }
            rs.close();
        } catch (SQLException sqlex) {
            logger.log(Level.WARNING, "Error while reading table information for {0} Exception: {1}", new Object[]{tableName, sqlex.getMessage()});
        }

    }

    private String getReadStatement(String table) {

        // falls wir keinen Inital Load durchführen, bereite das WhereStatement vor
        if (!isInitial()) {
            // prepareIncremental(table);
        }

        StringBuilder sb = new StringBuilder();
        String s = "  "; // der Abstand am Anfang der Zeile
        boolean first = true;

        sb.append("select ");
        if (isTEST()) {
            sb.append("top 1 ");  // im Testlauf werden nur 5 Datensaetze verarbeitet
        }
        sb.append("\r\n");

        TabellenSpalteInfo tsi = new TabellenSpalteInfo();
        Iterator<TabellenSpalteInfo> iterator = spalten.listIterator();
        String aktuelleTabelle = "";

        while (iterator.hasNext()) {
            tsi = iterator.next();

            // nur für die aktuelle Tabelle
            if (tsi.getTabelle().equalsIgnoreCase(table)) {

                // beim ersten Durchgang setzen wir die aktuelle Tabelle
                if (first) {
                    first = false;
                    aktuelleTabelle = tsi.getName();
                } else {
                    sb.append(", \r\n");
                }

                sb.append(s).append(tsi.getName());

            }
        }
        sb.append("\r\nfrom ").append(table);
        sb.append(getWhereStatement(table));
        return sb.toString();
    }

    /*
     Ueberschreibe diese Methode, falls du eine spezifische Tabelle mit einer spezifischen WHERE-Klausel versehen moechtest
     */
    String whereStatement = "";

    public String getWhereStatement(String table) {
        return whereStatement;
    }

    public void setWhereStatement(String v) {
        whereStatement = v;
    }

    private String getCreateStatement(String table) {
        StringBuilder sb = new StringBuilder();
        String fieldType = "";
        sb.append("CREATE TABLE ").append(table).append("( \r\n");

        // wir machen den DGI-OCR Key
        TabellenSpalteInfo tsi = new TabellenSpalteInfo();
        tsi = spalten.get(0);
        int pkLength = 15 + tsi.getLength();

        for (int i = 0; i < spalten.size(); i++) {

            if (i > 0) {
                sb.append(", \r\n");
            }

            tsi = new TabellenSpalteInfo();
            tsi = spalten.get(i);

            if (tsi.getTabelle().equalsIgnoreCase(table)) {
                sb.append("   ").append((String) tsi.getName()).append(" ");  // Attribute Name

                // Attribute Type and MS SQL Server AUTO_Increment speciality
                fieldType = (String) tsi.getType();

                if (fieldType.equals("int identity")) {
                    sb.append("int");
                } else {
                    sb.append(fieldType);  // Attribute Type
                }

                boolean useLength = true;
                if (fieldType.toLowerCase().equals("text")) {
                    useLength = false;
                }
                if (fieldType.toLowerCase().equals("clob")) {
                    useLength = false;
                }

                if (fieldType.toLowerCase().equals("image")) {
                    useLength = false;
                }

                if (fieldType.toLowerCase().equals("int")) {
                    useLength = false;
                }
                if (fieldType.toLowerCase().equals("integer")) {
                    useLength = false;
                }
                if (fieldType.toLowerCase().equals("datetime")) {
                    fieldType = "TIMESTAMP";
                    useLength = false;
                }

                if (fieldType.toLowerCase().equals("timestamp")) {
                    useLength = false;
                }
                if (fieldType.toLowerCase().equals("date")) {
                    useLength = false;
                }
                if (fieldType.toLowerCase().startsWith("int")) {
                    useLength = false;
                }

                if (fieldType.toLowerCase().equalsIgnoreCase("tinyint")) {
                    useLength = false;
                }
                if (fieldType.toLowerCase().equalsIgnoreCase("smallint")) {
                    useLength = false;
                }

                 if (fieldType.toLowerCase().equalsIgnoreCase("float")) {
                    useLength = false;
                }
                if (fieldType.toLowerCase().equals("decimal")) {
                    useLength = false;
                    sb.append("(").append(Integer.toString(tsi.getLength())).append(",").append(Integer.toString(tsi.getDecimalDigits())).append(")");
                }

                 if (fieldType.toLowerCase().equalsIgnoreCase("time")) {
                    useLength = false;
                }

                if (((int) tsi.getLength()) < 1) {
                    useLength = false;
                }

                if (useLength) {
                    sb.append("(").append((new Integer((int) tsi.getLength())).toString()).append(") "); // Size
                } else {
                    sb.append(" ");
                }
                if (!(boolean) tsi.isNullAllowed()) {
                    sb.append("NOT NULL");  // null not allowed
                }

                // if MS SQL Server Auto_increment
                if (fieldType.equals("int identity")) {
                    //sb.append(" IDENTITY(1,1)");

                    // Derby specific
                    //sb.append(" GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1) ");
                }

                //sb.append(",\r\n");
            }
        }

        // und jetzt noch den Primary Key fuer DGI_Reporting_ID
        //sb.append(",\r\n");
        //sb.append("   ").append("PRIMARY KEY (DGI_Reporting_ID)");
        sb.append("\r\n)\r\n");
        return sb.toString();
    }

    private ArrayList<String> getColumns(String db, String schema, String table, Connection c) {
        ArrayList<String> tables = new ArrayList();
        String[] tableTypes = {"TABLE", "VIEW", "ALIAS", "SYNONYM"};

        try {

            String colPattern = "%";
            ResultSet rs = dmd.getColumns(null, null, table, null);
            while (rs.next()) {
                tables.add((String) rs.getString(4));
            }
        } catch (SQLException sqlex) {
            logger.log(Level.WARNING, "Error while while fetching metadata : {0}", sqlex.getMessage());
        }
        return tables;
    }

    /*
     lies die Primary Keys dieser Tabelle
     */
    private ArrayList<String> getPrimaryKeys(String db, String schema, String table, Connection c) {
        ArrayList<String> pk = new ArrayList();

        try {
            ResultSet rs = dmd.getPrimaryKeys(db, schema, table);
            while (rs.next()) {
                pk.add((String) rs.getString(4));
            }
        } catch (SQLException sqlex) {
            logger.log(Level.WARNING, "Error while while fetching primary keys : {0}", sqlex.getMessage());
        }

        return pk;
    }

    private String getPrimaryKey(String db, String schema, String table, Connection c) {
        StringBuilder sb = new StringBuilder();
        ArrayList<String> pk = getPrimaryKeys(db, schema, table, c);

        boolean found = false;
        for (int i = 0; i < pk.size(); i++) {

            if (i == 0) {
                sb.append("\r\nwhere ").append((String) pk.get(i)).append(" = ? ");
                found = true;
            } else {
                sb.append("\r\nand ").append((String) pk.get(i)).append(" = ? ");
            }
        }

        if (!found) {
            sb.append("where -- please add here your condition to identify this row exactly --");
        }
        return sb.toString();
    }

    private String getInsertPreparedStatement(String db, String schema, String table, Connection c) {

        ArrayList<String> al = getColumns(db, schema, table, c);

        StringBuilder sb = new StringBuilder();
        StringBuilder sb1 = new StringBuilder();

        sb.append("insert into ").append(table).append(" ( \r\n");
        for (int i = 0; i < spalten.size(); i++) {
            TabellenSpalteInfo tsi = spalten.get(i);
            sb.append(" ").append((String) tsi.getName());  // Attribute Name

            if (i < spalten.size() - 1) {
                sb.append(" ,\r\n");
            } else {
                sb.append("\r\n");
            }

            if (i > 0) {
                sb1.append(",");
            }
            sb1.append("?");
        }
        sb.append(") values \r\n( ").append(sb1.toString()).append(" )");
        return sb.toString();
    }

    public String getUpdatePreparedStatement(String db, String schema, String table, Connection c) {
        StringBuilder sb = new StringBuilder();
        ArrayList<String> al = getColumns(db, schema, table, c);

        sb.append("update ").append(table).append(" set \r\n");
        for (int i = 0; i < al.size(); i++) {
            sb.append(" ").append((String) al.get(i)).append(" = ? ");  // Attribute Name
            if (i < al.size() - 1) {
                sb.append(",\r\n");
            }
        }
        sb.append(getPrimaryKey(db, schema, table, c));

        return sb.toString();

    }

    public String getCheckStatement(String table) {
        return "";
    }

    /**
     * @return the table
     */
    public String getTable() {
        return table;
    }

    /**
     * @param table the table to set
     */
    public void setTable(String table) {
        this.table = table;
    }

    /**
     * @return the tableNamePattern
     */
    public String getTableNamePattern() {
        return tableNamePattern;
    }

    /**
     * @param tableNamePattern the tableNamePattern to set
     */
    public void setTableNamePattern(String tableNamePattern) {
        this.tableNamePattern = tableNamePattern;
    }

    /**
     * @return the TEST
     */
    public boolean isTEST() {
        return TEST;
    }

    /**
     * @param TEST the TEST to set
     */
    public void setTEST(boolean TEST) {
        this.TEST = TEST;
    }

    /**
     * @return the CHUNKSIZE
     */
    public int getCHUNKSIZE() {
        return CHUNKSIZE;
    }

    /**
     * @param CHUNKSIZE the CHUNKSIZE to set
     */
    public void setCHUNKSIZE(int CHUNKSIZE) {
        this.CHUNKSIZE = CHUNKSIZE;
    }

    /**
     * @return the initial
     */
    public boolean isInitial() {
        return initial;
    }

    /**
     * @param initial the initial to set
     */
    public void setInitial(boolean initial) {
        this.initial = initial;
    }

    /**
     * @return the sourceConnection
     */
    public Connection getSourceConnection() {
        return sourceConnection;
    }

    /**
     * @param sourceConnection the sourceConnection to set
     */
    public void setSourceConnection(Connection sourceConnection) {
        this.sourceConnection = sourceConnection;
    }

    /**
     * @return the destinationConnection
     */
    public Connection getDestinationConnection() {
        return destinationConnection;
    }

    /**
     * @param destinationConnection the destinationConnection to set
     */
    public void setDestinationConnection(Connection destinationConnection) {
        this.destinationConnection = destinationConnection;
    }

    /**
     * @return the srcDb
     */
    public String getSrcDb() {
        return srcDb;
    }

    /**
     * @param srcDb the srcDb to set
     */
    public void setSrcDb(String srcDb) {
        this.srcDb = srcDb;
    }

    /**
     * @return the destDb
     */
    public String getDestDb() {
        return destDb;
    }

    /**
     * @param destDb the destDb to set
     */
    public void setDestDb(String destDb) {
        this.destDb = destDb;
    }

    /**
     * @return the srcSchema
     */
    public String getSrcSchema() {
        return srcSchema;
    }

    /**
     * @param srcSchema the srcSchema to set
     */
    public void setSrcSchema(String srcSchema) {
        this.srcSchema = srcSchema;
    }

    /**
     * @return the destSchema
     */
    public String getDestSchema() {
        return destSchema;
    }

    /**
     * @param destSchema the destSchema to set
     */
    public void setDestSchema(String destSchema) {
        this.destSchema = destSchema;
    }

}


text:
#include <aws/codeartifact/model/PackageVersionDescription.h>
#include <aws/core/utils/json/JsonSerializer.h>

#include <utility>

using namespace Aws::Utils::Json;
using namespace Aws::Utils;

namespace Aws
{
namespace CodeArtifact
{
namespace Model
{

PackageVersionDescription::PackageVersionDescription() :
    m_format(PackageFormat::NOT_SET),
    m_formatHasBeenSet(false),
    m_namespaceHasBeenSet(false),
    m_packageNameHasBeenSet(false),
    m_displayNameHasBeenSet(false),
    m_versionHasBeenSet(false),
    m_summaryHasBeenSet(false),
    m_homePageHasBeenSet(false),
    m_sourceCodeRepositoryHasBeenSet(false),
    m_publishedTimeHasBeenSet(false),
    m_licensesHasBeenSet(false),
    m_revisionHasBeenSet(false),
    m_status(PackageVersionStatus::NOT_SET),
    m_statusHasBeenSet(false),
    m_originHasBeenSet(false)
{
}

PackageVersionDescription::PackageVersionDescription(JsonView jsonValue) :
    m_format(PackageFormat::NOT_SET),
    m_formatHasBeenSet(false),
    m_namespaceHasBeenSet(false),
    m_packageNameHasBeenSet(false),
    m_displayNameHasBeenSet(false),
    m_versionHasBeenSet(false),
    m_summaryHasBeenSet(false),
    m_homePageHasBeenSet(false),
    m_sourceCodeRepositoryHasBeenSet(false),
    m_publishedTimeHasBeenSet(false),
    m_licensesHasBeenSet(false),
    m_revisionHasBeenSet(false),
    m_status(PackageVersionStatus::NOT_SET),
    m_statusHasBeenSet(false),
    m_originHasBeenSet(false)
{
  *this = jsonValue;
}

PackageVersionDescription& PackageVersionDescription::operator =(JsonView jsonValue)
{
  if(jsonValue.ValueExists("format"))
  {
    m_format = PackageFormatMapper::GetPackageFormatForName(jsonValue.GetString("format"));

    m_formatHasBeenSet = true;
  }

  if(jsonValue.ValueExists("namespace"))
  {
    m_namespace = jsonValue.GetString("namespace");

    m_namespaceHasBeenSet = true;
  }

  if(jsonValue.ValueExists("packageName"))
  {
    m_packageName = jsonValue.GetString("packageName");

    m_packageNameHasBeenSet = true;
  }

  if(jsonValue.ValueExists("displayName"))
  {
    m_displayName = jsonValue.GetString("displayName");

    m_displayNameHasBeenSet = true;
  }

  if(jsonValue.ValueExists("version"))
  {
    m_version = jsonValue.GetString("version");

    m_versionHasBeenSet = true;
  }

  if(jsonValue.ValueExists("summary"))
  {
    m_summary = jsonValue.GetString("summary");

    m_summaryHasBeenSet = true;
  }

  if(jsonValue.ValueExists("homePage"))
  {
    m_homePage = jsonValue.GetString("homePage");

    m_homePageHasBeenSet = true;
  }

  if(jsonValue.ValueExists("sourceCodeRepository"))
  {
    m_sourceCodeRepository = jsonValue.GetString("sourceCodeRepository");

    m_sourceCodeRepositoryHasBeenSet = true;
  }

  if(jsonValue.ValueExists("publishedTime"))
  {
    m_publishedTime = jsonValue.GetDouble("publishedTime");

    m_publishedTimeHasBeenSet = true;
  }

  if(jsonValue.ValueExists("licenses"))
  {
    Aws::Utils::Array<JsonView> licensesJsonList = jsonValue.GetArray("licenses");
    for(unsigned licensesIndex = 0; licensesIndex < licensesJsonList.GetLength(); ++licensesIndex)
    {
      m_licenses.push_back(licensesJsonList[licensesIndex].AsObject());
    }
    m_licensesHasBeenSet = true;
  }

  if(jsonValue.ValueExists("revision"))
  {
    m_revision = jsonValue.GetString("revision");

    m_revisionHasBeenSet = true;
  }

  if(jsonValue.ValueExists("status"))
  {
    m_status = PackageVersionStatusMapper::GetPackageVersionStatusForName(jsonValue.GetString("status"));

    m_statusHasBeenSet = true;
  }

  if(jsonValue.ValueExists("origin"))
  {
    m_origin = jsonValue.GetObject("origin");

    m_originHasBeenSet = true;
  }

  return *this;
}

JsonValue PackageVersionDescription::Jsonize() const
{
  JsonValue payload;

  if(m_formatHasBeenSet)
  {
   payload.WithString("format", PackageFormatMapper::GetNameForPackageFormat(m_format));
  }

  if(m_namespaceHasBeenSet)
  {
   payload.WithString("namespace", m_namespace);

  }

  if(m_packageNameHasBeenSet)
  {
   payload.WithString("packageName", m_packageName);

  }

  if(m_displayNameHasBeenSet)
  {
   payload.WithString("displayName", m_displayName);

  }

  if(m_versionHasBeenSet)
  {
   payload.WithString("version", m_version);

  }

  if(m_summaryHasBeenSet)
  {
   payload.WithString("summary", m_summary);

  }

  if(m_homePageHasBeenSet)
  {
   payload.WithString("homePage", m_homePage);

  }

  if(m_sourceCodeRepositoryHasBeenSet)
  {
   payload.WithString("sourceCodeRepository", m_sourceCodeRepository);

  }

  if(m_publishedTimeHasBeenSet)
  {
   payload.WithDouble("publishedTime", m_publishedTime.SecondsWithMSPrecision());
  }

  if(m_licensesHasBeenSet)
  {
   Aws::Utils::Array<JsonValue> licensesJsonList(m_licenses.size());
   for(unsigned licensesIndex = 0; licensesIndex < licensesJsonList.GetLength(); ++licensesIndex)
   {
     licensesJsonList[licensesIndex].AsObject(m_licenses[licensesIndex].Jsonize());
   }
   payload.WithArray("licenses", std::move(licensesJsonList));

  }

  if(m_revisionHasBeenSet)
  {
   payload.WithString("revision", m_revision);

  }

  if(m_statusHasBeenSet)
  {
   payload.WithString("status", PackageVersionStatusMapper::GetNameForPackageVersionStatus(m_status));
  }

  if(m_originHasBeenSet)
  {
   payload.WithObject("origin", m_origin.Jsonize());

  }

  return payload;
}

} // namespace Model
} // namespace CodeArtifact
} // namespace Aws


text:
require 'rails_helper'
require 'factory_girl_rails'

describe User do
  describe 'Normal user creation' do

    it "should create a new User that isn't an admin" do
      user = build(:user)
      expect(user.admin?).to be false
    end

  end

  describe 'Admin user creation' do
    it 'should create an admin user' do
      user = build(:admin)
      expect(user.admin?).to be true
    end
  end

end