text:
use utf8;
use strict;
use warnings;

use CPAN::Meta();
use CPANPLUS::Backend();
use Module::CoreList;
use Getopt::Long::Descriptive qw( describe_options );
use JSON::PP qw( encode_json );
use Log::Log4perl qw(:easy);
use Readonly();

# Readonly hash that maps CPAN style license strings to information
# necessary to generate a Nixpkgs style license attribute.
Readonly::Hash my %LICENSE_MAP => (

    # The Perl 5 License (Artistic 1 & GPL 1 or later).
    perl_5 => {
        licenses => [qw( artistic1 gpl1Plus )]
    },

    # GNU Affero General Public License, Version 3.
    agpl_3 => {
        licenses => [qw( agpl3Plus )],
        amb      => 1
    },

    # Apache Software License, Version 1.1.
    apache_1_1 => {
        licenses => ["Apache License 1.1"],
        in_set   => 0
    },

    # Apache License, Version 2.0.
    apache_2_0 => {
        licenses => [qw( asl20 )]
    },

    # Artistic License, (Version 1).
    artistic_1 => {
        licenses => [qw( artistic1 )]
    },

    # Artistic License, Version 2.0.
    artistic_2 => {
        licenses => [qw( artistic2 )]
    },

    # BSD License (three-clause).
    bsd => {
        licenses => [qw( bsd3 )],
        amb      => 1
    },

    # FreeBSD License (two-clause).
    freebsd => {
        licenses => [qw( bsd2 )]
    },

    # GNU Free Documentation License, Version 1.2.
    gfdl_1_2 => {
        licenses => [qw( fdl12Plus )]
    },

    # GNU Free Documentation License, Version 1.3.
    gfdl_1_3 => {
        licenses => [qw( fdl13Plus )]
    },

    # GNU General Public License, Version 1.
    gpl_1 => {
        licenses => [qw( gpl1Plus )],
        amb      => 1
    },

    # GNU General Public License, Version 2. Note, we will interpret
    # "gpl" alone as GPL v2+.
    gpl_2 => {
        licenses => [qw( gpl2Plus )],
        amb      => 1
    },

    # GNU General Public License, Version 3.
    gpl_3 => {
        licenses => [qw( gpl3Plus )],
        amb      => 1
    },

    # GNU Lesser General Public License, Version 2.1. Note, we will
    # interpret "gpl" alone as LGPL v2.1+.
    lgpl_2_1 => {
        licenses => [qw( lgpl21Plus )],
        amb      => 1
    },

    # GNU Lesser General Public License, Version 3.0.
    lgpl_3_0 => {
        licenses => [qw( lgpl3Plus )],
        amb      => 1
    },

    # MIT (aka X11) License.
    mit => {
        licenses => [qw( mit )]
    },

    # Mozilla Public License, Version 1.0.
    mozilla_1_0 => {
        licenses => [qw( mpl10 )]
    },

    # Mozilla Public License, Version 1.1.
    mozilla_1_1 => {
        licenses => [qw( mpl11 )]
    },

    # OpenSSL License.
    openssl => {
        licenses => [qw( openssl )]
    },

    # Q Public License, Version 1.0.
    qpl_1_0 => {
        licenses => [qw( qpl )]
    },

    # Original SSLeay License.
    ssleay => {
        licenses => ["Original SSLeay License"],
        in_set   => 0
    },

    # Sun Internet Standards Source License (SISSL).
    sun => {
        licenses => ["Sun Industry Standards Source License v1.1"],
        in_set   => 0
    },

    # zlib License.
    zlib => {
        licenses => [qw( zlib )]
    },

    # Other Open Source Initiative (OSI) approved license.
    open_source => {
        licenses => [qw( free )],
        amb      => 1
    },

    # Requires special permission from copyright holder.
    restricted => {
        licenses => [qw( unfree )],
        amb      => 1
    },

    # Not an OSI approved license, but not restricted. Note, we
    # currently map this to unfreeRedistributable, which is a
    # conservative choice.
    unrestricted => {
        licenses => [qw( unfreeRedistributable )],
        amb      => 1
    },

    # License not provided in metadata.
    unknown => {
        licenses => [],
        amb      => 1
    }
);

sub handle_opts {
    my ( $opt, $usage ) = describe_options(
        'usage: $0 %o MODULE',
        [ 'maintainer|m=s', 'the package maintainer' ],
        [ 'debug|d',        'enable debug output' ],
        [ 'help',           'print usage message and exit' ]
    );

    if ( $opt->help ) {
        print $usage->text;
        exit;
    }

    my $module_name = $ARGV[0];

    if ( !defined $module_name ) {
        print STDERR "Missing module name\n";
        print STDERR $usage->text;
        exit 1;
    }

    return ( $opt, $module_name );
}

# Takes a Perl package attribute name and returns 1 if the name cannot
# be referred to as a bareword. This typically happens if the package
# name is a reserved Nix keyword.
sub is_reserved {
    my ($pkg) = @_;

    return $pkg =~ /^(?: assert    |
                         else      |
                         if        |
                         import    |
                         in        |
                         inherit   |
                         let       |
                         rec       |
                         then      |
                         while     |
                         with      )$/x;
}

sub pkg_to_attr {
    my ($module) = @_;
    my $attr_name = $module->package_name;
    if ( $attr_name eq "libwww-perl" ) {
        return "LWP";
    }
    else {
        $attr_name =~ s/-//g;
        return $attr_name;
    }
}

sub get_pkg_name {
    my ($module) = @_;
    return ( $module->package_name, $module->package_version =~ s/^v(\d)/$1/r );
}

sub read_meta {
    my ($pkg_path) = @_;

    my $yaml_path = "$pkg_path/META.yml";
    my $json_path = "$pkg_path/META.json";
    my $meta;

    if ( -r $json_path ) {
        $meta = CPAN::Meta->load_file($json_path);
    }
    elsif ( -r $yaml_path ) {
        $meta = CPAN::Meta->load_file($yaml_path);
    }
    else {
        WARN("package has no META.yml or META.json");
    }

    return $meta;
}

# Map a module to the attribute corresponding to its package
# (e.g. HTML::HeadParser will be mapped to HTMLParser, because that
# module is in the HTML-Parser package).
sub module_to_pkg {
    my ( $cb, $module_name ) = @_;
    my @modules = $cb->search( type => "name", allow => [$module_name] );
    if ( scalar @modules == 0 ) {

        # Fallback.
        $module_name =~ s/:://g;
        return $module_name;
    }
    my $module    = $modules[0];
    my $attr_name = pkg_to_attr($module);
    DEBUG("mapped dep $module_name to $attr_name");
    return $attr_name;
}

sub get_deps {
    my ( $cb, $meta, $type ) = @_;

    return if !defined $meta;

    my $prereqs = $meta->effective_prereqs;
    my $deps = $prereqs->requirements_for( $type, "requires" );
    my @res;
    foreach my $n ( $deps->required_modules ) {
        next if $n eq "perl";

        my @core = Module::CoreList->find_modules(qr/^$n$/);
        next if (@core);

        my $pkg = module_to_pkg( $cb, $n );

        # If the package name is reserved then we need to refer to it
        # through the "self" variable.
        $pkg = "self.\"$pkg\"" if is_reserved($pkg);

        push @res, $pkg;
    }
    return @res;
}

sub uniq {
    return keys %{ { map { $_ => 1 } @_ } };
}

sub render_license {
    my ($cpan_license) = @_;

    return if !defined $cpan_license;

    my $licenses;

    # If the license is ambiguous then we'll print an extra warning.
    # For example, "gpl_2" is ambiguous since it may refer to exactly
    # "GPL v2" or to "GPL v2 or later".
    my $amb = 0;

    # Whether the license is available inside `lib.licenses`.
    my $in_set = 1;

    my $nix_license = $LICENSE_MAP{$cpan_license};
    if ( !$nix_license ) {
        WARN("Unknown license: $cpan_license");
        $licenses = [$cpan_license];
        $in_set   = 0;
    }
    else {
        $licenses = $nix_license->{licenses};
        $amb      = $nix_license->{amb};
        $in_set   = !$nix_license->{in_set};
    }

    my $license_line;

    if ( @$licenses == 0 ) {

        # Avoid defining the license line.
    }
    elsif ($in_set) {
        my $lic = 'lib.licenses';
        if ( @$licenses == 1 ) {
            $license_line = "$lic.$licenses->[0]";
        }
        else {
            $license_line = "with $lic; [ " . join( ' ', @$licenses ) . " ]";
        }
    }
    else {
        if ( @$licenses == 1 ) {
            $license_line = $licenses->[0];
        }
        else {
            $license_line = '[ ' . join( ' ', @$licenses ) . ' ]';
        }
    }

    INFO("license: $cpan_license");
    WARN("License '$cpan_license' is ambiguous, please verify") if $amb;

    return $license_line;
}

my ( $opt, $module_name ) = handle_opts();

Log::Log4perl->easy_init(
    {
        level => $opt->debug ? $DEBUG : $INFO,
        layout => '%m%n'
    }
);

my $cb = CPANPLUS::Backend->new;

my @modules = $cb->search( type => "name", allow => [$module_name] );
die "module $module_name not found\n" if scalar @modules == 0;
die "multiple packages that match module $module_name\n" if scalar @modules > 1;
my $module = $modules[0];

my ($pkg_name, $pkg_version) = get_pkg_name $module;
my $attr_name = pkg_to_attr $module;

INFO( "attribute name: ", $attr_name );
INFO( "module: ",         $module->module );
INFO( "version: ",        $module->version );
INFO( "package: ", $module->package, " (", "$pkg_name-$pkg_version", ", ", $attr_name, ")" );
INFO( "path: ",    $module->path );

my $tar_path = $module->fetch();
INFO( "downloaded to: ", $tar_path );
INFO( "sha-256: ",       $module->status->checksum_value );

my $pkg_path = $module->extract();
INFO( "unpacked to: ", $pkg_path );

my $meta = read_meta($pkg_path);

DEBUG( "metadata: ", encode_json( $meta->as_struct ) ) if defined $meta;

my @runtime_deps = sort( uniq( get_deps( $cb, $meta, "runtime" ) ) );
INFO("runtime deps: @runtime_deps");

my @build_deps = sort( uniq(
        get_deps( $cb, $meta, "configure" ),
        get_deps( $cb, $meta, "build" ),
        get_deps( $cb, $meta, "test" )
) );

# Filter out runtime dependencies since those are already handled.
my %in_runtime_deps = map { $_ => 1 } @runtime_deps;
@build_deps = grep { not $in_runtime_deps{$_} } @build_deps;

INFO("build deps: @build_deps");

my $homepage = $meta ? $meta->resources->{homepage} : undef;
INFO("homepage: $homepage") if defined $homepage;

my $description = $meta ? $meta->abstract : undef;
if ( defined $description ) {
    $description = uc( substr( $description, 0, 1 ) )
      . substr( $description, 1 );    # capitalise first letter
    $description =~ s/\.$//;          # remove period at the end
    $description =~ s/\s*$//;
    $description =~ s/^\s*//;
    $description =~ s/\n+/ /;         # Replace new lines by space.
    INFO("description: $description");
}

#print(Data::Dumper::Dumper($meta->licenses) . "\n");
my $license = $meta ? render_license( $meta->licenses ) : undef;

INFO( "RSS feed: https://metacpan.org/feed/distribution/",
    $module->package_name );

my $build_fun = -e "$pkg_path/Build.PL"
  && !-e "$pkg_path/Makefile.PL" ? "buildPerlModule" : "buildPerlPackage";

print STDERR "===\n";

print <<EOF;
  ${\(is_reserved($attr_name) ? "\"$attr_name\"" : $attr_name)} = $build_fun {
    pname = "$pkg_name";
    version = "$pkg_version";
    src = fetchurl {
      url = "mirror://cpan/${\$module->path}/${\$module->package}";
      sha256 = "${\$module->status->checksum_value}";
    };
EOF
print <<EOF if scalar @build_deps > 0;
    buildInputs = [ @build_deps ];
EOF
print <<EOF if scalar @runtime_deps > 0;
    propagatedBuildInputs = [ @runtime_deps ];
EOF
print <<EOF;
    meta = {
EOF
print <<EOF if defined $homepage;
      homepage = "$homepage";
EOF
print <<EOF if defined $description && $description ne "Unknown";
      description = "$description";
EOF
print <<EOF if defined $license;
      license = $license;
EOF
print <<EOF if $opt->maintainer;
      maintainers = [ maintainers.${\$opt->maintainer} ];
EOF
print <<EOF;
    };
  };
