text:
using System;
using System.IO;
using System.Xml;
using Abp.Reflection.Extensions;
using Castle.Core.Logging;
using log4net;
using log4net.Config;
using log4net.Repository;

namespace Abp.Castle.Logging.Log4Net
{
    public class Log4NetLoggerFactory : AbstractLoggerFactory
    {
        internal const string DefaultConfigFileName = "log4net.config";
        private readonly ILoggerRepository _loggerRepository;

        public Log4NetLoggerFactory()
            : this(DefaultConfigFileName)
        {
        }

        public Log4NetLoggerFactory(string configFileName)
        {
            _loggerRepository = LogManager.CreateRepository(
                typeof(Log4NetLoggerFactory).GetAssembly(),
                typeof(log4net.Repository.Hierarchy.Hierarchy)
            );

            var log4NetConfig = new XmlDocument();
            log4NetConfig.Load(File.OpenRead(configFileName));
            XmlConfigurator.Configure(_loggerRepository, log4NetConfig["log4net"]);
        }

        public Log4NetLoggerFactory(string configFileName, bool reloadOnChange)
        {
            _loggerRepository = LogManager.CreateRepository(
                typeof(Log4NetLoggerFactory).GetAssembly(),
                typeof(log4net.Repository.Hierarchy.Hierarchy)
            );

            if (reloadOnChange)
            {
                XmlConfigurator.ConfigureAndWatch(_loggerRepository, new FileInfo(configFileName));
            }
            else
            {
                var log4NetConfig = new XmlDocument();
                log4NetConfig.Load(File.OpenRead(configFileName));
                XmlConfigurator.Configure(_loggerRepository, log4NetConfig["log4net"]);
            }
        }

        public override ILogger Create(string name)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }

            return new Log4NetLogger(LogManager.GetLogger(_loggerRepository.Name, name), this);
        }

        public override ILogger Create(string name, LoggerLevel level)
        {
            throw new NotSupportedException("Logger levels cannot be set at runtime. Please review your configuration file.");
        }
    }
}


text:
class GridLayout
{
    ImGui::ImVec2 screen_size_;
    ImGui::ImVec2 grid_division_;

    int menu_height_ { 20 };

public:
    bool active { true };

    GridLayout(
        const ImGui::ImVec2& screen_size,
        ImGui::ImVec2 grid_division = ImVec2( 10, 10 ),
        int menu_height = 20 );

    void placeNextWindow(
        const ImGui::ImVec2& corner1,
        const ImGui::ImVec2& corner2,
        const char* mode ,
        int border = 1 ) const;

    void resize( const ImGui::ImVec2& screen_size );
};

redpajama_set_name: RedPajamaGithub


text:
import Config from '../../config';
import { writeFile } from 'fs';
import { join } from 'path';

const nodeResolve = require('rollup-plugin-node-resolve');
const commonjs = require('rollup-plugin-commonjs');
const includePaths = require('rollup-plugin-includepaths');
const rollup = require('rollup');

const config = {
  entry: join(Config.TMP_DIR, Config.BOOTSTRAP_FACTORY_PROD_MODULE),
  sourceMap: true,
  treeshake: true,
  moduleName: 'main',
  plugins: [
    includePaths({
      include: {},
      paths: [join(Config.TMP_DIR, 'app')],
      external: [],
      extensions: ['.js', '.json', '.html', '.ts']
    }),
    nodeResolve({
      jsnext: true, main: true, module: true
    }),
    commonjs({
      include: 'node_modules/**',
      namedExports: {
        // 'node_modules/immutable/dist/immutable.js': [ 'Map', 'Set', 'List', 'fromJS' ],
        // 'node_modules/ng2-dragula/ng2-dragula.js': [ 'DragulaModule', 'DragulaService' ]
      }
    })
  ]
};

export = (done: any) => {
  rollup.rollup(config)
    .then((bundle: any) => {
      const result = bundle.generate({
        format: 'iife'
      });
      const path = join(Config.TMP_DIR, 'bundle.js');
      writeFile(path, result.code, (error: any) => {
        if (error) {
          console.error(error);
          process.exit(0);
        }
        done();
      });
    })
    .catch((error: any) => {
      console.error(error);
      process.exit(0);
    });
};


text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.

package com.azure.analytics.synapse.artifacts.models;

import com.azure.core.annotation.Fluent;
import com.azure.core.annotation.JsonFlatten;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.JsonTypeName;
import java.util.List;
import java.util.Map;

/** HDInsight Spark activity. */
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonTypeName("HDInsightSpark")
@JsonFlatten
@Fluent
public class HDInsightSparkActivity extends ExecutionActivity {
    /*
     * The root path in 'sparkJobLinkedService' for all the job's files. Type: string (or Expression with resultType
     * string).
     */
    @JsonProperty(value = "typeProperties.rootPath", required = true)
    private Object rootPath;

    /*
     * The relative path to the root folder of the code/package to be executed. Type: string (or Expression with
     * resultType string).
     */
    @JsonProperty(value = "typeProperties.entryFilePath", required = true)
    private Object entryFilePath;

    /*
     * The user-specified arguments to HDInsightSparkActivity.
     */
    @JsonProperty(value = "typeProperties.arguments")
    private List<Object> arguments;

    /*
     * Debug info option.
     */
    @JsonProperty(value = "typeProperties.getDebugInfo")
    private HDInsightActivityDebugInfoOption getDebugInfo;

    /*
     * The storage linked service for uploading the entry file and dependencies, and for receiving logs.
     */
    @JsonProperty(value = "typeProperties.sparkJobLinkedService")
    private LinkedServiceReference sparkJobLinkedService;

    /*
     * The application's Java/Spark main class.
     */
    @JsonProperty(value = "typeProperties.className")
    private String className;

    /*
     * The user to impersonate that will execute the job. Type: string (or Expression with resultType string).
     */
    @JsonProperty(value = "typeProperties.proxyUser")
    private Object proxyUser;

    /*
     * Spark configuration property.
     */
    @JsonProperty(value = "typeProperties.sparkConfig")
    private Map<String, Object> sparkConfig;

    /**
     * Get the rootPath property: The root path in 'sparkJobLinkedService' for all the job's files. Type: string (or
     * Expression with resultType string).
     *
     * @return the rootPath value.
     */
    public Object getRootPath() {
        return this.rootPath;
    }

    /**
     * Set the rootPath property: The root path in 'sparkJobLinkedService' for all the job's files. Type: string (or
     * Expression with resultType string).
     *
     * @param rootPath the rootPath value to set.
     * @return the HDInsightSparkActivity object itself.
     */
    public HDInsightSparkActivity setRootPath(Object rootPath) {
        this.rootPath = rootPath;
        return this;
    }

    /**
     * Get the entryFilePath property: The relative path to the root folder of the code/package to be executed. Type:
     * string (or Expression with resultType string).
     *
     * @return the entryFilePath value.
     */
    public Object getEntryFilePath() {
        return this.entryFilePath;
    }

    /**
     * Set the entryFilePath property: The relative path to the root folder of the code/package to be executed. Type:
     * string (or Expression with resultType string).
     *
     * @param entryFilePath the entryFilePath value to set.
     * @return the HDInsightSparkActivity object itself.
     */
    public HDInsightSparkActivity setEntryFilePath(Object entryFilePath) {
        this.entryFilePath = entryFilePath;
        return this;
    }

    /**
     * Get the arguments property: The user-specified arguments to HDInsightSparkActivity.
     *
     * @return the arguments value.
     */
    public List<Object> getArguments() {
        return this.arguments;
    }

    /**
     * Set the arguments property: The user-specified arguments to HDInsightSparkActivity.
     *
     * @param arguments the arguments value to set.
     * @return the HDInsightSparkActivity object itself.
     */
    public HDInsightSparkActivity setArguments(List<Object> arguments) {
        this.arguments = arguments;
        return this;
    }

    /**
     * Get the getDebugInfo property: Debug info option.
     *
     * @return the getDebugInfo value.
     */
    public HDInsightActivityDebugInfoOption getGetDebugInfo() {
        return this.getDebugInfo;
    }

    /**
     * Set the getDebugInfo property: Debug info option.
     *
     * @param getDebugInfo the getDebugInfo value to set.
     * @return the HDInsightSparkActivity object itself.
     */
    public HDInsightSparkActivity setGetDebugInfo(HDInsightActivityDebugInfoOption getDebugInfo) {
        this.getDebugInfo = getDebugInfo;
        return this;
    }

    /**
     * Get the sparkJobLinkedService property: The storage linked service for uploading the entry file and dependencies,
     * and for receiving logs.
     *
     * @return the sparkJobLinkedService value.
     */
    public LinkedServiceReference getSparkJobLinkedService() {
        return this.sparkJobLinkedService;
    }

    /**
     * Set the sparkJobLinkedService property: The storage linked service for uploading the entry file and dependencies,
     * and for receiving logs.
     *
     * @param sparkJobLinkedService the sparkJobLinkedService value to set.
     * @return the HDInsightSparkActivity object itself.
     */
    public HDInsightSparkActivity setSparkJobLinkedService(LinkedServiceReference sparkJobLinkedService) {
        this.sparkJobLinkedService = sparkJobLinkedService;
        return this;
    }

    /**
     * Get the className property: The application's Java/Spark main class.
     *
     * @return the className value.
     */
    public String getClassName() {
        return this.className;
    }

    /**
     * Set the className property: The application's Java/Spark main class.
     *
     * @param className the className value to set.
     * @return the HDInsightSparkActivity object itself.
     */
    public HDInsightSparkActivity setClassName(String className) {
        this.className = className;
        return this;
    }

    /**
     * Get the proxyUser property: The user to impersonate that will execute the job. Type: string (or Expression with
     * resultType string).
     *
     * @return the proxyUser value.
     */
    public Object getProxyUser() {
        return this.proxyUser;
    }

    /**
     * Set the proxyUser property: The user to impersonate that will execute the job. Type: string (or Expression with
     * resultType string).
     *
     * @param proxyUser the proxyUser value to set.
     * @return the HDInsightSparkActivity object itself.
     */
    public HDInsightSparkActivity setProxyUser(Object proxyUser) {
        this.proxyUser = proxyUser;
        return this;
    }

    /**
     * Get the sparkConfig property: Spark configuration property.
     *
     * @return the sparkConfig value.
     */
    public Map<String, Object> getSparkConfig() {
        return this.sparkConfig;
    }

