text:
import rospy
import tf

from visualization_msgs.msg import Marker
from geometry_msgs.msg import Point
from std_srvs.srv import *

# Give ourselves the ability to run a dynamic reconfigure server.
from dynamic_reconfigure.server import Server as DynamicReconfigureServer
from tf_trace_publisher.cfg import tf_Trace_PublisherConfig as ConfigType

class TfTracePublisher():
	def __init__(self):

		# initalize
		self.trace = Marker()
		self.trace.id = rospy.get_param('~id', 1)
		self.trace.type= Marker.LINE_STRIP
		self.trace.action = Marker.MODIFY

		self.server = DynamicReconfigureServer(ConfigType, self.reconfigure)
		self.srv = rospy.Service('~reset', Empty, self.reset_trace)

		tf_listener = tf.TransformListener()
		pub_markerLine = rospy.Publisher('visualization_marker', Marker, queue_size=10)

		while not rospy.is_shutdown():
			try:
				(trans,rot) = tf_listener.lookupTransform(self.trace.header.frame_id, self.trace.ns, rospy.Time(0))

				if True:# len(trace.points) == 0 or not (trace.points[len(trace.points)-1].x != trans[0] and trace.points[len(trace.points)-1].y != trans[1] and trace.points[len(trace.points)-1].z != trans[2]):
					p1 = Point()
					p1.x = trans[0]
					p1.y = trans[1]
					p1.z = trans[2]
					while len(self.trace.points) > self.maxLen:
						self.trace.points.pop(0)
					self.trace.points.append(p1)

				if len(self.trace.points) > 0:
					pub_markerLine.publish(self.trace)

			except (tf.LookupException, tf.ConnectivityException, tf.ExtrapolationException):
				rospy.logwarn("Transformation Lookup failed")
				rospy.sleep(rospy.Duration(1))
				continue
			self.rate.sleep()

	# Create a callback function for the dynamic reconfigure server.
	def reconfigure(self, config, level):
		# Fill in local variables with values received from dynamic reconfigure clients (typically the GUI).

		self.trace.header.frame_id = config["tf_parent"]
		self.trace.ns = config["tf_child"]

		self.trace.scale.x = config["scale"]
		self.trace.scale.y = config["scale"]
		self.trace.scale.z = config["scale"]

		self.trace.color.r = config["color_R"]
		self.trace.color.g = config["color_G"]
		self.trace.color.b = config["color_B"]
		self.trace.color.a = config["color_A"]

		self.maxLen = config["length"]
		self.rateTime = config["rate"]
		self.rate = rospy.Rate(self.rateTime)

		config["tf_parent"] = self.trace.header.frame_id
		config["tf_child"] = self.trace.ns
		config["scale"] = self.trace.scale.x
		config["color_R"] = self.trace.color.r
		config["color_G"] = self.trace.color.g
		config["color_B"] = self.trace.color.b
		config["color_A"] = self.trace.color.a

		config["length"] = self.maxLen
		config["rate"] = self.rateTime

		rospy.loginfo("Configuration changed!")
		return config

	def reset_trace(self, req):
		del self.trace.points[:]
		return EmptyResponse()

if __name__ == '__main__':

	rospy.init_node('tf_Trace_Publisher', anonymous=True)
	try:
		node = TfTracePublisher()
	except rospy.ROSInterruptException: pass


text:
package com.ctrip.framework.apollo.adminservice.aop;

import com.ctrip.framework.apollo.biz.config.BizConfig;
import com.ctrip.framework.apollo.biz.entity.Item;
import com.ctrip.framework.apollo.biz.entity.Namespace;
import com.ctrip.framework.apollo.biz.entity.NamespaceLock;
import com.ctrip.framework.apollo.biz.service.ItemService;
import com.ctrip.framework.apollo.biz.service.NamespaceLockService;
import com.ctrip.framework.apollo.biz.service.NamespaceService;
import com.ctrip.framework.apollo.common.dto.ItemChangeSets;
import com.ctrip.framework.apollo.common.dto.ItemDTO;
import com.ctrip.framework.apollo.common.exception.BadRequestException;
import com.ctrip.framework.apollo.common.exception.ServiceException;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Component;

/**
 * 一个namespace在一次发布中只能允许一个人修改配置
 * 通过数据库lock表来实现
 */
@Aspect
@Component
public class NamespaceAcquireLockAspect {
  private static final Logger logger = LoggerFactory.getLogger(NamespaceAcquireLockAspect.class);

  private final NamespaceLockService namespaceLockService;
  private final NamespaceService namespaceService;
  private final ItemService itemService;
  private final BizConfig bizConfig;

  public NamespaceAcquireLockAspect(
      final NamespaceLockService namespaceLockService,
      final NamespaceService namespaceService,
      final ItemService itemService,
      final BizConfig bizConfig) {
    this.namespaceLockService = namespaceLockService;
    this.namespaceService = namespaceService;
    this.itemService = itemService;
    this.bizConfig = bizConfig;
  }

  //create item
  @Before("@annotation(PreAcquireNamespaceLock) && args(appId, clusterName, namespaceName, item, ..)")
  public void requireLockAdvice(String appId, String clusterName, String namespaceName,
                                ItemDTO item) {
    acquireLock(appId, clusterName, namespaceName, item.getDataChangeLastModifiedBy());
  }

  //update item
  @Before("@annotation(PreAcquireNamespaceLock) && args(appId, clusterName, namespaceName, itemId, item, ..)")
  public void requireLockAdvice(String appId, String clusterName, String namespaceName, long itemId,
                                ItemDTO item) {
    acquireLock(appId, clusterName, namespaceName, item.getDataChangeLastModifiedBy());
  }

  //update by change set
  @Before("@annotation(PreAcquireNamespaceLock) && args(appId, clusterName, namespaceName, changeSet, ..)")
  public void requireLockAdvice(String appId, String clusterName, String namespaceName,
                                ItemChangeSets changeSet) {
    acquireLock(appId, clusterName, namespaceName, changeSet.getDataChangeLastModifiedBy());
  }

  //delete item
  @Before("@annotation(PreAcquireNamespaceLock) && args(itemId, operator, ..)")
  public void requireLockAdvice(long itemId, String operator) {
    Item item = itemService.findOne(itemId);
    if (item == null){
      throw new BadRequestException("item not exist.");
    }
    acquireLock(item.getNamespaceId(), operator);
  }

  void acquireLock(String appId, String clusterName, String namespaceName,
                           String currentUser) {
    if (bizConfig.isNamespaceLockSwitchOff()) {
      return;
    }

    Namespace namespace = namespaceService.findOne(appId, clusterName, namespaceName);

    acquireLock(namespace, currentUser);
  }

  void acquireLock(long namespaceId, String currentUser) {
    if (bizConfig.isNamespaceLockSwitchOff()) {
      return;
    }

    Namespace namespace = namespaceService.findOne(namespaceId);

    acquireLock(namespace, currentUser);

  }

  private void acquireLock(Namespace namespace, String currentUser) {
    if (namespace == null) {
      throw new BadRequestException("namespace not exist.");
    }

    long namespaceId = namespace.getId();

    NamespaceLock namespaceLock = namespaceLockService.findLock(namespaceId);
    if (namespaceLock == null) {
      try {
        tryLock(namespaceId, currentUser);
        //lock success
      } catch (DataIntegrityViolationException e) {
        //lock fail
        namespaceLock = namespaceLockService.findLock(namespaceId);
        checkLock(namespace, namespaceLock, currentUser);
      } catch (Exception e) {
        logger.error("try lock error", e);
        throw e;
      }
    } else {
      //check lock owner is current user
      checkLock(namespace, namespaceLock, currentUser);
    }
  }

  private void tryLock(long namespaceId, String user) {
    NamespaceLock lock = new NamespaceLock();
    lock.setNamespaceId(namespaceId);
    lock.setDataChangeCreatedBy(user);
    lock.setDataChangeLastModifiedBy(user);
    namespaceLockService.tryLock(lock);
  }

  private void checkLock(Namespace namespace, NamespaceLock namespaceLock,
                         String currentUser) {
    if (namespaceLock == null) {
      throw new ServiceException(
          String.format("Check lock for %s failed, please retry.", namespace.getNamespaceName()));
    }

    String lockOwner = namespaceLock.getDataChangeCreatedBy();
    if (!lockOwner.equals(currentUser)) {
      throw new BadRequestException(
          "namespace:" + namespace.getNamespaceName() + " is modified by " + lockOwner);
    }
  }

}

redpajama_set_name: RedPajamaGithub


text:
using base::Time;
using base::TimeDelta;
using base::win::RegKey;

class GCAPILastRunTest : public ::testing::Test {
 protected:
  void SetUp() override {
    // Override keys - this is undone during destruction.
    ASSERT_NO_FATAL_FAILURE(
        override_manager_.OverrideRegistry(HKEY_CURRENT_USER));

    // Create the client state key in the right places.
    std::wstring reg_path(google_update::kRegPathClientState);
    reg_path += L"\\";
    reg_path += google_update::kChromeUpgradeCode;
    RegKey client_state(HKEY_CURRENT_USER,
                        reg_path.c_str(),
                        KEY_CREATE_SUB_KEY | KEY_WOW64_32KEY);
    ASSERT_TRUE(client_state.Valid());

    // Place a bogus "pv" value in the right places to make the last run
    // checker believe Chrome is installed.
    std::wstring clients_path(google_update::kRegPathClients);
    clients_path += L"\\";
    clients_path += google_update::kChromeUpgradeCode;
    RegKey client_key(HKEY_CURRENT_USER,
                      clients_path.c_str(),
                      KEY_CREATE_SUB_KEY | KEY_SET_VALUE | KEY_WOW64_32KEY);
    ASSERT_TRUE(client_key.Valid());
    client_key.WriteValue(L"pv", L"1.2.3.4");
  }

  bool SetLastRunTime(int64_t last_run_time) {
    return SetLastRunTimeString(base::NumberToString16(last_run_time));
  }

  bool SetLastRunTimeString(const base::string16& last_run_time_string) {
    const wchar_t* base_path = google_update::kRegPathClientState;
    std::wstring path(base_path);
    path += L"\\";
    path += google_update::kChromeUpgradeCode;

    RegKey client_state(
        HKEY_CURRENT_USER, path.c_str(), KEY_SET_VALUE | KEY_WOW64_32KEY);
    return (client_state.Valid() &&
            client_state.WriteValue(
                google_update::kRegLastRunTimeField,
                last_run_time_string.c_str()) == ERROR_SUCCESS);
  }

 private:
  registry_util::RegistryOverrideManager override_manager_;
};

TEST_F(GCAPILastRunTest, Basic) {
  Time last_run = Time::NowFromSystemTime() - TimeDelta::FromDays(10);
  EXPECT_TRUE(SetLastRunTime(last_run.ToInternalValue()));

  int days_since_last_run = GoogleChromeDaysSinceLastRun();
  EXPECT_EQ(10, days_since_last_run);
}

TEST_F(GCAPILastRunTest, NoLastRun) {
  int days_since_last_run = GoogleChromeDaysSinceLastRun();
  EXPECT_EQ(-1, days_since_last_run);
}

TEST_F(GCAPILastRunTest, InvalidLastRun) {
  EXPECT_TRUE(SetLastRunTimeString(L"Hi Mum!"));
  int days_since_last_run = GoogleChromeDaysSinceLastRun();
  EXPECT_EQ(-1, days_since_last_run);
}

