text:
using System;
using System.Linq;

namespace WorkflowCore.Models
{
    public class WorkflowInstance
    {
        public string Id { get; set; }

        public string WorkflowDefinitionId { get; set; }

        public int Version { get; set; }

        public string Description { get; set; }

        public string Reference { get; set; }

        public ExecutionPointerCollection ExecutionPointers { get; set; } = new ExecutionPointerCollection();

        public long? NextExecution { get; set; }

        public WorkflowStatus Status { get; set; }

        public object Data { get; set; }

        public DateTime CreateTime { get; set; }

        public DateTime? CompleteTime { get; set; }

        public bool IsBranchComplete(string parentId)
        {
            return ExecutionPointers
                .FindByScope(parentId)
                .All(x => x.EndTime != null);
        }
    }

    public enum WorkflowStatus
    {
        Runnable = 0,
        Suspended = 1,
        Complete = 2,
        Terminated = 3,
    }
}


text:
require_relative 'Player'

def compute_horizontal_score(board_array,player,direction)
	player_id = player.get_id

	player_pattern = player.get_win_pattern

	score_hash = Hash.new
	board_array.each_with_index do |row , row_index|
		score_counter = 0
		found_piece = false
		row=(direction)? row : row.reverse
		row.each_with_index do |column, column_index|
			c_index=(direction)? column_index : 6 - column_index

			if player_pattern[score_counter] == board_array[row_index][c_index]
				score_counter=score_counter+1
				found_piece = true
			elsif board_array[row_index][column_index] != 0
				found_piece = false
				score_counter=0
			end

			if board_array[row_index][c_index] == 0 && found_piece
				# p board_array[row_index][c_index]
				if score_counter == 0
					score_counter=1
				end
				score = score_counter*10
				score_hash[[row_index,c_index]]=[player_id,score]
				found_piece = false
			end
		end
	end
	return score_hash

end

def compute_vertical_score(board_array, player)
	player_pattern = player.get_win_pattern
	player_id = player.get_id
	score_hash = Hash.new
	for column_index in 0..board_array[0].length-1
		found_piece = false
		score_counter = 0
		board_array.each_with_index do |row , row_index|

			if player_pattern[score_counter] == board_array[row_index][column_index]
				score_counter=score_counter+1
				found_piece = true
			elsif board_array[row_index][column_index] != 0
				found_piece = false
				score_counter=0
			end

			if board_array[row_index][column_index] == 0 && found_piece
				# p board_array[row_index][c_index]
				if score_counter == 0
					score_counter=1
				end
				score = score_counter*10
				score_hash[[row_index,column_index]]=[player_id,score]
				found_piece = false
			end
		end
	end
	return score_hash
end

def compute_right_diagonal_up_score(board_array,player)
	player_pattern = player.get_win_pattern
	player_id = player.get_id
	score_hash = Hash.new

	for row_index in 0..board_array.length-1
		for column_index in 0..board_array[0].length-1
			temp_row_index=row_index
			temp_column_index=column_index
			score_counter = 0
			found_piece = false

			while (!(temp_column_index >= board_array[0].length || temp_row_index >= board_array.length))
				board_value=board_array[temp_row_index][temp_column_index]

				if player_pattern[score_counter]==board_value
					score_counter=score_counter+1
					found_piece = true
				elsif board_array[temp_row_index][temp_column_index] != 0
					found_piece = false
					score_counter=0
				end

				if board_array[temp_row_index][temp_column_index] == 0 && found_piece
					if score_counter == 0
						score_counter=1
					end
					score = score_counter*10
					if !score_hash.key?([temp_row_index,temp_column_index])
						score_hash[[temp_row_index,temp_column_index]]=[player_id,score]
					end
					# found_piece = false
					break
				end
				temp_row_index=temp_row_index+1
				temp_column_index=temp_column_index+1
			end
		end
	end
	return score_hash
end

def compute_diagonal_up_score(board_array,player,direction)
	player_pattern = player.get_win_pattern
	player_id = player.get_id
	score_hash = Hash.new

	for row_index in 0..board_array.length-1
		column_array=(direction)? [*(0..board_array[0].length-1)] : [*(0..board_array[0].length-1)].reverse
		for column_index in column_array
			temp_row_index=row_index
			temp_column_index=column_index
			score_counter = 0
			found_piece = false

			while (!(temp_column_index >= board_array[0].length || temp_row_index >= board_array.length||temp_column_index<0||temp_row_index<0))
				board_value=board_array[temp_row_index][temp_column_index]

				if player_pattern[score_counter]==board_value
					score_counter=score_counter+1
					found_piece = true
				elsif board_array[temp_row_index][temp_column_index] != 0
					found_piece = false
					score_counter=0
				end

				if board_array[temp_row_index][temp_column_index] == 0 && found_piece
					if score_counter == 0
						score_counter=1
					end
					score = score_counter*10
					if !score_hash.key?([temp_row_index,temp_column_index])
						score_hash[[temp_row_index,temp_column_index]]=[player_id,score]
					end
					# found_piece = false
					break
				end
				temp_row_index=temp_row_index+1
				if direction
					temp_column_index=temp_column_index+1
				else
					temp_column_index=temp_column_index-1
				end
			end
		end
	end

	return score_hash
end

def compute_diagonal_score(board_array,player,direction1,direction2)
	player_pattern = player.get_win_pattern
	player_id = player.get_id
	score_hash = Hash.new

	player_pattern = player.get_win_pattern
	player_id = player.get_id
	score_hash = Hash.new
	row_array = (direction2)? [*0..board_array.length-1] : [*0..board_array.length-1].reverse
	for row_index in 0..board_array.length-1
		column_array=(direction1)? [*(0..board_array[0].length-1)] : [*(0..board_array[0].length-1)].reverse
		for column_index in column_array
			temp_row_index=row_index
			temp_column_index=column_index
			score_counter = 0
			found_piece = false

			while (!(temp_column_index >= board_array[0].length || temp_row_index >= board_array.length||temp_column_index<0||temp_row_index<0))
				board_value=board_array[temp_row_index][temp_column_index]

				if player_pattern[score_counter]==board_value
					score_counter=score_counter+1
					found_piece = true
				elsif board_array[temp_row_index][temp_column_index] != 0
					found_piece = false
					score_counter=0
				end

				if board_array[temp_row_index][temp_column_index] == 0 && found_piece
					if score_counter == 0
						score_counter=1
					end
					score = score_counter*10
					if !score_hash.key?([temp_row_index,temp_column_index]) 	|| score_hash[[temp_row_index,temp_column_index]][1]<score
						score_hash[[temp_row_index,temp_column_index]]=[player_id,score]
					end
					# found_piece = false
					break
				end
				if direction2
					temp_row_index=temp_row_index+1
				else
					temp_row_index=temp_row_index-1
				end
				if direction1
					temp_column_index=temp_column_index+1
				else
					temp_column_index=temp_column_index-1
				end
			end
		end
	end

	return score_hash
end

def format_board(board_array)

	return_str = ""
	board_array.reverse.each do |row|
		return_str=return_str+row.to_s+"\n"
	end
	return return_str
end

board_array = Array.new(6){Array.new(7,0)}
player1 = Player.new(1,"J",[1,1,1,1])

board_array[0][0] = 1
board_array[0][1] = 1
board_array[1][0] = 2
board_array[1][1] = 2
board_array[2][0] = 1
board_array[2][1] = 1
board_array[0][6] = 1
board_array[0][2] = 2
board_array[1][2] = 1

puts format_board(board_array)
puts
# p compute_vertical_score(board_array,player1)
# p compute_horizontal_score(board_array,player1,true)
# p compute_diagonal_score(board_array,player1,false,false)

redpajama_set_name: RedPajamaGithub


text:
=head1 NAME

VCP::Maintenance - VCP code maintenance tips & tricks

=head1 SYNOPSIS

 VCPNODELETE=yes

 bin/hexdump.pl

 vcp revml: --dtd <dtd file name> --save_dtd <how>

=head1 DESCRIPTION

=head2 The distribution hierarchy

As untarred, the distribution hierarchy looks like (some files not
shown for brevity):

   VCP-x.yy/
   +--- Makefile.PL     ## Generates the Makefile
   +--- MANIFEST        ## what files to ship, built with `make manifest`
   +--- MANIFEST.SKIP   ## what filenames `make manifest` should ignore
   +--- CHANGES         ## A detailed summary of all edits
   +--- TODO            ## Things we can't get to quite yet
   +--- LICENSE
   +--- README
   +--- revml.dtd       ## Defines legal RevML
   +--+ bin/            ## Executable files
   |  +---- vcp         ## The command line interface
   |  +---- gentrevml   ## builds RevML files for the test suite
   |  +---- hexdump.pl  ## dumps files in hex, a debugging aid
   |
   +--+ lib/            ## All modules that comprise VCP itself
   |  +--- VCP.pm       ## Drives the VCP process
   |  +--- *.pod        ## Supplemental documentation
   |  +--- Plugin.pm    ## Base class for all sources & destinations
   |  |
   |  +--- Source.pm    ## Base class for all sources
   |  +--+ Source/
   |  |  +--- foo.pm    ## A backend to read from repo. type "foo"
   |  |
   |  +--- Dest.pm      ## Base class for all destinations
   |  +--+ Dest/
   |  |  +--- foo.pm    ## A backend to write to repo. type "foo"
   |  |
   |  +--+ Utils/
   |  |  +--- foo.pm    ## Routines shared by Source/ and Dest/ foo.pm's
   |  |
   |  +--- Rev.pm       ## VCP's concept of a revision
   |  +--- Revs.pm      ## A collection of VCP::Rev instances
   |  |
   |  +--- RevML/       ## Files defining RevML
   |
   +--+ t/              ## The test suite
      +--- *.t          ## Test scripts
      +--- test-*.revml ## Fodder for test scripts

In addition, the following files are created:

   |
   +--- vcp_html        ## By running the `vcp html` command
   +--- pod2htm*        ## Gunk left over from `vcp html`
   +--- blib/           ## By running `make`

=head2 Useful command line idioms

=over

=item perl -Ilib -cw %