    /**
     * Set the sparkConfig property: Spark configuration property.
     *
     * @param sparkConfig the sparkConfig value to set.
     * @return the HDInsightSparkActivity object itself.
     */
    public HDInsightSparkActivity setSparkConfig(Map<String, Object> sparkConfig) {
        this.sparkConfig = sparkConfig;
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public HDInsightSparkActivity setLinkedServiceName(LinkedServiceReference linkedServiceName) {
        super.setLinkedServiceName(linkedServiceName);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public HDInsightSparkActivity setPolicy(ActivityPolicy policy) {
        super.setPolicy(policy);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public HDInsightSparkActivity setName(String name) {
        super.setName(name);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public HDInsightSparkActivity setDescription(String description) {
        super.setDescription(description);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public HDInsightSparkActivity setDependsOn(List<ActivityDependency> dependsOn) {
        super.setDependsOn(dependsOn);
        return this;
    }

    /** {@inheritDoc} */
    @Override
    public HDInsightSparkActivity setUserProperties(List<UserProperty> userProperties) {
        super.setUserProperties(userProperties);
        return this;
    }
}


text:
![](./image/glide_logo.png)

## 功能介绍
Android图片加载框架,支持Video,Gif,SVG格式,支持缩略图请求,打造更好的图片列表滑动体验。Glide有生命周期的概念,可以与Activity和Fragment绑定,默认使用基于HttpUrlConnection的自定义网络层,支持Okhttp和Volley,友好的内存管理和磁盘管理。

## 简单用法
```java
Glide.with(context).load(url).into(imageView);
```

## 框架图
![](./image/glide_module.jpg)

## 基本概念
**Glide**
使用RequestBuilder创建Request的静态接口,并持有Engine,BitmapPool, MemoryCache,各种解码器,转换器。实现了ComponentCallbacks2,注册了低内存回调。当内存不足时,进行内存清理。回调发成在RequestManagerFragment的onLowMemory和onTrimMemory方法中。

**GlideBuild**
为Glide提供一些默认配置,比如Engine, BitmapPool, MemoryCache, DiskCache, DecodeFormat, ExecutorService(包括sourceService, diskCacheService);

**GlideModule**
可以通过GlideBuild和Glide进行一些延迟配置和Components的注册。
注意:所有的实现的GlideBuild必须是public的,并且只拥有一个空的构造函数,以便Glide懒加载的时候可以通过反射调用。
```java
@Override
public void applyOptions(Context context, GlideBuilder glideBuilder) {
    glideBuilder.setDecodeFormat(DecodeFormat.PREFER_ARGB_8888);
    glideBuilder.setDiskCache(new DiskCache.Factory() {
        @Override
        public DiskCache build() {
            return getDiskCache();
        }
    });
}

@Override
public void registerComponents(Context context, Glide glide) {
    // 内存策略,有低、正常、高三种配置
    glide.setMemoryCategory(MemoryCategory.NORMAL);

    // 给View设置一个唯一的TAG ID
    ViewTarget.setTagId(R.id.glide_request);

    // Other components
    GlideUtils.fixBitmapDrawError(context);
}
```
**Engine**
调度器:任务的创建,发起,回调,资源的管理。

**DecodeerJob**
调度任务的核心类,处理原始的数据或缓存数据,应用转换动画,以及转码。

**ModeLoader**
各种资源的ModelLoader<Model, Data>,将任意复杂的Model转换为可以被Decode的数据类型,允许Model结合View的尺寸,获取特定大小资源。

**Resouce**
对资源进行包装的接口,提供get,recycle,getSize,以及原始类的getResourceClass方法。Resource包下也就是各种资源:bitmap,bytes,drawable,file,gif,以及相关解码器,转换器。

**Target**
request 的载体,各种资源对应的加载类,含有生命周期的回调方法,方便开发人员进行相应的准备以及资源回收工作。

**Request**
每次请求都会新建立一个xxxRequest类

**ThumbnailRequestCoordinator**
请求协调器,包含两个请求:缩略图请求+完整图片请求.

**Register**
对Glide所支持的Encoder,Decoder,Transcoder组件进行注册, 因为Glide所支持的数据类型太多,把每一种的数据类型及相应处理方式的组合形象化为一种组件的概念。通过registry的方式管理。
如下,注册了将使用BitmapDrawableTranscoder将Bitmap转换为BitmapDrawable的组件。
```java
transcoderRegistry.register(Bitmap.class, GlideBitmapDrawable.class,
      new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool));
transcoderRegistry.register(GifBitmapWrapper.class, GlideDrawable.class,
      new GifBitmapWrapperDrawableTranscoder(newGlideBitmapDrawableTranscoder(context.getResources(), bitmapPool)));
```
**相关概念**
* data :代表原始的,未修改过的资源,对应 dataClass
* resource : 修改过的资源,对应 resourceClass
* transcoder : 资源转换器,比如 BitmapBytesTranscoder(Bitmap 转换为 Bytes),GifDrawableBytesTranscoder
* ResourceEncoder : 持久化数据的接口,注意,该类并不与 decoder 相对应,而是用于本地缓存的接口
* ResourceDecoder : 数据解码器,比如 ByteBufferGifDecoder(将 ByteBuffer 转换为 Gif),StreamBitmapDecoder(Stream 转换为 Bitmap)
* ResourceTranscoder : 资源转换器,将给定的资源类型,转换为另一种资源类型,比如将 Bitmap 转换为 Drawable,Bitmap 转换为 Bytes
* Transformation : 比如对图片进行 FitCenter,CircleCrop,CenterCrop 的 transformation,或者根据给定宽高对 Bitmap 进行处理的 BitmapDrawableTransformation

## 基本流程
![](./image/glide_base_flow.jpg)

### 初始化
**初始化GlideBuild**
```java
// 初始化默认配置
Glide createGlide() {
    // 获取数据源线程池,数量为当前可用最大值
    if (sourceService == null) {
        final int cores = Math.max(1, Runtime.getRuntime().availableProcessors());
        sourceService = new FifoPriorityThreadPoolExecutor(cores);
    }

    // 获取磁盘缓存线程池,数量为1
    if (diskCacheService == null) {
        diskCacheService = new FifoPriorityThreadPoolExecutor(1);
    }

    // 根据屏幕的宽和高,图片的像素,计算bitmap pool的大小
    MemorySizeCalculator calculator = new MemorySizeCalculator(context);
    if (bitmapPool == null) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            int size = calculator.getBitmapPoolSize();
            bitmapPool = new LruBitmapPool(size);
        } else {
            bitmapPool = new BitmapPoolAdapter();
        }
    }

    // 内存缓存
    if (memoryCache == null) {
        memoryCache = new LruResourceCache(calculator.getMemoryCacheSize());
    }

    // 磁盘缓存
    if (diskCacheFactory == null) {
        diskCacheFactory = new InternalCacheDiskCacheFactory(context);
    }

    // 不对外提供接口
    if (engine == null) {
        engine = new Engine(memoryCache, diskCacheFactory, diskCacheService, sourceService);
    }

    // 默认RGB_565格式
    if (decodeFormat == null) {
        decodeFormat = DecodeFormat.DEFAULT;
    }

    return new Glide(engine, memoryCache, bitmapPool, context, decodeFormat);
}
```
**初始化Glide**

Glide初始化部分变量,注册默认components,用户也可以自定义注册
```java
Glide(Engine engine, MemoryCache memoryCache, BitmapPool bitmapPool, Context context, DecodeFormat decodeFormat) {
        this.engine = engine;
        this.bitmapPool = bitmapPool;
        this.memoryCache = memoryCache;
        this.decodeFormat = decodeFormat;
        loaderFactory = new GenericLoaderFactory(context);
        mainHandler = new Handler(Looper.getMainLooper());
        bitmapPreFiller = new BitmapPreFiller(memoryCache, bitmapPool, decodeFormat);

        // 注册data和resource的decoder的encoder,包括bitmap,File,ParcelFileDescriptor, ImageVideo,Gif,ImageVideoGif
        dataLoadProviderRegistry = new DataLoadProviderRegistry();

        StreamBitmapDataLoadProvider streamBitmapLoadProvider =
                new StreamBitmapDataLoadProvider(bitmapPool, decodeFormat);
        dataLoadProviderRegistry.register(InputStream.class, Bitmap.class, streamBitmapLoadProvider);

        FileDescriptorBitmapDataLoadProvider fileDescriptorLoadProvider =
                new FileDescriptorBitmapDataLoadProvider(bitmapPool, decodeFormat);
        dataLoadProviderRegistry.register(ParcelFileDescriptor.class, Bitmap.class, fileDescriptorLoadProvider);

        ImageVideoDataLoadProvider imageVideoDataLoadProvider =
                new ImageVideoDataLoadProvider(streamBitmapLoadProvider, fileDescriptorLoadProvider);
        dataLoadProviderRegistry.register(ImageVideoWrapper.class, Bitmap.class, imageVideoDataLoadProvider);

        GifDrawableLoadProvider gifDrawableLoadProvider =
                new GifDrawableLoadProvider(context, bitmapPool);
        dataLoadProviderRegistry.register(InputStream.class, GifDrawable.class, gifDrawableLoadProvider);

        dataLoadProviderRegistry.register(ImageVideoWrapper.class, GifBitmapWrapper.class,
                new ImageVideoGifDrawableLoadProvider(imageVideoDataLoadProvider, gifDrawableLoadProvider, bitmapPool));

        dataLoadProviderRegistry.register(InputStream.class, File.class, new StreamFileDataLoadProvider());

        // 注册ModelLoaderFactory,获取各种类型资源
        register(File.class, ParcelFileDescriptor.class, new FileDescriptorFileLoader.Factory());
        register(File.class, InputStream.class, new StreamFileLoader.Factory());
        register(int.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
        register(int.class, InputStream.class, new StreamResourceLoader.Factory());
        register(Integer.class, ParcelFileDescriptor.class, new FileDescriptorResourceLoader.Factory());
        register(Integer.class, InputStream.class, new StreamResourceLoader.Factory());
        register(String.class, ParcelFileDescriptor.class, new FileDescriptorStringLoader.Factory());
        register(String.class, InputStream.class, new StreamStringLoader.Factory());
        register(Uri.class, ParcelFileDescriptor.class, new FileDescriptorUriLoader.Factory());
        register(Uri.class, InputStream.class, new StreamUriLoader.Factory());
        register(URL.class, InputStream.class, new StreamUrlLoader.Factory());
        // 这个是Glide封装的网络请求器
        register(GlideUrl.class, InputStream.class, new HttpUrlGlideUrlLoader.Factory());
        register(byte[].class, InputStream.class, new StreamByteArrayLoader.Factory());

        // 资源转换器,Bitmap和Gif
        transcoderRegistry.register(Bitmap.class, GlideBitmapDrawable.class,
                new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool));
        transcoderRegistry.register(GifBitmapWrapper.class, GlideDrawable.class,
                new GifBitmapWrapperDrawableTranscoder(
                        new GlideBitmapDrawableTranscoder(context.getResources(), bitmapPool)));

        // Bitmap的转型,包括宽高,缩放类型
        bitmapCenterCrop = new CenterCrop(bitmapPool);
        drawableCenterCrop = new GifBitmapWrapperTransformation(bitmapPool, bitmapCenterCrop);
        bitmapFitCenter = new FitCenter(bitmapPool);
        drawableFitCenter = new GifBitmapWrapperTransformation(bitmapPool, bitmapFitCenter);
    }
```
### 建立请求
**创建RequestManager**
```java
Glide.with(context);
```
Context支持五类参数
* android.app.Activity
* android.support.v4.app.FragmentActivity
* android.app.Fragment
* android.support.v4.app.Fragment
* Context

创建流程
* 创建RequestManagerRetriever单例,实例化一个RequestMnanger,管理Activity和Fragment生命周期。
* 通过Activity和Fragment获取FragmentManager, 并创建一个对应的空页面RequestManagerFragment,添加到FragmentTransaction。
* RequestManagerFragment,管理子RequestManagerFragment,并实例化一个ActivityFragmentLifecycle,并将它传递给RequestManager。
```java
// RequestManagerFragment生命周期管理
@Override
   public void onStart() {
       super.onStart();
       lifecycle.onStart();
   }

   @Override
   public void onStop() {
       super.onStop();
       lifecycle.onStop();
   }

   @Override
   public void onDestroy() {
       super.onDestroy();
       lifecycle.onDestroy();
   }
```

**创建Request**

支持的类型有网络图片,本地图片,应用资源,二进制流,Uri对象等。

加载普通图片,创建DrawableTypeRequest,所有Request的基类为GenericRequestBuilder。
```java
Glide.with(context).load(url);
```

RequestManager实例化DrawableTypeRequest时,会将lifecycle传递给DrawableTypeRequest
```java
return optionsApplier.apply(
             new DrawableTypeRequest<T>(modelClass, streamModelLoader, fileDescriptorModelLoader, context,
                     glide, requestTracker, lifecycle, optionsApplier));
```

DrawableTypeRequest提供类型转换,做一些特殊处理,例如生成bitmap,加载gif,下载图片等。
```java
// 转换为BitmapTypeRequest
asBitmap();

// 转换为GifTypeRequest
asGif();

// 转换为FutureTarget<File>
downloadOnly();
```

**创建Target**

设置资源的Target,并创建,绑定,跟踪,发起请求。可创建多种Target,例如ImageView、自定义Target等。
```java
// 将图片加载到ImageView
into(ImageView);

// 自定义Target,得到图片加载各个状态的和生命周期回调。
into(Y target);

// 不推荐,使用override(int width, int height).into(target)替代
into(width, height);
```

### Engine任务调度
主要函数
* loadFromCache(Key key, boolean isMemoryCacheable)
  从内存缓存中获取资源,获取成功后会放入到 activeResources 中

* loadFromActiveResources
从存活的资源中加载资源,资源加载完成后,再将这个缓存数据放到一个 value 为软引用的 activeResources map 中,并计数引用数,在图片加载完成后进行判断,如果引用计数为空则回收掉。

* getReferenceQueue
activeResources 是一个持有缓存 WeakReference 的 Map 集合。ReferenceQueue 就是提供资源 WeakReference 的虚引用队列。 activeResources.put(key, new ResourceWeakReference(key, cached, getReferenceQueue()));
这里要提的是负责清除 WeakReference 被回收的 activeResources 资源的实现:
使用到了 MessageQueue.IdleHandler,源码的注释:当一个线程等待更多 message 的时候会触发该回调,就是 messageQuene 空闲的时候会触发该回调

* load( GlideContext glideContext, Object model, Key signature, int width, int height, Class resourceClass, Class transcodeClass, Priority priority, DiskCacheStrategy diskCacheStrategy, Map, Transformation<?>> transformations, boolean isTransformationRequired, Options options, boolean isMemoryCacheable, ResourceCallback cb)
Target.into()、preload、download时,会调度任务

```Java
// load时,会先进行MemoryCache获取,再去调度EngineJob
EngineResource<?> cached = loadFromCache(key, isMemoryCacheable);
  if (cached != null) {
      cb.onResourceReady(cached);
      if (Log.isLoggable(TAG, Log.VERBOSE)) {
          logWithTimeAndKey("Loaded resource from cache", startTime, key);
      }
      return null;
  }
```

真正的开始加载资源,看下面的流程图
![](./image/glide_preload_flow.jpg)

### EngineJob
调度DecodeJob,添加、移除资源回调,并回调通知。

* start(EngineRunnable runnable);
开始EngineRunnable,调度decodeJob

* MainThreadCallback
最终的结果,回调主线程

```Java
// Engine.load() 代码片段
EngineJob engineJob = engineJobFactory.build(key, isMemoryCacheable);
DecodeJob<T, Z, R> decodeJob = new DecodeJob<T, Z, R>(key, width, height, fetcher, loadProvider, transformation,
        transcoder, diskCacheProvider, diskCacheStrategy, priority);
EngineRunnable runnable = new EngineRunnable(engineJob, decodeJob, priority);
jobs.put(key, engineJob);
engineJob.addCallback(cb);

// EngineJob调用执行DecodeJob
engineJob.start(runnable);

// cb
public interface ResourceCallback {
    void onResourceReady(Resource<?> resource);
    void onException(Exception e);
}
// RequestBuild的listener就是通过ResourceCallback进行回调
requestBuilder.listener(new RequestListener<String, GlideDrawable>())
```

### EngineRunnable
实现Runnable方法,真正任务执行的地方,持有EngineRunnableManager和DecodeJob

// 任务调度逻辑
```Java
@Override
public void run() {
    // ...
    try {
        resource = decode();
    } catch (Exception e) {
        if (Log.isLoggable(TAG, Log.VERBOSE)) {
            Log.v(TAG, "Exception decoding", e);
        }
        exception = e;
    }

    // ...
    if (resource == null) {
        onLoadFailed(exception);
    } else {
        onLoadComplete(resource);
    }
}
```

// 加载图片逻辑
```Java
// 优先从Cache中获取数据
private Resource<?> decode() throws Exception {
   if (isDecodingFromCache()) {
       return decodeFromCache();
   } else {
       return decodeFromSource();
   }
}

// 加载成功,回调onResourceReady方法
private void onLoadComplete(Resource resource) {
   manager.onResourceReady(resource);
}

// 加载缓存失败,则从Source中获取; 加载Source失败,回调onException。
private void onLoadFailed(Exception e) {
   if (isDecodingFromCache()) {
       stage = Stage.SOURCE;
       // 更改来源,重新执行任务
       manager.submitForSource(this);
   } else {
       manager.onException(e);
   }
}
```

### DecodeJob

// 加载Source流程
```Java
// 获取数据
final A data = fetcher.loadData(priority);

// 解码
decoded = loadProvider.getSourceDecoder().decode(data, width, height);

// 转换
Resource<T> transformed = transformation.transform(decoded, width, height);

// 转码
Resource result = transcoder.transcode(transformed);
```

// 加载Cache流程
```Java
// 加载Cache
Resource<T> transformed = loadFromCache(resultKey);
Resource<Z> result = transcode(transformed);

// Cache中Result为空,则从Cache的Source中获取,再进行转换、转码
Resource<T> decoded = loadFromCache(resultKey.getOriginalKey());
Resource<T> transformed = transformation.transform(decoded, width, height);
Resource result = transcoder.transcode(transformed);
```

**DiskCache key需要注意的地方**
Key有二类,一类为原始Source的Key,另一种为Result的key,二者不一样。使用Download方法下载图片后,获取Cache时需要注意。

### ModelLoader
ModelLoader 是一个工厂接口。将任意复杂的 model 转换为准确具体的可以被 DataFetcher 获取的数据类型。每一个 model 内部实现了一个 ModelLoaderFactory,内部实现就是将 model 转换为 Data

```Java
// 获取DataFetcher
public interface ModelLoader<T, Y> {
    DataFetcher<Y> getResourceFetcher(T model, int width, int height);
}

// 获取Source数据
public interface DataFetcher<T> {
  T loadData(Priority priority) throws Exception;
}
```

## Glide数据处理流程

**主要成员变量**
- ModelLoaderRegistry :注册所有数据加载的 loader
- ResourceDecoderRegistry:注册所有资源转换的 decoder
- TranscoderRegistry:注册所有对 decoder 之后进行特殊处理的 transcoder
- ResourceEncoderRegistry:注册所有持久化 resource(处理过的资源)数据的 encoder
- EncoderRegistry : 注册所有的持久化原始数据的 encoder

**标准的数据处理流程:**
![数据处理流程图](image/glide_data_process_flow.jpg)

Glide 在初始化的时候,通过 Registry 注册以下所有组件, 每种组件由功能及处理的资源类型组成:

组件| 构成
:--|:-- |
loader |   model+data+ModelLoaderFactory
decoder |    dataClass+resourceClass+decoder
transcoder |  resourceClass+transcodeClass
encoder  |    dataClass+encoder
resourceEncoder  | resourceClass + encoder
rewind  |    缓冲区处理

Decoder | 数据源 | 解码后的资源 |
:--|:-- |:--  |
BitmapDrawableDecoder   | 	Bitmap              |		Drawable
StreamBitmapDecoder     |  	InputStream         |  	Bitmap
ByteBufferBitmapDecoder |	  ByteBuffer          |  	Bitmap
GifFrameResourceDecoder | 	GifDecoder          |	 	Bitmap
StreamGifDecoder 	      |	  InputStream         | 	GifDrawable
ByteBufferGifDecoder	  |	  ByteBuffer          |	  Gif
SvgDecoder		          |		InputStream	        |   SVG
VideoBitmapDecoder 	    |	  ParcelFileDescriptor|	  Bitmap
FileDecoder             |		File                | 	file

Transcoder | 数据源 | 转换后的资源 |
:--|:-- |:--  |
BitmapBytesTranscoder   | 	Bitmap              |		Bytes
BitmapDrawableTranscoder     |  	Bitmap         |  	Drawable
GifDrawableBytesTranscoder |	  GifDrawable          |  	Bytes
SvgDrawableTranscoder | 	Svg          |	 	Drawable

## 附录

### 遗留问题
1. 懒加载
  可以使用,解决某些glide.setMemoryCategory(MemoryCategory.NORMAL)需要在主线程运行的问题
2. 缩略图逻辑
  Glide的缩略图加载逻辑是先加载小图,最终显示大图加载的结果。
3. 图片加载崩溃
  TODO,为什么要去判断资源是否释放?需解决此问题。
4. 内存过高问题,超过200M
  Glide的MemoryCache并不高,普通的配置占比为33%~40%,引起内存过高的原因是页面过多,且单个页面占用内存高。
5. 解决Glide下载指定宽高图片
  TODO,做到只缓存Result,不保存Source。

### 参考资料
* [Glide 源码解析](https://github.com/android-cn/android-open-project-analysis/tree/master/tool-lib/image-cache/glide)

### 图片加载框架
* [Android-Universal-Image-Loader](https://github.com/nostra13/Android-Universal-Image-Loader),个人发起的项目,Android早期开发比较火,于2015年停止维护。
* [Picasso](https://github.com/square/picasso),Square公司出品
* [Fresco](https://github.com/facebook/fresco),Facebook公司出品


text:
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE chapter SYSTEM "chapter.dtd">

<chapter>

    <copyright>
      <year>2011</year><year>2016</year>
      <holder>Ericsson AB. All Rights Reserved.</holder>
    </copyright>
    <legalnotice>
      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.

    </legalnotice>

    <title>Getting Started</title>
    <prepared></prepared>
    <docno></docno>
    <date></date>
    <rev></rev>
    <file>using_public_key.xml</file>

This section describes examples of how to use the
    Public Key API. Keys and certificates used in the following
    sections are generated only for testing the Public Key
    application.

Some shell printouts in the following examples
    are abbreviated for increased readability.

    <title>PEM Files</title>

Public-key data (keys, certificates, and so on) can be stored in
    Privacy Enhanced Mail (PEM) format.
    The PEM files have the following structure:

    <text>
    -----BEGIN <SOMETHING>-----
    <Attribute> : <Value>
    <Base64 encoded DER data>
    -----END <SOMETHING>-----
    <text>

A file can contain several <c>BEGIN/END</c> blocks. Text lines between
    blocks are ignored. Attributes, if present, are ignored except
    for <c>Proc-Type</c> and <c>DEK-Info</c>, which are used when <c>DER</c>
    data is encrypted.

      <title>DSA Private Key</title>

A DSA private key can look as follows:

      <note>
File handling is not done by the Public Key application.
</note>

      1> {ok, PemBin} = file:read_file("dsa.pem").
{ok,<<"-----BEGIN DSA PRIVATE KEY-----\nMIIBuw"...>>}

The following PEM file has only one entry, a private DSA key:

      2> [DSAEntry] =  public_key:pem_decode(PemBin).
[{'DSAPrivateKey',<<48,130,1,187,2,1,0,2,129,129,0,183,
                    179,230,217,37,99,144,157,21,228,204,
		    162,207,61,246,...>>,
		    not_encrypted}]

      3> Key = public_key:pem_entry_decode(DSAEntry).
#'DSAPrivateKey'{version = 0,
                 p = 12900045185019966618...6593,
                 q = 1216700114794736143432235288305776850295620488937,
                 g = 10442040227452349332...47213,
                 y = 87256807980030509074...403143,
                 x = 510968529856012146351317363807366575075645839654}

      <title>RSA Private Key with Password</title>

An RSA private key encrypted with a password can look as follows:

      1> {ok, PemBin} = file:read_file("rsa.pem").
{ok,<<"Bag Attribut"...>>}

The following PEM file has only one entry, a private RSA key:

    2>[RSAEntry] = public_key:pem_decode(PemBin).
[{'RSAPrivateKey',<<224,108,117,203,152,40,15,77,128,126,
                    221,195,154,249,85,208,202,251,109,
                    119,120,57,29,89,19,9,...>>,
                  {"DES-EDE3-CBC",<<"kÙeø¼pµL">>}}]

In this following example, the password is <c>"abcd1234"</c>:

    3> Key = public_key:pem_entry_decode(RSAEntry, "abcd1234").
    #'RSAPrivateKey'{version = 'two-prime',
                 modulus = 1112355156729921663373...2737107,
                 publicExponent = 65537,
                 privateExponent = 58064406231183...2239766033,
                 prime1 = 11034766614656598484098...7326883017,
                 prime2 = 10080459293561036618240...77738643771,
                 exponent1 = 77928819327425934607...22152984217,
                 exponent2 = 36287623121853605733...20588523793,
                 coefficient = 924840412626098444...41820968343,
                 otherPrimeInfos = asn1_NOVALUE}

    <title>X509 Certificates</title>

The following is an example of X509 certificates:

      1> {ok, PemBin} = file:read_file("cacerts.pem").
{ok,<<"-----BEGIN CERTIFICATE-----\nMIIC7jCCAl"...>>}

The following file includes two certificates:

      2> [CertEntry1, CertEntry2] = public_key:pem_decode(PemBin).
[{'Certificate',<<48,130,2,238,48,130,2,87,160,3,2,1,2,2,
                  9,0,230,145,97,214,191,2,120,150,48,13,
                  ...>>,
                not_encrypted},
 {'Certificate',<<48,130,3,200,48,130,3,49,160,3,2,1,2,2,1,
                  1,48,13,6,9,42,134,72,134,247,...>>,
                not_encrypted}]

Certificates can be decoded as usual:

      2> Cert = public_key:pem_entry_decode(CertEntry1).
#'Certificate'{
    tbsCertificate =
        #'TBSCertificate'{
            version = v3,serialNumber = 16614168075301976214,
            signature =
                #'AlgorithmIdentifier'{
                    algorithm = {1,2,840,113549,1,1,5},
                    parameters = <<5,0>>},
            issuer =
                {rdnSequence,
                    [[#'AttributeTypeAndValue'{
                          type = {2,5,4,3},
                          value = <<19,8,101,114,108,97,110,103,67,65>>}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,11},
                          value = <<19,10,69,114,108,97,110,103,32,79,84,80>>}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,10},
                          value = <<19,11,69,114,105,99,115,115,111,110,32,65,66>>}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,7},
                          value = <<19,9,83,116,111,99,107,104,111,108,109>>}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,6},
                          value = <<19,2,83,69>>}],
                     [#'AttributeTypeAndValue'{
                          type = {1,2,840,113549,1,9,1},
                          value = <<22,22,112,101,116,101,114,64,101,114,...>>}]]},
            validity =
                #'Validity'{
                    notBefore = {utcTime,"080109082929Z"},
                    notAfter = {utcTime,"080208082929Z"}},
            subject =
                {rdnSequence,
                    [[#'AttributeTypeAndValue'{
                          type = {2,5,4,3},
                          value = <<19,8,101,114,108,97,110,103,67,65>>}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,11},
                          value = <<19,10,69,114,108,97,110,103,32,79,84,80>>}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,10},
                          value = <<19,11,69,114,105,99,115,115,111,110,32,...>>}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,7},
                          value = <<19,9,83,116,111,99,107,104,111,108,...>>}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,6},
                          value = <<19,2,83,69>>}],
                     [#'AttributeTypeAndValue'{
                          type = {1,2,840,113549,1,9,1},
                          value = <<22,22,112,101,116,101,114,64,...>>}]]},
            subjectPublicKeyInfo =
                #'SubjectPublicKeyInfo'{
                    algorithm =
                        #'AlgorithmIdentifier'{
                            algorithm = {1,2,840,113549,1,1,1},
                            parameters = <<5,0>>},
                    subjectPublicKey =
                        {0,<<48,129,137,2,129,129,0,203,209,187,77,73,231,90,...>>}},
            issuerUniqueID = asn1_NOVALUE,
            subjectUniqueID = asn1_NOVALUE,
            extensions =
                [#'Extension'{
                     extnID = {2,5,29,19},
                     critical = true,
                     extnValue = [48,3,1,1,255]},
                 #'Extension'{
                     extnID = {2,5,29,15},
                     critical = false,
                     extnValue = [3,2,1,6]},
                 #'Extension'{
                     extnID = {2,5,29,14},
                     critical = false,
                     extnValue = [4,20,27,217,65,152,6,30,142|...]},
                 #'Extension'{
                     extnID = {2,5,29,17},
                     critical = false,
                     extnValue = [48,24,129,22,112,101,116,101|...]}]},
    signatureAlgorithm =
        #'AlgorithmIdentifier'{
            algorithm = {1,2,840,113549,1,1,5},
            parameters = <<5,0>>},
    signature =
    <<163,186,7,163,216,152,63,47,154,234,139,73,154,96,120,
    165,2,52,196,195,109,167,192,...>>}