TEST_F(GCAPILastRunTest, OutOfRangeLastRun) {
  Time last_run = Time::NowFromSystemTime() - TimeDelta::FromDays(-42);
  EXPECT_TRUE(SetLastRunTime(last_run.ToInternalValue()));

  int days_since_last_run = GoogleChromeDaysSinceLastRun();
  EXPECT_EQ(-1, days_since_last_run);
}


text:
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.

using System.Collections.Generic;
using System.Linq;
using osu.Framework.Localisation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Game.Localisation;
using osu.Game.Overlays.Settings.Sections.Audio;

namespace osu.Game.Overlays.Settings.Sections
{
    public class AudioSection : SettingsSection
    {
        public override LocalisableString Header => AudioSettingsStrings.AudioSectionHeader;

        public override Drawable CreateIcon() => new SpriteIcon
        {
            Icon = FontAwesome.Solid.VolumeUp
        };

        public override IEnumerable<string> FilterTerms => base.FilterTerms.Concat(new[] { "sound" });

        public AudioSection()
        {
            Children = new Drawable[]
            {
                new AudioDevicesSettings(),
                new VolumeSettings(),
                new OffsetSettings(),
            };
        }
    }
}


text:
<?php
/**
 * Product_Type class
 *
 * @author David Vandemaele <david@tigron.be>
 */

use \Skeleton\Database\Database;

class Product_Type {
	use \Skeleton\Object\Model;
	use \Skeleton\Object\Get;
	use \Skeleton\Object\Save;
	use \Skeleton\Object\Delete;
	use \Skeleton\Pager\Page;

	/**
	 * Validate user data
	 *
	 * @access public
	 * @param array $errors
	 * @return bool $validated
	 */
	public function validate(&$errors = null) {
		$errors = [];
		$required_fields = [ 'name' ];
		foreach ($required_fields as $required_field) {
			if (!isset($this->details[$required_field]) OR $this->details[$required_field] == '') {
				$errors[$required_field] = 'required';
			}
		}

		if (count($errors) > 0) {
			return false;
		} else {
			return true;
		}
	}

	/**
	 * Get by identifier
	 *
	 * @access public
	 * @param string $identifier
	 * @return Product_Type $product_type
	 */
	public static function get_by_identifier($identifier) {
		$db = Database::get();
		$id = $db->get_one('SELECT id FROM product_type WHERE identifier=?', [ $identifier ]);
		if ($id === null) {
			throw new Exception('No product type found');
		}
		return self::get_by_id($id);
	}

}


text:
package org.apache.hadoop.metrics2.lib;

import org.apache.hadoop.metrics2.MetricsSink;
import org.apache.hadoop.metrics2.MetricsSource;
import org.apache.hadoop.metrics2.MetricsSystem;
import org.apache.hadoop.metrics2.impl.MetricsSystemImpl;

/**
 * The default metrics system singleton
 */
public enum DefaultMetricsSystem implements MetricsSystem {

  /**
   * The singleton instance
   */
  INSTANCE;

  private static final int VERSION = 2;
  private final MetricsSystemImpl impl = new MetricsSystemImpl();

  private MetricsSystem init(String prefix) {
    impl.init(prefix);
    return impl;
  }

  /**
   * Common static convenience method to initialize the metrics system
   * @param prefix  for configuration
   * @return the metrics system instance
   */
  public static MetricsSystem initialize(String prefix) {
    return INSTANCE.init(prefix);
  }

  public <T extends MetricsSource> T
  register(String name, String desc, T source) {
    return impl.register(name, desc, source);
  }

  /**
   * Common static method to register a source
   * @param <T>   type of the source
   * @param name  of the source
   * @param desc  description
   * @param source  the source object to register
   * @return the source object
   */
  public static <T extends MetricsSource> T
  registerSource(String name, String desc, T source) {
    return INSTANCE.register(name, desc, source);
  }

  public <T extends MetricsSink> T register(String name, String desc, T sink) {
    return impl.register(name, desc, sink);
  }

  public void register(Callback callback) {
    impl.register(callback);
  }

  public void start() {
    impl.start();
  }

  public void stop() {
    impl.stop();
  }

  public void refreshMBeans() {
    impl.refreshMBeans();
  }

  public String currentConfig() {
    return impl.currentConfig();
  }

  public void shutdown() {
    impl.shutdown();
  }

}


text:
// Copyright 2021 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import * as i18n from '../../core/i18n/i18n.js';
import type * as Platform from '../../core/platform/platform.js';
import * as SDK from '../../core/sdk/sdk.js';
import type * as IssuesManager from '../../models/issues_manager/issues_manager.js';

import {AffectedElementsView} from './AffectedElementsView.js';

const UIStrings = {
  /**
  *@description Noun for singular or plural number of affected document nodes indication in issue view.
  */
  nDocuments: '{n, plural, =1 { document} other { documents}}',
  /**
   *@description Column title for the Document in the DOM tree column in the quirks mode issue view
   */
  documentInTheDOMTree: 'Document in the DOM tree',
  /**
  *@description Column title for the url column in the quirks mode issue view
  */
  url: 'URL',
  /**
  *@description Column title for the Mode column in the quirks mode issue view
  */
  mode: 'Mode',
};
const str_ = i18n.i18n.registerUIStrings('panels/issues/AffectedDocumentsInQuirksModeView.ts', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);

export class AffectedDocumentsInQuirksModeView extends AffectedElementsView {
  #runningUpdatePromise: Promise<void> = Promise.resolve();

  update(): void {
    // Ensure that doUpdate is invoked atomically by serializing the update calls
    // because it's not re-entrace safe.
    this.#runningUpdatePromise = this.#runningUpdatePromise.then(this.#doUpdate.bind(this));
  }

  protected getResourceName(count: number): Platform.UIString.LocalizedString {
    return i18nString(UIStrings.nDocuments, {n: count});
  }

  async #doUpdate(): Promise<void> {
    this.clear();
    await this.#appendQuirksModeDocuments(this.issue.getQuirksModeIssues());
  }

  async #appendQuirksModeDocument(issue: IssuesManager.QuirksModeIssue.QuirksModeIssue): Promise<void> {
    const row = document.createElement('tr');
    row.classList.add('affected-resource-quirks-mode');

    const details = issue.details();

    const target =
        SDK.FrameManager.FrameManager.instance().getFrame(details.frameId)?.resourceTreeModel().target() || null;
    row.appendChild(await this.createElementCell(
        {nodeName: 'document', backendNodeId: details.documentNodeId, target}, issue.getCategory()));
    this.appendIssueDetailCell(row, details.isLimitedQuirksMode ? 'Limited Quirks Mode' : 'Quirks Mode');
    this.appendIssueDetailCell(row, details.url);

    this.affectedResources.appendChild(row);
  }

  async #appendQuirksModeDocuments(issues: Iterable<IssuesManager.QuirksModeIssue.QuirksModeIssue>): Promise<void> {
    const header = document.createElement('tr');
    this.appendColumnTitle(header, i18nString(UIStrings.documentInTheDOMTree));
    this.appendColumnTitle(header, i18nString(UIStrings.mode));
    this.appendColumnTitle(header, i18nString(UIStrings.url));

    this.affectedResources.appendChild(header);
    let count = 0;
    for (const issue of issues) {
      count++;
      await this.#appendQuirksModeDocument(issue);
    }
    this.updateAffectedResourceCount(count);
  }
}


text:
// Copyright (c) 2013-2020 Rob Norris and Contributors
// This software is licensed under the MIT License (MIT).
// For more information see LICENSE or https://opensource.org/licenses/MIT

package doobie.util.meta

import doobie.enumerated.JdbcType._

trait SqlMeta {

  object javasql extends MetaConstructors with SqlMetaInstances

}

trait SqlMetaInstances { this: MetaConstructors =>

  /** @group Instances */
  implicit val DateMeta: Meta[java.sql.Date] =
    Basic.one[java.sql.Date](
      Date,
      List(Char, VarChar, LongVarChar, Timestamp),
      _.getDate(_), _.setDate(_, _), _.updateDate(_, _))

  /** @group Instances */
  implicit val TimeMeta: Meta[java.sql.Time] =
    Basic.one[java.sql.Time](
      Time,
      List(Char, VarChar, LongVarChar, Timestamp),
      _.getTime(_), _.setTime(_, _), _.updateTime(_, _))

  /** @group Instances */
  implicit val TimestampMeta: Meta[java.sql.Timestamp] =
    Basic.one[java.sql.Timestamp](
      Timestamp,
      List(Char, VarChar, LongVarChar, Date, Time),
      _.getTimestamp(_), _.setTimestamp(_, _), _.updateTimestamp(_, _))

}


text:
require 'spec_helper'

module DailyActivities
  describe LoadActivities do
    let(:context) do
      {date: activity_record_date, user_id: 'user' }
    end

    subject { LoadActivities.call(context) }
    let!(:another_activity) { create_activity(activity_name: 'Another Activity', user_id: 'user', list_id: 2) }
    let!(:activity) { create_activity(activity_name: 'Activity', user_id: 'user', list_id: 1) }
    let!(:other_activity) { create_activity(activity_name: 'Other Activity', user_id: 'user', list_id: 1) }
    let!(:other_user_activity) { create_activity(activity_name: 'Other User Activity', user_id: 'other user', list_id: 2) }

    before do
      create_activity_record(activity: activity, record_date: Date.new(2014, 01, 05))
      create_activity_record(activity: activity, record_date: Date.new(2013, 12, 31))
      create_activity_record(activity: other_activity, record_date: Date.new(2014, 01, 02))
      create_activity_record(activity: other_user_activity)
    end

    shared_examples_for 'order of :attribute is :list' do |attribute, list|
      specify do
        expect(subject.activities.map{|activity| activity[attribute]}).to eq list
      end
    end

    context 'when list_id has been supplied' do
      before { context[:list_id] = 1 }
      let(:activity_record_date) { Date.new(2014, 01, 01) }

      it_should_behave_like 'order of :attribute is :list', :activity_name, ['Activity', 'Other Activity']
      it_should_behave_like 'order of :attribute is :list', :record_count, [2, 1]
      it_should_behave_like 'order of :attribute is :list', :recorded, [nil, nil]

      it 'orders "Activity" first, with the most activity records' do
        expect(subject.activities[0]).to match hash_including(
          activity_name: 'Activity',
          id: activity[:id],
          record_count: 2,
          recorded: nil
        )
      end

      it 'orders "Other Activity" last, with the seconds most activity records' do
        expect(subject.activities[1]).to match hash_including(
          activity_name: 'Other Activity',
          id: other_activity[:id],
          record_count: 1,
          recorded: nil
        )
      end
    end

    context 'when no date has been supplied' do
      before { context.delete(:date) }
      let(:activity_record_date) { Date.new(2014, 01, 01) }

      it_should_behave_like 'order of :attribute is :list', :activity_name, ['Activity', 'Other Activity', 'Another Activity']
      it_should_behave_like 'order of :attribute is :list', :record_count, [2, 1, 0 ]
      it_should_behave_like 'order of :attribute is :list', :recorded, [true, true, nil]

      it 'orders "Activity" first, with the most activity records' do
        expect(subject.activities[0]).to match hash_including(
          activity_name: 'Activity',
          id: activity[:id],
          record_count: 2,
          recorded: true
        )
      end

      it 'orders "Other Activity" second, with the seconds most activity records' do
        expect(subject.activities[1]).to match hash_including(
          activity_name: 'Other Activity',
          id: other_activity[:id],
          record_count: 1,
          recorded: true
        )
      end

      it 'orders "Another Activity" last, with the fewest activity records' do
        expect(subject.activities[2]).to match hash_including(
          activity_name: 'Another Activity',
          id: another_activity[:id],
          record_count: 0,
          recorded: nil
        )
      end
    end

    context 'when a date is provided, but no activity records exist for the date' do
      let(:activity_record_date) { Date.new(2014, 01, 01) }

      it_should_behave_like 'order of :attribute is :list', :activity_name, [
        'Activity',
        'Other Activity',
        'Another Activity'
      ]

      it 'orders "Activity" first, with the most activity records' do
        expect(subject.activities[0]).to match hash_including(
          record_count: 2,
          activity_name: 'Activity',
          id: activity[:id],
          recorded: nil
        )
      end

      it 'orders "Other Activity" second, with the seconds most activity records' do
        expect(subject.activities[1]).to match hash_including(
          record_count: 1,
          activity_name: 'Other Activity',
          id: other_activity[:id],
          recorded: nil
        )
      end

      it 'orders "Another Activity" last, with the fewest activity records' do
        expect(subject.activities[2]).to match hash_including(
          record_count: 0,
          activity_name: 'Another Activity',
          id: another_activity[:id],
          recorded: nil
        )
      end
    end

    context 'when a date is provided, and activity records exist for the date' do
      let(:activity_record_date) { Date.new(2014, 01, 02) }

      it_should_behave_like 'order of :attribute is :list', :activity_name, [
        'Other Activity',
        'Activity',
        'Another Activity'
      ]

      it 'orders "Other Activity" first, because it was recorded for the date' do
        expect(subject.activities[0]).to match hash_including(
          record_count: 1,
          activity_name: 'Other Activity',
          id: other_activity[:id],
          recorded: true
        )
      end

      it 'orders "Activity" second, with the most activity records' do
        expect(subject.activities[1]).to match hash_including(
          record_count: 2,
          activity_name: 'Activity',
          id: activity[:id],
          recorded: nil
        )
      end

      it 'orders "Another Activity" last, with the fewest activity records' do
        expect(subject.activities[2]).to match hash_including(
          record_count: 0,
          activity_name: 'Another Activity',
          id: another_activity[:id],
          recorded: nil
        )
      end
    end
  end
