text:
using System;
using System.Collections.Generic;
using System.Web;
using System.Data;
using System.Diagnostics;
using Senparc.Weixin.MP;
using Senparc.Weixin.MP.Entities;

namespace DTcms.API.Weixin.Common
{
    /// <summary>
    /// 处理事件的方法
    /// </summary>
    public partial class MessageFunction
    {
        Model.siteconfig siteConfig = new BLL.siteconfig().loadConfig(); //站点配置

        #region 处理关注/取消/默认回复方法===========================
        /// <summary>
        /// 定阅事件的统一处理
        /// </summary>
        public IResponseMessageBase EventSubscribe(int type, RequestMessageEventBase requestMessage)
        {
            string EventName = "";

            if (requestMessage.Event.ToString().Trim() != "")
            {
                EventName = requestMessage.Event.ToString();
            }
            else if (requestMessage.EventKey != null)
            {
                EventName += requestMessage.EventKey.ToString();
            }

            if (!ExistsOriginalId(requestMessage.ToUserName))
            {
                //验证接收方是否为我们系统配置的帐号,即验证微帐号与微信原始帐号id是否一致,如果不一致,说明【1】配置错误,【2】数据来源有问题
                new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), EventName, "none", "未取到关键词对应的数据", requestMessage.ToUserName);
                return GetResponseMessageTxtByContent(requestMessage, "验证微帐号与微信原始帐号id不一致,可能原因【1】系统配置错误,【2】非法的数据来源");
            }

            int responseType = 0;
            int ruleId = new BLL.weixin_request_rule().GetRuleIdAndResponseType("request_type=" + type, out responseType);
            if (ruleId <= 0 || responseType <= 0)
            {
                new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), EventName, "none", "未取到关键词对应的数据", requestMessage.ToUserName);
                return null;
            }

            IResponseMessageBase reponseMessage = null;
            switch (responseType)
            {
                case 1:
                    //发送纯文字
                    reponseMessage = GetResponseMessageTxt(requestMessage, ruleId);
                    break;
                case 2:
                    //发送多图文
                    reponseMessage = GetResponseMessageNews(requestMessage, ruleId);
                    break;
                case 3:
                    //发送语音
                    reponseMessage = GetResponseMessageeMusic(requestMessage, ruleId);
                    break;
                default:
                    break;
            }
            return reponseMessage;
        }
        #endregion

        #region 请求为文本的处理=====================================
        /// <summary>
        /// 推送纯文字
        /// </summary>
        public IResponseMessageBase GetResponseMessageTxt(RequestMessageText requestMessage, int ruleId)
        {
            var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(requestMessage);
            string openid = requestMessage.FromUserName;
            string token = ConvertDateTimeInt(DateTime.Now).ToString();
            responseMessage.Content = new BLL.weixin_request_content().GetContent(ruleId);
            new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), requestMessage.Content, "text", responseMessage.Content, requestMessage.ToUserName);
            return responseMessage;
        }

        /// <summary>
        /// 推送纯文字
        /// </summary>
        public IResponseMessageBase GetResponseMessageTxtByContent(RequestMessageText requestMessage, string content)
        {
            var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(requestMessage);
            responseMessage.Content = content;
            new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), requestMessage.Content, "text", "文字请求,推送纯粹文字,内容为:" + content, requestMessage.ToUserName);
            return responseMessage;
        }

        /// <summary>
        /// 处理语音请求
        /// </summary>
        public IResponseMessageBase GetResponseMessageeMusic(RequestMessageText requestMessage, int ruleId)
        {
            string EventName = "";
            var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageMusic>(requestMessage);
            Model.weixin_request_content model = new BLL.weixin_request_content().GetModel(ruleId);
            if (model == null)
            {
                new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), EventName, "music", "-1", requestMessage.ToUserName);
            }
            else
            {
                if (model.media_url.Contains("http://"))
                {
                    responseMessage.Music.MusicUrl = model.media_url;

                }
                else
                {
                    //因为安装目录是以/开头,所以去掉,以免出现双斜杆
                    responseMessage.Music.MusicUrl = siteConfig.weburl + "/" + siteConfig.webpath.Replace("/", "") + model.media_url;
                }
                responseMessage.Music.Title = model.title;
                responseMessage.Music.Description = model.content;
                new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), EventName, "music", "音乐链接:" + model.media_url + "|标题:" + model.title + "|描述:" + model.content, requestMessage.ToUserName);

            }
            return responseMessage;
        }

        /// <summary>
        /// 推送多图文
        /// </summary>
        public IResponseMessageBase GetResponseMessageNews(RequestMessageText requestMessage, int ruleId)
        {
            var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageNews>(requestMessage);
            string openid = requestMessage.FromUserName;
            string token = ConvertDateTimeInt(DateTime.Now).ToString();

            Article article;
            List<Article> artList = new List<Article>();
            IList<Model.weixin_request_content> twList = new BLL.weixin_request_content().GetModelList(10, ruleId, string.Empty);
            foreach (Model.weixin_request_content modelt in twList)
            {
                article = new Article();
                article.Title = modelt.title;
                article.Description = modelt.content;
                article.Url = GetWXApiUrl(modelt.link_url, token, openid);
                if (string.IsNullOrEmpty(modelt.img_url))
                {
                    article.PicUrl = string.Empty;
                }
                else
                {
                    if (modelt.img_url.Contains("http://"))
                    {
                        article.PicUrl = modelt.img_url;

                    }
                    else
                    {
                        //因为安装目录是以/开头,所以去掉,以免出现双斜杆
                        article.PicUrl = siteConfig.weburl + "/" + siteConfig.webpath.Replace("/", "") + modelt.img_url;
                    }
                }
                artList.Add(article);
            }

            if (artList.Count == 0)
            {
                new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), requestMessage.Content, "txtpic", "-1", requestMessage.ToUserName);
            }
            else
            {
                new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), requestMessage.Content, "txtpic", "这次发了" + artList.Count + "条图文", requestMessage.ToUserName);
            }
            responseMessage.Articles.AddRange(artList);
            return responseMessage;
        }
        #endregion

        #region 请求为事件的处理=====================================
        /// <summary>
        /// 推送纯文字
        /// </summary>
        public IResponseMessageBase GetResponseMessageTxt(RequestMessageEventBase requestMessage, int ruleId)
        {
            var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(requestMessage);
            string openid = requestMessage.FromUserName;
            string token = ConvertDateTimeInt(DateTime.Now).ToString();
            responseMessage.Content = new BLL.weixin_request_content().GetContent(ruleId);

            string EventName = "";
            if (requestMessage.Event.ToString().Trim() != "")
            {
                EventName = requestMessage.Event.ToString();
            }
            else if (requestMessage.EventKey != null)
            {
                EventName += requestMessage.EventKey.ToString();
            }

            new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), EventName, "text", responseMessage.Content, requestMessage.ToUserName);

            return responseMessage;
        }

        /// <summary>
        /// 推送纯文字
        /// </summary>
        public IResponseMessageBase GetResponseMessageTxtByContent(RequestMessageEventBase requestMessage, string content)
        {
            var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(requestMessage);
            var locationService = new LocationService();
            responseMessage.Content = content;
            string EventName = "";
            if (requestMessage.Event.ToString().Trim() != "")
            {
                EventName = requestMessage.Event.ToString();
            }
            else if (requestMessage.EventKey != null)
            {
                EventName += requestMessage.EventKey.ToString();
            }
            new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), EventName, "text", "事件:推送纯粹的文字,内容为:" + content, requestMessage.ToUserName);

            return responseMessage;
        }

        /// <summary>
        /// 处理语音请求
        /// </summary>
        public IResponseMessageBase GetResponseMessageeMusic(RequestMessageEventBase requestMessage, int ruleId)
        {
            var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageMusic>(requestMessage);
            string EventName = "";
            if (requestMessage.Event.ToString().Trim() != "")
            {
                EventName = requestMessage.Event.ToString();
            }
            else if (requestMessage.EventKey != null)
            {
                EventName += requestMessage.EventKey.ToString();
            }

            Model.weixin_request_content model = new BLL.weixin_request_content().GetModel(ruleId);
            if (model == null)
            {

                new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), EventName, "music", "-1", requestMessage.ToUserName);
            }
            else
            {
                if (model.media_url.Contains("http://"))
                {
                    responseMessage.Music.MusicUrl = model.media_url;

                }
                else
                {
                    //因为安装目录是以/开头,所以去掉,以免出现双斜杆
                    responseMessage.Music.MusicUrl = siteConfig.weburl + "/" + siteConfig.webpath.Replace("/", "") + model.media_url;
                }
                responseMessage.Music.Title = model.title;
                responseMessage.Music.Description = model.content;
                new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), EventName, "music", "音乐链接:" + model.media_url + "|标题:" + model.title + "|描述:" + model.content, requestMessage.ToUserName);
            }
            return responseMessage;
        }

        /// <summary>
        /// 推送多图文
        /// </summary>
        public IResponseMessageBase GetResponseMessageNews(RequestMessageEventBase requestMessage, int ruleId)
        {
            var responseMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageNews>(requestMessage);
            string openid = requestMessage.FromUserName;
            string token = ConvertDateTimeInt(DateTime.Now).ToString();

            Article article;
            List<Article> artList = new List<Article>();
            IList<Model.weixin_request_content> twList = new BLL.weixin_request_content().GetModelList(10, ruleId, string.Empty);
            foreach (Model.weixin_request_content modelt in twList)
            {
                article = new Article();
                article.Title = modelt.title;
                article.Description = modelt.content;
                article.Url = GetWXApiUrl(modelt.link_url, token, openid);
                if (string.IsNullOrEmpty(modelt.img_url))
                {
                    article.PicUrl = string.Empty;
                }
                else
                {
                    if (modelt.img_url.Contains("http://"))
                    {
                        article.PicUrl = modelt.img_url;

                    }
                    else
                    {
                        //因为安装目录是以/开头,所以去掉,以免出现双斜杆
                        article.PicUrl = siteConfig.weburl + "/" + siteConfig.webpath.Replace("/", "") + modelt.img_url;
                    }
                }
                artList.Add(article);
            }

            string EventName = "";
            if (requestMessage.Event.ToString().Trim() != "")
            {
                EventName = requestMessage.Event.ToString();
            }
            else if (requestMessage.EventKey != null)
            {
                EventName += requestMessage.EventKey.ToString();
            }

            if (artList.Count == 0)
            {
                new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), EventName, "txtpic", "-1", requestMessage.ToUserName);
            }
            else
            {
                new BLL.weixin_response_content().Add(requestMessage.FromUserName, requestMessage.MsgType.ToString(), EventName, "txtpic", "这次发了" + artList.Count + "条图文", requestMessage.ToUserName);
            }
            responseMessage.Articles.AddRange(artList);
            return responseMessage;
        }
        #endregion

        #region 获取验证公众账户ID===================================
        /// <summary>
        /// 验证公众账户原始ID是否一致
        /// </summary>
        public bool ExistsOriginalId(string originalId)
        {
            return new BLL.weixin_account().ExistsOriginalId(originalId);
        }
        #endregion

        #region 常用的方法封装=======================================
        /// <summary>
        /// 拼接微信URL地址参数
        /// </summary>
        public string GetWXApiUrl(string url, string token, string openid)
        {
            if (url.Contains("?"))
            {
                return url + "&token=" + token + "&openid=" + openid;
            }
            return url + "?token=" + token + "&openid=" + openid;
        }

        /// <summary>
        /// 设置微信url地址的后缀
        /// </summary>
        /// <returns></returns>
        public string GetWxUrlSuffix()
        {
            return "wxref=mp.weixin.qq.com";
        }

        /// <summary>
        /// DateTime时间格式转换为Unix时间戳格式
        /// </summary>
        public long ConvertDateTimeInt(System.DateTime time)
        {
            long intResult = 0;
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            intResult = (long)(time - startTime).TotalSeconds;
            return intResult;
        }
        #endregion
    }
}