(in your editor's key mapping).

Useful to map an editor key to this.  Use whatever path for -I works
given your cwd usage habit, and replace the "%" with whatever macro your
editor replaces with the path to the current file.

=item make test TEST_FILES=t/90foo.t TEST_VERBOSE=1

Runs just the listed test files (space separated list; use quotes) and
shows STDOUT.

=item perl -Ilib bin/vcp ...

Run C<vcp> manually without setting PERL5LIB or installing it.

=item export PERL5LIB=lib

Allows C<vcp> and C<gentrevml> to be run from command line

=item make test

Runs all tests, generating C<t/test-*.revml> if need be.

=back

=head2 Environment Variables

Some environment variables that are useful in debugging:

=over

=item VCPDEBUG

Set this to a TRUE value to force C<VCP::*> modules
emit debugging messages.

See also L<VCP::Debug|VCP::Debug> for more details.

=item VCPNODELETE

Set this to C<yes> to tell C<vcp> I<not> to delete it's working
directories.  This allows you to take a look at them and see what
the source and dest command lines saw.

=item IPCRUN3DEBUG

Set this to some number from 0..10 to see how C<vcp> (via
L<IPC::Run3|IPC::Run3>) is treating it's subprocesses.

=item VCPP4LICENSE

If this is present and pointing to a readable file when a p4 daemon is
started via vcp, a symlink will be created in the (possibly newly
created) p4root directory to point to the p4 license file pointed to
by VCPP4LICENSE.  The 'make' target test_all_p4_versions will cycle
through each version of p4 and p4d contained in the 'p4versions'
directory, in both unlicensed and (if VCPP4LICENSE present) licensed
mode.

=back

In addition, both CVS and Perforce backends pay attention to the relevant
environment variables.

=head2 C<hexdump.pl>

C<bin/hexdump.pl> is useful for debugging issues involving line endings,
embedded control code (esp. ^Z on Win32 and NULL on every platform, since most
C programs die when encountering NULL in a text file).

=head2 The tests

The t/*.t files in the source distribution contain a large number of
tests.  The tests begin with a two digit number that orders them so that
more primitive tests run first, followed by higher level "end-to-end"
tests in C<t/90*.t>.

The more primitive tests are pretty standard fare for Perl test suites.
Where things get interesting is the C<t/90*.t> tests.  These tests use the
command-line C<vcp> interface to move reasonably sized chunks of RevML
(up to about 65k currently; pretty small in comparison to "real"
exports) in to, out of, and between various repositories.

The RevML extracted from the repositories is compared to the RevML that
was fed in to them, after sanitizing both of data that is known to not
make it through ok.

The module L<VCP::TestUtils|VCP::TestUtils> contains support routines
for initializing repositories and shutting them down (when a server is
needed).  Existing repositories are not used in the test suite; they'd
be useless and in danger if we did.

The file C<bin/gentrevml> is used to generate the RevML files
(C<t/test*.revml>) from scratch using hand written code instead of
L<VCP::Dest::revml> in order to reduce the chances of a bug in
VCP::Dest::revml causing false positives in the test results.

It's highly likely that new back ends will require new test RevML files.
C<bin/gentrevml> should be hacked up to generate these and new rules
should be added to the C<Makefile> by editing C<Makefile.PL>.

=head3 The structure of a test script.

The t/*.t scripts generally all follow the same structure.

First, they import all necessary modules and init themselves.

Then they build a

   my @tests = (
   sub {
       ...
   },
   );

array that contain the actual tests.  Each
test is a single anonymous C<sub {...}>, every once in a while a single
C<sub {...}> will contain two tests; it is preceded by an empty (or nearly
empty) C<sub {}> in these cases.

At the bottom, some final checks are run to see if all tests should be
skipped, then

   plan tests => scalar @tests;

emits how many tests are to be run, and

   $_->() for @tests;

runs the tests.

This structure is used for several reasons:

=over

=item 1. No counting tests

Tests are counted automatically for you this way, the C<scalar @tests>
does this.  Otherwise you end up having to remember to manually fudge
this every time a test is adding or removed.

=item 2. Clear demarcation

Tests tend to use local variables a lot; this structure keeps them from
"leaking" from one test to another.  Things that are shared between
tests are usually declared right above the C<my @tests => line and are
pretty obvious.

=item 3. Commenting out tests

In situations where you want to focus on one or a few tests, just put a
line like:

    ); @tests = (

before the first test C<sub> you want to run, and a line like

   sub { last },

after the last one.  This is especially important.

=item 4. Test line numbers

Failing tests, when run with C<TEST_VERBOSE=1> as shown above, will
report their line numbers.  This is the fastest way to find out what's
failing.  The list-of-subs approach is used even when C<@tests> could
actually contain just test vectors and the C<for @tests > loop could
check the vectors because we want line numbers to tell us where to look.
If we used test vectors, then the call to C<ok()> would report some line
number in the C<for @tests> loop, not the line number of the test.

=item 5.

If you want to enable C<vcp> or L<IPC::Run3> debugging (see
L<VCP::Debug>, too), you can put a

   local $ENV{IPCRUN3DEBUG} = 1;  ## 1..10

in the appropriate C<sub {...}> and it won't cause all the other tests
to spew a lot of noise.

=back

=head2 Developing a new backend

In general, backends are created in pairs so that a C<t/90foo.t> can be
written to import the RevML files in to the backend repository, extract
new RevML from it, and compare the two.

A backend usually consists of 3 Perl classes: VCP::Source::foo,
VCP::Dest::foo, and VCP::Utils::foo.  The reason for the lowercase
final name is so that the C<vcp> command can translate from the scheme
name (C<cvs:>) to a source or destination module name trivially.

The VCP::Source::foo generally contains a parser to extract metadata
from repository log reports and a routine to drive the copying process.
The L<VCP|VCP> module (C</lib/VCP.pm>)

=head2 Updating the RevML DTD

Run the command C<compile_dtd>, which by default will look for the
file 'revml.dtd'.  This should be done each time the dtd changes.
Optionally you may pass in a dtd file name as the argument to C<compile_dtd>.

The generated file is placed in C<./lib/RevML/Doctype/> or C<./RevML/Doctype/>
or C<./>, whichever is found first.  No directories will be created.

This does not update the L<VCP::Source::revml|VCP::Source::revml> or
L<VCP::Dest::revml|VCP::Dest::revml> drivers to match the DTD, nor does
it affect C<bin/gentrevml>, which is used by the test suite to build the
RevML files used for testing.

=head1 AUTHOR

Barrie Slaymaker <barries@slaysys.com>

=head1 COPYRIGHT

Copyright (c) 2000, 2001, Perforce Software, Inc.
All rights reserved.

See L<VCP::License|VCP::License> (C<vcp help license>) for the terms of use.

=cut


text:
This implementation of the `raplcap` interface uses the [Intel® Power Gadget](https://software.intel.com/en-us/articles/intel-power-gadget/).
It is mostly a proof-of-concept implementation and not documented as a normal backend for RAPLCap.

Note that because IPG is read-only, the RAPLCap setter functions are not supported in this implementation.
In fact, it can only read Package-level power limits.

## Prerequisites

* [Intel® Power Gadget >= 3.0](https://software.intel.com/en-us/articles/intel-power-gadget/)

On Windows, download and install IPG from the above link.

On OSX, install IPG using:
```sh
brew install intel-power-gadget
```


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>GMap Window Example</title>
    <link rel="stylesheet" type="text/css" href="../../resources/css/ext-all.css" />
    <link rel="stylesheet" type="text/css" href="../shared/example.css" />

GMap Window

This example shows how to create an extension and utilize an external library.

    <input type="button" id="show-btn" value="Gimme a Map" />

Note that the js is not minified so it is readable. See GMapPanel.js and gmap.js for the full source code.


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

namespace ReverseCharacters
{
    class Program
    {
        static void Main(string[] args)
        {
            char firstChar = char.Parse(Console.ReadLine());
            char secondChar = char.Parse(Console.ReadLine());
            char thirdChar = char.Parse(Console.ReadLine());

            Console.WriteLine($"{thirdChar}{secondChar}{firstChar}");
        }
    }
}


text:
Now when loading a project that has multiple build.sbt files the logger shows the path as well.
Before it was:

```bash
[info] Loading settings from build.sbt ...
[info] Loading settings from build.sbt ...
[info] Loading settings from build.sbt ...
[info] Loading settings from build.sbt ...
```

Now it's:

```bash
[info] Loading settings from /home/user/Work/personal/someProject/build.sbt ...
[info] Loading settings from /home/user/Work/personal/someProject/subProject1/build.sbt ...
[info] Loading settings from /home/user/Work/personal/someProject/subProject2/build.sbt ...
[info] Loading settings from /home/user/Work/personal/someProject/subProject3/build.sbt ...
```

This should solve the issue: https://github.com/sbt/sbt/issues/3607


text:
package com.opengamma.core.position.impl;

import java.util.Map;

import com.opengamma.core.change.AggregatingChangeManager;
import com.opengamma.core.change.ChangeManager;
import com.opengamma.core.position.Portfolio;
import com.opengamma.core.position.PortfolioNode;
import com.opengamma.core.position.Position;
import com.opengamma.core.position.PositionSource;
import com.opengamma.core.position.Trade;
import com.opengamma.id.ObjectId;
import com.opengamma.id.UniqueId;
import com.opengamma.id.UniqueIdSchemeDelegator;
import com.opengamma.id.VersionCorrection;
import com.opengamma.util.ArgumentChecker;

/**
 * A source of positions that uses the scheme of the unique identifier to determine which
 * underlying source should handle the request.
 *

 * If no scheme-specific handler has been registered, a default is used.
 *

 * Change events are aggregated from the different sources and presented through a single change manager.
 */
public class DelegatingPositionSource extends UniqueIdSchemeDelegator<PositionSource> implements PositionSource {

  /**
   * The change manager.
   */
  private final ChangeManager _changeManager;

  /**
   * Creates an instance specifying the default delegate.
   *
   * @param defaultSource  the source to use when no scheme matches, not null
   */
  public DelegatingPositionSource(final PositionSource defaultSource) {
    super(defaultSource);
    _changeManager = defaultSource.changeManager();
  }

  /**
   * Creates an instance specifying the default delegate.
   *
   * @param defaultSource  the source to use when no scheme matches, not null
   * @param schemePrefixToSourceMap  the map of sources by scheme to switch on, not null
   */
  public DelegatingPositionSource(final PositionSource defaultSource, final Map<String, PositionSource> schemePrefixToSourceMap) {
    super(defaultSource, schemePrefixToSourceMap);
    final AggregatingChangeManager changeManager = new AggregatingChangeManager();

    // REVIEW jonathan 2011-08-03 -- this assumes that the delegating source lasts for the lifetime of the engine as we
    // never detach from the underlying change managers.
    changeManager.addChangeManager(defaultSource.changeManager());
    for (final PositionSource source : schemePrefixToSourceMap.values()) {
      changeManager.addChangeManager(source.changeManager());
    }
    _changeManager = changeManager;
  }

  //-------------------------------------------------------------------------
  @Override
  public Portfolio getPortfolio(final UniqueId uniqueId, final VersionCorrection versionCorrection) {
    ArgumentChecker.notNull(uniqueId, "uniqueId");
    ArgumentChecker.notNull(versionCorrection, "versionCorrection");
    return chooseDelegate(uniqueId.getScheme()).getPortfolio(uniqueId, versionCorrection);
  }

  @Override
  public Portfolio getPortfolio(final ObjectId objectId, final VersionCorrection versionCorrection) {
    ArgumentChecker.notNull(objectId, "objectId");
    ArgumentChecker.notNull(versionCorrection, "versionCorrection");
    return chooseDelegate(objectId.getScheme()).getPortfolio(objectId, versionCorrection);
  }

  @Override
  public PortfolioNode getPortfolioNode(final UniqueId uniqueId, final VersionCorrection versionCorrection) {
    ArgumentChecker.notNull(uniqueId, "uniqueId");
    ArgumentChecker.notNull(versionCorrection, "versionCorrection");
    return chooseDelegate(uniqueId.getScheme()).getPortfolioNode(uniqueId, versionCorrection);
  }

  @Override
  public Position getPosition(final UniqueId uniqueId) {
    ArgumentChecker.notNull(uniqueId, "uniqueId");
    return chooseDelegate(uniqueId.getScheme()).getPosition(uniqueId);
  }

  @Override
  public Position getPosition(final ObjectId objectId, final VersionCorrection versionCorrection) {
    ArgumentChecker.notNull(objectId, "objectId");
    ArgumentChecker.notNull(versionCorrection, "versionCorrection");
    return chooseDelegate(objectId.getScheme()).getPosition(objectId, versionCorrection);
  }

  @Override
  public Trade getTrade(final UniqueId uniqueId) {
    ArgumentChecker.notNull(uniqueId, "uniqueId");
    return chooseDelegate(uniqueId.getScheme()).getTrade(uniqueId);
  }

  //-------------------------------------------------------------------------
  @Override
  public ChangeManager changeManager() {
    return _changeManager;
  }

}


text:
require 'dumbstats/graphite'

module Dumbstats
  module Graphite
    class Formatter
      include Initialization

      # Called with String.
      attr_accessor :output

      # Unescaped Graphite path prefix.
      attr_accessor :prefix

      # Time to use for each #add!.
      attr_accessor :now

      # Output per_X records for rate Buckets.
      # per_sec is true by default.
      attr_accessor :per_sec, :per_min, :per_hr, :per_day

      def initialize *opts
        @per_sec = true
        super
      end

      def call item
        return if item == :flush
        add! item[:path], item[:value], item[:time], :encode_name => false
      end

      def add! name, value, now = nil, o = nil
        o ||= EMPTY_Hash
        now ||= self.now || Time.now.utc
        name = encode_path(name) unless o[:encode_name] == false
        output.call "#{prefix}#{o[:prefix]}#{name}#{o[:suffix]} #{value} #{now.to_i}\n"
        self
      end

      def add_bucket! b, opts = nil
        opts ||= EMPTY_Hash
        now = opts[:now] || opts[:time]
        now ||= self.now || Time.now.utc
        if b.rate?
          add! b.name, b.rate, now, opts.dup.update(:prefix => opts[:prefix], :suffix => '.per_sec') if @per_sec || opts[:per_sec]
          add! b.name, b.rate * 60 , now, opts.dup.update(:prefix => opts[:prefix], :suffix => '.per_min') if @per_min || opts[:per_min]
          add! b.name, b.rate * 3600, now, opts.dup.update(:prefix => opts[:prefix], :suffix => '.per_hr') if @per_hr || opts[:per_hr]
          add! b.name, b.rate * 86400, now, opts.dup.update(:prefix => opts[:prefix], :suffix => '.per_day') if @per_day || opts[:per_day]
        else
          b.to_a.each do | k, v |
            next if a = opts[:ignore] and a.include?(k)
            add! b.name, v, now, opts.dup.update(:prefix => opts[:prefix], :suffix => '.' << encode_path(k))
          end
        end
        self
      end

      def encode_path name
        name.to_s.gsub(/[^a-z0-9_]/i, '-')
      end
    end
  end
end


text:
title: "Concurrent Linux Memory Allocation Performance/Scalability"
categories: articles
date: 2015-04-17
modified: 2015-04-17
tags: [tags]
image:
  feature:
  teaser: /assets/images/2014/03/stutter.jpg
  path: /assets/images/2014/03/stutter.jpg
  thumb:
---

Teaser:
    - Allocating 600MB takes 1s. But allocating 600MB for each thread in a 8 thread group takes 20 times as long?! Is this a bug?

FIXME: kernel number

Start situation:
    - process loads big files (600MB) multiple times to memory
    - naive assumption: as long as the thread count doesn't exceed the core count, it should be not slower
    - reality: much slower than loading only one file. even slower than one thread loading x files?
    - What are the reasons and how can this be fixed?

Overview Allocation Process
    - multiple (software) layers Prog -> libc -> kernel
    - I'll talk about glibc 2.21, other libc implementations can do this differently. glibc as uses currently ptmalloc2 "This is a version (aka ptmalloc2) of malloc/free/realloc written by Doug Lea and adapted to multiple threads/arenas by Wolfram Gloger."
    - process of dynamically allocating memory
        - prog asks for a memory block (malloc())
        - a arena is picked
            - see post on description of arenas
            - malloc tries to lock the arena which was used the last time by this thread. if it fails, it continues to try-lock other arenas until the lock was successful. if none found, arena is created.
            - this approach high parallelization, but some vmem-overhead, and increased fragmentation.
        - libc decides if it should be mmapped or placed into heap
            - It uses some settings to decide:
                - mmap active? (MALLOC_MMAP_THRESHOLD_>0)
                - requested block size >= mmap_thresthold
                - is there enough free space in arena ?
                - is count of mmaped blocks smaller as MALLOC_MMAP_MAX_
        - calling mmap or retrieving a block from arena
            - if decision is to retrieve from arena (because the block doesn't meet the requirements to be mmaped)
                - check free space in arena
                - increase arena size if it's too small -> system call (mprotect())
                - if arena reached the maximum size (64MB on 64bit systems), create a new arena -> system call (mmap())
            - else call mmap -> system call (mmap())

Memory Pages Availability
    - memory 'allocation' via mmap() or brk() doesn't occupy any real memory. the kernel just sets some flags internally that the section has been allocated.
    - the real work is done when the memory section is actually accessed
    - this is done per-page. (typical page size for 64bit systems: 4096, call `getconf PAGESIZE`)
    - page is backed by physical memory and zeroed (filled with zeros).

!    - simple test: allocate pages without accessing them until out ouf memory.
!    - simple test: allocate pages with writing 1 byte (reading?) until out of memory

Bottlenecks


text:
<?xml version="1.0" encoding="utf-8"?>
<Roots >
  <Roots.RootTypes>
    <RootType FullName="Windows.UI.Xaml.Controls.UserControl">
      <RootProperty Name="Resources" />
      <RootProperty Name="Content" />
    </RootType>
    <RootType FullName="Windows.UI.Xaml.Media.Animation.Storyboard">
      <RootProperty Name="Children" />
      <RootMethod Name="GetTargetName" />
      <RootMethod Name="SetTargetName" />
      <RootMethod Name="GetTargetProperty" />
      <RootMethod Name="SetTargetProperty" />
    </RootType>
    <RootType FullName="Windows.UI.Xaml.Media.Animation.DoubleAnimation">
      <RootProperty Name="Duration" />
      <RootProperty Name="From" />
      <RootProperty Name="To" />
      <RootProperty Name="AutoReverse" />
      <RootProperty Name="EnableDependentAnimation" />
      <RootProperty Name="SpeedRatio" />
      <RootProperty Name="RepeatBehavior" />
      <RootProperty Name="BeginTime" />
    </RootType>
    <RootType FullName="Windows.UI.Xaml.Media.Animation.RepositionThemeAnimation">
      <RootProperty Name="FromVerticalOffset" />
    </RootType>
    <RootType FullName="Windows.UI.Xaml.Controls.Grid">
      <RootProperty Name="Children" />
    </RootType>
    <RootType FullName="Windows.UI.Xaml.Shapes.Ellipse">
      <RootProperty Name="Name" />
      <RootProperty Name="Width" />
      <RootProperty Name="Height" />
      <RootProperty Name="Fill" />
      <RootProperty Name="Visibility" />
    </RootType>
    <RootType FullName="Windows.UI.Xaml.Controls.TextBlock">
      <RootProperty Name="Foreground" />
      <RootProperty Name="Margin" />
      <RootProperty Name="Text" />
      <RootProperty Name="FontFamily" />
      <RootProperty Name="FontSize" />
      <RootProperty Name="Visibility" />
      <RootProperty Name="VerticalAlignment" />
      <RootProperty Name="HorizontalAlignment" />
    </RootType>
    <RootType FullName="Microsoft.Xaml.DirectUI.ProxyTypes.BindExtension">
      <RootProperty Name="Mode" />
    </RootType>
    <RootType FullName="PiStudio.Win10.Voice.UI.VoiceUI" />
  </Roots.RootTypes>
</Roots>


text:
import collections
import logging

from django.db import models
from django.db.migrations.topological_sort import stable_topological_sort
from django.utils.lru_cache import lru_cache
import requests

from . import SupportedServices

logger = logging.getLogger(__name__)
Coordinates = collections.namedtuple('Coordinates', ('latitude', 'longitude'))
FieldInfo = collections.namedtuple('FieldInfo', 'fields fields_required extra_fields_required')

class GeoIpException(Exception):
    pass

def get_coordinates_by_ip(ip_address):
    url = 'http://freegeoip.net/json/{}'.format(ip_address)

    try:
        response = requests.get(url)
    except requests.exceptions.RequestException as e:
        raise GeoIpException("Request to geoip API %s failed: %s" % (url, e))

    if response.ok:
        data = response.json()
        return Coordinates(latitude=data['latitude'],
                           longitude=data['longitude'])
    else:
        params = (url, response.status_code, response.text)
        raise GeoIpException("Request to geoip API %s failed: %s %s" % params)

@lru_cache(maxsize=1)
def get_sorted_dependencies(service_model):
    """
    Returns list of application models in topological order.
    It is used in order to correctly delete dependent resources.
    """
    app_models = list(service_model._meta.app_config.get_models())
    dependencies = {model: set() for model in app_models}
    relations = (
        relation
        for model in app_models
        for relation in model._meta.related_objects
        if relation.on_delete in (models.PROTECT, models.CASCADE)
    )
    for rel in relations:
        dependencies[rel.model].add(rel.related_model)
    return stable_topological_sort(app_models, dependencies)

def sort_dependencies(service_model, resources):
    ordering = get_sorted_dependencies(service_model)
    resources.sort(key=lambda resource: ordering.index(resource._meta.model))
    return resources

@lru_cache(maxsize=1)
def get_all_services_field_info():
    services_fields = dict()
    services_fields_required = dict()
    services_extra_fields_required = dict()
    service_models = SupportedServices.get_service_models()

    for service_name in service_models:
        service_model = service_models[service_name]['service']
        service_serializer = SupportedServices.get_service_serializer(service_model)

        fields = service_serializer.SERVICE_ACCOUNT_FIELDS.keys() \
            if service_serializer.SERVICE_ACCOUNT_FIELDS is not NotImplemented else []

        fields_extra = service_serializer.SERVICE_ACCOUNT_EXTRA_FIELDS.keys() \
            if service_serializer.SERVICE_ACCOUNT_EXTRA_FIELDS is not NotImplemented else []

        fields_required = service_serializer.Meta.required_fields \
            if hasattr(service_serializer.Meta, 'required_fields') else []

        services_fields[service_name] = list(fields)
        services_fields_required[service_name] = list(set(fields) & set(fields_required))
        services_extra_fields_required[service_name] = list(set(fields_extra) & set(fields_required))

    return FieldInfo(fields=services_fields,
                     fields_required=services_fields_required,
                     extra_fields_required=services_extra_fields_required)

def update_pulled_fields(instance, imported_instance, fields):
    """
    Update instance fields based on imported from backend data.
    Save changes to DB only one or more fields were changed.
    """
    modified = False
    for field in fields:
        pulled_value = getattr(imported_instance, field)
        current_value = getattr(instance, field)
        if current_value != pulled_value:
            setattr(instance, field, pulled_value)
            logger.info("%s's with PK %s %s field updated from value '%s' to value '%s'",
                        instance.__class__.__name__, instance.pk, field, current_value, pulled_value)
            modified = True
    error_message = getattr(imported_instance, 'error_message', '') or getattr(instance, 'error_message', '')
    if error_message and instance.error_message != error_message:
        instance.error_message = imported_instance.error_message
        modified = True
    if modified:
        instance.save()

def handle_resource_not_found(resource):
    """
    Set resource state to ERRED and append/create "not found" error message.
    """
    resource.set_erred()
    resource.runtime_state = ''
    message = 'Does not exist at backend.'
    if message not in resource.error_message:
        if not resource.error_message:
            resource.error_message = message
        else:
            resource.error_message += ' (%s)' % message
    resource.save()
    logger.warning('%s %s (PK: %s) does not exist at backend.' % (
        resource.__class__.__name__, resource, resource.pk))

def handle_resource_update_success(resource):
    """
    Recover resource if its state is ERRED and clear error message.
    """
    update_fields = []
    if resource.state == resource.States.ERRED:
        resource.recover()
        update_fields.append('state')

    if resource.state in (resource.States.UPDATING, resource.States.CREATING):
        resource.set_ok()
        update_fields.append('state')

    if resource.error_message:
        resource.error_message = ''
        update_fields.append('error_message')

    if update_fields:
        resource.save(update_fields=update_fields)
    logger.warning('%s %s (PK: %s) was successfully updated.' % (
        resource.__class__.__name__, resource, resource.pk))


text:
/* NAME: parse
 * PARAMS:
 * context -- context for parsing
 * src     -- source to parse
 * len     -- length of source
 * RETURN:
 * length parsed
 * NOTE: create for test
 */
int  parse(Context* context, char const* src, int len);
/*********************************
 * NAME: parse
 * PARAMS:
 * context -- context for parsing
 * src     -- source to parse
 * len     -- length of source
 * RETURN:
 * length parsed
 * NOTE: create for test
 **********************************/
int  parse(Context* context,
    char const* src,
    int len)


text:
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import *

from test_framework import auxpow

class GetAuxBlockTest (BitcoinTestFramework):

  def run_test (self):
    BitcoinTestFramework.run_test (self)

    # Generate a block so that we are not "downloading blocks".
    self.nodes[0].generate (1)

    # We used to compare to getblocktemplate, but this call is gone
    # now completely for merge-mining.

    # Verify data that can be found in another way.
    auxblock = self.nodes[0].getauxblock ()
    assert_equal (auxblock['chainid'], 1)
    assert_equal (auxblock['height'], self.nodes[0].getblockcount () + 1)
    assert_equal (auxblock['previousblockhash'], self.nodes[0].getblockhash (auxblock['height'] - 1))

    # Calling again should give the same block.
    auxblock2 = self.nodes[0].getauxblock ()
    assert_equal (auxblock2, auxblock)

    # If we receive a new block, the old hash will be replaced.
    self.sync_all ()
    self.nodes[1].generate (1)
    self.sync_all ()
    auxblock2 = self.nodes[0].getauxblock ()
    assert auxblock['hash'] != auxblock2['hash']
    try:
      self.nodes[0].getauxblock (auxblock['hash'], "x")
      raise AssertionError ("invalid block hash accepted")
    except JSONRPCException as exc:
      assert_equal (exc.error['code'], -8)

    # Invalid format for auxpow.
    try:
      self.nodes[0].getauxblock (auxblock2['hash'], "x")
      raise AssertionError ("malformed auxpow accepted")
    except JSONRPCException as exc:
      assert_equal (exc.error['code'], -1)

    # Invalidate the block again, send a transaction and query for the
    # auxblock to solve that contains the transaction.
    self.nodes[0].generate (1)
    addr = self.nodes[1].getnewaddress ()
    txid = self.nodes[0].sendtoaddress (addr, 1)
    self.sync_all ()
    assert_equal (self.nodes[1].getrawmempool (), [txid])
    auxblock = self.nodes[0].getauxblock ()
    target = auxpow.reverseHex (auxblock['_target'])

    # Compute invalid auxpow.
    apow = auxpow.computeAuxpow (auxblock['hash'], target, False)
    res = self.nodes[0].getauxblock (auxblock['hash'], apow)
    assert not res

    # Compute and submit valid auxpow.
    apow = auxpow.computeAuxpow (auxblock['hash'], target, True)
    res = self.nodes[0].getauxblock (auxblock['hash'], apow)
    assert res

    # Make sure that the block is indeed accepted.
    self.sync_all ()
    assert_equal (self.nodes[1].getrawmempool (), [])
    height = self.nodes[1].getblockcount ()
    assert_equal (height, auxblock['height'])
    assert_equal (self.nodes[1].getblockhash (height), auxblock['hash'])

    # Call getblock and verify the auxpow field.
    data = self.nodes[1].getblock (auxblock['hash'])
    assert 'auxpow' in data
    auxJson = data['auxpow']
    assert_equal (auxJson['index'], 0)
    assert_equal (auxJson['chainindex'], 0)
    assert_equal (auxJson['merklebranch'], [])
    assert_equal (auxJson['chainmerklebranch'], [])
    assert_equal (auxJson['parentblock'], apow[-160:])

    # Also previous blocks should have 'auxpow', since all blocks (also
    # those generated by "generate") are merge-mined.
    oldHash = self.nodes[1].getblockhash (100)
    data = self.nodes[1].getblock (oldHash)
    assert 'auxpow' in data

    # Check that it paid correctly to the first node.
    t = self.nodes[0].listtransactions ("", 1)
    assert_equal (len (t), 1)
    t = t[0]
    assert_equal (t['category'], "immature")
    assert_equal (t['blockhash'], auxblock['hash'])
    assert t['generated']
    assert t['amount'] >= Decimal ("10")
    assert_equal (t['confirmations'], 1)

    # Verify the coinbase script.  Ensure that it includes the block height
    # to make the coinbase tx unique.  The expected block height is around
    # 200, so that the serialisation of the CScriptNum ends in an extra 00.
    # The vector has length 2, which makes up for 02XX00 as the serialised
    # height.  Check this.
    blk = self.nodes[1].getblock (auxblock['hash'])
    tx = self.nodes[1].getrawtransaction (blk['tx'][0], 1)
    coinbase = tx['vin'][0]['coinbase']
    assert_equal ("02%02x00" % auxblock['height'], coinbase[0 : 6])

    # Ensure that the payout address is changed from one block to the next.
    addr1 = self.getCoinbaseAddr (auxblock['hash'])
    newHash = auxpow.mineAuxpowBlock (self.nodes[0])
    self.sync_all ()
    addr2 = self.getCoinbaseAddr (newHash)
    assert addr1 != addr2
    valid = self.nodes[0].validateaddress (addr1)
    assert valid['ismine']
    valid = self.nodes[0].validateaddress (addr2)
    assert valid['ismine']

  def getCoinbaseAddr (self, blockHash):
    """
    Extract the coinbase tx' payout address for the given block.
    """

    blockData = self.nodes[1].getblock (blockHash)
    txn = blockData['tx']
    assert len (txn) >= 1

    txData = self.nodes[1].getrawtransaction (txn[0], 1)
    assert len (txData['vout']) == 1 and len (txData['vin']) == 1
    assert 'coinbase' in txData['vin'][0]

    addr = txData['vout'][0]['scriptPubKey']['addresses']
    assert len (addr) == 1
    return addr[0]

if __name__ == '__main__':
  GetAuxBlockTest ().main ()


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_width="250dp"
    android:layout_height="match_parent">

    <View
        android:layout_width="match_parent"
    	android:layout_height="5dip">
    </View>

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="Select a channel from the list below"
    />

    <ListView
        android:id="@+id/useJoinChannelList"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:layout_marginBottom="5dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:divider="#ff505050"
        android:background="#ff202020"
        android:dividerHeight="1dp"
        android:transcriptMode="alwaysScroll"
    />

    <Button
        android:id="@+id/useJoinCancel"
        android:layout_width="120dp"
        android:layout_height="wrap_content"
        android:text="Cancel"
    />

</LinearLayout>


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Metrodiana, Sonderheft 2: 20 (1983)

#### Original name
Pustularia microspora Raithelh.

### Remarks
null


text:
<?xml version="1.0" encoding="UTF-8"?>
<definitions id="definitions"
  xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
  xmlns:camunda="http://activiti.org/bpmn"
  targetNamespace="Examples">

  <process id="process">

    <startEvent id="theStart" camunda:formHandlerClass="org.camunda.bpm.engine.test.authorization.service.MyStartFormHandler"/>

    <sequenceFlow sourceRef="theStart" targetRef="task" />

    <userTask id="task" />

    <sequenceFlow sourceRef="task" targetRef="theEnd" />

    <endEvent id="theEnd" />

  </process>

</definitions>


text:
/**
 * Tests Collection and CollectionView.
 * @flow
 */
import getScrollbarSize from 'dom-helpers/util/scrollbarSize'
import React from 'react'
import { findDOMNode } from 'react-dom'
import { Simulate } from 'react-addons-test-utils'
import { render } from '../TestUtils'
import Collection from './Collection'
import { CELLS, SECTION_SIZE } from './TestData'

describe('Collection', () => {
  function defaultCellRenderer ({ index }) {
    return (

        cell:{index}

    )
  }

  function getMarkup ({
    className,
    cellCount = CELLS.length,
    cellGroupRenderer,
    cellRenderer,
    cellSizeAndPositionGetter,
    height = SECTION_SIZE,
    noContentRenderer,
    onSectionRendered,
    onScroll,
    sectionSize = SECTION_SIZE,
    scrollLeft,
    scrollToAlignment,
    scrollToCell,
    scrollTop,
    style,
    width = SECTION_SIZE * 2
  } = {}) {
    function defaultCellSizeAndPositionGetter ({ index }) {
      index = index % cellCount

      return CELLS[index]
    }

    return (
      <Collection
        className={className}
        cellCount={cellCount}
        cellGroupRenderer={cellGroupRenderer}
        cellRenderer={cellRenderer || defaultCellRenderer}
        cellSizeAndPositionGetter={cellSizeAndPositionGetter || defaultCellSizeAndPositionGetter}
        height={height}
        noContentRenderer={noContentRenderer}
        onSectionRendered={onSectionRendered}
        onScroll={onScroll}
        sectionSize={sectionSize}
        scrollLeft={scrollLeft}
        scrollToAlignment={scrollToAlignment}
        scrollToCell={scrollToCell}
        scrollTop={scrollTop}
        style={style}
        width={width}
      />
    )
  }

  function simulateScroll ({ collection, scrollLeft, scrollTop }) {
    const target = { scrollLeft, scrollTop }
    collection.refs.CollectionView.refs.scrollingContainer = target // HACK to work around _onScroll target check
    Simulate.scroll(findDOMNode(collection), { target })
  }

  function compareArrays (array1, array2) {
    expect(array1.length).toEqual(array2.length)

    array1.forEach(value => {
      expect(array2).toContain(value)
    })
  }

  describe('number of rendered children', () => {
    it('should render enough children to fill the available area', () => {
      const rendered = findDOMNode(render(getMarkup()))
      expect(rendered.querySelectorAll('.cell').length).toEqual(4)
    })

    it('should not render more cells than available if the area is not filled', () => {
      const rendered = findDOMNode(render(getMarkup({ cellCount: 2 })))
      expect(rendered.querySelectorAll('.cell').length).toEqual(2)
    })

    // Small performance tweak added in 5.5.6
    it('should not render/parent cells that are null or false', () => {
      function cellRenderer ({ index }) {
        if (index > 2) {
          return null
        } else {
          return (

              {index}

          )
        }
      }
      const rendered = findDOMNode(render(getMarkup({ cellRenderer })))
      expect(rendered.querySelectorAll('.cell').length).toEqual(3)
    })
  })

  describe('shows and hides scrollbars based on rendered content', () => {
    let scrollbarSize

    beforeAll(() => {
      scrollbarSize = getScrollbarSize()
    })

    it('should set overflowX:hidden if columns fit within the available width and y-axis has no scrollbar', () => {
      const rendered = findDOMNode(render(getMarkup({
        height: 4,
        width: 6
      })))
      expect(rendered.style.overflowX).toEqual('hidden')
    })

    it('should set overflowX:hidden if columns and y-axis scrollbar fit within the available width', () => {
      const rendered = findDOMNode(render(getMarkup({
        height: 1,
        width: 6 + scrollbarSize
      })))
      expect(rendered.style.overflowX).toEqual('hidden')
    })

    it('should leave overflowX:auto if columns require more than the available width', () => {
      const rendered = findDOMNode(render(getMarkup({
        width: 1
      })))
      expect(rendered.style.overflowX).not.toEqual('hidden')
    })

    it('should leave overflowX:auto if columns and y-axis scrollbar require more than the available width', () => {
      const rendered = findDOMNode(render(getMarkup({
        height: 1,
        width: 6 + scrollbarSize - 1
      })))
      expect(rendered.style.overflowX).not.toEqual('hidden')
    })

    it('should set overflowY:hidden if rows fit within the available width and xaxis has no scrollbar', () => {
      const rendered = findDOMNode(render(getMarkup({
        height: 4,
        width: 6
      })))
      expect(rendered.style.overflowY).toEqual('hidden')
    })

    it('should set overflowY:hidden if rows and x-axis scrollbar fit within the available width', () => {
      const rendered = findDOMNode(render(getMarkup({
        height: 4 + scrollbarSize,
        width: 1
      })))
      expect(rendered.style.overflowY).toEqual('hidden')
    })

    it('should leave overflowY:auto if rows require more than the available height', () => {
      const rendered = findDOMNode(render(getMarkup({
        height: 1
      })))
      expect(rendered.style.overflowY).not.toEqual('hidden')
    })

    it('should leave overflowY:auto if rows and y-axis scrollbar require more than the available height', () => {
      const rendered = findDOMNode(render(getMarkup({
        height: 4 + scrollbarSize - 1,
        width: 1
      })))
      expect(rendered.style.overflowY).not.toEqual('hidden')
    })
  })

  describe(':scrollToCell', () => {
    it('should scroll to the top/left', () => {
      const grid = render(getMarkup({ scrollToCell: 0 }))
      expect(grid.refs.CollectionView.state.scrollLeft).toEqual(0)
      expect(grid.refs.CollectionView.state.scrollTop).toEqual(0)
    })

    it('should scroll over to the middle', () => {
      const grid = render(getMarkup({ scrollToCell: 7 }))
      expect(grid.refs.CollectionView.state.scrollLeft).toEqual(1)
      expect(grid.refs.CollectionView.state.scrollTop).toEqual(1)
    })

    it('should scroll to the bottom/right', () => {
      const grid = render(getMarkup({ scrollToCell: 9 }))
      expect(grid.refs.CollectionView.state.scrollLeft).toEqual(2)
      expect(grid.refs.CollectionView.state.scrollTop).toEqual(2)
    })

    it('should honor the specified :scrollToAlignment', () => {
      let grid = render(getMarkup({
        scrollToAlignment: 'start',
        scrollToCell: 2,
        width: SECTION_SIZE
      }))
      // Minimum amount of scrolling ("auto") would be 0,0
      expect(grid.refs.CollectionView.state.scrollLeft).toEqual(2)
      expect(grid.refs.CollectionView.state.scrollTop).toEqual(1)

      grid = render(getMarkup({
        scrollToAlignment: 'end',
        scrollToCell: 2,
        width: SECTION_SIZE
      }))
      // This cell would already by visible by "auto" rules
      expect(grid.refs.CollectionView.state.scrollLeft).toEqual(1)
      expect(grid.refs.CollectionView.state.scrollTop).toEqual(0)

      grid = render(getMarkup({
        scrollToAlignment: 'center',
        scrollToCell: 4,
        width: SECTION_SIZE
      }))
      // This cell would already by visible by "auto" rules
      expect(grid.refs.CollectionView.state.scrollLeft).toEqual(1)
      expect(grid.refs.CollectionView.state.scrollTop).toEqual(0)
    })

    it('should scroll to a cell just added', () => {
      let grid = render(getMarkup({
        cellCount: 4
      }))
      expect(grid.refs.CollectionView.state.scrollLeft).toEqual(0)
      expect(grid.refs.CollectionView.state.scrollTop).toEqual(0)
      grid = render(getMarkup({
        cellCount: 8,
        scrollToCell: 7
      }))
      expect(grid.refs.CollectionView.state.scrollLeft).toEqual(1)
      expect(grid.refs.CollectionView.state.scrollTop).toEqual(1)
    })
  })

  describe('property updates', () => {
    it('should update :scrollToCell position when :width changes', () => {
      let grid = findDOMNode(render(getMarkup({ scrollToCell: 3 })))
      expect(grid.textContent).toContain('cell:3')
      // Making the grid narrower leaves only room for 1 item
      grid = findDOMNode(render(getMarkup({ scrollToCell: 3, width: 1 })))
      expect(grid.textContent).toContain('cell:3')
    })

    it('should update :scrollToCell position when :height changes', () => {
      let grid = findDOMNode(render(getMarkup({ scrollToCell: 4 })))
      expect(grid.textContent).toContain('cell:4')
      // Making the grid shorter leaves only room for 1 item
      grid = findDOMNode(render(getMarkup({ scrollToCell: 4, height: 1 })))
      expect(grid.textContent).toContain('cell:4')
    })

    it('should update scroll position when :scrollToCell changes', () => {
      let grid = findDOMNode(render(getMarkup()))
      expect(grid.textContent).not.toContain('cell:9')
      grid = findDOMNode(render(getMarkup({ scrollToCell: 9 })))
      expect(grid.textContent).toContain('cell:9')
    })
  })

  describe('noContentRenderer', () => {
    it('should call :noContentRenderer if :cellCount is 0', () => {
      let list = findDOMNode(render(getMarkup({
        noContentRenderer: () =>
No data
,
        cellCount: 0
      })))
      expect(list.textContent).toEqual('No data')
    })

    it('should render an empty body if :cellCount is 0 and there is no :noContentRenderer', () => {
      let list = findDOMNode(render(getMarkup({
        cellCount: 0
      })))
      expect(list.textContent).toEqual('')
    })
  })

  describe('onSectionRendered', () => {
    it('should call :onSectionRendered if at least one cell is rendered', () => {
      let indices
      render(getMarkup({
        onSectionRendered: params => {
          indices = params.indices
        }
      }))
      compareArrays(indices, [0, 1, 2, 3])
    })

    it('should not call :onSectionRendered unless the rendered indices have changed', () => {
      let numCalls = 0
      let indices
      const onSectionRendered = params => {
        indices = params.indices
        numCalls++
      }
      render(getMarkup({ onSectionRendered }))
      expect(numCalls).toEqual(1)
      compareArrays(indices, [0, 1, 2, 3])
      render(getMarkup({ onSectionRendered }))
      expect(numCalls).toEqual(1)
      compareArrays(indices, [0, 1, 2, 3])
    })

    it('should call :onSectionRendered if the rendered indices have changed', () => {
      let numCalls = 0
      let indices
      const onSectionRendered = params => {
        indices = params.indices
        numCalls++
      }
      render(getMarkup({ onSectionRendered }))
      expect(numCalls).toEqual(1)
      compareArrays(indices, [0, 1, 2, 3])
      render(getMarkup({
        height: SECTION_SIZE * 2,
        onSectionRendered
      }))
      expect(numCalls).toEqual(2)
      compareArrays(indices, [0, 1, 2, 3, 4, 5])
      render(getMarkup({
        height: SECTION_SIZE * 2,
        onSectionRendered,
        width: SECTION_SIZE
      }))
      expect(numCalls).toEqual(3)
      expect(indices).toEqual([0, 4])
    })

    it('should not call :onSectionRendered if no cells are rendered', () => {
      let numCalls = 0
      render(getMarkup({
        height: 0,
        onSectionRendered: () => numCalls++
      }))
      expect(numCalls).toEqual(0)
    })
  })

  describe(':scrollLeft and :scrollTop properties', () => {
    it('should render correctly when an initial :scrollLeft and :scrollTop properties are specified', () => {
      let indices
      render(getMarkup({
        onSectionRendered: params => {
          indices = params.indices
        },
        scrollLeft: 2,
        scrollTop: 2
      }))
      compareArrays(indices, [3, 4, 5, 7, 8, 9])
    })

    it('should render correctly when :scrollLeft and :scrollTop properties are updated', () => {
      let indices
      render(getMarkup({
        onSectionRendered: params => {
          indices = params.indices
        }
      }))
      compareArrays(indices, [0, 1, 2, 3])
      render(getMarkup({
        onSectionRendered: params => {
          indices = params.indices
        },
        scrollLeft: 2,
        scrollTop: 2
      }))
      compareArrays(indices, [3, 4, 5, 7, 8, 9])
    })
  })

  describe('styles and classeNames', () => {
    it('should use the expected global CSS classNames', () => {
      const rendered = findDOMNode(render(getMarkup()))
      expect(rendered.className).toEqual('Collection')
    })

    it('should use a custom :className if specified', () => {
      const rendered = findDOMNode(render(getMarkup({ className: 'foo' })))
      expect(rendered.className).toContain('foo')
    })

    it('should use a custom :style if specified', () => {
      const style = { backgroundColor: 'red' }
      const rendered = findDOMNode(render(getMarkup({ style })))
      expect(rendered.style.backgroundColor).toEqual('red')
    })
  })

  describe('onScroll', () => {
    it('should trigger callback when component is mounted', () => {
      const onScrollCalls = []
      render(getMarkup({
        onScroll: params => onScrollCalls.push(params),
        scrollLeft: 2,
        scrollTop: 1
      }))
      expect(onScrollCalls).toEqual([{
        clientHeight: SECTION_SIZE,
        clientWidth: SECTION_SIZE * 2,
        scrollHeight: 4,
        scrollLeft: 2,
        scrollTop: 1,
        scrollWidth: 6
      }])
    })

    it('should trigger callback when component scrolls horizontally', () => {
      const onScrollCalls = []
      const collection = render(getMarkup({
        onScroll: params => onScrollCalls.push(params)
      }))
      simulateScroll({
        collection,
        scrollLeft: 1,
        scrollTop: 0
      })
      expect(onScrollCalls.length).toEqual(2)
      expect(onScrollCalls[1]).toEqual({
        clientHeight: SECTION_SIZE,
        clientWidth: SECTION_SIZE * 2,
        scrollHeight: 4,
        scrollLeft: 1,
        scrollTop: 0,
        scrollWidth: 6
      })
    })

    it('should trigger callback when component scrolls vertically', () => {
      const onScrollCalls = []
      const collection = render(getMarkup({
        onScroll: params => onScrollCalls.push(params)
      }))
      simulateScroll({
        collection,
        scrollLeft: 0,
        scrollTop: 2
      })
      expect(onScrollCalls.length).toEqual(2)
      expect(onScrollCalls[1]).toEqual({
        clientHeight: SECTION_SIZE,
        clientWidth: SECTION_SIZE * 2,
        scrollHeight: 4,
        scrollLeft: 0,
        scrollTop: 2,
        scrollWidth: 6
      })
    })

    it('should not allow negative scroll values', () => {
      const onScrollCalls = []
      const collection = render(getMarkup({
        onScroll: params => onScrollCalls.push(params)
      }))
      simulateScroll({
        collection,
        scrollLeft: -1,
        scrollTop: -1
      })
      expect(onScrollCalls.length).toEqual(1)
      expect(onScrollCalls[0].scrollLeft).toEqual(0)
      expect(onScrollCalls[0].scrollTop).toEqual(0)
    })
  })

  describe('cellGroupRenderer', () => {
    it('should use a custom :cellGroupRenderer if specified', () => {
      let cellGroupRendererCalled = 0
      let cellGroupRendererParams
      const cellRenderer = ({ index }) => index
      findDOMNode(render(getMarkup({
        cellRenderer,
        cellGroupRenderer: (params) => {
          cellGroupRendererParams = params
          cellGroupRendererCalled++

          return [

Fake content

          ]
        }
      })))
      expect(cellGroupRendererCalled).toEqual(1)
      expect(cellGroupRendererParams.cellRenderer).toEqual(cellRenderer)
      expect(typeof cellGroupRendererParams.cellSizeAndPositionGetter).toEqual('function')
      compareArrays(cellGroupRendererParams.indices, [0, 1, 2, 3])
    })
  })

  it('should pass the cellRenderer an :isScrolling flag when scrolling is in progress', () => {
    const cellRendererCalls = []
    function cellRenderer ({ index, isScrolling }) {
      cellRendererCalls.push(isScrolling)
      return defaultCellRenderer({ index })
    }
    const collection = render(getMarkup({
      cellRenderer
    }))
    expect(cellRendererCalls[0]).toEqual(false)
    cellRendererCalls.splice(0)
    simulateScroll({ collection, scrollTop: 100 })
    expect(cellRendererCalls[0]).toEqual(true)
  })
})


text:
Dailyprogrammer challenges
==========================

My solutions to [/r/dailyprogrammer](http://reddit.com/r/dailyprogrammer) challenges.

Done so far:

- [Challenge #171](/Challenge-171)
   - [Easy](/Challenge-171/01-Easy): Conversion of 8 hexadecimal numbers to an image.
   - [Intermediate](Challenge-171/02-Intermediate): Image manipulation (rotation, zoom, inversion...)
   - [Hard](/Challenge-171/03-Hard): String compression with my own algorithm
- [Challenge #172](/Challenge-172)
   - [Easy](/Challenge-172/01-Easy): P1 PBM image generation from text.
   - [Intermediate 1](Challenge-172/02-Intermediate-1): P1 PBM, P2 PGM and P3 PPM image rendering with Pillow
   - [Intermediate 2](Challenge-172/02-Intermediate-2): Password salting and hashing
- [Challenge #173](/Challenge-173)
   - [Easy](/Challenge-173/01-Easy): Unit coverter (mass & length)
   - [Intermediate](/Challenge-173/02-Intermediate): Advanced [Langton's Ant](http://en.wikipedia.org/wiki/Langton%27s_ant)
   - [Hard](/Challenge-173/03-Hard): Road Trip Game
- [Challenge #174](/Challenge-174)
   - [Easy](/Challenge-174/01-Easy): Thue-Morse sequence generator
   - [Intermediate](/Challenge-174/02-Intermediate): Username-to-Avatar generator
   - [Hard](/Challenge-174/03-Hard): Convex Hull problem with the Gift Wrapping algorithm
- [Challenge #175](/Challenge-175)
   - [Easy](/Challenge-175/01-Easy): Extremely inefficient sorting algorithms
   - [Intermediate](/Challenge-175/02-Intermediate): Largest word from list of characters
   - [Hard](/Challenge-175/03-Hard): Simulation of a laser in a 2D hall of mirrors
- [Challenge #176](/Challenge-176)
   - [Easy 1](/Challenge-176/01-Easy-1): Spreadsheet cell-selection formula parsing
   - [Hard](/Challenge-176/02-Hard): Spreadsheet cell operations
   - [Easy 2](/Challenge-176/03-Easy-2): Pivot tables
- [Challenge #177](/Challenge-177)
   - [Easy](/Challenge-177/01-Easy): Quicksort
   - [Intermediate](/Challenge-177/02-Intermediate): Morse audio file generation
   - [Hard](/Challenge-177/03-Hard): Stats on Monty Python and The Holy Grail
- [Challenge #178](/Challenge-178)
   - [Easy](/Challenge-178/01-Easy): Geometric transformations
   - [Intermediate](/Challenge-178/02-Intermediate): Longest possible trip between planets with limited fuel
   - [Hard](/Challenge-178/03-Hard): Regex Fractals
- [Challenge #179](/Challenge-179)
   - [Easy](/Challenge-179/01-Easy): Grayscale conversion


text:
@extends('layouts.master')
@section('css')
@stop
@section('content')

      {{ Form::open(array('route' => 'session.store', 'role'=>'form', 'class' => 'form-todo')) }}

          {{ Form::label('email', 'email', array('class' => 'text-uppercase')) }}
          {{ Form::email('email', $value = null, $attributes = array('autofocus')) }}

          {{ Form::label('password', 'password', array('class' => 'text-uppercase')) }}
          {{ Form::password('password', $attributes = array('autofocus')) }}

          Forgot password?

          {{ Form::submit('Submit',$attributes = array('class'=>'btn btn-todo-red')) }}

      {{ Form::close() }}

@stop


text:
all: scanner.go parser.go

scanner.go: scanner.l
	golex -t scanner.l | gofmt > scanner.go

parser.go: parser.y
	go tool yacc -o parser.go -v parser.tab parser.y
	sed -i -e 's/^func yyParse(yylex yyLexer) int {/func yyParse(yylex *lex) int {/' -e 's|//line.*||' parser.go
	gofmt -w parser.go

clean:
	rm -f scanner.go parser.go lex.yy.go y.go parser.tab y.output *~


text:
name: Support Question ❓
about: If you have a question, you can try asking in the PowerShell Slack channel first. If you need official support, refer to the [PowerShell Support Lifecycle](https://aka.ms/pslifecycle)
title: "Support Question"
labels: Issue-Question
assignees: ''

---

# Support Question

## Official support

[PowerShell Support Lifecycle](https://aka.ms/pslifecycle)

## Community Resources

[Slack Community Chat](https://powershell.slack.com) - Interactive chat with other PowerShell enthusiasts
[PowerShell.org Forum](https://powershell.org/forums/) - Search or post new general PowerShell usage questions


text:
package cpuid

import (
	"fmt"
	"strings"
)

// contextID is the package for context.Context.Value keys.
type contextID int

const (
	// CtxFeatureSet is the FeatureSet for the context.
	CtxFeatureSet contextID = iota
)

// context represents context.Context.
type context interface {
	Value(key any) any
}

// FromContext returns the FeatureSet from the context, if available.
func FromContext(ctx context) FeatureSet {
	v := ctx.Value(CtxFeatureSet)
	if v == nil {
		return FeatureSet{} // Panics if used.
	}
	return v.(FeatureSet)
}

// Feature is a unique identifier for a particular cpu feature. We just use an
// int as a feature number on x86 and arm64.
//
// On x86, features are numbered according to "blocks". Each block is 32 bits, and
// feature bits from the same source (cpuid leaf/level) are in the same block.
//
// On arm64, features are numbered according to the ELF HWCAP definition, from
// arch/arm64/include/uapi/asm/hwcap.h.
type Feature int

// allFeatureInfo is the value for allFeatures.
type allFeatureInfo struct {
	// displayName is the short display name for the feature.
	displayName string

	// shouldAppear indicates whether the feature normally appears in
	// cpuinfo. This affects FlagString only.
	shouldAppear bool
}

// String implements fmt.Stringer.String.
func (f Feature) String() string {
	info, ok := allFeatures[f]
	if ok {
		return info.displayName
	}
	return fmt.Sprintf("[0x%x?]", int(f)) // No given name.
}

// reverseMap is a map from displayName to Feature.
var reverseMap = func() map[string]Feature {
	m := make(map[string]Feature)
	for feature, info := range allFeatures {
		if info.displayName != "" {
			// Sanity check that the name is unique.
			if old, ok := m[info.displayName]; ok {
				panic(fmt.Sprintf("feature %v has conflicting values (0x%x vs 0x%x)", info.displayName, old, feature))
			}
			m[info.displayName] = feature
		}
	}
	return m
}()

// FeatureFromString returns the Feature associated with the given feature
// string plus a bool to indicate if it could find the feature.
func FeatureFromString(s string) (Feature, bool) {
	feature, ok := reverseMap[s]
	return feature, ok
}

// AllFeatures returns the full set of all possible features.
func AllFeatures() (features []Feature) {
	archFlagOrder(func(f Feature) {
		features = append(features, f)
	})
	return
}

// Subtract returns the features present in fs that are not present in other.
// If all features in fs are present in other, Subtract returns nil.
//
// This does not check for any kinds of incompatibility.
func (fs FeatureSet) Subtract(other FeatureSet) (left map[Feature]struct{}) {
	for feature := range allFeatures {
		thisHas := fs.HasFeature(feature)
		otherHas := other.HasFeature(feature)
		if thisHas && !otherHas {
			if left == nil {
				left = make(map[Feature]struct{})
			}
			left[feature] = struct{}{}
		}
	}
	return
}

// FlagString prints out supported CPU flags.
func (fs FeatureSet) FlagString() string {
	var s []string
	archFlagOrder(func(feature Feature) {
		if !fs.HasFeature(feature) {
			return
		}
		info := allFeatures[feature]
		if !info.shouldAppear {
			return
		}
		s = append(s, info.displayName)
	})
	return strings.Join(s, " ")
}

// ErrIncompatible is returned for incompatible feature sets.
type ErrIncompatible struct {
	reason string
}

// Error implements error.Error.
func (e *ErrIncompatible) Error() string {
	return fmt.Sprintf("incompatible FeatureSet: %v", e.reason)
}

// CheckHostCompatible returns nil if fs is a subset of the host feature set.
func (fs FeatureSet) CheckHostCompatible() error {
	hfs := HostFeatureSet()

	// Check that hfs is a superset of fs.
	if diff := fs.Subtract(hfs); len(diff) > 0 {
		return &ErrIncompatible{
			reason: fmt.Sprintf("missing features: %v", diff),
		}
	}

	// Make arch-specific checks.
	return fs.archCheckHostCompatible(hfs)
}


text:
package topoos.Objects;

import java.io.Serializable;
import java.util.Date;

/**
 * The Class Image.
 *
 * @author topoos
 */
public class Image implements Serializable{

	/**
	 * V0
	 */
	private static final long serialVersionUID = 1L;

	/** The id. */
	private String id = null;

	/** The client_id. */
	private String client_id = null;

	/** The user_id. */
	private String user_id = null;

	/** The filename. */
	private String filename = null;

	/** The filename_unique. */
	private String filename_unique = null;

	/** The file_ext. */
	private String file_ext = null;

	/** The uri. */
	private String uri = null;

	/** The register_date. */
	private Date register_date = null;

	/** The geo_data. */
	private GeoData geo_data = null;

	/**
	 * Instantiates a new image.
	 *
	 * @param id the id
	 * @param client_id the client_id
	 * @param user_id the user_id
	 * @param filename the filename
	 * @param filename_unique the filename_unique
	 * @param file_ext the file_ext
	 * @param uri the uri
	 * @param register_date the register_date
	 * @param geo_data the geo_data
	 */
	public Image(String id, String client_id, String user_id, String filename,
			String filename_unique, String file_ext, String uri,
			Date register_date, GeoData geo_data) {
		super();
		this.id = id;
		this.client_id = client_id;
		this.user_id = user_id;
		this.filename = filename;
		this.filename_unique = filename_unique;
		this.file_ext = file_ext;
		this.uri = uri;
		this.register_date = register_date;
		this.geo_data = geo_data;
	}

	/**
	 * Gets the id.
	 *
	 * @return the id
	 */
	public String getId() {
		return id;
	}

	/**
	 * Sets the id.
	 *
	 * @param id the id to set
	 */
	public void setId(String id) {
		this.id = id;
	}

	/**
	 * Gets the client_id.
	 *
	 * @return the client_id
	 */
	public String getClient_id() {
		return client_id;
	}

	/**
	 * Sets the client_id.
	 *
	 * @param client_id the client_id to set
	 */
	public void setClient_id(String client_id) {
		this.client_id = client_id;
	}

	/**
	 * Gets the user_id.
	 *
	 * @return the user_id
	 */
	public String getUser_id() {
		return user_id;
	}

	/**
	 * Sets the user_id.
	 *
	 * @param user_id the user_id to set
	 */
	public void setUser_id(String user_id) {
		this.user_id = user_id;
	}

	/**
	 * Gets the filename.
	 *
	 * @return the filename
	 */
	public String getFilename() {
		return filename;
	}

	/**
	 * Sets the filename.
	 *
	 * @param filename the filename to set
	 */
	public void setFilename(String filename) {
		this.filename = filename;
	}

	/**
	 * Gets the filename_unique.
	 *
	 * @return the filename_unique
	 */
	public String getFilename_unique() {
		return filename_unique;
	}

	/**
	 * Sets the filename_unique.
	 *
	 * @param filename_unique the filename_unique to set
	 */
	public void setFilename_unique(String filename_unique) {
		this.filename_unique = filename_unique;
	}

	/**
	 * Gets the file_ext.
	 *
	 * @return the file_ext
	 */
	public String getFile_ext() {
		return file_ext;
	}

	/**
	 * Sets the file_ext.
	 *
	 * @param file_ext the file_ext to set
	 */
	public void setFile_ext(String file_ext) {
		this.file_ext = file_ext;
	}

	/**
	 * Gets the uri.
	 *
	 * @return the uri
	 */
	public String getUri() {
		return uri;
	}

	/**
	 * Sets the uri.
	 *
	 * @param uri the uri to set
	 */
	public void setUri(String uri) {
		this.uri = uri;
	}

	/**
	 * Gets the register_date.
	 *
	 * @return the register_date
	 */
	public Date getRegister_date() {
		return register_date;
	}

	/**
	 * Sets the register_date.
	 *
	 * @param register_date the register_date to set
	 */
	public void setRegister_date(Date register_date) {
		this.register_date = register_date;
	}

	/**
	 * Gets the geo_data.
	 *
	 * @return the geo_data
	 */
	public GeoData getGeo_data() {
		return geo_data;
	}

	/**
	 * Sets the geo_data.
	 *
	 * @param geo_data the geo_data to set
	 */
	public void setGeo_data(GeoData geo_data) {
		this.geo_data = geo_data;
	}

}


text:
namespace TextToImageHttpHandler
{
    using System;
    using System.Drawing;
    using System.Drawing.Imaging;
    using System.Linq;
    using System.Web;

    /// <summary>
    /// You can generate image at address:
    /// http://localhost:4444/example.img?text=sample%20text
    /// </summary>
    /// <remarks>
    /// For more info:
    /// http://www.hanselman.com/blog/ASPNETFuturesGeneratingDynamicImagesWithHttpHandlersGetsEasier.aspx
    /// </remarks>
    public class TextToImage : IHttpHandler
    {
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        public void ProcessRequest(HttpContext context)
        {
            var content = context.Request.QueryString["text"];
            if (string.IsNullOrWhiteSpace(content))
            {
                throw new InvalidOperationException("No text content specified.");
            }

            this.GenerateImage(context.Response, content, 500, 100, Color.Black,
                FontFamily.GenericSansSerif, 18, Brushes.BlueViolet, 0, 0, "image/png", ImageFormat.Png);
        }

        private void GenerateImage(HttpResponse response, string textToInsert, int width, int height, Color backgroundColor,
            FontFamily fontFamily, float emSize, Brush brush, float x, float y, string contentType, ImageFormat imageFormat)
        {
            using (var bitmap = new Bitmap(width, height))
            {
                using (var graphics = Graphics.FromImage(bitmap))
                {
                    graphics.Clear(backgroundColor);
                    graphics.DrawString(textToInsert, new Font(fontFamily, emSize), brush, x, y);
                    response.ContentType = contentType;
                    bitmap.Save(response.OutputStream, imageFormat);
                }
            }
        }
    }
}


text:
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
    <title>Finecrop tutorial and manual</title>

Finecrop Tutorial

A simple example

You have scanned four photos but your job was not very precise and the result is the following.

Image selection

The first step is to create a smaller image for each of the scanned photos. Draw four rectangles by pressing and dragging your left mouse button over each photo. You must do it from the top left corner to the bottom right one.

If you make a mistake you can delete the last rectangle with your right mouse button. If there is no rectangle you can cancel the whole operation with this mouse button.

When you are ready, press the middle button to validate your rectangles.

Image rotation

Now let us look at the first generated sub-image.

The goal is to make the blue photo appear horizontal. We draw a line parallel to the horizontal border of the photo (usually on this border). As for rectangle definition, we use the left mouse button press, drag and release to draw the line. To change the current line just draw a new one and confirm with the middle button. The right button will bring you back to the previous step and let you redraw a selection rectangle (for example if the first try cut off some portion of your photo).

Final crop

You should have obtained something like this.

Draw a last crop rectangle that perfectly fit the borders and press the middle button. You will see the result and have a last chance to cancel it with the right button or confirm with the middle button. Now you can proceed with the next image.

Files are renamed by finecrop from x.ext to x.bak. The produced result is named x.jpg or x-0.jpg ... x-3.jpg.

Command line options

By default finecrop streamlines the previous process and repeat the following actions on all the files or the files directly contained in folders given as arguments.

-b

Book mode. It assumes there is only one book page per image and goes directly to the rotate action followed by a crop

-p

Photo mode. In that mode there is a selection first followed by a rotation and a crop.

-c <spec>

A custom mode which is a sequence of letters representing each one of the following operations on the original image:

M: Selection of multiple sub-images. Following operations will be applied to each sub-image

R: Image rotation

C: Crop.


text:
using Grabacr07.KanColleViewer.Composition;
using Grabacr07.KanColleViewer.Models;
using Grabacr07.KanColleViewer.Properties;
using Grabacr07.KanColleViewer.ViewModels.Composition;
using Grabacr07.KanColleViewer.ViewModels.Messages;
using Grabacr07.KanColleWrapper;
using Grabacr07.KanColleWrapper.Models;
using Livet.EventListeners;
using Livet.Messaging;
using Livet.Messaging.IO;
using MetroRadiance;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using Settings = Grabacr07.KanColleViewer.Models.Settings;

namespace Grabacr07.KanColleViewer.ViewModels
{
	public class SettingsViewModel : TabItemViewModel
	{
		public override string Name
		{
			get { return Resources.Settings; }
			protected set { throw new NotImplementedException(); }
		}

		#region ScreenshotFolder 変更通知プロパティ

		public string ScreenshotFolder
		{
			get { return Settings.Current.ScreenshotFolder; }
			set
			{
				if (Settings.Current.ScreenshotFolder != value)
				{
					Settings.Current.ScreenshotFolder = value;
					this.RaisePropertyChanged();
					this.RaisePropertyChanged("CanOpenScreenshotFolder");
				}
			}
		}

		#endregion

		#region CanOpenScreenshotFolder 変更通知プロパティ

		public bool CanOpenScreenshotFolder
		{
			get { return Directory.Exists(this.ScreenshotFolder); }
		}

		#endregion

		#region ScreenshotImageFormat 変更通知プロパティ

		public SupportedImageFormat ScreenshotImageFormat
		{
			get { return Settings.Current.ScreenshotImageFormat; }
			set
			{
				if (Settings.Current.ScreenshotImageFormat != value)
				{
					Settings.Current.ScreenshotImageFormat = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region Libraries 変更通知プロパティ

		private IEnumerable<BindableTextViewModel> _Libraries;

		public IEnumerable<BindableTextViewModel> Libraries
		{
			get { return this._Libraries; }
			set
			{
				if (!Equals(this._Libraries, value))
				{
					this._Libraries = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region IsDarkTheme 変更通知プロパティ

		private bool _IsDarkTheme;

		public bool IsDarkTheme
		{
			get { return this._IsDarkTheme; }
			set
			{
				if (this._IsDarkTheme != value)
				{
					this._IsDarkTheme = value;
					this.RaisePropertyChanged();
					if (value) ThemeService.Current.ChangeTheme(Theme.Dark);
				}
			}
		}

		#endregion

		#region IsLightTheme 変更通知プロパティ

		private bool _IsLightTheme;

		public bool IsLightTheme
		{
			get { return this._IsLightTheme; }
			set
			{
				if (this._IsLightTheme != value)
				{
					this._IsLightTheme = value;
					this.RaisePropertyChanged();
					if (value) ThemeService.Current.ChangeTheme(Theme.Light);
				}
			}
		}

		#endregion

		#region Cultures 変更通知プロパティ

		private IReadOnlyCollection<CultureViewModel> _Cultures;

		public IReadOnlyCollection<CultureViewModel> Cultures
		{
			get { return this._Cultures; }
			set
			{
				if (!Equals(this._Cultures, value))
				{
					this._Cultures = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region Culture 変更通知プロパティ

		/// <summary>
		/// カルチャを取得または設定します。
		/// </summary>
		public string Culture
		{
			get { return Settings.Current.Culture; }
			set
			{
				if (Settings.Current.Culture != value)
				{
					ResourceService.Current.ChangeCulture(value);
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region BrowserZoomFactor 変更通知プロパティ

		private BrowserZoomFactor _BrowserZoomFactor;

		public BrowserZoomFactor BrowserZoomFactor
		{
			get { return this._BrowserZoomFactor; }
			private set
			{
				if (this._BrowserZoomFactor != value)
				{
					this._BrowserZoomFactor = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region EnableLogging 変更通知プロパティ

		public bool EnableLogging
		{
			get { return Settings.Current.EnableLogging; }
			set
			{
				if (Settings.Current.EnableLogging != value)
				{
					Settings.Current.EnableLogging = value;
					KanColleClient.Current.Logger.EnableLogging = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region EnableTranslations 変更通知プロパティ

		public bool EnableTranslations
		{
			get { return Settings.Current.EnableTranslations; }
			set
			{
				if (Settings.Current.EnableTranslations != value)
				{
					Settings.Current.EnableTranslations = value;
					KanColleClient.Current.Translations.EnableTranslations = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region EnableAddUntranslated 変更通知プロパティ

		public bool EnableAddUntranslated
		{
			get { return Settings.Current.EnableAddUntranslated; }
			set
			{
				if (Settings.Current.EnableAddUntranslated != value)
				{
					Settings.Current.EnableAddUntranslated = value;
					KanColleClient.Current.Translations.EnableAddUntranslated = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region EnableCriticalNotify 変更通知プロパティ

		public bool EnableCriticalNotify
		{
			get { return Settings.Current.EnableCriticalNotify; }
			set
			{
				if (Settings.Current.EnableCriticalNotify != value)
				{
					Settings.Current.EnableCriticalNotify = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region EnableBattlePreview 変更通知プロパティ

		public bool EnableBattlePreview
		{
			get { return Settings.Current.EnableBattlePreview; }
			set
			{
				if (Settings.Current.EnableBattlePreview != value)
				{
					Settings.Current.EnableBattlePreview = value;
					KanColleClient.Current.OracleOfCompass.EnableBattlePreview = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region EnableMMCSS 変更通知プロパティ

		public bool EnableMMCSS
		{
			get { return Settings.Current.EnableMMCSS; }
			set
			{
				if (Settings.Current.EnableMMCSS != value)
				{
					Settings.Current.EnableMMCSS = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region EnableCriticalAccent 変更通知プロパティ

		public bool EnableCriticalAccent
		{
			get { return Settings.Current.EnableCriticalAccent; }
			set
			{
				if (Settings.Current.EnableCriticalAccent != value)
				{
					Settings.Current.EnableCriticalAccent = value;
					if (!Settings.Current.EnableCriticalAccent && App.ViewModelRoot.Mode == Mode.CriticalCondition)
						App.ViewModelRoot.Mode = Mode.Started;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region EquipmentVersion 変更通知プロパティ

		public string EquipmentVersion
		{
			get { return KanColleClient.Current.Translations.EquipmentVersion; }
			set
			{
				if (KanColleClient.Current.Translations.EquipmentVersion != value)
				{
					KanColleClient.Current.Translations.EquipmentVersion = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region OperationsVersion 変更通知プロパティ

		public string OperationsVersion
		{
			get { return KanColleClient.Current.Translations.OperationsVersion; }
			set
			{
				if (KanColleClient.Current.Translations.OperationsVersion != value)
				{
					KanColleClient.Current.Translations.OperationsVersion = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region QuestsVersion 変更通知プロパティ

		public string QuestsVersion
		{
			get { return KanColleClient.Current.Translations.QuestsVersion; }
			set
			{
				if (KanColleClient.Current.Translations.QuestsVersion != value)
				{
					KanColleClient.Current.Translations.QuestsVersion = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region ShipsVersion 変更通知プロパティ

		public string ShipsVersion
		{
			get { return KanColleClient.Current.Translations.ShipsVersion; }
			set
			{
				if (KanColleClient.Current.Translations.ShipsVersion != value)
				{
					KanColleClient.Current.Translations.ShipsVersion = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region ShipTypesVersion 変更通知プロパティ

		public string ShipTypesVersion
		{
			get { return KanColleClient.Current.Translations.ShipTypesVersion; }
			set
			{
				if (KanColleClient.Current.Translations.ShipTypesVersion != value)
				{
					KanColleClient.Current.Translations.ShipTypesVersion = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region ExpeditionsVersion 変更通知プロパティ

		public string ExpeditionsVersion
		{
			get { return KanColleClient.Current.Translations.ExpeditionsVersion; }
			set
			{
				if (KanColleClient.Current.Translations.ExpeditionsVersion != value)
				{
					KanColleClient.Current.Translations.ExpeditionsVersion = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region RemodelSlotsVersion 変更通知プロパティ

		public string RemodelSlotsVersion
		{
			get { return KanColleClient.Current.Translations.RemodelSlotsVersion; }
			set
			{
				if (KanColleClient.Current.Translations.RemodelSlotsVersion != value)
				{
					KanColleClient.Current.Translations.RemodelSlotsVersion = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region AppOnlineVersion 変更通知プロパティ

		private string _AppOnlineVersion;
		public string AppOnlineVersionURL { get; set; }

		public string AppOnlineVersion
		{
			get { return _AppOnlineVersion; }
			set
			{
				if (_AppOnlineVersion != value)
				{
					_AppOnlineVersion = value;
					this.RaisePropertyChanged();
					this.RaisePropertyChanged("AppOnlineVersionURL");
				}
			}
		}

		#endregion

		#region EquipmentOnlineVersion 変更通知プロパティ

		private string _EquipmentOnlineVersion;
		public string EquipmentOnlineVersionURL { get; set; }

		public string EquipmentOnlineVersion
		{
			get { return _EquipmentOnlineVersion; }
			set
			{
				if (_EquipmentOnlineVersion != value)
				{
					_EquipmentOnlineVersion = value;
					this.RaisePropertyChanged();
					this.RaisePropertyChanged("EquipmentOnlineVersionURL");
				}
			}
		}

		#endregion

		#region OperationsOnlineVersion 変更通知プロパティ

		private string _OperationsOnlineVersion;
		public string OperationsOnlineVersionURL { get; set; }

		public string OperationsOnlineVersion
		{
			get { return _OperationsOnlineVersion; }
			set
			{
				if (_OperationsOnlineVersion != value)
				{
					_OperationsOnlineVersion = value;
					this.RaisePropertyChanged();
					this.RaisePropertyChanged("OperationsOnlineVersionURL");
				}
			}
		}

		#endregion

		#region QuestsOnlineVersion 変更通知プロパティ

		private string _QuestsOnlineVersion;
		public string QuestsOnlineVersionURL { get; set; }

		public string QuestsOnlineVersion
		{
			get { return _QuestsOnlineVersion; }
			set
			{
				if (_QuestsOnlineVersion != value)
				{
					_QuestsOnlineVersion = value;
					this.RaisePropertyChanged();
					this.RaisePropertyChanged("QuestsOnlineVersionURL");
				}
			}
		}

		#endregion

		#region ShipsOnlineVersion 変更通知プロパティ

		private string _ShipsOnlineVersion;
		public string ShipsOnlineVersionURL { get; set; }

		public string ShipsOnlineVersion
		{
			get { return _ShipsOnlineVersion; }
			set
			{
				if (_ShipsOnlineVersion != value)
				{
					_ShipsOnlineVersion = value;
					this.RaisePropertyChanged();
					this.RaisePropertyChanged("ShipsOnlineVersionURL");
				}
			}
		}

		#endregion

		#region ShipTypesOnlineVersion 変更通知プロパティ

		private string _ShipTypesOnlineVersion;
		public string ShipTypesOnlineVersionURL { get; set; }

		public string ShipTypesOnlineVersion
		{
			get { return _ShipTypesOnlineVersion; }
			set
			{
				if (_ShipTypesOnlineVersion != value)
				{
					_ShipTypesOnlineVersion = value;
					this.RaisePropertyChanged();
					this.RaisePropertyChanged("ShipTypesOnlineVersionURL");
				}
			}
		}

		#endregion

		#region ExpeditionsOnlineVersion 変更通知プロパティ

		private string _ExpeditionsOnlineVersion;
		public string ExpeditionsOnlineVersionURL { get; set; }

		public string ExpeditionsOnlineVersion
		{
			get { return _ExpeditionsOnlineVersion; }
			set
			{
				if (_ExpeditionsOnlineVersion != value)
				{
					_ExpeditionsOnlineVersion = value;
					this.RaisePropertyChanged();
					this.RaisePropertyChanged("ExpeditionsOnlineVersionURL");
				}
			}
		}

		#endregion
		#region RemodelSlotsOnlineVersion 変更通知プロパティ

		private string _RemodelSlotsOnlineVersion;
		public string RemodelSlotsOnlineVersionURL { get; set; }

		public string RemodelSlotsOnlineVersion
		{
			get { return _RemodelSlotsOnlineVersion; }
			set
			{
				if (_RemodelSlotsOnlineVersion != value)
				{
					_RemodelSlotsOnlineVersion = value;
					this.RaisePropertyChanged();
					this.RaisePropertyChanged("RemodelSlotsOnlineVersionURL");
				}
			}
		}

		#endregion

		#region EnableUpdateNotification 変更通知プロパティ

		public bool EnableUpdateNotification
		{
			get { return Settings.Current.EnableUpdateNotification; }
			set
			{
				if (Settings.Current.EnableUpdateNotification != value)
				{
					Settings.Current.EnableUpdateNotification = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region EnableUpdateTransOnStart 変更通知プロパティ

		public bool EnableUpdateTransOnStart
		{
			get { return Settings.Current.EnableUpdateTransOnStart; }
			set
			{
				if (Settings.Current.EnableUpdateTransOnStart != value)
				{
					Settings.Current.EnableUpdateTransOnStart = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region CustomSoundVolume 変更通知プロパティ

		public int CustomSoundVolume
		{
			get { return Settings.Current.CustomSoundVolume; }
			set
			{
				if (Settings.Current.CustomSoundVolume != value)
				{
					Settings.Current.CustomSoundVolume = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region NotifierPlugins 変更通知プロパティ

		private List<NotifierViewModel> _NotifierPlugins;

		public List<NotifierViewModel> NotifierPlugins
		{
			get { return this._NotifierPlugins; }
			set
			{
				if (this._NotifierPlugins != value)
				{
					this._NotifierPlugins = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region ToolPlugins 変更通知プロパティ

		private List<ToolViewModel> _ToolPlugins;

		public List<ToolViewModel> ToolPlugins
		{
			get { return this._ToolPlugins; }
			set
			{
				if (this._ToolPlugins != value)
				{
					this._ToolPlugins = value;
					this.RaisePropertyChanged();
				}
			}
		}

		#endregion

		#region ViewRangeSettingsCollection 変更通知プロパティ

		private List<ViewRangeSettingsViewModel> _ViewRangeSettingsCollection;

		public List<ViewRangeSettingsViewModel> ViewRangeSettingsCollection
		{
			get { return this._ViewRangeSettingsCollection; }
			set
			{
				if (this._ViewRangeSettingsCollection != value)
				{
					this._ViewRangeSettingsCollection = value;
					this.RaisePropertyChanged();
					//if (value) Settings.Current.KanColleClientSettings.ViewRangeCalcLogic = ViewRangeCalcLogic.Type1;
				}
			}
		}

		#endregion

		#region Orientation

		private WindowOrientaionMode _Orientation;

		public WindowOrientaionMode Orientation
		{
			get { return this._Orientation; }
			private set
			{
				if (this._Orientation != value)
				{
					this._Orientation = value;
					this.RaisePropertyChanged();
				}
			}
		}
		#endregion

		public SettingsViewModel()
		{
			if (Helper.IsInDesignMode) return;

			this.Libraries = App.ProductInfo.Libraries.Aggregate(
				new List<BindableTextViewModel>(),
				(list, lib) =>
				{
					list.Add(new BindableTextViewModel { Text = list.Count == 0 ? "Build with " : ", " });
					list.Add(new HyperlinkViewModel { Text = lib.Name.Replace(' ', Convert.ToChar(160)), Uri = lib.Url });
					// プロダクト名の途中で改行されないように、space を non-break space に置き換えてあげてるんだからねっっ
					return list;
				});

			this.Cultures = new[] { new CultureViewModel { DisplayName = "(auto)" } }
				.Concat(ResourceService.Current.SupportedCultures
					.Select(x => new CultureViewModel { DisplayName = x.EnglishName, Name = x.Name })
					.OrderBy(x => x.DisplayName))
				.ToList();

			this.CompositeDisposable.Add(new PropertyChangedEventListener(Settings.Current)
			{
				(sender, args) => this.RaisePropertyChanged(args.PropertyName),
			});

			this._IsDarkTheme = ThemeService.Current.Theme == Theme.Dark;
			this._IsLightTheme = ThemeService.Current.Theme == Theme.Light;

			var zoomFactor = new BrowserZoomFactor { Current = Settings.Current.BrowserZoomFactor };
			this.CompositeDisposable.Add(new PropertyChangedEventListener(zoomFactor)
			{
				{ "Current", (sender, args) => Settings.Current.BrowserZoomFactor = zoomFactor.Current },
			});
			this.BrowserZoomFactor = zoomFactor;

			this.ViewRangeSettingsCollection = ViewRangeCalcLogic.Logics
				.Select(x => new ViewRangeSettingsViewModel(x))
				.ToList();

			var orientationMode = new WindowOrientaionMode { CurrentMode = Settings.Current.OrientationMode };
			this.CompositeDisposable.Add(orientationMode);
			this.CompositeDisposable.Add(new PropertyChangedEventListener(orientationMode)
			{
				{ "Current", (sender, args) => Settings.Current.Orientation = orientationMode.Current },
				{ "CurrentMode", (sender, args) => Settings.Current.OrientationMode = orientationMode.CurrentMode },
			});
			Settings.Current.Orientation = orientationMode.Current;
			this.Orientation = orientationMode;

			this.ReloadPlugins();
		}

		public void OpenScreenshotFolderSelectionDialog()
		{
			var message = new FolderSelectionMessage("OpenFolderDialog/Screenshot")
			{
				Title = Resources.Settings_Screenshot_FolderSelectionDialog_Title,
				DialogPreference = Helper.IsWindows8OrGreater
					? FolderSelectionDialogPreference.CommonItemDialog
					: FolderSelectionDialogPreference.FolderBrowser,
				SelectedPath = this.CanOpenScreenshotFolder
					? this.ScreenshotFolder
					: ""
			};
			this.Messenger.Raise(message);

			if (Directory.Exists(message.Response))
			{
				this.ScreenshotFolder = message.Response;
			}
		}

		public void OpenScreenshotFolder()
		{
			if (this.CanOpenScreenshotFolder)
			{
				try
				{
					Process.Start(this.ScreenshotFolder);
				}
				catch (Exception ex)
				{
					Debug.WriteLine(ex);
				}
			}
		}

		public void ClearZoomFactor()
		{
			App.ViewModelRoot.Messenger.Raise(new InteractionMessage { MessageKey = "WebBrowser/Zoom" });
		}

		public void SetLocationLeft()
		{
			App.ViewModelRoot.Messenger.Raise(new SetWindowLocationMessage { MessageKey = "Window/Location", Left = 0.0 });
		}

		public void ReloadPlugins()
		{
			this.NotifierPlugins = new List<NotifierViewModel>(PluginHost.Instance.Notifiers.Select(x => new NotifierViewModel(x)));
			this.ToolPlugins = new List<ToolViewModel>(PluginHost.Instance.Tools.Select(x => new ToolViewModel(x)));
		}

		public class ViewRangeSettingsViewModel
		{
			private bool selected;

			public ICalcViewRange Logic { get; set; }

			public bool Selected
			{
				get { return this.selected; }
				set
				{
					this.selected = value;
					if (value)
					{
						Settings.Current.KanColleClientSettings.ViewRangeCalcType = this.Logic.Id;
					}
				}
			}

			public ViewRangeSettingsViewModel(ICalcViewRange logic)
			{
				this.Logic = logic;
				this.selected = Settings.Current.KanColleClientSettings.ViewRangeCalcType == logic.Id;
			}
		}

		public void CheckForUpdates()
		{
			if (KanColleClient.Current.Updater.LoadVersion(Properties.Settings.Default.KCVUpdateUrl.AbsoluteUri))
			{
				AppOnlineVersionURL = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.App, true);
				EquipmentOnlineVersionURL = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.Equipment, true);
				OperationsOnlineVersionURL = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.Operations, true);
				QuestsOnlineVersionURL = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.Quests, true);
				ShipsOnlineVersionURL = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.Ships, true);
				ShipTypesOnlineVersionURL = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.ShipTypes, true);
				ExpeditionsOnlineVersionURL = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.Expeditions, true);
				RemodelSlotsOnlineVersionURL = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.RemodelSlots, true);

				AppOnlineVersion = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.App);
				EquipmentOnlineVersion = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.Equipment);
				OperationsOnlineVersion = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.Operations);
				QuestsOnlineVersion = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.Quests);
				ShipsOnlineVersion = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.Ships);
				ShipTypesOnlineVersion = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.ShipTypes);
				ExpeditionsOnlineVersion = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.Expeditions);
				RemodelSlotsOnlineVersion = KanColleClient.Current.Updater.GetOnlineVersion(TranslationType.RemodelSlots);
			}
			else
			{
				PluginHost.Instance.GetNotifier().Show(
					NotifyType.Update,
					Resources.Updater_Notification_Title,
					Resources.Updater_Notification_CheckFailed,
					() => App.ViewModelRoot.Activate());
			}
		}

		public void UpdateTranslations()
		{
			int UpdateStatus = KanColleClient.Current.Updater.UpdateTranslations(Properties.Settings.Default.XMLTransUrl.AbsoluteUri, KanColleClient.Current.Translations);

			if (UpdateStatus > 0)
			{
				PluginHost.Instance.GetNotifier().Show(
					NotifyType.Update,
					Resources.Updater_Notification_Title,
					Resources.Updater_Notification_TransUpdate_Success,
					() => App.ViewModelRoot.Activate());
			}
			else if (UpdateStatus < 0)
			{
				PluginHost.Instance.GetNotifier().Show(
					NotifyType.Update,
					Resources.Updater_Notification_Title,
					Resources.Updater_Notification_TransUpdate_Fail,
					() => App.ViewModelRoot.Activate());
			}
			else
			{
				PluginHost.Instance.GetNotifier().Show(
					NotifyType.Update,
					Resources.Updater_Notification_Title,
					Resources.Updater_Notification_TransUpdate_Same,
					() => App.ViewModelRoot.Activate());
			}

		}
		public void LogoutDMM()
		{
			App.ViewModelRoot.Navigator.Logout();
		}
	}
}