end


text:
package org.dita.dost.reader;

import org.dita.dost.log.DITAOTLogger;
import org.dita.dost.util.Job;
import org.dita.dost.util.MergeUtils;
import org.dita.dost.util.URLUtils;
import org.dita.dost.util.XMLUtils;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import org.xml.sax.helpers.XMLFilterImpl;

import java.io.File;
import java.net.URI;

import static javax.xml.XMLConstants.XML_NS_URI;
import static org.dita.dost.reader.MergeMapParser.ATTRIBUTE_NAME_OHREF;
import static org.dita.dost.reader.MergeMapParser.ATTRIBUTE_NAME_OID;
import static org.dita.dost.util.Constants.*;
import static org.dita.dost.util.DitaUtils.isLocalScope;
import static org.dita.dost.util.FileUtils.stripFragment;
import static org.dita.dost.util.URLUtils.*;

/**
 * MergeTopicParser reads topic file and transform the references to other dita
 * files into internal references. The parse result of MergeTopicParser will be
 * returned to MergeMapParser and serves as part of intermediate merged result.
 * Instances are reusable but not thread-safe.
 */
public final class MergeTopicParser extends XMLFilterImpl {

    private File dirPath = null;
    private String filePath = null;
    private String rootLang = null;

    /** ID of the first topic */
    private String firstTopicId = null;
    private final MergeUtils util;
    private Job job;
    private DITAOTLogger logger;
    private File output;
    private final String GENERATED_DITA_ELEMENT_ID = "GENERATED-DITA-ID";

    /**
     * Default Constructor.
     *
     * @param util merge utility
     */
    public MergeTopicParser(final MergeUtils util) {
        this.util = util;
    }

    public final void setLogger(final DITAOTLogger logger) {
        this.logger = logger;
    }

    public final void setJob(final Job job) { this.job = job; }

    /**
     * Set merge output file
     *
     * @param output merge output file
     */
    public void setOutput(File output) {
        this.output = output;
    }

    /**
     * Get ID of the first topic
     *
     * @return id attribute value of the first topic
     */
    public String getFirstTopicId() {
        return firstTopicId;
    }

    @Override
    public void endDocument() throws SAXException {
        // NOOP
    }

    @Override
    public void endElement(final String uri, final String localName, final String qName) throws SAXException {
        getContentHandler().endElement(uri, localName, qName);
    }

    /**
     * Get new value for topic id attribute.
     *
     */
    private void handleID(final AttributesImpl atts) {
        String idValue = atts.getValue(ATTRIBUTE_NAME_ID);
        if (idValue != null) {
            XMLUtils.addOrSetAttribute(atts, ATTRIBUTE_NAME_OID, idValue);
            final URI value = setFragment(URLUtils.toDirURI(dirPath).resolve(toURI(filePath)), idValue);
            if (util.findId(value)) {
                idValue = util.getIdValue(value);
            } else {
                idValue = util.addId(value);
            }
            XMLUtils.addOrSetAttribute(atts, ATTRIBUTE_NAME_ID, idValue);
        }
    }

    /**
     * Rewrite local DITA href value.
     *
     * @param href href attribute value
     * @return rewritten href value
     */
    private URI handleLocalDita(final URI href, final AttributesImpl atts) {
        final URI attValue = href;
        final int sharpIndex = attValue.toString().indexOf(SHARP);
        URI pathFromMap;
        URI retAttValue;
        if (sharpIndex != -1) { // href value refer to an id in a topic
            if (sharpIndex == 0) {
                pathFromMap = toURI(filePath);
            } else {
                pathFromMap = toURI(filePath).resolve(attValue.toString().substring(0, sharpIndex));
            }
            XMLUtils.addOrSetAttribute(atts, ATTRIBUTE_NAME_OHREF, toURI(pathFromMap + attValue.toString().substring(sharpIndex)).toString());
            final String topicID = getTopicID(attValue.getFragment());
            final int index = attValue.toString().indexOf(SLASH, sharpIndex);
            final String elementId = index != -1 ? attValue.toString().substring(index) : "";
            final URI pathWithTopicID = setFragment(URLUtils.toDirURI(dirPath).resolve(pathFromMap), topicID);
            if (util.findId(pathWithTopicID)) {// topicId found
                retAttValue = toURI(SHARP + util.getIdValue(pathWithTopicID) + elementId);
            } else {// topicId not found
                retAttValue = toURI(SHARP + util.addId(pathWithTopicID) + elementId);
            }
        } else { // href value refer to a topic
            pathFromMap = toURI(filePath).resolve(attValue.toString());
            URI absolutePath = URLUtils.toDirURI(dirPath).resolve(pathFromMap);
            XMLUtils.addOrSetAttribute(atts, ATTRIBUTE_NAME_OHREF, pathFromMap.toString());
            if (util.findId(absolutePath)) {
                retAttValue = toURI(SHARP + util.getIdValue(absolutePath));
            } else {
                final String fileId = util.getFirstTopicId(absolutePath, false);
                final URI key = setFragment(absolutePath, fileId);
                if (util.findId(key)) {
                    util.addId(absolutePath, util.getIdValue(key));
                    retAttValue = toURI(SHARP + util.getIdValue(key));
                } else {
                    retAttValue = toURI(SHARP + util.addId(absolutePath));
                    util.addId(key, util.getIdValue(absolutePath));
                }

            }
        }
        return retAttValue;
    }

    private String getTopicID(final String fragment) {
        final int slashIndex = fragment.indexOf(SLASH);
        return slashIndex != -1 ? fragment.substring(0, slashIndex) : fragment;
    }

    /**
     * Parse the file to update id.
     *
     * @param filename relative topic system path, may contain a fragment part
     * @param dir topic directory system path
     */
    public void parse(final String filename, final File dir) {
        filePath = stripFragment(filename);
        dirPath = dir;
        try {
            final URI f = dir.toPath().resolve(filePath).toAbsolutePath().toFile().toURI();
            logger.info("Processing " + f);
            job.getStore().transform(f, this);
        } catch (final RuntimeException e) {
            throw e;
        } catch (final Exception e) {
            throw new RuntimeException("Failed to parse " + filename + ": " + e.getMessage(), e);
        }
    }

    @Override
    public void startDocument() throws SAXException {
        firstTopicId = null;
        rootLang = null;
    }

    @Override
    public void startElement(final String uri, final String localName, final String qName, final Attributes attributes)
            throws SAXException {
        final AttributesImpl atts = new AttributesImpl(attributes);
        final String classValue = atts.getValue(ATTRIBUTE_NAME_CLASS);

        if (ELEMENT_NAME_DITA.equals(qName)) {
            rootLang = attributes.getValue(XML_NS_URI, "lang");
            if (atts.getValue(ATTRIBUTE_NAME_ID) == null) {
                XMLUtils.addOrSetAttribute(atts, ATTRIBUTE_NAME_ID, GENERATED_DITA_ELEMENT_ID);
            }
        }
        if (TOPIC_TOPIC.matches(classValue) || ELEMENT_NAME_DITA.equals(qName)) {
            handleID(atts);
            if (firstTopicId == null) {
                firstTopicId = atts.getValue(ATTRIBUTE_NAME_ID);
            }
        }
        handleHref(classValue, atts);

        getContentHandler().startElement(uri, localName, qName, atts);
    }

    /**
     * Rewrite href attribute.
     *
     * @param classValue element class value
     * @param atts attributes
     */
    private void handleHref(final String classValue, final AttributesImpl atts) {
        final URI attValue = toURI(atts.getValue(ATTRIBUTE_NAME_HREF));
        if (attValue != null) {
            final String scopeValue = atts.getValue(ATTRIBUTE_NAME_SCOPE);
            if (isLocalScope(scopeValue)
                    && attValue.getScheme() == null) {
                final String formatValue = atts.getValue(ATTRIBUTE_NAME_FORMAT);
                // The scope for @href is local
                if ((TOPIC_XREF.matches(classValue) || TOPIC_LINK.matches(classValue) || TOPIC_LQ.matches(classValue)
                // term, keyword, cite, ph, and dt are resolved as keyref can make them links
                        || TOPIC_TERM.matches(classValue) || TOPIC_KEYWORD.matches(classValue)
                        || TOPIC_CITE.matches(classValue) || TOPIC_PH.matches(classValue)
                        || TOPIC_DT.matches(classValue))
                        && (formatValue == null || ATTR_FORMAT_VALUE_DITA.equals(formatValue))) {
                    // local xref or link that refers to dita file
                    XMLUtils.addOrSetAttribute(atts, ATTRIBUTE_NAME_HREF, handleLocalDita(attValue, atts).toString());
                } else {
                    // local @href other than local xref and link that refers to
                    // dita file
                    XMLUtils.addOrSetAttribute(atts, ATTRIBUTE_NAME_HREF, handleLocalHref(attValue).toString());
                }
            }
        }
    }

    /**
     * Rewrite local non-DITA href value.
     *
     * @param attValue href attribute value
     * @return rewritten href value
     */
    private URI handleLocalHref(final URI attValue) {
        final URI current = dirPath.toPath().resolve(filePath).toUri().normalize();
        final URI reference = current.resolve(attValue);
        final URI merge = output.toURI();
        return getRelativePath(merge, reference);
    }

}


text:
global.COUNT = global.COUNT || 0
global.COUNT ++

var assert = require('assert')
var m = module.exports
assert.strictEqual(require('./self-reference'), m)

assert.equal(global.COUNT, 1)


text:
<?php