Parts of certificates can be decoded with
      <c>public_key:der_decode/2</c>, using the ASN.1 type of that part.
      However, an application-specific certificate extension requires
      application-specific ASN.1 decode/encode-functions.
      In the recent example, the first value of <c>rdnSequence</c> is
      of ASN.1 type <c>'X520CommonName'. ({2,5,4,3} = ?id-at-commonName)</c>:

      public_key:der_decode('X520CommonName', <<19,8,101,114,108,97,110,103,67,65>>).
{printableString,"erlangCA"}

However, certificates can also be decoded using <c>pkix_decode_cert/2</c>,
      which can customize and recursively decode standard parts of a certificate:

      3>{_, DerCert, _} = CertEntry1.

      4> public_key:pkix_decode_cert(DerCert, otp).
#'OTPCertificate'{
    tbsCertificate =
        #'OTPTBSCertificate'{
            version = v3,serialNumber = 16614168075301976214,
            signature =
                #'SignatureAlgorithm'{
                    algorithm = {1,2,840,113549,1,1,5},
                    parameters = 'NULL'},
            issuer =
                {rdnSequence,
                    [[#'AttributeTypeAndValue'{
                          type = {2,5,4,3},
                          value = {printableString,"erlangCA"}}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,11},
                          value = {printableString,"Erlang OTP"}}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,10},
                          value = {printableString,"Ericsson AB"}}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,7},
                          value = {printableString,"Stockholm"}}],
                     [#'AttributeTypeAndValue'{type = {2,5,4,6},value = "SE"}],
                     [#'AttributeTypeAndValue'{
                          type = {1,2,840,113549,1,9,1},
                          value = "peter@erix.ericsson.se"}]]},
            validity =
                #'Validity'{
                    notBefore = {utcTime,"080109082929Z"},
                    notAfter = {utcTime,"080208082929Z"}},
            subject =
                {rdnSequence,
                    [[#'AttributeTypeAndValue'{
                          type = {2,5,4,3},
                          value = {printableString,"erlangCA"}}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,11},
                          value = {printableString,"Erlang OTP"}}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,10},
                          value = {printableString,"Ericsson AB"}}],
                     [#'AttributeTypeAndValue'{
                          type = {2,5,4,7},
                          value = {printableString,"Stockholm"}}],
                     [#'AttributeTypeAndValue'{type = {2,5,4,6},value = "SE"}],
                     [#'AttributeTypeAndValue'{
                          type = {1,2,840,113549,1,9,1},
                          value = "peter@erix.ericsson.se"}]]},
            subjectPublicKeyInfo =
                #'OTPSubjectPublicKeyInfo'{
                    algorithm =
                        #'PublicKeyAlgorithm'{
                            algorithm = {1,2,840,113549,1,1,1},
                            parameters = 'NULL'},
                    subjectPublicKey =
                        #'RSAPublicKey'{
                            modulus =
                                1431267547247997...37419,
                            publicExponent = 65537}},
            issuerUniqueID = asn1_NOVALUE,
            subjectUniqueID = asn1_NOVALUE,
            extensions =
                [#'Extension'{
                     extnID = {2,5,29,19},
                     critical = true,
                     extnValue =
                         #'BasicConstraints'{
                             cA = true,pathLenConstraint = asn1_NOVALUE}},
                 #'Extension'{
                     extnID = {2,5,29,15},
                     critical = false,
                     extnValue = [keyCertSign,cRLSign]},
                 #'Extension'{
                     extnID = {2,5,29,14},
                     critical = false,
                     extnValue = [27,217,65,152,6,30,142,132,245|...]},
                 #'Extension'{
                     extnID = {2,5,29,17},
                     critical = false,
                     extnValue = [{rfc822Name,"peter@erix.ericsson.se"}]}]},
    signatureAlgorithm =
        #'SignatureAlgorithm'{
            algorithm = {1,2,840,113549,1,1,5},
            parameters = 'NULL'},
    signature =
         <<163,186,7,163,216,152,63,47,154,234,139,73,154,96,120,
           165,2,52,196,195,109,167,192,...>>}

