当前位置: 首页>>代码示例>>Scala>>正文


Scala JValue类代码示例

本文整理汇总了Scala中org.json4s.JsonAST.JValue的典型用法代码示例。如果您正苦于以下问题:Scala JValue类的具体用法?Scala JValue怎么用?Scala JValue使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。


在下文中一共展示了JValue类的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Scala代码示例。

示例1: RedditExtractor

//设置package包名称以及导入依赖的类
package com.orendain.sraw.util

import org.json4s.JsonAST.JValue
import org.json4s.JsonAST.JArray
import com.orendain.sraw.model._
import com.orendain.sraw.model.extract._

object RedditExtractor extends HasExtractor[RedditEntity] {

  val extractor = new Extractor[RedditEntity] {
    def canExtract(json: JValue) = true
    def extract(json: JValue) =
      extractors.map(_.extractor).filter(_.canExtract(json)).head.extract(json)
  }

  // TODO: fix
  val extractors = Seq(
    Comment,
    LoggedInUser,
    User,
    Submission,
    Message,
    Subreddit,
    Trophy,
    GenericObject,
    GenericEntity
  )
}

object RedditExtractors {

  object CommentTree extends HasExtractor[Listing[Comment]] {

    val extractor = new Extractor[Listing[Comment]] {
      def canExtract(json: JValue) = RedditJson.unwrap(json) match {
        case JArray(arr) => Listing.extractor(Comment).extractor.canExtract(arr.tail.head)
      }
      def extract(json: JValue) = RedditJson.unwrap(json) match {
        case JArray(arr) => Listing.extractor(Comment).extractor.extract(arr.tail.head)
      }
    }
  }

} 
开发者ID:orendain,项目名称:sraw,代码行数:45,代码来源:RedditExtractor.scala

示例2: JSON

//设置package包名称以及导入依赖的类
package se.joham.funrts.util

import org.json4s.{CustomSerializer, Extraction, ShortTypeHints}
import se.joham.funrts.model._
import Extraction.{decompose, extract}
import org.json4s.JsonAST.JValue
import se.gigurra.scalego.serialization.KnownSubTypes
import se.gigurra.scalego.serialization.json.JsonSerializer
import se.joham.funrts.model.FunRtsECS.{ECS, IdTypes}
import org.json4s.jackson.JsonMethods.{compact, parse}
import org.json4s.jackson.JsonMethods.{pretty => prty}


object JSON {

  def writeAst(ecs: ECS): JValue = ecsSerializer.SerializableOps(ecs).toJsonAst
  def    write(ecs: ECS, pretty: Boolean): String = ecsSerializer.SerializableOps(ecs).toJson(pretty)
  def writeAst(terrain: Terrain): JValue = decompose(terrain)
  def    write(terrain: Terrain, pretty: Boolean): String = if (pretty) prty(writeAst(terrain)) else compact(writeAst(terrain))

  def     readEcsAst(ecs: ECS, json: JValue): Unit = ecsSerializer.SerializableOps(ecs).appendJsonAst(json)
  def        readEcs(ecs: ECS, json: String): Unit = ecsSerializer.SerializableOps(ecs).appendJson(json)
  def readTerrainAst(json: JValue): Terrain = extract[Terrain](json)
  def    readTerrain(json: String): Terrain = readTerrainAst(parse(json))


  //////////////////////////////////////////////////////////////////////////////////////

  object TerrainSerializer extends CustomSerializer[Terrain](_ => ({
    case json => extract[TerrainSerializable](json).toTerrain },{
    case terrain: Terrain => decompose(new TerrainSerializable(terrain))
  }))

  case class TerrainSerializable(nx: Int, ny: Int, base64Tiles: String) {
    def this(terrain: Terrain) = this(terrain.nx, terrain.ny, Base64.encodeString(terrain.tiles))
    def toTerrain: Terrain = Terrain(nx, ny, Base64.decodeBinary(base64Tiles))
  }

  implicit lazy val jsonFormats = org.json4s.DefaultFormats + TerrainSerializer + ShortTypeHints(Action.classes)
  val ecsSerializer = new JsonSerializer[IdTypes](
    knownSubtypes = KnownSubTypes.fromShortClassName(types = Action.classes:_*),
    jsonFormats = jsonFormats
  )

} 
开发者ID:GiGurra,项目名称:fun-rts,代码行数:46,代码来源:JSON.scala