namespace HierarchyDistances;

class Lorem implements FirstLoremInterface, SecondLoremInterface
{

	use TraitTwo;

}


text:
layout: post
title: Pigtailed Schoolgirl Gets 3 Cocks
titleinfo: pornvd
desc: Watch Pigtailed Schoolgirl Gets 3 Cocks. Pornhub is the ultimate xxx porn and sex site.
---

Pigtailed Schoolgirl Gets 3 Cocks

Watch Pigtailed Schoolgirl Gets 3 Cocks. Pornhub is the ultimate xxx porn and sex site.


text:
    The protection of privacy, a challenge these days:

    What are we doing today to preserve our privacy in this new digital world? We read social networks such as Facebook
    or Google+ more without moderation.
    And we are posting our moods and other stuff without worrying about what will happen to our data, in the near future
    but also in the more distant future!

Also, it appears that our practices on social networks pose security challenges of tomorrow:
I invite you to watch this video or a security expert (Mikko Hyppönen at USI – OCTO Technology), explains these issues. Take a few minutes to look at is quite edifying!

There was a time where all electronic devices did not exist! How we were doing then? We went to the cafe, or in a public place to meet people, our friends, our acquaintances.

Today the situation has completely changed! With the proliferation of electronic applications on media such as telephone or tablets but also personal computers, without extent, we are posting our moods if we had a good night, or if we butt itch!

Everything is an artifact to post, and we are so happy to share such important things in the whole world! But in the pre digital age, would we have done that? I think not! Today when we post publicly on Facebook, we ask if we would be willing to go to the village square, and with a megaphone, say we had a bad night for example.

    Some facts:

The first thing appears: the Internet of the majors are now building an IT model, whose ultimate goal is to collect our data. To shape our person, and thus sell tailored advertising. You think I'm paranoid? So let's look at this a little closer:

Google built "data center" on the planet.

Facebook buys WhatsApp for $ 22 million, with the ultimate goal to correlate your Facebook profile with a phone
        number. Facebook has not purchased the application, they bought the data, that is to say, our phone number.

Twitter, Facebook Google still without the triumvirate of these practices, but they are not alone!

The statements are the first to hack our private data, all in order to protect us of course.

I think businesses are there to make money it is their goal. They can not survive without money, and thus repay us our wages. So when she can do so without pain for us, they do! All because of the "I Agree syndrome".

Who takes the time to read the Terms and Conditions applications? Nobody actually somehow you have already paid for the software, and especially for those that are free. You no longer have a choice!

I think there is no fate, and that alternatives may exist and even I would have to exist. So I invite you to join forces with mine for and b ready for change!

With IT professional for over 15 years, other models may exist. Take for example peer-to-peer model: a long time ago used to share music film also often hacked!

Why not put it to good use model for our data exchanges on social networks? After all our private data do not necessarily have to pass on third-party servers. scattered in the cloud, and we don't know where they are !Google Facebook and other know where our data, we involuntary these clients profiling practices.


text:
package gitlab

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"

	"github.com/pkg/errors"
	"github.com/rancher/norman/api/access"
	"github.com/rancher/norman/httperror"
	"github.com/rancher/norman/types"
	"github.com/rancher/norman/types/convert"
	v32 "github.com/rancher/rancher/pkg/apis/project.cattle.io/v3"
	client "github.com/rancher/rancher/pkg/client/generated/project/v3"
	"github.com/rancher/rancher/pkg/pipeline/remote/model"
	"github.com/rancher/rancher/pkg/ref"
)

const (
	gitlabDefaultHostName = "https://gitlab.com"
	actionDisable         = "disable"
	actionTestAndApply    = "testAndApply"
	actionLogin           = "login"
)

func (g *GlProvider) Formatter(apiContext *types.APIContext, resource *types.RawResource) {
	if convert.ToBool(resource.Values["enabled"]) {
		resource.AddAction(apiContext, actionDisable)
	}

	resource.AddAction(apiContext, actionTestAndApply)
}

func (g *GlProvider) ActionHandler(actionName string, action *types.Action, request *types.APIContext) error {
	if actionName == actionTestAndApply {
		return g.testAndApply(actionName, action, request)
	} else if actionName == actionDisable {
		return g.DisableAction(request, g.GetName())
	}

	return httperror.NewAPIError(httperror.ActionNotAvailable, "")
}

func (g *GlProvider) providerFormatter(apiContext *types.APIContext, resource *types.RawResource) {
	resource.AddAction(apiContext, actionLogin)
}

func (g *GlProvider) providerActionHandler(actionName string, action *types.Action, request *types.APIContext) error {
	if actionName == actionLogin {
		return g.authuser(request)
	}

	return httperror.NewAPIError(httperror.ActionNotAvailable, "")
}

func (g *GlProvider) testAndApply(actionName string, action *types.Action, apiContext *types.APIContext) error {
	applyInput := &v32.GitlabApplyInput{}

	if err := json.NewDecoder(apiContext.Request.Body).Decode(applyInput); err != nil {
		return httperror.NewAPIError(httperror.InvalidBodyContent,
			fmt.Sprintf("Failed to parse body: %v", err))
	}

	ns, _ := ref.Parse(apiContext.ID)
	pConfig, err := g.GetProviderConfig(ns)
	if err != nil {
		return err
	}
	storedGitlabPipelineConfig, ok := pConfig.(*v32.GitlabPipelineConfig)
	if !ok {
		return fmt.Errorf("Failed to get gitlab provider config")
	}
	toUpdate := storedGitlabPipelineConfig.DeepCopy()

	toUpdate.ClientID = applyInput.ClientID
	toUpdate.ClientSecret = applyInput.ClientSecret
	toUpdate.Hostname = applyInput.Hostname
	toUpdate.TLS = applyInput.TLS
	currentURL := apiContext.URLBuilder.Current()
	u, err := url.Parse(currentURL)
	if err != nil {
		return err
	}
	toUpdate.RedirectURL = fmt.Sprintf("%s://%s/verify-auth", u.Scheme, u.Host)
	//oauth and add user
	userName := apiContext.Request.Header.Get("Impersonate-User")
	sourceCodeCredential, err := g.AuthAddAccount(userName, applyInput.Code, toUpdate, toUpdate.ProjectName, model.GitlabType)
	if err != nil {
		return err
	}
	if _, err = g.RefreshReposByCredentialAndConfig(sourceCodeCredential, toUpdate); err != nil {
		return err
	}
	toUpdate.Enabled = true
	//update gitlab pipeline config
	if _, err = g.SourceCodeProviderConfigs.ObjectClient().Update(toUpdate.Name, toUpdate); err != nil {
		return err
	}

	apiContext.WriteResponse(http.StatusOK, nil)
	return nil
}