text:
from google.appengine.ext import db

class Files(db.Model):
    photo = db.BlobProperty()
    string = db.StringProperty()

redpajama_set_name: RedPajamaGithub


text:
require_relative '../../spec_helper'
require_lib 'reek/spec'

RSpec.describe Reek::Spec::ShouldReekOnlyOf do
  let(:examiner) { instance_double(Reek::Examiner).as_null_object }
  let(:expected_context_name) { 'SmellyClass#big_method' }
  let(:expected_smell_type) { :NestedIterators }
  let(:matcher) { described_class.new(expected_smell_type) }
  let(:matcher_matches) { matcher.matches_examiner?(examiner) }

  before do
    allow(examiner).to receive(:smells) { smells }
    matcher_matches
  end

  shared_examples_for 'no match' do
    it 'does not match' do
      expect(matcher_matches).to be_falsey
    end

    context 'when a match was expected' do
      let(:source) { 'the_path/to_a/source_file.rb' }

      before { allow(examiner).to receive(:origin).and_return(source) }

      it 'reports the source' do
        expect(matcher.failure_message).to match(source)
      end

      it 'reports the expected smell class' do
        expect(matcher.failure_message).to match(expected_smell_type.to_s)
      end
    end
  end

  context 'with no smells' do
    let(:smells) { [] }

    it_behaves_like 'no match'
  end

  context 'with 1 non-matching smell' do
    let(:smells) { [build_smell_warning(smell_type: 'ControlParameter')] }

    it_behaves_like 'no match'
  end

  context 'with 2 non-matching smells' do
    let(:smells) do
      [
        build_smell_warning(smell_type: 'ControlParameter'),
        build_smell_warning(smell_type: 'FeatureEnvy')
      ]
    end

    it_behaves_like 'no match'
  end

  context 'with 1 non-matching and 1 matching smell' do
    let(:smells) do
      [
        build_smell_warning(smell_type: 'ControlParameter'),
        build_smell_warning(smell_type: expected_smell_type.to_s,
                            message: "message mentioning #{expected_context_name}")
      ]
    end

    it_behaves_like 'no match'
  end

  context 'with 1 matching smell' do
    let(:smells) do
      [build_smell_warning(smell_type: expected_smell_type.to_s,
                           message: "message mentioning #{expected_context_name}")]
    end

    it 'matches' do
      expect(matcher_matches).to be_truthy
    end

    it 'reports the expected smell when no match was expected' do
      expect(matcher.failure_message_when_negated).to match(expected_smell_type.to_s)
    end

    it 'reports the source when no match was expected' do
      source = 'the_path/to_a/source_file.rb'
      allow(examiner).to receive(:origin).and_return(source)
      expect(matcher.failure_message_when_negated).to match(source)
    end
  end
end


text:
<!-- TOC depthFrom:1 depthTo:6 withLinks:1 updateOnSave:1 orderedList:0 -->