示例3: ApiErrorParser

//设置package包名称以及导入依赖的类
package io.corbel.sdk.error

import com.ning.http.client.Response
import grizzled.slf4j.Logging
import org.json4s.DefaultFormats
import org.json4s.JsonAST.JValue
import org.json4s.native.JsonMethods._

import scala.util.{Success, Try}


class ApiErrorParser[T](f: Response => T) extends (Response => Either[ApiError, T]) with Logging {
  override def apply(res: Response): Either[ApiError, T] = res.getStatusCode match {
    case ok: Int if ok / 100 == 2 => Right(f(res))
    case other: Int => Left(apiErrorBody(res))
  }

  def apiErrorBody(res: Response): ApiError = {
    val apiError = ApiError(status = res.getStatusCode)
    if(!res.hasResponseBody){
      apiError
    }
    else {
      Try(parse(res.getResponseBodyAsStream)) match {
        case Success(json) => completeFromJson(apiError, json)
        case _ =>
          warn(s"Corbel error message without expected JSON body: ${res.getStatusCode} : ${res.getResponseBody}")
          apiError.copy(message = Option(res.getResponseBody))
      }
    }
  }

  def completeFromJson(apiError: ApiError, json: JValue): ApiError = {
    implicit val format = DefaultFormats
    val c = (json \ "error").extractOpt[String]
    val m = (json \ "errorDescription").extractOpt[String]
    apiError.copy(errorCode = c, message = m)
  }

} 
开发者ID:devialab,项目名称:corbel-sdk,代码行数:41,代码来源:ApiErrorParser.scala

示例4: DummyDeviceHistory

//设置package包名称以及导入依赖的类
package com.ubirch.avatar.test.tools.model

import java.util.UUID

import com.ubirch.avatar.model.rest.device.DeviceHistory
import com.ubirch.util.uuid.UUIDUtil

import org.joda.time.{DateTime, DateTimeZone}
import org.json4s.JsonAST.JValue
import org.json4s.native.JsonMethods._

import scala.collection.mutable.ListBuffer


object DummyDeviceHistory {

  def data(deviceId: String = UUIDUtil.uuidStr,
           messageId: UUID = UUIDUtil.uuid,
           deviceType: String = "lightsLamp",
           timestamp: DateTime = DateTime.now,
           deviceTags: Set[String] = Set("ubirch#0", "actor"),
           deviceMessage: JValue = parse("""{"foo": 23, "bar": 42}""")
          ): DeviceHistory = {

    DeviceHistory(
      messageId = messageId,
      deviceDataRawId = UUIDUtil.uuid,
      deviceId = deviceId,
      deviceName = s"$deviceType $deviceId",
      deviceType = deviceType,
      deviceTags = deviceTags,
      deviceMessage = deviceMessage,
      timestamp = timestamp
    )
  }

  def dataSeries(deviceId: String = UUIDUtil.uuidStr,
                 dType: String = "lightsLamp",
                 tags: Set[String] = Set("ubirch#0", "actor"),
                 message: JValue = parse("""{"foo": 23, "bar": 42}"""),
                 intervalMillis: Long = 1000 * 10, // 10s
                 timestampOffset: Long = -1000 * 60 * 60, // 1h
                 elementCount: Int = 5
                ): List[DeviceHistory] = {

    val deviceDataList: ListBuffer[DeviceHistory] = ListBuffer()
    val newestDateTime = DateTime.now(DateTimeZone.UTC).minus(timestampOffset)

    val range = 0 until elementCount
    for (i <- range) {
      val timestamp = newestDateTime.minus(i * intervalMillis)
      val deviceData = data(deviceId = deviceId, deviceType = dType, timestamp = timestamp, deviceTags = tags, deviceMessage = message)
      deviceDataList.+=:(deviceData)
    }

    deviceDataList.toList

  }

} 
开发者ID:ubirch,项目名称:ubirch-avatar-service,代码行数:61,代码来源:DummyDeviceHistory.scala

示例5: DummyDeviceHistory

//设置package包名称以及导入依赖的类
package com.ubirch.avatar.core.test.model