This call is equivalent to <c>public_key:pem_entry_decode(CertEntry1)</c>:

      5> public_key:pkix_decode_cert(DerCert, plain).
#'Certificate'{ ...}

    <title>Encoding Public-Key Data to PEM Format</title>

If you have public-key data and want to create a PEM file
    this can be done by calling functions
    <c>public_key:pem_entry_encode/2</c> and <c>pem_encode/1</c> and
    saving the result to a file. For example, assume that you have
    <c>PubKey = 'RSAPublicKey'{}</c>. Then you can create a PEM-"RSA PUBLIC KEY"
    file (ASN.1 type <c>'RSAPublicKey'</c>) or a PEM-"PUBLIC KEY" file
    (<c>'SubjectPublicKeyInfo'</c> ASN.1 type).

The second element of the PEM-entry is the ASN.1 <c>DER</c> encoded
    key data:

    1> PemEntry = public_key:pem_entry_encode('RSAPublicKey', RSAPubKey).
{'RSAPublicKey', <<48,72,...>>, not_encrypted}

2> PemBin = public_key:pem_encode([PemEntry]).
<<"-----BEGIN RSA PUBLIC KEY-----\nMEgC...>>

3> file:write_file("rsa_pub_key.pem", PemBin).
ok

or:

    1> PemEntry = public_key:pem_entry_encode('SubjectPublicKeyInfo', RSAPubKey).
{'SubjectPublicKeyInfo', <<48,92...>>, not_encrypted}

2> PemBin = public_key:pem_encode([PemEntry]).
<<"-----BEGIN PUBLIC KEY-----\nMFw...>>

3> file:write_file("pub_key.pem", PemBin).
ok

      <title>RSA Public-Key Cryptography</title>

Suppose you have the following private key and a corresponding public key:

       <list type="bulleted">
	 <item><c>PrivateKey = #'RSAPrivateKey{}'</c> and
	 the plaintext <c>Msg = binary()</c></item>
	 <item><c>PublicKey = #'RSAPublicKey'{}</c>
	 </item>
       </list>

Then you can proceed as follows:

Encrypt with the private key:

       RsaEncrypted = public_key:encrypt_private(Msg, PrivateKey),
Msg = public_key:decrypt_public(RsaEncrypted, PublicKey),

Encrypt with the public key:

       RsaEncrypted = public_key:encrypt_public(Msg, PublicKey),
Msg = public_key:decrypt_private(RsaEncrypted, PrivateKey),

      <note>
You normally do only one of the encrypt or decrypt operations,
      and the peer does the other. This normaly used in legacy applications
      as a primitive digital signature.

</note>

    <title>Digital Signatures</title>

