text:
package describe

import (
	"bytes"
	"fmt"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"text/tabwriter"
	"time"

	"github.com/docker/docker/pkg/parsers"
	"github.com/docker/docker/pkg/units"

	kapi "k8s.io/kubernetes/pkg/api"
	kerrs "k8s.io/kubernetes/pkg/api/errors"
	"k8s.io/kubernetes/pkg/api/meta"
	"k8s.io/kubernetes/pkg/api/unversioned"
	kclient "k8s.io/kubernetes/pkg/client/unversioned"
	kctl "k8s.io/kubernetes/pkg/kubectl"
	"k8s.io/kubernetes/pkg/runtime"
	"k8s.io/kubernetes/pkg/util/sets"

	authorizationapi "github.com/openshift/origin/pkg/authorization/api"
	buildapi "github.com/openshift/origin/pkg/build/api"
	"github.com/openshift/origin/pkg/client"
	deployapi "github.com/openshift/origin/pkg/deploy/api"
	imageapi "github.com/openshift/origin/pkg/image/api"
	oauthapi "github.com/openshift/origin/pkg/oauth/api"
	projectapi "github.com/openshift/origin/pkg/project/api"
	routeapi "github.com/openshift/origin/pkg/route/api"
	templateapi "github.com/openshift/origin/pkg/template/api"
	userapi "github.com/openshift/origin/pkg/user/api"
)

func describerMap(c *client.Client, kclient kclient.Interface, host string) map[unversioned.GroupKind]kctl.Describer {
	m := map[unversioned.GroupKind]kctl.Describer{
		buildapi.Kind("Build"):                        &BuildDescriber{c, kclient},
		buildapi.Kind("BuildConfig"):                  &BuildConfigDescriber{c, host},
		deployapi.Kind("DeploymentConfig"):            &DeploymentConfigDescriber{c, kclient, nil},
		authorizationapi.Kind("Identity"):             &IdentityDescriber{c},
		imageapi.Kind("Image"):                        &ImageDescriber{c},
		imageapi.Kind("ImageStream"):                  &ImageStreamDescriber{c},
		imageapi.Kind("ImageStreamTag"):               &ImageStreamTagDescriber{c},
		imageapi.Kind("ImageStreamImage"):             &ImageStreamImageDescriber{c},
		routeapi.Kind("Route"):                        &RouteDescriber{c, kclient},
		projectapi.Kind("Project"):                    &ProjectDescriber{c, kclient},
		templateapi.Kind("Template"):                  &TemplateDescriber{c, meta.NewAccessor(), kapi.Scheme, nil},
		authorizationapi.Kind("Policy"):               &PolicyDescriber{c},
		authorizationapi.Kind("PolicyBinding"):        &PolicyBindingDescriber{c},
		authorizationapi.Kind("RoleBinding"):          &RoleBindingDescriber{c},
		authorizationapi.Kind("Role"):                 &RoleDescriber{c},
		authorizationapi.Kind("ClusterPolicy"):        &ClusterPolicyDescriber{c},
		authorizationapi.Kind("ClusterPolicyBinding"): &ClusterPolicyBindingDescriber{c},
		authorizationapi.Kind("ClusterRoleBinding"):   &ClusterRoleBindingDescriber{c},
		authorizationapi.Kind("ClusterRole"):          &ClusterRoleDescriber{c},
		oauthapi.Kind("OAuthAccessToken"):             &OAuthAccessTokenDescriber{c},
		userapi.Kind("User"):                          &UserDescriber{c},
		userapi.Kind("Group"):                         &GroupDescriber{c.Groups()},
		userapi.Kind("UserIdentityMapping"):           &UserIdentityMappingDescriber{c},
	}
	return m
}

// DescribableResources lists all of the resource types we can describe
func DescribableResources() []string {
	// Include describable resources in kubernetes
	keys := kctl.DescribableResources()

	for k := range describerMap(nil, nil, "") {
		resource := strings.ToLower(k.Kind)
		keys = append(keys, resource)
	}
	return keys
}

// DescriberFor returns a describer for a given kind of resource
func DescriberFor(kind unversioned.GroupKind, c *client.Client, kclient kclient.Interface, host string) (kctl.Describer, bool) {
	f, ok := describerMap(c, kclient, host)[kind]
	if ok {
		return f, true
	}
	return nil, false
}

// BuildDescriber generates information about a build
type BuildDescriber struct {
	osClient   client.Interface
	kubeClient kclient.Interface
}

// Describe returns the description of a build
func (d *BuildDescriber) Describe(namespace, name string) (string, error) {
	c := d.osClient.Builds(namespace)
	build, err := c.Get(name)
	if err != nil {
		return "", err
	}
	events, _ := d.kubeClient.Events(namespace).Search(build)
	if events == nil {
		events = &kapi.EventList{}
	}
	// get also pod events and merge it all into one list for describe
	if pod, err := d.kubeClient.Pods(namespace).Get(buildapi.GetBuildPodName(build)); err == nil {
		if podEvents, _ := d.kubeClient.Events(namespace).Search(pod); podEvents != nil {
			events.Items = append(events.Items, podEvents.Items...)
		}
	}
	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, build.ObjectMeta)

		fmt.Fprintln(out, "")

		status := bold(build.Status.Phase)
		if build.Status.Message != "" {
			status += " (" + build.Status.Message + ")"
		}
		formatString(out, "Status", status)

		if build.Status.StartTimestamp != nil && !build.Status.StartTimestamp.IsZero() {
			formatString(out, "Started", build.Status.StartTimestamp.Time.Format(time.RFC1123))
		}

		// Create the time object with second-level precision so we don't get
		// output like "duration: 1.2724395728934s"
		formatString(out, "Duration", describeBuildDuration(build))

		if build.Status.Config != nil {
			formatString(out, "Build Config", build.Status.Config.Name)
		}
		formatString(out, "Build Pod", buildapi.GetBuildPodName(build))

		describeCommonSpec(build.Spec.CommonSpec, out)
		describeBuildTriggerCauses(build.Spec.TriggeredBy, out)

		kctl.DescribeEvents(events, out)

		return nil
	})
}

func describeBuildDuration(build *buildapi.Build) string {
	t := unversioned.Now().Rfc3339Copy()
	if build.Status.StartTimestamp == nil &&
		build.Status.CompletionTimestamp != nil &&
		(build.Status.Phase == buildapi.BuildPhaseCancelled ||
			build.Status.Phase == buildapi.BuildPhaseFailed ||
			build.Status.Phase == buildapi.BuildPhaseError) {
		// time a build waited for its pod before ultimately being cancelled before that pod was created
		return fmt.Sprintf("waited for %s", build.Status.CompletionTimestamp.Rfc3339Copy().Time.Sub(build.CreationTimestamp.Rfc3339Copy().Time))
	} else if build.Status.StartTimestamp == nil && build.Status.Phase != buildapi.BuildPhaseCancelled {
		// time a new build has been waiting for its pod to be created so it can run
		return fmt.Sprintf("waiting for %v", t.Sub(build.CreationTimestamp.Rfc3339Copy().Time))
	} else if build.Status.StartTimestamp != nil && build.Status.CompletionTimestamp == nil {
		// time a still running build has been running in a pod
		return fmt.Sprintf("running for %v", build.Status.Duration)
	}
	return fmt.Sprintf("%v", build.Status.Duration)
}

// BuildConfigDescriber generates information about a buildConfig
type BuildConfigDescriber struct {
	client.Interface
	host string
}

func nameAndNamespace(ns, name string) string {
	if len(ns) != 0 {
		return fmt.Sprintf("%s/%s", ns, name)
	}
	return name
}

func describeCommonSpec(p buildapi.CommonSpec, out *tabwriter.Writer) {
	formatString(out, "\nStrategy", buildapi.StrategyType(p.Strategy))
	noneType := true
	if p.Source.Git != nil {
		noneType = false
		formatString(out, "URL", p.Source.Git.URI)
		if len(p.Source.Git.Ref) > 0 {
			formatString(out, "Ref", p.Source.Git.Ref)
		}
		if len(p.Source.ContextDir) > 0 {
			formatString(out, "ContextDir", p.Source.ContextDir)
		}
		if p.Source.SourceSecret != nil {
			formatString(out, "Source Secret", p.Source.SourceSecret.Name)
		}
		squashGitInfo(p.Revision, out)
	}
	if p.Source.Dockerfile != nil {
		if len(strings.TrimSpace(*p.Source.Dockerfile)) == 0 {
			formatString(out, "Dockerfile", "")
		} else {
			fmt.Fprintf(out, "Dockerfile:\n")
			for _, s := range strings.Split(*p.Source.Dockerfile, "\n") {
				fmt.Fprintf(out, "  %s\n", s)
			}
		}
	}
	switch {
	case p.Strategy.DockerStrategy != nil:
		describeDockerStrategy(p.Strategy.DockerStrategy, out)
	case p.Strategy.SourceStrategy != nil:
		describeSourceStrategy(p.Strategy.SourceStrategy, out)
	case p.Strategy.CustomStrategy != nil:
		describeCustomStrategy(p.Strategy.CustomStrategy, out)
	case p.Strategy.JenkinsPipelineStrategy != nil:
		describeJenkinsPipelineStrategy(p.Strategy.JenkinsPipelineStrategy, out)
	}

	if p.Output.To != nil {
		formatString(out, "Output to", fmt.Sprintf("%s %s", p.Output.To.Kind, nameAndNamespace(p.Output.To.Namespace, p.Output.To.Name)))
	}

	if p.Source.Binary != nil {
		noneType = false
		if len(p.Source.Binary.AsFile) > 0 {
			formatString(out, "Binary", fmt.Sprintf("provided as file %q on build", p.Source.Binary.AsFile))
		} else {
			formatString(out, "Binary", "provided on build")
		}
	}

	if len(p.Source.Secrets) > 0 {
		result := []string{}
		for _, s := range p.Source.Secrets {
			result = append(result, fmt.Sprintf("%s->%s", s.Secret.Name, filepath.Clean(s.DestinationDir)))
		}
		formatString(out, "Build Secrets", strings.Join(result, ","))
	}
	if len(p.Source.Images) == 1 && len(p.Source.Images[0].Paths) == 1 {
		noneType = false
		image := p.Source.Images[0]
		path := image.Paths[0]
		formatString(out, "Image Source", fmt.Sprintf("copies %s from %s to %s", path.SourcePath, nameAndNamespace(image.From.Namespace, image.From.Name), path.DestinationDir))
	} else {
		for _, image := range p.Source.Images {
			noneType = false
			formatString(out, "Image Source", fmt.Sprintf("%s", nameAndNamespace(image.From.Namespace, image.From.Name)))
			for _, path := range image.Paths {
				fmt.Fprintf(out, "\t- %s -> %s\n", path.SourcePath, path.DestinationDir)
			}
		}
	}

	if noneType {
		formatString(out, "Empty Source", "no input source provided")
	}

	describePostCommitHook(p.PostCommit, out)

	if p.Output.PushSecret != nil {
		formatString(out, "Push Secret", p.Output.PushSecret.Name)
	}

	if p.CompletionDeadlineSeconds != nil {
		formatString(out, "Fail Build After", time.Duration(*p.CompletionDeadlineSeconds)*time.Second)
	}
}

func describePostCommitHook(hook buildapi.BuildPostCommitSpec, out *tabwriter.Writer) {
	command := hook.Command
	args := hook.Args
	script := hook.Script
	if len(command) == 0 && len(args) == 0 && len(script) == 0 {
		// Post commit hook is not set, nothing to do.
		return
	}
	if len(script) != 0 {
		command = []string{"/bin/sh", "-ic"}
		if len(args) > 0 {
			args = append([]string{script, command[0]}, args...)
		} else {
			args = []string{script}
		}
	}
	if len(command) == 0 {
		command = []string{"<image-entrypoint>"}
	}
	all := append(command, args...)
	for i, v := range all {
		all[i] = fmt.Sprintf("%q", v)
	}
	formatString(out, "Post Commit Hook", fmt.Sprintf("[%s]", strings.Join(all, ", ")))
}

func describeSourceStrategy(s *buildapi.SourceBuildStrategy, out *tabwriter.Writer) {
	if len(s.From.Name) != 0 {
		formatString(out, "From Image", fmt.Sprintf("%s %s", s.From.Kind, nameAndNamespace(s.From.Namespace, s.From.Name)))
	}
	if len(s.Scripts) != 0 {
		formatString(out, "Scripts", s.Scripts)
	}
	if s.PullSecret != nil {
		formatString(out, "Pull Secret Name", s.PullSecret.Name)
	}
	if s.Incremental {
		formatString(out, "Incremental Build", "yes")
	}
	if s.ForcePull {
		formatString(out, "Force Pull", "yes")
	}
}