func (g *GlProvider) authuser(apiContext *types.APIContext) error {
	authUserInput := v32.AuthUserInput{}
	requestBytes, err := ioutil.ReadAll(apiContext.Request.Body)
	if err != nil {
		return err
	}
	if err := json.Unmarshal(requestBytes, &authUserInput); err != nil {
		return err
	}

	ns, _ := ref.Parse(apiContext.ID)
	pConfig, err := g.GetProviderConfig(ns)
	if err != nil {
		return err
	}
	config, ok := pConfig.(*v32.GitlabPipelineConfig)
	if !ok {
		return fmt.Errorf("Failed to get gitlab provider config")
	}
	if !config.Enabled {
		return errors.New("gitlab oauth app is not configured")
	}

	//oauth and add user
	userName := apiContext.Request.Header.Get("Impersonate-User")
	account, err := g.AuthAddAccount(userName, authUserInput.Code, config, config.ProjectName, model.GitlabType)
	if err != nil {
		return err
	}
	data := map[string]interface{}{}
	if err := access.ByID(apiContext, apiContext.Version, client.SourceCodeCredentialType, account.Name, &data); err != nil {
		return err
	}

	if _, err := g.RefreshReposByCredentialAndConfig(account, config); err != nil {
		return err
	}

	apiContext.WriteResponse(http.StatusOK, data)
	return nil
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--
  ~ Copyright (c) 2016 Savoir Technologies
  ~
  ~ 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.
  ~
  ~
  -->

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.savoirtech</groupId>
        <artifactId>savoir-parent</artifactId>
        <version>1.0.3</version>
    </parent>

    <groupId>com.savoirtech.logging</groupId>
    <artifactId>slf4j-json-logger-parent</artifactId>
    <packaging>pom</packaging>
    <version>3.0.0-SNAPSHOT</version>
    <name>SavoirTech ::: SLF4J JSON logger ::: Parent</name>

    <description>
        Parent for the easy-to-use Logger generating JSON-formatted messages on top of SLF4J
        logging.
    </description>

    <modules>
        <module>slf4j-json-logger</module>
        <module>slf4j-json-logger-mockito</module>
        <module>features</module>
    </modules>

    <scm>
        <url>https://github.com/savoirtech/slf4j-json-logger</url>
        <connection>scm:git:git@github.com:savoirtech/slf4j-json-logger.git</connection>
        <developerConnection>scm:git:git@github.com:savoirtech/slf4j-json-logger.git
        </developerConnection>
    </scm>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <gson.version>2.6.2</gson.version>
        <slf4j.version>1.7.12</slf4j.version>
        <commons.lang3.version>3.4</commons.lang3.version>
        <junit.version>4.12</junit.version>
        <mockito.version>1.10.19</mockito.version>

        <sonar.version>3.0.1</sonar.version>

        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.felix</groupId>
                <artifactId>maven-bundle-plugin</artifactId>
            </plugin>
        </plugins>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>sonar-maven-plugin</artifactId>
                    <version>${sonar.version}</version>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.savoirtech.logging</groupId>
                <artifactId>slf4j-json-logger</artifactId>
                <version>${project.version}</version>
            </dependency>

            <dependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
                <version>${gson.version}</version>
            </dependency>

            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>${commons.lang3.version}</version>
            </dependency>

            <!-- logging -->

            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>

            <!-- testing -->

            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
            </dependency>

            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>${slf4j.version}</version>
            </dependency>

            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-core</artifactId>
                <version>${mockito.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

</project>


text:
module Azure::Appconfiguration::Mgmt::V2020_06_01
  module Models
    #
    # Defines values for IdentityType
    #
    module IdentityType
      None = "None"
      SystemAssigned = "SystemAssigned"
      UserAssigned = "UserAssigned"
      SystemAssignedUserAssigned = "SystemAssigned, UserAssigned"
    end
  end
end


text:
// Copyright 2012 The Closure Library Authors. All Rights Reserved.
//
// 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.

goog.provide('goog.dbTest');
goog.setTestOnly('goog.dbTest');

goog.require('goog.Disposable');
goog.require('goog.Promise');
goog.require('goog.array');
goog.require('goog.db');
goog.require('goog.db.Cursor');
goog.require('goog.db.Error');
goog.require('goog.db.IndexedDb');
goog.require('goog.db.KeyRange');
goog.require('goog.db.Transaction');
goog.require('goog.events');
goog.require('goog.object');
goog.require('goog.testing.PropertyReplacer');
goog.require('goog.testing.asserts');
goog.require('goog.testing.jsunit');
goog.require('goog.userAgent.product');

var idbSupported = goog.userAgent.product.CHROME;
var dbName;
var dbBaseName = 'testDb';
var globalDb = null;
var dbsToClose = [];
var propertyReplacer;

var baseVersion = 1;

var dbVersion = 1;

var TransactionMode = goog.db.Transaction.TransactionMode;
var EventTypes = goog.db.Transaction.EventTypes;

function openDatabase() {
  return goog.db.openDatabase(dbName).addCallback(function(db) {
    dbsToClose.push(db);
  });
}

function incrementVersion(db, onUpgradeNeeded) {
  db.close();

  var onBlocked = function(ev) {
    fail('Upgrade to version ' + dbVersion + ' is blocked.');
  };

  return goog.db.openDatabase(dbName, ++dbVersion, onUpgradeNeeded, onBlocked)
      .addCallback(function(db) {
        dbsToClose.push(db);
        assertEquals(dbVersion, db.getVersion());
      });
}

function addStore(db) {
  return incrementVersion(
      db, function(ev, db, tx) { db.createObjectStore('store'); });
}

function addStoreWithIndex(db) {
  return incrementVersion(db, function(ev, db, tx) {
    var store = db.createObjectStore('store', {keyPath: 'key'});
    store.createIndex('index', 'value');
  });
}

function populateStore(values, keys, db) {
  var putTx = db.createTransaction(['store'], TransactionMode.READ_WRITE);
  var store = putTx.objectStore('store');
  for (var i = 0; i < values.length; ++i) {
    store.put(values[i], keys[i]);
  }
  return putTx.wait();
}

function populateStoreWithObjects(values, keys, db) {
  var putTx = db.createTransaction(['store'], TransactionMode.READ_WRITE);
  var store = putTx.objectStore('store');
  goog.array.forEach(values, function(value, index) {
    store.put({'key': keys[index], 'value': value});
  });
  return putTx.wait();
}

function assertStoreValues(values, db) {
  var assertStoreTx = db.createTransaction(['store']);
  assertStoreTx.objectStore('store').getAll().addCallback(function(results) {
    assertSameElements(values, results);
  });
}

/**
 * Assert the keys are as expected.
 * @param {!Array<string>} keys - The expected keys.
 * @param {!goog.db.IndexedDb} db - The indexed db.
 */
function assertStoreKeyValues(keys, db) {
  var assertStoreTx = db.createTransaction(['store']);
  assertStoreTx.objectStore('store').getAllKeys().addCallback(function(
      results) {
    assertSameElements(keys, results);
  });
}

function assertStoreObjectValues(values, db) {
  var assertStoreTx = db.createTransaction(['store']);
  assertStoreTx.objectStore('store').getAll().addCallback(function(results) {
    var retrievedValues =
        goog.array.map(results, function(result) { return result['value']; });
    assertSameElements(values, retrievedValues);
  });
}

function assertStoreValuesAndCursorsDisposed(values, cursors, db) {
  var assertStoreTx = db.createTransaction(['store']);
  assertStoreTx.objectStore('store').getAll().addCallback(function(results) {
    assertSameElements(values, results);
    assertTrue(cursors.length > 0);
    goog.array.forEach(cursors, function(elem, index, array) {
      console.log(elem);
      assertTrue(
          'array[' + index + '] (' + elem + ') is not disposed',
          goog.Disposable.isDisposed(elem));
    });
  });
}

function assertStoreDoesntExist(db) {
  try {
    db.createTransaction(['store']);
    fail('Create transaction with a non-existent store should have failed.');
  } catch (e) {
    // expected
    assertEquals(e.getName(), goog.db.Error.ErrorName.NOT_FOUND_ERR);
  }
}

function transactionToPromise(db, trx) {
  return new goog.Promise(function(resolve, reject) {
    goog.events.listen(trx, EventTypes.ERROR, reject);
    goog.events.listen(trx, EventTypes.COMPLETE, function() { resolve(db); });
  });
}

// Calls onRecordReady each time that a new record can be read by the
// cursor with cursor.next(). Returns a promise that resolves or rejects
// based on when the cursor is complete or errors out. If onRecordReady
// returns a promise that promises is also waited on before the returned
// promise resolves.
function forEachRecord(cursor, onRecordReady) {
  var promises = [];
  return new goog
      .Promise(function(resolve, reject) {
        var key = goog.events.listen(
            cursor, goog.db.Cursor.EventType.NEW_DATA, function() {
              var result = onRecordReady();
              if (result && ('then' in result)) {
                promises.push(result);
              }
            });

        goog.events.listenOnce(
            cursor,
            [goog.db.Cursor.EventType.COMPLETE, goog.db.Cursor.EventType.ERROR],
            function(evt) {
              goog.events.unlistenByKey(key);
              if (evt.type == goog.db.Cursor.EventType.COMPLETE) {
                resolve();
              } else {
                reject(evt);
              }
            });
      })
      .then(function() { return goog.Promise.all(promises); });
}

function failOnErrorEvent(ev) {
  fail(ev.target.message);
}

function setUpPage() {
  propertyReplacer = new goog.testing.PropertyReplacer();
}

function setUp() {
  if (!idbSupported) {
    return;
  }

  // Always use a clean database by generating a new database name.
  dbName = dbBaseName + Date.now().toString();
  globalDb = openDatabase();
}

function tearDown() {
  for (var i = 0; i < dbsToClose.length; i++) {
    dbsToClose[i].close();
  }
  dbsToClose = [];
  propertyReplacer.reset();
}

function testDatabaseOpened() {
  if (!idbSupported) {
    return;
  }

  assertNotNull(globalDb);
  return globalDb.branch().addCallback(function(db) {
    assertTrue(db.isOpen());
  });
}

function testOpenWithNewVersion() {
  if (!idbSupported) {
    return;
  }

  var upgradeNeeded = false;
  return globalDb.branch()
      .addCallback(function(db) {
        assertEquals(baseVersion, db.getVersion());
        return incrementVersion(
            db, function(ev, db, tx) { upgradeNeeded = true; });
      })
      .addCallback(function(db) { assertTrue(upgradeNeeded); });
}

function testManipulateObjectStores() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch()
      .addCallback(function(db) {
        assertEquals(baseVersion, db.getVersion());
        return incrementVersion(db, function(ev, db, tx) {
          db.createObjectStore('basicStore');
          db.createObjectStore('keyPathStore', {keyPath: 'keyGoesHere'});
          db.createObjectStore('autoIncrementStore', {autoIncrement: true});
        });
      })
      .addCallback(function(db) {
        var storeNames = db.getObjectStoreNames();
        assertEquals(3, storeNames.length);
        assertTrue(storeNames.contains('basicStore'));
        assertTrue(storeNames.contains('keyPathStore'));
        assertTrue(storeNames.contains('autoIncrementStore'));
        return incrementVersion(
            db, function(ev, db, tx) { db.deleteObjectStore('basicStore'); });
      })
      .addCallback(function(db) {
        var storeNames = db.getObjectStoreNames();
        assertEquals(2, storeNames.length);
        assertFalse(storeNames.contains('basicStore'));
        assertTrue(storeNames.contains('keyPathStore'));
        assertTrue(storeNames.contains('autoIncrementStore'));
      });
}

function testBadObjectStoreManipulation() {
  if (!idbSupported) {
    return;
  }

  var expectedCode = goog.db.Error.ErrorName.INVALID_STATE_ERR;
  return globalDb.branch()
      .addCallback(function(db) {
        try {
          db.createObjectStore('diediedie');
          fail('Create object store outside transaction should have failed.');
        } catch (err) {
          // expected
          assertEquals(expectedCode, err.getName());
        }
      })
      .addCallback(addStore)
      .addCallback(function(db) {
        try {
          db.deleteObjectStore('store');
          fail('Delete object store outside transaction should have failed.');
        } catch (err) {
          // expected
          assertEquals(expectedCode, err.getName());
        }
      })
      .addCallback(function(db) {
        return incrementVersion(db, function(ev, db, tx) {
          try {
            db.deleteObjectStore('diediedie');
            fail('Delete non-existent store should have failed.');
          } catch (err) {
            // expected
            assertEquals(goog.db.Error.ErrorName.NOT_FOUND_ERR, err.getName());
          }
        });
      });
}

function testGetNonExistentObjectStore() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch().addCallback(addStore).addCallback(function(db) {
    var tx = db.createTransaction(['store']);
    try {
      tx.objectStore('diediedie');
      fail('getting non-existent object store should have failed');
    } catch (err) {
      assertEquals(goog.db.Error.ErrorName.NOT_FOUND_ERR, err.getName());
    }
  });
}

function testCreateTransaction() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch().addCallback(addStore).addCallback(function(db) {
    var tx = db.createTransaction(['store']);
    assertEquals('mode not READ_ONLY', TransactionMode.READ_ONLY, tx.getMode());
    tx = db.createTransaction(
        ['store'], goog.db.Transaction.TransactionMode.READ_WRITE);
    assertEquals(
        'mode not READ_WRITE', TransactionMode.READ_WRITE, tx.getMode());
  });
}

function testPutRecord() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(function(db) {
        var initialPutTx =
            db.createTransaction(['store'], TransactionMode.READ_WRITE);
        var putOperation = initialPutTx.objectStore('store').put(
            {key: 'initial', value: 'value1'}, 'putKey');
        putOperation.addCallback(function(key) {
          assertEquals('putKey', key);
        });
        return transactionToPromise(db, initialPutTx);
      })
      .addCallback(function(db) {
        var checkResultsTx = db.createTransaction(['store']);
        var getOperation = checkResultsTx.objectStore('store').get('putKey');
        getOperation.addCallback(function(result) {
          assertEquals('initial', result.key);
          assertEquals('value1', result.value);
        });
        return transactionToPromise(db, checkResultsTx);
      })
      .addCallback(function(db) {
        var overwriteTx =
            db.createTransaction(['store'], TransactionMode.READ_WRITE);
        var putOperation = overwriteTx.objectStore('store').put(
            {key: 'overwritten', value: 'value2'}, 'putKey');
        putOperation.addCallback(function(key) {
          assertEquals('putKey', key);
        });
        return transactionToPromise(db, overwriteTx);
      })
      .addCallback(function(db) {
        var checkOverwriteTx = db.createTransaction(['store']);
        checkOverwriteTx.objectStore('store').get('putKey').addCallback(
            function(result) {
              // this is guaranteed to run before the COMPLETE event fires on
              // the transaction
              assertEquals('overwritten', result.key);
              assertEquals('value2', result.value);
            });

        return transactionToPromise(db, checkOverwriteTx);
      });
}

function testAddRecord() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(function(db) {
        var initialAddTx =
            db.createTransaction(['store'], TransactionMode.READ_WRITE);
        var addOperation = initialAddTx.objectStore('store').add(
            {key: 'hi', value: 'something'}, 'stuff');
        addOperation.addCallback(function(key) {
          assertEquals('stuff', key);
        });
        return transactionToPromise(db, initialAddTx);
      })
      .addCallback(function(db) {
        var successfulAddTx = db.createTransaction(['store']);
        var getOperation = successfulAddTx.objectStore('store').get('stuff');
        getOperation.addCallback(function(result) {
          assertEquals('hi', result.key);
          assertEquals('something', result.value);
        });
        return transactionToPromise(db, successfulAddTx);
      })
      .addCallback(function(db) {
        var addOverwriteTx =
            db.createTransaction(['store'], TransactionMode.READ_WRITE);
        addOverwriteTx.objectStore('store')
            .add({key: 'bye', value: 'nothing'}, 'stuff')
            .addErrback(function(err) {
              // expected
              assertEquals(
                  goog.db.Error.ErrorName.CONSTRAINT_ERR, err.getName());
            });
        return transactionToPromise(db, addOverwriteTx)
            .then(
                function() {
                  fail('adding existing record should not have succeeded');
                },
                function(ev) {
                  // expected
                  assertEquals(
                      goog.db.Error.ErrorName.CONSTRAINT_ERR,
                      ev.target.getName());
                });
      });
}