EOF


text:
metalsmith-sass
===============

[![Build Status](https://app.travis-ci.com/stevenschobert/metalsmith-sass.svg?branch=master)](https://app.travis-ci.com/stevenschobert/metalsmith-sass)

A Sass plugin for Metalsmith.

## Installation

```sh
npm install --save metalsmith-sass node-sass
```

> Note: As of [v2.0](https://github.com/stevenschobert/metalsmith-sass/releases/v2.0.0), `node-sass` is listed as a peer dependency, and will need to be installed alongside metalsmith-sass as shown above.

## Getting Started

If you haven't checked out [Metalsmith](http://metalsmith.io/) before, head over to their website and check out the
documentation.

## CLI Usage

If you are using the command-line version of Metalsmith, you can install via npm, and then add the
`metalsmith-sass` key to your `metalsmith.json` file:

```json
{
  "plugins": {
    "metalsmith-sass": {
      "outputStyle": "expanded"
    }
  }
}
```

## JavaScript API

If you are using the JS Api for Metalsmith, then you can require the module and add it to your
`.use()` directives:

```js
var sass = require("metalsmith-sass");

metalsmith.use(sass({
  outputStyle: "expanded"
}));
```

## Options

See [node-sass](https://github.com/andrew/node-sass) for a complete list of supported options.

In addition to the options that node-sass provides, metalsmith-sass provides the following options:

### outputDir

Change the base folder path styles are output to. You can use this in combination with
Metalsmith's `destination` option to control where styles end up after the build.

The final output directory is equal to `Metalsmith.destination() + outputDirOption`. For example,
the following setup output styles to `build/css/` even though the source files are in `src/scss/`:

```js
Metalsmith()
  .source("src/")
  .destination("build/")
  .use(sass({
    outputDir: "css/"   // This changes the output dir to "build/css/" instead of "build/scss/"
  }))
  .build(function () {
    done();
  });
```

As of version [v1.1](https://github.com/stevenschobert/metalsmith-sass/releases/v1.1.0), you can also use a function to dynamically manipulate the output dir.

This is useful if you want to preserve your folder structure, but change just one folder name.

```js
Metalsmith(__dirname)
  .source("src/")
  .destination("build/")
  .use(sass({
    outputDir: function(originalPath) {
      // this will change scss/some/path to css/some/path
      return originalPath.replace("scss", "css");
    }
  }))
  .build(function () {
    done();
  });
```

## Source Maps

The easiest way to enable source maps in your metalsmith project is to add the following options:

```js
Metalsmith(__dirname)
  .source("src/")
  .destination("build/")
  .use(sass({
    sourceMap: true,
    sourceMapContents: true   // This will embed all the Sass contents in your source maps.
  }))
  .build(function () {
    done();
  });
```

Though the `sourceMapContents` is not required, I recommend adding it, otherwise you'll need to
manually serve up your `.scss` files along with your compiled `.css` files when you publish your
site.

## .sass files

As of version [v1.2](https://github.com/stevenschobert/metalsmith-sass/releases/v1.2.0),
metalsmith-sass automatically handles `.sass` files, so you don't need to specify the `indentedSyntax`
option. Though you might still need set options for `indentType` and `indentWidth` if you are
using something other than 2 spaces for indentation.

## Credits

Thanks to [Segment.io](http://github.com/segmentio) for creating and open-sourcing
[Metalsmith](https://github.com/segmentio/metalsmith)! Also thanks to the whole community behind
the [node-sass](https://github.com/andrew/node-sass) project.

redpajama_set_name: RedPajamaGithub


text:
package bip38

import (
	"fmt"
	"log"
	"math"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"sync/atomic"
	"time"
)

var totalTried uint64 = 0
var chunkSize uint64 = 0
var stopSearch int32 = 0
var startFrom uint64 = 0
var offset uint64 = 0
var startTime = time.Now()
var statsCalculated = time.Now()

func searchRange(start uint64, finish uint64, encryptedKey string, charset string, pwlen int, c chan string) {
	cset := []rune(charset)
	var i uint64
	for i = start; atomic.LoadInt32(&stopSearch) == 0 && i < finish; i++ {
		acum := i
		var guess string = ""
		for j := 0; j < pwlen; j++ {
			guess = guess + string(cset[acum%uint64(len(cset))])
			acum /= uint64(len(cset))
		}
		privKey := DecryptWithPassphrase(encryptedKey, guess)
		if privKey != "" {
			c <- privKey + " (" + guess + ")"
			return
		}

		atomic.AddUint64(&totalTried, 1)

		fmt.Printf("%6d tries (latest: %s )", atomic.LoadUint64(&totalTried), guess)
		fmt.Printf("%s", eta())
		fmt.Printf("\r")
	}
	if atomic.LoadInt32(&stopSearch) != 0 {
		c <- fmt.Sprintf("%d", i-start) // interrupt signal received, announce our position for the resume code
		return
	}
	c <- ""
}

func eta() string {
	now := time.Now()
	activeTime := now.Sub(startTime)
	workDone := int64(atomic.LoadUint64(&totalTried) - atomic.LoadUint64(&startFrom) - offset)
	workRemaining := int64(atomic.LoadUint64(&chunkSize)) - workDone
	if statsCalculated.Before(now.Add(-10 * time.Second)) {
		statsCalculated = now
		// fmt.Printf("done: %d; remaining: %d ", workDone, workRemaining)
		if activeTime.Seconds() > 5 {
			rate := float64(workDone) / float64(activeTime.Seconds())
			timeRemaining := time.Second * time.Duration((float64(workRemaining) / rate))
			doneBy := now.Add(timeRemaining)
			percent := float64(atomic.LoadUint64(&totalTried)) / float64(atomic.LoadUint64(&chunkSize)) * float64(100)
			stats := fmt.Sprintf(" [%.*fh up, %.*fh left, %s/s, ETA: %s] %2.2f %%", 2, activeTime.Hours(), 2, timeRemaining.Hours(), strings.TrimSpace(fmt.Sprintf("%3.2f", rate)), doneBy.Format("Jan 2 2006 15:04 MST"), percent)
			return stats
		}
	}
	return ""
}

func Brute(routines int, encryptedKey string, charset string, pwlen int, resume uint64) string {
	return BruteChunk(routines, encryptedKey, charset, pwlen, 0, 1, resume)
}

func BruteChunk(routines int, encryptedKey string, charset string, pwlen int, chunk int, chunks int, resume uint64) string {
	if chunk < 0 || chunks <= 0 || chunk >= chunks {
		log.Fatal("chunk/chunks specification invalid")
	}
	if encryptedKey == "" {
		log.Fatal("encryptedKey required")
	}

	if routines < 1 {
		log.Fatal("routines must be >= 1")
	}

	if pwlen < 1 {
		log.Fatal("pw length must be >= 1")
	}

	// Extended ASCII
	//charset := " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~.€.'ƒ"…†‡ˆ‰Š‹Œ.Ž..''""•–—˜™š›œ.žŸ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ"

	// Printable ASCII
	if charset == "" {
		charset = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~."
	}
	fmt.Printf("Using character set: %s\nEncrypted key: %s\nPassword length: %d\n", charset, encryptedKey, pwlen)

	spaceSize := uint64(math.Pow(float64(len(charset)), float64(pwlen)))
	fmt.Printf("Total keyspace size: %d\n", spaceSize)
	chunkSize = spaceSize / uint64(chunks)
	offset = resume * uint64(routines)
	blockSize := uint64(chunkSize / uint64(routines))
	if chunks > 1 {
		startFrom = chunkSize * uint64(chunk)
		csz := chunkSize
		// offset = (resume * uint64(routines)) - (uint64(chunkSize) * uint64(chunks))
		offset = offset - chunkSize*uint64(chunk) //(chunkSize * uint64(chunks))
		if chunk == chunks-1 {
			csz = spaceSize - startFrom
		}
		fmt.Printf("Chunk keyspace size: %d  Starting from point: %d\n", csz, startFrom)
	}

	totalTried = resume * uint64(routines)
	c := make(chan string)

	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, os.Interrupt)
	defer signal.Stop(sigc)

	for i := 0; i < routines; i++ {
		var finish uint64
		if i == routines-1 {
			// Last block needs to go right to the end of the search space
			finish = chunkSize + startFrom
			if chunk == chunks-1 {
				finish = spaceSize
			}
		} else {
			finish = uint64(i)*blockSize + blockSize + startFrom
		}
		start := uint64(i)*blockSize + startFrom + resume
		go searchRange(start, finish, encryptedKey, charset, pwlen, c)
	}
	var minResumeKey uint64 = 0
	i := routines - 1
	for {
		select {
		case s := <-c:
			if s == "" {
				// a search thread has ended!
				i--
				if i <= 0 {
					return "" // last search thread ended!
				}
			} else if atomic.LoadInt32(&stopSearch) != 0 {
				u, err := strconv.ParseUint(s, 10, 64)
				if err == nil && (u+resume < minResumeKey || minResumeKey == 0) {
					minResumeKey = u + resume
				} else if err != nil {
					// happened to crack key on interrupt! return cracked key
					return s
				}
				i--
				if i <= 0 {
					return fmt.Sprintf("to resume, use offset %d", minResumeKey)
				}
			} else { // found/cracked key! return answer!
				return s
			}
		case sig := <-sigc:
			atomic.StoreInt32(&stopSearch, 1) // tell search functions they need to stop
			fmt.Printf("\n(%s)\n", sig.String())
		}
	}
	return "" // not reached
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:lang="http://www.springframework.org/schema/lang"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/lang
                           http://www.springframework.org/schema/lang/spring-lang.xsd
                           http://camel.apache.org/schema/spring
                           http://camel.apache.org/schema/spring/camel-spring.xsd">

    <camelContext xmlns="http://camel.apache.org/schema/spring">
        <route id="spongeConsumerXmlSpringRoute">
            <from uri="sponge:spongeEngine" />
            <transform>
                <simple>XML/Spring route - Received message: ${body}</simple>
            </transform>
            <to uri="stream:out" />
        </route>
    </camelContext>

    <!-- Should be created manually because a custom Camel context is used. -->
    <bean name="camel" class="org.openksavi.sponge.camel.CamelPlugin" />
</beans>


text:
import { TestBed } from '@angular/core/testing';

import { SkyAppConfigHost } from './app-config-host';
import { SkyAppConfigParams } from './app-config-params';
import { SkyAppConfigModule } from './app-config.module';

describe('SkyAppConfigModule', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [SkyAppConfigModule],
    });
  });

  it('should not add providers by default', () => {
    expect(() => TestBed.inject(SkyAppConfigHost)).toThrowError(
      /No provider for SkyAppConfigHost/
    );
    expect(() => TestBed.inject(SkyAppConfigParams)).toThrowError(
      /No provider for SkyAppConfigParams/
    );
  });
});

describe('SkyAppConfigModule.forRoot()', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [SkyAppConfigModule.forRoot()],
    });
  });

  it('should setup providers with default config', () => {
    const hostConfig = TestBed.inject(SkyAppConfigHost);
    expect(hostConfig.host).toEqual({
      frameOptions: {
        none: true,
      },
      url: 'https://host.nxt.blackbaud.com/',
    });

    const paramsConfig = TestBed.inject(SkyAppConfigParams);
    expect(paramsConfig.params).toEqual({
      envid: { required: false },
      leid: { required: false },
      svcid: { required: false },
    });
  });
});

describe('SkyAppConfigModule.forRoot(config)', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        SkyAppConfigModule.forRoot({
          host: {
            frameOptions: {
              blackbaud: true,
            },
          },
          params: {
            foo: {
              value: 'bar',
            },
          },
        }),
      ],
    });
  });

  it('should setup providers with config from forRoot args', () => {
    const hostConfig = TestBed.inject(SkyAppConfigHost);
    const configParams = TestBed.inject(SkyAppConfigParams);
    expect(hostConfig.host.frameOptions).toEqual({
      blackbaud: true,
    });
    expect(configParams.params.foo).toEqual({
      value: 'bar',
    });
  });
});


text:
'use strict';