import java.util.UUID

import com.ubirch.avatar.model.rest.device.DeviceHistory
import com.ubirch.util.uuid.UUIDUtil

import org.joda.time.{DateTime, DateTimeZone}
import org.json4s.JsonAST.JValue
import org.json4s.native.JsonMethods._

import scala.collection.mutable.ListBuffer


object DummyDeviceHistory {

  def data(deviceId: String = UUIDUtil.uuidStr,
           messageId: UUID = UUIDUtil.uuid,
           deviceType: String = "lightsLamp",
           timestamp: DateTime = DateTime.now,
           deviceTags: Set[String] = Set("ubirch#0", "actor"),
           deviceMessage: JValue = parse("""{"foo": 23, "bar": 42}""")
          ): DeviceHistory = {

    DeviceHistory(
      messageId = messageId,
      deviceDataRawId = UUIDUtil.uuid,
      deviceId = deviceId,
      deviceName = s"$deviceType $deviceId",
      deviceType = deviceType,
      deviceTags = deviceTags,
      deviceMessage = deviceMessage,
      timestamp = timestamp
    )
  }

  def dataSeries(deviceId: String = UUIDUtil.uuidStr,
                 dType: String = "lightsLamp",
                 tags: Set[String] = Set("ubirch#0", "actor"),
                 message: JValue = parse("""{"foo": 23, "bar": 42}"""),
                 intervalMillis: Long = 1000 * 10, // 10s
                 timestampOffset: Long = -1000 * 60 * 60, // 1h
                 elementCount: Int = 5
                ): List[DeviceHistory] = {

    val deviceDataList: ListBuffer[DeviceHistory] = ListBuffer()
    val newestDateTime = DateTime.now(DateTimeZone.UTC).minus(timestampOffset)

    val range = 0 until elementCount
    for (i <- range) {
      val timestamp = newestDateTime.minus(i * intervalMillis)
      val deviceData = data(deviceId = deviceId, deviceType = dType, timestamp = timestamp, deviceTags = tags, deviceMessage = message)
      deviceDataList.+=:(deviceData)
    }

    deviceDataList.toList

  }

} 
开发者ID:ubirch,项目名称:ubirch-avatar-service,代码行数:61,代码来源:DummyDeviceHistory.scala

示例6: SighashSpec

//设置package包名称以及导入依赖的类
package fr.acinq.syscoin.reference

import java.io.InputStreamReader

import fr.acinq.syscoin._
import org.json4s.DefaultFormats
import org.json4s.JsonAST.{JInt, JString, JValue}
import org.json4s.jackson.JsonMethods
import org.junit.runner.RunWith
import org.scalatest.FlatSpec
import org.scalatest.junit.JUnitRunner

@RunWith(classOf[JUnitRunner])
class SighashSpec extends FlatSpec {
  implicit val format = DefaultFormats

  "syscoin-lib" should "pass reference client sighash tests" in {
    val stream = classOf[Base58Spec].getResourceAsStream("/data/sighash.json")
    val json = JsonMethods.parse(new InputStreamReader(stream))
    // use tail to skip the first line of the .json file
    json.extract[List[List[JValue]]].tail.map(_ match {
      case JString(raw_transaction) :: JString(script) :: JInt(input_index) :: JInt(hashType) :: JString(signature_hash) :: Nil => {
        val tx = Transaction.read(raw_transaction)
        val hash = Transaction.hashForSigning(tx, input_index.intValue, fromHexString(script), hashType.intValue)
        assert(toHexString(hash.reverse) === signature_hash)
      }
      case _ => println("warning: could not parse sighash.json properly!")
    })
  }
} 
开发者ID:sidhujag,项目名称:syscoin-lib,代码行数:31,代码来源:SighashSpec.scala

示例7: HTTPPollingActorSpec

//设置package包名称以及导入依赖的类
package polling

import java.time.Instant

import akka.NotUsed
import akka.actor.ActorSystem
import akka.http.scaladsl.model.ResponseEntity
import akka.stream.scaladsl.{Flow, Keep}
import akka.stream.testkit.scaladsl.{TestSink, TestSource}
import akka.testkit.TestKit
import org.json4s.JsonAST.JValue
import org.scalatest.{BeforeAndAfterAll, FlatSpecLike}