func describeDockerStrategy(s *buildapi.DockerBuildStrategy, out *tabwriter.Writer) {
	if s.From != nil && len(s.From.Name) != 0 {
		formatString(out, "From Image", fmt.Sprintf("%s %s", s.From.Kind, nameAndNamespace(s.From.Namespace, s.From.Name)))
	}
	if len(s.DockerfilePath) != 0 {
		formatString(out, "Dockerfile Path", s.DockerfilePath)
	}
	if s.PullSecret != nil {
		formatString(out, "Pull Secret Name", s.PullSecret.Name)
	}
	if s.NoCache {
		formatString(out, "No Cache", "true")
	}
	if s.ForcePull {
		formatString(out, "Force Pull", "true")
	}
}

func describeCustomStrategy(s *buildapi.CustomBuildStrategy, out *tabwriter.Writer) {
	if len(s.From.Name) != 0 {
		formatString(out, "Image Reference", fmt.Sprintf("%s %s", s.From.Kind, nameAndNamespace(s.From.Namespace, s.From.Name)))
	}
	if s.ExposeDockerSocket {
		formatString(out, "Expose Docker Socket", "yes")
	}
	if s.ForcePull {
		formatString(out, "Force Pull", "yes")
	}
	if s.PullSecret != nil {
		formatString(out, "Pull Secret Name", s.PullSecret.Name)
	}
	for i, env := range s.Env {
		if i == 0 {
			formatString(out, "Environment", formatEnv(env))
		} else {
			formatString(out, "", formatEnv(env))
		}
	}
}

func describeJenkinsPipelineStrategy(s *buildapi.JenkinsPipelineBuildStrategy, out *tabwriter.Writer) {
}

// DescribeTriggers generates information about the triggers associated with a
// buildconfig
func (d *BuildConfigDescriber) DescribeTriggers(bc *buildapi.BuildConfig, out *tabwriter.Writer) {
	describeBuildTriggers(bc.Spec.Triggers, bc.Name, bc.Namespace, out, d)
}

func describeBuildTriggers(triggers []buildapi.BuildTriggerPolicy, name, namespace string, w *tabwriter.Writer, d *BuildConfigDescriber) {
	if len(triggers) == 0 {
		formatString(w, "Triggered by", "<none>")
		return
	}

	labels := []string{}

	for _, t := range triggers {
		switch t.Type {
		case buildapi.GitHubWebHookBuildTriggerType, buildapi.GenericWebHookBuildTriggerType:
			continue
		case buildapi.ConfigChangeBuildTriggerType:
			labels = append(labels, "Config")
		case buildapi.ImageChangeBuildTriggerType:
			if t.ImageChange != nil && t.ImageChange.From != nil && len(t.ImageChange.From.Name) > 0 {
				labels = append(labels, fmt.Sprintf("Image(%s %s)", t.ImageChange.From.Kind, t.ImageChange.From.Name))
			} else {
				labels = append(labels, string(t.Type))
			}
		case "":
			labels = append(labels, "<unknown>")
		default:
			labels = append(labels, string(t.Type))
		}
	}

	desc := strings.Join(labels, ", ")
	formatString(w, "Triggered by", desc)

	webHooks := webHooksDescribe(triggers, name, namespace, d.Interface)
	for webHookType, webHookDesc := range webHooks {
		fmt.Fprintf(w, "Webhook %s:\n", strings.Title(webHookType))
		for _, trigger := range webHookDesc {
			fmt.Fprintf(w, "\tURL:\t%s\n", trigger.URL)
			if webHookType == string(buildapi.GenericWebHookBuildTriggerType) && trigger.AllowEnv != nil {
				fmt.Fprintf(w, fmt.Sprintf("\t%s:\t%v\n", "AllowEnv", *trigger.AllowEnv))
			}
		}
	}
}

// Describe returns the description of a buildConfig
func (d *BuildConfigDescriber) Describe(namespace, name string) (string, error) {
	c := d.BuildConfigs(namespace)
	buildConfig, err := c.Get(name)
	if err != nil {
		return "", err
	}
	buildList, err := d.Builds(namespace).List(kapi.ListOptions{})
	if err != nil {
		return "", err
	}
	buildList.Items = buildapi.FilterBuilds(buildList.Items, buildapi.ByBuildConfigPredicate(name))

	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, buildConfig.ObjectMeta)
		if buildConfig.Status.LastVersion == 0 {
			formatString(out, "Latest Version", "Never built")
		} else {
			formatString(out, "Latest Version", strconv.Itoa(buildConfig.Status.LastVersion))
		}
		describeCommonSpec(buildConfig.Spec.CommonSpec, out)
		formatString(out, "\nBuild Run Policy", string(buildConfig.Spec.RunPolicy))
		d.DescribeTriggers(buildConfig, out)
		if len(buildList.Items) == 0 {
			return nil
		}
		fmt.Fprintf(out, "\nBuild\tStatus\tDuration\tCreation Time\n")

		builds := buildList.Items
		sort.Sort(sort.Reverse(buildapi.BuildSliceByCreationTimestamp(builds)))

		for i, build := range builds {
			fmt.Fprintf(out, "%s \t%s \t%v \t%v\n",
				build.Name,
				strings.ToLower(string(build.Status.Phase)),
				describeBuildDuration(&build),
				build.CreationTimestamp.Rfc3339Copy().Time)
			// only print the 10 most recent builds.
			if i == 9 {
				break
			}
		}
		return nil
	})
}

// OAuthAccessTokenDescriber generates information about an OAuth Acess Token (OAuth)
type OAuthAccessTokenDescriber struct {
	client.Interface
}

func (d *OAuthAccessTokenDescriber) Describe(namespace, name string) (string, error) {
	c := d.OAuthAccessTokens()
	oAuthAccessToken, err := c.Get(name)
	if err != nil {
		return "", err
	}

	var timeCreated time.Time = oAuthAccessToken.ObjectMeta.CreationTimestamp.Time
	var timeExpired time.Time = timeCreated.Add(time.Duration(oAuthAccessToken.ExpiresIn) * time.Second)

	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, oAuthAccessToken.ObjectMeta)
		formatString(out, "Scopes", oAuthAccessToken.Scopes)
		formatString(out, "Expires In", formatToHumanDuration(timeExpired.Sub(time.Now())))
		formatString(out, "User Name", oAuthAccessToken.UserName)
		formatString(out, "User UID", oAuthAccessToken.UserUID)
		formatString(out, "Client Name", oAuthAccessToken.ClientName)

		return nil
	})
}

// ImageDescriber generates information about a Image
type ImageDescriber struct {
	client.Interface
}

// Describe returns the description of an image
func (d *ImageDescriber) Describe(namespace, name string) (string, error) {
	c := d.Images()
	image, err := c.Get(name)
	if err != nil {
		return "", err
	}

	return describeImage(image, "")
}

func describeImage(image *imageapi.Image, imageName string) (string, error) {
	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, image.ObjectMeta)
		formatString(out, "Docker Image", image.DockerImageReference)
		if len(imageName) > 0 {
			formatString(out, "Image Name", imageName)
		}
		switch l := len(image.DockerImageLayers); l {
		case 0:
			// legacy case, server does not know individual layers
			formatString(out, "Layer Size", units.HumanSize(float64(image.DockerImageMetadata.Size)))
		case 1:
			formatString(out, "Image Size", units.HumanSize(float64(image.DockerImageMetadata.Size)))
		default:
			info := []string{}
			if image.DockerImageLayers[0].Size > 0 {
				info = append(info, fmt.Sprintf("first layer %s", units.HumanSize(float64(image.DockerImageLayers[0].Size))))
			}
			for i := l - 1; i > 0; i-- {
				if image.DockerImageLayers[i].Size == 0 {
					continue
				}
				info = append(info, fmt.Sprintf("last binary layer %s", units.HumanSize(float64(image.DockerImageLayers[i].Size))))
				break
			}
			if len(info) > 0 {
				formatString(out, "Image Size", fmt.Sprintf("%s (%s)", units.HumanSize(float64(image.DockerImageMetadata.Size)), strings.Join(info, ", ")))
			} else {
				formatString(out, "Image Size", units.HumanSize(float64(image.DockerImageMetadata.Size)))
			}
		}
		//formatString(out, "Parent Image", image.DockerImageMetadata.Parent)
		formatString(out, "Image Created", fmt.Sprintf("%s ago", formatRelativeTime(image.DockerImageMetadata.Created.Time)))
		formatString(out, "Author", image.DockerImageMetadata.Author)
		formatString(out, "Arch", image.DockerImageMetadata.Architecture)
		describeDockerImage(out, image.DockerImageMetadata.Config)
		return nil
	})
}

func describeDockerImage(out *tabwriter.Writer, image *imageapi.DockerConfig) {
	if image == nil {
		return
	}
	hasCommand := false
	if len(image.Entrypoint) > 0 {
		hasCommand = true
		formatString(out, "Entrypoint", strings.Join(image.Entrypoint, " "))
	}
	if len(image.Cmd) > 0 {
		hasCommand = true
		formatString(out, "Command", strings.Join(image.Cmd, " "))
	}
	if !hasCommand {
		formatString(out, "Command", "")
	}
	formatString(out, "Working Dir", image.WorkingDir)
	formatString(out, "User", image.User)
	ports := sets.NewString()
	for k := range image.ExposedPorts {
		ports.Insert(k)
	}
	formatString(out, "Exposes Ports", strings.Join(ports.List(), ", "))
	formatMapStringString(out, "Docker Labels", image.Labels)
	for i, env := range image.Env {
		if i == 0 {
			formatString(out, "Environment", env)
		} else {
			fmt.Fprintf(out, "\t%s\n", env)
		}
	}
	volumes := sets.NewString()
	for k := range image.Volumes {
		volumes.Insert(k)
	}
	for i, volume := range volumes.List() {
		if i == 0 {
			formatString(out, "Volumes", volume)
		} else {
			fmt.Fprintf(out, "\t%s\n", volume)
		}
	}
}

// ImageStreamTagDescriber generates information about a ImageStreamTag (Image).
type ImageStreamTagDescriber struct {
	client.Interface
}

// Describe returns the description of an imageStreamTag
func (d *ImageStreamTagDescriber) Describe(namespace, name string) (string, error) {
	c := d.ImageStreamTags(namespace)
	repo, tag := parsers.ParseRepositoryTag(name)
	if tag == "" {
		// TODO use repo's preferred default, when that's coded
		tag = imageapi.DefaultImageTag
	}
	imageStreamTag, err := c.Get(repo, tag)
	if err != nil {
		return "", err
	}

	return describeImage(&imageStreamTag.Image, imageStreamTag.Image.Name)
}

// ImageStreamImageDescriber generates information about a ImageStreamImage (Image).
type ImageStreamImageDescriber struct {
	client.Interface
}

// Describe returns the description of an imageStreamImage
func (d *ImageStreamImageDescriber) Describe(namespace, name string) (string, error) {
	c := d.ImageStreamImages(namespace)
	repo, id := parsers.ParseRepositoryTag(name)
	imageStreamImage, err := c.Get(repo, id)
	if err != nil {
		return "", err
	}

	return describeImage(&imageStreamImage.Image, imageStreamImage.Image.Name)
}

// ImageStreamDescriber generates information about a ImageStream (Image).
type ImageStreamDescriber struct {
	client.Interface
}

// Describe returns the description of an imageStream
func (d *ImageStreamDescriber) Describe(namespace, name string) (string, error) {
	c := d.ImageStreams(namespace)
	imageStream, err := c.Get(name)
	if err != nil {
		return "", err
	}

	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, imageStream.ObjectMeta)
		formatString(out, "Docker Pull Spec", imageStream.Status.DockerImageRepository)
		formatImageStreamTags(out, imageStream)
		return nil
	})
}

// RouteDescriber generates information about a Route
type RouteDescriber struct {
	client.Interface
	kubeClient kclient.Interface
}