Suppose you have the following private key and a corresponding public key:

    <list type="bulleted">
       <item><c>PrivateKey = #'RSAPrivateKey{}'</c> or
       <c>#'DSAPrivateKey'{}</c> and the plaintext <c>Msg = binary()</c></item>
       <item><c>PublicKey = #'RSAPublicKey'{}</c> or
       <c>{integer(), #'DssParams'{}}</c></item>
     </list>

Then you can proceed as follows:

    Signature = public_key:sign(Msg, sha, PrivateKey),
true = public_key:verify(Msg, sha, Signature, PublicKey),

    <note>
You normally do only one of the sign or verify operations,
    and the peer does the other.
</note>

It can be appropriate to calculate the message digest before
    calling <c>sign</c> or <c>verify</c>, and then use <c>none</c> as
    second argument:

    Digest = crypto:sha(Msg),
Signature = public_key:sign(Digest, none, PrivateKey),
true = public_key:verify(Digest, none, Signature, PublicKey),

   <marker id="verify_hostname"></marker>
   <title>Verifying a certificate hostname</title>

     <title>Background</title>

When a client checks a server certificate there are a number of checks available like
     checks that the certificate is not revoked, not forged or not out-of-date.

There are however attacks that are not detected by those checks. Suppose a bad guy has
     succeded with a DNS infection. Then the client could belive it is connecting to one host but
     ends up at another but evil one. Though it is evil, it could have a perfectly legal
     certificate! The certificate has a valid signature, it is not revoked, the certificate chain
     is not faked and has a trusted root and so on.

To detect that the server is not the intended one, the client must additionaly perform
     a hostname verification. This procedure is described in
     <url href="https://tools.ietf.org/html/rfc6125">RFC 6125</url>. The idea is that the certificate
     lists the hostnames it could be fetched from. This is checked by the certificate issuer when
     the certificate is signed. So if the certificate is issued by a trusted root the client
     could trust the host names signed in it.

There is a default hostname matching procedure defined in
     <url href="https://tools.ietf.org/html/rfc6125#section-6">RFC 6125, section 6</url>
     as well as protocol dependent variations defined in
     <url href="https://tools.ietf.org/html/rfc6125#appendix-B">RFC 6125 appendix B</url>.
     The default procedure is implemented in
     <seealso marker="public_key:public_key#pkix_verify_hostname-2">public_key:pkix_verify_hostname/2,3</seealso>.
     It is possible for a client to hook in modified rules using the options list.

Some terminology is needed: the certificate presents hostname(s) on which it is valid.
     Those are called Presented IDs. The hostname(s) the client belives it connects to
     are called Reference IDs. The matching rules aims to verify that there is at least
     one of the Reference IDs that matches one of the Presented IDs. If not, the verification fails.

The IDs contains normal fully qualified domain names like e.g <c>foo.example.com</c>,
     but IP addresses are not recommended. The rfc describes why this is not recommended as well
     as security considerations about how to aquire the Reference IDs.

Internationalized domain names are not supported.

     <title>The verification process</title>

Traditionally the Presented IDs were found in the <c>Subject</c> certificate field as <c>CN</c>
     names. This is still quite common. When printing a certificate they show up as:

 $ openssl x509 -text < cert.pem
 ...
 Subject: C=SE, CN=example.com, CN=*.example.com, O=erlang.org
 ...

The example <c>Subject</c> field has one C, two CN and one O part. It is only the
     CN (Common Name) that is used by hostname verification. The two other (C and O) is not used
     here even when they contain a domain name like the O part. The C and O parts are defined
     elsewhere and meaningful only for other functions.

In the example the Presented IDs are <c>example.com</c> as well as hostnames matching
     <c>*.example.com</c>. For example <c>foo.example.com</c> and <c>bar.example.com</c> both
     matches but not <c>foo.bar.example.com</c>. The name <c>erlang.org</c> matches neither
     since it is not a CN.

In case where the Presented IDs are fetched from the <c>Subject</c> certificate field, the
     names may contain wildcard characters. The function handles this as defined in
     <url href="https://tools.ietf.org/html/rfc6125#section-6.4.3">chapter 6.4.3 in RFC 6125</url>.

There may only be one wildcard character and that is in the first label, for example:
     <c>*.example.com</c>. This matches <c>foo.example.com</c> but neither <c>example.com</c> nor
     <c>foo.bar.example.com</c>.

There may be label characters before or/and after the wildcard. For example:
     <c>a*d.example.com</c> matches <c>abcd.example.com</c> and <c>ad.example.com</c>,
     but not <c>ab.cd.example.com</c>.

In the previous example there is no indication of which protocols are expected. So a client
     has no indication of whether it is a web server, an ldap server or maybe a sip server it is
     connected to.
     There are fields in the certificate that can indicate this. To be more exact, the rfc
     introduces the usage of the <c>X509v3 Subject Alternative Name</c> in the <c>X509v3 extensions</c>
     field:

 $ openssl x509 -text < cert.pem
 ...
 X509v3 extensions:
     X509v3 Subject Alternative Name:
         DNS:kb.example.org, URI:https://www.example.org
 ...

Here <c>kb.example.org</c> serves any protocol while <c>www.example.org</c> presents a secure
     web server.

The next example has both <c>Subject</c> and <c>Subject Alternate Name</c> present:

 $ openssl x509 -text < cert.pem
 ...
 Subject: C=SE, CN=example.com, CN=*.example.com, O=erlang.org
 ...
 X509v3 extensions:
     X509v3 Subject Alternative Name:
         DNS:kb.example.org, URI:https://www.example.org
 ...

The RFC states that if a certificate defines Reference IDs in a <c>Subject Alternate Name</c>
     field, the <c>Subject</c> field MUST NOT be used for host name checking, even if it contains
     valid CN names.
     Therefore only <c>kb.example.org</c> and <c>https://www.example.org</c> matches. The match fails
     both for <c>example.com</c> and <c>foo.example.com</c> becuase they are in the <c>Subject</c>
     field which is not checked because the <c>Subject Alternate Name</c> field is present.

    <marker id="verify_hostname_examples"></marker>
     <title>Function call examples</title>
     <note>

Other applications like ssl/tls or https might have options that are passed
       down to the <c>public_key:pkix_verify_hostname</c>. You will probably not
       have to call it directly

     </note>

Suppose our client expects to connect to the web server https://www.example.net. This
     URI is therefore the Reference IDs of the client.
     The call will be:

 public_key:pkix_verify_hostname(CertFromHost,
                                 [{uri_id, "https://www.example.net"}
                                 ]).

The call will return <c>true</c> or <c>false</c> depending on the check. The caller
     do not need to handle the matching rules in the rfc. The matching will proceed as:

     <list>
       <item>If there is a <c>Subject Alternate Name</c> field, the <c>{uri_id,string()}</c> in the
       function call will be compared to any
       <c>{uniformResourceIdentifier,string()}</c> in the Certificate field.
       If the two <c>strings()</c> are equal (case insensitive), there is a match.
       The same applies for any <c>{dns_id,string()}</c> in the call which is compared
       with all <c>{dNSName,string()}</c> in the Certificate field.
       </item>
       <item>If there is NO <c>Subject Alternate Name</c> field, the <c>Subject</c> field will be
       checked. All <c>CN</c> names will be compared to all hostnames extracted from
       <c>{uri_id,string()}</c> and from <c>{dns_id,string()}</c>.
       </item>
     </list>

     <title>Extending the search mechanism</title>

The caller can use own extraction and matching rules. This is done with the two options
     <c>fqdn_fun</c> and <c>match_fun</c>.

       <title>Hostname extraction</title>

The <c>fqdn_fun</c> extracts hostnames (Fully Qualified Domain Names) from uri_id
       or other ReferenceIDs that are not pre-defined in the public_key function.
       Suppose you have some URI with a very special protocol-part:
       <c>myspecial://example.com"</c>. Since this a non-standard URI there will be no hostname
       extracted for matching CN-names in the <c>Subject</c>.

To "teach" the function how to extract, you can give a fun which replaces the default
       extraction function.
       The  <c>fqdn_fun</c> takes one argument and returns
       either a <c>string()</c> to be matched to each CN-name or the atom <c>default</c> which will invoke
       the default fqdn extraction function. The return value <c>undefined</c> removes the current
       URI from the fqdn extraction.

 ...
 Extract = fun({uri_id, "myspecial://"++HostName}) -> HostName;
              (_Else) -> default
           end,
 ...
 public_key:pkix_verify_hostname(CertFromHost, RefIDs,
                                 [{fqdn_fun, Extract}])
 ...

       <title>Re-defining the match operations</title>

The default matching handles dns_id and uri_id. In an uri_id the value is tested for
       equality with a value from the <c>Subject Alternate Name</c>. If som other kind of matching
       is needed, use the  <c>match_fun</c> option.

The  <c>match_fun</c> takes two arguments and returns either <c>true</c>,
       <c>false</c> or <c>default</c>. The value  <c>default</c> will invoke the default
       match function.

 ...
 Match = fun({uri_id,"myspecial://"++A},
             {uniformResourceIdentifier,"myspecial://"++B}) ->
                                                    my_match(A,B);
            (_RefID, _PresentedID) ->
                                default
         end,
 ...
 public_key:pkix_verify_hostname(CertFromHost, RefIDs,
                                 [{match_fun, Match}]),
 ...

In case of a match operation between a ReferenceID and a CN value from the <c>Subject</c>
       field, the first argument to the fun is the extracted hostname from the ReferenceID, and the
       second argument is the tuple <c>{cn, string()}</c> taken from the <c>Subject</c> field. That
       makes it possible to have separate matching rules for Presented IDs from the  <c>Subject</c>
       field and from the <c>Subject Alternate Name</c> field.

The default matching transformes the ascii values in strings to lowercase before comparing.
       The  <c>match_fun</c> is however called without any transfomation applied to the strings.  The
       reason is to enable the user to do unforseen handling of the strings where the original format
       is needed.

     <title>"Pinning" a Certificate</title>

The <url href="https://tools.ietf.org/html/rfc6125">RFC 6125</url> defines pinning
     as:

     <quote>

"The act of establishing a cached name association between
       the application service's certificate and one of the client's
       reference identifiers, despite the fact that none of the presented
       identifiers matches the given reference identifier. ..."

     </quote>

The purpose is to have a mechanism for a human to accept an otherwise faulty Certificate.
     In for example a web browser, you could get a question like

     <quote>

Warning: you wanted to visit the site www.example.com,
       but the certificate is for shop.example.com. Accept anyway (yes/no)?"

     </quote>

This could be accomplished with the option <c>fail_callback</c> which will
     be called if the hostname verification fails:

 -include_lib("public_key/include/public_key.hrl"). % Record def
 ...
 Fail = fun(#'OTPCertificate'{}=C) ->
              case in_my_cache(C) orelse my_accept(C) of
                  true ->
                       enter_my_cache(C),
                       true;
                  false ->
                       false
         end,
 ...
 public_key:pkix_verify_hostname(CertFromHost, RefIDs,
                                 [{fail_callback, Fail}]),
 ...

    <title>SSH Files</title>

SSH typically uses PEM files for private keys but has its
    own file format for storing public keys. The <c>public_key</c>
    application can be used to parse the content of SSH public-key files.

   <title>RFC 4716 SSH Public-Key Files</title>

RFC 4716 SSH files looks confusingly like PEM files,
       but there are some differences:

      1> {ok, SshBin} = file:read_file("ssh2_rsa_pub").
{ok, <<"---- BEGIN SSH2 PUBLIC KEY ----\nAAAA"...>>}

This is equivalent to calling <c>public_key:ssh_decode(SshBin, rfc4716_public_key)</c>:

      2> public_key:ssh_decode(SshBin, public_key).
[{#'RSAPublicKey'{modulus = 794430685...91663,
                  publicExponent = 35}, []}]

   <title>OpenSSH Public-Key Format</title>

OpenSSH public-key format looks as follows:

      1> {ok, SshBin} = file:read_file("openssh_dsa_pub").
{ok,<<"ssh-dss AAAAB3Nza"...>>}

This is equivalent to calling <c>public_key:ssh_decode(SshBin, openssh_public_key)</c>:

    2>  public_key:ssh_decode(SshBin, public_key).
[{{15642692...694280725,
   #'Dss-Parms'{p = 17291273936...696123221,
                q = 1255626590179665817295475654204371833735706001853,
                g = 10454211196...480338645}},
  [{comment,"dhopson@VMUbuntu-DSH"}]}]

   <title>Known Hosts - OpenSSH Format</title>

Known hosts - OpenSSH format looks as follows:

      1> {ok, SshBin} = file:read_file("known_hosts").
{ok,<<"hostname.domain.com,192.168.0.1 ssh-rsa AAAAB...>>}

Returns a list of public keys and their related attributes.
    Each pair of key and attribute corresponds to one entry in
    the known hosts file:

    2>  public_key:ssh_decode(SshBin, known_hosts).
[{#'RSAPublicKey'{modulus = 1498979460408...72721699,
                  publicExponent = 35},
  [{hostnames,["hostname.domain.com","192.168.0.1"]}]},
 {#'RSAPublicKey'{modulus = 14989794604088...2721699,
                  publicExponent = 35},
  [{comment,"foo@bar.com"},
   {hostnames,["|1|BWO5qDxk/cFH0wa05JLdHn+j6xQ=|rXQvIxh5cDD3C43k5DPDamawVNA="]}]}]

    <title>Authorized Keys - OpenSSH Format</title>

Authorized keys - OpenSSH format looks as follows:

    1> {ok, SshBin} = file:read_file("auth_keys").
{ok, <<"command=\"dump /home\",no-pty,no-port-forwarding ssh-rsa AAA...>>}

Returns a list of public keys and their related attributes.
    Each pair of key and attribute corresponds to one entry in
    the authorized key file:

    2> public_key:ssh_decode(SshBin, auth_keys).
[{#'RSAPublicKey'{modulus = 794430685...691663,
                  publicExponent = 35},
  [{comment,"dhopson@VMUbuntu-DSH"},
   {options,["command=\"dump/home\"","no-pty",
             "no-port-forwarding"]}]},
 {{1564269258491...607694280725,
   #'Dss-Parms'{p = 17291273936185...763696123221,
                q = 1255626590179665817295475654204371833735706001853,
                g = 10454211195705...60511039590076780999046480338645}},
  [{comment,"dhopson@VMUbuntu-DSH"}]}]

      <title>Creating an SSH File from Public-Key Data</title>

If you got a public key <c>PubKey</c> and a related list of
      attributes <c>Attributes</c> as returned
      by <c>ssh_decode/2</c>, you can create a new SSH file, for example:

      N> SshBin = public_key:ssh_encode([{PubKey, Attributes}], openssh_public_key),
<<"ssh-rsa "...>>
N+1> file:write_file("id_rsa.pub", SshBin).
ok

</chapter>


text:
package kr.debop4j.timeperiod;

import com.google.common.base.Objects;
import kr.debop4j.timeperiod.tools.TimeSpec;
import kr.debop4j.timeperiod.tools.Times;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.Duration;

import static kr.debop4j.timeperiod.tools.TimeSpec.ZeroDuration;
import static org.joda.time.Duration.ZERO;

/**
 * 기준 일자의 시간 간격을 이용하여 기간을 표현합니다.
 *
 * @author 배성혁 sunghyouk.bae@gmail.com
 * @since 13. 5. 11. 오후 9:04
 */
@Slf4j
public class TimeBlock extends TimePeriodBase implements ITimeBlock {
    private static final long serialVersionUID = 3967092362222887325L;