class HTTPPollingActorSpec(_system: ActorSystem) extends TestKit(_system)
  with FlatSpecLike with BeforeAndAfterAll {

  override def afterAll = {
    TestKit.shutdownActorSystem(system)
  }

  def testExchangeFlowPubSub(flow: Flow[(Instant, ResponseEntity), (String, JValue), NotUsed]) =
    TestSource.probe[(Instant, ResponseEntity)]
      .via(flow)
      .toMat(TestSink.probe[(String, JValue)])(Keep.both)
} 
开发者ID:blbradley,项目名称:kafka-cryptocoin,代码行数:27,代码来源:HTTPPollingActorSpec.scala

示例8: JsonRpcError

//设置package包名称以及导入依赖的类
package io.iohk.ethereum.jsonrpc

import org.json4s.JsonAST.JValue

case class JsonRpcError(code: Int, message: String, data: Option[JValue])

// scalastyle:off magic.number
// scalastyle:off public.methods.have.type
object JsonRpcErrors {
  val ParseError = JsonRpcError(-32700, "An error occurred on the server while parsing the JSON text", None)
  val InvalidRequest = JsonRpcError(-32600, "The JSON sent is not a valid Request object", None)
  val MethodNotFound = JsonRpcError(-32601, "The method does not exist / is not available", None)
  def InvalidParams(msg: String = "Invalid method parameters") = JsonRpcError(-32602, msg, None)
  val InternalError = JsonRpcError(-32603, "Internal JSON-RPC error", None)
  def LogicError(msg: String) = JsonRpcError(-32000, msg, None)
  val AccountLocked = LogicError("account is locked or unknown")
} 
开发者ID:input-output-hk,项目名称:etc-client,代码行数:18,代码来源:JsonRpcError.scala

示例9: Athanor

//设置package包名称以及导入依赖的类
package au.edu.utscic.athanorserver.athanor

import au.edu.utscic.athanorserver.data.RhetoricalImplicits
import au.edu.utscic.athanorserver.data.RhetoricalTypes._
import com.typesafe.config.{Config, ConfigFactory}
import com.xerox.jatanor.JAtanor
import org.json4s.JsonAST.JValue
import org.json4s.NoTypeHints
import org.json4s.jackson.JsonMethods.parse
import org.json4s.jackson.Serialization
import org.json4s.jackson.Serialization.write

import scala.io.Source


object Athanor {

  lazy val config: Config = ConfigFactory.load()
  lazy val path: String = config.getString("app.path")
  lazy val athanor = new JAtanor
  lazy val handler = athanor.LoadProgram(program,"")
  lazy val program: String = fullPath("apply.kif")
  lazy val testSentence: String = fullPath("sentence.json")
  lazy val demoFile:String = Source.fromFile(testSentence).getLines.mkString

  def fullPath(file:String): String = {
    s"$path/scripts/$file"
  }


  def parseJsonSentence(sent:String):ParsedSentence = {

    import RhetoricalImplicits._

    val json:JValue = parse(sent)
    val lexNodes:LexicalNodes = json(0)
    val constTree:ConstituentTree = json(1).extract[ConstituentTree]
    val deps:Dependencies = json(2).extract[Dependencies]
    (lexNodes,constTree,deps)
  }

  def parsedSentenceToJsonString(parsedSent:ParsedSentence):String = {
    implicit val formats = Serialization.formats(NoTypeHints)
    val l = write(parsedSent._1)
    val c = write(parsedSent._2).replaceAll("""(\"(?=[0-9]))|((?<=[0-9])\")""","") //remove quotes around Ints for json
    val d = write(parsedSent._3)
    s"[$l,$c,$d]"
  }

  def analyseParsedSentence(parsed:ParsedSentence):List[String] = {
    val jsonStr:String = parsedSentenceToJsonString(parsed)
    this.analyseJson(jsonStr)
  }

  def analyseJson(json:String):List[String] = {
    athanor.ExecuteFunctionArray(handler,"Apply",List(json).toArray).toList
  }

} 
开发者ID:uts-cic,项目名称:athanor-server,代码行数:60,代码来源:Athanor.scala

示例10: FieldDoesNotExistError