// Describe returns the description of a route
func (d *RouteDescriber) Describe(namespace, name string) (string, error) {
	c := d.Routes(namespace)
	route, err := c.Get(name)
	if err != nil {
		return "", err
	}

	endpoints, endsErr := d.kubeClient.Endpoints(namespace).Get(route.Spec.To.Name)

	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, route.ObjectMeta)
		if len(route.Spec.Host) > 0 {
			formatString(out, "Requested Host", route.Spec.Host)
			for _, ingress := range route.Status.Ingress {
				if route.Spec.Host != ingress.Host {
					continue
				}
				switch status, condition := routeapi.IngressConditionStatus(&ingress, routeapi.RouteAdmitted); status {
				case kapi.ConditionTrue:
					fmt.Fprintf(out, "\t  exposed on router %s %s ago\n", ingress.RouterName, strings.ToLower(formatRelativeTime(condition.LastTransitionTime.Time)))
				case kapi.ConditionFalse:
					fmt.Fprintf(out, "\t  rejected by router %s: %s (%s ago)\n", ingress.RouterName, condition.Reason, strings.ToLower(formatRelativeTime(condition.LastTransitionTime.Time)))
					if len(condition.Message) > 0 {
						fmt.Fprintf(out, "\t    %s\n", condition.Message)
					}
				}
			}
		} else {
			formatString(out, "Requested Host", "<auto>")
		}
		for _, ingress := range route.Status.Ingress {
			if route.Spec.Host == ingress.Host {
				continue
			}
			switch status, condition := routeapi.IngressConditionStatus(&ingress, routeapi.RouteAdmitted); status {
			case kapi.ConditionTrue:
				fmt.Fprintf(out, "\t%s exposed on router %s %s ago\n", ingress.Host, ingress.RouterName, strings.ToLower(formatRelativeTime(condition.LastTransitionTime.Time)))
			case kapi.ConditionFalse:
				fmt.Fprintf(out, "\trejected by router %s: %s (%s ago)\n", ingress.RouterName, condition.Reason, strings.ToLower(formatRelativeTime(condition.LastTransitionTime.Time)))
				if len(condition.Message) > 0 {
					fmt.Fprintf(out, "\t  %s\n", condition.Message)
				}
			}
		}
		formatString(out, "Path", route.Spec.Path)

		tlsTerm := ""
		insecurePolicy := ""
		if route.Spec.TLS != nil {
			tlsTerm = string(route.Spec.TLS.Termination)
			insecurePolicy = string(route.Spec.TLS.InsecureEdgeTerminationPolicy)
		}
		formatString(out, "TLS Termination", tlsTerm)
		formatString(out, "Insecure Policy", insecurePolicy)

		formatString(out, "Service", route.Spec.To.Name)
		if route.Spec.Port != nil {
			formatString(out, "Endpoint Port", route.Spec.Port.TargetPort.String())
		} else {
			formatString(out, "Endpoint Port", "<all endpoint ports>")
		}

		ends := "<none>"
		if endsErr != nil {
			ends = fmt.Sprintf("Unable to get endpoints: %v", endsErr)
		} else if len(endpoints.Subsets) > 0 {
			list := []string{}

			max := 3
			count := 0

			for i := range endpoints.Subsets {
				ss := &endpoints.Subsets[i]
				for p := range ss.Ports {
					for a := range ss.Addresses {
						if len(list) < max {
							list = append(list, fmt.Sprintf("%s:%d", ss.Addresses[a].IP, ss.Ports[p].Port))
						}
						count++
					}
				}
			}
			ends = strings.Join(list, ", ")
			if count > max {
				ends += fmt.Sprintf(" + %d more...", count-max)
			}
		}
		formatString(out, "Endpoints", ends)
		return nil
	})
}

// ProjectDescriber generates information about a Project
type ProjectDescriber struct {
	osClient   client.Interface
	kubeClient kclient.Interface
}

// Describe returns the description of a project
func (d *ProjectDescriber) Describe(namespace, name string) (string, error) {
	projectsClient := d.osClient.Projects()
	project, err := projectsClient.Get(name)
	if err != nil {
		return "", err
	}
	resourceQuotasClient := d.kubeClient.ResourceQuotas(name)
	resourceQuotaList, err := resourceQuotasClient.List(kapi.ListOptions{})
	if err != nil {
		return "", err
	}
	limitRangesClient := d.kubeClient.LimitRanges(name)
	limitRangeList, err := limitRangesClient.List(kapi.ListOptions{})
	if err != nil {
		return "", err
	}

	nodeSelector := ""
	if len(project.ObjectMeta.Annotations) > 0 {
		if ns, ok := project.ObjectMeta.Annotations[projectapi.ProjectNodeSelector]; ok {
			nodeSelector = ns
		}
	}

	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, project.ObjectMeta)
		formatString(out, "Display Name", project.Annotations[projectapi.ProjectDisplayName])
		formatString(out, "Description", project.Annotations[projectapi.ProjectDescription])
		formatString(out, "Status", project.Status.Phase)
		formatString(out, "Node Selector", nodeSelector)
		if len(resourceQuotaList.Items) == 0 {
			formatString(out, "Quota", "")
		} else {
			fmt.Fprintf(out, "Quota:\n")
			for i := range resourceQuotaList.Items {
				resourceQuota := &resourceQuotaList.Items[i]
				fmt.Fprintf(out, "\tName:\t%s\n", resourceQuota.Name)
				fmt.Fprintf(out, "\tResource\tUsed\tHard\n")
				fmt.Fprintf(out, "\t--------\t----\t----\n")

				resources := []kapi.ResourceName{}
				for resource := range resourceQuota.Status.Hard {
					resources = append(resources, resource)
				}
				sort.Sort(kctl.SortableResourceNames(resources))

				msg := "\t%v\t%v\t%v\n"
				for i := range resources {
					resource := resources[i]
					hardQuantity := resourceQuota.Status.Hard[resource]
					usedQuantity := resourceQuota.Status.Used[resource]
					fmt.Fprintf(out, msg, resource, usedQuantity.String(), hardQuantity.String())
				}
			}
		}
		if len(limitRangeList.Items) == 0 {
			formatString(out, "Resource limits", "")
		} else {
			fmt.Fprintf(out, "Resource limits:\n")
			for i := range limitRangeList.Items {
				limitRange := &limitRangeList.Items[i]
				fmt.Fprintf(out, "\tName:\t%s\n", limitRange.Name)
				fmt.Fprintf(out, "\tType\tResource\tMin\tMax\tDefault\n")
				fmt.Fprintf(out, "\t----\t--------\t---\t---\t---\n")
				for i := range limitRange.Spec.Limits {
					item := limitRange.Spec.Limits[i]
					maxResources := item.Max
					minResources := item.Min
					defaultResources := item.Default

					set := map[kapi.ResourceName]bool{}
					for k := range maxResources {
						set[k] = true
					}
					for k := range minResources {
						set[k] = true
					}
					for k := range defaultResources {
						set[k] = true
					}

					for k := range set {
						// if no value is set, we output -
						maxValue := "-"
						minValue := "-"
						defaultValue := "-"

						maxQuantity, maxQuantityFound := maxResources[k]
						if maxQuantityFound {
							maxValue = maxQuantity.String()
						}

						minQuantity, minQuantityFound := minResources[k]
						if minQuantityFound {
							minValue = minQuantity.String()
						}

						defaultQuantity, defaultQuantityFound := defaultResources[k]
						if defaultQuantityFound {
							defaultValue = defaultQuantity.String()
						}

						msg := "\t%v\t%v\t%v\t%v\t%v\n"
						fmt.Fprintf(out, msg, item.Type, k, minValue, maxValue, defaultValue)
					}
				}
			}
		}
		return nil
	})
}

// TemplateDescriber generates information about a template
type TemplateDescriber struct {
	client.Interface
	meta.MetadataAccessor
	runtime.ObjectTyper
	kctl.ObjectDescriber
}

// DescribeParameters prints out information about the parameters of a template
func (d *TemplateDescriber) DescribeParameters(params []templateapi.Parameter, out *tabwriter.Writer) {
	formatString(out, "Parameters", " ")
	indent := "    "
	for _, p := range params {
		formatString(out, indent+"Name", p.Name)
		if len(p.DisplayName) > 0 {
			formatString(out, indent+"Display Name", p.DisplayName)
		}
		if len(p.Description) > 0 {
			formatString(out, indent+"Description", p.Description)
		}
		formatString(out, indent+"Required", p.Required)
		if len(p.Generate) == 0 {
			formatString(out, indent+"Value", p.Value)
			continue
		}
		if len(p.Value) > 0 {
			formatString(out, indent+"Value", p.Value)
			formatString(out, indent+"Generated (ignored)", p.Generate)
			formatString(out, indent+"From", p.From)
		} else {
			formatString(out, indent+"Generated", p.Generate)
			formatString(out, indent+"From", p.From)
		}
		out.Write([]byte("\n"))
	}
}

// describeObjects prints out information about the objects of a template
func (d *TemplateDescriber) describeObjects(objects []runtime.Object, out *tabwriter.Writer) {
	formatString(out, "Objects", " ")
	indent := "    "
	for _, obj := range objects {
		if d.ObjectDescriber != nil {
			output, err := d.DescribeObject(obj)
			if err != nil {
				fmt.Fprintf(out, "error: %v\n", err)
				continue
			}
			fmt.Fprint(out, output)
			fmt.Fprint(out, "\n")
			continue
		}

		gvk, _ := d.ObjectTyper.ObjectKind(obj)
		meta := kapi.ObjectMeta{}
		meta.Name, _ = d.MetadataAccessor.Name(obj)
		fmt.Fprintf(out, fmt.Sprintf("%s%s\t%s\n", indent, gvk.Kind, meta.Name))
		//meta.Annotations, _ = d.MetadataAccessor.Annotations(obj)
		//meta.Labels, _ = d.MetadataAccessor.Labels(obj)
		/*if len(meta.Labels) > 0 {
			formatString(out, indent+"Labels", formatLabels(meta.Labels))
		}
		formatAnnotations(out, meta, indent)*/
	}
}

// Describe returns the description of a template
func (d *TemplateDescriber) Describe(namespace, name string) (string, error) {
	c := d.Templates(namespace)
	template, err := c.Get(name)
	if err != nil {
		return "", err
	}
	return d.DescribeTemplate(template)
}

func (d *TemplateDescriber) DescribeTemplate(template *templateapi.Template) (string, error) {
	// TODO: write error?
	_ = runtime.DecodeList(template.Objects, kapi.Codecs.UniversalDecoder(), runtime.UnstructuredJSONScheme)

	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, template.ObjectMeta)
		out.Write([]byte("\n"))
		out.Flush()
		d.DescribeParameters(template.Parameters, out)
		out.Write([]byte("\n"))
		formatString(out, "Object Labels", formatLabels(template.ObjectLabels))
		out.Write([]byte("\n"))
		out.Flush()
		d.describeObjects(template.Objects, out)
		return nil
	})
}

// IdentityDescriber generates information about a user
type IdentityDescriber struct {
	client.Interface
}

// Describe returns the description of an identity
func (d *IdentityDescriber) Describe(namespace, name string) (string, error) {
	userClient := d.Users()
	identityClient := d.Identities()

	identity, err := identityClient.Get(name)
	if err != nil {
		return "", err
	}

	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, identity.ObjectMeta)

		if len(identity.User.Name) == 0 {
			formatString(out, "User Name", identity.User.Name)
			formatString(out, "User UID", identity.User.UID)
		} else {
			resolvedUser, err := userClient.Get(identity.User.Name)

			nameValue := identity.User.Name
			uidValue := string(identity.User.UID)

			if kerrs.IsNotFound(err) {
				nameValue += fmt.Sprintf(" (Error: User does not exist)")
			} else if err != nil {
				nameValue += fmt.Sprintf(" (Error: User lookup failed)")
			} else {
				if !sets.NewString(resolvedUser.Identities...).Has(name) {
					nameValue += fmt.Sprintf(" (Error: User identities do not include %s)", name)
				}
				if resolvedUser.UID != identity.User.UID {
					uidValue += fmt.Sprintf(" (Error: Actual user UID is %s)", string(resolvedUser.UID))
				}
			}

			formatString(out, "User Name", nameValue)
			formatString(out, "User UID", uidValue)
		}
		return nil
	})

}

// UserIdentityMappingDescriber generates information about a user
type UserIdentityMappingDescriber struct {
	client.Interface
}