angular.module('kkNavigation', [])
  .controller('NavigationCtrl', function ($scope, $http) {
    $http.get('/api/is_admin').success(function(data, status, headers, config) {
        $scope.is_admin =  data.is_admin;
    });
    $http.get('/api/user_id').success(function(data, status, headers, config) {
        $scope.user_id =  data.user_id;
    });
    $http.get('/api/hide_matches').success(function(data, status, headers, config) {
        $scope.hide_matches =  data.hide_matches;
    });
  });


text:
Это layout (раскладка) для позиционирования потомков (view) в структуру типа тблицы.

![Демонстрация](/images/main.jpg)

### Возможные режимы раскладки

 - [left](/breaklayout/src/main/java/com/turlir/breaklayout/LeftStrategy.java), прижато к левому краю

 - [center](/breaklayout/src/main/java/com/turlir/breaklayout/CenterStrategy.java), по центру см. иллюстрацию

 - [right](/breaklayout/src/main/java/com/turlir/breaklayout/RightStrategy.java), прижато к правому краю

 - [edge](/breaklayout/src/main/java/com/turlir/breaklayout/EdgeStrategy.java), по краям

 - [as is](/breaklayout/src/main/java/com/turlir/breaklayout/AsIsStrategy.java), как есть

Указанные классы являются потомками
[AlignStrategy](/breaklayout/src/main/java/com/turlir/breaklayout/AlignStrategy.java),
который в свою очередь реализует интерфейс
[Strategy](/breaklayout/src/main/java/com/turlir/breaklayout/Strategy.java).
Реализовав этот интерфейс можно создать собственный режим.

Модуль `app` содержит демо-приложение, модуль `breaklayout` - библиотеку.
Демо-приложение не использует appcompat. Библиотека доступна с api 15, но из-за своей простоты
обеспечивает совместимость и с более низкими версиями.


text: Start [Tutorial](articles/tutorials/walk-around.md).


text:
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.psi.impl.source.tree;

import com.intellij.lang.ASTFactory;
import com.intellij.lang.DefaultASTFactory;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.psi.JavaTokenType;
import com.intellij.psi.impl.source.javadoc.PsiDocTagValueImpl;
import com.intellij.psi.impl.source.javadoc.PsiDocTokenImpl;
import com.intellij.psi.impl.source.tree.java.PsiIdentifierImpl;
import com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl;
import com.intellij.psi.impl.source.tree.java.PsiKeywordImpl;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.java.IJavaDocElementType;
import com.intellij.psi.tree.java.IJavaElementType;
import org.jetbrains.annotations.NotNull;

/**
 * @author yole
 */
public class JavaASTFactory extends ASTFactory {
  private final DefaultASTFactory myDefaultASTFactory = ApplicationManager.getApplication().getService(DefaultASTFactory.class);

  @Override
  public LeafElement createLeaf(@NotNull IElementType type, @NotNull CharSequence text) {
    if (type == JavaTokenType.C_STYLE_COMMENT || type == JavaTokenType.END_OF_LINE_COMMENT) {
      return myDefaultASTFactory.createComment(type, text);
    }
    if (type == JavaTokenType.IDENTIFIER) {
      return new PsiIdentifierImpl(text);
    }
    if (ElementType.KEYWORD_BIT_SET.contains(type)) {
      return new PsiKeywordImpl(type, text);
    }
    if (type instanceof IJavaElementType) {
      return new PsiJavaTokenImpl(type, text);
    }
    if (type instanceof IJavaDocElementType) {
      assert type != JavaDocElementType.DOC_TAG_VALUE_ELEMENT;
      return new PsiDocTokenImpl(type, text);
    }

    return null;
  }

  @Override
  public CompositeElement createComposite(@NotNull IElementType type) {
    if (type == JavaDocElementType.DOC_TAG_VALUE_ELEMENT) {
      return new PsiDocTagValueImpl();
    }

    return null;
  }
}


text:
// <license>
// The MIT License (MIT)
// </license>
// <copyright company="TTRider Technologies, Inc.">
// Copyright (c) 2014-2015 All Rights Reserved
// </copyright>

using System.Collections.Generic;

namespace TTRider.FluidSql
{
    public class AlterIndexStatement : Token, IIndex, IStatement
    {
        public AlterIndexStatement()
        {
            this.Columns = new List<Order>();
            this.Set = new IndexOptions();
            this.RebuildWith = new IndexOptions();
        }

        public Name Name { get; set; }

        public Name On { get; set; }

        public bool Unique { get; set; }

        public bool Rebuild { get; set; }

        public List<Order> Columns { get; private set; }

        public ICreateOrAlterIndexOptions RebuildWith { get; set; }

        public bool Disable { get; set; }

        public bool Reorganize { get; set; }
        //TODO:[ PARTITION = partition_number ][ WITH ( LOB_COMPACTION = { ON | OFF } ) ]

        public ISetIndexOptions Set { get; private set; }

        public bool CheckIfNotExists { get; set; }

        public Token Where { get; set; }
    }
}