//设置package包名称以及导入依赖的类
package com.github.rcoh.query.render

import org.json4s.JsonAST.{JArray, JObject, JValue}
import com.github.rcoh.query.lang.Query
import com.github.rcoh.query.loaders.{ConcreteLoadable, ExposeAlways, Loadable, LoadableField}


trait RenderError
case class FieldDoesNotExistError(field: String) extends Exception(s"Field $field did not exist in object.")
case class ObjectNotIndexable(field: String, obj: JValue) extends Exception(s"Requested $field but $obj is not indexable.")

object Renderer {
  def render[A: Loadable](obj: A, query: Query): JValue = {
    val concreteLoadable = Loadable.toConcreteLoadable(obj)
    val loadResult = concreteLoadable.load
    val fieldMap = loadResult match {
      case Right(jValue) if query.fields.nonEmpty => throw ObjectNotIndexable(query.fields.head._1, jValue)
      case Right(jValue) => return jValue
      case Left(fields) => fields
    }

    val requestedFields = query.fields.map { case (fieldName, subQuery) =>
        val field = fieldMap.getOrElse(fieldName, throw FieldDoesNotExistError(fieldName))
        field.loader() match {
          case Left(loadable) => fieldName -> render(loadable, subQuery)
          case Right(loadables) => fieldName -> renderList(loadables, subQuery)
        }
    }

    val alwaysExposed = (fieldMap -- query.fields.keySet).collect {
      case (fieldName, LoadableField(ExposeAlways, loader)) => loader() match {
        case Left(loadable) => fieldName -> render(loadable, Query.NoQuery)
        case Right(loadables) => fieldName -> renderList(loadables, Query.NoQuery)
      }
    }
    val resultingMap = requestedFields ++ alwaysExposed
    JObject(resultingMap.toList: _*)
  }

  private def renderList(loadables: Iterable[ConcreteLoadable], query: Query): JArray = {
    val paged = loadables.drop(query.paging.offset).take(query.paging.max)
    val renderedObjects = paged.map(render(_, query))
    JArray(renderedObjects.toList)
  }
} 
开发者ID:rcoh,项目名称:lasic,代码行数:46,代码来源:Renderer.scala

示例11: unjsonify

//设置package包名称以及导入依赖的类
package com.telegram.json

import org.json4s.JsonAST.JValue
import org.json4s.NoTypeHints
import org.json4s.native.JsonMethods._
import org.json4s.native.Serialization
import org.json4s.native.Serialization._


  def unjsonify[T : Manifest](json: String): T = {
    unjsonify(parse(json))
  }

  def unjsonify[T : Manifest](json: JValue): T = {
    implicit val formats = Serialization.formats(NoTypeHints)
    val camelCased = json transformField {
      case (name, value) => (underscoreToCamel(name), value)
    }
    camelCased.extract[T]
  }
} 
开发者ID:rub0,项目名称:tbot,代码行数:22,代码来源:JsonUtils.scala

示例12: JsonSerializer

//设置package包名称以及导入依赖的类
package com.github.gigurra.scalego.serialization.json

import org.json4s.JsonAST.JValue
import org.json4s.{DefaultFormats, Extraction, Formats}
import org.json4s.jackson.JsonMethods.{compact, parse}
import org.json4s.jackson.JsonMethods.{pretty => prty}
import Extraction.{decompose, extract}
import com.github.gigurra.scalego.core.{ECS, IdTypes}
import com.github.gigurra.scalego.serialization.{ECSSerializer, IdTypeMapper, KnownSubTypes}
import ECSSerializer._