- [Project software site](#project-software-site)
- [Generate files](#generate-files)
	- [Config](#config)
	- [Repositories](#repositories)
	- [Publications](#publications)
- [Local hosting](#local-hosting)
- [Update website automatically](#update-website-automatically)

<!-- /TOC -->

# Project software site

Website listing the software and other output used/made/changed in this NLeSC project.

# Generate files

Install requirements with:
```
pip install -r utils/requirements.txt
```

## Config

```
python utils/generate.py config <organization name>
```

This will use the Github API to fetch information about the organization and write the `_config.yml` file. The `_config.yml` must be edited to complete the configuration.

## Repositories

```
python utils/generate.py repos <organization name>
```

This will generate a Markdown file in `_repos` directory for each public repo found in the organization.

## Publications

The list of doi's in `_data/dois.yml` can be converted to a publication list `_includes/publications.html` by
```
python utils/generate.py publications
```

The default citation style is `apa`.

# News items

Creating news item can be done by creating a Markdown file in the `_posts` directory.

The files should be called `YEAR-MONTH-DAY-title.md` and contain the following front matter.
```
---
title: New version of software X
---
```

See https://jekyllrb.com/docs/posts/ for more information.

# Team members

The team members of the project can be displayed on this website.

To add a new member create a biography file in `_team_members/` directory where the filename should be the person name.
The following front matter should be used.
```
---
title: <Name of person>
photo: <Url of photo of person, eg. /assets/team_members/name_of_person.jpg>
role: <Role of person>
---
```
A photo of the person should be added to the `assets/team_members/` directory with the same name as the biography.

# Local hosting

```
docker run --rm --volume=$(pwd):/srv/jekyll -i -t  -p 127.0.0.1:4000:4000 jekyll/jekyll:pages jekyll serve
```

The website can be viewed at http://localhost:4000

# Update website automatically

This website can be automatically updated see [BUILD_NIGHTLY.md](BUILD_NIGHTLY.md) and [BUILD_ON_CHANGE.md](BUILD_ON_CHANGE.md).


text:
require 'lib/parser'

class WHDebatesParser < Parser
  attr_reader :section

  def initialize(date, house="Commons", section="Westminster Hall")
    super(date, house)
    @section = section
  end

  def get_section_index
    super(section)
  end

  def parse_pages
    @page = 0
    @count = 0
    @contribution_count = 0

    @members = {}
    @section_members = {}
    @member = nil
    @contribution = nil

    @last_link = ""
    @snippet = []
    @subject = ""
    @start_column = ""
    @end_column = ""

    @chair = ""

    @indexer = Indexer.new()

    unless link_to_first_page
      warn "No #{section} data available for this date"
    else
      page = HansardPage.new(link_to_first_page)
      parse_page(page)
      while page.next_url
        page = HansardPage.new(page.next_url)
        parse_page(page)
      end

      #flush the buffer
      unless @snippet.empty? or @snippet.join("").length == 0
        store_debate(page)
        @snippet = []
      end
    end
  end

  private
    def parse_node(node, page)
      case node.name
        when "a"
          @last_link = node.attr("name") if node.attr("class") == "anchor"
          if node.attr("class") == "anchor-column"
            if @start_column == ""
              @start_column = node.attr("name").gsub("column_", "")
            else
              @end_column = node.attr("name").gsub("column_", "")
            end
          elsif node.attr("name") =~ /column_(.*)/  #older page format
            if @start_column == ""
              @start_column = node.attr("name").gsub("column_", "")
            else
              @end_column = node.attr("name").gsub("column_", "")
            end
          elsif node.attr("name") =~ /^\d*$/ #older page format
            @last_link = node.attr("name")
          end
        when "h3"
          unless @snippet.empty? or @snippet.join("").length == 0
            store_debate(page)
            @snippet = []
            @segment_link = ""
          end
          text = node.text.gsub("\n", "").squeeze(" ").strip
          @snippet << sanitize_text(text)
          @subject = sanitize_text(text)
          @segment_link = "#{page.url}\##{@last_link}"
        when "h4"
          text = node.text.gsub("\n", "").squeeze(" ").strip
          if text[text.length-13..text.length-2] == "in the Chair"
            @chair = text[1..text.length-15]
          end
        when "p"
          column_desc = ""
          member_name = ""
          if node.xpath("a") and node.xpath("a").length > 0
            @last_link = node.xpath("a").last.attr("name")
          end
          unless node.xpath("b").empty?
            node.xpath("b").each do |bold|
              if bold.text =~ /^\d+ [A-Z][a-z]+ \d{4} : Column (\d+(?:WH)?(?:WS)?(?:P)?(?:W)?)(?:-continued)?$/  #older page format
                if @start_column == ""
                  @start_column = $1
                else
                  @end_column = $1
                end
                column_desc = bold.text
              else
                member_name = bold.text.strip
              end
            end
          else
            member_name = ""
          end

          text = node.text.gsub("\n", "").gsub(column_desc, "").squeeze(" ").strip
          #ignore column heading text
          unless text =~ /^\d+ [A-Z][a-z]+ \d{4} : Column (\d+(?:WH)?(?:WS)?(?:P)?(?:W)?)(?:-continued)?$/
            #check if this is a new contrib
            case member_name
              when /^(([^\(]*) \(in the Chair\):)/
                #the Chair
                name = $2
                post = "Debate Chair"
                member = HansardMember.new(name, name, "", "", post)
                handle_contribution(@member, member, page)
                @contribution.segments << sanitize_text(text.gsub($1, "")).strip
              when /^(([^\(]*) \(([^\(]*)\):)/
                #we has a minister
                post = $2
                name = $3
                member = HansardMember.new(name, "", "", "", post)
                handle_contribution(@member, member, page)
                @contribution.segments << sanitize_text(text.gsub($1, "")).strip
              when /^(([^\(]*) \(([^\(]*)\) \(([^\(]*)\):)/
                #an MP speaking for the first time in the debate
                name = $2
                constituency = $3
                party = $4
                member = HansardMember.new(name, "", constituency, party)
                handle_contribution(@member, member, page)
                @contribution.segments << sanitize_text(text.gsub($1, "")).strip
              when /^(([^\(]*):)/
                #an MP who's spoken before
                name = $2
                member = HansardMember.new(name, name)
                handle_contribution(@member, member, page)
                @contribution.segments << sanitize_text(text.gsub($1, "")).strip
              else
                if @member
                  unless text =~ /^Sitting suspended|^Sitting adjourned|^On resuming|^Question put/ or
                      text == "#{@member.search_name} rose\342\200\224"
                    @contribution.segments << sanitize_text(text)
                  end
                end
            end
            @snippet << sanitize_text(text)
          end
      end
    end

    def store_debate(page)
      handle_contribution(@member, @member, page)

      if @segment_link #no point storing pointers that don't link back to the source
        segment_id = "#{doc_id}_wh_#{@count}"
        @count += 1
        names = []
        @members.each { |x, y| names << y.index_name unless names.include?(y.index_name) }

        column_text = ""
        if @start_column == @end_column or @end_column == ""
          column_text = @start_column
        else
          column_text = "#{@start_column} to #{@end_column}"
        end

        doc = {:title => sanitize_text("Debate: #{@subject}"),
         :volume => page.volume,
         :columns => column_text,
         :part => sanitize_text(page.part.to_s),
         :members => "| #{names.join(" | ")} |".squeeze(" "),
         :chair => @chair,
         :subject => @subject,
         :url => @segment_link,
         :house => house,
         :section => section,
         :timestamp => Time.parse(date).to_i
        }

        categories = {"house" => house, "section" => section}

        @indexer.add_document(segment_id, doc, @snippet.join(" "), categories, "idx")

        @start_column = @end_column if @end_column != ""

        p @subject
        p segment_id
        p @segment_link
        p ""

        store_member_contributions
      end
    end

end


text:
import time
import urllib

from lxml import etree

from tempest.common import rest_client
from tempest.common import xml_utils
from tempest import config
from tempest import exceptions

CONF = config.CONF

class VolumesExtensionsClientXML(rest_client.RestClient):
    TYPE = "xml"

    def __init__(self, auth_provider):
        super(VolumesExtensionsClientXML, self).__init__(
            auth_provider)
        self.service = CONF.compute.catalog_type
        self.build_interval = CONF.compute.build_interval
        self.build_timeout = CONF.compute.build_timeout

    def _parse_volume(self, body):
        vol = dict((attr, body.get(attr)) for attr in body.keys())

        for child in body.getchildren():
            tag = child.tag
            if tag.startswith("{"):
                ns, tag = tag.split("}", 1)
            if tag == 'metadata':
                vol['metadata'] = dict((meta.get('key'),
                                        meta.text) for meta in list(child))
            else:
                vol[tag] = xml_utils.xml_to_json(child)
        return vol

    def list_volumes(self, params=None):
        """List all the volumes created."""
        url = 'os-volumes'

        if params:
            url += '?%s' % urllib.urlencode(params)

        resp, body = self.get(url)
        body = etree.fromstring(body)
        volumes = []
        if body is not None:
            volumes += [self._parse_volume(vol) for vol in list(body)]
        return resp, volumes

    def list_volumes_with_detail(self, params=None):
        """List all the details of volumes."""
        url = 'os-volumes/detail'

        if params:
            url += '?%s' % urllib.urlencode(params)

        resp, body = self.get(url)
        body = etree.fromstring(body)
        volumes = []
        if body is not None:
            volumes += [self._parse_volume(vol) for vol in list(body)]
        return resp, volumes

    def get_volume(self, volume_id):
        """Returns the details of a single volume."""
        url = "os-volumes/%s" % str(volume_id)
        resp, body = self.get(url)
        body = etree.fromstring(body)
        return resp, self._parse_volume(body)

    def create_volume(self, size, display_name=None, metadata=None):
        """Creates a new Volume.

        :param size: Size of volume in GB. (Required)
        :param display_name: Optional Volume Name.
        :param metadata: An optional dictionary of values for metadata.
        """
        volume = xml_utils.Element("volume",
                                   xmlns=xml_utils.XMLNS_11,
                                   size=size)
        if display_name:
            volume.add_attr('display_name', display_name)

        if metadata:
            _metadata = xml_utils.Element('metadata')
            volume.append(_metadata)
            for key, value in metadata.items():
                meta = xml_utils.Element('meta')
                meta.add_attr('key', key)
                meta.append(xml_utils.Text(value))
                _metadata.append(meta)

        resp, body = self.post('os-volumes', str(xml_utils.Document(volume)))
        body = xml_utils.xml_to_json(etree.fromstring(body))
        return resp, body

    def delete_volume(self, volume_id):
        """Deletes the Specified Volume."""
        return self.delete("os-volumes/%s" % str(volume_id))

    def wait_for_volume_status(self, volume_id, status):
        """Waits for a Volume to reach a given status."""
        resp, body = self.get_volume(volume_id)
        volume_name = body['displayName']
        volume_status = body['status']
        start = int(time.time())

        while volume_status != status:
            time.sleep(self.build_interval)
            resp, body = self.get_volume(volume_id)
            volume_status = body['status']
            if volume_status == 'error':
                raise exceptions.VolumeBuildErrorException(volume_id=volume_id)

            if int(time.time()) - start >= self.build_timeout:
                message = 'Volume %s failed to reach %s status within '\
                          'the required time (%s s).' % (volume_name, status,
                                                         self.build_timeout)
                raise exceptions.TimeoutException(message)

    def is_resource_deleted(self, id):
        try:
            self.get_volume(id)
        except exceptions.NotFound:
            return True
        return False

    @property
    def resource_type(self):
        """Returns the primary type of resource this client works with."""
        return 'volume'


text:
// Copyright 2014 The Bazel 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.
package com.google.devtools.build.lib.events;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.collect.ImmutableList;
import com.google.common.eventbus.EventBus;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/**
 * Tests the {@link Reporter} class.
 */
@RunWith(JUnit4.class)
public class ReporterTest extends EventTestTemplate {

  private Reporter reporter;
  private StringBuilder out;
  private AbstractEventHandler outAppender;

  @Before
  public final void initializeOutput() throws Exception  {
    reporter = new Reporter(new EventBus());
    out = new StringBuilder();
    outAppender = new AbstractEventHandler(EventKind.ERRORS) {
      @Override
      public void handle(Event event) {
        out.append(event.getMessage());
      }
    };
  }

  @Test
  public void reporterShowOutput() {
    reporter.setOutputFilter(OutputFilter.RegexOutputFilter.forRegex("naughty"));
    EventCollector collector = new EventCollector();
    reporter.addHandler(collector);
    Event interesting = Event.warn(null, "show-me").withTag("naughty");

    reporter.handle(interesting);
    reporter.handle(Event.warn(null, "ignore-me").withTag("good"));

    assertThat(ImmutableList.of(interesting)).isEqualTo(ImmutableList.copyOf(collector));
  }

  @Test
  public void reporterCollectsEvents() {
    ImmutableList<Event> want = ImmutableList.of(Event.warn("xyz"), Event.error("err"));
    EventCollector collector = new EventCollector();
    reporter.addHandler(collector);
    for (Event e : want) {
      reporter.handle(e);
    }
    ImmutableList<Event> got = ImmutableList.copyOf(collector);
    assertThat(want).isEqualTo(got);
  }

  @Test
  public void reporterCopyConstructorCopiesHandlersList() {
    reporter.addHandler(outAppender);
    reporter.addHandler(outAppender);
    Reporter copiedReporter = new Reporter(reporter);
    copiedReporter.addHandler(outAppender); // Should have 3 handlers now.
    reporter.addHandler(outAppender);
    reporter.addHandler(outAppender); // Should have 4 handlers now.
    copiedReporter.handle(Event.error(location, "."));
    assertThat(out.toString()).isEqualTo("..."); // The copied reporter has 3 handlers.
    out = new StringBuilder();
    reporter.handle(Event.error(location, "."));
    assertThat(out.toString()).isEqualTo("...."); // The old reporter has 4 handlers.
  }

  @Test
  public void removeHandlerUndoesAddHandler() {
    assertThat(out.toString()).isEmpty();
    reporter.addHandler(outAppender);
    reporter.handle(Event.error(location, "Event gets registered."));
    assertThat(out.toString()).isEqualTo("Event gets registered.");
    out = new StringBuilder();
    reporter.removeHandler(outAppender);
    reporter.handle(Event.error(location, "Event gets ignored."));
    assertThat(out.toString()).isEmpty();
  }

}


text:
package middleware

import (
	"net/http"
	"net/http/httptest"
	"testing"

	"github.com/go-chi/chi"
)

func TestURLFormat(t *testing.T) {
	r := chi.NewRouter()

	r.Use(URLFormat)

	r.NotFound(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(404)
		w.Write([]byte("nothing here"))
	})

	r.Route("/samples/articles/samples.{articleID}", func(r chi.Router) {
		r.Get("/", func(w http.ResponseWriter, r *http.Request) {
			articleID := chi.URLParam(r, "articleID")
			w.Write([]byte(articleID))
		})
	})

	r.Route("/articles/{articleID}", func(r chi.Router) {
		r.Get("/", func(w http.ResponseWriter, r *http.Request) {
			articleID := chi.URLParam(r, "articleID")
			w.Write([]byte(articleID))
		})
	})

	ts := httptest.NewServer(r)
	defer ts.Close()

	if _, resp := testRequest(t, ts, "GET", "/articles/1.json", nil); resp != "1" {
		t.Fatalf(resp)
	}
	if _, resp := testRequest(t, ts, "GET", "/articles/1.xml", nil); resp != "1" {
		t.Fatalf(resp)
	}
	if _, resp := testRequest(t, ts, "GET", "/samples/articles/samples.1.json", nil); resp != "1" {
		t.Fatalf(resp)
	}
	if _, resp := testRequest(t, ts, "GET", "/samples/articles/samples.1.xml", nil); resp != "1" {
		t.Fatalf(resp)
	}
}


text:
;(function($){
	//定义命名空间
	_admin = $.extend({},$.admin);

	var fpModalStatus = function(status){
		$("#fpModel").modal(status);
	}

	var fpModelTitle = function(title){
		$("#fpTitle").html(title);
	}

	var fpIframe = function(src){
		$("#fpIframe").attr("src",src);
	}

	//初始化表格
	function initTable(){
		var grid = $("#formProcessGrid").bootgrid({
		    ajax: true,
		    ajaxSettings:{
		    	method:"POST",
		    	cache:false
		    },
	        templates: {
	        	actionButton:"<button class=\"btn btn-default\" type=\"button\" title=\"{{ctx.text}}\" style=\"height:34px;\">{{ctx.content}}</button>",
			    actions:"
<button type=\"button\" class=\"btn btn-default\" id=\"id_add_formProcess\">新增</button>
"
	        },
		    navigation:3,
		    searchSettings:{
		    	delay:100,
		    	characters:2
		    },
		    labels:{
		    	all:"全部",
		    	infos:"共 {{ctx.total}} 条,当前显示 {{ctx.start}} 至 {{ctx.end}} 条 ",
		    	loading:"加载中...",
		    	noResults:"没有结果",
		    	refresh:"刷新",
		    	search:"表单名称或流程名称"
		    },
		    post: function()
		    {
		        return FormProcess.defaults;
		    },
		    url: webRoot+"/page/admin/activiti/queryFormProcessList",
		    formatters: {
		        "date": function(column, row)
		        {
		            return new Date(row[column.id]).pattern("yyyy/MM/dd HH:mm:ss");
		        },
		        "commands":function(column,row){
					return "<button type=\"button\" class=\"btn btn-xs btn-default\" title=\"删除\" name=\"deleteFormProcess\" data-id=\"" + row.id + "\"></button>"+
					"<button type=\"button\" class=\"btn btn-xs btn-default\" title=\"修改\" name=\"updateFormProcess\" data-id=\"" + row.id + "\"></button>";
		        }
		    },
		    requestHandler:function(request){
		    	return convertParam(request);
		    },
		    responseHandler:function(response){
		    	return response;
		    }
		}).on("loaded.rs.jquery.bootgrid", function(){
			grid.find("button[name='deleteFormProcess']").on("click",formProcess.deleteFormProcess).end().
			find("button[name='updateFormProcess']").on("click",formProcess.updateFormProcess);
		});
	}

	//转换请求参数
	function convertParam(request){
		var paramObj = request;
    	paramObj.pageNo = request.current;
    	paramObj.pageSize = (request.rowCount == -1)?99999999:request.rowCount;
    	if(request.sort){
    		for(var key in request.sort){
    			if(key){
    				paramObj.sortFieldName = key;
    				paramObj.sortType = request.sort[key];
    				break;
    			}
    		}
    	}
    	return paramObj;
	}

	//初始化事件
	function initEvent(){
		$("#id_add_formProcess").click(function(){
			fpModalStatus("show");
			fpModelTitle("表单流程配置");
			fpIframe(webRoot+"/page/admin/activiti/formProcessForm.jsp");
		});

		$("#fpIframe").resizeIframe({extendHeight:20});
	}

	//初始化函数
	function init(){
        initTable.call(this);
        initEvent.call(this);
	}

	var FormProcess = function(ops){
		this.options = $.extend(true, {},FormProcess.defaults, ops);
		init.call(this);
	}

	FormProcess.defaults = {
	};

	FormProcess.prototype = {
		constructor:FormProcess,
		formProcessHandler:function(){
			fpModalStatus("hide");
			$("#formProcessGrid").bootgrid("reload");
		},
		deleteFormProcess:function(){
			var id = $(this).data("id");
			bootbox.dialog({
			  message: "确认删除该条数据吗?",
			  title: "删除确认",
			  buttons: {
			    success: {
			      label: "是",
			      className: "btn-success",
			      callback: function() {
			    	  FormProcessAction.deleteFormProcess({id:id},function(data){
							if(data && data.result){
								bootbox.alert("删除成功")
								$("#formProcessGrid").bootgrid("reload");
							}else{
								bootbox.alert("删除失败")
							}
						});
			      }
			    },
			    danger: {
			      label: "否",
			      className: "btn-danger",
			      callback: function() {
			      }
			    }
			  }
			});
		},
		updateFormProcess:function(){
			fpModalStatus("show");
			fpModelTitle("业务表单流程修改");
			fpIframe(webRoot+"/page/admin/activiti/formProcessForm.jsp?id="+$(this).data("id"));
		}
	}

	_admin.FormProcess = FormProcess;
	$.admin = _admin;
})(jQuery);

var formProcess = new $.admin.FormProcess({});

function getTargetObject(){
	return formProcess;
}


text:
[![npm](https://img.shields.io/npm/v/iab-vast-model.svg)](https://www.npmjs.com/package/iab-vast-model) [![Dependencies](https://img.shields.io/david/zentrick/iab-vast-model.svg)](https://david-dm.org/zentrick/iab-vast-model) [![Build Status](https://img.shields.io/circleci/project/github/zentrick/iab-vast-model/master.svg)](https://circleci.com/gh/zentrick/iab-vast-model) [![Coverage Status](https://img.shields.io/coveralls/zentrick/iab-vast-model/master.svg)](https://coveralls.io/r/zentrick/iab-vast-model) [![JavaScript Standard Style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg)](http://standardjs.com/)

Base classes for IAB VAST handling. Supports the full IAB VAST 2.0, 3.0, and 4.0
specifications.

To parse a tag into model objects, use
[iab-vast-parser](https://www.npmjs.com/package/iab-vast-parser).
To load and parse a chain of VAST files, use
[iab-vast-loader](https://www.npmjs.com/package/iab-vast-loader).

## Usage

```javascript
import { VAST } from 'iab-vast-model'

const vast = new VAST()
// ... Do your thing ...
```

## Rationale

The API attempts to favor developer experience over mapping the VAST
specifications to classes one-to-one. That has a few implications:

-   You won't find classes corresponding to `<Creatives>`, `<CreativeExtensions>`,
    `<Extensions>`, `<MediaFiles>` and `<Verifications>`. Instead, those have
    been folded into their parent objects.

-   Where a child object can occur multiple times, the corresponding property will
    either be an array or a `SortedList`. The latter models VAST's `sequence`
    attribute and automatically orders elements by its value.

-   Elements that are not required are `null` by default. A typical example is
    `TrackingEvents` on the ads in a `Creative`.

## API

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

#### Table of Contents

-   [AbsoluteTimeOffset](#absolutetimeoffset)
-   [AbstractAd](#abstractad)
    -   [adSystem](#adsystem)
    -   [conditionalAd](#conditionalad)
    -   [creatives](#creatives)
    -   [errors](#errors)
    -   [extensions](#extensions)
    -   [id](#id)
    -   [impressions](#impressions)
    -   [pricing](#pricing)
    -   [verifications](#verifications)
    -   [viewableImpression](#viewableimpression)
-   [AbstractClicks](#abstractclicks)
    -   [clickThrough](#clickthrough)
    -   [clickTrackings](#clicktrackings)
-   [AbstractExtension](#abstractextension)
    -   [type](#type)
    -   [xmlElement](#xmlelement)
-   [AbstractResource](#abstractresource)
    -   [uri](#uri)
-   [AbstractTimeOffset](#abstracttimeoffset)
    -   [value](#value)
-   [AbstractVerificationResource](#abstractverificationresource)
    -   [apiFramework](#apiframework)
-   [AdBuffet](#adbuffet)
    -   [adPod](#adpod)
    -   [ads](#ads)
-   [SortedList](#sortedlist)
    -   [add](#add)
    -   [clear](#clear)
    -   [get](#get)
    -   [length](#length)
    -   [remove](#remove)
    -   [toArray](#toarray)
-   [TrackingEvents](#trackingevents)
    -   [add](#add-1)
    -   [get](#get-1)
    -   [types](#types)
-   [Creative](#creative)
    -   [adID](#adid)
    -   [apiFramework](#apiframework-1)
    -   [companionAds](#companionads)
    -   [extensions](#extensions-1)
    -   [id](#id-1)
    -   [linear](#linear)
    -   [nonLinearAds](#nonlinearads)
    -   [universalAdId](#universaladid)
-   [Companion](#companion)
    -   [adParameters](#adparameters)
    -   [adSlotID](#adslotid)
    -   [altText](#alttext)
    -   [apiFramework](#apiframework-2)
    -   [assetHeight](#assetheight)
    -   [assetWidth](#assetwidth)
    -   [clickThrough](#clickthrough-1)
    -   [clickTrackings](#clicktrackings-1)
    -   [expandedHeight](#expandedheight)
    -   [expandedWidth](#expandedwidth)
    -   [height](#height)
    -   [id](#id-2)
    -   [pxratio](#pxratio)
    -   [resource](#resource)
    -   [trackingEvents](#trackingevents-1)
    -   [width](#width)
-   [NonLinear](#nonlinear)
    -   [adParameters](#adparameters-1)
    -   [apiFramework](#apiframework-3)
    -   [clickThrough](#clickthrough-2)
    -   [clickTrackings](#clicktrackings-2)
    -   [expandedHeight](#expandedheight-1)
    -   [expandedWidth](#expandedwidth-1)
    -   [height](#height-1)
    -   [id](#id-3)
    -   [maintainAspectRatio](#maintainaspectratio)
    -   [minSuggestedDuration](#minsuggestedduration)
    -   [resource](#resource-1)
    -   [scalable](#scalable)
    -   [width](#width-1)
-   [Linear](#linear-1)
    -   [adParameters](#adparameters-2)
    -   [duration](#duration)
    -   [icons](#icons)
    -   [interactiveCreativeFiles](#interactivecreativefiles)
    -   [mediaFiles](#mediafiles)
    -   [mezzanine](#mezzanine)
    -   [skipoffset](#skipoffset)
    -   [trackingEvents](#trackingevents-2)
    -   [videoClicks](#videoclicks)
-   [AdPod](#adpod-1)
    -   [ads](#ads-1)
-   [AdSystem](#adsystem-1)
    -   [name](#name)
    -   [version](#version)
-   [InLine](#inline)
    -   [adTitle](#adtitle)
    -   [advertiser](#advertiser)
    -   [categories](#categories)
    -   [description](#description)
    -   [surveys](#surveys)
-   [Wrapper](#wrapper)
    -   [allowMultipleAds](#allowmultipleads)
    -   [fallbackOnNoAd](#fallbackonnoad)
    -   [followAdditionalWrappers](#followadditionalwrappers)
    -   [vastAdTagURI](#vastadtaguri)
-   [Icon](#icon)
    -   [apiFramework](#apiframework-4)
    -   [clicks](#clicks)
    -   [duration](#duration-1)
    -   [height](#height-2)
    -   [offset](#offset)
    -   [program](#program)
    -   [pxratio](#pxratio-1)
    -   [resource](#resource-2)
    -   [viewTrackings](#viewtrackings)
    -   [width](#width-2)
    -   [xPosition](#xposition)
    -   [yPosition](#yposition)
-   [MediaFile](#mediafile)
    -   [apiFramework](#apiframework-5)
    -   [bitrate](#bitrate)
    -   [codec](#codec)
    -   [delivery](#delivery)
    -   [height](#height-3)
    -   [id](#id-4)
    -   [maintainAspectRatio](#maintainaspectratio-1)
    -   [maxBitrate](#maxbitrate)
    -   [minBitrate](#minbitrate)
    -   [scalable](#scalable-1)
    -   [type](#type-1)
    -   [uri](#uri-1)
    -   [width](#width-3)
-   [InteractiveCreativeFile](#interactivecreativefile)
    -   [apiFramework](#apiframework-6)
    -   [type](#type-2)
    -   [uri](#uri-2)
-   [Category](#category)
    -   [authority](#authority)
    -   [code](#code)
-   [Click](#click)
    -   [id](#id-5)
    -   [uri](#uri-3)
-   [CompanionAds](#companionads-1)
    -   [companions](#companions)
    -   [required](#required)
-   [CreativeExtension](#creativeextension)
-   [UniversalAdId](#universaladid-1)
    -   [creativeIdentifier](#creativeidentifier)
    -   [idRegistry](#idregistry)
    -   [idValue](#idvalue)
-   [StaticResource](#staticresource)
    -   [creativeType](#creativetype)
-   [Pricing](#pricing-1)
    -   [currency](#currency)
    -   [model](#model)
    -   [value](#value-1)
-   [VideoClicks](#videoclicks-1)
    -   [customClicks](#customclicks)
-   [VAST](#vast)
    -   [errors](#errors-1)
    -   [uri](#uri-4)
    -   [version](#version-1)
-   [Extension](#extension)
-   [FlashResource](#flashresource)
-   [Verification](#verification)
    -   [flashResources](#flashresources)
    -   [javaScriptResources](#javascriptresources)
    -   [vendor](#vendor)
    -   [viewableImpression](#viewableimpression-1)
-   [HTMLResource](#htmlresource)
-   [IconClicks](#iconclicks)
-   [ViewableImpression](#viewableimpression-2)
    -   [id](#id-6)
    -   [notViewables](#notviewables)
    -   [viewables](#viewables)
    -   [viewUndetermineds](#viewundetermineds)
-   [Impression](#impression)
    -   [id](#id-7)
    -   [uri](#uri-5)
-   [IFrameResource](#iframeresource)
-   [JavaScriptResource](#javascriptresource)
-   [NonLinearAds](#nonlinearads-1)
    -   [nonLinears](#nonlinears)
    -   [trackingEvents](#trackingevents-3)
-   [TrackingEvent](#trackingevent)
    -   [offset](#offset-1)
    -   [uri](#uri-6)
-   [RelativeTimeOffset](#relativetimeoffset)
-   [SortedListItem](#sortedlistitem)
    -   [sequence](#sequence)
-   [Survey](#survey)
    -   [type](#type-3)
    -   [uri](#uri-7)

### AbsoluteTimeOffset

**Extends AbstractTimeOffset**

Represents a time offset expressed as an absolute duration in seconds.

### AbstractAd

**Extends SortedListItem**

Abstract class for ads (i.e., [InLine](#inline) and [Wrapper](#wrapper)).

#### adSystem

The ad system for this ad.

Type: [AdSystem](#adsystem)

#### conditionalAd

The conditional attribute for this ad.

Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)

#### creatives

The creatives for this ad.

Type: [SortedList](#sortedlist)<[Creative](#creative)>

#### errors

The error-tracking URIs for this ad.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>

#### extensions

The extensions for this ad.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Extension](#extension)>

#### id

The ad server-defined identifier for this ad.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### impressions

The impression-tracking configurations for this ad.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Impression](#impression)>

#### pricing

The pricing configuration for this ad.

Type: [Pricing](#pricing)

#### verifications

The verifications for this ad.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Verification](#verification)>

#### viewableImpression

The viewable impression for this ad.

Type: [ViewableImpression](#viewableimpression)

### AbstractClicks

Stores the click-through URI and a set of click-tracking pixels.

#### clickThrough

The click-through configuration.

Type: [Click](#click)

#### clickTrackings

The click-tracking configurations.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Click](#click)>

### AbstractExtension

Base class for VAST [Extension](#extension) as well as [CreativeExtension](#creativeextension).

#### type

The MIME type of any code that might be included in the extension.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### xmlElement

The `<Extension>` XML DOM element.

Type: [Element](https://developer.mozilla.org/docs/Web/API/Element)

### AbstractResource

Base class for a verification resource used by a [HTMLResource](#htmlresource), a
[IFrameResource](#iframeresource) and a [StaticResource](#staticresource).

#### uri

The URI to this resource.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

### AbstractTimeOffset

Represents a time offset.

#### value

The value for this offset.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

### AbstractVerificationResource

**Extends AbstractResource**

Base class for a verification resource used by a [FlashResource](#flashresource) and a
[JavaScriptResource](#javascriptresource).

#### apiFramework

The name of the API framework.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

### AdBuffet

Represents a VAST ad buffet.

#### adPod

The ad pod for this ad buffet.

Type: [AdPod](#adpod)

#### ads

The ads in this ad buffet.

Type: [SortedList](#sortedlist)

### SortedList

Represents a list of [SortedListItem](#sortedlistitem)s, ordered by
[SortedListItem#sequence](#sortedlistitemsequence).

#### add

Adds the given item to this list.

**Parameters**

-   `item` **[SortedListItem](#sortedlistitem)** the item.

#### clear

Empties this list.

#### get

Gets the item at the given index.

**Parameters**

-   `index` **[number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)** the index.

Returns **[SortedListItem](#sortedlistitem)** the item.

#### length

The length of this list.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### remove

Removes the given item from this list.

**Parameters**

-   `item` **[SortedListItem](#sortedlistitem)** the item.

#### toArray

Creates an array representation of this list.

Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[SortedListItem](#sortedlistitem)>** the item array.

### TrackingEvents

Configures tracking events. Maps VAST event types to arrays of
[TrackingEvent](#trackingevent) instances.

#### add

Adds a tracking-event configuration for the given event type.

**Parameters**

-   `event` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the event type.
-   `config` **[TrackingEvent](#trackingevent)** the tracking event configuration.

#### get

Gets the tracking-event configurations for the given event type.

**Parameters**

-   `event` **[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)** the event type.

Returns **[Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[TrackingEvent](#trackingevent)>** the tracking event configurations.

#### types

The event types tracked by this configuration.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>

### Creative

**Extends SortedListItem**

Represents a creative.

#### adID

The ID of the [Ad](Ad) with which this creative is served.

Required for VAST 2.0 and 3.0, optional for VAST 4.0.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### apiFramework

The string that identifies an API that is needed to execute this creative.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### companionAds

The companion ads for this creative, if any.

Type: [CompanionAds](#companionads)

#### extensions

The creative extensions for this creative.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[CreativeExtension](#creativeextension)>

#### id

The ID of this creative.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### linear

The linear ad for this creative, if any.

Type: [Linear](#linear)

#### nonLinearAds

The non-linear ads for this creative, if any.

Type: [NonLinearAds](#nonlinearads)

#### universalAdId

The unique creative identifier for this creative.

Type: [UniversalAdId](#universaladid)

### Companion

Represents a single companion inside [CompanionAds](#companionads).

#### adParameters

The ad parameters for this companion ad.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### adSlotID

The ad slot ID of this companion ad.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### altText

The alt text of this companion ad.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### apiFramework

The API framework used by this companion ad.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### assetHeight

The height of this companion ad's asset in pixels.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### assetWidth

The width of this companion ad's asset in pixels.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### clickThrough

The click-through configuration.

Type: [Click](#click)

#### clickTrackings

The click-tracking configurations.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Click](#click)>

#### expandedHeight

The expanded height of this companion ad in pixels.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### expandedWidth

The expanded width of this companion ad in pixels.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### height

The height of this companion ad in pixels.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### id

The ID for this companion ad.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### pxratio

The pixel ratio for which the companion creative is intended.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### resource

The resource associated with this companion ad.

Type: ([StaticResource](#staticresource) \| [IFrameResource](#iframeresource) \| [HTMLResource](#htmlresource))

#### trackingEvents

The event-tracking configuration for this companion ad.

Type: [TrackingEvents](#trackingevents)

#### width

The width of this companion ad in pixels.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

### NonLinear

Represents a single non-linear ad inside [NonLinearAds](#nonlinearads).

#### adParameters

The ad parameters for this non-linear ad.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### apiFramework

The API framework used by this non-linear ad.

VAST 2.0 and 3.0 only.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### clickThrough

The click-through configuration for this non-linear ad.

Type: [Click](#click)

#### clickTrackings

The click-tracking configurations for this non-linear ad.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Click](#click)>

#### expandedHeight

The expanded height of this non-linear ad in pixels.

VAST 2.0 and 3.0 only.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### expandedWidth

The expanded width of this non-linear ad in pixels.

VAST 2.0 and 3.0 only.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### height

The height of this non-linear ad in pixels.

VAST 2.0 and 3.0 only.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### id

The ID of this non-linear ad.

VAST 2.0 and 3.0 only.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### maintainAspectRatio

Whether this non-linear ad's aspect ratio should be maintained when scaled.

VAST 2.0 and 3.0 only.

Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)

#### minSuggestedDuration

The minimum suggested duration of this non-linear ad in seconds.

VAST 2.0 and 3.0 only.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### resource

The resource associated with this non-linear ad.

Type: Resource

#### scalable

Whether this non-linear ad is meant to scale to larger dimensions.

VAST 2.0 and 3.0 only.

Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)

#### width

The width of this non-linear ad in pixels.

VAST 2.0 and 3.0 only.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

### Linear

Represents a linear within a [Creative](#creative).

#### adParameters

The ad parameters for this linear creative.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### duration

The duration of this linear creative in seconds.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### icons

The icons for this linear creative.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Icon](#icon)>

#### interactiveCreativeFiles

The interactive creative files for this linear creative.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[InteractiveCreativeFile](#interactivecreativefile)>

#### mediaFiles

The media files for this linear creative.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[MediaFile](#mediafile)>

#### mezzanine

The URI of the raw mezzanine file for this linear creative, intended for
video transcoding.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### skipoffset

The time interval after which this linear creative can be skipped.

Type: TimeOffset

#### trackingEvents

The event-tracking configuration for this linear creative.

Type: [TrackingEvents](#trackingevents)

#### videoClicks

The video click tracking configuration for this linear creative.

Type: [VideoClicks](#videoclicks)

### AdPod

Represents a VAST ad pod.

#### ads

The ads in this ad pod.

Type: [SortedList](#sortedlist)

### AdSystem

Stores information about the ad system.

#### name

The name of the ad server that returned the ad.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### version

The version of the ad system.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

### InLine

**Extends AbstractAd**

Represents an InLine ad.

#### adTitle

The title for this ad.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### advertiser

The advertiser name for this ad.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### categories

The categories for this ad.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Category](#category)>

#### description

The description for this ad.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### surveys

The survey URI for this ad.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Survey](#survey)>

### Wrapper

**Extends AbstractAd**

Represents a wrapper ad.

#### allowMultipleAds

Whether multiple ads are allowed in the requested VAST response.

Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)

#### fallbackOnNoAd

Whether to use an available Ad when the requested VAST response returns no
ads.

Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)

#### followAdditionalWrappers

Whether subsequent wrappers after a requested VAST response is allowed.

Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)

#### vastAdTagURI

The URI to a VAST response that may be another VAST [Wrapper](#wrapper) or a
VAST [InLine](#inline) ad.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

### Icon

Represents an icon used in a [Linear](#linear) creative.

#### apiFramework

The API framework used by this icon.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### clicks

The click-tracking configuration for this icon.

Type: [IconClicks](#iconclicks)

#### duration

The duration of this icon in seconds.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### height

The height of this icon in pixels.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### offset

The time offset of this icon in seconds.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### program

The industry initiative that this icon supports.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### pxratio

The pixel ratio for which the icon creative is intended.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### resource

The resource associated with this icon.

Type: Resource

#### viewTrackings

The view-tracking URIs for this icon.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>

#### width

The width of this icon in pixels.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### xPosition

The horizontal position of this icon. Either a number of pixels or the
string `"left"` or `"right"`.

Type: ([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number) \| [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))

#### yPosition

The vertical position of this icon. Either a number of pixels or the
string `"top"` or `"bottom"`.

Type: ([number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number) \| [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String))

### MediaFile

Represents a media file used in a [Linear](#linear) creative.

#### apiFramework

The API framework used by this media file.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### bitrate

The bitrate of this media file in kbps.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### codec

The codec of this media file in RFC 4281 format.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### delivery

The delivery method for this media file.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### height

The height of this media file in pixels.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### id

The ID of this media file.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### maintainAspectRatio

Whether this media file's aspect ratio should be maintained when scaled.

Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)

#### maxBitrate

The maximum bitrate of this media file in kbps.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### minBitrate

The minimum bitrate of this media file in kbps.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

#### scalable

Whether this media file is meant to scale to larger dimensions.

Type: [boolean](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean)

#### type

The MIME type of this media file.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### uri

The URI to this media file.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### width

The width of this media file in pixels.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

### InteractiveCreativeFile

Represents an interactive creative file used in a [Linear](#linear) creative.

#### apiFramework

The API framework used by this interactive creative file.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### type

The MIME type of this interactive creative file.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### uri

The URI to this interactive creative file.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

### Category

Pricing information for real-time bidding.

#### authority

The URL for the organizational authority that produced the list being used
to identify the ad content.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### code

The category code or label that identifies the ad content.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

### Click

Describes a click configuration.

#### id

The ID of this click.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### uri

The URI of this tracking pixel.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

### CompanionAds

Represents companion ads within a [Creative](#creative).

#### companions

The companion ads.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Companion](#companion)>

#### required

Determines which companion creative to display when multiple companions
are supplied and whether the ad can be displayed without its companion
creative. Either `"all"`, `"any"`, or `"none"`.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

### CreativeExtension

**Extends AbstractExtension**

Represents a creative extension.

### UniversalAdId

Represents a unique identifier for an ad.

#### creativeIdentifier

The string identifying the unique creative identifier.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### idRegistry

The registry URL for the unique creative identifier.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### idValue

A string for the unique creative identifier.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

### StaticResource

**Extends AbstractResource**

Describes non-HTML creative.

#### creativeType

The MIME type of this resource.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

### Pricing

Represents pricing information for real-time bidding.

#### currency

The three-letter ISO-4217 currency symbol that identifies the currency of
the value provided (e.g. `"USD"`, `"GBP"`, etc.).

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### model

The pricing model. Either `"CPM"`, `"CPC"`, `"CPE"`, or `"CPV"`.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### value

The price that can be used in real-time bidding systems.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

### VideoClicks

**Extends AbstractClicks**

Represents the click-tracking configuration for a [Linear](#linear) creative.

#### customClicks

The custom-click configurations.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[Click](#click)>

### VAST

**Extends AdBuffet**

Represents a VAST document.

#### errors

The error-tracking URIs for this document.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>

#### uri

The URI associated with this document.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### version

The VAST version used by this document.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

### Extension

**Extends AbstractExtension**

Represents a VAST extension.

### FlashResource

**Extends AbstractVerificationResource**

Describes a Flash resource used to collect verification data.

### Verification

Represents a list of verification resources for a vendor.

#### flashResources

The Flash resources for this verification vendor.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[FlashResource](#flashresource)>

#### javaScriptResources

The JavaScript resources for this verification vendor.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[JavaScriptResource](#javascriptresource)>

#### vendor

The home page URL for the verification service provider that supplies the
resource file.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### viewableImpression

The viewable impression for this verification vendor.

Type: [ViewableImpression](#viewableimpression)

### HTMLResource

**Extends AbstractResource**

Describes an HTML snippet.

### IconClicks

**Extends AbstractClicks**

Represents the click tracking configuration for an [Icon](#icon).

### ViewableImpression

Represents the impression-tracking URIs for both an [InLine](#inline) and any
[Wrapper](#wrapper).

#### id

The ad server ID of this viewability impression pixel.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### notViewables

The URIs that direct the video player to a tracking resource file that the
video player should request if the ad is executed but never meets criteria
for a viewable impression.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>

#### viewables

The URIs that direct the video player to a tracking resource file that the
video player should request at the time that criteria is met for a viewable
impression.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>

#### viewUndetermineds

The URIs that direct the video player to a tracking resource file that the
video player should request if the player cannot determine whether criteria
is met for a viewable impression.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)>

### Impression

Represents an impression.

#### id

The ad server id for the impression.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### uri

The URI of this impression resource.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

### IFrameResource

**Extends AbstractResource**

Describes an HTML page for display within an iframe.

### JavaScriptResource

**Extends AbstractVerificationResource**

Describes a JavaScript resource used to collect verification data.

### NonLinearAds

Represents non-linear ads within a [Creative](#creative).

#### nonLinears

The non-linear ads.

Type: [Array](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array)<[NonLinear](#nonlinear)>

#### trackingEvents

The event-tracking configuration.

Type: [TrackingEvents](#trackingevents)

### TrackingEvent

Represents an event to be tracked.

#### offset

The time offset for this event configuration.

Type: TimeOffset

#### uri

The tracking URI for this event configuration.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

### RelativeTimeOffset

**Extends AbstractTimeOffset**

Represents a time offset expressed as a percentage (between 0 and 100).

### SortedListItem

Represents an item in a [SortedList](#sortedlist). Base class for [Ad](Ad) and
[Creative](#creative).

#### sequence

The sequence number of this item within its parent.

Type: [number](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number)

### Survey

Represents survey information for data collection.

#### type

The MIME type of the resource being served.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

#### uri

The URI to any resource relating to an integrated survey.

Type: [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String)

## TODO

The main thing that's missing is **validation**. There are a few steps to this:

-   Use [validator](https://www.npmjs.com/package/validator) to check all values
    passed to setters.
-   Verify that every required property is set.
-   Write tests for the validation code.
-   Enclose all validation code in marker comments (e.g., `// <strict>`). This
    will allow us to strip it out and produce a lightweight "loose" build without
    any validation, making tags load faster.

PRs welcome!

## Maintainers

-   [Tim De Pauw](https://github.com/timdp)
-   [Christophe Bonello](https://github.com/cbonello)

## License

MIT


text:
package org.springframework.boot.cli.compiler;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.junit.Test;
import org.springframework.boot.cli.compiler.grape.RepositoryConfiguration;
import org.springframework.boot.cli.util.SystemProperties;

import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertThat;

/**
 * Tests for {@link RepositoryConfigurationFactory}
 *
 * @author Andy Wilkinson
 */
public class RepositoryConfigurationFactoryTests {

	@Test
	public void defaultRepositories() {
		SystemProperties.doWithSystemProperties(new Runnable() {
			@Override
			public void run() {
				List<RepositoryConfiguration> repositoryConfiguration = RepositoryConfigurationFactory
						.createDefaultRepositoryConfiguration();
				assertRepositoryConfiguration(repositoryConfiguration, "central",
						"local", "spring-snapshot", "spring-milestone");
			}
		}, "user.home:src/test/resources/maven-settings/basic");
	}

	@Test
	public void snapshotRepositoriesDisabled() {
		SystemProperties.doWithSystemProperties(
				new Runnable() {
					@Override
					public void run() {
						List<RepositoryConfiguration> repositoryConfiguration = RepositoryConfigurationFactory
								.createDefaultRepositoryConfiguration();
						assertRepositoryConfiguration(repositoryConfiguration, "central",
								"local");
					}
				}, "user.home:src/test/resources/maven-settings/basic",
				"disableSpringSnapshotRepos:true");
	}

	@Test
	public void activeByDefaultProfileRepositories() {
		SystemProperties.doWithSystemProperties(new Runnable() {
			@Override
			public void run() {
				List<RepositoryConfiguration> repositoryConfiguration = RepositoryConfigurationFactory
						.createDefaultRepositoryConfiguration();
				assertRepositoryConfiguration(repositoryConfiguration, "central",
						"local", "spring-snapshot", "spring-milestone",
						"active-by-default");
			}
		}, "user.home:src/test/resources/maven-settings/active-profile-repositories");
	}

	@Test
	public void activeByPropertyProfileRepositories() {
		SystemProperties.doWithSystemProperties(
				new Runnable() {
					@Override
					public void run() {
						List<RepositoryConfiguration> repositoryConfiguration = RepositoryConfigurationFactory
								.createDefaultRepositoryConfiguration();
						assertRepositoryConfiguration(repositoryConfiguration, "central",
								"local", "spring-snapshot", "spring-milestone",
								"active-by-property");
					}
				},
				"user.home:src/test/resources/maven-settings/active-profile-repositories",
				"foo:bar");
	}

	private void assertRepositoryConfiguration(
			List<RepositoryConfiguration> configurations, String... expectedNames) {
		assertThat(configurations, hasSize(expectedNames.length));
		Set<String> actualNames = new HashSet<String>();
		for (RepositoryConfiguration configuration : configurations) {
			actualNames.add(configuration.getName());
		}
		assertThat(actualNames, hasItems(expectedNames));
	}
}