text:
Zulip
=====

Zulip is a powerful, open source group chat application. Written in
Python and using the Django framework, Zulip supports both private
messaging and group chats via conversation streams.

Zulip also supports fast search, drag-and-drop file uploads, image
previews, group private messages, audible notifications,
missed-message emails, desktop apps, and much more.

Further information on the Zulip project and its features can be found
at https://www.zulip.org.

[![Build Status][1]][2]

[1]: https://travis-ci.org/zulip/zulip.svg?branch=master
[2]: https://travis-ci.org/zulip/zulip

Installing the Zulip Development environment
============================================

The Zulip development environment is the recommended option for folks
interested in trying out Zulip.  This is documented in
[README.dev.md](README.dev.md).

Running Zulip in production
===========================

Zulip in production only supports Ubuntu 14.04 right now, but work is
ongoing on adding support for additional platforms. The installation
process is documented at https://zulip.org/server.html and in more
detail in [README.prod.md](README.prod.md).

Contributing to Zulip
=====================

Zulip welcomes all forms of contributions!  The page documents the
Zulip development process.

* **Pull requests**. Before a pull request can be merged, you need to
to sign the [Dropbox Contributor License Agreement][cla].  Also,
please skim our [commit message style guidelines][doc-commit-style].

* **Testing**. The Zulip automated tests all run automatically when
you submit a pull request, but you can also run them all in your
development environment following the instructions in the [testing
docs][doc-test].

* **Developer Documentation**.  Zulip has a growing collection of
developer documentation on [Read The Docs][doc].  Recommended reading
for new contributors includes the [directory structure][doc-dirstruct]
and [new feature tutorial][doc-newfeat]. You can also improve
[Zulip.org][z-org].

* **Mailing lists and bug tracker**. Zulip has a [development
discussion mailing list][gg-devel] and uses [GitHub issues
][gh-issues].  There are also lists for the [Android][email-android]
and [iOS][email-ios] apps.  Feel free to send any questions or
suggestions of areas where you'd love to see more documentation to the
relevant list!  Please report any security issues you discover to
zulip-security@googlegroups.com.

* **App codebases**. This repository is for the Zulip server and web
app (including most integrations); the [desktop][], [Android][], and
[iOS][] apps, are separate repositories, as is [our experimental React
Native iOS app][ios-exp].

* **Glue code**. We maintain a [Hubot adapter][hubot-adapter] and several
integrations ([Phabricator][phab], [Jenkins][], [Puppet][], [Redmine][],
and [Trello][]), plus [node.js API bindings][node], and a [full-text search
PostgreSQL extension][tsearch], as separate repos.

* **Translations**.  Zulip is in the process of being translated into
10+ languages, and we love contributions to our translations.  See our
[translating documentation](transifex) if you're interested in
contributing!

[cla]: https://opensource.dropbox.com/cla/
[doc]: https://zulip.readthedocs.io/
[doc-commit-style]: http://zulip.readthedocs.io/en/latest/code-style.html#commit-messages
[doc-dirstruct]: http://zulip.readthedocs.io/en/latest/directory-structure.html
[doc-newfeat]: http://zulip.readthedocs.io/en/latest/new-feature-tutorial.html
[doc-test]: https://github.com/zulip/zulip/blob/master/README.dev.md#running-the-test-suite
[gg-devel]: https://groups.google.com/forum/#!forum/zulip-devel
[gh-issues]: https://github.com/zulip/zulip/issues
[desktop]: https://github.com/zulip/zulip-desktop
[android]: https://github.com/zulip/zulip-android
[ios]: https://github.com/zulip/zulip-ios
[ios-exp]: https://github.com/zulip/zulip-mobile
[email-android]: https://groups.google.com/forum/#!forum/zulip-android
[email-ios]: https://groups.google.com/forum/#!forum/zulip-ios
[hubot-adapter]: https://github.com/zulip/hubot-zulip
[jenkins]: https://github.com/zulip/zulip-jenkins-plugin
[node]: https://github.com/zulip/zulip-node
[phab]: https://github.com/zulip/phabricator-to-zulip
[puppet]: https://github.com/matthewbarr/puppet-zulip
[redmine]: https://github.com/zulip/zulip-redmine-plugin
[trello]: https://github.com/zulip/trello-to-zulip
[tsearch]: https://github.com/zulip/tsearch_extras
[transifex]: https://www.transifex.com/zulip/zulip/
[z-org]: https://github.com/zulip/zulip.github.io

How to get involved with contributing to Zulip
==============================================

First, subscribe to the Zulip [development discussion mailing
list][gg-devel].

The Zulip project uses a system of labels in our [issue
tracker][gh-issues] to make it easy to find a project if you don't
have your own project idea in mind or want to get some experience with
working on Zulip before embarking on a larger project you have in
mind:

* [Integrations](https://github.com/zulip/zulip/labels/integrations).
  Integrate Zulip with another piece of software and contribute it
  back to the community!  Writing an integration can be a great first
  contribution.  There's detailed documentation on how to write
  integrations in [the Zulip integration writing
  guide](https://zulip.readthedocs.io/en/latest/integration-guide.html).

* [Bite Size](https://github.com/zulip/zulip/labels/bite%20size):
  Smaller projects that might be a great first contribution.

* [Documentation](https://github.com/zulip/zulip/labels/documentation):
  The Zulip project loves contributions of new documentation.

* [Help Wanted](https://github.com/zulip/zulip/labels/help%20wanted):
  A broader list of projects that nobody is currently working on.

* [Platform support](https://github.com/zulip/zulip/labels/Platform%20support):
  These are open issues about making it possible to install Zulip on a
  wider range of platforms.

* [Bugs](https://github.com/zulip/zulip/labels/bug): Open bugs.

* [Feature requests](https://github.com/zulip/zulip/labels/enhancement):
  Browsing this list can be a great way to find feature ideas to
  implement that other Zulip users are excited about.

* [2016 roadmap milestone](http://zulip.readthedocs.io/en/latest/roadmap.html): The
  projects that are [priorities for the Zulip project](https://zulip.readthedocs.io/en/latest/roadmap.html).  These are great projects if you're looking to make an impact.

If you're excited about helping with an open issue, just post on the
conversation thread that you're working on it.  You're encouraged to
ask questions on how to best implement or debug your changes -- the
Zulip maintainers are excited to answer questions to help you stay
unblocked and working efficiently.

We also welcome suggestions of features that you feel would be
valuable or changes that you feel would make Zulip a better open
source project, and are happy to support you in adding new features or
other user experience improvements to Zulip.

If you have a new feature you'd like to add, we recommend you start by
opening a GitHub issue about the feature idea explaining the problem
that you're hoping to solve and that you're excited to work on it.  A
Zulip maintainer will usually reply within a day with feedback on the
idea, notes on any important issues or concerns, and and often tips on
how to implement or test it.  Please feel free to ping the thread if
you don't hear a response from the maintainers -- we try to be very
responsive so this usually means we missed your message.

For significant changes to the visual design, user experience, data
model, or architecture, we highly recommend posting a mockup,
screenshot, or description of what you have in mind to zulip-devel@ to
get broad feedback before you spend too much time on implementation
details.

Finally, before implementing a larger feature, we highly recommend
looking at the new feature tutorial and coding style guidelines on
ReadTheDocs.

Feedback on how to make this development process more efficient, fun,
and friendly to new contributors is very welcome!  Just send an email
to the Zulip Developers list with your thoughts.

License
=======

Copyright 2011-2015 Dropbox, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

The software includes some works released by third parties under other
free and open source licenses. Those works are redistributed under the
license terms under which the works were received. For more details,
see the ``THIRDPARTY`` file included with this distribution.


text:
package org.telegram.dao;

// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable "keep" sections if you want to edit.
/**
 * Entity mapped to table SECRET_CHAT.
 */
public class SecretChat {

    private long id;
    private long accessHash;
    private int uid;
    private int state;
    private boolean isOut;
    private byte[] key;
    private Integer selfDestruct;

    public SecretChat() {
    }

    public SecretChat(long id) {
        this.id = id;
    }

    public SecretChat(long id, long accessHash, int uid, int state, boolean isOut, byte[] key, Integer selfDestruct) {
        this.id = id;
        this.accessHash = accessHash;
        this.uid = uid;
        this.state = state;
        this.isOut = isOut;
        this.key = key;
        this.selfDestruct = selfDestruct;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public long getAccessHash() {
        return accessHash;
    }

    public void setAccessHash(long accessHash) {
        this.accessHash = accessHash;
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public boolean getIsOut() {
        return isOut;
    }

    public void setIsOut(boolean isOut) {
        this.isOut = isOut;
    }

    public byte[] getKey() {
        return key;
    }

    public void setKey(byte[] key) {
        this.key = key;
    }

    public Integer getSelfDestruct() {
        return selfDestruct;
    }

    public void setSelfDestruct(Integer selfDestruct) {
        this.selfDestruct = selfDestruct;
    }

}

redpajama_set_name: RedPajamaGithub


text:
// +build windows

package hyperv

import (
	"bufio"
	"bytes"
	"os/exec"
	"strings"

	"github.com/golang/glog"
)

var powershell string

func init() {
	powershell, _ = exec.LookPath("powershell")
}

func cmdOut(args ...string) (string, error) {
	args = append([]string{"-NoProfile", "-NonInteractive"}, args...)
	cmd := exec.Command(powershell, args...)
	glog.Infof("[executing ==>] : %v %v", powershell, strings.Join(args, " "))
	var stdout bytes.Buffer
	var stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	err := cmd.Run()
	glog.Infof("[stdout =====>] : %s", stdout.String())
	glog.Infof("[stderr =====>] : %s", stderr.String())
	if err != nil {
		glog.Infof("[err =====>] : %v", err)
	}
	return stdout.String(), err
}

func cmd(args ...string) error {
	_, err := cmdOut(args...)
	return err
}

func parseLines(stdout string) []string {
	var resp []string

	s := bufio.NewScanner(strings.NewReader(stdout))
	for s.Scan() {
		resp = append(resp, s.Text())
	}

	return resp
}


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main_dialog_root_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context=".MainDialog"
    >
  <androidx.recyclerview.widget.RecyclerView
      android:id="@+id/main_dialog_recycler_view"
      android:layout_width="match_parent"
      android:layout_height="200dp"
      app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
      />
  <LinearLayout
      android:id="@+id/main_dialog_emoji_bar"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:background="@color/chat_input_background"
      android:gravity="center_vertical"
      android:orientation="horizontal"
      android:padding="4dp"
      >
    <ImageButton
        android:id="@+id/main_dialog_emoji"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:background="?attr/selectableItemBackgroundBorderless"
        android:padding="12dp"
        android:scaleType="centerCrop"
        app:srcCompat="@drawable/ic_emojis"
        tools:ignore="ContentDescription"
        />
    <EditText
        android:id="@+id/main_dialog_chat_bottom_message_edittext"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:hint="Type a message ..."
        android:imeOptions="actionSend"
        android:importantForAutofill="no"
        android:inputType="textCapSentences|textMultiLine"
        android:maxLines="3"
        tools:ignore="HardcodedText,LabelFor"
        />
    <ImageView
        android:id="@+id/main_dialog_send"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:background="?attr/selectableItemBackgroundBorderless"
        android:padding="12dp"
        android:scaleType="centerCrop"
        app:srcCompat="@drawable/ic_send"
        tools:ignore="ContentDescription"
        />
  </LinearLayout>
</LinearLayout>


text:
package ezbake.frack.api;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import ezbake.base.thrift.Visibility;
import ezbake.quarantine.thrift.AdditionalMetadata;

import java.io.Serializable;
import java.util.Map;

/**
 * Created by eperry on 2/10/14.
 */
public class SimplePublisher implements Publisher {
    private Multimap<Class<? extends Serializable>, Envelope> dataBetweenPipes;

    public SimplePublisher() {
        dataBetweenPipes = ArrayListMultimap.create();
    }

    @Override
    public void publish(Class<? extends Serializable> clazz, Envelope envelope) {
        dataBetweenPipes.put(clazz, envelope);
    }

    @Override
    public void sendRawToQuarantine(byte[] data, Visibility visibility, String error, AdditionalMetadata additionalMetadata) {}

    public Multimap<Class<? extends Serializable>, Envelope>  getDataBetweenPipes() {
        Multimap<Class<? extends Serializable>, Envelope> result = dataBetweenPipes;
        dataBetweenPipes = ArrayListMultimap.create();
        return result;
    }
}


text:
namespace VideoGamesSpa.ApiParser.Models
{
	public class PsnProfile
	{
		public string Id { get; set; }
		public string Pic { get; set; }
		public int Points { get; set; }
		public int PossiblePoints { get; set; }
		public int Level { get; set; }
		public double LevelProgress { get; set; }
		public int NextLevelPoints { get; set; }
		public int Trophies { get; set; }
		public int TrophiesBronze { get; set; }
		public int TrophiesSilver { get; set; }
		public int TrophiesGold { get; set; }
		public int TrophiesPlatinum { get; set; }
		public int PossibleTrophies { get; set; }
		public int PossibleTrophiesBronze { get; set; }
		public int PossibleTrophiesSilver { get; set; }
		public int PossibleTrophiesGold { get; set; }
		public int PossibleTrophiesPlatinum { get; set; }
		public double CompletionPercent { get; set; }
		public int TotalGames { get; set; }

		public PsnProfile()
		{
		}

		public void Serialize(System.IO.TextWriter writer)
		{
			var serializer = new System.Xml.Serialization.XmlSerializer(this.GetType());
			serializer.Serialize(writer, this);
		}
	}
}


text:
JSizes is a small plugin for the [jQuery JavaScript library](http://jquery.com/) which adds convenience methods for querying and setting the CSS `min-width`, `min-height`, `max-width`, `max-height`, `border-*-width`, `margin`, and `padding` properties. Additionally it has one method for determining whether an element is visible. In total it adds six new methods to the jQuery element API. It internally calls the jQuery built-in `css` method, so syntax and use is identical to calling `css('property-name', ...)`. An example of its use follows.

    jQuery(function($) {
       var myDiv = $('#myDiv');

       myDiv.minWidth(100); // set 'min-width' to 100px
       alert(myDiv.minWidth()); // displays '100'
    });

Note that all returned values are converted to pixel values, without the `px` suffix. It is thus safe to use these methods in calculations without having to worry about non-numeric values. Most importantly, it does *not* add support for min- and max-sizes on browsers that do not natively support it, it just adds convenient methods to query these properties and return a sensible value when they are not available or not set.

## API

The plugin adds the following methods to the JQuery object:

minSize()

Returns the CSS `min-width` and `min-height` properties of the first matched element as pixel values in an object with `width` and `height` properties. If a CSS property is not set `0` is returned as value.

minSize(value)

Sets the CSS `min-width`, and `min-height` property on all matched elements. Expects a value object containing any of `width` and `height` properties. If the property values are numbers they will be converted to pixel values.

maxSize()

Returns the CSS `max-width` and `max-height` properties of the first matched element as pixel values in an object with `width` and `height` properties. If a CSS property is not set `Number.MAX_VALUE` is returned as value.

maxSize(value)

Sets the CSS `max-width` and `max-height` property on all matched elements. Expects a value object containing any of `width` and `height` properties. If the property values are numbers they will be converted to pixel values.

margin()

Returns the CSS `margin` property of the first matched element as pixel values in an object with `top`, `bottom`, `left`, and `right` properties.

margin(value)

Sets the CSS `margin` property on all matched elements. Expects a value object containing any of `top` , `bottom` , `left` , and `right` properties. If the property values are numbers they will be converted to pixel values.

padding()

Returns the CSS `padding` property of the first matched element as pixel values in an object with `top`, `bottom`, `left`, and `right` properties.

padding(value)

Sets the CSS `padding` property on all matched elements. Expects a value object containing any of `top`, `bottom`, `left`, and `right` properties. If the property values are numbers they will be converted to pixel values.

border()

Returns the CSS `border-*-width` property of the first matched element as pixels values in an object with `top`, `bottom`, `left`, and `right` properties.

border(value)

Sets the CSS `border-*-width` property on all matched elements. Expects a value object containing any of `top`, `bottom`, `left`, and `right` properties. If the property values are numbers they will be converted to pixel values. Note that the CSS `border-style` property also needs to be set in order for the border to show.

isVisible()

Returns true if the any of the matched element are visible, false otherwise.

## Examples

Some examples of how the new methods can be used:

    jQuery(function($) {
       var myDiv = $('#myDiv');

       // set margin-top to 100px and margin-bottom to 10em
       myDiv.margin({top: 100, bottom: '10em'});

       // displays the size of the top border in pixels
       alert(myDiv.border().top);

       // displays true if the element is visible, false otherwise
       alert(myDiv.isVisible());

       // set padding-right to 10px and margin-left to 15px using chaining
       myDiv.padding({right: 10}).margin({left: 15});
    });

The above example also shows that chaining can be used on methods that do not return values.

## Credits

* John Bowers ― Setting values to zero bug fix.


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

		<title>example of a page going back and forward for iframes</title>

		<link rel="stylesheet" href="../toolkits/dojo/dijit/themes/tundra/tundra.css"/>
		<link rel="stylesheet" href="../toolkits/dojo/dojo/resources/dojo.css"/>

go


text:
#ifndef Py_STRUCTMEMBER_H
#define Py_STRUCTMEMBER_H
#ifdef __cplusplus
extern "C" {
#endif

#include <stddef.h> /* For offsetof */
#ifndef offsetof
#define offsetof(type, member) ( (int) & ((type*)0) -> member )
#endif

typedef struct PyMemberDef {
	/* Current version, use this */
	char *name;
	int type;
	Py_ssize_t offset;
	int flags;
	char *doc;
} PyMemberDef;

/* Types. These constants are also in structmemberdefs.py. */
#define T_SHORT		0
#define T_INT		1
#define T_LONG		2
#define T_FLOAT		3
#define T_DOUBLE	4
#define T_STRING	5
#define T_OBJECT	6
#define T_CHAR		7	/* 1-character string */
#define T_BYTE		8	/* 8-bit signed int */
#define T_UBYTE		9
#define T_USHORT	10
#define T_UINT		11
#define T_ULONG		12
#define T_STRING_INPLACE 13	/* Strings contained in the structure */
#define T_BOOL		14
#define T_OBJECT_EX	16	/* Like T_OBJECT, but raises AttributeError
				   when the value is NULL, instead of
				   converting to None. */
#define T_LONGLONG	17
#define T_ULONGLONG	18
#define T_PYSSIZET	19

/* Flags. These constants are also in structmemberdefs.py. */
#define READONLY      1
#define RO            READONLY                /* Shorthand */
#define READ_RESTRICTED 2
#define PY_WRITE_RESTRICTED 4
#define RESTRICTED    (READ_RESTRICTED | PY_WRITE_RESTRICTED)

#ifdef __cplusplus
}
#endif
#endif /* !Py_STRUCTMEMBER_H */


text:
package com.opengamma.analytics.financial.model.option.pricing.tree;

/**
 *
 */
public abstract class LatticeSpecification {

  /**
   * Compute up factor, down factor, up probability, down probability
   * @param spot Spot price of underlying
   * @param strike Strike price
   * @param timeToExpiry Time to expiry of option
   * @param volatility Volatility
   * @param interestRate Interest rate
   * @param nSteps Number of Steps
   * @param dt Time step, that is, dt * N = tiemToExpiry
   * @return {up factor, down factor, up probability, down probability}
   */
  public abstract double[] getParameters(final double spot, final double strike, final double timeToExpiry, final double volatility, final double interestRate, final int nSteps, final double dt);

  /**
   * If (up factor)*(down factor)=1 is satisfied, e.g., CRR specification, simpler approximation can be used
   * @param spot Spot
   * @param volatility Volatility
   * @param interestRate Interest rate
   * @param dividend Continuous dividend
   * @param dt Time step
   * @param greeksTmp {price_{0,0}, delta_{0,0}, gamma_{0,0}, price_{2,1}}
   * @return Theta
   */
  public double getTheta(final double spot, final double volatility, final double interestRate, final double dividend, final double dt, final double[] greeksTmp) {

    return interestRate * greeksTmp[0] - (interestRate - dividend) * spot * greeksTmp[1] - 0.5 * volatility * volatility * spot * spot * greeksTmp[2];
  }

  /**
   * Compute up factor, middle factor, down factor, up probability, middle probability, down probability
   * @param spot Spot price of underlying
   * @param strike Strike price
   * @param timeToExpiry Time to expiry of option
   * @param volatility Volatility
   * @param interestRate Interest rate
   * @param nSteps Number of Steps
   * @param dt Time step, that is, dt * N = tiemToExpiry
   * @return {up factor, middle factor, down Factor, up Probability, middle probability, down Probability}
   */
  public double[] getParametersTrinomial(final double spot, final double strike, final double timeToExpiry, final double volatility, final double interestRate, final int nSteps, final double dt) {
    throw new IllegalArgumentException("This lattice specification does not cover trinomial tree");
  }

}


text:
<!DOCTYPE html>

    <meta charset="UTF-8">
    <meta name="format-detection" content="telephone=no">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta name="viewport" content="width=device-width,height=device-height,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
    <meta http-equiv="cleartype" content="on">
    <meta name="HandheldFriendly" content="True">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="description" content="">
    <meta name="author" content="">
    <meta name="description" content="">
    <meta name="keyword" content="">
    <title></title>

adsada

<input type="button" value="add" onclick="add()"/>


text:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<METS:mets LABEL="Zeitschrift für Kranken-und Humanitätsanstalten, 4, 10.03.1911" TYPE="Periodical"
  xmlns:METS="http://www.loc.gov/METS/"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.loc.gov/METS/
    http://www.loc.gov/standards/mets/mets.xsd
    info:lc/xmlns/premis-v2
    http://www.loc.gov/standards/premis/v2/premis.xsd">
<METS:metsHdr CREATEDATE="2014-11-18T12:06:15Z" ID="ope301-00000v" >
<METS:agent ROLE="CREATOR" TYPE="ORGANIZATION">
<METS:name>OSA001</METS:name>
</METS:agent>
</METS:metsHdr>
<METS:amdSec ID="PageID_0060">
<METS:techMD ID="MIX_001">
<METS:mdWrap MDTYPE="NISOIMG" MIMETYPE="text/xml">
<METS:xmlData>
<mix:mix xmlns:mix="http://www.loc.gov/mix/v20">
	<mix:BasicDigitalObjectInformation>
		<mix:ObjectIdentifier>
			<mix:objectIdentifierType>filename</mix:objectIdentifierType>
			<mix:objectIdentifierValue>PS_ope301-00000v_0060.tif</mix:objectIdentifierValue>
		</mix:ObjectIdentifier>
		<mix:ObjectIdentifier>
			<mix:objectIdentifierType>MD5</mix:objectIdentifierType>
			<mix:objectIdentifierValue>eeae54e3351beb235ec277fdf3b8f879</mix:objectIdentifierValue>
		</mix:ObjectIdentifier>
		<mix:fileSize>28459442</mix:fileSize>
		<mix:FormatDesignation>
			<mix:formatName>image/tiff</mix:formatName>
			<mix:formatVersion>6.0</mix:formatVersion>
		</mix:FormatDesignation>
		<mix:byteOrder>little endian</mix:byteOrder>
		<mix:Compression>
			<mix:compressionScheme>uncompressed</mix:compressionScheme>
		</mix:Compression>
	</mix:BasicDigitalObjectInformation>
	<mix:BasicImageInformation>
		<mix:BasicImageCharacteristics>
			<mix:imageWidth>2662</mix:imageWidth>
			<mix:imageHeight>3560</mix:imageHeight>
			<mix:PhotometricInterpretation>
				<mix:colorSpace>RGB</mix:colorSpace>
				<mix:ColorProfile>
					<mix:IccProfile>
						<mix:iccProfileName>Adobe RGB (1998)</mix:iccProfileName>
						<mix:iccProfileVersion>2.1.0</mix:iccProfileVersion>
					</mix:IccProfile>
				</mix:ColorProfile>
			</mix:PhotometricInterpretation>
		</mix:BasicImageCharacteristics>
	</mix:BasicImageInformation>
	<mix:ImageCaptureMetadata>
		<mix:GeneralCaptureInformation>
			<mix:dateTimeCreated>2014-05-22T12:40:52Z</mix:dateTimeCreated>
			<mix:imageProducer>Exon s.r.o.</mix:imageProducer>
			<mix:captureDevice>digital still camera</mix:captureDevice>
		</mix:GeneralCaptureInformation>
		<mix:ScannerCapture>
			<mix:scannerManufacturer>i2S</mix:scannerManufacturer>
			<mix:ScannerModel>
				<mix:scannerModelName>i2S</mix:scannerModelName>
				<mix:scannerModelNumber>ONYX RGB</mix:scannerModelNumber>
				<mix:scannerModelSerialNo>321007</mix:scannerModelSerialNo>
			</mix:ScannerModel>
			<mix:MaximumOpticalResolution>
				<mix:xOpticalResolution>400</mix:xOpticalResolution>
				<mix:yOpticalResolution>400</mix:yOpticalResolution>
				<mix:opticalResolutionUnit>in.</mix:opticalResolutionUnit>
			</mix:MaximumOpticalResolution>
			<mix:scannerSensor>OneChipColourArea</mix:scannerSensor>
			<mix:ScanningSystemSoftware>
				<mix:scanningSoftwareName>CopiBook RGB+</mix:scanningSoftwareName>
				<mix:scanningSoftwareVersionNo>4.0.7</mix:scanningSoftwareVersionNo>
			</mix:ScanningSystemSoftware>
		</mix:ScannerCapture>
		<mix:orientation>normal*</mix:orientation>
	</mix:ImageCaptureMetadata>
	<mix:ImageAssessmentMetadata>
		<mix:SpatialMetrics>
			<mix:samplingFrequencyUnit>in.</mix:samplingFrequencyUnit>
			<mix:xSamplingFrequency>
				<mix:numerator>300</mix:numerator>
				<mix:denominator>1</mix:denominator>
			</mix:xSamplingFrequency>
			<mix:ySamplingFrequency>
				<mix:numerator>300</mix:numerator>
				<mix:denominator>1</mix:denominator>
			</mix:ySamplingFrequency>
		</mix:SpatialMetrics>
		<mix:ImageColorEncoding>
			<mix:BitsPerSample>
				<mix:bitsPerSampleValue>8</mix:bitsPerSampleValue>
				<mix:bitsPerSampleValue>8</mix:bitsPerSampleValue>
				<mix:bitsPerSampleValue>8</mix:bitsPerSampleValue>
			</mix:BitsPerSample>
			<mix:samplesPerPixel>3</mix:samplesPerPixel>
		</mix:ImageColorEncoding>
	</mix:ImageAssessmentMetadata>
</mix:mix>
</METS:xmlData>
</METS:mdWrap>
</METS:techMD>
<METS:techMD ID="MIX_002">
<METS:mdWrap MDTYPE="NISOIMG" MIMETYPE="text/xml">
<METS:xmlData>
<mix:mix xmlns:mix="http://www.loc.gov/mix/v20">
	<mix:BasicDigitalObjectInformation>
		<mix:ObjectIdentifier>
			<mix:objectIdentifierType>filename</mix:objectIdentifierType>
			<mix:objectIdentifierValue>MC_ope301-00000v_0060.jp2</mix:objectIdentifierValue>
		</mix:ObjectIdentifier>
		<mix:ObjectIdentifier>
			<mix:objectIdentifierType>MD5</mix:objectIdentifierType>
			<mix:objectIdentifierValue>a61ba7aa8c711f410685325aed0c6a62</mix:objectIdentifierValue>
		</mix:ObjectIdentifier>
		<mix:fileSize>13986181</mix:fileSize>
		<mix:FormatDesignation>
			<mix:formatName>image/jp2</mix:formatName>
			<mix:formatVersion>1.0</mix:formatVersion>
		</mix:FormatDesignation>
		<mix:byteOrder>big endian</mix:byteOrder>
		<mix:Compression>
			<mix:compressionScheme>JPEG 2000</mix:compressionScheme>
		</mix:Compression>
	</mix:BasicDigitalObjectInformation>
	<mix:BasicImageInformation>
		<mix:BasicImageCharacteristics>
			<mix:imageWidth>2662</mix:imageWidth>
			<mix:imageHeight>3560</mix:imageHeight>
			<mix:PhotometricInterpretation>
				<mix:colorSpace>RGB</mix:colorSpace>
				<mix:ColorProfile>
					<mix:IccProfile>
						<mix:iccProfileName>IT8_7_2-1993.icm</mix:iccProfileName>
						<mix:iccProfileVersion>2</mix:iccProfileVersion>
					</mix:IccProfile>
				</mix:ColorProfile>
			</mix:PhotometricInterpretation>
		</mix:BasicImageCharacteristics>
		<mix:SpecialFormatCharacteristics>
			<mix:JPEG2000>
				<mix:CodecCompliance>
					<mix:codec>Kakadu</mix:codec>
					<mix:codecVersion>7.0</mix:codecVersion>
					<mix:codestreamProfile>P0</mix:codestreamProfile>
					<mix:complianceClass>C1</mix:complianceClass>
				</mix:CodecCompliance>
				<mix:EncodingOptions>
					<mix:Tiles>
						<mix:tileWidth>4096</mix:tileWidth>
						<mix:tileHeight>4096</mix:tileHeight>
					</mix:Tiles>
					<mix:qualityLayers>1</mix:qualityLayers>
					<mix:resolutionLevels>5</mix:resolutionLevels>
				</mix:EncodingOptions>
			</mix:JPEG2000>
		</mix:SpecialFormatCharacteristics>
	</mix:BasicImageInformation>
	<mix:ImageAssessmentMetadata>
		<mix:SpatialMetrics>
			<mix:samplingFrequencyUnit>in.</mix:samplingFrequencyUnit>
			<mix:xSamplingFrequency>
				<mix:numerator>300</mix:numerator>
				<mix:denominator>1</mix:denominator>
			</mix:xSamplingFrequency>
			<mix:ySamplingFrequency>
				<mix:numerator>300</mix:numerator>
				<mix:denominator>1</mix:denominator>
			</mix:ySamplingFrequency>
		</mix:SpatialMetrics>
		<mix:ImageColorEncoding>
			<mix:BitsPerSample>
				<mix:bitsPerSampleValue>8</mix:bitsPerSampleValue>
				<mix:bitsPerSampleValue>8</mix:bitsPerSampleValue>
				<mix:bitsPerSampleValue>8</mix:bitsPerSampleValue>
			</mix:BitsPerSample>
			<mix:samplesPerPixel>3</mix:samplesPerPixel>
		</mix:ImageColorEncoding>
	</mix:ImageAssessmentMetadata>
	<mix:ChangeHistory>
		<mix:ImageProcessing>
			<mix:dateTimeProcessed>2014-07-02T13:59:22</mix:dateTimeProcessed>
			<mix:sourceData>PS_ope301-00000v_0060.tif</mix:sourceData>
		</mix:ImageProcessing>
	</mix:ChangeHistory>
</mix:mix>
</METS:xmlData>
</METS:mdWrap>
</METS:techMD>
<METS:techMD ID="OBJ_001">
<METS:mdWrap MDTYPE="PREMIS" MIMETYPE="text/xml">
<METS:xmlData>
<premis:object xsi:type="premis:file" xmlns:premis="info:lc/xmlns/premis-v2">
	<premis:objectIdentifier>
		<premis:objectIdentifierType>ObjectID</premis:objectIdentifierType>
		<premis:objectIdentifierValue>Object_3615</premis:objectIdentifierValue>
	</premis:objectIdentifier>
	<premis:preservationLevel>
		<premis:preservationLevelValue>deleted</premis:preservationLevelValue>
		<premis:preservationLevelDateAssigned>2014-11-18T11:44:02</premis:preservationLevelDateAssigned>
	</premis:preservationLevel>
	<premis:objectCharacteristics>
		<premis:compositionLevel>0</premis:compositionLevel>
		<premis:fixity>
			<premis:messageDigestAlgorithm>CRC32</premis:messageDigestAlgorithm>
			<premis:messageDigest>48172778</premis:messageDigest>
			<premis:messageDigestOriginator>JHOVE</premis:messageDigestOriginator>
		</premis:fixity>
		<premis:fixity>
			<premis:messageDigestAlgorithm>SHA-1</premis:messageDigestAlgorithm>
			<premis:messageDigest>5a5231153774cfe122fae66d04a4921cc2a02fab</premis:messageDigest>
			<premis:messageDigestOriginator>JHOVE</premis:messageDigestOriginator>
		</premis:fixity>
		<premis:fixity>
			<premis:messageDigestAlgorithm>MD5</premis:messageDigestAlgorithm>
			<premis:messageDigest>eeae54e3351beb235ec277fdf3b8f879</premis:messageDigest>
			<premis:messageDigestOriginator>JHOVE</premis:messageDigestOriginator>
		</premis:fixity>
		<premis:size>28459442</premis:size>
		<premis:format>
			<premis:formatDesignation>
				<premis:formatName>image/tiff</premis:formatName>
				<premis:formatVersion>6.0</premis:formatVersion>
			</premis:formatDesignation>
			<premis:formatRegistry>
				<premis:formatRegistryName>PRONOM</premis:formatRegistryName>
				<premis:formatRegistryKey>fmt/10</premis:formatRegistryKey>
			</premis:formatRegistry>
		</premis:format>
		<premis:creatingApplication>
			<premis:creatingApplicationName>CopiBook RGB+</premis:creatingApplicationName>
			<premis:creatingApplicationVersion>4.0.7</premis:creatingApplicationVersion>
			<premis:dateCreatedByApplication>2014-05-22T12:40:52Z</premis:dateCreatedByApplication>
		</premis:creatingApplication>
	</premis:objectCharacteristics>
	<premis:originalName>PS_ope301-00000v_0060.tif</premis:originalName>
	<premis:linkingEventIdentifier>
		<premis:linkingEventIdentifierType>EventID</premis:linkingEventIdentifierType>
		<premis:linkingEventIdentifierValue>Event_0525</premis:linkingEventIdentifierValue>
	</premis:linkingEventIdentifier>
</premis:object>
</METS:xmlData>
</METS:mdWrap>
</METS:techMD>
<METS:techMD ID="OBJ_003">
<METS:mdWrap MDTYPE="PREMIS" MIMETYPE="text/xml">
<METS:xmlData>
<premis:object xsi:type="premis:file" xmlns:premis="info:lc/xmlns/premis-v2">
	<premis:objectIdentifier>
		<premis:objectIdentifierType>ObjectID</premis:objectIdentifierType>
		<premis:objectIdentifierValue>Object_3150</premis:objectIdentifierValue>
	</premis:objectIdentifier>
	<premis:preservationLevel>
		<premis:preservationLevelValue>preservation</premis:preservationLevelValue>
		<premis:preservationLevelDateAssigned>2014-11-18T11:29:19</premis:preservationLevelDateAssigned>
	</premis:preservationLevel>
	<premis:objectCharacteristics>
		<premis:compositionLevel>0</premis:compositionLevel>
		<premis:fixity>
			<premis:messageDigestAlgorithm>CRC32</premis:messageDigestAlgorithm>
			<premis:messageDigest>9006e513</premis:messageDigest>
			<premis:messageDigestOriginator>JHOVE</premis:messageDigestOriginator>
		</premis:fixity>
		<premis:fixity>
			<premis:messageDigestAlgorithm>SHA-1</premis:messageDigestAlgorithm>
			<premis:messageDigest>eef5116ae90f15629772920b0cc8c8dddb60fdaf</premis:messageDigest>
			<premis:messageDigestOriginator>JHOVE</premis:messageDigestOriginator>
		</premis:fixity>
		<premis:fixity>
			<premis:messageDigestAlgorithm>MD5</premis:messageDigestAlgorithm>
			<premis:messageDigest>1d01789bdea20a9d002bcc0eea497857</premis:messageDigest>
			<premis:messageDigestOriginator>JHOVE</premis:messageDigestOriginator>
		</premis:fixity>
		<premis:size>207171</premis:size>
		<premis:format>
			<premis:formatDesignation>
				<premis:formatName>text/xml</premis:formatName>
				<premis:formatVersion>1.0</premis:formatVersion>
			</premis:formatDesignation>
			<premis:formatRegistry>
				<premis:formatRegistryName>PRONOM</premis:formatRegistryName>
				<premis:formatRegistryKey>fmt/101</premis:formatRegistryKey>
			</premis:formatRegistry>
		</premis:format>
		<premis:creatingApplication>
			<premis:creatingApplicationName>Recognition Server</premis:creatingApplicationName>
			<premis:creatingApplicationVersion>4.0</premis:creatingApplicationVersion>
			<premis:dateCreatedByApplication>2014-11-18T11:22:41Z</premis:dateCreatedByApplication>
		</premis:creatingApplication>
	</premis:objectCharacteristics>
	<premis:originalName>ALTO_ope301-00000v_0060.xml</premis:originalName>
	<premis:relationship>
		<premis:relationshipType>derivation</premis:relationshipType>
		<premis:relationshipSubType>created from</premis:relationshipSubType>
		<premis:relatedObjectIdentification>
			<premis:relatedObjectIdentifierType>temporary filepath</premis:relatedObjectIdentifierType>
			<premis:relatedObjectIdentifierValue>D:\EXON-VISK 7\MVK_projekty\cnb002200033-001\PS_ope301-00000v_0060.TIF</premis:relatedObjectIdentifierValue>
		</premis:relatedObjectIdentification>
		<premis:relatedEventIdentification>
			<premis:relatedEventIdentifierType>EventID</premis:relatedEventIdentifierType>
			<premis:relatedEventIdentifierValue>Event_0060</premis:relatedEventIdentifierValue>
			<premis:relatedEventSequence>0060</premis:relatedEventSequence>
		</premis:relatedEventIdentification>
	</premis:relationship>
</premis:object>
</METS:xmlData>
</METS:mdWrap>
</METS:techMD>
<METS:techMD ID="OBJ_002">
<METS:mdWrap MDTYPE="PREMIS" MIMETYPE="text/xml">
<METS:xmlData>
<premis:object xsi:type="premis:file" xmlns:premis="info:lc/xmlns/premis-v2">
	<premis:objectIdentifier>
		<premis:objectIdentifierType>ObjectID</premis:objectIdentifierType>
		<premis:objectIdentifierValue>Object_3616</premis:objectIdentifierValue>
	</premis:objectIdentifier>
	<premis:preservationLevel>
		<premis:preservationLevelValue>preservation</premis:preservationLevelValue>
		<premis:preservationLevelDateAssigned>2014-11-18T11:44:03</premis:preservationLevelDateAssigned>
	</premis:preservationLevel>
	<premis:objectCharacteristics>
		<premis:compositionLevel>0</premis:compositionLevel>
		<premis:fixity>
			<premis:messageDigestAlgorithm>CRC32</premis:messageDigestAlgorithm>
			<premis:messageDigest>760dfd51</premis:messageDigest>
			<premis:messageDigestOriginator>JHOVE</premis:messageDigestOriginator>
		</premis:fixity>
		<premis:fixity>
			<premis:messageDigestAlgorithm>SHA-1</premis:messageDigestAlgorithm>
			<premis:messageDigest>9aaa82cbfb92091c6c73da667e9c8dc466d79317</premis:messageDigest>
			<premis:messageDigestOriginator>JHOVE</premis:messageDigestOriginator>
		</premis:fixity>
		<premis:fixity>
			<premis:messageDigestAlgorithm>MD5</premis:messageDigestAlgorithm>
			<premis:messageDigest>a61ba7aa8c711f410685325aed0c6a62</premis:messageDigest>
			<premis:messageDigestOriginator>JHOVE</premis:messageDigestOriginator>
		</premis:fixity>
		<premis:size>13986181</premis:size>
		<premis:format>
			<premis:formatDesignation>
				<premis:formatName>image/jp2</premis:formatName>
				<premis:formatVersion>1.0</premis:formatVersion>
			</premis:formatDesignation>
			<premis:formatRegistry>
				<premis:formatRegistryName>PRONOM</premis:formatRegistryName>
				<premis:formatRegistryKey>x-fmt/392</premis:formatRegistryKey>
			</premis:formatRegistry>
		</premis:format>
		<premis:creatingApplication>
			<premis:creatingApplicationName>Kakadu</premis:creatingApplicationName>
			<premis:creatingApplicationVersion>7.0</premis:creatingApplicationVersion>
			<premis:dateCreatedByApplication>2014-06-23T12:00:40Z</premis:dateCreatedByApplication>
		</premis:creatingApplication>
	</premis:objectCharacteristics>
	<premis:originalName>MC_ope301-00000v_0060.jp2</premis:originalName>
	<premis:relationship>
		<premis:relationshipType>derivation</premis:relationshipType>
		<premis:relationshipSubType>created from</premis:relationshipSubType>
		<premis:relatedObjectIdentification>
			<premis:relatedObjectIdentifierType>temporary filepath</premis:relatedObjectIdentifierType>
			<premis:relatedObjectIdentifierValue>D:\EXON-VISK 7\MVK_projekty\cnb002200033-001\PS_ope301-00000v_0060.TIF</premis:relatedObjectIdentifierValue>
		</premis:relatedObjectIdentification>
		<premis:relatedEventIdentification>
			<premis:relatedEventIdentifierType>EventID</premis:relatedEventIdentifierType>
			<premis:relatedEventIdentifierValue>Event_0526</premis:relatedEventIdentifierValue>
			<premis:relatedEventSequence>0526</premis:relatedEventSequence>
		</premis:relatedEventIdentification>
	</premis:relationship>
</premis:object>
</METS:xmlData>
</METS:mdWrap>
</METS:techMD>
<METS:digiprovMD ID="EVT_001">
<METS:mdWrap MDTYPE="PREMIS" MIMETYPE="text/xml">
<METS:xmlData>
<premis:event xmlns:premis="info:lc/xmlns/premis-v2">
	<premis:eventIdentifier>
		<premis:eventIdentifierType>EventId</premis:eventIdentifierType>
		<premis:eventIdentifierValue>Event_0060</premis:eventIdentifierValue>
	</premis:eventIdentifier>
	<premis:eventType>capture</premis:eventType>
	<premis:eventDateTime>2014-11-18T11:22:41Z</premis:eventDateTime>
	<premis:eventDetail>capture/XML_creation</premis:eventDetail>
	<premis:eventOutcomeInformation>
		<premis:eventOutcome>successful</premis:eventOutcome>
	</premis:eventOutcomeInformation>
	<premis:linkingAgentIdentifier>
		<premis:linkingAgentIdentifierType>AgentId</premis:linkingAgentIdentifierType>
		<premis:linkingAgentIdentifierValue>agent_OCR</premis:linkingAgentIdentifierValue>
	</premis:linkingAgentIdentifier>
	<premis:linkingObjectIdentifier>
		<premis:linkingObjectIdentifierType>FILE_ID</premis:linkingObjectIdentifierType>
		<premis:linkingObjectIdentifierValue>ALTO_ope301-00000v_0060.xml</premis:linkingObjectIdentifierValue>
	</premis:linkingObjectIdentifier>
</premis:event>
</METS:xmlData>
</METS:mdWrap>
</METS:digiprovMD>
<METS:digiprovMD ID="EVT_002">
<METS:mdWrap MDTYPE="PREMIS" MIMETYPE="text/xml">
<METS:xmlData>
<premis:event xmlns:premis="info:lc/xmlns/premis-v2">
	<premis:eventIdentifier>
		<premis:eventIdentifierType>EventId</premis:eventIdentifierType>
		<premis:eventIdentifierValue>Event_0526</premis:eventIdentifierValue>
	</premis:eventIdentifier>
	<premis:eventType>migration</premis:eventType>
	<premis:eventDateTime>2014-06-23T12:00:40Z</premis:eventDateTime>
	<premis:eventDetail>migration/MC_creation</premis:eventDetail>
	<premis:eventOutcomeInformation>
		<premis:eventOutcome>successful</premis:eventOutcome>
	</premis:eventOutcomeInformation>
	<premis:linkingAgentIdentifier>
		<premis:linkingAgentIdentifierType>AgentId</premis:linkingAgentIdentifierType>
		<premis:linkingAgentIdentifierValue>agent_Convertor</premis:linkingAgentIdentifierValue>
	</premis:linkingAgentIdentifier>
	<premis:linkingObjectIdentifier>
		<premis:linkingObjectIdentifierType>FILE_ID</premis:linkingObjectIdentifierType>
		<premis:linkingObjectIdentifierValue>MC_ope301-00000v_0060.jp2</premis:linkingObjectIdentifierValue>
	</premis:linkingObjectIdentifier>
</premis:event>
</METS:xmlData>
</METS:mdWrap>
</METS:digiprovMD>
<METS:digiprovMD ID="EVT_003">
<METS:mdWrap MDTYPE="PREMIS" MIMETYPE="text/xml">
<METS:xmlData>
<premis:event xmlns:premis="info:lc/xmlns/premis-v2">
	<premis:eventIdentifier>
		<premis:eventIdentifierType>EventId</premis:eventIdentifierType>
		<premis:eventIdentifierValue>Event_0525</premis:eventIdentifierValue>
	</premis:eventIdentifier>
	<premis:eventType>capture</premis:eventType>
	<premis:eventDateTime>2014-05-22T12:40:52Z</premis:eventDateTime>
	<premis:eventDetail>capture_digitization</premis:eventDetail>
	<premis:eventOutcomeInformation>
		<premis:eventOutcome>successful</premis:eventOutcome>
	</premis:eventOutcomeInformation>
	<premis:linkingAgentIdentifier>
		<premis:linkingAgentIdentifierType>AgentId</premis:linkingAgentIdentifierType>
		<premis:linkingAgentIdentifierValue>agent_Scanner</premis:linkingAgentIdentifierValue>
	</premis:linkingAgentIdentifier>
	<premis:linkingObjectIdentifier>
		<premis:linkingObjectIdentifierType>FILE_ID</premis:linkingObjectIdentifierType>
		<premis:linkingObjectIdentifierValue>PS_ope301-00000v_0060.tif</premis:linkingObjectIdentifierValue>
	</premis:linkingObjectIdentifier>
</premis:event>
</METS:xmlData>
</METS:mdWrap>
</METS:digiprovMD>
<METS:digiprovMD ID="AGENT_001">
<METS:mdWrap MDTYPE="PREMIS" MIMETYPE="text/xml">
<METS:xmlData>
<premis:agent xmlns:premis="info:lc/xmlns/premis-v2">
	<premis:agentIdentifier>
		<premis:agentIdentifierType>AgentID</premis:agentIdentifierType>
		<premis:agentIdentifierValue>agent_Scanner</premis:agentIdentifierValue>
	</premis:agentIdentifier>
	<premis:agentName>i2S</premis:agentName>
	<premis:agentType>software</premis:agentType>
</premis:agent>
</METS:xmlData>
</METS:mdWrap>
</METS:digiprovMD>
<METS:digiprovMD ID="AGENT_002">
<METS:mdWrap MDTYPE="PREMIS" MIMETYPE="text/xml">
<METS:xmlData>
<premis:agent xmlns:premis="info:lc/xmlns/premis-v2">
	<premis:agentIdentifier>
		<premis:agentIdentifierType>AgentID</premis:agentIdentifierType>
		<premis:agentIdentifierValue>agent_OCR</premis:agentIdentifierValue>
	</premis:agentIdentifier>
	<premis:agentName>Recognition Server v4.0</premis:agentName>
	<premis:agentType>software</premis:agentType>
</premis:agent>
</METS:xmlData>
</METS:mdWrap>
</METS:digiprovMD>
<METS:digiprovMD ID="AGENT_003">
<METS:mdWrap MDTYPE="PREMIS" MIMETYPE="text/xml">
<METS:xmlData>
<premis:agent xmlns:premis="info:lc/xmlns/premis-v2">
	<premis:agentIdentifier>
		<premis:agentIdentifierType>AgentID</premis:agentIdentifierType>
		<premis:agentIdentifierValue>agent_Convertor</premis:agentIdentifierValue>
	</premis:agentIdentifier>
	<premis:agentName>Kakadu v7.0</premis:agentName>
	<premis:agentType>software</premis:agentType>
	<premis:agentNote>kdu_compress -i "PS_ope301-00000v_0060.tif" -o "MC_ope301-00000v_0060.jp2" "Cblk={64,64}" Corder=RPCL "Stiles={4096,4096}" "Cprecincts={256,256},{256,256},{128,128}" ORGtparts=R Creversible=yes Clayers=1 Clevels=5 "Cmodes={BYPASS}" -double_buffering 60 Cuse_sop=yes Cuse_eph=yes</premis:agentNote>
</premis:agent>
</METS:xmlData>
</METS:mdWrap>
</METS:digiprovMD>
</METS:amdSec>
<METS:fileSec>
<METS:fileGrp ID="MC_IMGGRP" USE="Images" >
<METS:file SEQ="0060" CREATED="2014-07-02T13:59:22Z" ID="JP210060" MIMETYPE="image/jp2" CHECKSUM="a61ba7aa8c711f410685325aed0c6a62" CHECKSUMTYPE="MD5" SIZE="13986181">
<METS:FLocat LOCTYPE="URL" xlink:href="./masterCopy/MC_ope301-00000v_0060.jp2" />
</METS:file>
</METS:fileGrp>
<METS:fileGrp ID="UC_IMGGRP" USE="Images" >
<METS:file SEQ="0060" CREATED="2014-07-02T14:07:40Z" ID="JP220060" MIMETYPE="image/jp2" CHECKSUM="7400c2d0e3f3e9866705a70a981f0588" CHECKSUMTYPE="MD5" SIZE="1422366">
<METS:FLocat LOCTYPE="URL" xlink:href="./userCopy/UC_ope301-00000v_0060.jp2" />
</METS:file>
</METS:fileGrp>
<METS:fileGrp ID="TXTGRP" USE="Text" >
<METS:file SEQ="0060" CREATED="2014-07-02T14:07:35Z" ID="TXT30060" MIMETYPE="text/plain" CHECKSUM="a47792c35b62fb244a4e4bb03b94a4af" CHECKSUMTYPE="MD5" SIZE="6242">
<METS:FLocat LOCTYPE="URL" xlink:href="./TXT/TXT_ope301-00000v_0060.txt" />
</METS:file>
</METS:fileGrp>
<METS:fileGrp ID="ALTOGRP" USE="Layout" >
<METS:file SEQ="0060" CREATED="2014-07-02T13:58:53Z" ID="XML40060" MIMETYPE="text/xml" CHECKSUM="1d01789bdea20a9d002bcc0eea497857" CHECKSUMTYPE="MD5" SIZE="207171">
<METS:FLocat LOCTYPE="URL" xlink:href="./ALTO/ALTO_ope301-00000v_0060.xml" />
</METS:file>
</METS:fileGrp>
</METS:fileSec>
<METS:structMap LABEL="Physical_Structure" TYPE="PHYSICAL">
<METS:div TYPE="PERIODICAL_PAGE">
<METS:fptr FILEID="JP210060" />
<METS:fptr FILEID="JP220060" />
<METS:fptr FILEID="TXT30060" />
<METS:fptr FILEID="XML40060" />
</METS:div>
</METS:structMap>
</METS:mets>


text:
package com.fangyuzhong.FilterDesign.TopTen;

import com.fangyuzhong.FilterDesign.TopFilterN.DistinctUserMapper;
import com.fangyuzhong.FilterDesign.TopFilterN.DistinctUserReducer;
import com.fangyuzhong.FilterDesign.TopFilterN.TopFilterNMapper;
import com.fangyuzhong.FilterDesign.TopFilterN.TopFilterNReducer;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mrunit.mapreduce.MapDriver;
import org.apache.hadoop.mrunit.mapreduce.MapReduceDriver;
import org.apache.hadoop.mrunit.mapreduce.ReduceDriver;
import org.apache.hadoop.mrunit.types.Pair;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

/**
 * Created by fangyuzhong on 17-7-5.
 */
public class TopFilterNMapReduceTest
{
    private MapDriver mapDriver;
    private ReduceDriver reduceDriver;
    private MapReduceDriver mapReduceDriver;

    @Before
    public void setUp()
    {
        TopFilterNMapper mapper = new TopFilterNMapper();
        mapDriver = MapDriver.newMapDriver(mapper);
        TopFilterNReducer reducer = new TopFilterNReducer();
        reduceDriver =ReduceDriver.newReduceDriver();
        reduceDriver.withReducer(reducer);
        mapReduceDriver = MapReduceDriver.newMapReduceDriver(mapper,reducer);
    }

    @Test
    public void testMapper() throws IOException
    {
        Text text1 = new Text("004955246,CANTOMANY,M,19700505,47");
        Text text2 = new Text("005111197197404013018,Q,M,19740401,43");
        Text text3 = new Text("001222519819822210209447,W,F,19821020,35");
        mapDriver.withInput(new LongWritable(),text1);
        mapDriver.withInput(new LongWritable(),text2);
        mapDriver.withInput(new LongWritable(),text3);
        mapDriver.withOutput(NullWritable.get(),text3);
        mapDriver.withOutput(NullWritable.get(),text2);
        mapDriver.withOutput(NullWritable.get(),text1);
        mapDriver.runTest();
        // 输出
        List<Pair> expectedOutputList = mapDriver.getExpectedOutputs();
        for(Pair pair : expectedOutputList)
        {
            System.out.println(pair.getFirst() + " --- " + pair.getSecond());
        }
    }

    @Test
    public void testReduce() throws IOException
    {
    }

    @Test
    public void testMapperAndReducer() throws IOException
    {
        Text text1 = new Text("004955246,CANTOMANY,M,19700505,47");
        Text text2 = new Text("005111197197404013018,Q,M,19740401,43");
        Text text3 = new Text("001222519819822210209447,W,F,19821020,35");
        mapReduceDriver.withInput(new LongWritable(),text3);
        mapReduceDriver.withInput(new LongWritable(),text2);
        mapReduceDriver.withInput(new LongWritable(),text1);
        mapReduceDriver.withOutput(new IntWritable(1),text3);
        mapReduceDriver.withOutput(new IntWritable(2),text2);
        mapReduceDriver.withOutput(new IntWritable(3),text1);
        //mapReduceDriver.runTest();
        // 输出
        List<Pair> expectedOutputList = mapReduceDriver.getExpectedOutputs();
        for(Pair pair : expectedOutputList)
        {
            System.out.println(pair.getFirst() + " ---- " + pair.getSecond());
        }
    }
}


text:
<?php $__env->startSection('head'); ?>

	<?php echo HTML::style('ckeditor/plugins/codesnippet/lib/highlight/styles/default.css'); ?>

<?php $__env->stopSection(); ?>

<?php $__env->startSection('main'); ?>

	<?php echo $__env->make('back.partials.entete', ['title' => trans('back/blog.dashboard'), 'icone' => 'pencil', 'fil' => link_to('blog', trans('back/blog.posts')) . ' / ' . trans('back/blog.creation')], array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>

		<?php echo $__env->yieldContent('form'); ?>

				<?php echo Form::checkbox('active'); ?>

				<?php echo e(trans('back/blog.published')); ?>

		<?php echo Form::control('text', 0, 'title', $errors, trans('back/blog.title')); ?>

		<div class="form-group <?php echo $errors->has('slug') ? 'has-error' : ''; ?>">
			<?php echo Form::label('slug', trans('back/blog.permalink'), ['class' => 'control-label']); ?>

			<?php echo url('/') . '/blog/' . Form::text('slug', null, ['id' => 'permalien']); ?>

			<?php echo $errors->first('slug'); ?>

		<?php echo Form::control('textarea', 0, 'summary', $errors, trans('back/blog.summary')); ?>

		<?php echo Form::control('textarea', 0, 'content', $errors, trans('back/blog.content')); ?>

		<?php echo Form::control('text', 0, 'tags', $errors, trans('back/blog.tags'), isset($tags)? implode(',', $tags) : ''); ?>

		<?php echo Form::submit(trans('front/form.send')); ?>

		<?php echo Form::close(); ?>

<?php $__env->stopSection(); ?>

<?php $__env->startSection('scripts'); ?>

	<?php echo HTML::script('ckeditor/ckeditor.js'); ?>

<?php $__env->stopSection(); ?>
<?php echo $__env->make('back.template', array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>


text:
from tkinter import *
from tkinter.ttk import *

import suapp.jandw
import suapp.simple_json as simple_json
from suapp.logdecorator import *

# Extra widgets
class MultiListbox(Frame):
    def __init__(self, master, lists):
        Frame.__init__(self, master)
        self.lists = []
        for l, w in lists:
            frame = Frame(self)
            frame.pack(side=LEFT, expand=YES, fill=BOTH)
            Label(frame, text=l, borderwidth=1, relief=RAISED).pack(fill=X)
            lb = Listbox(
                frame,
                width=w,
                borderwidth=0,
                selectborderwidth=0,
                relief=FLAT,
                exportselection=FALSE,
            )
            lb.pack(expand=YES, fill=BOTH)
            self.lists.append(lb)
            lb.bind("<B1-Motion>", lambda e, s=self: s._select(e.y))
            lb.bind("<Button-1>", lambda e, s=self: s._select(e.y))
            lb.bind("<Leave>", lambda e: "break")
            lb.bind("<B2-Motion>", lambda e, s=self: s._b2motion(e.x, e.y))
            lb.bind("<Button-2>", lambda e, s=self: s._button2(e.x, e.y))
        frame = Frame(self)
        frame.pack(side=LEFT, fill=Y)
        Label(frame, borderwidth=1, relief=RAISED).pack(fill=X)
        sb = Scrollbar(frame, orient=VERTICAL, command=self._scroll)
        sb.pack(expand=YES, fill=Y)
        self.lists[0]["yscrollcommand"] = sb.set

    def _select(self, y):
        row = self.lists[0].nearest(y)
        self.selection_clear(0, END)
        self.selection_set(row)
        return "break"

    def _button2(self, x, y):
        for l in self.lists:
            l.scan_mark(x, y)
        return "break"

    def _b2motion(self, x, y):
        for l in self.lists:
            l.scan_dragto(x, y)
        return "break"

    def _scroll(self, *args):
        for l in self.lists:
            apply(l.yview, args)

    def curselection(self):
        return self.lists[0].curselection()

    def delete(self, first, last=None):
        for l in self.lists:
            l.delete(first, last)

    def get(self, first, last=None):
        result = []
        for l in self.lists:
            result.append(l.get(first, last))
        if last:
            return apply(map, [None] + result)
        return result

    def index(self, index):
        self.lists[0].index(index)

    def insert(self, index, *elements):
        for e in elements:
            i = 0
            for l in self.lists:
                l.insert(index, e[i])
                i = i + 1

    def size(self):
        return self.lists[0].size()

    def see(self, index):
        for l in self.lists:
            l.see(index)

    def selection_anchor(self, index):
        for l in self.lists:
            l.selection_anchor(index)

    def selection_clear(self, first, last=None):
        for l in self.lists:
            l.selection_clear(first, last)

    def selection_includes(self, index):
        return self.lists[0].selection_includes(index)

    def selection_set(self, first, last=None):
        for l in self.lists:
            l.selection_set(first, last)

# END of extra widgets

class ToplevelWooster(Toplevel, suapp.jandw.Wooster):
    closed = False

    @loguse
    def preClose(self):
        pass

    # Overriding this disables the [X]
    @loguse
    def destroy(self):
        """
        When you click the [X] (or the parent window gets destroyed)
        """
        self.closed = True
        # Calling parent destroy() to actually destroy it.
        self.preClose()
        super().destroy()

    @loguse
    def close(self):
        """
        Close as Wooster
        """
        self.destroy()

ipsum = """Lorem ipsum dolor sit amet, consectetur adipiscing elit. \
Suspendisse pretium sapien sit amet magna viverra id faucibus nibh condimentum. \
Fusce dui magna, venenatis vel elementum eu, suscipit at quam. Nullam sed felis lorem, vel pretium leo. \
Cras at neque orci. \
Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. \
Pellentesque ullamcorper quam eu ligula mattis tempor. \
Aliquam erat volutpat. Vivamus feugiat aliquam purus, \
euismod blandit lacus scelerisque vel. \
Phasellus sodales dignissim eros nec accumsan. \
Aenean est lectus, placerat sed ornare ut, congue nec nulla. \
Phasellus at sapien purus. \
Maecenas et sapien at ipsum fringilla tempus.

Donec non quam mauris. \
Vivamus bibendum ante id velit rhoncus molestie. \
Nullam bibendum suscipit elit sed aliquam. \
Maecenas felis magna, laoreet ut volutpat eget, varius at lorem. \
Quisque nisl dolor, aliquet et vestibulum nec, ullamcorper quis libero. \
Aliquam erat volutpat. \
Aenean mauris augue, varius sit amet iaculis quis, rhoncus at eros. \
Phasellus luctus congue cursus. \
Praesent lobortis vestibulum cursus. \
Nulla euismod nisi ac diam semper molestie. \
Curabitur quis leo at velit ultrices consectetur in in tellus. \
Nunc auctor erat ac justo porttitor consectetur. \
Cras vestibulum elit nec nulla consectetur euismod. \
Curabitur sodales vehicula lacus quis iaculis. \
Nulla laoreet eros eget ipsum commodo aliquet.

Cras gravida egestas nunc a hendrerit. \
Quisque consequat arcu ac dolor bibendum a porttitor augue malesuada. \
Etiam suscipit augue ac eros lobortis auctor. \
Vivamus urna sem, ultrices non ultrices in, sodales id justo. \
Aenean gravida bibendum risus, a pharetra arcu rhoncus quis. \
Maecenas interdum fringilla dapibus. \
Sed non diam massa, a sodales eros. \
Cras interdum nibh leo. \
Praesent non urna turpis. \
Pellentesque posuere massa vel ligula porta sed egestas arcu lacinia. \
Curabitur rutrum ultrices vestibulum. \
Mauris posuere, arcu id tempor volutpat, lacus nisl euismod felis, non facilisis purus sem ac sem. \
Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. \
Mauris posuere ornare elit non congue. \
Praesent pretium, nisl eget pulvinar pulvinar, nibh purus sollicitudin tellus, eget malesuada lacus nulla vel neque.

In non elit nisi. \
Phasellus porta vestibulum erat non condimentum. \
Sed sed augue neque, sed venenatis eros. \
In et nunc neque. \
Mauris mi velit, dignissim id vehicula at, semper vitae est. \
Ut porta lacus eget ipsum faucibus vel luctus metus scelerisque. \
Duis ipsum nulla, rutrum sit amet ultricies et, sodales vitae sem. \
Donec suscipit aliquam diam, id mollis nibh gravida vel. \
Quisque in blandit lectus. \
Fusce interdum nulla turpis, sit amet venenatis metus. \
Praesent ac tristique tortor.

Suspendisse ut magna sed nulla cursus rutrum. \
Suspendisse in lacus dui, non bibendum tellus. Nulla facilisi. \
Morbi urna justo, volutpat eu mattis id, facilisis sed sapien. \
Vestibulum vitae sapien orci. \
Proin aliquet euismod neque, vel sodales nulla hendrerit vitae. \
Sed auctor euismod adipiscing. \
Curabitur feugiat dui quis lorem gravida a mattis eros vehicula. \
Aenean eget ullamcorper nunc. \
Mauris sagittis eros aliquam dolor varius sit amet eleifend dolor placerat. \
Vestibulum nec dui metus. \
Nullam nec ante in lectus faucibus condimentum. \
Donec ac enim purus, et bibendum erat. \
Aliquam vestibulum tempus consectetur."""

class TableWindow(ToplevelWooster):

    name = "TABLE"

    @loguse
    def __init__(self, table, master=None):
        Toplevel.__init__(self, master, class_="Table")
        self.data = table
        self.title("Table %s" % ("TODO"))
        # Don't make it smaller then this
        self.minsize(200, 100)
        # So it doesn't get in the task bar as a separate window but as a child of the master/parent
        self.transient(master)
        self.grid()

    @loguse
    def goTo(self, key):
        self.jeeves.drone(
            self, "RECORD", self.jeeves.MODE_OPEN, {"key": key, "table": self.data}
        )

    @loguse
    def goToFunction(self, key):
        """
        Neede to create this intermediat function because 'key' isn't reused in the for loop and hence all buttons go to the last 'key'
        """
        return lambda: self.goTo(key)

    @loguse
    def createWidgets(self):
        row = 0
        # if type(self.data) == type({}):
        self.listbox = MultiListbox(
            self, [["ID", 20], ["Represantation", 50]]
        )  # Listbox(self)
        try:
            for key in self.data:
                # TODO: build in a maximum so we take maximum advantage of iterators
                label = Button(self, text="%s" % (key), command=self.goToFunction(key))
                label.grid(column=0, row=row, sticky=E + W)
                text = Entry(self)
                text.insert(0, "%s" % (self.data[key]))
                text.config(state=DISABLED)
                text.grid(column=1, row=row, sticky=E + W)
                self.listbox.insert(END, ["%s" % (key), "%s" % (self.data[key])])
                row += 1
        except Exception as err:
            logging.getLogger(self.__module__).error(
                ": TableWindow[%r].createWidgets : Not iterable? %s" % (self, err)
            )
            raise
        self.listbox.grid(column=0, columnspan=2, row=row, sticky=E + W)
        row += 1
        self.buttonS = Button(self, text="Close", command=self.close)
        self.buttonS.grid(column=0, row=row, sticky=E + W)
        self.update()

    @loguse
    def inflow(self, jeeves, drone):
        self.jeeves = jeeves
        # TODO: Need to apply the filter in drone.dataobject on self.data
        self.createWidgets()

class Table(suapp.jandw.Wooster):
    @loguse
    def inflow(self, jeeves, drone):
        # TODO: should use the data API for this
        population = {
            "(131GAOC)298": {
                "ID": "(131GAOC)298",
                "band": "BGC/BR23/2011/298",
                "father": "(AC62)131",
                "mother": "GAOC",
                "line": "GA25/(GAOC*)",
            },
            "(AC62)131": {
                "ID": "(AC62)131",
                "band": "BGC/BR23/2010/131",
                "father": "AC",
                "mother": "(GOVAYF)62",
                "line": "GA25/AC*",
            },
            "AC": {"ID": "AC", "line": "GA25/AC"},
            "(GOVAYF)62": {
                "ID": "(GOVAYF)62",
                "band": "BGC/BR23/2008/62",
                "father": "GOc",
                "mother": "VAYF",
                "line": "FS2/GO*HH731/VAYF",
            },
            "GOc": {"ID": "GOc", "line": "FS2/GO"},
            "VAYF": {"ID": "VAYF", "line": "HH731/VAYF"},
            "GAOC": {"ID": "GAOC", "line": "GA25/GOAC"},
        }
        table = population
        if "table" in drone.dataobject:
            if "tables" in drone.dataobject:
                if drone.dataobject["table"] in drone.dataobject["tables"]:
                    # print("Table: %s: %s" % (drone.dataobject['table'], drone.dataobject['tables'][drone.dataobject['table']]))
                    table = drone.dataobject["tables"][drone.dataobject["table"]]
        if isinstance(drone.fromvertex, Frame):
            logging.getLogger(self.__module__).debug(
                ": TableFactory[%r].inflow : Using parent" % (self)
            )
            # TODO: if it has been closed/destroyed then give the parent of fromvertex instead?
            window = TableWindow(table, drone.fromvertex)
        else:
            logging.getLogger(self.__module__).debug(
                ": TableFactory[%r].inflow : Not using parent" % (self)
            )
            window = TableWindow(table)
        window.inflow(jeeves, drone)
        window.lift()
        window.focus_set()

class RecordWindow(ToplevelWooster):
    @loguse
    def __init__(self, master=None):
        Toplevel.__init__(self, master, class_="About")
        self.title("Record")
        # Don't make it smaller than this.
        self.minsize(50, 50)
        # So it doesn't get in the task bar as a separate window but as a child of the master/parent.
        self.transient(master)
        self.grid()

    @loguse
    def __edit(self, key):
        print("Key: %s" % (key))  # DELME
        # If the value is composite (map), open a RecordWindow modal
        # If the value is singular, open a EditWindow modal
        return

    @loguse
    def __editFunction(self, key):
        return lambda: self.__edit(key)

    @loguse
    def __style(self):
        s = Style()
        styles = s.theme_names()
        i = styles.index(s.theme_use())
        x = styles[0]
        try:
            x = styles[i + 1]
        except:
            pass
        s.theme_use(x)
        return "SWITCHING TO STYLE %s" % (x)

    @loguse
    def createWidgets(self):
        row = 0
        try:
            for key in self.table.configuration["fields"]:
                if "auto_increment" in self.table.configuration["fields"][key]:
                    if self.table.configuration["fields"][key]["auto_increment"]:
                        continue
                label = Label(self, text="%s: " % (key))
                label.grid(column=0, row=row, sticky=E)
                text = Entry(self)  # , textvariable=self.data[key])
                if key in self.data:
                    if "toVisual" in self.table.configuration["fields"][key]:
                        text.insert(
                            0,
                            "%s"
                            % self.table.configuration["fields"][key]["toVisual"](
                                self.data[key]
                            ),
                        )
                    else:
                        text.insert(0, "%s" % (self.data[key]))
                text.config(state=DISABLED)
                text.grid(column=1, row=row, sticky=E + W)
                button = Button(
                    self, text="\u2026", width=2, command=self.__editFunction(key)
                )  # Black pointing left index finger: \u261a ; Triangle: \u2023 ; Tripple bullet: \u2026
                button.grid(column=2, row=row, sticky=E)
                self.columnconfigure(2, weight=0)
                row += 1
        except Exception as err:
            logging.getLogger(self.__module__).error(
                ": RecordWindow[%r].createWidgets : Not iterable? %s" % (self, err)
            )
            raise
        self.buttonS = Button(self, text="Save", command=self.close)  # u25b6
        self.buttonS.grid(column=0, row=row)
        self.buttonC = Button(self, text="Cancel", command=self.__style)  # u25b6
        self.buttonC.grid(column=1, row=row, sticky=W)
        self.update()

    @loguse
    def inflow(self, jeeves, drone):
        self.jeeves = jeeves
        self.table = drone.dataobject.get("table", None)
        self.data = drone.dataobject.get("object", drone.dataobject.get("key", None))
        self.createWidgets()

class Record(suapp.jandw.Wooster):
    """
    Note: it will open a new window. If you want to avoid doubles open, use subclass UniqueRecordFactory
    """

    @loguse
    def inflow(self, jeeves, drone):
        if isinstance(drone.fromvertex, Frame):
            logging.getLogger(self.__module__).debug(
                ": RecordFactory[%r].inflow : Using parent" % (self)
            )
            # TODO: if it has been closed/destroyed then give the parent of fromvertex instead?
            RecordWindow(drone.fromvertex).inflow(jeeves, drone)
        else:
            logging.getLogger(self.__module__).debug(
                ": RecordFactory[%r].inflow : Not using parent" % (self)
            )
            RecordWindow().inflow(jeeves, drone)

class UniqueRecord(Record):

    windowreferences = {}

    @loguse
    def inflow(self, jeeves, drone):
        # TODO replace the id and object!
        table = drone.dataobject["table"]
        if "key" in drone.dataobject:
            key = drone.dataobject["key"]
        elif "object" in drone.dataobject:
            object = drone.dataobject["object"]
            key = table.getKey(object)
            # We looked it up so we just as wel might put it in.
            drone.dataobject["key"] = key
        logging.getLogger(self.__module__).debug(
            ": UniqueRecordFactory[%r].inflow : windowreferences: %s in %s"
            % (self, key, self.windowreferences)
        )
        if key in self.windowreferences:
            logging.getLogger(self.__module__).debug(
                ": UniqueRecordFactory[%r].inflow : Reusing for %s" % (self, key)
            )
            if self.windowreferences[key].closed:
                logging.getLogger(self.__module__).debug(
                    ": UniqueRecordFactory[%r].inflow : Oops that one is already closed so not reusing it."
                    % (self)
                )
                del self.windowreferences[key]
        if key not in self.windowreferences:
            if isinstance(drone.fromvertex, Frame):
                logging.getLogger(self.__module__).debug(
                    ": UniqueRecordFactory[%r].inflow : Using parent" % (self)
                )
                # TODO: if it has been closed/destroyed then give the parent of fromvertex instead?
                self.windowreferences[key] = RecordWindow(drone.fromvertex)
            else:
                logging.getLogger(self.__module__).debug(
                    ": UniqueRecordFactory[%r].inflow : Not using parent" % (self)
                )
                self.windowreferences[key] = RecordWindow()
            self.windowreferences[key].inflow(jeeves, drone)
        self.windowreferences[key].lift()
        self.windowreferences[key].focus_set()

class AboutWindow(ToplevelWooster):
    @loguse
    def __init__(self, master=None):
        Toplevel.__init__(self, master, class_="About")
        self.title("About")
        # Don't make it smaller then this
        self.minsize(300, 200)
        # So it doesn't get in the task bar as a separate window but as a child of the master/parent
        self.transient(master)
        self.grid()
        self.createWidgets()

    @loguse
    def createWidgets(self):
        self.text = Text(self, wrap=WORD)
        self.text.config(state=DISABLED)
        self.text.grid()
        self.button = Button(self, text="Close", command=self.close)
        self.button.grid()
        self.update()

    @loguse
    def inflow(self, jeeves, drone):
        self.jeeves = jeeves
        # Looking for txt file
        text = []
        file_name = self.jeeves.app.configuration["self"].rsplit(".", 1)[0]
        file_name += ".txt"
        try:
            with open(file_name) as fh:
                for line in fh:
                    text.append(line)
        except OSError:
            logging.getLogger(self.__module__).warning(
                "Could not open about file %s.", file_name, exc_info=sys.exc_info()
            )
        except IOError:
            logging.getLogger(self.__module__).warning(
                "Could not open about file %s.", file_name, exc_info=sys.exc_info()
            )
        if not text:
            text = ["ERROR: Could not open file %s." % (file_name)]
        self.text.config(state=NORMAL)
        self.text.delete("1.0", END)
        self.text.insert(END, "\n".join(text))
        self.text.config(state=DISABLED)
        self.update()

class About(suapp.jandw.Wooster):
    """
    Perhaps I should replace the FACTORY with just a FUNCTION (though it doesn't make a lot of difference in python)
    """

    @loguse
    def __init__(self):
        self.window = None

    @loguse
    def inflow(self, jeeves, drone):
        if self.window:
            if self.window.closed:
                self.window = None
        if not self.window:
            if isinstance(drone.fromvertex, Frame):
                logging.getLogger(self.__module__).debug(
                    ": About[%r].inflow : Using parent" % (self)
                )
                # TODO: if it has been closed/destroyed then give the parent of fromvertex instead?
                self.window = AboutWindow(drone.fromvertex)
            else:
                logging.getLogger(self.__module__).debug(
                    ": About[%r].inflow : Not using parent" % (self)
                )
                self.window = AboutFrame()
        self.window.inflow(jeeves, drone)
        self.window.focus_set()

class Application(Frame, suapp.jandw.Wooster):

    name = "APP"
    dataobject = {"name": "SuApp"}
    testdata = {"ID": "(150112)164", "ring": "BGC/BR23/10/164"}
    tables = {}

    @loguse
    def __init__(self, master=None):
        Frame.__init__(self, master, class_="Application")
        # Default title, could be overriden in inflow
        self._root().title("SuApp")
        self._root().minsize(400, 300)
        self.grid()
        # Moved to inflow self.createWidgets()

    def openTableWindow(self, tablename):
        """
        Neede to create this intermediat function because 'key' isn't reused in the for loop and hence all buttons go to the last 'key'
        """
        return lambda: self.__testTable(tablename)

    @loguse
    def createWidgets(self):
        top = self.winfo_toplevel()
        self.menuBar = Menu(top, tearoff=0)
        top["menu"] = self.menuBar

        self.menuFile = Menu(self.menuBar, tearoff=0)
        self.menuBar.add_cascade(label="File", menu=self.menuFile)
        self.menuFile.add_command(label="Quit", command=self.close)

        self.menuRecord = Menu(self.menuBar, tearoff=0)
        self.menuBar.add_cascade(label="Record", menu=self.menuRecord)
        self.menuRecord.add_command(
            label="Test record (\u20ac)", command=self.__testRecord
        )

        self.menuTable = Menu(self.menuBar, tearoff=0)
        self.menuBar.add_cascade(label="Table", menu=self.menuTable)
        for table in self.tables:
            self.menuTable.add_command(
                label="%s" % (table), command=self.openTableWindow(table)
            )

        self.menuHelp = Menu(self.menuBar, tearoff=0)
        self.menuBar.add_cascade(label="Help", menu=self.menuHelp)
        self.menuHelp.add_command(label="About", command=self.__about)
        self.menuHelp.add_command(label="Configuration", command=self.__configuration)

    @loguse
    def __testTable(self, tablename):
        self.jeeves.drone(
            self,
            "TABLE",
            self.jeeves.MODE_OPEN,
            {"tables": self.tables, "table": tablename},
        )

    @loguse
    def __testRecord(self):
        self.jeeves.drone(
            self,
            "RECORD",
            self.jeeves.MODE_OPEN,
            {"table": self.tables["organism"], "object": self.testdata},
        )

    @loguse
    def __about(self):
        self.jeeves.drone(self, "ABOUT", self.jeeves.MODE_MODAL, None)

    @loguse
    def __configuration(self):
        self.jeeves.drone(self, "CONFIGURATION", self.jeeves.MODE_MODAL, None)

    @loguse
    def inflow(self, jeeves, drone):
        if drone.dataobject:
            self.dataobject = drone.dataobject
        if "name" not in self.dataobject:
            self.dataobject["name"] = "SuApp"
        self._root().title(self.dataobject["name"])
        if "tables" in self.dataobject:
            logging.getLogger(self.__module__).debug(
                ": Application[%r].inflow() : Setting tables." % (self)
            )
            self.tables = self.dataobject["tables"]
        self.jeeves = jeeves
        self.createWidgets()  # Perhaps this needs to be in mainloop() so we can do a refresh?
        self.mainloop()

    @loguse
    def lock(self):
        pass

    @loguse
    def unlock(self):
        pass

    @loguse
    def destroy(self):
        """
        When you click the [X]
        """
        self.preClose()
        super().destroy()

    @loguse
    def preClose(self):
        pass

    @loguse
    def close(self):
        """
        Close as Wooster
        """
        self.destroy()
        self.quit()

class ConfigurationWindow(ToplevelWooster):
    @loguse
    def __init__(self, master=None):
        Toplevel.__init__(self, master, class_="Configuration")
        self.title("Configuration")
        # Don't make it smaller then this
        self.minsize(300, 200)
        # So it doesn't get in the task bar as a separate window but as a child of the master/parent
        self.transient(master)
        self.grid()
        self.createWidgets()

    @loguse
    def createWidgets(self):
        self.text = Text(self, wrap=WORD)
        self.text.config(state=DISABLED)
        self.text.grid()
        self.button = Button(self, text="Close", command=self.close)
        self.button.grid()
        self.update()

    @loguse
    def inflow(self, jeeves, drone):
        self.jeeves = jeeves
        self.text.config(state=NORMAL)
        self.text.delete(1.0, END)
        print(type(self.jeeves.app.configuration))
        title = "Configuration:"
        self.text.insert(
            END,
            "%s\n\n%s"
            % (
                title,
                simple_json.dumps(dict(self.jeeves.app.configuration), indent="    "),
            ),
        )
        self.text.tag_add("title", "1.0", "1.%s" % len(title))
        self.text.tag_config("title", background="black", foreground="yellow")
        self.text.config(state=DISABLED)
        self.update()

class Configuration(suapp.jandw.Wooster):

    name = "CONFIGURATION"

    """
    Perhaps I should replace the FACTORY with just a FUNCTION (though it doesn't make a lot of difference in python)
    """

    @loguse
    def __init__(self):
        self.window = None

    @loguse
    def inflow(self, jeeves, drone):
        if self.window:
            if self.window.closed:
                self.window = None
        if not self.window:
            if isinstance(drone.fromvertex, Frame):
                logging.getLogger(self.__module__).debug(
                    ": Configuration[%r].inflow : Using parent" % (self)
                )
                # TODO: if it has been closed/destroyed then give the parent of fromvertex instead?
                self.window = ConfigurationWindow(drone.fromvertex)
            else:
                logging.getLogger(self.__module__).debug(
                    ": Configuration[%r].inflow : Not using parent" % (self)
                )
                self.window = AboutFrame()
        self.window.inflow(jeeves, drone)
        self.window.focus_set()

class View(suapp.jandw.Wooster):
    """
    Generic view page for showing.
    """

    @loguse("@")  # Not logging the return value.
    def inflow(self, jeeves, drone):
        """
        Entry point for the view.
        """
        self.jeeves = jeeves

        # Getting the flow (usually uppercase) and ref (lowercase) names.
        flow_name = drone.name
        ref_name = flow_name.lower()
        name = ref_name.capitalize()

        # Getting the view definition.
        definition = jeeves.views.get(flow_name, {})

        # Getting the session, params and preparing the scope.
        session = drone.dataobject.get("session", {})
        # Setting default dabase paging parameters for the query.
        query_params = {"pagenum": 1, "pagesize": 5}
        # Getting the http request params.
        for param in drone.dataobject["params"]:
            query_params[param] = drone.dataobject["params"][param][0]
        scope = {}  # NOTUSED
        # scope.update(jeeves.ormscope) # jeeves.ormscope is always empty.

        # JS parameters
        js_params = {}
        if drone.dataobject:
            js_params[
                "query"
            ] = "query/%(query)s?pagenum=%(pagenum)s&pagesize=%(pagesize)s"
        result = []
        js_params["service_url"] = jeeves.app.configuration["httpd"]["service_url"]

        """"
        # Title
        title = definition.get('name', name)
        if logging.getLogger(self.__module__).isEnabledFor(logging.DEBUG):
            html.append('<!-- DEBUG title = %s -->' % (title))

        def_tabs = definition.get('tabs', {0: {'title': ''}})
        if logging.getLogger(self.__module__).isEnabledFor(logging.DEBUG):
            html.append('<!-- DEBUG def_tabs = %s -->' % (def_tabs))

        tabs = collections.OrderedDict()
        tab_count = 0
        if 'query' in def_tabs:
            if logging.getLogger(self.__module__).isEnabledFor(logging.DEBUG):
                html.append('<!-- DEBUG query = %s -->' % (def_tabs['query']))
            tab_title = def_tabs.get('title', name)
            tab_objects = self.jeeves.do_query(def_tabs['query'], params=query_params)
            parameters = self.jeeves.pre_query(def_tabs['query'], params=query_params)[1]
            parameters['query'] = def_tabs['query']
            js_query_params = with_expanded_values(js_params, params=parameters)
            js_query_params['view'] = "testview" # TODO
            html.append(View.raw_js % (js_query_params))
            # TESTVIEW
            html.append('<table id="testview">')
            html.append('</table>')
            if logging.getLogger(self.__module__).isEnabledFor(logging.DEBUG):
                html.append('<!-- DEBUG tab_objects = %s -->' % (tab_objects))
            for tab in tab_objects:
                if tab_title[0] == ".":
                    tabs[tab_count] = (getattr(tab, tab_title[1:]), tab)
                else:
                    tabs[tab_count] = (tab_title, tab)
                tab_count += 1
        else:
            # Loop over all integer keys and get out the titles.
            for i in def_tabs:
                # TODO: is this second element in the tuple correct?
                tabs[i] = (def_tabs[i]['title'], def_tabs[i])
                if logging.getLogger(self.__module__).isEnabledFor(logging.DEBUG):
                    html.append('<!-- DEBUG tabs: %s -->' % (tabs))

        # Tab headers
        html.append('<ul class="nav nav-tabs">')
        for i in sorted(tabs): # CHECKME: DO WE NEED SORTED HERE?
            if i is 0:
                html.append('\t<li class="active"><a data-toggle="tab" href="#tab%s">%s</a></li>' % (i, tabs[i][0]))
            else:
                html.append('\t<li><a data-toggle="tab" href="#tab%s">%s</a></li>' % (i, tabs[i][0]))
        html.append('</ul>')

        # Tabs
        html.append('<div class="tab-content">')
        for i in sorted(tabs):
            if logging.getLogger(self.__module__).isEnabledFor(logging.DEBUG):
                html.append('<!-- DEBUG tab: %s = %s -->' % (i, tabs[i]))
            if i is 0:
                html.append('\t<div id="tab%s" class="tab-pane fade in active">' % (i))
            else:
                html.append('\t<div id="tab%s" class="tab-pane fade">' % (i))
            # Sections
            sections = tabs[i][1].get('sections', definition.get('sections', {0: {'title': ''}}))
            if logging.getLogger(self.__module__).isEnabledFor(logging.DEBUG):
                html.append('<!-- DEBUG sections: %s -->' % (sections))
            for s in sorted(sections.keys(), key=str):
                if logging.getLogger(self.__module__).isEnabledFor(logging.DEBUG):
                    html.append('<!-- DEBUG section: %s -->' % (s))
                if not str(s).isdigit():
                    continue
                section_title = sections[s].get('title', '')
                html.append('\t\t<div class="panel panel-default">')  # panel-primary <> panel-default ?
                if section_title != tabs[i][0]:
                    html.append('\t\t\t<div class="panel-heading">%s</div>' % (section_title))
                html.append('\t\t\t<div class="panel-body" id="section%s_%s">' % (i, s))
                # Lines
                lines = sections[s].get('lines', tabs.get('lines', definition.get('sections', {0: {'title': ''}})))
                # DEBUGGING
                if logging.getLogger(self.__module__).isEnabledFor(logging.DEBUG):
                    html.append('<!-- DEBUG lines = %s -->' % (lines))
                line_objects = []
                if 'query' in lines:
                    line_objects = self.jeeves.do_query(lines['query'], params=query_params)
                    query_template, parameters = self.jeeves.pre_query(lines['query'], params=query_params)
                    parameters['query'] = lines['query']
                    js_query_params = with_expanded_values(js_params, params=parameters)
                    js_query_params['view'] = "section%s_%s" % (i, s)
                    if 'elements' in lines:
                        for e in sorted(lines['elements']):
                            value = lines['elements'][e].get('value', '#')
                            element_type = lines['elements'][e].get('type', 'label').lower()
                            outmessage = lines['elements'][e].get('outmessage', '')
                            if value[0] == ".":
                                value = '\' + data["objects"][elementid]["' + value[1:] + '"] + \''
                            html_element = " "
                            if element_type == "button":
                                # Button
                                html_element = View._button_as_button(
                                    value=value,
                                    outmessage=outmessage
                                )
                            else:
                                # Label
                                pass
                            js_query_params['html'] = html_element
                    html.append(View.raw_js % (js_query_params))
                else:
                    for line_object in line_objects:
                        if logging.getLogger(self.__module__).isEnabledFor(logging.DEBUG):
                            html.append('<!-- DEBUG line_object = %s (%s in %s) -->' % (line_object, type(line_object), line_object.__module__))
                        line_elements = []
                        # Line elements
                        if 'elements' in lines:
                            for e in sorted(lines['elements']):
                                if logging.getLogger(self.__module__).isEnabledFor(logging.DEBUG):
                                    html.append('<!-- DEBUG element = %s -->' % (e))
                                value = lines['elements'][e].get('value', '#')
                                element_type = lines['elements'][e].get('type', 'label').lower()
                                outmessage = lines['elements'][e].get('outmessage', '')
                                if value[0] == ".":
                                    value = getattr(line_object, value[1:])
                                if element_type == "button":
                                    html.append("\t\t\t\t" +
                                        View.button(
                                            value=value,
                                            outmessage=outmessage,
                                            module=line_object.__module__,
                                            table=line_object.__class__.__name__.split("_")[-1],
                                            key=line_object._pk_
                                        )
                                    )
                                else:
                                    html.append("\t\t\t\t" + View.label(value=value))
                    for l in sorted(lines.keys(), key=str):
                        if str(l).isdigit():
                            # Line elements
                            if 'elements' in lines[l]:
                                for e in sorted(lines[l]['elements']):
                                    if logging.getLogger(self.__module__).isEnabledFor(logging.DEBUG):
                                        html.append('<!-- DEBUG element = %s -->' % (e))
                                    value = lines[l]['elements'][e].get('value', '#')
                                    l_type = lines[l]['elements'][e].get('type', 'button').lower()
                                    outmessage = lines[l]['elements'][e].get('outmessage', '')
                                    if value[0] == ".":
                                        value = getattr(line_object, value[1:])
                                    if element_type == "button":
                                        html.append("\t\t\t" +
                                            View.button(
                                                value=value,
                                                outmessage=outmessage,
                                                module=line_object.__module__,
                                                table=line_object.__class__.__name__.split("_")[-1],
                                                key=line_object._pk_
                                            )
                                        )
                                    else:
                                        html.append("\t\t\t" + View.label(value=value))
                html.append('\t\t\t</div>')
                html.append('\t\t</div>')

            html.append('\t</div>')
        html.append('</div>')

        return (title, "\n".join(html))
        """

if __name__ == "__main__":
    logging.getLogger(__name__).setLevel(logging.DEBUG)  # DEBUG/INFO
    flow = suapp.jandw.Jeeves()
    flow.flow = {
        "": {
            "START": suapp.jandw.Drone("START", Application()),
            "RECORD": suapp.jandw.Drone("RECORD", UniqueRecord()),
        },
        "APP": {
            "ABOUT": suapp.jandw.Drone("ABOUT", About()),
            "TABLE": suapp.jandw.Drone("TABLE", Table()),
        },
    }
    flow.start()