case class JsonSerializer[T_IdTypes <: IdTypes](knownSubtypes: KnownSubTypes = KnownSubTypes.empty,
                                                jsonFormats: Formats = DefaultFormats)
                                               (implicit systemIdMapper: IdTypeMapper[T_IdTypes#SystemId], entityIdMapper: IdTypeMapper[T_IdTypes#EntityId]) {

  private val serializer = new ECSSerializer[JValue, T_IdTypes](new JsonMapper[T_IdTypes](jsonFormats), knownSubtypes)

  implicit class SerializableOps(ecs: ECS[T_IdTypes]) {

    def toJsonAst: JValue = {
      val map = serializer.SerializableECSOpsWrite(ecs).toSerializable
      decompose(map)(jsonFormats)
    }

    def toJson(pretty: Boolean = false): String = {
      if (pretty) prty(toJsonAst)
      else compact(toJsonAst)
    }

    def appendJson(json: String): Unit = {
      appendJsonAst(parse(json))
    }

    def appendJsonAst(json: JValue): Unit = {
      val intermediaryFormat = extract[SerializableEcs[JValue]](json)(jsonFormats, implicitly[Manifest[SerializableEcs[JValue]]])
      serializer.SerializableECSOpsRead(ecs).append(intermediaryFormat)
    }
  }
} 
开发者ID:GiGurra,项目名称:scalego,代码行数:41,代码来源:JsonSerializer.scala

示例13: JsonRPCRequest

//设置package包名称以及导入依赖的类
package fr.acinq.eclair.blockchain.rpc

import java.io.IOException

import akka.actor.ActorSystem
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshalling.Marshal
import akka.http.scaladsl.model._
import akka.http.scaladsl.model.headers.{Authorization, BasicHttpCredentials}
import akka.http.scaladsl.unmarshalling.Unmarshal
import akka.stream.ActorMaterializer
import de.heikoseeberger.akkahttpjson4s.Json4sSupport._
import org.json4s.JsonAST.JValue
import org.json4s.{DefaultFormats, jackson}

import scala.concurrent.{ExecutionContext, Future}

// @formatter:off
case class JsonRPCRequest(jsonrpc: String = "1.0", id: String = "scala-client", method: String, params: Seq[Any])
case class Error(code: Int, message: String)
case class JsonRPCResponse(result: JValue, error: Option[Error], id: String)
case class JsonRPCError(error: Error) extends IOException(s"${error.message} (code: ${error.code})")
// @formatter:on

class BitcoinJsonRPCClient(user: String, password: String, host: String = "127.0.0.1", port: Int = 8332, ssl: Boolean = false)(implicit system: ActorSystem) {

  val scheme = if (ssl) "https" else "http"
  val uri = Uri(s"$scheme://$host:$port")

  implicit val materializer = ActorMaterializer()
  val httpClient = Http(system)
  implicit val serialization = jackson.Serialization
  implicit val formats = DefaultFormats

  def invoke(method: String, params: Any*)(implicit ec: ExecutionContext): Future[JValue] =
    for {
      entity <- Marshal(JsonRPCRequest(method = method, params = params)).to[RequestEntity]
      httpRes <- httpClient.singleRequest(HttpRequest(uri = uri, method = HttpMethods.POST).addHeader(Authorization(BasicHttpCredentials(user, password))).withEntity(entity))
      jsonRpcRes <- Unmarshal(httpRes).to[JsonRPCResponse].map {
        case JsonRPCResponse(_, Some(error), _) => throw JsonRPCError(error)
        case o => o
      } recover {
        case t: Throwable if httpRes.status == StatusCodes.Unauthorized => throw new RuntimeException("bitcoind replied with 401/Unauthorized (bad user/password?)", t)
      }
    } yield jsonRpcRes.result

  def invoke(request: Seq[(String, Seq[Any])])(implicit ec: ExecutionContext): Future[Seq[JValue]] =
    for {
      entity <- Marshal(request.map(r => JsonRPCRequest(method = r._1, params = r._2))).to[RequestEntity]
      httpRes <- httpClient.singleRequest(HttpRequest(uri = uri, method = HttpMethods.POST).addHeader(Authorization(BasicHttpCredentials(user, password))).withEntity(entity))
      jsonRpcRes <- Unmarshal(httpRes).to[Seq[JsonRPCResponse]].map {
        //case JsonRPCResponse(_, Some(error), _) => throw JsonRPCError(error)
        case o => o
      } recover {
        case t: Throwable if httpRes.status == StatusCodes.Unauthorized => throw new RuntimeException("bitcoind replied with 401/Unauthorized (bad user/password?)", t)
      }
    } yield jsonRpcRes.map(_.result)

} 
开发者ID:viacoin,项目名称:eclair,代码行数:60,代码来源:BitcoinJsonRPCClient.scala


注:本文中的org.json4s.JsonAST.JValue类示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。