text:
$(document).ready(function(){
	var bar = $('.determinate');
        var percent = $('.percent');
        var status = $('#status');

        $('#uploadForm').ajaxForm({
            beforeSubmit: function () {
                status.empty();
                var percentVal = '0%';
                bar.width(percentVal);
                percent.html(percentVal);
            },
            uploadProgress: function (event, position, total, percentComplete) {
                var percentVal = percentComplete + '%';
                bar.width(percentVal);
                percent.html(percentVal);
            },
            complete: function (xhr) {
	    $( "#status" ).html("<button class='btn btn-default green left'>Upload erfolgreich</button>  <button class='btn btn-default orange'>Convertierung läuft!</button>");
setTimeout(function() {
      // Do something after 5 seconds
      location.reload();//reload page
}, 3000);       }
});
$('#uploadForm').find('input[type=file]').change(function(e){
    var ext = this.value.match(/\.([^\.]+)$/)[1];
    switch(ext)
    {
        case 'mp4':
        case 'mkv':
        case 'avi':
            break;
        default:
            this.value='';
    }
});
  $('.toc-wrapper').pushpin({
    offset: 150
  });
   NProgress.start();
   setTimeout(function() { NProgress.set(0.45); $('.fade').removeClass('out'); }, 1500);
   setTimeout(function() { NProgress.set(0.80); $('.fade').removeClass('out'); }, 2200);
   setTimeout(function() { NProgress.done(); $('.fade').removeClass('out'); }, 3000);
   $('.parallax').parallax();
   $('.scrollspy').scrollSpy();
   $('.collapsible').collapsible();
   $('.modal').modal();
   $('select').material_select();
   $('ul.tabs').tabs();
   $('#loader').addClass("hide-loader");
   $('.tooltipped').tooltip({delay: 50});
   $("html").niceScroll({styler:"fb",cursorcolor:"#303F9F", cursorwidth: '10', cursorborderradius: '10px', background: '#404040', spacebarenabled:false,  cursorborder: '', zindex: '1000'});
   $('.button-collapse').sideNav({
    edge: 'left', // Choose the horizontal origin
    menuWidth: 240
  }
);
});
document.addEventListener('submit', function () { document.getElementsByTagName('body')[0].insertAdjacentHTML('beforeend', '

'); });


text:
package nl.knaw.huygens.timbuctoo.databaselog;

import com.google.common.collect.Lists;
import nl.knaw.huygens.timbuctoo.server.GraphWrapper;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

import java.io.Writer;
import java.util.UUID;

import static nl.knaw.huygens.timbuctoo.util.TestGraphBuilder.newGraph;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.text.StringContainsInOrder.stringContainsInOrder;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;

public class GraphLogValidatorTest {

  public static final String VERTEX_ID_1 = "id1";
  public static final String VERTEX_ID_2 = "id2";
  public static final UUID REL_1_ID = UUID.fromString("ff65089c-2ded-4af0-95e7-0476979f96b8");
  public static final UUID REL_2_ID = UUID.fromString("a628b090-ec7f-4608-9356-61728355ad5a");

  @Test
  public void writeReportWritesALineForEachInvalidVertex() throws Exception {
    GraphWrapper wrapper = newGraph().withVertex(v -> v.withTimId(VERTEX_ID_1)
                                                       .withProperty("rev", 1)
                                                       .withLabel("document"))
                                     .withVertex(v -> v.withTimId(VERTEX_ID_2)
                                                       .withProperty("rev", 1)
                                                       .withLabel("document"))
                                     .withVertex(v -> v.withTimId(VERTEX_ID_1)
                                                       .withProperty("rev", 2)
                                                       .withLabel("document"))
                                     .withVertex(v -> v.withTimId(VERTEX_ID_2)
                                                       .withProperty("rev", 2)
                                                       .withLabel("document"))
                                     .withVertex(v -> v.withLabel("history")
                                                       .withOutgoingRelation("NEXT_ITEM", "v1"))
                                     .withVertex("v1", v -> v.withProperty("TIM_tim_id", VERTEX_ID_1)
                                                             .withProperty("rev", 1)
                                                             .withLabel("createVertexEntry")
                                                             .withOutgoingRelation("NEXT_ITEM", "v2")
                                     )
                                     .withVertex("v2", v -> v.withProperty("TIM_tim_id", VERTEX_ID_1)
                                                             .withProperty("rev", 2)
                                                             .withLabel("updateVertexEntry"))
                                     .wrap();
    GraphLogValidator graphLogValidator = new GraphLogValidator(wrapper);
    Writer writer = mock(Writer.class);

    graphLogValidator.writeReport(writer);

    ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
    verify(writer, times(2)).write(stringArgumentCaptor.capture());
    assertThat(stringArgumentCaptor.getAllValues(), containsInAnyOrder(
        stringContainsInOrder(Lists.newArrayList("Vertex", VERTEX_ID_2, "1")),
        stringContainsInOrder(Lists.newArrayList("Vertex", VERTEX_ID_2, "2"))
    ));
    verifyNoMoreInteractions(writer);
  }

  @Test
  public void writeReportWritesALineForEachInvalidEdge() throws Exception {
    GraphWrapper wrapper = newGraph().withVertex("v1", v -> v.withTimId(VERTEX_ID_1)
                                                             .withProperty("rev", 1)
                                                             .withLabel("document"))
                                     .withVertex("v2", v -> v.withTimId(VERTEX_ID_2)
                                                             .withProperty("rev", 1)
                                                             .withLabel("document")
                                                             .withOutgoingRelation("relatedTo", "v1",
                                                               r -> r.withTim_id(REL_1_ID)
                                                                     .withRev(1)
                                                             )
                                                             .withOutgoingRelation("relatedTo", "v1",
                                                               r -> r.withTim_id(REL_1_ID)
                                                                     .withRev(2)
                                                             )
                                                             .withOutgoingRelation("otherRelation", "v1",
                                                               r -> r.withTim_id(REL_2_ID)
                                                                     .withRev(1))
                                                             .withOutgoingRelation("otherRelation", "v1",
                                                               r -> r.withTim_id(REL_2_ID)
                                                                     .withRev(2))
                                     )
                                     .withVertex("v3", v -> v.withLabel("createVertexEntry")
                                                             .withProperty("TIM_tim_id", VERTEX_ID_1)
                                                             .withProperty("rev", 1)
                                                             .withOutgoingRelation("NEXT_ITEM", "v4")
                                     )
                                     .withVertex("v4", v -> v.withLabel("updateVertexEntry")
                                                             .withProperty("TIM_tim_id", VERTEX_ID_2)
                                                             .withProperty("rev", 1)
                                                             .withOutgoingRelation("NEXT_ITEM", "v5")

                                     )
                                     .withVertex("v5", v -> v.withLabel("createEdgeEntry")
                                                             .withProperty("TIM_tim_id", REL_2_ID.toString())
                                                             .withProperty("rev", 1)
                                                             .withOutgoingRelation("NEXT_ITEM", "v6")
                                     )
                                     .withVertex("v6", v -> v.withLabel("updateEdgeEntry")
                                                             .withProperty("TIM_tim_id", REL_2_ID.toString())
                                                             .withProperty("rev", 2)
                                     )
                                     .wrap();
    GraphLogValidator graphLogValidator = new GraphLogValidator(wrapper);
    Writer writer = mock(Writer.class);

    graphLogValidator.writeReport(writer);

    ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
    verify(writer, times(2)).write(stringArgumentCaptor.capture());
    assertThat(stringArgumentCaptor.getAllValues(), containsInAnyOrder(
      stringContainsInOrder(Lists.newArrayList("Edge", REL_1_ID.toString(), "1")),
      stringContainsInOrder(Lists.newArrayList("Edge", REL_1_ID.toString(), "2"))));

    verifyNoMoreInteractions(writer);
  }

}


text:
package restaurant.mcneal.test;

public class SharedDataWaiterTest {

}


text:
package com.bijoykochar.launcher.util;

import android.app.Activity;
import android.content.Context;
import android.util.DisplayMetrics;
import android.view.Display;

/**
 * Created by bijoy on 10/20/15.
 */
public class Utilities {

    public static double getScreenSizeInInches(Activity activity) {
        Display display = activity.getWindowManager().getDefaultDisplay();
        DisplayMetrics displayMetrics = new DisplayMetrics();
        display.getMetrics(displayMetrics);

        int width = displayMetrics.widthPixels / displayMetrics.densityDpi;
        int height = displayMetrics.heightPixels / displayMetrics.densityDpi;

        return Math.sqrt(width * width + height * height);
    }

    /**
     * Converts dp value to pixel value
     *
     * @param context the app context
     * @param dp      the length in dp
     * @return the pixel size
     */
    public static int dpToPixels(Context context, int dp) {
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
    }
}


text:
package org.apache.mxnetexamples.imclassification.models

import org.apache.mxnet._

object Resnet {
  /**
    * Helper to produce individual residual unit
    */
  def residualUnit(data: Symbol, numFilter: Int, stride: Shape, dimMatch: Boolean,
                   name: String = "", bottleNeck: Boolean = true, bnMom: Float = 0.9f,
                   workspace: Int = 256, memonger: Boolean = false): Symbol = {
    val (act1, operated) = if (bottleNeck) {
      val bn1 = Symbol.api.BatchNorm(data = Some(data), fix_gamma = Some(false), eps = Some(2e-5),
        momentum = Some(bnMom), name = name + "_bn1")
      val act1: Symbol = Symbol.api.Activation(data = Some(bn1), act_type = "relu",
        name = name + "_relu1")
      val conv1 = Symbol.api.Convolution(data = Some(act1), num_filter = (numFilter * 0.25).toInt,
        kernel = Shape(1, 1), stride = Some(Shape(1, 1)), pad = Some(Shape(0, 0)),
        no_bias = Some(true), workspace = Some(workspace), name = name + "_conv1")
      val bn2 = Symbol.api.BatchNorm(data = Some(conv1), fix_gamma = Some(false),
        eps = Some(2e-5), momentum = Some(bnMom), name = name + "_bn2")
      val act2 = Symbol.api.Activation(data = Some(bn2), act_type = "relu", name = name + "_relu2")
      val conv2 = Symbol.api.Convolution(data = Some(act2), num_filter = (numFilter * 0.25).toInt,
        kernel = Shape(3, 3), stride = Some(stride), pad = Some(Shape(1, 1)),
        no_bias = Some(true), workspace = Some(workspace), name = name + "_conv2")
      val bn3 = Symbol.api.BatchNorm(data = Some(conv2), fix_gamma = Some(false),
        eps = Some(2e-5), momentum = Some(bnMom), name = name + "_bn3")
      val act3 = Symbol.api.Activation(data = Some(bn3), act_type = "relu", name = name + "_relu3")
      val conv3 = Symbol.api.Convolution(data = Some(act3), num_filter = numFilter,
        kernel = Shape(1, 1), stride = Some(Shape(1, 1)), pad = Some(Shape(0, 0)),
        no_bias = Some(true), workspace = Some(workspace), name = name + "_conv3")
      (act1, conv3)
    } else {
      val bn1 = Symbol.api.BatchNorm(data = Some(data), fix_gamma = Some(false),
        eps = Some(2e-5), momentum = Some(bnMom), name = name + "_bn1")
      val act1 = Symbol.api.Activation(data = Some(bn1), act_type = "relu", name = name + "_relu1")
      val conv1 = Symbol.api.Convolution(data = Some(act1), num_filter = numFilter,
        kernel = Shape(3, 3), stride = Some(stride), pad = Some(Shape(1, 1)),
        no_bias = Some(true), workspace = Some(workspace), name = name + "_conv1")
      val bn2 = Symbol.api.BatchNorm(data = Some(conv1), fix_gamma = Some(false),
        eps = Some(2e-5), momentum = Some(bnMom), name = name + "_bn2")
      val act2 = Symbol.api.Activation(data = Some(bn2), act_type = "relu", name = name + "_relu2")
      val conv2 = Symbol.api.Convolution(data = Some(act2), num_filter = numFilter,
        kernel = Shape(3, 3), stride = Some(Shape(1, 1)), pad = Some(Shape(1, 1)),
        no_bias = Some(true), workspace = Some(workspace), name = name + "_conv2")
      (act1, conv2)
    }
    val shortcut = if (dimMatch) {
      data
    } else {
      Symbol.api.Convolution(Some(act1), num_filter = numFilter, kernel = Shape(1, 1),
        stride = Some(stride), no_bias = Some(true), workspace = Some(workspace),
        name = name + "_sc")
    }
    operated + shortcut
  }

  /**
    * Helper for building the resnet Symbol
    */
  def resnet(units: List[Int], numStages: Int, filterList: List[Int], numClasses: Int,
             imageShape: List[Int], bottleNeck: Boolean = true, bnMom: Float = 0.9f,
             workspace: Int = 256, dtype: String = "float32", memonger: Boolean = false): Symbol = {
    assert(units.size == numStages)
    var data = Symbol.Variable("data", shape = Shape(List(4) ::: imageShape), dType = DType.Float32)
    if (dtype == "float32") {
      data = Symbol.api.identity(Some(data), "id")
    } else if (dtype == "float16") {
      data = Symbol.api.cast(Some(data), "float16")
    }
    data = Symbol.api.BatchNorm(Some(data), fix_gamma = Some(true), eps = Some(2e-5),
      momentum = Some(bnMom), name = "bn_data")
    val List(channels, height, width) = imageShape
    var body = if (height <= 32) {
      Symbol.api.Convolution(Some(data), num_filter = filterList.head, kernel = Shape(7, 7),
        stride = Some(Shape(1, 1)), pad = Some(Shape(1, 1)), no_bias = Some(true), name = "conv0",
        workspace = Some(workspace))
    } else {
      var body0 = Symbol.api.Convolution(Some(data), num_filter = filterList.head,
        kernel = Shape(3, 3), stride = Some(Shape(2, 2)), pad = Some(Shape(3, 3)),
        no_bias = Some(true), name = "conv0", workspace = Some(workspace))
      body0 = Symbol.api.BatchNorm(Some(body0), fix_gamma = Some(false), eps = Some(2e-5),
        momentum = Some(bnMom), name = "bn0")
      body0 = Symbol.api.Activation(Some(body0), act_type = "relu", name = "relu0")
      Symbol.api.Pooling(Some(body0), kernel = Some(Shape(3, 3)), stride = Some(Shape(2, 2)),
        pad = Some(Shape(1, 1)), pool_type = Some("max"))
    }
    for (((filter, i), unit) <- filterList.tail.zipWithIndex.zip(units)) {
      val stride = Shape(if (i == 0) 1 else 2, if (i == 0) 1 else 2)
      body = residualUnit(body, filter, stride, false, name = s"stage${i + 1}_unit${1}",
        bottleNeck = bottleNeck, workspace = workspace, memonger = memonger)
      for (j <- 0 until unit - 1) {
        body = residualUnit(body, filter, Shape(1, 1), true, s"stage${i + 1}_unit${j + 2}",
          bottleNeck, workspace = workspace, memonger = memonger)
      }
    }
    val bn1 = Symbol.api.BatchNorm(Some(body), fix_gamma = Some(false), eps = Some(2e-5),
      momentum = Some(bnMom), name = "bn1")
    val relu1 = Symbol.api.Activation(Some(bn1), act_type = "relu", name = "relu1")
    val pool1 = Symbol.api.Pooling(Some(relu1), global_pool = Some(true),
      kernel = Some(Shape(7, 7)), pool_type = Some("avg"), name = "pool1")
    val flat = Symbol.api.Flatten(Some(pool1))
    var fc1 = Symbol.api.FullyConnected(Some(flat), num_hidden = numClasses, name = "fc1")
    if (dtype == "float16") {
      fc1 = Symbol.api.cast(Some(fc1), "float32")
    }
    Symbol.api.SoftmaxOutput(Some(fc1), name = "softmax")
  }

  /**
    * Gets the resnet model symbol
    * @param numClasses Number of classes to classify into
    * @param numLayers Number of residual layers
    * @param imageShape The image shape as List(channels, height, width)
    * @param convWorkspace Maximum temporary workspace allowed (MB) in convolutions
    * @param dtype Type of data (float16, float32, etc) to use during computation
    * @return Model symbol
    */
  def getSymbol(numClasses: Int, numLayers: Int, imageShape: List[Int], convWorkspace: Int = 256,
                dtype: String = "float32"): Symbol = {
    val List(channels, height, width) = imageShape
    val (numStages, units, filterList, bottleNeck): (Int, List[Int], List[Int], Boolean) =
      if (height <= 28) {
        val (perUnit, filterList, bottleNeck) = if ((numLayers - 2) % 9 == 0 && numLayers > 165) {
          (List(Math.floor((numLayers - 2) / 9).toInt),
            List(16, 64, 128, 256),
            true)
        } else if ((numLayers - 2) % 6 == 0 && numLayers < 164) {
          (List(Math.floor((numLayers - 2) / 6).toInt),
            List(16, 16, 32, 64),
            false)
        } else {
          throw new Exception(s"Invalid number of layers: ${numLayers}")
        }
        val numStages = 3
        val units = (1 to numStages).map(_ => perUnit.head).toList
        (numStages, units, filterList, bottleNeck)
      } else {
        val (filterList, bottleNeck) = if (numLayers >= 50) {
          (List(64, 256, 512, 1024, 2048), true)
        } else {
          (List(64, 64, 128, 256, 512), false)
        }
        val units: List[Int] = Map(
          18 -> List(2, 2, 2, 2),
          34 -> List(3, 4, 6, 3),
          50 -> List(3, 4, 6, 3),
          101 -> List(3, 4, 23, 3),
          152 -> List(3, 8, 36, 3),
          200 -> List(3, 24, 36, 3),
          269 -> List(3, 30, 48, 8)
        ).get(numLayers) match {
          case Some(x) => x
          case None => throw new Exception(s"Invalid number of layers: ${numLayers}")
        }
        (4, units, filterList, bottleNeck)
      }
    resnet(units, numStages, filterList, numClasses, imageShape, bottleNeck,
      workspace = convWorkspace, dtype = dtype)
  }
}


text:
/*
 * test_export.cpp
 *
 *  Created on: 2013-4-30
 *      Author: fasiondog
 */

#include "doctest/doctest.h"
#include <hikyuu/config.h>

#if HKU_SUPPORT_SERIALIZATION

#include <fstream>
#include <boost/archive/xml_oarchive.hpp>
#include <boost/archive/xml_iarchive.hpp>
#include <hikyuu/StockManager.h>
#include <hikyuu/trade_sys/moneymanager/build_in.h>

using namespace hku;

/**
 * @defgroup test_money_manager_serialization test_money_manager_serialization
 * @ingroup test_hikyuu_trade_sys_suite
 * @{
 */

/** @par 检测点 */
TEST_CASE("test_MM_FixedCount_export") {
    StockManager& sm = StockManager::instance();
    string filename(sm.tmpdir());
    filename += "/Fixed_MM.xml";

    MoneyManagerPtr mm1 = MM_FixedCount(100);
    {
        std::ofstream ofs(filename);
        boost::archive::xml_oarchive oa(ofs);
        oa << BOOST_SERIALIZATION_NVP(mm1);
    }

    MoneyManagerPtr mm2;
    {
        std::ifstream ifs(filename);
        boost::archive::xml_iarchive ia(ifs);
        ia >> BOOST_SERIALIZATION_NVP(mm2);
    }

    CHECK_EQ(mm1->name(), mm2->name());
}

/** @} */

#endif /* HKU_SUPPORT_SERIALIZATION */


text:
export interface DropdownSettings {
    label?: string;
    color?: string;
    size?: string;
    dropUp?: boolean;
    split?: boolean;
    alignment?: string;
    header?: string;
}


text:
<?php
namespace FOA\Responder_Bundle\Renderer;

use Aura\View\View;

class AuraView implements RendererInterface
{
    protected $engine;

    public function __construct(View $engine)
    {
        $this->engine = $engine;
    }

    public function render($data, $view, $layout = null)
    {
        $this->engine->setView($view);
        $this->engine->setLayout($layout);
        $this->engine->addData($data);
        return $this->engine->__invoke();
    }

    public function getEngine()
    {
        return $this->engine;
    }
}


text:
<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <!--
    <parameters>
        <parameter key="ordr_data.example.class">Ordr\DataBundle\Example</parameter>
    </parameters>

    <services>
        <service id="ordr_data.example" class="%ordr_data.example.class%">
            <argument type="service" id="service_id" />
            <argument>plain_value</argument>
            <argument>%parameter_name%</argument>
        </service>
    </services>
    -->
</container>


text:
// This source code has been donated to the Public Domain.  Do
// whatever you want with it.

// Generic C++ containers.  Problem: STL is murder on compile times,
// and is hard to debug.  These are substitutes that compile much
// faster and are somewhat easier to debug.  Not as featureful,
// efficient or hammered-on as STL though.  You can use STL
// implementations if you want; see _TU_USE_STL.

#ifndef CONTAINER_H
#define CONTAINER_H

#include "tu_config.h"
#include "utility.h"
#include <stdlib.h>
#include <string.h>	// for strcmp and friends
#include <new>	// for placement new

// If you prefer STL implementations of array<> (i.e. std::vector) and
// hash<> (i.e. std::hash_map) instead of home cooking, then put
// -D_TU_USE_STL=1 in your compiler flags, or do it in tu_config.h, or do
// it right here:
//#define _TU_USE_STL 1

template<class T>
class fixed_size_hash
// Computes a hash of an object's representation.
{
public:
	size_t	operator()(const T& data) const
	{
		unsigned char*	p = (unsigned char*) &data;
		int	size = sizeof(T);

		return sdbm_hash(p, size);
	}
};

template<class T>
class identity_hash
// Hash is just the input value; can use this for integer-indexed hash tables.
{
public:
	size_t	operator()(const T& data) const
	{
		return (size_t) data;
	}
};

#if _TU_USE_STL == 1

//
// Thin wrappers around STL
//

//// @@@ crap compatibility crap
//#define StlAlloc(size) malloc(size)
//#define StlFree(ptr, size) free(ptr)

#include <vector>
#include <hash_map>
#include <string>

// array<> is much like std::vector<>
//
// @@ move this towards a strict subset of std::vector ?  Compatibility is good.
template<class T> class array : public std::vector<T>
{
public:
	int	size() const { return (int) std::vector<T>::size(); }

	void	append(const array<T>& other)
	// Append the given data to our array.
	{
		std::vector<T>::insert(end(), other.begin(), other.end());
	}

	void	append(const T other[], int count)
	{
		// This will probably work.  Depends on std::vector<T>::iterator being typedef'd as T*
		std::vector<T>::insert(end(), &other[0], &other[count]);
	}

	void	remove(int index)
	{
		std::vector<T>::erase(begin() + index);
	}

	void	insert(int index, const T& val = T())
	{
		std::vector<T>::insert(begin() + index, val);
	}

	void	release()
	{
		// Drop all storage.
		std::vector<T>	temp;
		this->swap(temp);
	}
};

// hash<> is similar to std::hash_map<>
//
// @@ move this towards a strict subset of std::hash_map<> ?
template<class T, class U, class hash_functor = fixed_size_hash<T> >
class hash : public stdext::hash_map<T, U, hash_functor>
{
public:
	// extra convenience interfaces
	void	set(const T& key, const U& value)
	// Set a new or existing value under the key, to the value.
	{
		(*this)[key] = value;
	}

	void	add(const T& key, const U& value)
	{
		assert(find(key) == end());
		(*this)[key] = value;
	}

	bool	is_empty() const { return empty(); }

	bool	get(const T& key, U* value) const
	// Retrieve the value under the given key.
	//
	// If there's no value under the key, then return false and leave
	// *value alone.
	//
	// If there is a value, return true, and set *value to the entry's
	// value.
	//
	// If value == NULL, return true or false according to the
	// presence of the key, but don't touch *value.
	{
		const_iterator	it = find(key);
		if (it != end())
		{
			if (value) *value = it->second;
			return true;
		}
		else
		{
			return false;
		}
	}
};

// // tu_string is a subset of std::string, for the most part
// class tu_string : public std::string
// {
// public:
// 	tu_string(const char* str) : std::string(str) {}
// 	tu_string() : std::string() {}
// 	tu_string(const tu_string& str) : std::string(str) {}

// 	int	length() const { return (int) std::string::length(); }
// };

// template<class U>
// class string_hash : public hash<tu_string, U, std::hash<std::string> >
// {
// };

#else // not _TU_USE_STL

//
// Homemade containers; almost strict subsets of STL.
//

#ifdef _WIN32
#pragma warning(disable : 4345)	// in MSVC 7.1, warning about placement new POD default initializer
#endif // _WIN32

template<class T>
class array {
// Resizable array.  Don't put anything in here that can't be moved
// around by bitwise copy.  Don't keep the address of an element; the
// array contents will move around as it gets resized.
//
// Default constructor and destructor get called on the elements as
// they are added or removed from the active part of the array.
public:
	typedef T value_type;

	array() : m_buffer(0), m_size(0), m_buffer_size(0) {}
	array(int size_hint) : m_buffer(0), m_size(0), m_buffer_size(0) { resize(size_hint); }
	array(const array<T>& a)
		:
		m_buffer(0),
		m_size(0),
		m_buffer_size(0)
	{
		operator=(a);
	}
	~array() {
		clear();
	}

	// Basic array access.
	T&	operator[](int index) { assert(index >= 0 && index < m_size); return m_buffer[index]; }
	const T&	operator[](int index) const { assert(index >= 0 && index < m_size); return m_buffer[index]; }
	int	size() const { return m_size; }

	void	push_back(const T& val)
	// Insert the given element at the end of the array.
	{
		// DO NOT pass elements of your own vector into
		// push_back()!  Since we're using references,
		// resize() may munge the element storage!
		// this is irrelevant to MAC OS !!!
//		assert(&val < &m_buffer[0] || &val > &m_buffer[m_buffer_size]);

		int	new_size = m_size + 1;
		resize(new_size);
		(*this)[new_size-1] = val;
	}

	void	pop_back()
	// Remove the last element.
	{
		assert(m_size > 0);
		resize(m_size - 1);
	}

	// Access the first element.
	T&	front() { return (*this)[0]; }
	const T&	front() const { return (*this)[0]; }

	// Access the last element.
	T&	back() { return (*this)[m_size-1]; }
	const T&	back() const { return (*this)[m_size-1]; }

	void	clear()
	// Empty and destruct all elements.
	{
		resize(0);
	}

	void	operator=(const array<T>& a)
	// Array copy.  Copies the contents of a into this array.
	{
		resize(a.size());
		for (int i = 0; i < m_size; i++) {
			*(m_buffer + i) = a[i];
		}
	}

	void	remove(int index)
	// Removing an element from the array is an expensive operation!
	// It compacts only after removing the last element.
	{
		assert(index >= 0 && index < m_size);

		if (m_size == 1)
		{
			clear();
		}
		else
		{
			m_buffer[index].~T();	// destructor

			memmove(m_buffer+index, m_buffer+index+1, sizeof(T) * (m_size - 1 - index));
			m_size--;
		}
	}

	void	insert(int index, const T& val = T())
	// Insert the given object at the given index shifting all the elements up.
	{
		assert(index >= 0 && index <= m_size);

		resize(m_size + 1);

		if (index < m_size - 1)
		{
			// is it safe to use memmove?
			memmove(m_buffer+index+1, m_buffer+index, sizeof(T) * (m_size - 1 - index));
		}

		// Copy-construct into the newly opened slot.
		new (m_buffer + index) T(val);
	}

	void	append(const array<T>& other)
	// Append the given data to our array.
	{
		append(other.m_buffer, other.size());
	}

	void	append(const T other[], int count)
	// Append the given data to our array.
	{
		if (count > 0)
		{
			int	size0 = m_size;
			resize(m_size + count);
			// Must use operator=() to copy elements, in case of side effects (e.g. ref-counting).
			for (int i = 0; i < count; i++)
			{
				m_buffer[i + size0] = other[i];
			}
		}
	}

	void	resize(int new_size)
	// Preserve existing elements via realloc.
	//
	// Newly created elements are initialized with default element
	// of T.  Removed elements are destructed.
	{
		assert(new_size >= 0);

		int	old_size = m_size;

		// Destruct old elements (if we're shrinking).
		{for (int i = new_size; i < old_size; i++) {
			(m_buffer + i)->~T();
		}}

		if (new_size == 0) {
			m_buffer_size = 0;
			reserve(0);
		} else if (new_size <= m_buffer_size && new_size > m_buffer_size >> 1) {
			// don't compact yet.
			assert(m_buffer != 0);
		} else {
			int	new_buffer_size = new_size + (new_size >> 1);
			reserve(new_buffer_size);
		}

		// Copy default T into new elements.
		{for (int i = old_size; i < new_size; i++) {
			new (m_buffer + i) T();	// placement new
		}}

		m_size = new_size;
	}

	void	reserve(int rsize)
	// @@ TODO change this to use ctor, dtor, and operator=
	// instead of preserving existing elements via binary copy via
	// realloc?
	{
		assert(m_size >= 0);

		int	old_size = m_buffer_size;
		old_size = old_size;	// don't warn that this is unused.
		m_buffer_size = rsize;

		// Resize the buffer.
		if (m_buffer_size == 0) {
			if (m_buffer) {
				tu_free(m_buffer, sizeof(T) * old_size);
			}
			m_buffer = 0;
		} else {
			if (m_buffer) {
				m_buffer = (T*) tu_realloc(m_buffer, sizeof(T) * m_buffer_size, sizeof(T) * old_size);
			} else {
				m_buffer = (T*) tu_malloc(sizeof(T) * m_buffer_size);
				memset(m_buffer, 0, (sizeof(T) * m_buffer_size));
			}
			assert(m_buffer);	// need to throw (or something) on malloc failure!
		}
	}

	void	transfer_members(array<T>* a)
	// UNSAFE!  Low-level utility function: replace this array's
	// members with a's members.
	{
		m_buffer = a->m_buffer;
		m_size = a->m_size;
		m_buffer_size = a->m_buffer_size;

		a->m_buffer = 0;
		a->m_size = 0;
		a->m_buffer_size = 0;
	}

	// Iterator API, for STL compatibility.
	typedef T* iterator;
	typedef const T* const_iterator;

	iterator begin() {
		return m_buffer;
	}
	iterator end() {
		return m_buffer + m_size;
	}
	const_iterator begin() const {
		return m_buffer;
	}
	const_iterator end() const {
		return m_buffer + m_size;
	}

private:
	T*	m_buffer;
	int	m_size;
	int	m_buffer_size;
};

// there are problem with STL
#if 0
template<class T>
class shared_array {
	// Resizable array.  Don't put anything in here that can't be moved
	// around by bitwise copy.  Don't keep the address of an element; the
	// array contents will move around as it gets resized.
	//
	// Default constructor and destructor get called on the elements as
	// they are added or removed from the active part of the array.
public:
	shared_array() : m_buffer(0), m_size(0), m_buffer_size(0) {}
	shared_array(int size_hint) : m_buffer(0), m_size(0), m_buffer_size(0) { resize(size_hint); }
	shared_array(const shared_array<T>& a)
		:
		m_buffer(0),
		m_buffer(0),
		m_size(0),
		m_buffer_size(0)
	{
		operator=(a);
	}
	~shared_array() {
		clear();
	}

	// Basic array access.
	T&	operator[](int index) { assert(index >= 0 && index < m_size); create_own_copy(); return m_buffer[index]; }
	const T&	operator[](int index) const { assert(index >= 0 && index < m_size); return m_buffer[index]; }
	int	size() const { return m_size; }

	void	push_back(const T& val)
	// Insert the given element at the end of the array.
	{
		// DO NOT pass elements of your own vector into
		// push_back()!  Since we're using references,
		// resize() may munge the element storage!
		assert(&val < &m_buffer[0] || &val > &m_buffer[m_buffer_size]);

		int	new_size = m_size + 1;
		resize(new_size);
		(*this)[new_size-1] = val;
	}

	void	pop_back()
		// Remove the last element.
	{
		assert(m_size > 0);
		resize(m_size - 1);
	}

	// Access the first element.
	T&	front() { create_own_copy();return (*this)[0]; }
	const T&	front() const { return (*this)[0]; }

	// Access the last element.
	T&	back() { create_own_copy(); return (*this)[m_size-1]; }
	const T&	back() const { return (*this)[m_size-1]; }

	void	clear()
	// Empty and destruct all elements.
	{
		resize( 0 );
	}

	void	operator=(const shared_array<T>& a)
	// Array copy.  Copies the contents of a into this array.
	{

		m_buffer = a.m_buffer;
		m_size = a.m_size;
		m_buffer_size = a.m_buffer_size;

		int * counter;
		counter = reinterpret_cast<int*>( m_buffer ) - 1;

		(*counter)++;
	}

	void	remove(int index)
	// Removing an element from the array is an expensive operation!
	// It compacts only after removing the last element.
	{
		create_own_copy();
		assert(index >= 0 && index < m_size);

		if (m_size == 1)
		{
			clear();
		}
		else
		{
			m_buffer[index].~T();	// destructor

			memmove(m_buffer+index, m_buffer+index+1, sizeof(T) * (m_size - 1 - index));
			m_size--;
		}
	}

	void	insert(int index, const T& val = T())
	// Insert the given object at the given index shifting all the elements up.
	{
		create_own_copy();
		assert(index >= 0 && index <= m_size);

		resize(m_size + 1);

		if (index < m_size - 1)
		{
			// is it safe to use memmove?
			memmove(m_buffer+index+1, m_buffer+index, sizeof(T) * (m_size - 1 - index));
		}

		// Copy-construct into the newly opened slot.
		new (m_buffer + index) T(val);
	}

	void	append(const shared_array<T>& other)
	// Append the given data to our array.
	{
		append(other.m_buffer, other.size());
	}

	void	append(const T other[], int count)
	// Append the given data to our array.
	{
		create_own_copy();
		if (count > 0)
		{
			int	size0 = m_size;
			resize(m_size + count);
			// Must use operator=() to copy elements, in case of side effects (e.g. ref-counting).
			for (int i = 0; i < count; i++)
			{
				m_buffer[i + size0] = other[i];
			}
		}
	}

	void	resize(int new_size)
	// Preserve existing elements via realloc.
	//
	// Newly created elements are initialized with default element
	// of T.  Removed elements are destructed.
	{
		private_resize( new_size );
	}

	void	reserve(int rsize)
		// @@ TODO change this to use ctor, dtor, and operator=
		// instead of preserving existing elements via binary copy via
		// realloc?
	{
		assert(m_size >= 0);
		assert( owns_buffer() );

		int	old_size = m_buffer_size;
		old_size = old_size;	// don't warn that this is unused.
		m_buffer_size = rsize;

		// Resize the buffer.
		if (m_buffer_size == 0) {
			if (m_buffer) {
				tu_free(get_buffer(), sizeof(T) * old_size + sizeof(int));
			}
			m_buffer = 0;
		} else {
			if (m_buffer) {
				set_buffer( tu_realloc( get_buffer(), sizeof(T) * m_buffer_size + sizeof(int), sizeof(T) * old_size  + sizeof(int) ) );
			} else {
				set_buffer( tu_malloc(sizeof(T) * m_buffer_size + sizeof(int)) );
				memset(m_buffer, 0, (sizeof(T) * m_buffer_size));
			}
			assert(m_buffer);	// need to throw (or something) on malloc failure!

			*( reinterpret_cast<int*>( m_buffer ) - 1 ) = 1;
		}
	}

private:

	inline void *get_buffer()
	{
		return reinterpret_cast<int*>( m_buffer ) - 1;
	}

	inline void set_buffer( void * buffer )
	{
		m_buffer = reinterpret_cast<T*>( reinterpret_cast<int*>( buffer ) + 1 );
	}

	bool	owns_buffer()
	{
		return m_buffer == NULL || ( *( reinterpret_cast<int*>( m_buffer ) - 1 ) == 1 );
	}

	void	create_own_copy()
	{
		if( m_buffer )
		{
			int * counter;

			counter = reinterpret_cast<int*>( m_buffer ) - 1;
			assert( *counter != 0 );

			if( *counter != 1 )
			{
				T*	old_buffer;
				int	old_size;

				old_buffer = m_buffer;
				old_size = m_size;

				m_buffer = 0;
				m_size = 0;
				m_buffer_size = 0;

				private_resize( old_size );

				// copy
				{for (int i = 0; i < old_size; i++) {
					m_buffer[i] = old_buffer[ i ];
				}}

				( *counter )--;
			}
		}
	}

	void	private_resize(int new_size)
		// Preserve existing elements via realloc.
		//
		// Newly created elements are initialized with default element
		// of T.  Removed elements are destructed.
	{
		assert( new_size >= 0 );

		if( !owns_buffer() )
		{
			if( new_size )
			{
				create_own_copy();
				private_resize( new_size );
			}
			else
			{
				int * counter;

				counter = reinterpret_cast<int*>( m_buffer ) - 1;

				( *counter )--;

				m_buffer = 0;
				m_buffer_size = 0;
				m_size = 0;
			}
		}
		else
		{
			int	old_size = m_size;
			m_size = new_size;

			// Destruct old elements (if we're shrinking).
			{for (int i = new_size; i < old_size; i++) {
				(m_buffer + i)->~T();
			}}

			if (new_size == 0) {
				m_buffer_size = 0;
				reserve(m_buffer_size);
			} else if (m_size <= m_buffer_size && m_size > m_buffer_size >> 1) {
				// don't compact yet.
				assert(m_buffer != 0);
			} else {
				int	new_buffer_size = m_size + (m_size >> 2);
				reserve(new_buffer_size);
			}

			// Copy default T into new elements.
			{for (int i = old_size; i < new_size; i++) {
				new (m_buffer + i) T();	// placement new
			}}
		}
	}

	T*	m_buffer;
	int	m_size;
	int	m_buffer_size;
};
#endif

template<class T, class U, class hash_functor = fixed_size_hash<T> >
class hash {
// Hash table, linear probing, internal chaining.  One
// interesting/nice thing about this implementation is that the table
// itself is a flat chunk of memory containing no pointers, only
// relative indices.  If the key and value types of the hash contain
// no pointers, then the hash can be serialized using raw IO.  Could
// come in handy.
//
// Never shrinks, unless you explicitly clear() it.  Expands on
// demand, though.  For best results, if you know roughly how big your
// table will be, default it to that size when you create it.
public:
	hash() : m_table(NULL) { }
	hash(int size_hint) : m_table(NULL) { set_capacity(size_hint); }
	~hash() { clear(); }

	hash(const hash<T,U,hash_functor>& src)
		:
		m_table(NULL)
	{
		*this = src;
	}

	void	operator=(const hash<T,U,hash_functor>& src)
	{
		clear();
		if (src.is_empty() == false)
		{
			set_capacity(src.size());

			for (const_iterator it = src.begin(); it != src.end(); ++it)
			{
				add(it->first, it->second);
			}
		}
	}

	// For convenience
	U&	operator[](const T& key)
	{
		int	index = find_index(key);
		if (index >= 0)
		{
			return E(index).second;
		}
		add(key, (U) 0);
		index = find_index(key);
		if (index >= 0)
		{
			return E(index).second;
		}

		// Doesn't look nice but removes
		// warning on non-void function not returning.
		assert(0);
		return E(index).second;
	}

	void	set(const T& key, const U& value)
	// Set a new or existing value under the key, to the value.
	{
		int	index = find_index(key);
		if (index >= 0)
		{
			E(index).second = value;
			return;
		}

		// Entry under key doesn't exist.
		add(key, value);
	}

	void	add(const T& key, const U& value)
	// Add a new value to the hash table, under the specified key.
	{
		assert(find_index(key) == -1);

		check_expand();
		assert(m_table);
		m_table->m_entry_count++;

		unsigned int	hash_value = (unsigned int) compute_hash(key);
		int	index = hash_value & m_table->m_size_mask;

		entry*	natural_entry = &(E(index));

		if (natural_entry->is_empty()) {
			// Put the new entry in.
			new (natural_entry) entry(key, value, -1, hash_value);
		} else if (natural_entry->is_tombstone()) {
			// Put the new entry in, without disturbing the rest of the chain.
			int next_in_chain = natural_entry->m_next_in_chain;
			new (natural_entry) entry(key, value, next_in_chain, hash_value);
		} else {
			// Find a blank spot.
			int	blank_index = index;
			for (;;)
			{
				blank_index = (blank_index + 1) & m_table->m_size_mask;
				if (E(blank_index).is_empty()) break;	// found it
			}
			entry*	blank_entry = &E(blank_index);

			if (int(natural_entry->m_hash_value & m_table->m_size_mask) == index)
			{
				// Collision.  Link into this chain.

				// Move existing list head.
				// @@ this could invalidate an existing iterator
				new (blank_entry) entry(*natural_entry);	// placement new, copy ctor

				// Put the new info in the natural entry.
				natural_entry->first = key;
				natural_entry->second = value;
				natural_entry->m_next_in_chain = blank_index;
				natural_entry->m_hash_value = hash_value;
			}
			else
			{
				// Existing entry does not naturally
				// belong in this slot.  Existing
				// entry must be moved.

				// Find natural location of collided element (i.e. root of chain)
				int	collided_index = (int) (natural_entry->m_hash_value & m_table->m_size_mask);
				for (;;)
				{
					entry*	e = &E(collided_index);
					if (e->m_next_in_chain == index)
					{
						// Here's where we need to splice.
						// @@ this could invalidate an existing iterator
						new (blank_entry) entry(*natural_entry);
						e->m_next_in_chain = blank_index;
						break;
					}
					collided_index = e->m_next_in_chain;
					assert(collided_index >= 0 && collided_index <= m_table->m_size_mask);
				}

				// Put the new data in the natural entry.
				natural_entry->first = key;
				natural_entry->second = value;
				natural_entry->m_hash_value = hash_value;
				natural_entry->m_next_in_chain = -1;
			}
		}
	}

	void	clear()
	// Remove all entries from the hash table.
	{
		if (m_table)
		{
			// Delete the entries.
			for (int i = 0, n = m_table->m_size_mask; i <= n; i++)
			{
				entry*	e = &E(i);
				if (e->is_empty() == false && e->is_tombstone() == false)
				{
					e->clear();
				}
			}
			tu_free(m_table, sizeof(table) + sizeof(entry) * (m_table->m_size_mask + 1));
			m_table = NULL;
		}
	}

	bool	is_empty() const
	// Returns true if the hash is empty.
	{
		return m_table == NULL || m_table->m_entry_count == 0;
	}

	bool	get(const T& key, U* value) const
	// Retrieve the value under the given key.
	//
	// If there's no value under the key, then return false and leave
	// *value alone.
	//
	// If there is a value, return true, and set *value to the entry's
	// value.
	//
	// If value == NULL, return true or false according to the
	// presence of the key, but don't touch *value.
	{
		int	index = find_index(key);
		if (index >= 0)
		{
			if (value) {
				*value = E(index).second;
			}
			return true;
		}
		return false;
	}

	int	size() const
	{
		return m_table == NULL ? 0 : m_table->m_entry_count;
	}

	void	check_expand()
	// Resize the hash table to fit one more entry.  Often this
	// doesn't involve any action.
	{
		if (m_table == NULL) {
			// Initial creation of table.  Make a minimum-sized table.
			set_raw_capacity(16);
		} else if (m_table->m_entry_count * 3 > (m_table->m_size_mask + 1) * 2) {
			// Table is more than 2/3rds full.  Expand.
			set_raw_capacity((m_table->m_size_mask + 1) * 2);
		}
	}

	void check_shrink()
	// Shrink our capacity, if it makes sense.
	{
		if (m_table) {
			if (size() * 3 < m_table->m_size_mask + 1) {
				// Table is less than 1/3 full.  Shrink.
				set_capacity(size());
			}
		}
	}

	void	resize(size_t n)
	// Hint the bucket count to >= n.
	{
		// Not really sure what this means in relation to
		// STLport's hash_map... they say they "increase the
		// bucket count to at least n" -- but does that mean
		// their real capacity after resize(n) is more like
		// n*2 (since they do linked-list chaining within
		// buckets?).
		set_capacity(n);
	}

	void	set_capacity(int new_size)
	// Size the hash so that it can comfortably contain the given
	// number of elements.  If the hash already contains more
	// elements than new_size, then this may be a no-op.
	{
		if (new_size < size()) {
			// Make sure requested size is large enough to
			// contain existing elements!
			new_size = size();
		}
		int	new_raw_size = (new_size * 3) / 2;
		set_raw_capacity(new_raw_size);
	}

	// Behaves much like std::pair
	struct entry
	{
		int	m_next_in_chain;	// internal chaining for collisions
		size_t	m_hash_value;		// avoids recomputing.  Worthwhile?
		T	first;
		U	second;

		entry() : m_next_in_chain(-2) {}
		entry(const entry& e)
			: m_next_in_chain(e.m_next_in_chain), m_hash_value(e.m_hash_value), first(e.first), second(e.second)
		{
		}
		entry(const T& key, const U& value, int next_in_chain, int hash_value)
			: m_next_in_chain(next_in_chain), m_hash_value(hash_value), first(key), second(value)
		{
		}
		bool is_empty() const { return m_next_in_chain == -2; }
		bool is_end_of_chain() const { return m_next_in_chain == -1; }
		bool is_tombstone() const { return m_hash_value == TOMBSTONE_HASH; }

		void	clear()
		{
			first.~T();	// placement delete
			second.~U();	// placement delete
			m_next_in_chain = -2;
			m_hash_value = ~TOMBSTONE_HASH;
		}

		void make_tombstone() {
			first.~T();
			second.~U();
			m_hash_value = TOMBSTONE_HASH;
		}
	};

	// Iterator API, like STL.

	class const_iterator
	{
	public:
		T	get_key() const { return m_hash->E(m_index).first; }
		U	get_value() const { return m_hash->E(m_index).second; }

		const entry&	operator*() const
		{
			assert(is_end() == false && m_hash->E(m_index).is_empty() == false);
			assert(m_hash->E(m_index).is_tombstone() == false);
			return m_hash->E(m_index);
		}
		const entry*	operator->() const { return &(operator*()); }

		void	operator++()
		{
			assert(m_hash);

			// Find next non-empty entry.
			if (m_index <= m_hash->m_table->m_size_mask)
			{
				m_index++;
				while (m_index <= m_hash->m_table->m_size_mask
					   && (m_hash->E(m_index).is_empty() || m_hash->E(m_index).is_tombstone()))
				{
					m_index++;
				}
			}
		}

		bool	operator==(const const_iterator& it) const
		{
			if (is_end() && it.is_end())
			{
				return true;
			}
			else
			{
				return
					m_hash == it.m_hash
					&& m_index == it.m_index;
			}
		}

		bool	operator!=(const const_iterator& it) const { return ! (*this == it); }

		bool	is_end() const
		{
			return
				m_hash == NULL
				|| m_hash->m_table == NULL
				|| m_index > m_hash->m_table->m_size_mask;
		}

	protected:
		friend class hash<T,U,hash_functor>;

		const_iterator(const hash* h, int index)
			:
			m_hash(h),
			m_index(index)
		{
		}

		const hash* m_hash;
		int m_index;
	};
	friend class const_iterator;

	// non-const iterator; get most of it from const_iterator.
	class iterator : public const_iterator
	{
	public:
		// Allow non-const access to entries.
		entry&	operator*() const
		{
			assert(const_iterator::is_end() == false);
			return const_cast<hash*>(const_iterator::m_hash)->E(const_iterator::m_index);
		}
		entry*	operator->() const { return &(operator*()); }

	private:
		friend class hash<T,U,hash_functor>;

		iterator(hash* h, int i0)
			:
			const_iterator(h, i0)
		{
		}
	};
	friend class iterator;

	void erase(const iterator& pos)
	// Removes the element at pos.
	{
		if (pos.is_end() || pos.m_hash != this) {
			// Invalid iterator.
			return;
		}
		assert(m_table);

		int natural_index = (int) (pos->m_hash_value & m_table->m_size_mask);

		if (pos.m_index != natural_index) {
			// We're not the head of our chain, so we can
			// be spliced out of it.

			// Iterate up the chain, and splice out when
			// we get to m_index.
			entry* e = &E(natural_index);
			while (e->m_next_in_chain != pos.m_index) {
				assert(e->is_end_of_chain() == false);
				e = &E(e->m_next_in_chain);
			}
			e->m_next_in_chain = pos->m_next_in_chain;
			pos->clear();
		} else if (pos->is_end_of_chain() == false) {
			// We're the head of our chain, and there are
			// additional elements.
			//
			// We need to put a tombstone here.
			//
			// We can't clear the element, because the
			// rest of the elements in the chain must be
			// linked to this position.
			//
			// We can't move any of the succeeding
			// elements in the chain (i.e. to fill this
			// entry), because we don't want to invalidate
			// any other existing iterators.
			pos->make_tombstone();
		} else {
			// We're the head of the chain, but we're the
			// only member of the chain.
			pos->clear();
		}

		m_table->m_entry_count--;
	}

	void erase(const T& key)
	// Removes the element with the given key (if any).
	{
		iterator it = find(key);
		if (it != end()) {
			erase(it);
		}
	}

	iterator	begin()
	{
		if (m_table == 0) return iterator(NULL, 0);

		// Scan til we hit the first valid entry.
		int	i0 = 0;
		while (i0 <= m_table->m_size_mask
			&& (E(i0).is_empty() || E(i0).is_tombstone()))
		{
			i0++;
		}
		return iterator(this, i0);
	}
	iterator	end() { return iterator(NULL, 0); }

	const_iterator	begin() const { return const_cast<hash*>(this)->begin(); }
	const_iterator	end() const { return const_cast<hash*>(this)->end(); }

	iterator	find(const T& key)
	{
		int	index = find_index(key);
		if (index >= 0)
		{
			return iterator(this, index);
		}
		return iterator(NULL, 0);
	}

	const_iterator	find(const T& key) const { return const_cast<hash*>(this)->find(key); }

private:
	// A value of m_hash_value that marks an entry as a
	// "tombstone" -- i.e. a placeholder entry.
	static const size_t TOMBSTONE_HASH = (size_t) -1;

	int	find_index(const T& key) const
	// Find the index of the matching entry.  If no match, then return -1.
	{
		if (m_table == NULL) return -1;

		size_t	hash_value = compute_hash(key);
		int	index = (int) (hash_value & m_table->m_size_mask);

		const entry*	e = &E(index);
		if (e->is_empty()) return -1;
		if (e->is_tombstone() == false
			&& int(e->m_hash_value & m_table->m_size_mask) != index) {
			// occupied by a collider
			return -1;
		}

		for (;;)
		{
			assert(e->is_tombstone()
				   || (e->m_hash_value & m_table->m_size_mask) == (hash_value & m_table->m_size_mask));

			if (e->m_hash_value == hash_value && e->first == key)
			{
				// Found it.
				return index;
			}
			assert(e->is_tombstone() || ! (e->first == key));	// keys are equal, but hash differs!

			// Keep looking through the chain.
			index = e->m_next_in_chain;
			if (index == -1) break;	// end of chain

			assert(index >= 0 && index <= m_table->m_size_mask);
			e = &E(index);

			assert(e->is_empty() == false || e->is_tombstone());
		}
		return -1;
	}

	size_t compute_hash(const T& key) const {
		size_t hash_value = hash_functor()(key);
		if (hash_value == TOMBSTONE_HASH) {
			hash_value ^= 0x8000;
		}
		return hash_value;
	}

	// Helpers.
	entry&	E(int index)
	{
		assert(m_table);
		assert(index >= 0 && index <= m_table->m_size_mask);
		return *(((entry*) (m_table + 1)) + index);
	}
	const entry&	E(int index) const
	{
		assert(m_table);
		assert(index >= 0 && index <= m_table->m_size_mask);
		return *(((entry*) (m_table + 1)) + index);
	}

	void	set_raw_capacity(int new_size)
	// Resize the hash table to the given size (Rehash the
	// contents of the current table).  The arg is the number of
	// hash table entries, not the number of elements we should
	// actually contain (which will be less than this).
	{
		if (new_size <= 0) {
			// Special case.
			clear();
			return;
		}

		// Force new_size to be a power of two.
		int	bits = fchop(log2((float)(new_size-1)) + 1);
		assert((1 << bits) >= new_size);

		new_size = 1 << bits;

		// Minimum size; don't incur rehashing cost when
		// expanding very small tables.
		if (new_size < 16)
		{
			new_size = 16;
		}

		if (m_table && new_size == m_table->m_size_mask + 1) {
			// No change in raw capacity; don't do any work.
			return;
		}

		hash<T, U, hash_functor>	new_hash;
		new_hash.m_table = (table*) tu_malloc(sizeof(table) + sizeof(entry) * new_size);
		assert(new_hash.m_table);	// @@ need to throw (or something) on malloc failure!

		new_hash.m_table->m_entry_count = 0;
		new_hash.m_table->m_size_mask = new_size - 1;
		{for (int i = 0; i < new_size; i++)
		{
			new_hash.E(i).m_next_in_chain = -2;	// mark empty
		}}

		// Copy stuff to new_hash
		if (m_table)
		{
			for (int i = 0, n = m_table->m_size_mask; i <= n; i++)
			{
				entry*	e = &E(i);
				if (e->is_empty() == false && e->is_tombstone() == false)
				{
					// Insert old entry into new hash.
					new_hash.add(e->first, e->second);
					e->clear();	// placement delete of old element
				}
			}

			// Delete our old data buffer.
			tu_free(m_table, sizeof(table) + sizeof(entry) * (m_table->m_size_mask + 1));
		}

		// Steal new_hash's data.
		m_table = new_hash.m_table;
		new_hash.m_table = NULL;
	}

	struct table
	{
		int	m_entry_count;
		int	m_size_mask;
		// entry array goes here!
	};
	table*	m_table;
};

#endif // not _TU_USE_STL

class tu_stringi;

// String-like type.  Attempt to be memory-efficient with small strings.
class tu_string
{
public:
	tu_string() {
		m_union.m_local.m_bufsize_minus_length = sizeof(m_union.m_local.m_buffer);
		m_union.m_local.m_buffer[0] = 0;
	}
	// TODO: add 'explicit' here
	tu_string(int val)
	{
		char str[50];
		snprintf(str, 50, "%d", val);

		m_union.m_local.m_bufsize_minus_length = sizeof(m_union.m_local.m_buffer);
		m_union.m_local.m_buffer[0] = 0;

		int	new_size = (int) strlen(str);
		resize(new_size);
		strcpy(get_buffer(), str);
	}
	// TODO: add 'explicit' here
	tu_string(double val)
	{
		char str[50];
		snprintf(str, 50, "%.14g", val);

		m_union.m_local.m_bufsize_minus_length = sizeof(m_union.m_local.m_buffer);
		m_union.m_local.m_buffer[0] = 0;

		int	new_size = (int) strlen(str);
		resize(new_size);
		strcpy(get_buffer(), str);
	}
	tu_string(const char* str)
	{
		m_union.m_local.m_bufsize_minus_length = sizeof(m_union.m_local.m_buffer);
		m_union.m_local.m_buffer[0] = 0;

		if (str)
		{
			int	new_size = (int) strlen(str);
			resize(new_size);
			strcpy(get_buffer(), str);
		}
	}
	tu_string(const char* buf, int buflen)
	{
		m_union.m_local.m_bufsize_minus_length = sizeof(m_union.m_local.m_buffer);
		m_union.m_local.m_buffer[0] = 0;

		int	new_size = buflen;
		resize(new_size);
		memcpy(get_buffer(), buf, buflen);
		get_buffer()[buflen] = 0;	// terminate.
	}
	tu_string(const tu_string& str)
	{
		m_union.m_local.m_bufsize_minus_length = sizeof(m_union.m_local.m_buffer);
		m_union.m_local.m_buffer[0] = 0;

		resize(str.size());
		memcpy(get_buffer(), str.get_buffer(), size() + 1);
	}
	tu_string(const uint32* wide_char_str)
	{
		m_union.m_local.m_bufsize_minus_length = sizeof(m_union.m_local.m_buffer);
		m_union.m_local.m_buffer[0] = 0;

		*this = wide_char_str;
	}
	tu_string(const uint16* wide_char_str)
	{
		m_union.m_local.m_bufsize_minus_length = sizeof(m_union.m_local.m_buffer);
		m_union.m_local.m_buffer[0] = 0;

		*this = wide_char_str;
	}

	~tu_string()
	{
		if (using_heap())
		{
			tu_free(m_union.m_heap.m_buffer, m_heap.m_capacity);
		}
	}

	exported_module operator const char*() const
	{
		return get_buffer();
	}

	exported_module const char*	c_str() const
	{
		return (const char*) (*this);
	}

	// If you need a const tu_stringi, don't create a new object;
	// these things have the same internal representation.
	exported_module const tu_stringi&	to_tu_stringi() const { return *(tu_stringi*) this; }

	// operator= returns void; if you want to know why, ask Charles Bloom :)
	// (executive summary: a = b = c is an invitation to bad code)
	exported_module void	operator=(const char* str)
	{
		if (str)
		{
			resize((int) strlen(str));
			memcpy(get_buffer(), str, size() + 1);
			assert(get_buffer()[size()] == 0);
		}
	}

	exported_module void	operator=(const tu_string& str)
	{
		if (this != &str) {
			resize(str.size());
			memcpy(get_buffer(), str.get_buffer(), size() + 1);
			assert(get_buffer()[size()] == 0);
		}
	}

	exported_module bool	operator==(const char* str) const
	{
		return strcmp(*this, str) == 0;
	}

	exported_module bool	operator!=(const char* str) const
	{
		return strcmp(*this, str) != 0;
	}

	exported_module bool	operator==(const tu_string& str) const
	{
		if (size() != str.size()) {
			return false;
		}
		return memcmp(*this, str, size()) == 0;
	}

	exported_module bool	operator!=(const tu_string& str) const
	{
		return !(*this == str);
	}

	exported_module int	length() const
	{
		if (using_heap() == false)
		{
			return sizeof(m_union.m_local.m_buffer) -
				m_union.m_local.m_bufsize_minus_length;
		}
		else
		{
			return m_union.m_heap.m_size;
		}
	}

	exported_module int	size() const {
		return length();
	}

	// index >=0
	exported_module void erase(int index, int count)
	{
		assert(index + count <= length());
		memmove(get_buffer() + index, get_buffer() + index + count,
			size() - index - count);
		resize(size() - count);
	}

	// insert char before index
	exported_module void insert(int index, char ch)
	{
		assert(index >= 0 && index <= size());
		int len = length();
		resize(len + 1);
		char* buf = get_buffer();
		// actual memory size of the empty string is 1 (zero at the end)
		memmove(buf + index + 1, buf + index, len + 1 - index);
		*(buf + index) = ch;
	}

	exported_module char&	operator[](int index)
	{
		assert(index >= 0 && index <= size());
		return get_buffer()[index];
	}

	exported_module const char&	operator[](int index) const
	{
		return (*(const_cast<tu_string*>(this)))[index];
	}

	exported_module void	operator+=(const char* str)
	{
		int	str_length = (int) strlen(str);
		int	old_length = length();
		assert(old_length >= 0);
		resize(old_length + str_length);
		memcpy(get_buffer() + old_length, str, str_length + 1);
	}

	exported_module void	operator+=(char ch)
	{
		int old_length = length();
		assert(old_length >= 0);
		resize(old_length + 1);
		*(get_buffer() + old_length) = ch;
	}

	// Append wide char.  Both versions of wide char.
	exported_module void	append_wide_char(uint16 ch);
	exported_module void	append_wide_char(uint32 ch);

	exported_module void	operator+=(const tu_string& str)
	{
		int str_length = str.length();
		int old_length = length();
		assert(old_length >= 0);
		int new_length = old_length + str_length;
		resize(new_length);
		memcpy(get_buffer() + old_length, str.c_str(), str_length);
		get_buffer()[new_length] = 0;
	}

	exported_module tu_string	operator+(const tu_string& str) const
	{
		tu_string	new_string(*this);
		new_string += str;
		return new_string;
	}

	exported_module tu_string	operator+(const char* str) const
	// NOT EFFICIENT!  But convenient.
	{
		tu_string	new_string(*this);
		new_string += str;
		return new_string;
	}

	exported_module bool	operator<(const char* str) const
	{
		return strcmp(c_str(), str) < 0;
	}

	exported_module bool operator<(const tu_string& str) const
	{
		const char* p0 = get_buffer();
		const char* p1 = str.get_buffer();
		int min_len = length();
		bool str_longer = true;
		if (str.length() < min_len) {
			min_len = str.length();
			str_longer = false;
		}
		int cmp = memcmp(p0, p1, min_len);
		if (cmp < 0) {
			return true;
		} else if (cmp > 0) {
			return false;
		}
		return str_longer;
	}

	exported_module bool	operator>(const char* str) const
	{
		return strcmp(c_str(), str) > 0;
	}

	exported_module bool	operator>(const tu_string& str) const
	{
		return str < *this;
	}

	exported_module void clear()
	{
		resize(0);
	}

	// Sets buffer size to new_size+1 (i.e. enough room for
	// new_size chars, plus terminating 0).
	exported_module void	resize(int new_size);

	// Set *result to the UTF-8 encoded version of wstr[].
	// Both version of wchar_t.
	//
	// Could add operator= overloads, but maybe it's better to
	// keep this very explicit.
	exported_module static void	encode_utf8_from_wchar(tu_string* result, const uint32* wstr);
	exported_module static void	encode_utf8_from_wchar(tu_string* result, const uint16* wstr);

	// Utility: case-insensitive string compare.  stricmp() is not
	// ANSI or POSIX, doesn't seem to appear in Linux.
	exported_module static int	stricmp(const char* a, const char* b);

	// Return the Unicode char at the specified character
	// position.  index is in UTF-8 chars, NOT bytes.
	exported_module uint32	utf8_char_at(int index) const;

	// Return the string in this container as all upper case letters
	exported_module tu_string utf8_to_upper() const;

	// Return the string in this container as all lower case letters
	exported_module tu_string utf8_to_lower() const;

	// Return the number of UTF-8 characters in the given
	// substring buffer.  You must pass in a valid buffer length;
	// this routine does not look for a terminating \0.
	exported_module static int	utf8_char_count(const char* buf, int buflen);

	exported_module int	utf8_length() const { return utf8_char_count(get_buffer(), length()); }

	// Returns a tu_string that's a substring of this.  start and
	// end are in UTF-8 character positions (NOT bytes).
	//
	// start is the index of the first character you want to include.
	//
	// end is the index one past the last character you want to include.
	exported_module tu_string	utf8_substring(int start, int end) const;

private:
	char*	get_buffer()
	{
		if (using_heap() == false)
		{
			return m_union.m_local.m_buffer;
		}
		else
		{
			return m_union.m_heap.m_buffer;
		}
	}

	const char*	get_buffer() const
	{
		return const_cast<tu_string*>(this)->get_buffer();
	}

	bool	using_heap() const
	{
		bool heap = (m_union.m_local.m_bufsize_minus_length == (char) ~0);
		return heap;
	}

	// The idea here is that tu_string is an N-byte structure,
	// which uses internal storage for strings of N-1 characters
	// or less.  For longer strings, it allocates a heap buffer,
	// and keeps the buffer-tracking info in the same bytes that
	// would be used for internal string storage.
	//
	// A string that's implemented like vector<char> is typically
	// 12 bytes plus heap storage, so storing short strings
	// directly in the string metadata is usually a big win.
	// Also, a zero-length string still needs a terminator
	// character, which with vector<char> means an unfortunate
	// heap alloc just to hold a single '0'.
	union
	{
		// Heap storage.
		struct heap_metadata
		{
			int m_size;  // not counting terminating \0
			char* m_buffer;
			int m_capacity;  // TODO: move this into the heap data, a la Won Chun
			// m_local uses the last byte of the struct to
			// signal when it's active, so m_heap can't
			// put anything there.
			int m_dummy;
		} m_heap;

		// Internal storage.
		struct local_data
		{
			char m_buffer[sizeof(heap_metadata) - 1];
			char m_bufsize_minus_length;
			// m_bufsize_minus_length holds
			// ((sizeof(m_buffer) - length).  This is so
			// that a string of length sizeof(m_buffer)
			// has a zero byte in the length field, that
			// does double-duty as the string terminator.
			// This trick allows us to hold one more byte
			// than we would otherwise be able to.
			//
			// if the m_bufsize_minus_length byte is all
			// ones, then that's a flag indicating the
			// active string data is in m_heap.
		} m_local;
	} m_union;
};

// String-like type; comparisons are CASE INSENSITIVE.
// Uses tu_string for implementation.
class tu_stringi
{
public:
	tu_stringi() {}
	tu_stringi(const char* str) : m_string(str) {}
	tu_stringi(const tu_string& str) : m_string(str) {}
	tu_stringi(const tu_stringi& stri) : m_string(stri.c_str()) {}

	~tu_stringi() {}

	operator const char*() const { return (const char*) m_string; }
	const char*	c_str() const { return m_string.c_str(); }
	void	operator=(const char* str) { m_string = str; }
	void	operator=(const tu_string& str) { m_string = str; }
	void	operator=(const tu_stringi& str) { m_string = str.m_string; }
	int	length() const { return m_string.length(); }
	int	size() const { return length(); }
	char&	operator[](int index) { return m_string[index]; }
	const char&	operator[](int index) const { return m_string[index]; }
	void	operator+=(const char* str) { m_string += str; }
	void	operator+=(const tu_string& str) { m_string += str; }
	void	operator+=(const tu_stringi& str) { m_string += str.m_string; }
	tu_stringi	operator+(const char* str) const { return tu_stringi(m_string + str); }

	// The special stuff.
	tu_string& to_tu_string() { return m_string; }
	const tu_string& to_tu_string() const { return m_string; }

	bool	operator==(const char* str) const
	{
		return tu_string::stricmp(*this, str) == 0;
	}
	bool	operator==(const tu_stringi& str) const
	{
		return tu_string::stricmp(*this, str) == 0;
	}
	bool	operator<(const char* str) const
	{
		return tu_string::stricmp(c_str(), str) < 0;
	}
	bool	operator<(const tu_stringi& str) const
	{
		return *this < str.c_str();
	}
	bool	operator>(const char* str) const
	{
		return tu_string::stricmp(c_str(), str) > 0;
	}
	bool	operator>(const tu_stringi& str) const
	{
		return *this > str.c_str();
	}

	void	resize(int new_size) { m_string.resize(new_size); }

private:
	tu_string	m_string;
};

template<class T>
class string_hash_functor
// Computes a hash of a string-like object (something that has
// ::length() and ::[int]).
{
public:
	size_t	operator()(const T& data) const
	{
		int	size = data.length();

		return bernstein_hash((const char*) data, size);
	}
};

template<class U>
class string_hash : public hash<tu_string, U, string_hash_functor<tu_string> >
{
};

template<class T>
class stringi_hash_functor
// Computes a case-insensitive hash of a string-like object (something that has
// ::length() and ::[int] and tolower(::[])).
{
public:
	size_t	operator()(const T& data) const
	{
		int	size = data.length();

		return bernstein_hash_case_insensitive((const char*) data, size);
	}
};

// Case-insensitive string hash.
template<class U>
class stringi_hash : public hash<tu_stringi, U, stringi_hash_functor<tu_stringi> >
{
};

// Utility: handy sprintf wrapper.
tu_string string_printf(const char* fmt, ...)
#ifdef __GNUC__
	// use the following to catch errors: (only with gcc)
	__attribute__((format (printf, 1, 2)))
#endif	// not __GNUC__
;

#endif // CONTAINER_H

// Local Variables:
// mode: C++
// c-basic-offset: 8
// tab-width: 8
// indent-tabs-mode: t
// End:


text:
using System;
using Xamarin.Forms.Xaml;
using Xamarin.Forms;

namespace ClassManagement
{
    // You exclude the 'Extension' suffix when using in Xaml markup
    [ContentProperty("Source")]
    public class ImageResourceExtension : IMarkupExtension
    {
        public string Source { get; set; }

        public object ProvideValue(IServiceProvider serviceProvider)
        {
            if (Source == null)
                return null;

            // Do your translation lookup here, using whatever method you require
            var imageSource = ImageSource.FromResource(Source);

            return imageSource;
        }
    }
}