    public static final TimeBlock Anytime = new TimeBlock(true);

    public static TimeRange toRange(TimeBlock block) {
        return new TimeRange(block.getStart(), block.getDuration(), block.isReadonly());
    }

    public static TimeInterval toInterval(TimeBlock block) {
        return new TimeInterval(block.getStart(), block.getEnd(), block.isReadonly());
    }

    // region << Constructor >>

    public TimeBlock() {}

    public TimeBlock(boolean readonly) {
        super(readonly);
        this.duration = TimeSpec.MaxDuration;
    }

    public TimeBlock(DateTime moment) {
        super(moment);
        this.duration = super.getDuration();
    }

    public TimeBlock(DateTime moment, boolean readonly) {
        super(moment, readonly);
        this.duration = super.getDuration();
    }

    public TimeBlock(DateTime start, DateTime end) {
        this(start, end, false);
    }

    public TimeBlock(DateTime start, DateTime end, boolean readonly) {
        super(start, end, readonly);
        this.duration = super.getDuration();
    }

    public TimeBlock(DateTime start, Duration duration) {
        this(start, duration, false);
    }

    public TimeBlock(DateTime start, Duration duration, boolean readonly) {
        super(start, duration, readonly);
        assertValidDuration(duration);
        this.duration = super.getDuration();
    }

    public TimeBlock(Duration duration, DateTime end) {
        this(duration, end, false);
    }

    public TimeBlock(Duration duration, DateTime end, boolean readonly) {
        super(null, end, readonly);
        assertValidDuration(duration);
        this.duration = duration;
        this.start = end.minus(duration);
    }

    public TimeBlock(ITimePeriod source) {
        super(source);
        this.duration = source.getDuration();
    }

    public TimeBlock(ITimePeriod source, boolean readonly) {
        super(source, readonly);
        this.duration = source.getDuration();
    }

    // endregion

    private Duration duration;

    protected void assertValidDuration(Duration duration) {
        assert duration.compareTo(ZeroDuration) >= 0 : "duration은 0 이상이어야 합니다.";
    }

    @Override
    public void setStart(DateTime start) {
        assertMutable();
        this.start = start;
    }

    @Override
    public void setEnd(DateTime end) {
        assertMutable();
        this.end = end;
    }

    @Override
    public Duration getDuration() {
        return duration;
    }

    @Override
    public void setDuration(Duration duration) {
        assertMutable();
        assertValidDuration(duration);
        durationFromStart(duration);
    }

    @Override
    public TimeBlock copy() {
        return copy(ZERO);
    }

    @Override
    public TimeBlock copy(Duration offset) {
        if (ZERO.isEqual(offset))
            return new TimeBlock(this);

        return new TimeBlock(hasStart() ? start.plus(offset) : start,
                             hasEnd() ? end.plus(offset) : end,
                             readonly);
    }

    public void setup(DateTime newStart, Duration duration) {
        assertMutable();
        assertValidDuration(duration);

            log.trace("TimeBlock 값을 새로 설정합니다. newStart=[{}], duration=[{}]", newStart, duration);

        this.start = newStart;
        this.duration = duration;
        this.end = newStart.plus(duration);
    }

    @Override
    public void durationFromStart(Duration newDuration) {
        assertMutable();
        assertValidDuration(newDuration);

        if (newDuration.isEqual(TimeSpec.MaxDuration)) {
            this.duration = newDuration;
            this.end = TimeSpec.MaxPeriodTime;
        } else {
            if (end != null)
                assert this.end.plus(newDuration).compareTo(TimeSpec.MaxPeriodTime) <= 0 : "duration 이 너무 크네요.";

            this.duration = newDuration;
            this.end = this.start.plus(this.duration);
        }
    }

    @Override
    public void durationFromEnd(Duration newDuration) {
        assertMutable();
        assertValidDuration(newDuration);
        this.duration = newDuration;
        this.start = this.end.minus(this.duration);
    }

    public ITimeBlock getPreviousBlock() {
        return getPreviousBlock(ZERO);
    }

    @Override
    public ITimeBlock getPreviousBlock(Duration offset) {
        Duration endOffset = (offset.compareTo(ZERO) > 0) ? new Duration(-offset.getMillis()) : offset;
        return new TimeBlock(getDuration(), getStart().plus(endOffset), readonly);
    }

    public ITimeBlock getNextBlock() {
        return getNextBlock(ZERO);
    }

    @Override
    public ITimeBlock getNextBlock(Duration offset) {
        Duration startOffset = (offset.compareTo(ZERO) > 0) ? offset : new Duration(-offset.getMillis());
        return new TimeBlock(getEnd().plus(startOffset), getDuration(), readonly);
    }

    public TimeBlock getIntersection(ITimePeriod other) {
        assert other != null;
        return Times.getIntersectionBlock(this, other);
    }

    public TimeBlock getUnion(ITimePeriod other) {
        assert other != null;
        return Times.getUnionBlock(this, other);
    }

    @Override
    protected Objects.ToStringHelper buildStringHelper() {
        return super.buildStringHelper();
        //.add("duration", duration);
    }
}


text:
Bookmark Search this version is installed!

To use this extension, just type bm  on the omnibox (address bar).

Please also check the options page.

Click here to see the change log.


text:
/***************************************************************************************************
*
* SUBJECT:
*    A Benckmark for Massive Multiplayer Online Games
*    Game Server and Client
*
* AUTHOR:
*    Mihai Paslariu
*    Politehnica University of Bucharest, Bucharest, Romania
*    mihplaesu@yahoo.com
*
* TIME AND PLACE:
*    University of Toronto, Toronto, Canada
*    March - August 2007
*
***************************************************************************************************/

#ifndef __OGL_OBJECT_H
#define __OGL_OBJECT_H

class OglObject
{
public:
	virtual ~OglObject() {};
	virtual void render() = 0;

	virtual void render(float x, float y)
	{
		glPushMatrix();
		glTranslatef(x, 0.0, y);
		render();
		glPopMatrix();
	}

	virtual void render(float x, float y, float scale)
	{
		glPushMatrix();
		glTranslatef(x, 0.0, y);
		glScalef(scale,scale,scale);
		render();
		glPopMatrix();
	}

	virtual void render(float x, float y, float scale, float rotate)
	{
		glPushMatrix();
		glTranslatef(x, 0.0, y);
		glScalef(scale,scale,scale);
		glRotatef(rotate,0,1,0);
		render();
		glPopMatrix();
	}

	virtual void render(float x, float y, float scale,
		float rotate1, float rotate2)
	{
		glPushMatrix();
		glTranslatef(x, 0.0, y);
		glScalef(scale,scale,scale);
		glRotatef(rotate1,0,1,0);
		glRotatef(rotate2,1,0,0);
		render();
		glPopMatrix();
	}
};

#endif


text:
require 'cucumberator/parser'
require 'cucumberator/steps'