function testPutRecordKeyPathStore() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch()
      .addCallback(function(db) {
        return incrementVersion(db, function(ev, db, tx) {
          db.createObjectStore('keyStore', {keyPath: 'key'});
        });
      })
      .addCallback(function(db) {
        var putTx =
            db.createTransaction(['keyStore'], TransactionMode.READ_WRITE);
        var putOperation =
            putTx.objectStore('keyStore').put({key: 'hi', value: 'something'});
        putOperation.addCallback(function(key) {
          assertEquals('hi', key);
        });
        return transactionToPromise(db, putTx);
      })
      .addCallback(function(db) {
        var checkResultsTx = db.createTransaction(['keyStore']);
        checkResultsTx.objectStore('keyStore')
            .get('hi')
            .addCallback(function(result) {
              assertNotUndefined(result);
              assertEquals('hi', result.key);
              assertEquals('something', result.value);
            });
        return transactionToPromise(db, checkResultsTx);
      });
}

function testPutBadRecordKeyPathStore() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch()
      .addCallback(function(db) {
        return incrementVersion(db, function(ev, db, tx) {
          db.createObjectStore('keyStore', {keyPath: 'key'});
        });
      })
      .addCallback(function(db) {
        var badTx =
            db.createTransaction(['keyStore'], TransactionMode.READ_WRITE);
        return badTx.objectStore('keyStore')
            .put({key: 'diedie', value: 'anything'}, 'badKey')
            .then(
                function() {
                  fail('inserting with explicit key should have failed');
                },
                function(err) {
                  // expected
                  assertEquals(goog.db.Error.ErrorName.DATA_ERR, err.getName());
                });
      });
}

function testPutRecordAutoIncrementStore() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch()
      .addCallback(function(db) {
        return incrementVersion(db, function(ev, db, tx) {
          db.createObjectStore('aiStore', {autoIncrement: true});
        });
      })
      .addCallback(function(db) {
        var tx = db.createTransaction(['aiStore'], TransactionMode.READ_WRITE);
        var putOperation1 = tx.objectStore('aiStore').put('1');
        var putOperation2 = tx.objectStore('aiStore').put('2');
        var putOperation3 = tx.objectStore('aiStore').put('3');
        putOperation1.addCallback(function(key) {
          assertNotUndefined(key);
        });
        putOperation2.addCallback(function(key) {
          assertNotUndefined(key);
        });
        putOperation3.addCallback(function(key) {
          assertNotUndefined(key);
        });
        return transactionToPromise(db, tx);
      })
      .addCallback(function(db) {
        var tx = db.createTransaction(['aiStore']);
        var getAllOperation = tx.objectStore('aiStore').getAll();
        return getAllOperation.addCallback(function(results) {
          assertEquals(3, results.length);
          // only checking to see if the results are included because the keys
          // are not specified
          assertNotEquals(-1, results.indexOf('1'));
          assertNotEquals(-1, results.indexOf('2'));
          assertNotEquals(-1, results.indexOf('3'));
        });
      });
}

function testPutRecordKeyPathAndAutoIncrementStore() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch()
      .addCallback(function(db) {
        return incrementVersion(db, function(ev, db, tx) {
          db.createObjectStore(
              'hybridStore', {keyPath: 'key', autoIncrement: true});
        });
      })
      .addCallback(function(db) {
        var tx =
            db.createTransaction(['hybridStore'], TransactionMode.READ_WRITE);
        var putOperation =
            tx.objectStore('hybridStore').put({value: 'whatever'});
        putOperation.addCallback(function(key) {
          assertNotUndefined(key);
        });
        return putOperation.addCallback(function() {
          return db;
        });
      })
      .addCallback(function(db) {
        var tx = db.createTransaction(['hybridStore']);
        return tx.objectStore('hybridStore').getAll().then(function(results) {
          assertEquals(1, results.length);
          assertEquals('whatever', results[0].value);
          assertNotUndefined(results[0].key);
        });
      });
}

function testPutIllegalRecords() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch().addCallback(addStore).addCallback(function(db) {
    var tx = db.createTransaction(['store'], TransactionMode.READ_WRITE);

    var promises = [];
    var badKeyFail = function(keyKind) {
      return function() {
        return fail('putting with ' + keyKind + ' key should have failed');
      };
    };
    var assertExpectedError = function(err) {
      assertEquals(goog.db.Error.ErrorName.DATA_ERR, err.getName());
    };

    promises.push(
        tx.objectStore('store')
            .put('death', null)
            .then(badKeyFail('null'), assertExpectedError));

    promises.push(
        tx.objectStore('store')
            .put('death', NaN)
            .then(badKeyFail('NaN'), assertExpectedError));

    promises.push(
        tx.objectStore('store')
            .put('death', undefined)
            .then(badKeyFail('undefined'), assertExpectedError));

    return goog.Promise.all(promises);
  });
}

function testPutIllegalRecordsWithIndex() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch()
      .addCallback(addStoreWithIndex)
      .addCallback(function(db) {
        var tx = db.createTransaction(['store'], TransactionMode.READ_WRITE);
        var promises = [];
        var badKeyFail = function(keyKind) {
          return function() {
            fail('putting with ' + keyKind + ' key should have failed');
          };
        };
        var assertExpectedError = function(err) {
          // expected
          assertEquals(goog.db.Error.ErrorName.DATA_ERR, err.getName());
        };

        promises.push(
            tx.objectStore('store')
                .put({value: 'diediedie', key: null})
                .then(badKeyFail('null'), assertExpectedError));

        promises.push(
            tx.objectStore('store')
                .put({value: 'dietodeath', key: NaN})
                .then(badKeyFail('NaN'), assertExpectedError));
        promises.push(
            tx.objectStore('store')
                .put({value: 'dietodeath', key: undefined})
                .then(badKeyFail('undefined'), assertExpectedError));

        return goog.Promise.all(promises);
      });
}

function testDeleteRecord() {
  if (!idbSupported) {
    return;
  }

  var db;
  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(function(openedDb) {
        db = openedDb;
        return db.createTransaction(['store'], TransactionMode.READ_WRITE)
            .objectStore('store')
            .put({key: 'hi', value: 'something'}, 'stuff');
      })
      .addCallback(function() {
        return db.createTransaction(['store'], TransactionMode.READ_WRITE)
            .objectStore('store')
            .remove('stuff');
      })
      .addCallback(function() {
        return db.createTransaction(['store']).objectStore('store').get(
            'stuff');
      })
      .addCallback(function(result) { assertUndefined(result); });
}

function testDeleteRange() {
  if (!idbSupported) {
    return;
  }

  var values = ['1', '2', '3'];
  var keys = ['a', 'b', 'c'];

  var addData = goog.partial(populateStore, values, keys);
  var checkStore = goog.partial(assertStoreValues, ['1']);

  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(addData)
      .addCallback(function(db) {
        return db.createTransaction(['store'], TransactionMode.READ_WRITE)
            .objectStore('store')
            .remove(goog.db.KeyRange.bound('b', 'c'))
            .then(function() {
              return db;
            });
      })
      .addCallback(checkStore);
}

function testGetAll() {
  if (!idbSupported) {
    return;
  }

  var values = ['1', '2', '3'];
  var keys = ['a', 'b', 'c'];

  var addData = goog.partial(populateStore, values, keys);
  var checkStore = goog.partial(assertStoreValues, values);

  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(addData)
      .addCallback(checkStore);
}

function testGetAllKeys() {
  if (!idbSupported) {
    return;
  }

  var values = ['1', '2', '3'];
  var keys = ['a', 'b', 'c'];

  var addData = goog.partial(populateStore, values, keys);
  var checkStore = goog.partial(assertStoreKeyValues, keys);

  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(addData)
      .addCallback(checkStore);
}

function testGetAllFreesCursor() {
  if (!idbSupported) {
    return;
  }
  var values = ['1', '2', '3'];
  var keys = ['a', 'b', 'c'];

  var addData = goog.partial(populateStore, values, keys);
  var origCursor = goog.db.Cursor;
  var cursors = [];
  /** @constructor */
  var testCursor = function() {
    origCursor.call(this);
    cursors.push(this);
  };
  goog.object.extend(testCursor, origCursor);
  // We don't use goog.inherits here because we are going to be overwriting
  // goog.db.Cursor and we don't want a new "base" method as
  // goog.db.Cursor.base(this, 'constructor') would be a call to
  // testCursor.base(this, 'constructor') which would be goog.db.Cursor and be
  // an infinite loop.
  testCursor.prototype = origCursor.prototype;
  propertyReplacer.replace(goog.db, 'Cursor', testCursor);
  var checkStoreAndCursorDisposed =
      goog.partial(assertStoreValuesAndCursorsDisposed, values, cursors);

  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(addData)
      .addCallback(checkStoreAndCursorDisposed);
}

function testObjectStoreCursorGet() {
  if (!idbSupported) {
    return;
  }

  var values = ['1', '2', '3', '4'];
  var keys = ['a', 'b', 'c', 'd'];

  var addData = goog.partial(populateStore, values, keys);
  var db;

  var resultValues = [];
  var resultKeys = [];
  // Open the cursor over range ['b', 'c'], move in backwards direction.
  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(addData)
      .addCallback(function(theDb) {
        db = theDb;
        var cursorTx = db.createTransaction(['store']);
        var store = cursorTx.objectStore('store');

        var cursor = store.openCursor(
            goog.db.KeyRange.bound('b', 'c'), goog.db.Cursor.Direction.PREV);

        var whenCursorComplete = forEachRecord(cursor, function() {
          resultValues.push(cursor.getValue());
          resultKeys.push(cursor.getKey());
          cursor.next();
        });

        return goog.Promise.all([cursorTx.wait(), whenCursorComplete]);
      })
      .addCallback(function() {
        assertArrayEquals(['3', '2'], resultValues);
        assertArrayEquals(['c', 'b'], resultKeys);
      });
}

function testObjectStoreCursorReplace() {
  if (!idbSupported) {
    return;
  }

  var values = ['1', '2', '3', '4'];
  var keys = ['a', 'b', 'c', 'd'];

  var addData = goog.partial(populateStore, values, keys);

  // Store should contain ['1', '2', '5', '4'] after replacement.
  var checkStore = goog.partial(assertStoreValues, ['1', '2', '5', '4']);

  // Use a bounded cursor for ('b', 'c'] to update value '3' -> '5'.
  var openCursorAndReplace = function(db) {
    var cursorTx = db.createTransaction(['store'], TransactionMode.READ_WRITE);
    var store = cursorTx.objectStore('store');

    var cursor = store.openCursor(goog.db.KeyRange.bound('b', 'c', true));
    var whenCursorComplete = forEachRecord(cursor, function() {
      assertEquals('3', cursor.getValue());
      return cursor.update('5').addCallback(function() { cursor.next(); });
    });

    return goog.Promise.all([cursorTx.wait(), whenCursorComplete])
        .then(function() { return db; });
  };

  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(addData)
      .addCallback(openCursorAndReplace)
      .addCallback(checkStore);
}