// Describe returns the description of a userIdentity
func (d *UserIdentityMappingDescriber) Describe(namespace, name string) (string, error) {
	c := d.UserIdentityMappings()

	mapping, err := c.Get(name)
	if err != nil {
		return "", err
	}

	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, mapping.ObjectMeta)
		formatString(out, "Identity", mapping.Identity.Name)
		formatString(out, "User Name", mapping.User.Name)
		formatString(out, "User UID", mapping.User.UID)
		return nil
	})
}

// UserDescriber generates information about a user
type UserDescriber struct {
	client.Interface
}

// Describe returns the description of a user
func (d *UserDescriber) Describe(namespace, name string) (string, error) {
	userClient := d.Users()
	identityClient := d.Identities()

	user, err := userClient.Get(name)
	if err != nil {
		return "", err
	}

	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, user.ObjectMeta)
		if len(user.FullName) > 0 {
			formatString(out, "Full Name", user.FullName)
		}

		if len(user.Identities) == 0 {
			formatString(out, "Identities", "<none>")
		} else {
			for i, identity := range user.Identities {
				resolvedIdentity, err := identityClient.Get(identity)

				value := identity
				if kerrs.IsNotFound(err) {
					value += fmt.Sprintf(" (Error: Identity does not exist)")
				} else if err != nil {
					value += fmt.Sprintf(" (Error: Identity lookup failed)")
				} else if resolvedIdentity.User.Name != name {
					value += fmt.Sprintf(" (Error: Identity maps to user name '%s')", resolvedIdentity.User.Name)
				} else if resolvedIdentity.User.UID != user.UID {
					value += fmt.Sprintf(" (Error: Identity maps to user UID '%s')", resolvedIdentity.User.UID)
				}

				if i == 0 {
					formatString(out, "Identities", value)
				} else {
					fmt.Fprintf(out, "           \t%s\n", value)
				}
			}
		}
		return nil
	})
}

// GroupDescriber generates information about a group
type GroupDescriber struct {
	c client.GroupInterface
}

// Describe returns the description of a group
func (d *GroupDescriber) Describe(namespace, name string) (string, error) {
	group, err := d.c.Get(name)
	if err != nil {
		return "", err
	}

	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, group.ObjectMeta)

		if len(group.Users) == 0 {
			formatString(out, "Users", "<none>")
		} else {
			for i, user := range group.Users {
				if i == 0 {
					formatString(out, "Users", user)
				} else {
					fmt.Fprintf(out, "           \t%s\n", user)
				}
			}
		}
		return nil
	})
}

// policy describers

// PolicyDescriber generates information about a Project
type PolicyDescriber struct {
	client.Interface
}

// Describe returns the description of a policy
// TODO make something a lot prettier
func (d *PolicyDescriber) Describe(namespace, name string) (string, error) {
	c := d.Policies(namespace)
	policy, err := c.Get(name)
	if err != nil {
		return "", err
	}

	return DescribePolicy(policy)
}

func DescribePolicy(policy *authorizationapi.Policy) (string, error) {
	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, policy.ObjectMeta)
		formatString(out, "Last Modified", policy.LastModified)

		// using .List() here because I always want the sorted order that it provides
		for _, key := range sets.StringKeySet(policy.Roles).List() {
			role := policy.Roles[key]
			fmt.Fprint(out, key+"\t"+PolicyRuleHeadings+"\n")
			for _, rule := range role.Rules {
				DescribePolicyRule(out, rule, "\t")
			}
		}

		return nil
	})
}

const PolicyRuleHeadings = "Verbs\tNon-Resource URLs\tExtension\tResource Names\tAPI Groups\tResources"

func DescribePolicyRule(out *tabwriter.Writer, rule authorizationapi.PolicyRule, indent string) {
	extensionString := ""
	if rule.AttributeRestrictions != nil {
		extensionString = fmt.Sprintf("%#v", rule.AttributeRestrictions)

		buffer := new(bytes.Buffer)
		printer := NewHumanReadablePrinter(true, false, false, false, false, false, []string{})
		if err := printer.PrintObj(rule.AttributeRestrictions, buffer); err == nil {
			extensionString = strings.TrimSpace(buffer.String())
		}
	}

	fmt.Fprintf(out, indent+"%v\t%v\t%v\t%v\t%v\t%v\n",
		rule.Verbs.List(),
		rule.NonResourceURLs.List(),
		extensionString,
		rule.ResourceNames.List(),
		rule.APIGroups,
		rule.Resources.List(),
	)
}

// RoleDescriber generates information about a Project
type RoleDescriber struct {
	client.Interface
}

// Describe returns the description of a role
func (d *RoleDescriber) Describe(namespace, name string) (string, error) {
	c := d.Roles(namespace)
	role, err := c.Get(name)
	if err != nil {
		return "", err
	}

	return DescribeRole(role)
}

func DescribeRole(role *authorizationapi.Role) (string, error) {
	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, role.ObjectMeta)

		fmt.Fprint(out, PolicyRuleHeadings+"\n")
		for _, rule := range role.Rules {
			DescribePolicyRule(out, rule, "")

		}

		return nil
	})
}

// PolicyBindingDescriber generates information about a Project
type PolicyBindingDescriber struct {
	client.Interface
}

// Describe returns the description of a policyBinding
func (d *PolicyBindingDescriber) Describe(namespace, name string) (string, error) {
	c := d.PolicyBindings(namespace)
	policyBinding, err := c.Get(name)
	if err != nil {
		return "", err
	}

	return DescribePolicyBinding(policyBinding)
}

func DescribePolicyBinding(policyBinding *authorizationapi.PolicyBinding) (string, error) {

	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, policyBinding.ObjectMeta)
		formatString(out, "Last Modified", policyBinding.LastModified)
		formatString(out, "Policy", policyBinding.PolicyRef.Namespace)

		// using .List() here because I always want the sorted order that it provides
		for _, key := range sets.StringKeySet(policyBinding.RoleBindings).List() {
			roleBinding := policyBinding.RoleBindings[key]
			users, groups, sas, others := authorizationapi.SubjectsStrings(roleBinding.Namespace, roleBinding.Subjects)

			formatString(out, "RoleBinding["+key+"]", " ")
			formatString(out, "\tRole", roleBinding.RoleRef.Name)
			formatString(out, "\tUsers", strings.Join(users, ", "))
			formatString(out, "\tGroups", strings.Join(groups, ", "))
			formatString(out, "\tServiceAccounts", strings.Join(sas, ", "))
			formatString(out, "\tSubjects", strings.Join(others, ", "))
		}

		return nil
	})
}

// RoleBindingDescriber generates information about a Project
type RoleBindingDescriber struct {
	client.Interface
}

// Describe returns the description of a roleBinding
func (d *RoleBindingDescriber) Describe(namespace, name string) (string, error) {
	c := d.RoleBindings(namespace)
	roleBinding, err := c.Get(name)
	if err != nil {
		return "", err
	}

	var role *authorizationapi.Role
	if len(roleBinding.RoleRef.Namespace) == 0 {
		var clusterRole *authorizationapi.ClusterRole
		clusterRole, err = d.ClusterRoles().Get(roleBinding.RoleRef.Name)
		role = authorizationapi.ToRole(clusterRole)
	} else {
		role, err = d.Roles(roleBinding.RoleRef.Namespace).Get(roleBinding.RoleRef.Name)
	}

	return DescribeRoleBinding(roleBinding, role, err)
}

// DescribeRoleBinding prints out information about a role binding and its associated role
func DescribeRoleBinding(roleBinding *authorizationapi.RoleBinding, role *authorizationapi.Role, err error) (string, error) {
	users, groups, sas, others := authorizationapi.SubjectsStrings(roleBinding.Namespace, roleBinding.Subjects)

	return tabbedString(func(out *tabwriter.Writer) error {
		formatMeta(out, roleBinding.ObjectMeta)

		formatString(out, "Role", roleBinding.RoleRef.Namespace+"/"+roleBinding.RoleRef.Name)
		formatString(out, "Users", strings.Join(users, ", "))
		formatString(out, "Groups", strings.Join(groups, ", "))
		formatString(out, "ServiceAccounts", strings.Join(sas, ", "))
		formatString(out, "Subjects", strings.Join(others, ", "))

		switch {
		case err != nil:
			formatString(out, "Policy Rules", fmt.Sprintf("error: %v", err))

		case role != nil:
			fmt.Fprint(out, PolicyRuleHeadings+"\n")
			for _, rule := range role.Rules {
				DescribePolicyRule(out, rule, "")
			}

		default:
			formatString(out, "Policy Rules", "<none>")
		}

		return nil
	})
}

// ClusterPolicyDescriber generates information about a Project
type ClusterPolicyDescriber struct {
	client.Interface
}

// Describe returns the description of a policy
// TODO make something a lot prettier
func (d *ClusterPolicyDescriber) Describe(namespace, name string) (string, error) {
	c := d.ClusterPolicies()
	policy, err := c.Get(name)
	if err != nil {
		return "", err
	}

	return DescribePolicy(authorizationapi.ToPolicy(policy))
}

type ClusterRoleDescriber struct {
	client.Interface
}

// Describe returns the description of a role
func (d *ClusterRoleDescriber) Describe(namespace, name string) (string, error) {
	c := d.ClusterRoles()
	role, err := c.Get(name)
	if err != nil {
		return "", err
	}

	return DescribeRole(authorizationapi.ToRole(role))
}

// ClusterPolicyBindingDescriber generates information about a Project
type ClusterPolicyBindingDescriber struct {
	client.Interface
}

// Describe returns the description of a policyBinding
func (d *ClusterPolicyBindingDescriber) Describe(namespace, name string) (string, error) {
	c := d.ClusterPolicyBindings()
	policyBinding, err := c.Get(name)
	if err != nil {
		return "", err
	}

	return DescribePolicyBinding(authorizationapi.ToPolicyBinding(policyBinding))
}

// ClusterRoleBindingDescriber generates information about a Project
type ClusterRoleBindingDescriber struct {
	client.Interface
}

// Describe returns the description of a roleBinding
func (d *ClusterRoleBindingDescriber) Describe(namespace, name string) (string, error) {
	c := d.ClusterRoleBindings()
	roleBinding, err := c.Get(name)
	if err != nil {
		return "", err
	}

	role, err := d.ClusterRoles().Get(roleBinding.RoleRef.Name)
	return DescribeRoleBinding(authorizationapi.ToRoleBinding(roleBinding), authorizationapi.ToRole(role), err)
}

func describeBuildTriggerCauses(causes []buildapi.BuildTriggerCause, out *tabwriter.Writer) {
	if causes == nil {
		formatString(out, "\nBuild trigger cause", "<unknown>")
	}

	for _, cause := range causes {
		formatString(out, "\nBuild trigger cause", cause.Message)

		switch {
		case cause.GitHubWebHook != nil:
			squashGitInfo(cause.GitHubWebHook.Revision, out)
			formatString(out, "Secret", cause.GitHubWebHook.Secret)

		case cause.GenericWebHook != nil:
			squashGitInfo(cause.GenericWebHook.Revision, out)
			formatString(out, "Secret", cause.GenericWebHook.Secret)

		case cause.ImageChangeBuild != nil:
			formatString(out, "Image ID", cause.ImageChangeBuild.ImageID)
			formatString(out, "Image Name/Kind", fmt.Sprintf("%s / %s", cause.ImageChangeBuild.FromRef.Name, cause.ImageChangeBuild.FromRef.Kind))
		}
	}
	fmt.Fprintf(out, "\n")
}

func squashGitInfo(sourceRevision *buildapi.SourceRevision, out *tabwriter.Writer) {
	if sourceRevision != nil && sourceRevision.Git != nil {
		rev := sourceRevision.Git
		formatString(out, "Commit", fmt.Sprintf("%s (%s)", rev.Commit[:7], rev.Message))
		hasAuthor := len(rev.Author.Name) != 0
		hasCommitter := len(rev.Committer.Name) != 0
		if hasAuthor && hasCommitter {
			if rev.Author.Name == rev.Committer.Name {
				formatString(out, "Author/Committer", rev.Author.Name)
			} else {
				formatString(out, "Author/Committer", fmt.Sprintf("%s / %s", rev.Author.Name, rev.Committer.Name))
			}
		} else if hasAuthor {
			formatString(out, "Author", rev.Author.Name)
		} else if hasCommitter {
			formatString(out, "Committer", rev.Committer.Name)
		}
	}
}