module Cucumberator
  class Input
    attr_accessor :world, :scenario, :step_line, :last_input, :exit_flag, :saved_stack

    def initialize(world, scenario, step_line = nil)
      @world, @scenario = world, scenario
      @step_line = step_line if step_line
      @saved_stack = []

      check_scenario
      set_autocomplete
      read_input
    end

    def check_scenario
      raise "Sorry, cucumberator is not available when scenario is already failing!" if scenario.failed?
    end

    def read_input
      input = Readline.readline("> ", true)
      exit_flag = Cucumberator::Parser.parse_input(input, scenario, step_line, world, saved_stack)
      read_input unless exit_flag
    end

    def set_autocomplete
      commands = Cucumberator::Commands::AVAILABLE

      Cucumberator::Steps.new(scenario).all.each do |s|
        # remove typical start/end regexp parts
        step = s.gsub(/^\/\^|\$\/$/,'')
        # every step is equal, no matter if When/Then/And, so combining everything for autocomplete
        commands << "When #{step}" << "Then #{step}" << "And #{step}"
      end

      Readline.basic_word_break_characters = ""; # no break chars = no autobreaking for completion input
      Readline.completion_proc = proc { |s| commands.grep( /^#{Regexp.escape(s)}/ ) }
    end
  end
end


text:
var expect = require('expect.js')
  , ffi = require('../')
  , Pointer = ffi.Pointer

describe('Pointer', function () {

  afterEach(gc)

  describe('toBuffer()', function () {

    it('should return a "Buffer" instance', function () {
      var p = new Pointer(8)
        , b = p.toBuffer()
      expect(Buffer.isBuffer(b)).to.be(true)
    })

    it('`Buffer#length` should match `Pointer#allocated`', function () {
      var p = new Pointer(128)
        , b = p.toBuffer()
      expect(b.length).to.equal(p.allocated)
    })

    it('should work when writing to Buffer, reading from Pointer', function () {
      var p = new Pointer(6)
        , b = p.toBuffer()
        , msg = 'hello'
      b.write(msg + '\0')
      expect(p.getCString()).to.equal(msg)
    })

    it('should work when writing to Pointer, reading from Buffer', function () {
      var p = new Pointer(12)
        , b = p.toBuffer()
        , msg = 'hello world'
      p.putCString(msg)
      expect(b.toString('ascii', 0, msg.length)).to.equal(msg)
    })

    it('should work when modifying a single byte in the Buffer', function () {
      var p = new Pointer(6)
        , b = p.toBuffer()
      p.putCString('hello')
      b[2] = 'L'.charCodeAt(0)
      expect(p.getCString()).to.equal('heLlo')
    })

  })

})


text:
module Theblog
  class Post < ContentNode
    belongs_to :category, class_name: "Theblog::Category", foreign_key: :parent_node_id
    validates_presence_of :body
  end
end


text:
{% extends "base.html" %}
{% include "meta.html" %}
{% block content %}

Contact Us We want to hear from you

          First Name *
          <input id="form_name" type="text" name="name" class="form-control" placeholder="Please enter your firstname *" required="required" data-error="Firstname is required.">

            Last Name *
            <input id="form_lastname" type="text" name="surname" class="form-control" placeholder="Please enter your lastname *" required="required" data-error="Lastname is required.">

            Email *
            <input id="form_email" type="email" name="email" class="form-control" placeholder="Please enter your email *" required="required" data-error="Valid email is required.">

            Phone
            <input id="form_phone" type="tel" name="phone" class="form-control" placeholder="Please enter your phone">

          Message *
          <textarea id="form_message" name="message" class="form-control" placeholder="Message for me *" rows="4" required="required" data-error="Please,leave us a message."></textarea>

        <input type="submit" class="btn btn-success btn-send" value="Send message">

* These fields are required.

{% endblock %}


text:
/*=========================
  Scrollbar
  ===========================*/
s.scrollbar = {
    isTouched: false,
    setDragPosition: function (e) {
        var sb = s.scrollbar;
        var x = 0, y = 0;
        var translate;
        var pointerPosition = s.isHorizontal() ?
            ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageX : e.pageX || e.clientX) :
            ((e.type === 'touchstart' || e.type === 'touchmove') ? e.targetTouches[0].pageY : e.pageY || e.clientY) ;
        var position = (pointerPosition) - sb.track.offset()[s.isHorizontal() ? 'left' : 'top'] - sb.dragSize / 2;
        var positionMin = -s.minTranslate() * sb.moveDivider;
        var positionMax = -s.maxTranslate() * sb.moveDivider;
        if (position < positionMin) {
            position = positionMin;
        }
        else if (position > positionMax) {
            position = positionMax;
        }
        position = -position / sb.moveDivider;
        s.updateProgress(position);
        s.setWrapperTranslate(position, true);
    },
    dragStart: function (e) {
        var sb = s.scrollbar;
        sb.isTouched = true;
        e.preventDefault();
        e.stopPropagation();

        sb.setDragPosition(e);
        clearTimeout(sb.dragTimeout);

        sb.track.transition(0);
        if (s.params.scrollbarHide) {
            sb.track.css('opacity', 1);
        }
        s.wrapper.transition(100);
        sb.drag.transition(100);
        s.emit('onScrollbarDragStart', s);
    },
    dragMove: function (e) {
        var sb = s.scrollbar;
        if (!sb.isTouched) return;
        if (e.preventDefault) e.preventDefault();
        else e.returnValue = false;
        sb.setDragPosition(e);
        s.wrapper.transition(0);
        sb.track.transition(0);
        sb.drag.transition(0);
        s.emit('onScrollbarDragMove', s);
    },
    dragEnd: function (e) {
        var sb = s.scrollbar;
        if (!sb.isTouched) return;
        sb.isTouched = false;
        if (s.params.scrollbarHide) {
            clearTimeout(sb.dragTimeout);
            sb.dragTimeout = setTimeout(function () {
                sb.track.css('opacity', 0);
                sb.track.transition(400);
            }, 1000);

        }
        s.emit('onScrollbarDragEnd', s);
        if (s.params.scrollbarSnapOnRelease) {
            s.slideReset();
        }
    },
    draggableEvents: (function () {
        if ((s.params.simulateTouch === false && !s.support.touch)) return s.touchEventsDesktop;
        else return s.touchEvents;
    })(),
    enableDraggable: function () {
        var sb = s.scrollbar;
        var target = s.support.touch ? sb.track : document;
        $(sb.track).on(sb.draggableEvents.start, sb.dragStart);
        $(target).on(sb.draggableEvents.move, sb.dragMove);
        $(target).on(sb.draggableEvents.end, sb.dragEnd);
    },
    disableDraggable: function () {
        var sb = s.scrollbar;
        var target = s.support.touch ? sb.track : document;
        $(sb.track).off(sb.draggableEvents.start, sb.dragStart);
        $(target).off(sb.draggableEvents.move, sb.dragMove);
        $(target).off(sb.draggableEvents.end, sb.dragEnd);
    },
    set: function () {
        if (!s.params.scrollbar) return;
        var sb = s.scrollbar;
        sb.track = $(s.params.scrollbar);
        if (s.params.uniqueNavElements && typeof s.params.scrollbar === 'string' && sb.track.length > 1 && s.container.find(s.params.scrollbar).length === 1) {
            sb.track = s.container.find(s.params.scrollbar);
        }
        sb.drag = sb.track.find('.swiper-scrollbar-drag');
        if (sb.drag.length === 0) {
            sb.drag = $('

');
            sb.track.append(sb.drag);
        }
        sb.drag[0].style.width = '';
        sb.drag[0].style.height = '';
        sb.trackSize = s.isHorizontal() ? sb.track[0].offsetWidth : sb.track[0].offsetHeight;

        sb.divider = s.size / s.virtualSize;
        sb.moveDivider = sb.divider * (sb.trackSize / s.size);
        sb.dragSize = sb.trackSize * sb.divider;

        if (s.isHorizontal()) {
            sb.drag[0].style.width = sb.dragSize + 'px';
        }
        else {
            sb.drag[0].style.height = sb.dragSize + 'px';
        }

        if (sb.divider >= 1) {
            sb.track[0].style.display = 'none';
        }
        else {
            sb.track[0].style.display = '';
        }
        if (s.params.scrollbarHide) {
            sb.track[0].style.opacity = 0;
        }
    },
    setTranslate: function () {
        if (!s.params.scrollbar) return;
        var diff;
        var sb = s.scrollbar;
        var translate = s.translate || 0;
        var newPos;

        var newSize = sb.dragSize;
        newPos = (sb.trackSize - sb.dragSize) * s.progress;
        if (s.rtl && s.isHorizontal()) {
            newPos = -newPos;
            if (newPos > 0) {
                newSize = sb.dragSize - newPos;
                newPos = 0;
            }
            else if (-newPos + sb.dragSize > sb.trackSize) {
                newSize = sb.trackSize + newPos;
            }
        }
        else {
            if (newPos < 0) {
                newSize = sb.dragSize + newPos;
                newPos = 0;
            }
            else if (newPos + sb.dragSize > sb.trackSize) {
                newSize = sb.trackSize - newPos;
            }
        }
        if (s.isHorizontal()) {
            if (s.support.transforms3d) {
                sb.drag.transform('translate3d(' + (newPos) + 'px, 0, 0)');
            }
            else {
                sb.drag.transform('translateX(' + (newPos) + 'px)');
            }
            sb.drag[0].style.width = newSize + 'px';
        }
        else {
            if (s.support.transforms3d) {
                sb.drag.transform('translate3d(0px, ' + (newPos) + 'px, 0)');
            }
            else {
                sb.drag.transform('translateY(' + (newPos) + 'px)');
            }
            sb.drag[0].style.height = newSize + 'px';
        }
        if (s.params.scrollbarHide) {
            clearTimeout(sb.timeout);
            sb.track[0].style.opacity = 1;
            sb.timeout = setTimeout(function () {
                sb.track[0].style.opacity = 0;
                sb.track.transition(400);
            }, 1000);
        }
    },
    setTransition: function (duration) {
        if (!s.params.scrollbar) return;
        s.scrollbar.drag.transition(duration);
    }
};


text:
layout: page
title: Booth Diamond Research Conference
date: 2016-05-24
author: Mary Mccarthy
tags: weekly links, java
status: published
summary: In hac habitasse platea dictumst. Maecenas maximus erat.
banner: images/banner/leisure-02.jpg
booking:
  startDate: 01/28/2016
  endDate: 01/31/2016
  ctyhocn: CRPKVHX
  groupCode: BDRC
published: true
---
Ut at volutpat dolor, ut dictum libero. Duis nec tincidunt ex. Etiam justo magna, tristique non fringilla eget, viverra nec ipsum. Mauris et odio sapien. Aliquam ullamcorper tincidunt sapien. Sed eu diam quis nibh imperdiet fringilla vitae vitae nunc. Nunc vulputate erat nec diam interdum, non rhoncus diam feugiat. Nullam non vestibulum odio. Aliquam elit velit, mollis quis volutpat vel, blandit ac mauris. Fusce nulla turpis, luctus nec interdum eget, sodales eu lectus.

1 Duis eget elit pharetra, fringilla nunc vel, aliquam odio
1 Nulla eu nulla in sem faucibus maximus
1 Etiam ut velit dignissim, iaculis mi a, consequat erat
1 Curabitur in lorem nec magna gravida aliquam.

Maecenas quis semper ex. Vestibulum mollis, purus id auctor porta, ipsum tortor egestas purus, sit amet porttitor tellus urna at justo. Curabitur finibus blandit nunc, id auctor lacus molestie id. Sed quis pretium ligula. Aenean venenatis dolor a bibendum condimentum. Integer imperdiet pellentesque imperdiet. Cras convallis diam ac lacus accumsan mattis.
Fusce non mi in est molestie varius at a metus. Vivamus quis arcu nec tellus congue sodales. Vestibulum eu bibendum purus, ultricies efficitur felis. Donec vitae mattis enim. Sed faucibus at metus non sollicitudin. Vestibulum et imperdiet urna. Praesent convallis massa id iaculis ornare. Vivamus ultricies rutrum ultrices. Donec ut interdum urna. Vivamus ac sagittis tellus. Proin malesuada placerat tempus. Vivamus consequat aliquam dignissim.


text:
from __future__ import absolute_import, print_function

from django.test import Client
from django.core.urlresolvers import reverse

def test_healthcheck_endpoint():
    c = Client()
    url = reverse("sentry-api-0-relays-healthcheck")
    response = c.get(url)
    assert response.status_code == 200
    print(response.data)


text:
#import "CCBReaderInternal.h"
#import "CCBReaderInternalV1.h"
#import "PlugInManager.h"
#import "PlugInNode.h"
#import "NodeInfo.h"
#import "CCBWriterInternal.h"
#import "TexturePropertySetter.h"
#import "AnimationPropertySetter.h"
#import "CCBGlobals.h"
#import "CocosBuilderAppDelegate.h"
#import "ResourceManager.h"
#import "NodeGraphPropertySetter.h"

@implementation CCBReaderInternal

+ (NSPoint) deserializePoint:(id) val
{
    float x = [[val objectAtIndex:0] floatValue];
    float y = [[val objectAtIndex:1] floatValue];
    return NSMakePoint(x,y);
}

+ (NSSize) deserializeSize:(id) val
{
    float w = [[val objectAtIndex:0] floatValue];
    float h = [[val objectAtIndex:1] floatValue];
    return NSMakeSize(w, h);
}

+ (float) deserializeFloat:(id) val
{
    return [val floatValue];
}

+ (int) deserializeInt:(id) val
{
    return [val intValue];
}

+ (BOOL) deserializeBool:(id) val
{
    return [val boolValue];
}

+ (ccColor3B) deserializeColor3:(id) val
{
    ccColor3B c;
    c.r = [[val objectAtIndex:0] intValue];
    c.g = [[val objectAtIndex:1] intValue];
    c.b = [[val objectAtIndex:2] intValue];
    return c;
}

+ (ccColor4B) deserializeColor4:(id) val
{
    ccColor4B c;
    c.r = [[val objectAtIndex:0] intValue];
    c.g = [[val objectAtIndex:1] intValue];
    c.b = [[val objectAtIndex:2] intValue];
    c.a = [[val objectAtIndex:3] intValue];
    return c;
}

+ (ccColor4F) deserializeColor4F:(id) val
{
    ccColor4F c;
    c.r = [[val objectAtIndex:0] floatValue];
    c.g = [[val objectAtIndex:1] floatValue];
    c.b = [[val objectAtIndex:2] floatValue];
    c.a = [[val objectAtIndex:3] floatValue];
    return c;
}

+ (ccBlendFunc) deserializeBlendFunc:(id) val
{
    ccBlendFunc bf;
    bf.src = [[val objectAtIndex:0] intValue];
    bf.dst = [[val objectAtIndex:1] intValue];
    return bf;
}

+ (void) setProp:(NSString*)name ofType:(NSString*)type toValue:(id)serializedValue forNode:(CCNode*)node
{
    // Fetch info and extra properties
    NodeInfo* nodeInfo = node.userObject;
    NSMutableDictionary* extraProps = nodeInfo.extraProps;

    if ([type isEqualToString:@"Position"]
        || [type isEqualToString:@"Point"]
        || [type isEqualToString:@"PointLock"])
    {
        NSPoint pt = [CCBReaderInternal deserializePoint: serializedValue];

        [node setValue:[NSValue valueWithPoint:pt] forKey:name];
    }
    else if ([type isEqualToString:@"Size"])
    {
        NSSize size = [CCBReaderInternal deserializeSize: serializedValue];
        [node setValue:[NSValue valueWithSize:size] forKey:name];
    }
    else if ([type isEqualToString:@"Scale"]
             || [type isEqualToString:@"ScaleLock"])
    {
        [node setValue:[serializedValue objectAtIndex:0] forKey:[NSString stringWithFormat:@"%@X",name]];
        [node setValue:[serializedValue objectAtIndex:1] forKey:[NSString stringWithFormat:@"%@Y",name]];
    }
    else if ([type isEqualToString:@"Float"]
             || [type isEqualToString:@"Degrees"])
    {
        float f = [CCBReaderInternal deserializeFloat: serializedValue];
        [node setValue:[NSNumber numberWithFloat:f] forKey:name];
    }
    else if ([type isEqualToString:@"FloatVar"])
    {
        [node setValue:[serializedValue objectAtIndex:0] forKey:name];
        [node setValue:[serializedValue objectAtIndex:1] forKey:[NSString stringWithFormat:@"%@Var",name]];
    }
    else if ([type isEqualToString:@"Integer"]
             || [type isEqualToString:@"IntegerLabeled"]
             || [type isEqualToString:@"Byte"])
    {
        int d = [CCBReaderInternal deserializeInt: serializedValue];
        [node setValue:[NSNumber numberWithInt:d] forKey:name];
    }
    else if ([type isEqualToString:@"Check"])
    {
        BOOL check = [CCBReaderInternal deserializeBool:serializedValue];
        [node setValue:[NSNumber numberWithBool:check] forKey:name];
    }
    else if ([type isEqualToString:@"Flip"])
    {
        [node setValue:[serializedValue objectAtIndex:0] forKey:[NSString stringWithFormat:@"%@X",name]];
        [node setValue:[serializedValue objectAtIndex:1] forKey:[NSString stringWithFormat:@"%@Y",name]];
    }
    else if ([type isEqualToString:@"SpriteFrame"])
    {
        NSString* spriteSheetFile = [serializedValue objectAtIndex:0];
        NSString* spriteFile = [serializedValue objectAtIndex:1];
        if (!spriteSheetFile || [spriteSheetFile isEqualToString:@""])
        {
            spriteSheetFile = kCCBUseRegularFile;
        }

        [extraProps setObject:spriteSheetFile forKey:[NSString stringWithFormat:@"%@Sheet",name]];
        [extraProps setObject:spriteFile forKey:name];
        [TexturePropertySetter setSpriteFrameForNode:node andProperty:name withFile:spriteFile andSheetFile:spriteSheetFile];
    }
    else if ([type isEqualToString:@"Animation"])
    {
        NSString* animationFile = [serializedValue objectAtIndex:0];
        NSString* animationName = [serializedValue objectAtIndex:1];
        if (!animationFile) animationFile = @"";
        if (!animationName) animationName = @"";

        [extraProps setObject:animationFile forKey:[NSString stringWithFormat:@"%@Animation",name]];
        [extraProps setObject:animationName forKey:name];
        [AnimationPropertySetter setAnimationForNode:node andProperty:name withName:animationName andFile:animationFile];
    }
    else if ([type isEqualToString:@"Texture"])
    {
        NSString* spriteFile = serializedValue;
        if (!spriteFile) spriteFile = @"";
        [TexturePropertySetter setTextureForNode:node andProperty:name withFile:spriteFile];
        [extraProps setObject:spriteFile forKey:name];
    }
    else if ([type isEqualToString:@"Color3"])
    {
        ccColor3B c = [CCBReaderInternal deserializeColor3:serializedValue];
        NSValue* colorValue = [NSValue value:&c withObjCType:@encode(ccColor3B)];
        [node setValue:colorValue forKey:name];
    }
    else if ([type isEqualToString:@"Color4FVar"])
    {
        ccColor4F c = [CCBReaderInternal deserializeColor4F:[serializedValue objectAtIndex:0]];
        ccColor4F cVar = [CCBReaderInternal deserializeColor4F:[serializedValue objectAtIndex:1]];
        NSValue* cValue = [NSValue value:&c withObjCType:@encode(ccColor4F)];
        NSValue* cVarValue = [NSValue value:&cVar withObjCType:@encode(ccColor4F)];
        [node setValue:cValue forKey:name];
        [node setValue:cVarValue forKey:[NSString stringWithFormat:@"%@Var",name]];
    }
    else if ([type isEqualToString:@"Blendmode"])
    {
        ccBlendFunc bf = [CCBReaderInternal deserializeBlendFunc:serializedValue];
        NSValue* blendValue = [NSValue value:&bf withObjCType:@encode(ccBlendFunc)];
        [node setValue:blendValue forKey:name];
    }
    else if ([type isEqualToString:@"FntFile"])
    {
        NSString* fntFile = serializedValue;
        if (!fntFile) fntFile = @"";
        [TexturePropertySetter setFontForNode:node andProperty:name withFile:fntFile];
        [extraProps setObject:fntFile forKey:name];
    }
    else if ([type isEqualToString:@"Text"])
    {
        NSString* str = serializedValue;
        if (!str) str = @"";
        [node setValue:str forKey:name];
    }
    else if ([type isEqualToString:@"FontTTF"])
    {
        NSString* str = serializedValue;
        if (!str) str = @"";
        [node setValue:str forKey:name];
    }
    else if ([type isEqualToString:@"Block"])
    {
        NSString* selector = [serializedValue objectAtIndex:0];
        NSNumber* target = [serializedValue objectAtIndex:1];
        if (!selector) selector = @"";
        if (!target) target = [NSNumber numberWithInt:0];
        [extraProps setObject: selector forKey:name];
        [extraProps setObject:target forKey:[NSString stringWithFormat:@"%@Target",name]];
    }
    else if ([type isEqualToString:@"CCBFile"])
    {
        NSString* ccbFile = serializedValue;
        if (!ccbFile) ccbFile = @"";
        [NodeGraphPropertySetter setNodeGraphForNode:node andProperty:name withFile:ccbFile];
        [extraProps setObject:ccbFile forKey:name];
    }
    else
    {
        NSLog(@"WARNING Unrecognized property type: %@", type);
    }
}

+ (CCNode*) nodeGraphFromDictionary:(NSDictionary*) dict
{
    NSArray* props = [dict objectForKey:@"properties"];
    NSString* baseClass = [dict objectForKey:@"baseClass"];
    NSArray* children = [dict objectForKey:@"children"];

    // Create the node
    CCNode* node = [[PlugInManager sharedManager] createDefaultNodeOfType:baseClass];
    if (!node)
    {
        NSLog(@"WARNING! Plug-in missing for %@", baseClass);
        return NULL;
    }

    // Fetch info and extra properties
    NodeInfo* nodeInfo = node.userObject;
    NSMutableDictionary* extraProps = nodeInfo.extraProps;
    PlugInNode* plugIn = nodeInfo.plugIn;

    // Set properties for the node
    int numProps = [props count];
    for (int i = 0; i < numProps; i++)
    {
        NSDictionary* propInfo = [props objectAtIndex:i];
        NSString* type = [propInfo objectForKey:@"type"];
        NSString* name = [propInfo objectForKey:@"name"];
        id serializedValue = [propInfo objectForKey:@"value"];

        if ([plugIn dontSetInEditorProperty:name])
        {
            [extraProps setObject:serializedValue forKey:name];
        }
        else
        {
            [CCBReaderInternal setProp:name ofType:type toValue:serializedValue forNode:node];
        }
    }

    // Set extra properties for code connections
    NSString* customClass = [dict objectForKey:@"customClass"];
    if (!customClass) customClass = @"";
    NSString* memberVarName = [dict objectForKey:@"memberVarAssignmentName"];
    if (!memberVarName) memberVarName = @"";
    int memberVarType = [[dict objectForKey:@"memberVarAssignmentType"] intValue];

    [extraProps setObject:customClass forKey:@"customClass"];
    [extraProps setObject:memberVarName forKey:@"memberVarAssignmentName"];
    [extraProps setObject:[NSNumber numberWithInt:memberVarType] forKey:@"memberVarAssignmentType"];

    for (int i = 0; i < [children count]; i++)
    {
        CCNode* child = [CCBReaderInternal nodeGraphFromDictionary:[children objectAtIndex:i]];
        [node addChild:child z:i];
    }

    return node;
}

+ (CCNode*) nodeGraphFromDocumentDictionary:(NSDictionary *)dict
{
    if (!dict)
    {
        NSLog(@"WARNING! Trying to load invalid file type (dict is null)");
        return NULL;
    }
    // Load file metadata

    NSString* fileType = [dict objectForKey:@"fileType"];
    int fileVersion = [[dict objectForKey:@"fileVersion"] intValue];

    if (!fileType  || ![fileType isEqualToString:@"CocosBuilder"])
    {
        NSLog(@"WARNING! Trying to load invalid file type (%@)", fileType);
    }

    NSDictionary* nodeGraph = [dict objectForKey:@"nodeGraph"];

    if (fileVersion <= 2)
    {
        // Use legacy reader
        NSString* assetsPath = [NSString stringWithFormat:@"%@/", [[ResourceManager sharedManager] mainActiveDirectoryPath]];

        return [CCBReaderInternalV1 ccObjectFromDictionary:nodeGraph assetsDir:assetsPath owner:NULL];
    }
    else if (fileVersion > kCCBFileFormatVersion)
    {
        NSLog(@"WARNING! Trying to load file made with a newer version of CocosBuilder");
        return NULL;
    }

    return [CCBReaderInternal nodeGraphFromDictionary:nodeGraph];
}

@end


text:
module CliLogger
  class CliLoggerError < RuntimeError; end

  class UnknownLogLevelError < CliLoggerError; end
end


text:
// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespaget;

import com.yahoo.documentapi.messagebus.protocol.DocumentProtocol;

import java.util.Iterator;
/**
 * This class contains the the program parameters.
 *
 * @author bjorncs
 */
public class ClientParameters {

    // Determines if the help page should be presented
    public final boolean help;
    // Contains the document ids. Is backed by either a list iterator if the ids were given as CLI arguments or Scanner(System.in) if ids are provided by standard input.
    public final Iterator<String> documentIds;
    // Print only the id for retrieved documents
    public final boolean printIdsOnly;
    // Determines which document fields to retrieve. Default is '[document]'.
    public final String fieldSet;
    // The Vespa route
    public final String route;
    // Alternative way to specify the route using cluster name.
    public final String cluster;
    // The configuration id for message bus. Default "client".
    public final String configId;
    // Determines if the serialized document size should be printed
    public final boolean showDocSize;
    // Document request timeout
    public final double timeout;
    // Determines whether or not the document request can be resent
    public final boolean noRetry;
    // Vespa trace level
    public final int traceLevel;
    // Document request priority
    public final DocumentProtocol.Priority priority;
    // If full documents are printed, they will be printed as JSON (instead of XML)
    public final boolean jsonOutput;

    private ClientParameters(
            boolean help, Iterator<String> documentIds, boolean printIdsOnly,
            String fieldSet, String route, String cluster, String configId,
            boolean showDocSize, double timeout, boolean noRetry, int traceLevel,
            DocumentProtocol.Priority priority, boolean jsonOutput) {

        this.help = help;
        this.documentIds = documentIds;
        this.printIdsOnly = printIdsOnly;
        this.fieldSet = fieldSet;
        this.route = route;
        this.cluster = cluster;
        this.configId = configId;
        this.showDocSize = showDocSize;
        this.timeout = timeout;
        this.noRetry = noRetry;
        this.traceLevel = traceLevel;
        this.priority = priority;
        this.jsonOutput = jsonOutput;
    }

    public static class Builder {
        private boolean help;
        private Iterator<String> documentIds;
        private boolean printIdsOnly;
        private String fieldSet;
        private String route;
        private String cluster;
        private String configId;
        private boolean showDocSize;
        private double timeout;
        private boolean noRetry;
        private int traceLevel;
        private DocumentProtocol.Priority priority;
        private boolean jsonOutput;

        public Builder setHelp(boolean help) {
            this.help = help;
            return this;
        }

        public Builder setDocumentIds(Iterator<String> documentIds) {
            this.documentIds = documentIds;
            return this;
        }

        public Builder setPrintIdsOnly(boolean printIdsOnly) {
            this.printIdsOnly = printIdsOnly;
            return this;
        }

        public Builder setFieldSet(String fieldSet) {
            this.fieldSet = fieldSet;
            return this;
        }

        public Builder setRoute(String route) {
            this.route = route;
            return this;
        }

        public Builder setCluster(String cluster) {
            this.cluster = cluster;
            return this;
        }

        public Builder setConfigId(String configId) {
            this.configId = configId;
            return this;
        }

        public Builder setShowDocSize(boolean showDocSize) {
            this.showDocSize = showDocSize;
            return this;
        }

        public Builder setTimeout(double timeout) {
            this.timeout = timeout;
            return this;
        }

        public Builder setNoRetry(boolean noRetry) {
            this.noRetry = noRetry;
            return this;
        }

        public Builder setTraceLevel(int traceLevel) {
            this.traceLevel = traceLevel;
            return this;
        }

        public Builder setPriority(DocumentProtocol.Priority priority) {
            this.priority = priority;
            return this;
        }

        public Builder setJsonOutput(boolean jsonOutput) {
            this.jsonOutput = jsonOutput;
            return this;
        }

        public ClientParameters build() {
            return new ClientParameters(
                    help, documentIds, printIdsOnly, fieldSet, route, cluster, configId,
                    showDocSize, timeout, noRetry, traceLevel, priority, jsonOutput);
        }
    }

}


text:
#pragma once

#include "../ProxyTransaction.h"

class Continuation;

class Http1Transaction : public ProxyTransaction
{
public:
  using super_type = ProxyTransaction;

  Http1Transaction() {}

  ////////////////////
  // Methods
  void release(IOBufferReader *r) override;
  void destroy() override; // todo make ~Http1Transaction()

  // Implement VConnection interface.
  VIO *do_io_read(Continuation *c, int64_t nbytes = INT64_MAX, MIOBuffer *buf = nullptr) override;
  VIO *do_io_write(Continuation *c = nullptr, int64_t nbytes = INT64_MAX, IOBufferReader *buf = nullptr,
                   bool owner = false) override;
  void do_io_close(int lerrno = -1) override;
  void do_io_shutdown(ShutdownHowTo_t howto) override;
  void reenable(VIO *vio) override;

  bool allow_half_open() const override;
  void set_active_timeout(ink_hrtime timeout_in) override;
  void set_inactivity_timeout(ink_hrtime timeout_in) override;
  void cancel_inactivity_timeout() override;
  void transaction_done() override;
  int get_transaction_id() const override;
  void increment_client_transactions_stat() override;
  void decrement_client_transactions_stat() override;

  void set_reader(IOBufferReader *reader);

  ////////////////////
  // Variables

protected:
  bool outbound_transparent{false};
};


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <title></title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">

      <input type="text" v-model="name">

{{message}}

      <input type="text" v-model="message" @keyup.enter="sendMessage">