function testObjectStoreCursorRemove() {
  if (!idbSupported) {
    return;
  }

  var values = ['1', '2', '3', '4'];
  var keys = ['a', 'b', 'c', 'd'];

  var addData = goog.partial(populateStore, values, keys);

  // Store should contain ['1', '2'] after removing elements.
  var checkStore = goog.partial(assertStoreValues, ['1', '2']);

  // Use a bounded cursor for ('b', ...) to remove '3', '4'.
  var openCursorAndRemove = function(db) {
    var cursorTx = db.createTransaction(['store'], TransactionMode.READ_WRITE);

    var store = cursorTx.objectStore('store');
    var cursor = store.openCursor(goog.db.KeyRange.lowerBound('b', true));
    var whenCursorComplete = forEachRecord(cursor, function() {
      return cursor.remove('5').addCallback(function() { cursor.next(); });
    });
    return goog.Promise.all([cursorTx.wait(), whenCursorComplete])
        .then(function(results) { return db; });
  };

  // Setup and execute test case.
  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(addData)
      .addCallback(openCursorAndRemove)
      .addCallback(checkStore);
}

function testClear() {
  if (!idbSupported) {
    return;
  }

  var db;
  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(function(theDb) {
        db = theDb;

        var putTx = db.createTransaction(['store'], TransactionMode.READ_WRITE);
        putTx.objectStore('store').put('1', 'a');
        putTx.objectStore('store').put('2', 'b');
        putTx.objectStore('store').put('3', 'c');
        return putTx.wait();
      })
      .addCallback(function() {
        return db.createTransaction(['store']).objectStore('store').getAll();
      })
      .addCallback(function(results) {
        assertEquals(3, results.length);
        return db.createTransaction(['store'], TransactionMode.READ_WRITE)
            .objectStore('store')
            .clear();
      })
      .addCallback(function() {
        return db.createTransaction(['store']).objectStore('store').getAll();
      })
      .addCallback(function(results) { assertEquals(0, results.length); });
}

function testAbortTransaction() {
  if (!idbSupported) {
    return;
  }

  var db;
  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(function(theDb) {
        db = theDb;
        return new Promise(function(resolve, reject) {
          var abortTx =
              db.createTransaction(['store'], TransactionMode.READ_WRITE);
          abortTx.objectStore('store')
              .put('data', 'stuff')
              .addCallback(function() { abortTx.abort(); });
          goog.events.listen(abortTx, EventTypes.ERROR, reject);

          goog.events.listen(abortTx, EventTypes.COMPLETE, function() {
            fail(
                'transaction shouldn\'t have' +
                ' completed after being aborted');
          });

          goog.events.listen(abortTx, EventTypes.ABORT, resolve);
        });
      })
      .addCallback(function() {
        var checkResultsTx = db.createTransaction(['store']);
        return checkResultsTx.objectStore('store').get('stuff');
      })
      .addCallback(function(result) { assertUndefined(result); });
}

function testInactiveTransaction() {
  if (!idbSupported) {
    return;
  }

  var db;
  var store;
  var index;
  var createAndFinishTransaction = function(theDb) {
    db = theDb;
    var tx = db.createTransaction(['store'], TransactionMode.READ_WRITE);
    store = tx.objectStore('store');
    index = store.getIndex('index');
    store.put({key: 'something', value: 'anything'});
    return tx.wait();
  };

  var assertCantUseInactiveTransaction = function() {
    var expectedCode = goog.db.Error.ErrorName.TRANSACTION_INACTIVE_ERR;
    var promises = [];

    var failOp = function(op) {
      return function() {
        fail(op + ' with inactive transaction should have failed');
      };
    };
    var assertCorrectError = function(err) {
      assertEquals(expectedCode, err.getName());
    };
    promises.push(
        store.put({key: 'another', value: 'thing'})
            .then(failOp('putting'), assertCorrectError));
    promises.push(
        store.add({key: 'another', value: 'thing'})
            .then(failOp('adding'), assertCorrectError));
    promises.push(
        store.remove('something').then(failOp('deleting'), assertCorrectError));
    promises.push(
        store.get('something').then(failOp('getting'), assertCorrectError));
    promises.push(
        store.getAll().then(failOp('getting all'), assertCorrectError));
    promises.push(
        store.clear().then(failOp('clearing all'), assertCorrectError));

    promises.push(
        index.get('anything')
            .then(failOp('getting from index'), assertCorrectError));
    promises.push(
        index.getKey('anything')
            .then(failOp('getting key from index'), assertCorrectError));
    promises.push(
        index.getAll('anything')
            .then(failOp('getting all from index'), assertCorrectError));
    promises.push(
        index.getAllKeys('anything')
            .then(failOp('getting all keys from index'), assertCorrectError));
    return goog.Promise.all(promises);
  };

  return globalDb.branch()
      .addCallback(addStoreWithIndex)
      .addCallback(createAndFinishTransaction)
      .addCallback(assertCantUseInactiveTransaction);
}

function testWrongTransactionMode() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch().addCallback(addStore).addCallback(function(db) {
    var tx = db.createTransaction(['store']);
    assertEquals(goog.db.Transaction.TransactionMode.READ_ONLY, tx.getMode());
    var promises = [];
    promises.push(
        tx.objectStore('store')
            .put('KABOOM!', 'anything')
            .then(
                function() { fail('putting should have failed'); },
                function(err) {
                  assertEquals(
                      goog.db.Error.ErrorName.READ_ONLY_ERR, err.getName());
                }));
    promises.push(
        tx.objectStore('store')
            .add('EXPLODE!', 'die')
            .then(
                function() { fail('adding should have failed'); },
                function(err) {
                  assertEquals(
                      goog.db.Error.ErrorName.READ_ONLY_ERR, err.getName());
                }));
    promises.push(
        tx.objectStore('store')
            .remove('no key', 'nothing')
            .then(
                function() { fail('deleting should have failed'); },
                function(err) {
                  assertEquals(
                      goog.db.Error.ErrorName.READ_ONLY_ERR, err.getName());
                }));
    return goog.Promise.all(promises);
  });
}

function testManipulateIndexes() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch()
      .addCallback(function(db) {
        return incrementVersion(db, function(ev, db, tx) {
          var store = db.createObjectStore('store');
          store.createIndex('index', 'attr1');
          store.createIndex('uniqueIndex', 'attr2', {unique: true});
          store.createIndex('multirowIndex', 'attr3', {multirow: true});
        });
      })
      .addCallback(function(db) {
        var tx = db.createTransaction(['store']);
        var store = tx.objectStore('store');
        var index = store.getIndex('index');
        var uniqueIndex = store.getIndex('uniqueIndex');
        var multirowIndex = store.getIndex('multirowIndex');
        try {
          var dies = store.getIndex('diediedie');
          fail('getting non-existent index should have failed');
        } catch (err) {
          // expected
          assertEquals(goog.db.Error.ErrorName.NOT_FOUND_ERR, err.getName());
        }

        return tx.wait();
      })
      .addCallback(function(db) {
        return incrementVersion(db, function(ev, db, tx) {
          var store = tx.objectStore('store');
          store.deleteIndex('index');
          try {
            store.deleteIndex('diediedie');
            fail('deleting non-existent index should have failed');
          } catch (err) {
            // expected
            assertEquals(goog.db.Error.ErrorName.NOT_FOUND_ERR, err.getName());
          }
        });
      })
      .addCallback(function(db) {
        var tx = db.createTransaction(['store']);
        var store = tx.objectStore('store');
        try {
          var index = store.getIndex('index');
          fail('getting deleted index should have failed');
        } catch (err) {
          // expected
          assertEquals(goog.db.Error.ErrorName.NOT_FOUND_ERR, err.getName());
        }
        var uniqueIndex = store.getIndex('uniqueIndex');
        var multirowIndex = store.getIndex('multirowIndex');
      });
}

function testAddRecordWithIndex() {
  if (!idbSupported) {
    return;
  }

  var addData = function(db) {
    var store = db.createTransaction(['store'], TransactionMode.READ_WRITE)
                    .objectStore('store');
    assertFalse(store.getIndex('index').isUnique());
    assertEquals('value', store.getIndex('index').getKeyPath());
    return store.add({key: 'someKey', value: 'lookUpThis'})
        .addCallback(function() { return db; });
  };
  var readAndAssertAboutData = function(db) {
    var index =
        db.createTransaction(['store']).objectStore('store').getIndex('index');
    var promises = [
      index.get('lookUpThis').addCallback(function(result) {
        assertNotUndefined(result);
        assertEquals('someKey', result.key);
        assertEquals('lookUpThis', result.value);
      }),
      index.getKey('lookUpThis').addCallback(function(result) {
        assertNotUndefined(result);
        assertEquals('someKey', result);
      })
    ];
    return goog.Promise.all(promises).then(function() { return db; });
  };
  return globalDb.branch()
      .addCallback(addStoreWithIndex)
      .addCallback(addData)
      .addCallback(readAndAssertAboutData);
}

function testGetMultipleRecordsFromIndex() {
  if (!idbSupported) {
    return;
  }

  var addData = function(db) {
    var addTx = db.createTransaction(['store'], TransactionMode.READ_WRITE);
    addTx.objectStore('store').add({key: '1', value: 'a'});
    addTx.objectStore('store').add({key: '2', value: 'a'});
    addTx.objectStore('store').add({key: '3', value: 'b'});

    return addTx.wait();
  };
  var readData = function(db) {
    var index =
        db.createTransaction(['store']).objectStore('store').getIndex('index');
    var promises = [];
    promises.push(index.getAll().addCallback(function(results) {
      assertNotUndefined(results);
      assertEquals(3, results.length);
    }));
    promises.push(index.getAll('a').addCallback(function(results) {
      assertNotUndefined(results);
      assertEquals(2, results.length);
    }));
    promises.push(index.getAllKeys().addCallback(function(results) {
      assertNotUndefined(results);
      assertEquals(3, results.length);
      assertArrayEquals(['1', '2', '3'], results);
    }));
    promises.push(index.getAllKeys('b').addCallback(function(results) {
      assertNotUndefined(results);
      assertEquals(1, results.length);
      assertArrayEquals(['3'], results);
    }));

    return goog.Promise.all(promises).then(function() { return db; });
  };
  return globalDb.branch()
      .addCallback(addStoreWithIndex)
      .addCallback(addData)
      .addCallback(readData);
}

function testUniqueIndex() {
  if (!idbSupported) {
    return;
  }

  var storeDuplicatesToUniqueIndex = function(db) {
    var tx = db.createTransaction(['store'], TransactionMode.READ_WRITE);
    assertTrue(tx.objectStore('store').getIndex('index').isUnique());
    tx.objectStore('store').add({key: '1', value: 'a'});
    tx.objectStore('store').add({key: '2', value: 'a'});
    return transactionToPromise(db, tx).then(
        function() {
          fail('Expected transaction violating unique constraint to fail');
        },
        function(ev) {
          // expected
          assertEquals(
              goog.db.Error.ErrorName.CONSTRAINT_ERR, ev.target.getName());
        });
  };

  return globalDb.branch()
      .addCallback(function(db) {
        return incrementVersion(db, function(ev, db, tx) {
          var store = db.createObjectStore('store', {keyPath: 'key'});
          store.createIndex('index', 'value', {unique: true});
        });
      })
      .addCallback(storeDuplicatesToUniqueIndex);
}

function testDeleteDatabase() {
  if (!idbSupported) {
    return;
  }

  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(function(db) {
        db.close();
        return goog.db.deleteDatabase(dbName, function() {
          fail('didn\'t expect deleteDatabase to be blocked');
        });
      })
      .addCallback(openDatabase)
      .addCallback(assertStoreDoesntExist);
}