text:
CREATE TABLE IF NOT EXISTS damage_report_mail (
  gmail_id varchar(255) PRIMARY KEY NOT NULL,
  message_id varchar(255) NOT NULL,
  opposite_agent_name varchar(255),
  attack_date datetime,
  create_date datetime
);
CREATE TABLE IF NOT EXISTS damage_portal (
  message_id varchar(255) NOT NULL,
  seq integer NOT NULL,
  portal_id varchar(255) NOT NULL,
  create_date datetime,
  PRIMARY KEY(message_id, seq)
);
CREATE TABLE IF NOT EXISTS portal (
  id varchar(255) NOT NULL,
  portal_name varchar(255),
  latitude float,
  longitude float,
  portal_intel_url varchar(255),
  create_date datetime,
  PRIMARY KEY(id)
);
CREATE UNIQUE INDEX IF NOT EXISTS message_id_uniq_idx ON damage_report_mail (message_id ASC);

redpajama_set_name: RedPajamaGithub


text:
// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/cloud/speech/v2/cloud_speech.proto

package com.google.cloud.speech.v2;

/**
 *
 *
 *

 * Explicitly specified decoding parameters.
 *

 *
 * Protobuf type {@code google.cloud.speech.v2.ExplicitDecodingConfig}
 */
public final class ExplicitDecodingConfig extends com.google.protobuf.GeneratedMessageV3
    implements
    // @@protoc_insertion_point(message_implements:google.cloud.speech.v2.ExplicitDecodingConfig)
    ExplicitDecodingConfigOrBuilder {
  private static final long serialVersionUID = 0L;
  // Use ExplicitDecodingConfig.newBuilder() to construct.
  private ExplicitDecodingConfig(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
    super(builder);
  }

  private ExplicitDecodingConfig() {
    encoding_ = 0;
  }

  @java.lang.Override
  @SuppressWarnings({"unused"})
  protected java.lang.Object newInstance(UnusedPrivateParameter unused) {
    return new ExplicitDecodingConfig();
  }

  @java.lang.Override
  public final com.google.protobuf.UnknownFieldSet getUnknownFields() {
    return this.unknownFields;
  }

  public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
    return com.google.cloud.speech.v2.CloudSpeechProto
        .internal_static_google_cloud_speech_v2_ExplicitDecodingConfig_descriptor;
  }

  @java.lang.Override
  protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
      internalGetFieldAccessorTable() {
    return com.google.cloud.speech.v2.CloudSpeechProto
        .internal_static_google_cloud_speech_v2_ExplicitDecodingConfig_fieldAccessorTable
        .ensureFieldAccessorsInitialized(
            com.google.cloud.speech.v2.ExplicitDecodingConfig.class,
            com.google.cloud.speech.v2.ExplicitDecodingConfig.Builder.class);
  }

  /**
   *
   *
   *

   * Supported audio data encodings.
   *

   *
   * Protobuf enum {@code google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding}
   */
  public enum AudioEncoding implements com.google.protobuf.ProtocolMessageEnum {
    /**
     *
     *
     *

     * Default value. This value is unused.
     *

     *
     * AUDIO_ENCODING_UNSPECIFIED = 0;
     */
    AUDIO_ENCODING_UNSPECIFIED(0),
    /**
     *
     *
     *

     * Headerless 16-bit signed little-endian PCM samples.
     *

     *
     * LINEAR16 = 1;
     */
    LINEAR16(1),
    /**
     *
     *
     *

     * Headerless 8-bit companded mulaw samples.
     *

     *
     * MULAW = 2;
     */
    MULAW(2),
    /**
     *
     *
     *

     * Headerless 8-bit companded alaw samples.
     *

     *
     * ALAW = 3;
     */
    ALAW(3),
    UNRECOGNIZED(-1),
    ;

    /**
     *
     *
     *

     * Default value. This value is unused.
     *

     *
     * AUDIO_ENCODING_UNSPECIFIED = 0;
     */
    public static final int AUDIO_ENCODING_UNSPECIFIED_VALUE = 0;
    /**
     *
     *
     *

     * Headerless 16-bit signed little-endian PCM samples.
     *

     *
     * LINEAR16 = 1;
     */
    public static final int LINEAR16_VALUE = 1;
    /**
     *
     *
     *

     * Headerless 8-bit companded mulaw samples.
     *

     *
     * MULAW = 2;
     */
    public static final int MULAW_VALUE = 2;
    /**
     *
     *
     *

     * Headerless 8-bit companded alaw samples.
     *

     *
     * ALAW = 3;
     */
    public static final int ALAW_VALUE = 3;

    public final int getNumber() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalArgumentException(
            "Can't get the number of an unknown enum value.");
      }
      return value;
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     * @deprecated Use {@link #forNumber(int)} instead.
     */
    @java.lang.Deprecated
    public static AudioEncoding valueOf(int value) {
      return forNumber(value);
    }

    /**
     * @param value The numeric wire value of the corresponding enum entry.
     * @return The enum associated with the given numeric wire value.
     */
    public static AudioEncoding forNumber(int value) {
      switch (value) {
        case 0:
          return AUDIO_ENCODING_UNSPECIFIED;
        case 1:
          return LINEAR16;
        case 2:
          return MULAW;
        case 3:
          return ALAW;
        default:
          return null;
      }
    }

    public static com.google.protobuf.Internal.EnumLiteMap<AudioEncoding> internalGetValueMap() {
      return internalValueMap;
    }

    private static final com.google.protobuf.Internal.EnumLiteMap<AudioEncoding> internalValueMap =
        new com.google.protobuf.Internal.EnumLiteMap<AudioEncoding>() {
          public AudioEncoding findValueByNumber(int number) {
            return AudioEncoding.forNumber(number);
          }
        };

    public final com.google.protobuf.Descriptors.EnumValueDescriptor getValueDescriptor() {
      if (this == UNRECOGNIZED) {
        throw new java.lang.IllegalStateException(
            "Can't get the descriptor of an unrecognized enum value.");
      }
      return getDescriptor().getValues().get(ordinal());
    }

    public final com.google.protobuf.Descriptors.EnumDescriptor getDescriptorForType() {
      return getDescriptor();
    }

    public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() {
      return com.google.cloud.speech.v2.ExplicitDecodingConfig.getDescriptor()
          .getEnumTypes()
          .get(0);
    }

    private static final AudioEncoding[] VALUES = values();

    public static AudioEncoding valueOf(com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
      if (desc.getType() != getDescriptor()) {
        throw new java.lang.IllegalArgumentException("EnumValueDescriptor is not for this type.");
      }
      if (desc.getIndex() == -1) {
        return UNRECOGNIZED;
      }
      return VALUES[desc.getIndex()];
    }

    private final int value;

    private AudioEncoding(int value) {
      this.value = value;
    }

    // @@protoc_insertion_point(enum_scope:google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding)
  }

  public static final int ENCODING_FIELD_NUMBER = 1;
  private int encoding_;
  /**
   *
   *
   *

   * Required. Encoding of the audio data sent for recognition.
   *

   *
   *
   * .google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding encoding = 1 [(.google.api.field_behavior) = REQUIRED];
   *
   *
   * @return The enum numeric value on the wire for encoding.
   */
  @java.lang.Override
  public int getEncodingValue() {
    return encoding_;
  }
  /**
   *
   *
   *

   * Required. Encoding of the audio data sent for recognition.
   *

   *
   *
   * .google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding encoding = 1 [(.google.api.field_behavior) = REQUIRED];
   *
   *
   * @return The encoding.
   */
  @java.lang.Override
  public com.google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding getEncoding() {
    @SuppressWarnings("deprecation")
    com.google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding result =
        com.google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding.valueOf(encoding_);
    return result == null
        ? com.google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding.UNRECOGNIZED
        : result;
  }

  public static final int SAMPLE_RATE_HERTZ_FIELD_NUMBER = 2;
  private int sampleRateHertz_;
  /**
   *
   *
   *

   * Sample rate in Hertz of the audio data sent for recognition. Valid
   * values are: 8000-48000. 16000 is optimal. For best results, set the
   * sampling rate of the audio source to 16000 Hz. If that's not possible, use
   * the native sample rate of the audio source (instead of re-sampling).
   * Supported for the following encodings:
   * * LINEAR16: Headerless 16-bit signed little-endian PCM samples.
   * * MULAW: Headerless 8-bit companded mulaw samples.
   * * ALAW: Headerless 8-bit companded alaw samples.
   *

   *
   * int32 sample_rate_hertz = 2;
   *
   * @return The sampleRateHertz.
   */
  @java.lang.Override
  public int getSampleRateHertz() {
    return sampleRateHertz_;
  }

  public static final int AUDIO_CHANNEL_COUNT_FIELD_NUMBER = 3;
  private int audioChannelCount_;
  /**
   *
   *
   *

   * Number of channels present in the audio data sent for recognition.
   * Supported for the following encodings:
   * * LINEAR16: Headerless 16-bit signed little-endian PCM samples.
   * * MULAW: Headerless 8-bit companded mulaw samples.
   * * ALAW: Headerless 8-bit companded alaw samples.
   *

   *
   * int32 audio_channel_count = 3;
   *
   * @return The audioChannelCount.
   */
  @java.lang.Override
  public int getAudioChannelCount() {
    return audioChannelCount_;
  }

  private byte memoizedIsInitialized = -1;

  @java.lang.Override
  public final boolean isInitialized() {
    byte isInitialized = memoizedIsInitialized;
    if (isInitialized == 1) return true;
    if (isInitialized == 0) return false;

    memoizedIsInitialized = 1;
    return true;
  }

  @java.lang.Override
  public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
    if (encoding_
        != com.google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding
            .AUDIO_ENCODING_UNSPECIFIED
            .getNumber()) {
      output.writeEnum(1, encoding_);
    }
    if (sampleRateHertz_ != 0) {
      output.writeInt32(2, sampleRateHertz_);
    }
    if (audioChannelCount_ != 0) {
      output.writeInt32(3, audioChannelCount_);
    }
    getUnknownFields().writeTo(output);
  }

  @java.lang.Override
  public int getSerializedSize() {
    int size = memoizedSize;
    if (size != -1) return size;

    size = 0;
    if (encoding_
        != com.google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding
            .AUDIO_ENCODING_UNSPECIFIED
            .getNumber()) {
      size += com.google.protobuf.CodedOutputStream.computeEnumSize(1, encoding_);
    }
    if (sampleRateHertz_ != 0) {
      size += com.google.protobuf.CodedOutputStream.computeInt32Size(2, sampleRateHertz_);
    }
    if (audioChannelCount_ != 0) {
      size += com.google.protobuf.CodedOutputStream.computeInt32Size(3, audioChannelCount_);
    }
    size += getUnknownFields().getSerializedSize();
    memoizedSize = size;
    return size;
  }

  @java.lang.Override
  public boolean equals(final java.lang.Object obj) {
    if (obj == this) {
      return true;
    }
    if (!(obj instanceof com.google.cloud.speech.v2.ExplicitDecodingConfig)) {
      return super.equals(obj);
    }
    com.google.cloud.speech.v2.ExplicitDecodingConfig other =
        (com.google.cloud.speech.v2.ExplicitDecodingConfig) obj;

    if (encoding_ != other.encoding_) return false;
    if (getSampleRateHertz() != other.getSampleRateHertz()) return false;
    if (getAudioChannelCount() != other.getAudioChannelCount()) return false;
    if (!getUnknownFields().equals(other.getUnknownFields())) return false;
    return true;
  }

  @java.lang.Override
  public int hashCode() {
    if (memoizedHashCode != 0) {
      return memoizedHashCode;
    }
    int hash = 41;
    hash = (19 * hash) + getDescriptor().hashCode();
    hash = (37 * hash) + ENCODING_FIELD_NUMBER;
    hash = (53 * hash) + encoding_;
    hash = (37 * hash) + SAMPLE_RATE_HERTZ_FIELD_NUMBER;
    hash = (53 * hash) + getSampleRateHertz();
    hash = (37 * hash) + AUDIO_CHANNEL_COUNT_FIELD_NUMBER;
    hash = (53 * hash) + getAudioChannelCount();
    hash = (29 * hash) + getUnknownFields().hashCode();
    memoizedHashCode = hash;
    return hash;
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig parseFrom(
      java.nio.ByteBuffer data) throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig parseFrom(
      java.nio.ByteBuffer data, com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig parseFrom(
      com.google.protobuf.ByteString data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig parseFrom(
      com.google.protobuf.ByteString data,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig parseFrom(byte[] data)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data);
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig parseFrom(
      byte[] data, com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws com.google.protobuf.InvalidProtocolBufferException {
    return PARSER.parseFrom(data, extensionRegistry);
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig parseFrom(
      java.io.InputStream input) throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input);
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig parseFrom(
      java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3.parseWithIOException(
        PARSER, input, extensionRegistry);
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig parseDelimitedFrom(
      java.io.InputStream input) throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(PARSER, input);
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig parseDelimitedFrom(
      java.io.InputStream input, com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3.parseDelimitedWithIOException(
        PARSER, input, extensionRegistry);
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig parseFrom(
      com.google.protobuf.CodedInputStream input) throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3.parseWithIOException(PARSER, input);
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig parseFrom(
      com.google.protobuf.CodedInputStream input,
      com.google.protobuf.ExtensionRegistryLite extensionRegistry)
      throws java.io.IOException {
    return com.google.protobuf.GeneratedMessageV3.parseWithIOException(
        PARSER, input, extensionRegistry);
  }

  @java.lang.Override
  public Builder newBuilderForType() {
    return newBuilder();
  }

  public static Builder newBuilder() {
    return DEFAULT_INSTANCE.toBuilder();
  }

  public static Builder newBuilder(com.google.cloud.speech.v2.ExplicitDecodingConfig prototype) {
    return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
  }

  @java.lang.Override
  public Builder toBuilder() {
    return this == DEFAULT_INSTANCE ? new Builder() : new Builder().mergeFrom(this);
  }

  @java.lang.Override
  protected Builder newBuilderForType(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
    Builder builder = new Builder(parent);
    return builder;
  }
  /**
   *
   *
   *

   * Explicitly specified decoding parameters.
   *

   *
   * Protobuf type {@code google.cloud.speech.v2.ExplicitDecodingConfig}
   */
  public static final class Builder extends com.google.protobuf.GeneratedMessageV3.Builder<Builder>
      implements
      // @@protoc_insertion_point(builder_implements:google.cloud.speech.v2.ExplicitDecodingConfig)
      com.google.cloud.speech.v2.ExplicitDecodingConfigOrBuilder {
    public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() {
      return com.google.cloud.speech.v2.CloudSpeechProto
          .internal_static_google_cloud_speech_v2_ExplicitDecodingConfig_descriptor;
    }

    @java.lang.Override
    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
        internalGetFieldAccessorTable() {
      return com.google.cloud.speech.v2.CloudSpeechProto
          .internal_static_google_cloud_speech_v2_ExplicitDecodingConfig_fieldAccessorTable
          .ensureFieldAccessorsInitialized(
              com.google.cloud.speech.v2.ExplicitDecodingConfig.class,
              com.google.cloud.speech.v2.ExplicitDecodingConfig.Builder.class);
    }

    // Construct using com.google.cloud.speech.v2.ExplicitDecodingConfig.newBuilder()
    private Builder() {}

    private Builder(com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
      super(parent);
    }

    @java.lang.Override
    public Builder clear() {
      super.clear();
      encoding_ = 0;

      sampleRateHertz_ = 0;

      audioChannelCount_ = 0;

      return this;
    }

    @java.lang.Override
    public com.google.protobuf.Descriptors.Descriptor getDescriptorForType() {
      return com.google.cloud.speech.v2.CloudSpeechProto
          .internal_static_google_cloud_speech_v2_ExplicitDecodingConfig_descriptor;
    }

    @java.lang.Override
    public com.google.cloud.speech.v2.ExplicitDecodingConfig getDefaultInstanceForType() {
      return com.google.cloud.speech.v2.ExplicitDecodingConfig.getDefaultInstance();
    }

    @java.lang.Override
    public com.google.cloud.speech.v2.ExplicitDecodingConfig build() {
      com.google.cloud.speech.v2.ExplicitDecodingConfig result = buildPartial();
      if (!result.isInitialized()) {
        throw newUninitializedMessageException(result);
      }
      return result;
    }

    @java.lang.Override
    public com.google.cloud.speech.v2.ExplicitDecodingConfig buildPartial() {
      com.google.cloud.speech.v2.ExplicitDecodingConfig result =
          new com.google.cloud.speech.v2.ExplicitDecodingConfig(this);
      result.encoding_ = encoding_;
      result.sampleRateHertz_ = sampleRateHertz_;
      result.audioChannelCount_ = audioChannelCount_;
      onBuilt();
      return result;
    }

    @java.lang.Override
    public Builder clone() {
      return super.clone();
    }

    @java.lang.Override
    public Builder setField(
        com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) {
      return super.setField(field, value);
    }

    @java.lang.Override
    public Builder clearField(com.google.protobuf.Descriptors.FieldDescriptor field) {
      return super.clearField(field);
    }

    @java.lang.Override
    public Builder clearOneof(com.google.protobuf.Descriptors.OneofDescriptor oneof) {
      return super.clearOneof(oneof);
    }

    @java.lang.Override
    public Builder setRepeatedField(
        com.google.protobuf.Descriptors.FieldDescriptor field, int index, java.lang.Object value) {
      return super.setRepeatedField(field, index, value);
    }

    @java.lang.Override
    public Builder addRepeatedField(
        com.google.protobuf.Descriptors.FieldDescriptor field, java.lang.Object value) {
      return super.addRepeatedField(field, value);
    }

    @java.lang.Override
    public Builder mergeFrom(com.google.protobuf.Message other) {
      if (other instanceof com.google.cloud.speech.v2.ExplicitDecodingConfig) {
        return mergeFrom((com.google.cloud.speech.v2.ExplicitDecodingConfig) other);
      } else {
        super.mergeFrom(other);
        return this;
      }
    }

    public Builder mergeFrom(com.google.cloud.speech.v2.ExplicitDecodingConfig other) {
      if (other == com.google.cloud.speech.v2.ExplicitDecodingConfig.getDefaultInstance())
        return this;
      if (other.encoding_ != 0) {
        setEncodingValue(other.getEncodingValue());
      }
      if (other.getSampleRateHertz() != 0) {
        setSampleRateHertz(other.getSampleRateHertz());
      }
      if (other.getAudioChannelCount() != 0) {
        setAudioChannelCount(other.getAudioChannelCount());
      }
      this.mergeUnknownFields(other.getUnknownFields());
      onChanged();
      return this;
    }

    @java.lang.Override
    public final boolean isInitialized() {
      return true;
    }

    @java.lang.Override
    public Builder mergeFrom(
        com.google.protobuf.CodedInputStream input,
        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
        throws java.io.IOException {
      if (extensionRegistry == null) {
        throw new java.lang.NullPointerException();
      }
      try {
        boolean done = false;
        while (!done) {
          int tag = input.readTag();
          switch (tag) {
            case 0:
              done = true;
              break;
            case 8:
              {
                encoding_ = input.readEnum();

                break;
              } // case 8
            case 16:
              {
                sampleRateHertz_ = input.readInt32();

                break;
              } // case 16
            case 24:
              {
                audioChannelCount_ = input.readInt32();

                break;
              } // case 24
            default:
              {
                if (!super.parseUnknownField(input, extensionRegistry, tag)) {
                  done = true; // was an endgroup tag
                }
                break;
              } // default:
          } // switch (tag)
        } // while (!done)
      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
        throw e.unwrapIOException();
      } finally {
        onChanged();
      } // finally
      return this;
    }

    private int encoding_ = 0;
    /**
     *
     *
     *

     * Required. Encoding of the audio data sent for recognition.
     *

     *
     *
     * .google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding encoding = 1 [(.google.api.field_behavior) = REQUIRED];
     *
     *
     * @return The enum numeric value on the wire for encoding.
     */
    @java.lang.Override
    public int getEncodingValue() {
      return encoding_;
    }
    /**
     *
     *
     *

     * Required. Encoding of the audio data sent for recognition.
     *

     *
     *
     * .google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding encoding = 1 [(.google.api.field_behavior) = REQUIRED];
     *
     *
     * @param value The enum numeric value on the wire for encoding to set.
     * @return This builder for chaining.
     */
    public Builder setEncodingValue(int value) {

      encoding_ = value;
      onChanged();
      return this;
    }
    /**
     *
     *
     *

     * Required. Encoding of the audio data sent for recognition.
     *

     *
     *
     * .google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding encoding = 1 [(.google.api.field_behavior) = REQUIRED];
     *
     *
     * @return The encoding.
     */
    @java.lang.Override
    public com.google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding getEncoding() {
      @SuppressWarnings("deprecation")
      com.google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding result =
          com.google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding.valueOf(encoding_);
      return result == null
          ? com.google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding.UNRECOGNIZED
          : result;
    }
    /**
     *
     *
     *

     * Required. Encoding of the audio data sent for recognition.
     *

     *
     *
     * .google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding encoding = 1 [(.google.api.field_behavior) = REQUIRED];
     *
     *
     * @param value The encoding to set.
     * @return This builder for chaining.
     */
    public Builder setEncoding(
        com.google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding value) {
      if (value == null) {
        throw new NullPointerException();
      }

      encoding_ = value.getNumber();
      onChanged();
      return this;
    }
    /**
     *
     *
     *

     * Required. Encoding of the audio data sent for recognition.
     *

     *
     *
     * .google.cloud.speech.v2.ExplicitDecodingConfig.AudioEncoding encoding = 1 [(.google.api.field_behavior) = REQUIRED];
     *
     *
     * @return This builder for chaining.
     */
    public Builder clearEncoding() {

      encoding_ = 0;
      onChanged();
      return this;
    }

    private int sampleRateHertz_;
    /**
     *
     *
     *

     * Sample rate in Hertz of the audio data sent for recognition. Valid
     * values are: 8000-48000. 16000 is optimal. For best results, set the
     * sampling rate of the audio source to 16000 Hz. If that's not possible, use
     * the native sample rate of the audio source (instead of re-sampling).
     * Supported for the following encodings:
     * * LINEAR16: Headerless 16-bit signed little-endian PCM samples.
     * * MULAW: Headerless 8-bit companded mulaw samples.
     * * ALAW: Headerless 8-bit companded alaw samples.
     *

     *
     * int32 sample_rate_hertz = 2;
     *
     * @return The sampleRateHertz.
     */
    @java.lang.Override
    public int getSampleRateHertz() {
      return sampleRateHertz_;
    }
    /**
     *
     *
     *

     * Sample rate in Hertz of the audio data sent for recognition. Valid
     * values are: 8000-48000. 16000 is optimal. For best results, set the
     * sampling rate of the audio source to 16000 Hz. If that's not possible, use
     * the native sample rate of the audio source (instead of re-sampling).
     * Supported for the following encodings:
     * * LINEAR16: Headerless 16-bit signed little-endian PCM samples.
     * * MULAW: Headerless 8-bit companded mulaw samples.
     * * ALAW: Headerless 8-bit companded alaw samples.
     *

     *
     * int32 sample_rate_hertz = 2;
     *
     * @param value The sampleRateHertz to set.
     * @return This builder for chaining.
     */
    public Builder setSampleRateHertz(int value) {

      sampleRateHertz_ = value;
      onChanged();
      return this;
    }
    /**
     *
     *
     *

     * Sample rate in Hertz of the audio data sent for recognition. Valid
     * values are: 8000-48000. 16000 is optimal. For best results, set the
     * sampling rate of the audio source to 16000 Hz. If that's not possible, use
     * the native sample rate of the audio source (instead of re-sampling).
     * Supported for the following encodings:
     * * LINEAR16: Headerless 16-bit signed little-endian PCM samples.
     * * MULAW: Headerless 8-bit companded mulaw samples.
     * * ALAW: Headerless 8-bit companded alaw samples.
     *

     *
     * int32 sample_rate_hertz = 2;
     *
     * @return This builder for chaining.
     */
    public Builder clearSampleRateHertz() {

      sampleRateHertz_ = 0;
      onChanged();
      return this;
    }

    private int audioChannelCount_;
    /**
     *
     *
     *

     * Number of channels present in the audio data sent for recognition.
     * Supported for the following encodings:
     * * LINEAR16: Headerless 16-bit signed little-endian PCM samples.
     * * MULAW: Headerless 8-bit companded mulaw samples.
     * * ALAW: Headerless 8-bit companded alaw samples.
     *

     *
     * int32 audio_channel_count = 3;
     *
     * @return The audioChannelCount.
     */
    @java.lang.Override
    public int getAudioChannelCount() {
      return audioChannelCount_;
    }
    /**
     *
     *
     *

     * Number of channels present in the audio data sent for recognition.
     * Supported for the following encodings:
     * * LINEAR16: Headerless 16-bit signed little-endian PCM samples.
     * * MULAW: Headerless 8-bit companded mulaw samples.
     * * ALAW: Headerless 8-bit companded alaw samples.
     *

     *
     * int32 audio_channel_count = 3;
     *
     * @param value The audioChannelCount to set.
     * @return This builder for chaining.
     */
    public Builder setAudioChannelCount(int value) {

      audioChannelCount_ = value;
      onChanged();
      return this;
    }
    /**
     *
     *
     *

     * Number of channels present in the audio data sent for recognition.
     * Supported for the following encodings:
     * * LINEAR16: Headerless 16-bit signed little-endian PCM samples.
     * * MULAW: Headerless 8-bit companded mulaw samples.
     * * ALAW: Headerless 8-bit companded alaw samples.
     *

     *
     * int32 audio_channel_count = 3;
     *
     * @return This builder for chaining.
     */
    public Builder clearAudioChannelCount() {

      audioChannelCount_ = 0;
      onChanged();
      return this;
    }

    @java.lang.Override
    public final Builder setUnknownFields(final com.google.protobuf.UnknownFieldSet unknownFields) {
      return super.setUnknownFields(unknownFields);
    }

    @java.lang.Override
    public final Builder mergeUnknownFields(
        final com.google.protobuf.UnknownFieldSet unknownFields) {
      return super.mergeUnknownFields(unknownFields);
    }

    // @@protoc_insertion_point(builder_scope:google.cloud.speech.v2.ExplicitDecodingConfig)
  }

  // @@protoc_insertion_point(class_scope:google.cloud.speech.v2.ExplicitDecodingConfig)
  private static final com.google.cloud.speech.v2.ExplicitDecodingConfig DEFAULT_INSTANCE;

  static {
    DEFAULT_INSTANCE = new com.google.cloud.speech.v2.ExplicitDecodingConfig();
  }

  public static com.google.cloud.speech.v2.ExplicitDecodingConfig getDefaultInstance() {
    return DEFAULT_INSTANCE;
  }

  private static final com.google.protobuf.Parser<ExplicitDecodingConfig> PARSER =
      new com.google.protobuf.AbstractParser<ExplicitDecodingConfig>() {
        @java.lang.Override
        public ExplicitDecodingConfig parsePartialFrom(
            com.google.protobuf.CodedInputStream input,
            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
            throws com.google.protobuf.InvalidProtocolBufferException {
          Builder builder = newBuilder();
          try {
            builder.mergeFrom(input, extensionRegistry);
          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
            throw e.setUnfinishedMessage(builder.buildPartial());
          } catch (com.google.protobuf.UninitializedMessageException e) {
            throw e.asInvalidProtocolBufferException().setUnfinishedMessage(builder.buildPartial());
          } catch (java.io.IOException e) {
            throw new com.google.protobuf.InvalidProtocolBufferException(e)
                .setUnfinishedMessage(builder.buildPartial());
          }
          return builder.buildPartial();
        }
      };

  public static com.google.protobuf.Parser<ExplicitDecodingConfig> parser() {
    return PARSER;
  }

  @java.lang.Override
  public com.google.protobuf.Parser<ExplicitDecodingConfig> getParserForType() {
    return PARSER;
  }

  @java.lang.Override
  public com.google.cloud.speech.v2.ExplicitDecodingConfig getDefaultInstanceForType() {
    return DEFAULT_INSTANCE;
  }
}


text:
import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  Image,
  TouchableOpacity
} from 'react-native';

var Dimensions = require('Dimensions');
var {width, height} = Dimensions.get('window')

import HomeCommonView from './homecommonview'

var HomeMiddleView = React.createClass({

    getDefaultProps(){
        return {
            dataObj: {}
        }
    },

    render(){
        var dataLeft = this.props.dataObj.dataLeft;
        return (
            <View style={styles.container}>
                <TouchableOpacity style={styles.leftViewStyle}>
                    <Image source={{uri: dataLeft.img1}} style={styles.imgStyle}/>
                    <Image source={{uri: dataLeft.img2}} style={styles.imgStyle}/>
                    <Text>{dataLeft.title}</Text>
                    <View style={{flexDirection: 'row'}}>
                        <Text>{dataLeft.price}</Text>
                        <Text>{dataLeft.sale}</Text>
                    </View>
                </TouchableOpacity>
                <View style={styles.rightViewStyle}>
                    {this.renderBottomItem()}
                </View>
            </View>
        )
    },

    renderBottomItem(){
        var rightDataArr = this.props.dataObj.dataRight;
        var itemArr = [];
        for (var i = 0; i < rightDataArr.length; i++) {
            var item = rightDataArr[i];
            itemArr.push(
                <HomeCommonView key={i} data={rightDataArr[i]}/>
            );
        }
        return itemArr;
    }
});

const styles = StyleSheet.create({
    container: {
        marginTop: 15,
        flexDirection: 'row'
    },
    leftViewStyle: {
        backgroundColor: 'white',
        width: width * 0.5 - 1,
        height: 131,
        alignItems: 'center',
        justifyContent: 'space-around',
        marginRight: 1
    },
    imgStyle: {
        width: width * 0.35,
        height: width * 0.1,
        resizeMode: 'contain'
    },
    rightViewStyle: {

    }
});

module.exports = HomeMiddleView


text:
<?php

namespace Parser;

class Custom implements ParserInterface
{
    private static $color = [
        'yellow' => 'Y',
        'blue' => 'B',
        'purple' => 'P',
        'red' => 'R'
    ];

    public static function parse($string, \cli\Arguments $args)
    {
        $string = self::parseByLogType($string, $args);

        return $string . PHP_EOL;
    }

    public static function parseByLogType($string, $args)
    {
        if (preg_match('/(DEBUG)/', $string) != false) {
            $string = self::parseWithColor($string, $args, self::$color['yellow']);
        } elseif (preg_match('/(NOTICE|INFO)/', $string) != false) {
            $string = self::parseWithColor($string, $args, self::$color['blue']);
        } elseif (preg_match('/(WARNING)/', $string) != false) {
            $string = self::parseWithColor($string, $args, self::$color['purple']);
        } elseif (preg_match('/(ERROR)/', $string) != false) {
            $string = self::parseWithColor($string, $args, self::$color['red']);
        } else {
            $string = self::parseWithColor($string, $args, self::$color['blue']);
        }

        return $string;
    }

    public static function parseWithColor($string, $args, $color)
    {
        $string = self::parseTypeLogString($string, $args, $color);
        $string = self::parseDateTime($string, $args, $color);
        $string = self::parsePaths($string, $args, $color);
        $string = self::parseSql($string, $args, $color);

        return $string;
    }

    public static function parseTypeLogString($string, $args, $color)
    {
        $string = preg_replace(
            '/(([a-zA-Z]+\.)(DEBUG|NOTICE|INFO|WARNING|ERROR)(\:|))/',
            '%' . $color . '%9$1%n',
            $string
        );

        return $string;
    }

    public static function parseDateTime($string, $args, $color)
    {
        $string = preg_replace('/((\[|)[0-9]{4}-[0-9]{2}-[0-9]{2}(\]|))/', '%' . $color . '%9$1%n', $string);
        $string = preg_replace('/((\[|)[0-9]{2}:[0-9]{2}(:[0-9]{2}|)(\]|))/', '%' . $color . '%9$1%n', $string);

        return $string;
    }

    public static function parsePaths($string, $args, $color)
    {
        $string = preg_replace("/(\"[a-zA-Z0-9_\-\.\\\\:\/]+\")/", '%' . $color . '%9$1%n', $string);

        return $string;
    }

    public static function parseSql($string, $args, $color)
    {
        // TODO regex to identify the sql string, and the parser for it
        if ($args['sql-formatter']) {
            if (preg_match('/(SELECT|INSERT|TRUNCATE|UPDATE|DELETE)/', $string) != false) {
                $string = preg_replace('/(SELECT|INSERT|TRUNCATE|UPDATE|DELETE)/', '$1' . PHP_EOL . "\t", $string);
            }
        }

        return $string;
    }
}


text:
package com.koushikdutta.async.util;

import com.koushikdutta.async.ByteBufferList;

import java.nio.ByteBuffer;

/**
 * Created by koush on 6/28/14.
 */
public class Allocator {
    final int maxAlloc;
    int currentAlloc = 0;
    int minAlloc = 2 << 11;

    public Allocator(int maxAlloc) {
        this.maxAlloc = maxAlloc;
    }

    public Allocator() {
        maxAlloc = ByteBufferList.MAX_ITEM_SIZE;
    }

    public ByteBuffer allocate() {
        return ByteBufferList.obtain(Math.min(Math.max(currentAlloc, minAlloc), maxAlloc));
    }

    public void track(long read) {
        currentAlloc = (int)read * 2;
    }

    public int getMaxAlloc() {
        return maxAlloc;
    }

    public void setCurrentAlloc(int currentAlloc) {
        this.currentAlloc = currentAlloc;
    }

    public int getMinAlloc() {
        return minAlloc;
    }

    public Allocator setMinAlloc(int minAlloc ) {
        this.minAlloc = minAlloc;
        return this;
    }
}


text:
import csv
import abc
import sqlite3
import operator
import bz2
import gzip

from bson import BSON, json_util
from smappdragon.tools.tweet_parser import TweetParser

def binary_mode(mode):
    '''
    Converts modes for compressed formats, like gzip and bz2.
    '''
    if mode == 'a':
        mode = 'at'
    elif mode == 'w':
        mode = 'wt'
    elif mode == 'r':
        mode = 'rt'

    return mode

class BaseCollection(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def __init__(self):
        self.limit = 0
        self.filter = {}
        self.keep_fields = []
        self.should_strip = False
        self.custom_filters = []

    '''
        returns an iterator that
        can iterate through the tweets
        in a collection
    '''
    @abc.abstractmethod
    def get_iterator(self):
        pass

    '''
        sets the fields to keep when
        the user calls strip tweets
    '''
    def strip_tweets(self, keep_fields):
        self.keep_fields = keep_fields
        self.should_strip = True
        return self

    '''
        returns the modified collection
        object with a limit on how many tweets
        it will ever output or query
    '''
    def set_limit(self, limit):
        self.limit = limit
        return self

    '''
        sets the filters you'd
        like to apply to the query
        follows mongdb query syntax
    '''
    def set_filter(self, query_filter):
        self.filter = query_filter
        return self

    '''
        takes a function as an input
        and appends it to the list of
        custom filters that need to be passed
    '''
    def set_custom_filter(self, func):
        self.custom_filters.append(func)
        return self

    '''
        takes a function as an input
        and appends it to the list of
        custom filters that need to be passed
    '''
    def set_custom_filter_list(self, functions_list):
        self.custom_filters.extend(functions_list)
        return self

    '''
        dumps the contents of a collection
        to a bson file, this is a binary format
    '''
    def dump_to_bson(self, output_bson):
        filehandle = open(output_bson, 'ab+')

        for tweet in self.get_iterator():
            filehandle.write(BSON.encode(tweet))
        filehandle.close()

    '''
        dumps the contents of a collection
        to a json file, a json object on
        each line
    '''

    def dump_to_json(self, output_json, compression=None, mode='a'):
        if compression == 'bz2':
            mode = binary_mode(mode)
            filehandle = bz2.open(output_json, mode)
        elif compression == 'gzip':
            mode = binary_mode(mode)
            filehandle = gzip.open(output_json, mode)
        else:
            filehandle = open(output_json, mode)

        for tweet in self.get_iterator():
            filehandle.write(json_util.dumps(tweet)+'\n')
        filehandle.close()

    '''
        dumps the contents of a collection
        to csv format with columns specified
        by input_fields
    '''
    def dump_to_csv(self, output_csv, input_fields, write_header=True, top_level=False, mode='a', encoding='utf-8', compression=None):
        if compression == 'bz2':
            mode = binary_mode(mode)
            filehandle = bz2.open(output_csv, mode)
        elif compression == 'gzip':
            mode = binary_mode(mode)
            filehandle = gzip.open(output_csv, mode)
        else:
            filehandle = open(output_csv, mode)

        writer = csv.writer(filehandle)
        if write_header:
            writer.writerow(input_fields)
        tweet_parser = TweetParser()

        for tweet in self.get_iterator():
            if top_level:
                ret = list(zip(input_fields, [tweet.get(field) for field in input_fields]))
            else:
                ret = tweet_parser.parse_columns_from_tweet(tweet,input_fields)
            ret_values = [col_val[1] for col_val in ret]
            writer.writerow(ret_values)
        filehandle.close()

    '''
        dumps the contents of a collection
        to an sqlite database with columns
        specified by input_fields
    '''
    def dump_to_sqlite_db(self, output_db, input_fields, top_level=False):
        def replace_none(s):
            if s is None:
                return 'NULL'
            return s

        tweet_parser = TweetParser()
        column_str = ','.join([column for column in input_fields]).replace('.','__')
        question_marks = ','.join(['?' for column in input_fields])

        con = sqlite3.connect(output_db)
        cur = con.cursor()
        cur.execute("CREATE TABLE IF NOT EXISTS data ({});".format(column_str))

        insert_list = []
        # batch insert if more than 10k tweets
        for count, tweet in enumerate(self.get_iterator()):
            if top_level:
                ret = list(zip(input_fields, [tweet.get(field) for field in input_fields]))
            else:
                ret = tweet_parser.parse_columns_from_tweet(tweet, input_fields)
            row = [replace_none(col_val[1]) for col_val in ret]
            insert_list.append(tuple(row))
            if (count % 10000) == 0:
                cur.executemany("INSERT INTO data ({}) VALUES ({});".format(column_str, question_marks), insert_list)
                con.commit()
                insert_list = []
        if count < 10000:
            cur.executemany("INSERT INTO data ({}) VALUES ({});".format(column_str, question_marks), insert_list)
            con.commit()
        con.close()


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Learning
{
    class Tree : IOracle
    {
        Index _pivot;
        bool _defaultReturn;
        Dictionary<object, IOracle> _children;

        public Tree(Index pivot, bool defaultReturn)
        {
            _pivot = pivot;
            _defaultReturn = defaultReturn;
            _children = new Dictionary<object, IOracle>();
        }

        public void AddChild(object modality, IOracle dn)
        {
            _children.Add(modality, dn);
        }

        public bool Predict(Person p)
        {
            object modality = p[_pivot];
            if (_children.ContainsKey(modality))
                return _children[modality].Predict(p);
            else
                return _defaultReturn;
        }

        public override string ToString()
        {
            StringBuilder builder = new StringBuilder();
            builder.AppendLine(string.Format("GeneralDN({0})", _pivot));

            foreach (KeyValuePair<object, IOracle> child in _children)
                builder.AppendLine("\t" + string.Format("({0} --> {1})", child.Key, child.Value));

            return builder.ToString();
        }
    }
}


text:
<title>Docs For Class PHPExcel_Worksheet_MemoryDrawing</title>
<link rel="stylesheet" type="text/css" href="../media/style.css">

    PHPExcel_Worksheet

                                                                                [ class tree: PHPExcel_Worksheet ]
		  [ index: PHPExcel_Worksheet ]
		  	    [ all elements ]

Todo List

      Packages:

              PHPExcel

              com-tecnick-tcpdf

              JAMA

              Math_Stats

              PHPExcel_CachedObjectStorage

              PHPExcel_Calculation

              PHPExcel_Cell

              PHPExcel_Reader

              PHPExcel_Reader_Excel5

              PHPExcel_Reader_Excel2007

              PHPExcel_RichText

              PHPExcel_Settings

              PHPExcel_Shared

              PHPExcel_Shared_Best_Fit

              PHPExcel_Shared_Escher

              PHPExcel_Shared_OLE

              PHPExcel_Shared_ZipArchive

              PHPExcel_Style

              PHPExcel_Worksheet

              PHPExcel_Worksheet_Drawing

              PHPExcel_Writer

              PHPExcel_Writer_Excel5

              PHPExcel_Writer_Excel2007

                        Files:

					BaseDrawing.php

					CellIterator.php

					ColumnDimension.php

					HeaderFooter.php

					HeaderFooterDrawing.php

					MemoryDrawing.php

					PageMargins.php

					PageSetup.php

					Protection.php

					Row.php

					RowDimension.php

					RowIterator.php

					SheetView.php

					Worksheet.php

            Classes:

		    		PHPExcel_Worksheet

	    		PHPExcel_Worksheet_BaseDrawing

	    		PHPExcel_Worksheet_CellIterator

	    		PHPExcel_Worksheet_ColumnDimension

	    		PHPExcel_Worksheet_HeaderFooter

	    		PHPExcel_Worksheet_HeaderFooterDrawing

	    		PHPExcel_Worksheet_MemoryDrawing

	    		PHPExcel_Worksheet_PageMargins

	    		PHPExcel_Worksheet_PageSetup

	    		PHPExcel_Worksheet_Protection

	    		PHPExcel_Worksheet_Row

	    		PHPExcel_Worksheet_RowDimension

	    		PHPExcel_Worksheet_RowIterator

	    		PHPExcel_Worksheet_SheetView

Class: PHPExcel_Worksheet_MemoryDrawing

Source Location: /PHPExcel/Worksheet/MemoryDrawing.php

Class Overview

PHPExcel_Worksheet_BaseDrawing
   |
   --PHPExcel_Worksheet_MemoryDrawing

PHPExcel_Worksheet_MemoryDrawing

Author(s):

Copyright:

Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)

            Implements interfaces:

PHPExcel_IComparable

Constants

MIMETYPE_DEFAULT

MIMETYPE_GIF

MIMETYPE_JPEG

MIMETYPE_PNG

RENDERING_DEFAULT

RENDERING_GIF

RENDERING_JPEG

RENDERING_PNG

Methods

getHashCode

getImageResource

getIndexedFilename

getMimeType

getRenderingFunction

__construct

setImageResource

setMimeType

setRenderingFunction

__clone

Inherited Variables

Class: PHPExcel_Worksheet_BaseDrawing

  PHPExcel_Worksheet_BaseDrawing::$_coordinates

  PHPExcel_Worksheet_BaseDrawing::$_description

  PHPExcel_Worksheet_BaseDrawing::$_height

  PHPExcel_Worksheet_BaseDrawing::$_name

  PHPExcel_Worksheet_BaseDrawing::$_offsetX

  PHPExcel_Worksheet_BaseDrawing::$_offsetY

  PHPExcel_Worksheet_BaseDrawing::$_resizeProportional

  PHPExcel_Worksheet_BaseDrawing::$_rotation

  PHPExcel_Worksheet_BaseDrawing::$_shadow

  PHPExcel_Worksheet_BaseDrawing::$_width

  PHPExcel_Worksheet_BaseDrawing::$_worksheet

Inherited Methods

Class: PHPExcel_Worksheet_BaseDrawing

    PHPExcel_Worksheet_BaseDrawing::__construct()

    Create a new PHPExcel_Worksheet_BaseDrawing

    PHPExcel_Worksheet_BaseDrawing::getCoordinates()

    Get Coordinates

    PHPExcel_Worksheet_BaseDrawing::getDescription()

    Get Description

    PHPExcel_Worksheet_BaseDrawing::getHashCode()

    Get hash code

    PHPExcel_Worksheet_BaseDrawing::getHeight()

    Get Height

    PHPExcel_Worksheet_BaseDrawing::getImageIndex()

    Get image index

    PHPExcel_Worksheet_BaseDrawing::getName()

    Get Name

    PHPExcel_Worksheet_BaseDrawing::getOffsetX()

    Get OffsetX

    PHPExcel_Worksheet_BaseDrawing::getOffsetY()

    Get OffsetY

    PHPExcel_Worksheet_BaseDrawing::getResizeProportional()

    Get ResizeProportional

    PHPExcel_Worksheet_BaseDrawing::getRotation()

    Get Rotation

    PHPExcel_Worksheet_BaseDrawing::getShadow()

    Get Shadow

    PHPExcel_Worksheet_BaseDrawing::getWidth()

    Get Width

    PHPExcel_Worksheet_BaseDrawing::getWorksheet()

    Get Worksheet

    PHPExcel_Worksheet_BaseDrawing::setCoordinates()

    Set Coordinates

    PHPExcel_Worksheet_BaseDrawing::setDescription()

    Set Description

    PHPExcel_Worksheet_BaseDrawing::setHeight()

    Set Height

    PHPExcel_Worksheet_BaseDrawing::setName()

    Set Name

    PHPExcel_Worksheet_BaseDrawing::setOffsetX()

    Set OffsetX

    PHPExcel_Worksheet_BaseDrawing::setOffsetY()

    Set OffsetY

    PHPExcel_Worksheet_BaseDrawing::setResizeProportional()

    Set ResizeProportional

    PHPExcel_Worksheet_BaseDrawing::setRotation()

    Set Rotation

    PHPExcel_Worksheet_BaseDrawing::setShadow()

    Set Shadow

    PHPExcel_Worksheet_BaseDrawing::setWidth()

    Set Width

    PHPExcel_Worksheet_BaseDrawing::setWidthAndHeight()

    Set width and height with proportional resize

    PHPExcel_Worksheet_BaseDrawing::setWorksheet()

    Set Worksheet

    PHPExcel_Worksheet_BaseDrawing::__clone()

    Implement PHP __clone to create a deep clone, not just a shallow copy.

Class Details

[line 36]

PHPExcel_Worksheet_MemoryDrawing

Tags:

    copyright:  	Copyright (c) 2006 - 2011 PHPExcel (http://www.codeplex.com/PHPExcel)

[ Top ]

Class Methods

method getHashCode [line 177]

		string getHashCode(
)

		Get hash code

Tags:

    return:  	Hash code

    access:  	public

	Overrides PHPExcel_Worksheet_BaseDrawing::getHashCode() (Get hash code)

[ Top ]

method getImageResource [line 98]

		resource getImageResource(
)

		Get image resource

Tags:

    access:  	public

[ Top ]

method getIndexedFilename [line 164]

		string getIndexedFilename(
)

		Get indexed filename (using image index)

Tags:

    access:  	public

[ Top ]

method getMimeType [line 144]

		string getMimeType(
)

		Get mime type

Tags:

    access:  	public

[ Top ]

method getRenderingFunction [line 124]

		string getRenderingFunction(
)

		Get rendering function

Tags:

    access:  	public

[ Top ]

constructor __construct [line 81]

		PHPExcel_Worksheet_MemoryDrawing __construct(
)

		Create a new PHPExcel_Worksheet_MemoryDrawing

Tags:

    access:  	public

	Overrides PHPExcel_Worksheet_BaseDrawing::__construct() (Create a new PHPExcel_Worksheet_BaseDrawing)

[ Top ]

method setImageResource [line 108]

		PHPExcel_Worksheet_MemoryDrawing setImageResource(
[$value
$value = null])

		Set image resource

Tags:

    access:  	public

Parameters:

        $value
        $value
        resource

[ Top ]

method setMimeType [line 154]

		PHPExcel_Worksheet_MemoryDrawing setMimeType(
[string
$value = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT])

		Set mime type

Tags:

    access:  	public

Parameters:

        string
        $value

[ Top ]

method setRenderingFunction [line 134]

		PHPExcel_Worksheet_MemoryDrawing setRenderingFunction(
[string
$value = PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT])

		Set rendering function

Tags:

    access:  	public

Parameters:

        string
        $value

[ Top ]

method __clone [line 190]

		void __clone(
)

		Implement PHP __clone to create a deep clone, not just a shallow copy.

Tags:

    access:  	public

	Overrides PHPExcel_Worksheet_BaseDrawing::__clone() (Implement PHP __clone to create a deep clone, not just a shallow copy.)

[ Top ]

Class Constants

MIMETYPE_DEFAULT =  'image/png'

[line 45]

[ Top ]

MIMETYPE_GIF =  'image/gif'

[line 47]

[ Top ]

MIMETYPE_JPEG =  'image/jpeg'

[line 48]

[ Top ]

MIMETYPE_PNG =  'image/png'

[line 46]

[ Top ]

RENDERING_DEFAULT =  'imagepng'

[line 39]

[ Top ]

RENDERING_GIF =  'imagegif'

[line 41]

[ Top ]

RENDERING_JPEG =  'imagejpeg'

[line 42]

[ Top ]

RENDERING_PNG =  'imagepng'

[line 40]

[ Top ]

		    Documentation generated on Sun, 27 Feb 2011 16:32:47 -0800 by phpDocumentor 1.4.3