function testDeleteDatabaseIsBlocked() {
  if (!idbSupported) {
    return;
  }

  var wasBlocked = false;
  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(function(db) {
        db.close();
        // Get a fresh connection, without any events registered on globalDb.
        return goog.db.openDatabase(dbName);
      })
      .addCallback(function(db) {
        dbsToClose.push(db);
        return goog.db.deleteDatabase(dbName, function(ev) {
          wasBlocked = true;
          db.close();
        });
      })
      .addCallback(function() {
        assertTrue(wasBlocked);
        return openDatabase();
      })
      .addCallback(assertStoreDoesntExist);
}

function testBlockedDeleteDatabaseWithVersionChangeEvent() {
  if (!idbSupported) {
    return;
  }

  var gotVersionChange = false;
  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(function(db) {
        db.close();
        // Get a fresh connection, without any events registered on globalDb.
        return goog.db.openDatabase(dbName);
      })
      .addCallback(function(db) {
        dbsToClose.push(db);
        goog.events.listen(
            db, goog.db.IndexedDb.EventType.VERSION_CHANGE, function(ev) {
              gotVersionChange = true;
              db.close();
            });
        return goog.db.deleteDatabase(dbName);
      })
      .addCallback(function() {
        assertTrue(gotVersionChange);
        return openDatabase();
      })
      .addCallback(assertStoreDoesntExist);
}

function testDeleteNonExistentDatabase() {
  if (!idbSupported) {
    return;
  }

  // Deleting non-existent db is a no-op.  Shall not throw anything.
  return globalDb.branch().addCallback(function(db) {
    db.close();
    return goog.db.deleteDatabase('non-existent-db');
  });
}

function testObjectStoreCountAll() {
  if (!idbSupported) {
    return;
  }

  var values = ['1', '2', '3', '4'];
  var keys = ['a', 'b', 'c', 'd'];

  var addData = goog.partial(populateStore, values, keys);

  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(addData)
      .addCallback(function(db) {
        var tx = db.createTransaction(['store']);
        return tx.objectStore('store').count().addCallback(function(count) {
          assertEquals(values.length, count);
        });
      });
}

function testObjectStoreCountSome() {
  if (!idbSupported) {
    return;
  }

  var values = ['1', '2', '3', '4'];
  var keys = ['a', 'b', 'c', 'd'];

  var addData = goog.partial(populateStore, values, keys);
  var countData = function(db) {
    var tx = db.createTransaction(['store']);
    return tx.objectStore('store')
        .count(goog.db.KeyRange.bound('b', 'c'))
        .addCallback(function(count) { assertEquals(2, count); });
  };

  return globalDb.branch()
      .addCallback(addStore)
      .addCallback(addData)
      .addCallback(countData);
}

function testIndexCursorGet() {
  if (!idbSupported) {
    return;
  }

  var values = ['1', '2', '3', '4'];
  var keys = ['a', 'b', 'c', 'd'];
  var addData = goog.partial(populateStoreWithObjects, values, keys);

  var valuesResult = [];
  var keysResult = [];

  // Open the cursor over range ['b', 'c'], move in backwards direction.
  var walkBackwardsOverCursor = function(db) {
    var cursorTx = db.createTransaction(['store']);
    var index = cursorTx.objectStore('store').getIndex('index');
    var values = [];
    var keys = [];

    var cursor = index.openCursor(
        goog.db.KeyRange.bound('2', '3'), goog.db.Cursor.Direction.PREV);
    var cursorFinished = forEachRecord(cursor, function() {
      valuesResult.push(cursor.getValue()['value']);
      keysResult.push(cursor.getValue()['key']);
      cursor.next();
    });

    return goog.Promise.all([cursorFinished, cursorTx.wait()]).then(function() {
      return db;
    });
  };

  return globalDb.branch()
      .addCallbacks(addStoreWithIndex)
      .addCallback(addData)
      .addCallback(walkBackwardsOverCursor)
      .addCallback(function(db) {
        assertArrayEquals(['3', '2'], valuesResult);
        assertArrayEquals(['c', 'b'], keysResult);
      });
}

function testIndexCursorReplace() {
  if (!idbSupported) {
    return;
  }

  var values = ['1', '2', '3', '4'];
  var keys = ['a', 'b', 'c', 'd'];

  var addData = goog.partial(populateStoreWithObjects, values, keys);
  var valuesResult = [];
  var keysResult = [];

  // Store should contain ['1', '2', '5', '4'] after replacement.
  var checkStore = goog.partial(assertStoreObjectValues, ['1', '2', '5', '4']);

  // Use a bounded cursor for ['3', '4') to update value '3' -> '5'.
  var openCursorAndReplace = function(db) {
    var cursorTx = db.createTransaction(['store'], TransactionMode.READ_WRITE);
    var index = cursorTx.objectStore('store').getIndex('index');
    var cursor =
        index.openCursor(goog.db.KeyRange.bound('3', '4', false, true));

    var cursorFinished = forEachRecord(cursor, function() {
      assertEquals('3', cursor.getValue()['value']);
      return cursor.update({'key': cursor.getValue()['key'], 'value': '5'})
          .addCallback(function() { cursor.next(); });
    });

    return goog.Promise.all([cursorFinished, cursorTx.wait()])
        .then(function(results) { return db; });
  };

  // Setup and execute test case.
  return globalDb.branch()
      .addCallback(addStoreWithIndex)
      .addCallback(addData)
      .addCallback(openCursorAndReplace)
      .addCallback(checkStore);
}

function testIndexCursorRemove() {
  if (!idbSupported) {
    return;
  }

  var values = ['1', '2', '3', '4'];
  var keys = ['a', 'b', 'c', 'd'];

  var addData = goog.partial(populateStoreWithObjects, values, keys);

  // Store should contain ['1', '2'] after removing elements.
  var checkStore = goog.partial(assertStoreObjectValues, ['1', '2']);

  // Use a bounded cursor for ('2', ...) to remove '3', '4'.
  var openCursorAndRemove = function(db) {
    var cursorTx = db.createTransaction(['store'], TransactionMode.READ_WRITE);

    var store = cursorTx.objectStore('store');
    var index = store.getIndex('index');
    var cursor = index.openCursor(goog.db.KeyRange.lowerBound('2', true));
    var cursorFinished = forEachRecord(cursor, function() {
      return cursor.remove('5').addCallback(function() { cursor.next(); });
    });

    return goog.Promise.all([cursorFinished, cursorTx.wait()])
        .then(function(results) { return db; });
  };

  // Setup and execute test case.
  return globalDb.branch()
      .addCallback(addStoreWithIndex)
      .addCallback(addData)
      .addCallback(openCursorAndRemove)
      .addCallback(checkStore);
}

function testCanWaitForTransactionToComplete() {
  if (!idbSupported) {
    return;
  }
  return globalDb.branch().addCallback(addStore).addCallback(function(db) {
    var tx = db.createTransaction(['store'], TransactionMode.READ_WRITE);
    tx.objectStore('store').add({key: 'hi', value: 'something'}, 'stuff');
    return tx.wait();
  });
}

function testWaitingOnTransactionThatHasAnError() {
  if (!idbSupported) {
    return;
  }
  return globalDb.branch()
      .addCallback(function(db) {
        return incrementVersion(db, function(ev, db, tx) {
          var store = db.createObjectStore('store', {keyPath: 'key'});
          store.createIndex('index', 'value', {unique: true});
        });
      })
      .addCallback(function(db) {
        var tx = db.createTransaction(['store'], TransactionMode.READ_WRITE);
        assertTrue(tx.objectStore('store').getIndex('index').isUnique());
        tx.objectStore('store').add({key: '1', value: 'a'});
        tx.objectStore('store').add({key: '2', value: 'a'});
        return transactionToPromise(db, tx).then(
            function() { fail('expected transaction to fail'); },
            function(ev) {
              // expected
              assertEquals(
                  goog.db.Error.ErrorName.CONSTRAINT_ERR, ev.target.getName());
            });
      });
}

function testWaitingOnAnAbortedTransaction() {
  if (!idbSupported) {
    return;
  }
  return globalDb.addCallback(addStore).addCallback(function(db) {
    var tx = db.createTransaction(['store'], TransactionMode.READ_WRITE);
    var waiting = tx.wait().then(
        function() { fail('Wait result should have failed'); },
        function(e) {
          assertEquals(goog.db.Error.ErrorName.ABORT_ERR, e.getName());
        });
    tx.abort();
    return waiting;
  });
}


text:
import urllib
import urllib2
import csv
import random

base_url="http://spapi.pixiv.net/"
attributes=['id', 'artist_id', 'format', 'title', 'img_folder', 'artist_name',
            'thumbnail_url', '', '', 'preview_url', '', '', 'upload_time', 'tags',
            'application', 'ratings', 'total_rating', 'views', 'description',
            'novel_pages', '', '', '', '', 'artist_nickname', '', '', '',
            '', 'artist_avatar_url', '']

class Work:
    def __init__(self,line):
        self.line=line
        for i in range(len(line)):
            if attributes[i]=='' : continue
            else: setattr(self,attributes[i],line[i])
        self.img_folder=self.img_folder.zfill(2)

    def get_full_url(self,page=None):
        single_fmt="http://i{}.pixiv.net/img{}/img/{}/{}.{}"
        if int(self.id)>11320000: #ID 11320066 uses new URL, 11319887 uses old URL, 11319948 uses old URL, but site thinks it uses new URL.
            novel_fmt="http://i{}.pixiv.net/img{}/img/{}/{}_big_p{}.{}"
        else:
            novel_fmt="http://i{}.pixiv.net/img{}/img/{}/{}_p{}.{}"
        if len(self.preview_url.split('/')[-1].split('_'))==3:
            private_salt=self.preview_url.split('/')[-1].split('_')[1]
            work_id="{}_{}".format(self.id,private_salt)
        else:
            work_id=self.id

        if page==None:
            return single_fmt.format(random.choice([1,2]),self.img_folder,self.artist_nickname,work_id,self.format)
        else:
            return novel_fmt.format(random.choice([1,2]),self.img_folder,self.artist_nickname,work_id,page,self.format)

    def get_files(self):
        files=[]
        if self.novel_pages=='':
            request=urllib2.Request(self.get_full_url(),headers={'Referer': "http://www.pixiv.net/"})
            files.append(request)
        else:
            for i in range(int(self.novel_pages)):
                request=urllib2.Request(self.get_full_url(i),headers={'Referer': "http://www.pixiv.net/"})
                files.append(request)
        return files

class Pixiv:
    def __init__(self,session_id=''):
        self.set_session_id(session_id)

    def set_session_id(self,session_id=''):
        self.session_id=session_id

    def make_request(self,url,query={}):
        query["PHPSESSID"]=self.session_id
        query_string=urllib.urlencode(query)
        url=base_url+url+"?"+query_string
        return urllib2.urlopen(url)

    def get_works_page(self,member_id,page=1):
        query={
            'id': member_id,
            'p': page,
        }
        data=self.make_request("iphone/member_illust.php",query)
        lines=csv.reader(data)
        works=[]
        for line in lines:
            works.append(Work(line))
        return works

    def get_works_all(self,member_id):
        page=1
        works=[]
        while True:
            current_works=self.get_works_page(member_id,page)
            if len(current_works)==0: break
            works.extend(current_works)
            page+=1
        return works

    def get_tagged(self, tag, page=1):
        query={
            'tag': tag,
            'p': page,
        }
        data=self.make_request("iphone/tags.php",query)
        if data=="": return False
        lines=csv.reader(data)
        works=[]
        for line in lines:
            works.append(Work(line))
        return works

    def get_tagged_all(self, tag):
        page = 1
        while True:
            works = self.get_tagged(tag, page)
            if works:
                yield works
                page+=1
            else:
                break